aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/qml/doc/src/qml-extending.qdoc28
-rw-r--r--examples/qml/referenceexamples/extended/main.cpp4
-rw-r--r--examples/qml/referenceexamples/methods/example.qml4
-rw-r--r--examples/quick/demos/samegame/content/qmldir1
-rw-r--r--examples/quick/demos/samegame/samegame.qrc2
-rw-r--r--examples/quick/scenegraph/graph/graph.cpp2
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h2
-rw-r--r--src/3rdparty/masm/stubs/ExecutableAllocator.h13
-rw-r--r--src/3rdparty/masm/wtf/Compiler.h5
-rw-r--r--src/3rdparty/masm/wtf/MathExtras.h2
-rw-r--r--src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp11
-rw-r--r--src/3rdparty/masm/wtf/Platform.h16
-rw-r--r--src/imports/imports.pro4
-rw-r--r--src/imports/layouts/qquicklayout.cpp29
-rw-r--r--src/imports/layouts/qquicklayout_p.h2
-rw-r--r--src/imports/layouts/qquicklayoutstyleinfo.cpp2
-rw-r--r--src/imports/layouts/qquicklinearlayout.cpp36
-rw-r--r--src/imports/layouts/qquicklinearlayout_p.h2
-rw-r--r--src/imports/layouts/qquickstacklayout.cpp6
-rw-r--r--src/imports/statemachine/signaltransition.cpp2
-rw-r--r--src/imports/statemachine/state.cpp2
-rw-r--r--src/imports/statemachine/statemachine.cpp2
-rw-r--r--src/imports/statemachine/timeouttransition.cpp2
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel.cpp8
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel_p.h4
-rw-r--r--src/particles/qquickgravity.cpp41
-rw-r--r--src/particles/qquickgravity_p.h42
-rw-r--r--src/particles/qquickimageparticle.cpp24
-rw-r--r--src/particles/qquickmaskextruder.cpp2
-rw-r--r--src/particles/qquickspritegoal_p.h2
-rw-r--r--src/particles/shaders/imageparticle.vert6
-rw-r--r--src/particles/shaders/imageparticle_core.vert6
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp5
-rw-r--r--src/plugins/scenegraph/openvg/openvg.pro1
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp5
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp4
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp73
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h32
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp8
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h4
-rw-r--r--src/qml/compiler/qv4codegen.cpp31
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_win.cpp8
-rw-r--r--src/qml/compiler/qv4compileddata.cpp7
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
-rw-r--r--src/qml/compiler/qv4ssa.cpp2
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h2
-rw-r--r--src/qml/doc/src/examples.qdoc36
-rw-r--r--src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc8
-rw-r--r--src/qml/doc/src/qmltypereference.qdoc4
-rw-r--r--src/qml/jit/qv4assembler.cpp182
-rw-r--r--src/qml/jit/qv4assembler_p.h4
-rw-r--r--src/qml/jit/qv4binop.cpp86
-rw-r--r--src/qml/jit/qv4binop_p.h98
-rw-r--r--src/qml/jit/qv4isel_masm.cpp178
-rw-r--r--src/qml/jit/qv4regalloc.cpp14
-rw-r--r--src/qml/jsapi/qjsvalue.cpp3
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp10
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp69
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h8
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp10
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp675
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h48
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp26
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4context.cpp34
-rw-r--r--src/qml/jsruntime/qv4context_p.h24
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp133
-rw-r--r--src/qml/jsruntime/qv4dataview_p.h18
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp475
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h102
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp25
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp134
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h32
-rw-r--r--src/qml/jsruntime/qv4global_p.h9
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp146
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h20
-rw-r--r--src/qml/jsruntime/qv4include.cpp19
-rw-r--r--src/qml/jsruntime/qv4include_p.h2
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp32
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h2
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp23
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp186
-rw-r--r--src/qml/jsruntime/qv4mathobject_p.h38
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp7
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp160
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h16
-rw-r--r--src/qml/jsruntime/qv4object.cpp53
-rw-r--r--src/qml/jsruntime/qv4object_p.h14
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp412
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h52
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp65
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp97
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h18
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp1
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h32
-rw-r--r--src/qml/jsruntime/qv4script.cpp2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp64
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h6
-rw-r--r--src/qml/jsruntime/qv4string.cpp12
-rw-r--r--src/qml/jsruntime/qv4string_p.h6
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp395
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h46
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp101
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h12
-rw-r--r--src/qml/jsruntime/qv4value_p.h2
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp47
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h8
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp4
-rw-r--r--src/qml/memory/memory.pri4
-rw-r--r--src/qml/memory/qv4heap_p.h43
-rw-r--r--src/qml/memory/qv4mm.cpp938
-rw-r--r--src/qml/memory/qv4mm_p.h212
-rw-r--r--src/qml/memory/qv4mmdefs_p.h262
-rw-r--r--src/qml/qml.pro2
-rw-r--r--src/qml/qml/qqmlabstractbinding.cpp2
-rw-r--r--src/qml/qml/qqmlabstracturlinterceptor.h1
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp15
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp9
-rw-r--r--src/qml/qml/qqmlcomponent.cpp74
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp2
-rw-r--r--src/qml/qml/qqmldelayedcallqueue.cpp10
-rw-r--r--src/qml/qml/qqmldelayedcallqueue_p.h2
-rw-r--r--src/qml/qml/qqmldirparser.cpp9
-rw-r--r--src/qml/qml/qqmlengine.cpp31
-rw-r--r--src/qml/qml/qqmlerror.cpp72
-rw-r--r--src/qml/qml/qqmlerror.h3
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp10
-rw-r--r--src/qml/qml/qqmlimport.cpp168
-rw-r--r--src/qml/qml/qqmlincubator.cpp17
-rw-r--r--src/qml/qml/qqmlincubator_p.h5
-rw-r--r--src/qml/qml/qqmlinfo.cpp127
-rw-r--r--src/qml/qml/qqmlinfo.h16
-rw-r--r--src/qml/qml/qqmllist.cpp5
-rw-r--r--src/qml/qml/qqmllocale.cpp485
-rw-r--r--src/qml/qml/qqmllocale_p.h82
-rw-r--r--src/qml/qml/qqmlloggingcategory.cpp4
-rw-r--r--src/qml/qml/qqmlmetatype.cpp2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp32
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h1
-rw-r--r--src/qml/qml/qqmlplatform.cpp4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp100
-rw-r--r--src/qml/qml/qqmltypeloader_p.h10
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp12
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h2
-rw-r--r--src/qml/qml/qqmlvme.cpp12
-rw-r--r--src/qml/qml/qqmlvme_p.h1
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp9
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp496
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp865
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h118
-rw-r--r--src/qml/qml/v8/qv4domerrors_p.h5
-rw-r--r--src/qml/types/qqmlbind.cpp4
-rw-r--r--src/qml/types/qqmlconnections.cpp6
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp147
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h6
-rw-r--r--src/qml/types/qqmllistmodel.cpp50
-rw-r--r--src/qml/types/qqmlobjectmodel.cpp6
-rw-r--r--src/qml/types/qquickworkerscript.cpp13
-rw-r--r--src/quick/doc/images/touchpoint-metrics.pngbin0 -> 38894 bytes
-rw-r--r--src/quick/doc/snippets/qml/listview/listview.qml15
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp17
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp1297
-rw-r--r--src/quick/items/qquickanchors.cpp34
-rw-r--r--src/quick/items/qquickanimatedimage.cpp2
-rw-r--r--src/quick/items/qquickanimatedsprite.cpp2
-rw-r--r--src/quick/items/qquickborderimage.cpp2
-rw-r--r--src/quick/items/qquickdrag.cpp12
-rw-r--r--src/quick/items/qquickevents.cpp1
-rw-r--r--src/quick/items/qquickevents_p_p.h2
-rw-r--r--src/quick/items/qquickflickable.cpp80
-rw-r--r--src/quick/items/qquickflickable_p.h12
-rw-r--r--src/quick/items/qquickflickable_p_p.h3
-rw-r--r--src/quick/items/qquickflickablebehavior_p.h12
-rw-r--r--src/quick/items/qquickflipable.cpp4
-rw-r--r--src/quick/items/qquickgridview.cpp121
-rw-r--r--src/quick/items/qquickgridview_p.h12
-rw-r--r--src/quick/items/qquickimagebase.cpp2
-rw-r--r--src/quick/items/qquickitem.cpp10
-rw-r--r--src/quick/items/qquickitemanimation.cpp14
-rw-r--r--src/quick/items/qquickitemgrabresult.cpp15
-rw-r--r--src/quick/items/qquickitemsmodule.cpp10
-rw-r--r--src/quick/items/qquickitemview.cpp73
-rw-r--r--src/quick/items/qquickitemview_p.h22
-rw-r--r--src/quick/items/qquickitemview_p_p.h12
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp2
-rw-r--r--src/quick/items/qquicklistview.cpp214
-rw-r--r--src/quick/items/qquicklistview_p.h14
-rw-r--r--src/quick/items/qquickloader.cpp2
-rw-r--r--src/quick/items/qquickmousearea.cpp7
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp73
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h19
-rw-r--r--src/quick/items/qquickpathview.cpp23
-rw-r--r--src/quick/items/qquickpathview_p.h14
-rw-r--r--src/quick/items/qquickpathview_p_p.h2
-rw-r--r--src/quick/items/qquickpositioners.cpp101
-rw-r--r--src/quick/items/qquickpositioners_p.h3
-rw-r--r--src/quick/items/qquickrepeater.cpp2
-rw-r--r--src/quick/items/qquickspriteengine.cpp10
-rw-r--r--src/quick/items/qquickspritesequence.cpp2
-rw-r--r--src/quick/items/qquickstateoperations.cpp8
-rw-r--r--src/quick/items/qquicktext.cpp16
-rw-r--r--src/quick/items/qquicktext_p.h3
-rw-r--r--src/quick/items/qquicktextdocument.cpp2
-rw-r--r--src/quick/items/qquicktextedit.cpp4
-rw-r--r--src/quick/items/qquicktextinput.cpp17
-rw-r--r--src/quick/items/qquicktextinput_p.h1
-rw-r--r--src/quick/items/qquicktextutil.cpp4
-rw-r--r--src/quick/items/qquickview.cpp2
-rw-r--r--src/quick/items/qquickview.h16
-rw-r--r--src/quick/items/qquickview_p.h2
-rw-r--r--src/quick/items/qquickwindow.cpp5
-rw-r--r--src/quick/items/qquickwindowmodule.cpp3
-rw-r--r--src/quick/quick.pro2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp5
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp34
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp7
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp3
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h2
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp10
-rw-r--r--src/quick/scenegraph/util/qsgdefaultimagenode.cpp15
-rw-r--r--src/quick/scenegraph/util/qsgdefaultimagenode_p.h4
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.h2
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp53
-rw-r--r--src/quick/scenegraph/util/qsgtexture.h11
-rw-r--r--src/quick/scenegraph/util/qsgtexture_p.h2
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.cpp2
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.h7
-rw-r--r--src/quick/util/qquickanimation.cpp18
-rw-r--r--src/quick/util/qquickanimationcontroller.cpp2
-rw-r--r--src/quick/util/qquickanimator.cpp1
-rw-r--r--src/quick/util/qquickbehavior.cpp2
-rw-r--r--src/quick/util/qquickfontloader.cpp2
-rw-r--r--src/quick/util/qquickimageprovider.cpp2
-rw-r--r--src/quick/util/qquickpath.cpp14
-rw-r--r--src/quick/util/qquickpath_p.h1
-rw-r--r--src/quick/util/qquickpixmapcache.cpp9
-rw-r--r--src/quick/util/qquickpixmapcache_p.h4
-rw-r--r--src/quick/util/qquickpropertychanges.cpp4
-rw-r--r--src/quick/util/qquickstatechangescript.cpp2
-rw-r--r--src/quick/util/qquickstategroup.cpp2
-rw-r--r--src/quick/util/qquickutilmodule.cpp9
-rw-r--r--src/quick/util/util.pri9
-rw-r--r--src/src.pro4
-rw-r--r--tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp4
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp28
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/data/qtquick2.qml5
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp53
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp4
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.h2
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp58
-rw-r--r--tests/auto/qml/qqmlapplicationengine/data/LocalComponent.qml6
-rw-r--r--tests/auto/qml/qqmlapplicationengine/data/nonResolvedLocal.qml9
-rw-r--r--tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp24
-rw-r--r--tests/auto/qml/qqmldirparser/data/classname/qmldir5
-rw-r--r--tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp9
-rw-r--r--tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml8
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h1
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp70
-rw-r--r--tests/auto/qml/qqmlinfo/tst_qqmlinfo.cpp58
-rw-r--r--tests/auto/qml/qqmllocale/data/date.qml1
-rw-r--r--tests/auto/qml/qqmllocale/tst_qqmllocale.cpp60
-rw-r--r--tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp42
-rw-r--r--tests/auto/qmltest/BLACKLIST2
-rw-r--r--tests/auto/qmltest/layout/Container.qml (renamed from examples/quick/demos/samegame/content/BBSettings.qml)32
-rw-r--r--tests/auto/qmltest/layout/ContainerUser.qml (renamed from examples/quick/demos/samegame/content/+blackberry/Settings.qml)20
-rw-r--r--tests/auto/qmltest/layout/tst_layout.qml78
-rw-r--r--tests/auto/qmltest/positioners/tst_positioners.qml75
-rw-r--r--tests/auto/quick/examples/tst_examples.cpp6
-rw-r--r--tests/auto/quick/qquickanimations/data/pathLineUnspecifiedXYBug.qml28
-rw-r--r--tests/auto/quick/qquickanimations/data/pathSvgAnimation.qml25
-rw-r--r--tests/auto/quick/qquickanimations/tst_qquickanimations.cpp44
-rw-r--r--tests/auto/quick/qquickflickable/data/overshoot.qml79
-rw-r--r--tests/auto/quick/qquickflickable/data/overshoot_reentrant.qml55
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp196
-rw-r--r--tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp2
-rw-r--r--tests/auto/quick/qquickimage/tst_qquickimage.cpp16
-rw-r--r--tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp4
-rw-r--r--tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml21
-rw-r--r--tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml107
-rw-r--r--tests/auto/quick/qquicklayouts/qquicklayouts.pro3
-rw-r--r--tests/auto/quick/qquicklistview/data/flickBothDirections.qml70
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp79
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp3
-rw-r--r--tests/auto/quick/qquickpathview/data/removePath.qml26
-rw-r--r--tests/auto/quick/qquickpathview/tst_qquickpathview.cpp14
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp5
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp52
-rw-r--r--tests/auto/quick/qquickwindow/data/grabContentItemToImage.qml15
-rw-r--r--tests/auto/quick/qquickwindow/qquickwindow.pro3
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp19
-rw-r--r--tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro4
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp585
-rw-r--r--tests/benchmarks/qml/compilation/tst_compilation.cpp71
-rw-r--r--tests/manual/text/SignalIndicator.qml66
-rw-r--r--tests/manual/text/main.cpp51
-rw-r--r--tests/manual/text/main.qml56
-rw-r--r--tests/manual/text/qml.qrc7
-rw-r--r--tests/manual/text/text.pro7
-rw-r--r--tests/manual/text/textInputPropertiesAndSignals.qml134
-rw-r--r--tests/manual/touch/mpta-crosshairs.qml92
-rw-r--r--tests/manual/v4/tests.pro2
-rw-r--r--tests/testapplications/textlayout/styledtext-layout.qml2
-rw-r--r--tools/qml/main.cpp30
-rw-r--r--tools/qmllint/main.cpp11
-rw-r--r--tools/qmlplugindump/main.cpp20
-rw-r--r--tools/qmltime/qmltime.cpp2
310 files changed, 8923 insertions, 5916 deletions
diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc
index 0812a3dba1..b4174426a8 100644
--- a/examples/qml/doc/src/qml-extending.qdoc
+++ b/examples/qml/doc/src/qml-extending.qdoc
@@ -75,9 +75,21 @@ This example builds on:
Shows how to use \l {QQmlEngine::}{qmlRegisterExtendedType()} to provide an \l {Registering
Extension Objects}{extension object} to a \l QLineEdit without modifying or
-subclassing. The QML engine instantiates a \l QLineEdit and sets a property that
-only exists on the extension type. The extension type performs calls on the \l
-QLineEdit that otherwise will not be accessible to the QML engine.
+subclassing.
+
+\snippet referenceexamples/extended/main.cpp 0
+
+The QML engine instantiates a \l QLineEdit
+
+\snippet referenceexamples/extended/main.cpp 1
+
+and sets a property that oly exists on the extension type.
+
+\snippet referenceexamples/extended/example.qml 0
+
+The QML engine instantiates a \l QLineEdit and sets a property that
+only exists on the extension type. The extension type performs calls on the
+\l QLineEdit that otherwise will not be accessible to the QML engine.
*/
@@ -293,12 +305,20 @@ This example builds on:
This example builds on:
\list
-\li \l {Extending QML - Default Property Example}
\li \l {Extending QML - Inheritance and Coercion Example}
\li \l {Extending QML - Object and List Property Types Example}
\li \l {Extending QML - Adding Types Example}
\endlist
+The Methods Example has an additional method in the \c BirthdayParty class: \c invite().
+\c invite() is declared with \l Q_INVOKABLE so that it can be
+called from QML.
+
+\snippet referenceexamples/methods/birthdayparty.h 0
+
+In \c example.qml, the \c invite() method is called in the \l [QML]{QtQml::Component::completed()}{Component.onCompleted} signal handler:
+
+\snippet referenceexamples/methods/example.qml 0
*/
/*!
diff --git a/examples/qml/referenceexamples/extended/main.cpp b/examples/qml/referenceexamples/extended/main.cpp
index fc11587841..f72cb0d9e2 100644
--- a/examples/qml/referenceexamples/extended/main.cpp
+++ b/examples/qml/referenceexamples/extended/main.cpp
@@ -48,11 +48,15 @@ int main(int argc, char ** argv)
{
QApplication app(argc, argv);
+// ![0]
qmlRegisterExtendedType<QLineEdit, LineEditExtension>("People", 1,0, "QLineEdit");
+// ![0]
+// ![1]
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
QLineEdit *edit = qobject_cast<QLineEdit *>(component.create());
+// ![1]
if (edit) {
edit->show();
diff --git a/examples/qml/referenceexamples/methods/example.qml b/examples/qml/referenceexamples/methods/example.qml
index 58985c5d5f..197e6007e1 100644
--- a/examples/qml/referenceexamples/methods/example.qml
+++ b/examples/qml/referenceexamples/methods/example.qml
@@ -38,6 +38,7 @@
**
****************************************************************************/
+// ![0]
import QtQuick 2.0
import People 1.0
@@ -52,7 +53,6 @@ BirthdayParty {
Person { name: "Anne Brown" }
]
-// ![0]
Component.onCompleted: invite("William Green")
-// ![0]
}
+// ![0]
diff --git a/examples/quick/demos/samegame/content/qmldir b/examples/quick/demos/samegame/content/qmldir
index 727989d006..3b552ec1f1 100644
--- a/examples/quick/demos/samegame/content/qmldir
+++ b/examples/quick/demos/samegame/content/qmldir
@@ -1,5 +1,4 @@
singleton Settings 1.0 Settings.qml
-BBSettings 1.0 BBSettings.qml
Block 1.0 Block.qml
BlockEmitter 1.0 BlockEmitter.qml
Button 1.0 Button.qml
diff --git a/examples/quick/demos/samegame/samegame.qrc b/examples/quick/demos/samegame/samegame.qrc
index e51d3fae05..348ee109f9 100644
--- a/examples/quick/demos/samegame/samegame.qrc
+++ b/examples/quick/demos/samegame/samegame.qrc
@@ -3,8 +3,6 @@
<file>samegame.qml</file>
<file>content/qmldir</file>
<file>content/Settings.qml</file>
- <file>content/BBSettings.qml</file>
- <file>content/+blackberry/Settings.qml</file>
<file>content/gfx/text-p1-won.png</file>
<file>content/gfx/background-puzzle.png</file>
<file>content/gfx/background.png</file>
diff --git a/examples/quick/scenegraph/graph/graph.cpp b/examples/quick/scenegraph/graph/graph.cpp
index 389bd384c2..6048a1032c 100644
--- a/examples/quick/scenegraph/graph/graph.cpp
+++ b/examples/quick/scenegraph/graph/graph.cpp
@@ -102,7 +102,7 @@ QSGNode *Graph::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
n->background = new NoisyNode(window());
n->grid = new GridNode();
n->line = new LineNode(10, 0.5, QColor("steelblue"));
- n->shadow = new LineNode(20, 0.2, QColor::fromRgbF(0.2, 0.2, 0.2, 0.4));
+ n->shadow = new LineNode(20, 0.2f, QColor::fromRgbF(0.2, 0.2, 0.2, 0.4));
n->appendChildNode(n->background);
n->appendChildNode(n->grid);
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h b/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
index f03254aa38..e3c77d99e6 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
+++ b/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
@@ -66,7 +66,7 @@
#define CALLING_CONVENTION_IS_STDCALL 0
#endif
-#if CPU(X86)
+#if CPU(X86) && !OS(INTEGRITY)
#define HAS_FASTCALL_CALLING_CONVENTION 1
#ifndef FASTCALL
#if COMPILER(MSVC)
diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h
index 5a3939b7b2..8617229b06 100644
--- a/src/3rdparty/masm/stubs/ExecutableAllocator.h
+++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h
@@ -39,11 +39,6 @@
#ifndef MASM_EXECUTABLEALLOCATOR_H
#define MASM_EXECUTABLEALLOCATOR_H
-// Defined via mkspec
-#if _MSC_VER >= 1900
-#include <windows.h>
-#endif
-
#include <RefPtr.h>
#include <RefCounted.h>
#include <wtf/PageBlock.h>
@@ -117,13 +112,11 @@ struct ExecutableAllocator {
DWORD oldProtect;
# if !OS(WINRT)
VirtualProtect(addr, size, PAGE_READWRITE, &oldProtect);
-# elif _MSC_VER >= 1900
+# else
bool hr = VirtualProtectFromApp(addr, size, PAGE_READWRITE, &oldProtect);
if (!hr) {
Q_UNREACHABLE();
}
-# else
- (void)oldProtect;
# endif
# else
int mode = PROT_READ | PROT_WRITE;
@@ -152,13 +145,11 @@ struct ExecutableAllocator {
DWORD oldProtect;
# if !OS(WINRT)
VirtualProtect(addr, size, PAGE_EXECUTE_READ, &oldProtect);
-# elif _MSC_VER >= 1900
+# else
bool hr = VirtualProtectFromApp(addr, size, PAGE_EXECUTE_READ, &oldProtect);
if (!hr) {
Q_UNREACHABLE();
}
-# else
- (void)oldProtect;
# endif
# else
int mode = PROT_READ | PROT_EXEC;
diff --git a/src/3rdparty/masm/wtf/Compiler.h b/src/3rdparty/masm/wtf/Compiler.h
index fc3b5c5c08..da10196cc1 100644
--- a/src/3rdparty/masm/wtf/Compiler.h
+++ b/src/3rdparty/masm/wtf/Compiler.h
@@ -113,6 +113,11 @@
#define GCCE_VERSION_AT_LEAST(major, minor, patch) (GCCE_VERSION >= (major * 10000 + minor * 100 + patch))
#endif
+/* COMPILER(GHS) - Green Hills MULTI Compiler */
+#if defined(__ghs)
+#define WTF_COMPILER_GHS 1
+#endif
+
/* COMPILER(GCC) - GNU Compiler Collection */
/* --gnu option of the RVCT compiler also defines __GNUC__ */
#if defined(__GNUC__) && !COMPILER(RVCT)
diff --git a/src/3rdparty/masm/wtf/MathExtras.h b/src/3rdparty/masm/wtf/MathExtras.h
index 75e3670367..3740d54beb 100644
--- a/src/3rdparty/masm/wtf/MathExtras.h
+++ b/src/3rdparty/masm/wtf/MathExtras.h
@@ -88,7 +88,7 @@ inline double wtf_ceil(double x) { return copysign(ceil(x), x); }
#endif
-#if OS(SOLARIS)
+#if OS(SOLARIS) && __cplusplus < 201103L
namespace std {
diff --git a/src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp b/src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp
index b7ad723f07..0a6eda8b98 100644
--- a/src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp
+++ b/src/3rdparty/masm/wtf/OSAllocatorWinRT.cpp
@@ -32,19 +32,8 @@
#include "windows.h"
#include <wtf/Assertions.h>
-#if _MSC_VER >= 1900
// Try to use JIT by default and fallback to non-JIT on first error
static bool qt_winrt_use_jit = true;
-#else // _MSC_VER < 1900
-# define PAGE_EXECUTE 0x10
-# define PAGE_EXECUTE_READ 0x20
-# define PAGE_EXECUTE_READWRITE 0x40
-# define MEM_RELEASE 0x8000
-inline void* VirtualAllocFromApp(void*, size_t, int, int) { return 0; }
-inline bool VirtualProtectFromApp(void *, size_t, int, DWORD*) { return false; }
-inline bool VirtualFree(void *, size_t, DWORD) { return false; }
-static bool qt_winrt_use_jit = false;
-#endif // _MSC_VER < 1900
namespace WTF {
diff --git a/src/3rdparty/masm/wtf/Platform.h b/src/3rdparty/masm/wtf/Platform.h
index 3f480d344a..bc62c381db 100644
--- a/src/3rdparty/masm/wtf/Platform.h
+++ b/src/3rdparty/masm/wtf/Platform.h
@@ -224,7 +224,8 @@
#elif defined(__ARM_ARCH_7A__) \
|| defined(__ARM_ARCH_7R__) \
- || defined(__ARM_ARCH_7S__)
+ || defined(__ARM_ARCH_7S__) \
+ || defined(__CORE_CORTEXA__) // GHS-specific
#define WTF_ARM_ARCH_VERSION 7
/* MSVC sets _M_ARM */
@@ -268,7 +269,8 @@
|| defined(__ARM_ARCH_7A__) \
|| defined(__ARM_ARCH_7M__) \
|| defined(__ARM_ARCH_7R__) \
- || defined(__ARM_ARCH_7S__)
+ || defined(__ARM_ARCH_7S__) \
+ || defined(__CORE_CORTEXA__) // GHS-specific
#define WTF_THUMB_ARCH_VERSION 4
/* RVCT sets __TARGET_ARCH_THUMB */
@@ -385,6 +387,11 @@
#define WTF_OS_HURD 1
#endif
+/* OS(INTEGRITY) - INTEGRITY */
+#ifdef __INTEGRITY
+#define WTF_OS_INTEGRITY 1
+#endif
+
/* OS(LINUX) - Linux */
#ifdef __linux__
#define WTF_OS_LINUX 1
@@ -433,6 +440,7 @@
|| OS(DARWIN) \
|| OS(FREEBSD) \
|| OS(HURD) \
+ || OS(INTEGRITY) \
|| OS(LINUX) \
|| OS(NETBSD) \
|| OS(OPENBSD) \
@@ -603,7 +611,9 @@
#if OS(UNIX)
#define HAVE_ERRNO_H 1
-#define HAVE_MMAP 1
+#if !OS(INTEGRITY)
+#define HAVE_MMAP 1
+#endif
#define HAVE_SIGNAL_H 1
#define HAVE_STRINGS_H 1
#define HAVE_SYS_PARAM_H 1
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index 7d5596e86e..0d84bf538f 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -5,10 +5,10 @@ SUBDIRS += \
qtqml \
folderlistmodel \
localstorage \
- models \
- statemachine
+ models
qtConfig(settings): SUBDIRS += settings
+qtConfig(statemachine): SUBDIRS += statemachine
qtHaveModule(quick) {
SUBDIRS += \
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp
index 3786d21727..55ee3b63c6 100644
--- a/src/imports/layouts/qquicklayout.cpp
+++ b/src/imports/layouts/qquicklayout.cpp
@@ -42,6 +42,7 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/private/qnumeric_p.h>
#include <QtCore/qmath.h>
+#include <QtQml/qqmlinfo.h>
#include <limits>
/*!
@@ -678,7 +679,7 @@ QQuickLayout *QQuickLayoutAttached::parentLayout() const
parentItem = parentItem->parentItem();
return qobject_cast<QQuickLayout *>(parentItem);
} else {
- qWarning("Layout must be attached to Item elements");
+ qmlWarning(parent()) << "Layout must be attached to Item elements";
}
return 0;
}
@@ -762,9 +763,11 @@ bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&in
void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
{
if (change == ItemChildAddedChange) {
+ Q_D(QQuickLayout);
QQuickItem *item = value.item;
qmlobject_connect(item, QQuickItem, SIGNAL(baselineOffsetChanged(qreal)), this, QQuickLayout, SLOT(invalidateSenderItem()));
QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility);
+ d->m_hasItemChangeListeners = true;
if (isReady())
updateLayoutItems();
} else if (change == ItemChildRemovedChange) {
@@ -802,6 +805,30 @@ bool QQuickLayout::isReady() const
return d_func()->m_isReady;
}
+/*!
+ * \brief QQuickLayout::deactivateRecur
+ * \internal
+ *
+ * Call this from the dtor of the top-level layout.
+ * Otherwise, it will trigger lots of unneeded item change listeners (itemVisibleChanged()) for all its descendants
+ * that will have its impact thrown away.
+ */
+void QQuickLayout::deactivateRecur()
+{
+ if (d_func()->m_hasItemChangeListeners) {
+ for (int i = 0; i < itemCount(); ++i) {
+ QQuickItem *item = itemAt(i);
+ // When deleting a layout with children, there is no reason for the children to inform the layout that their
+ // e.g. visibility got changed. The layout already knows that all its children will eventually become invisible, so
+ // we therefore remove its change listener.
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility);
+ if (QQuickLayout *layout = qobject_cast<QQuickLayout*>(item))
+ layout->deactivateRecur();
+ }
+ d_func()->m_hasItemChangeListeners = false;
+ }
+}
+
void QQuickLayout::itemSiblingOrderChanged(QQuickItem *item)
{
Q_UNUSED(item);
diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h
index eece6f8658..113498eb2b 100644
--- a/src/imports/layouts/qquicklayout_p.h
+++ b/src/imports/layouts/qquicklayout_p.h
@@ -95,6 +95,7 @@ public:
void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
bool isReady() const;
+ void deactivateRecur();
/* QQuickItemChangeListener */
@@ -134,6 +135,7 @@ public:
protected:
unsigned m_isReady : 1;
unsigned m_disableRearrange : 1;
+ unsigned m_hasItemChangeListeners : 1; // if false, we don't need to remove its item change listeners...
mutable QSet<QQuickItem *> m_ignoredItems;
};
diff --git a/src/imports/layouts/qquicklayoutstyleinfo.cpp b/src/imports/layouts/qquicklayoutstyleinfo.cpp
index c33ceffb2d..5c8be8f306 100644
--- a/src/imports/layouts/qquicklayoutstyleinfo.cpp
+++ b/src/imports/layouts/qquicklayoutstyleinfo.cpp
@@ -50,7 +50,7 @@ QQuickLayoutStyleInfo::QQuickLayoutStyleInfo()
qreal QQuickLayoutStyleInfo::spacing(Qt::Orientation /*orientation*/) const
{
-#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_BLACKBERRY) || defined(Q_OS_QNX) || defined(Q_OS_WINRT)
+#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_QNX) || defined(Q_OS_WINRT)
// On Android and iOS the default spacing between each UI element is 8dp
qreal spacing = 8.0;
#else
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp
index 13fdd496c2..887b9b1fa1 100644
--- a/src/imports/layouts/qquicklinearlayout.cpp
+++ b/src/imports/layouts/qquicklinearlayout.cpp
@@ -41,6 +41,7 @@
#include "qquickgridlayoutengine_p.h"
#include "qquicklayoutstyleinfo_p.h"
#include <QtCore/private/qnumeric_p.h>
+#include <QtQml/qqmlinfo.h>
#include "qdebug.h"
#include <limits>
@@ -305,11 +306,7 @@ QQuickGridLayoutBase::~QQuickGridLayoutBase()
// Remove item listeners so we do not act on signalling unnecessarily
// (there is no point, as the layout will be torn down anyway).
- for (int i = 0; i < itemCount(); ++i) {
- QQuickItem *item = itemAt(i);
- QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight | QQuickItemPrivate::Destroyed | QQuickItemPrivate::Visibility);
- }
-
+ deactivateRecur();
delete d->styleInfo;
}
@@ -668,34 +665,25 @@ void QQuickGridLayout::insertLayoutItems()
int &columnSpan = span[0];
int &rowSpan = span[1];
- bool invalidRowColumn = false;
if (info) {
if (info->isRowSet() || info->isColumnSet()) {
// If row is specified and column is not specified (or vice versa),
// the unspecified component of the cell position should default to 0
- row = column = 0;
- if (info->isRowSet()) {
- row = info->row();
- invalidRowColumn = row < 0;
- }
- if (info->isColumnSet()) {
- column = info->column();
- invalidRowColumn = column < 0;
- }
- }
- if (invalidRowColumn) {
- qWarning("QQuickGridLayoutBase::insertLayoutItems: invalid row/column: %d",
- row < 0 ? row : column);
- return;
+ // The getters do this for us, as they will return 0 for an
+ // unset (or negative) value.
+ row = info->row();
+ column = info->column();
}
rowSpan = info->rowSpan();
columnSpan = info->columnSpan();
- if (columnSpan < 1 || rowSpan < 1) {
- qWarning("QQuickGridLayoutBase::addItem: invalid row span/column span: %d",
- rowSpan < 1 ? rowSpan : columnSpan);
+ if (columnSpan < 1) {
+ qmlWarning(child) << "Layout: invalid column span: " << columnSpan;
return;
- }
+ } else if (rowSpan < 1) {
+ qmlWarning(child) << "Layout: invalid row span: " << rowSpan;
+ return;
+ }
alignment = info->alignment();
}
diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h
index b425df0fa4..f796c8a855 100644
--- a/src/imports/layouts/qquicklinearlayout_p.h
+++ b/src/imports/layouts/qquicklinearlayout_p.h
@@ -152,8 +152,8 @@ public:
int rows() const;
void setRows(int rows);
- Q_ENUMS(Flow)
enum Flow { LeftToRight, TopToBottom };
+ Q_ENUM(Flow)
Flow flow() const;
void setFlow(Flow flow);
diff --git a/src/imports/layouts/qquickstacklayout.cpp b/src/imports/layouts/qquickstacklayout.cpp
index a223dd0374..0bfe63816d 100644
--- a/src/imports/layouts/qquickstacklayout.cpp
+++ b/src/imports/layouts/qquickstacklayout.cpp
@@ -307,7 +307,11 @@ void QQuickStackLayout::rearrange(const QSizeF &newSize)
QQuickItem *item = itemAt(d->currentIndex);
Q_ASSERT(item);
item->setPosition(QPointF(0,0)); // ### respect alignment?
- item->setSize(newSize.expandedTo(hints.min()).boundedTo(hints.max()));
+ const QSizeF oldSize(item->width(), item->height());
+ const QSizeF effectiveNewSize = newSize.expandedTo(hints.min()).boundedTo(hints.max());
+ item->setSize(effectiveNewSize);
+ if (effectiveNewSize == oldSize)
+ item->polish();
QQuickLayout::rearrange(newSize);
}
diff --git a/src/imports/statemachine/signaltransition.cpp b/src/imports/statemachine/signaltransition.cpp
index 2e6381fc08..44fbf69431 100644
--- a/src/imports/statemachine/signaltransition.cpp
+++ b/src/imports/statemachine/signaltransition.cpp
@@ -127,7 +127,7 @@ void SignalTransition::setSignal(const QJSValue &signal)
Q_ASSERT(sender);
signalMethod = sender->metaObject()->method(signalObject->signalIndex());
} else {
- qmlInfo(this) << tr("Specified signal does not exist.");
+ qmlWarning(this) << tr("Specified signal does not exist.");
return;
}
diff --git a/src/imports/statemachine/state.cpp b/src/imports/statemachine/state.cpp
index 09d246cc1e..f1294b0de0 100644
--- a/src/imports/statemachine/state.cpp
+++ b/src/imports/statemachine/state.cpp
@@ -54,7 +54,7 @@ void State::componentComplete()
static bool once = false;
if (!once) {
once = true;
- qmlInfo(this) << "No top level StateMachine found. Nothing will run without a StateMachine.";
+ qmlWarning(this) << "No top level StateMachine found. Nothing will run without a StateMachine.";
}
}
}
diff --git a/src/imports/statemachine/statemachine.cpp b/src/imports/statemachine/statemachine.cpp
index 76de01fe94..a9ea5f7a95 100644
--- a/src/imports/statemachine/statemachine.cpp
+++ b/src/imports/statemachine/statemachine.cpp
@@ -69,7 +69,7 @@ void StateMachine::setRunning(bool running)
void StateMachine::componentComplete()
{
if (QStateMachine::initialState() == NULL && childMode() == QState::ExclusiveStates)
- qmlInfo(this) << "No initial state set for StateMachine";
+ qmlWarning(this) << "No initial state set for StateMachine";
// Everything is proper setup, now start the state-machine if we got
// asked to do so.
diff --git a/src/imports/statemachine/timeouttransition.cpp b/src/imports/statemachine/timeouttransition.cpp
index 4bb1df3c28..0d208b919b 100644
--- a/src/imports/statemachine/timeouttransition.cpp
+++ b/src/imports/statemachine/timeouttransition.cpp
@@ -72,7 +72,7 @@ void TimeoutTransition::componentComplete()
{
QState *state = qobject_cast<QState*>(parent());
if (!state) {
- qmlInfo(this) << "Parent needs to be a State";
+ qmlWarning(this) << "Parent needs to be a State";
return;
}
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
index 4306f477e9..61c8665a14 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
@@ -596,7 +596,7 @@ void QQuickXmlListModelPrivate::append_role(QQmlListProperty<QQuickXmlListModelR
int i = _this->d_func()->roleObjects.count();
_this->d_func()->roleObjects.append(role);
if (_this->d_func()->roleNames.contains(role->name())) {
- qmlInfo(role) << QQuickXmlListModel::tr("\"%1\" duplicates a previous role name and will be disabled.").arg(role->name());
+ qmlWarning(role) << QQuickXmlListModel::tr("\"%1\" duplicates a previous role name and will be disabled.").arg(role->name());
return;
}
_this->d_func()->roles.insert(i, _this->d_func()->highestRole);
@@ -847,7 +847,7 @@ void QQuickXmlListModel::setQuery(const QString &query)
{
Q_D(QQuickXmlListModel);
if (!query.startsWith(QLatin1Char('/'))) {
- qmlInfo(this) << QCoreApplication::translate("QQuickXmlRoleList", "An XmlListModel query must start with '/' or \"//\"");
+ qmlWarning(this) << QCoreApplication::translate("QQuickXmlRoleList", "An XmlListModel query must start with '/' or \"//\"");
return;
}
@@ -1136,11 +1136,11 @@ void QQuickXmlListModel::queryError(void* object, const QString& error)
Q_D(QQuickXmlListModel);
for (int i=0; i<d->roleObjects.count(); i++) {
if (d->roleObjects.at(i) == static_cast<QQuickXmlListModelRole*>(object)) {
- qmlInfo(d->roleObjects.at(i)) << QQuickXmlListModel::tr("invalid query: \"%1\"").arg(error);
+ qmlWarning(d->roleObjects.at(i)) << QQuickXmlListModel::tr("invalid query: \"%1\"").arg(error);
return;
}
}
- qmlInfo(this) << QQuickXmlListModel::tr("invalid query: \"%1\"").arg(error);
+ qmlWarning(this) << QQuickXmlListModel::tr("invalid query: \"%1\"").arg(error);
}
void QQuickXmlListModel::queryCompleted(const QQuickXmlQueryResult &result)
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h b/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
index 3a4487a085..e6a0898bb9 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
@@ -79,7 +79,6 @@ class QQuickXmlListModel : public QAbstractListModel, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
- Q_ENUMS(Status)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
@@ -119,6 +118,7 @@ public:
Q_INVOKABLE QQmlV4Handle get(int index) const;
enum Status { Null, Ready, Loading, Error };
+ Q_ENUM(Status)
Status status() const;
qreal progress() const;
@@ -177,7 +177,7 @@ public:
void setQuery(const QString &query)
{
if (query.startsWith(QLatin1Char('/'))) {
- qmlInfo(this) << tr("An XmlRole query must not start with '/'");
+ qmlWarning(this) << tr("An XmlRole query must not start with '/'");
return;
}
if (m_query == query)
diff --git a/src/particles/qquickgravity.cpp b/src/particles/qquickgravity.cpp
index 90f305f336..a2a2ad7e0e 100644
--- a/src/particles/qquickgravity.cpp
+++ b/src/particles/qquickgravity.cpp
@@ -37,6 +37,7 @@
**
****************************************************************************/
+#include <QtQml/qqmlinfo.h>
#include "qquickgravity_p.h"
#include <cmath>
QT_BEGIN_NAMESPACE
@@ -64,16 +65,51 @@ const qreal CONV = 0.017453292520444443;
Pixels per second that objects will be accelerated by.
*/
+void QQuickGravityAffector::setMagnitude(qreal arg)
+{
+ if (m_magnitude != arg) {
+ m_magnitude = arg;
+ m_needRecalc = true;
+ emit magnitudeChanged(arg);
+ }
+}
+
+qreal QQuickGravityAffector::magnitude() const
+{
+ return m_magnitude;
+}
+
+
/*!
\qmlproperty real QtQuick.Particles::Gravity::acceleration
+ \deprecated
- Name changed to magnitude, will be removed soon.
+ \warning The name for this property has changed to magnitude, use it instead.
*/
+void QQuickGravityAffector::setAcceleration(qreal arg)
+{
+ qmlWarning(this) << "The acceleration property is deprecated. Please use magnitude instead.";
+ setMagnitude(arg);
+}
+
/*!
\qmlproperty real QtQuick.Particles::Gravity::angle
Angle of acceleration.
*/
+void QQuickGravityAffector::setAngle(qreal arg)
+{
+ if (m_angle != arg) {
+ m_angle = arg;
+ m_needRecalc = true;
+ emit angleChanged(arg);
+ }
+}
+
+qreal QQuickGravityAffector::angle() const
+{
+ return m_angle;
+}
QQuickGravityAffector::QQuickGravityAffector(QQuickItem *parent) :
QQuickParticleAffector(parent), m_magnitude(-10), m_angle(90), m_needRecalc(true)
@@ -94,4 +130,7 @@ bool QQuickGravityAffector::affectParticle(QQuickParticleData *d, qreal dt)
d->setInstantaneousVY(d->curVY(m_system) + m_dy*dt, m_system);
return true;
}
+
+
+
QT_END_NAMESPACE
diff --git a/src/particles/qquickgravity_p.h b/src/particles/qquickgravity_p.h
index d3a7f6665c..333d3d1534 100644
--- a/src/particles/qquickgravity_p.h
+++ b/src/particles/qquickgravity_p.h
@@ -62,52 +62,20 @@ class QQuickGravityAffector : public QQuickParticleAffector
Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
public:
explicit QQuickGravityAffector(QQuickItem *parent = 0);
- qreal magnitude() const
- {
- return m_magnitude;
- }
+ qreal magnitude() const;
+ qreal angle() const;
- qreal angle() const
- {
- return m_angle;
- }
protected:
bool affectParticle(QQuickParticleData *d, qreal dt) override;
Q_SIGNALS:
-
void magnitudeChanged(qreal arg);
-
void angleChanged(qreal arg);
public Q_SLOTS:
-void setAcceleration(qreal arg)
-{
- qWarning() << "Gravity::acceleration has been renamed Gravity::magnitude";
- if (m_magnitude != arg) {
- m_magnitude = arg;
- m_needRecalc = true;
- Q_EMIT magnitudeChanged(arg);
- }
-}
-
-void setMagnitude(qreal arg)
-{
- if (m_magnitude != arg) {
- m_magnitude = arg;
- m_needRecalc = true;
- Q_EMIT magnitudeChanged(arg);
- }
-}
-
-void setAngle(qreal arg)
-{
- if (m_angle != arg) {
- m_angle = arg;
- m_needRecalc = true;
- Q_EMIT angleChanged(arg);
- }
-}
+ void setMagnitude(qreal arg);
+ void setAcceleration(qreal arg);
+ void setAngle(qreal arg);
private:
qreal m_magnitude;
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index 60cbf6175d..ccfebddb0e 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -58,12 +58,6 @@
QT_BEGIN_NAMESPACE
-#if defined(Q_OS_BLACKBERRY)
-#define SHADER_PLATFORM_DEFINES "Q_OS_BLACKBERRY\n"
-#else
-#define SHADER_PLATFORM_DEFINES
-#endif
-
//TODO: Make it larger on desktop? Requires fixing up shader code with the same define
#define UNIFORM_ARRAY_SIZE 64
@@ -102,7 +96,6 @@ public:
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
builder.addDefinition(QByteArrayLiteral("TABLE"));
builder.addDefinition(QByteArrayLiteral("DEFORM"));
builder.addDefinition(QByteArrayLiteral("COLOR"));
@@ -113,7 +106,6 @@ public:
builder.clear();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
builder.addDefinition(QByteArrayLiteral("TABLE"));
builder.addDefinition(QByteArrayLiteral("DEFORM"));
builder.addDefinition(QByteArrayLiteral("COLOR"));
@@ -180,7 +172,6 @@ public:
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
builder.addDefinition(QByteArrayLiteral("DEFORM"));
builder.addDefinition(QByteArrayLiteral("COLOR"));
if (isES)
@@ -190,7 +181,6 @@ public:
builder.clear();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
builder.addDefinition(QByteArrayLiteral("DEFORM"));
builder.addDefinition(QByteArrayLiteral("COLOR"));
if (isES)
@@ -245,7 +235,6 @@ public:
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
builder.addDefinition(QByteArrayLiteral("SPRITE"));
builder.addDefinition(QByteArrayLiteral("TABLE"));
builder.addDefinition(QByteArrayLiteral("DEFORM"));
@@ -257,7 +246,6 @@ public:
builder.clear();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
builder.addDefinition(QByteArrayLiteral("SPRITE"));
builder.addDefinition(QByteArrayLiteral("TABLE"));
builder.addDefinition(QByteArrayLiteral("DEFORM"));
@@ -327,7 +315,6 @@ public:
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
builder.addDefinition(QByteArrayLiteral("COLOR"));
if (isES)
builder.removeVersion();
@@ -336,7 +323,6 @@ public:
builder.clear();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
builder.addDefinition(QByteArrayLiteral("COLOR"));
if (isES)
builder.removeVersion();
@@ -405,7 +391,6 @@ public:
const bool isES = QOpenGLContext::currentContext()->isOpenGLES();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
if (isES)
builder.removeVersion();
@@ -413,7 +398,6 @@ public:
builder.clear();
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
- builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
if (isES)
builder.removeVersion();
@@ -1347,21 +1331,21 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
if (m_colorTable->pix.isReady())
colortable = m_colorTable->pix.image();
else
- qmlInfo(this) << "Error loading color table: " << m_colorTable->pix.error();
+ qmlWarning(this) << "Error loading color table: " << m_colorTable->pix.error();
}
if (m_sizeTable) {
if (m_sizeTable->pix.isReady())
sizetable = m_sizeTable->pix.image();
else
- qmlInfo(this) << "Error loading size table: " << m_sizeTable->pix.error();
+ qmlWarning(this) << "Error loading size table: " << m_sizeTable->pix.error();
}
if (m_opacityTable) {
if (m_opacityTable->pix.isReady())
opacitytable = m_opacityTable->pix.image();
else
- qmlInfo(this) << "Error loading opacity table: " << m_opacityTable->pix.error();
+ qmlWarning(this) << "Error loading opacity table: " << m_opacityTable->pix.error();
}
if (colortable.isNull()){//###Goes through image just for this
@@ -1383,7 +1367,7 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node)
if (!imageLoaded) {
if (!m_image || !m_image->pix.isReady()) {
if (m_image)
- qmlInfo(this) << m_image->pix.error();
+ qmlWarning(this) << m_image->pix.error();
delete m_material;
return;
}
diff --git a/src/particles/qquickmaskextruder.cpp b/src/particles/qquickmaskextruder.cpp
index 66d5808c33..7564fa6739 100644
--- a/src/particles/qquickmaskextruder.cpp
+++ b/src/particles/qquickmaskextruder.cpp
@@ -94,7 +94,7 @@ void QQuickMaskExtruder::startMaskLoading()
void QQuickMaskExtruder::finishMaskLoading()
{
if (m_pix.isError())
- qmlInfo(this) << m_pix.error();
+ qmlWarning(this) << m_pix.error();
}
QPointF QQuickMaskExtruder::extrude(const QRectF &r)
diff --git a/src/particles/qquickspritegoal_p.h b/src/particles/qquickspritegoal_p.h
index 2b15d0b8bb..e569603550 100644
--- a/src/particles/qquickspritegoal_p.h
+++ b/src/particles/qquickspritegoal_p.h
@@ -107,7 +107,7 @@ void setSystemStates(bool arg)
{
if (m_systemStates != arg) {
//TODO: GroupGoal was added (and this deprecated) Oct 4 - remove it in a few weeks.
- qmlInfo(this) << "systemStates is deprecated and will be removed soon. Use GroupGoal instead.";
+ qmlWarning(this) << "systemStates is deprecated and will be removed soon. Use GroupGoal instead.";
m_systemStates = arg;
Q_EMIT systemStatesChanged(arg);
}
diff --git a/src/particles/shaders/imageparticle.vert b/src/particles/shaders/imageparticle.vert
index 377f831686..4057a9eb4b 100644
--- a/src/particles/shaders/imageparticle.vert
+++ b/src/particles/shaders/imageparticle.vert
@@ -69,11 +69,7 @@ void main()
fTex = vPosTex.zw;
#endif
highp float currentSize = mix(vData.z, vData.w, t * t);
-#if defined (Q_OS_BLACKBERRY)
- highp float fade = 1.;
-#else
lowp float fade = 1.;
-#endif
highp float fadeIn = min(t * 10., 1.);
highp float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);
@@ -142,4 +138,4 @@ void main()
#endif
}
}
-} \ No newline at end of file
+}
diff --git a/src/particles/shaders/imageparticle_core.vert b/src/particles/shaders/imageparticle_core.vert
index ed9a918eb3..cfa0d57dfd 100644
--- a/src/particles/shaders/imageparticle_core.vert
+++ b/src/particles/shaders/imageparticle_core.vert
@@ -69,11 +69,7 @@ void main()
fTex = vPosTex.zw;
#endif
float currentSize = mix(vData.z, vData.w, t * t);
-#if defined (Q_OS_BLACKBERRY)
float fade = 1.;
-#else
- float fade = 1.;
-#endif
float fadeIn = min(t * 10., 1.);
float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);
@@ -142,4 +138,4 @@ void main()
#endif
}
}
-} \ No newline at end of file
+}
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
index 317471eeec..11cc257103 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12threadedrenderloop.cpp
@@ -773,6 +773,11 @@ void QSGD3D12ThreadedRenderLoop::windowDestroyed(QQuickWindow *window)
break;
}
}
+
+ // Now that we altered the window list, we may need to stop the animation
+ // timer even if we didn't via handleObscurity. This covers the case where
+ // we destroy a visible & exposed QQuickWindow.
+ startOrStopAnimationTimer();
}
void QSGD3D12ThreadedRenderLoop::exposureChanged(QQuickWindow *window)
diff --git a/src/plugins/scenegraph/openvg/openvg.pro b/src/plugins/scenegraph/openvg/openvg.pro
index 8a58796a05..6d5b190b37 100644
--- a/src/plugins/scenegraph/openvg/openvg.pro
+++ b/src/plugins/scenegraph/openvg/openvg.pro
@@ -10,6 +10,7 @@ QMAKE_TARGET_PRODUCT = "Qt Quick OpenVG Renderer (Qt $$QT_VERSION)"
QMAKE_TARGET_DESCRIPTION = "Quick OpenVG Renderer for Qt."
QMAKE_USE += openvg
+CONFIG += egl
OTHER_FILES += $$PWD/openvg.json
diff --git a/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp b/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp
index 80af227fb4..1f2709e06c 100644
--- a/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp
+++ b/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp
@@ -37,10 +37,11 @@
**
****************************************************************************/
+#include <QDebug>
#include "qopenvgoffscreensurface.h"
#include <QtGui/QImage>
-#include <QDebug>
+
QT_BEGIN_NAMESPACE
@@ -71,7 +72,7 @@ QOpenVGOffscreenSurface::QOpenVGOffscreenSurface(const QSize &size)
m_renderTarget = eglCreatePbufferFromClientBuffer(m_display,
EGL_OPENVG_IMAGE,
- (EGLClientBuffer)m_image,
+ reinterpret_cast<EGLClientBuffer>(uintptr_t(m_image)),
pbufferConfig,
0);
if (m_renderTarget == EGL_NO_SURFACE)
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
index 22a80c62e8..41fce7c7fc 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
@@ -39,8 +39,6 @@
#include "qsgopenvgcontext_p.h"
#include "qsgopenvgrenderer_p.h"
-#include "qsgopenvginternalrectanglenode.h"
-#include "qsgopenvginternalimagenode.h"
#include "qsgopenvgpublicnodes.h"
#include "qsgopenvgtexture.h"
#include "qsgopenvglayer.h"
@@ -52,6 +50,8 @@
#include "qopenvgcontext_p.h"
#include <private/qsgrenderer_p.h>
+#include "qsgopenvginternalrectanglenode.h"
+#include "qsgopenvginternalimagenode.h"
// polish, animations, sync, render and swap in the render loop
Q_LOGGING_CATEGORY(QSG_OPENVG_LOG_TIME_RENDERLOOP, "qt.scenegraph.time.renderloop")
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
index 1afc5ea7ca..e45b79706b 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
@@ -39,6 +39,8 @@
#include "qsgopenvgpublicnodes.h"
#include "qsgopenvghelpers.h"
+#include <VG/openvg.h>
+#include <QtGui/QPixmap>
QT_BEGIN_NAMESPACE
@@ -66,6 +68,11 @@ void QSGOpenVGRectangleNode::setRect(const QRectF &rect)
markDirty(DirtyMaterial);
}
+QRectF QSGOpenVGRectangleNode::rect() const
+{
+ return m_rect;
+}
+
void QSGOpenVGRectangleNode::setColor(const QColor &color)
{
m_color = color;
@@ -73,6 +80,11 @@ void QSGOpenVGRectangleNode::setColor(const QColor &color)
markDirty(DirtyMaterial);
}
+QColor QSGOpenVGRectangleNode::color() const
+{
+ return m_color;
+}
+
void QSGOpenVGRectangleNode::setTransform(const QOpenVGMatrix &transform)
{
// if there transform matrix is not affine, regenerate the path
@@ -177,12 +189,58 @@ QSGOpenVGImageNode::~QSGOpenVGImageNode()
}
}
+void QSGOpenVGImageNode::setRect(const QRectF &rect)
+{
+ m_rect = rect;
+ markDirty(DirtyMaterial);
+}
+
+QRectF QSGOpenVGImageNode::rect() const
+{
+ return m_rect;
+}
+
+void QSGOpenVGImageNode::setSourceRect(const QRectF &r)
+{
+ m_sourceRect = r;
+}
+
+QRectF QSGOpenVGImageNode::sourceRect() const
+{
+ return m_sourceRect;
+}
+
void QSGOpenVGImageNode::setTexture(QSGTexture *texture)
{
m_texture = texture;
markDirty(DirtyMaterial);
}
+QSGTexture *QSGOpenVGImageNode::texture() const
+{
+ return m_texture;
+}
+
+void QSGOpenVGImageNode::setFiltering(QSGTexture::Filtering filtering)
+{
+ m_filtering = filtering;
+ markDirty(DirtyMaterial);
+}
+
+QSGTexture::Filtering QSGOpenVGImageNode::filtering() const
+{
+ return m_filtering;
+}
+
+void QSGOpenVGImageNode::setMipmapFiltering(QSGTexture::Filtering)
+{
+}
+
+QSGTexture::Filtering QSGOpenVGImageNode::mipmapFiltering() const
+{
+ return QSGTexture::None;
+}
+
void QSGOpenVGImageNode::setTextureCoordinatesTransform(QSGImageNode::TextureCoordinatesTransformMode transformNode)
{
if (m_transformMode == transformNode)
@@ -191,6 +249,21 @@ void QSGOpenVGImageNode::setTextureCoordinatesTransform(QSGImageNode::TextureCoo
markDirty(DirtyGeometry);
}
+QSGImageNode::TextureCoordinatesTransformMode QSGOpenVGImageNode::textureCoordinatesTransform() const
+{
+ return m_transformMode;
+}
+
+void QSGOpenVGImageNode::setOwnsTexture(bool owns)
+{
+ m_owns = owns;
+}
+
+bool QSGOpenVGImageNode::ownsTexture() const
+{
+ return m_owns;
+}
+
void QSGOpenVGImageNode::render()
{
if (!m_texture) {
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
index 34c8e50615..8e12c27824 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
@@ -44,10 +44,6 @@
#include <QtQuick/qsgimagenode.h>
#include <QtQuick/qsgninepatchnode.h>
-#include <QtGui/QPixmap>
-
-#include <VG/openvg.h>
-
#include "qsgopenvgrenderable.h"
QT_BEGIN_NAMESPACE
@@ -59,10 +55,10 @@ public:
~QSGOpenVGRectangleNode();
void setRect(const QRectF &rect) override;
- QRectF rect() const override { return m_rect; }
+ QRectF rect() const override;
void setColor(const QColor &color) override;
- QColor color() const override { return m_color; }
+ QColor color() const override;
void setTransform(const QOpenVGMatrix &transform) override;
@@ -86,26 +82,26 @@ public:
QSGOpenVGImageNode();
~QSGOpenVGImageNode();
- void setRect(const QRectF &rect) override { m_rect = rect; markDirty(DirtyMaterial); }
- QRectF rect() const override { return m_rect; }
+ void setRect(const QRectF &rect) override;
+ QRectF rect() const override;
- void setSourceRect(const QRectF &r) override { m_sourceRect = r; }
- QRectF sourceRect() const override { return m_sourceRect; }
+ void setSourceRect(const QRectF &r) override;
+ QRectF sourceRect() const override;
void setTexture(QSGTexture *texture) override;
- QSGTexture *texture() const override { return m_texture; }
+ QSGTexture *texture() const override;
- void setFiltering(QSGTexture::Filtering filtering) override { m_filtering = filtering; markDirty(DirtyMaterial); }
- QSGTexture::Filtering filtering() const override { return m_filtering; }
+ void setFiltering(QSGTexture::Filtering filtering) override;
+ QSGTexture::Filtering filtering() const override;
- void setMipmapFiltering(QSGTexture::Filtering) override { }
- QSGTexture::Filtering mipmapFiltering() const override { return QSGTexture::None; }
+ void setMipmapFiltering(QSGTexture::Filtering) override;
+ QSGTexture::Filtering mipmapFiltering() const override;
void setTextureCoordinatesTransform(TextureCoordinatesTransformMode transformNode) override;
- TextureCoordinatesTransformMode textureCoordinatesTransform() const override { return m_transformMode; }
+ TextureCoordinatesTransformMode textureCoordinatesTransform() const override;
- void setOwnsTexture(bool owns) override { m_owns = owns; }
- bool ownsTexture() const override { return m_owns; }
+ void setOwnsTexture(bool owns) override;
+ bool ownsTexture() const override;
void render() override;
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index ab2b0553a9..85267225be 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -57,12 +57,12 @@
QT_BEGIN_NAMESPACE
QQmlTypeCompiler::QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData,
- QmlIR::Document *parsedQML, const QQmlRefPointer<QQmlTypeNameCache> &importCache,
+ QmlIR::Document *parsedQML, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache)
: resolvedTypes(resolvedTypeCache)
, engine(engine)
, typeData(typeData)
- , importCache(importCache)
+ , typeNameCache(typeNameCache)
, document(parsedQML)
{
}
@@ -138,7 +138,7 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
sss.scan();
}
- QmlIR::JSCodeGen v4CodeGenerator(typeData->finalUrlString(), document->code, &document->jsModule, &document->jsParserEngine, document->program, importCache, &document->jsGenerator.stringTable);
+ QmlIR::JSCodeGen v4CodeGenerator(typeData->finalUrlString(), document->code, &document->jsModule, &document->jsParserEngine, document->program, typeNameCache, &document->jsGenerator.stringTable);
QQmlJSCodeGenerator jsCodeGen(this, &v4CodeGenerator);
if (!jsCodeGen.generateCodeForComponents())
return nullptr;
@@ -164,7 +164,7 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
QV4::CompiledData::CompilationUnit *compilationUnit = document->javaScriptCompilationUnit;
compilationUnit = document->javaScriptCompilationUnit;
- compilationUnit->importCache = importCache;
+ compilationUnit->typeNameCache = typeNameCache;
compilationUnit->resolvedTypes = resolvedTypes;
compilationUnit->propertyCaches = std::move(m_propertyCaches);
Q_ASSERT(compilationUnit->propertyCaches.count() == static_cast<int>(compilationUnit->data->nObjects));
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index de6abb4ced..2b59e7e42f 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -89,7 +89,7 @@ struct QQmlTypeCompiler
{
Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
public:
- QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, const QQmlRefPointer<QQmlTypeNameCache> &importCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
+ QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
// --- interface used by QQmlPropertyCacheCreator
typedef QmlIR::Object CompiledObject;
@@ -139,7 +139,7 @@ private:
QList<QQmlError> errors;
QQmlEnginePrivate *engine;
QQmlTypeData *typeData;
- QQmlRefPointer<QQmlTypeNameCache> importCache;
+ QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
QmlIR::Document *document;
// index is string index of type name (use obj->inheritedTypeNameIndex)
QHash<int, QQmlCustomParser*> customParsers;
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index e0def1021b..7d3ad38f97 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -526,21 +526,21 @@ IR::Expr *Codegen::subscript(IR::Expr *base, IR::Expr *index)
if (hasError)
return 0;
- if (! base->asTemp() || base->asArgLocal()) {
+ if (! base->asTemp() && !base->asArgLocal()) {
const unsigned t = _block->newTemp();
move(_block->TEMP(t), base);
base = _block->TEMP(t);
}
- if (! index->asTemp() || index->asArgLocal()) {
+ if (! index->asTemp() && !index->asArgLocal() && !index->asConst()) {
const unsigned t = _block->newTemp();
move(_block->TEMP(t), index);
index = _block->TEMP(t);
}
Q_ASSERT(base->asTemp() || base->asArgLocal());
- Q_ASSERT(index->asTemp() || index->asArgLocal());
- return _block->SUBSCRIPT(base->asTemp(), index->asTemp());
+ Q_ASSERT(index->asTemp() || index->asArgLocal() || index->asConst());
+ return _block->SUBSCRIPT(base, index);
}
IR::Expr *Codegen::argument(IR::Expr *expr)
@@ -611,7 +611,7 @@ IR::Expr *Codegen::binop(IR::AluOp op, IR::Expr *left, IR::Expr *right, const AS
if (IR::Const *c1 = left->asConst()) {
if (IR::Const *c2 = right->asConst()) {
- if (c1->type == IR::NumberType && c2->type == IR::NumberType) {
+ if ((c1->type & IR::NumberType) && (c2->type & IR::NumberType)) {
switch (op) {
case IR::OpAdd: return _block->CONST(IR::NumberType, c1->value + c2->value);
case IR::OpAnd: return _block->CONST(IR::BoolType, c1->value ? c2->value : 0);
@@ -659,20 +659,20 @@ IR::Expr *Codegen::binop(IR::AluOp op, IR::Expr *left, IR::Expr *right, const AS
}
}
- if (!left->asTemp() && !left->asArgLocal()) {
+ if (!left->asTemp() && !left->asArgLocal() && !left->asConst()) {
const unsigned t = _block->newTemp();
setLocation(move(_block->TEMP(t), left), loc);
left = _block->TEMP(t);
}
- if (!right->asTemp() && !right->asArgLocal()) {
+ if (!right->asTemp() && !right->asArgLocal() && !right->asConst()) {
const unsigned t = _block->newTemp();
setLocation(move(_block->TEMP(t), right), loc);
right = _block->TEMP(t);
}
- Q_ASSERT(left->asTemp() || left->asArgLocal());
- Q_ASSERT(right->asTemp() || right->asArgLocal());
+ Q_ASSERT(left->asTemp() || left->asArgLocal() || left->asConst());
+ Q_ASSERT(right->asTemp() || right->asArgLocal() || right->asConst());
return _block->BINOP(op, left, right);
}
@@ -842,9 +842,16 @@ void Codegen::variableDeclaration(VariableDeclaration *ast)
Q_ASSERT(expr.code);
initializer = *expr;
- int initialized = _block->newTemp();
- move(_block->TEMP(initialized), initializer);
- move(identifier(ast->name.toString(), ast->identifierToken.startLine, ast->identifierToken.startColumn), _block->TEMP(initialized));
+ IR::Expr *lhs = identifier(ast->name.toString(), ast->identifierToken.startLine,
+ ast->identifierToken.startColumn);
+
+ if (lhs->asArgLocal()) {
+ move(lhs, initializer);
+ } else {
+ int initialized = _block->newTemp();
+ move(_block->TEMP(initialized), initializer);
+ move(lhs, _block->TEMP(initialized));
+ }
}
void Codegen::variableDeclarationList(VariableDeclarationList *ast)
diff --git a/src/qml/compiler/qv4compilationunitmapper_win.cpp b/src/qml/compiler/qv4compilationunitmapper_win.cpp
index 457b702ac3..37cac846a0 100644
--- a/src/qml/compiler/qv4compilationunitmapper_win.cpp
+++ b/src/qml/compiler/qv4compilationunitmapper_win.cpp
@@ -75,7 +75,6 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
CloseHandle(handle);
});
-#if !defined(Q_OS_WINRT) || _MSC_VER >= 1900
CompiledData::Unit header;
DWORD bytesRead;
if (!ReadFile(handle, reinterpret_cast<char *>(&header), sizeof(header), &bytesRead, nullptr)) {
@@ -115,19 +114,12 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co
}
return reinterpret_cast<CompiledData::Unit*>(dataPtr);
-#else
- Q_UNUSED(sourcePath);
- *errorString = QStringLiteral("Compilation unit mapping not supported on WinRT 8.1");
- return nullptr;
-#endif
}
void CompilationUnitMapper::close()
{
-#if !defined(Q_OS_WINRT) || _MSC_VER >= 1900
if (dataPtr != nullptr)
UnmapViewOfFile(dataPtr);
-#endif
dataPtr = nullptr;
}
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 8586c84c3d..25b090f555 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -207,7 +207,7 @@ void CompilationUnit::unlink()
dependentScripts.at(ii)->release();
dependentScripts.clear();
- importCache = nullptr;
+ typeNameCache = nullptr;
qDeleteAll(resolvedTypes);
resolvedTypes.clear();
@@ -407,6 +407,11 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, EvalISelFactory *iselFactory
const Unit * const oldDataPtr = (data && !(data->flags & QV4::CompiledData::Unit::StaticData)) ? data : nullptr;
QScopedValueRollback<const Unit *> dataPtrChange(data, mappedUnit);
+ if (sourcePath != QQmlFile::urlToLocalFileOrQrc(stringAt(data->sourceFileIndex))) {
+ *errorString = QStringLiteral("QML source file has moved to a different location.");
+ return false;
+ }
+
{
const QString foundArchitecture = stringAt(data->architectureIndex);
const QString expectedArchitecture = QSysInfo::buildAbi();
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 2682365182..97623b4d86 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -855,7 +855,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount
QQmlPropertyCacheVector propertyCaches;
QQmlPropertyCache *rootPropertyCache() const { return propertyCaches.at(data->indexOfRootObject); }
- QQmlRefPointer<QQmlTypeNameCache> importCache;
+ QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
// index is object index. This allows fast access to the
// property data when initializing bindings, avoiding expensive
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 943700de44..1d512711b8 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -2758,7 +2758,7 @@ public:
visit(s);
}
- foreach (const Conversion &conversion, _conversions) {
+ for (const Conversion &conversion : qAsConst(_conversions)) {
IR::Move *move = conversion.stmt->asMove();
// Note: isel only supports move into member when source is a temp, so convert
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index 3a507bef74..41fb2c5b7b 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -73,7 +73,7 @@ struct QQmlProfiler {};
struct QQmlBindingProfiler
{
- QQmlBindingProfiler(quintptr, QQmlBinding *, QV4::FunctionObject *) {}
+ QQmlBindingProfiler(quintptr, QV4::Function *) {}
};
struct QQmlHandlingSignalProfiler
diff --git a/src/qml/doc/src/examples.qdoc b/src/qml/doc/src/examples.qdoc
index f3550ae199..4f12d42f48 100644
--- a/src/qml/doc/src/examples.qdoc
+++ b/src/qml/doc/src/examples.qdoc
@@ -32,4 +32,40 @@
The list of examples demonstrating how to extend C++ to QML or the other way
around.
+
+\noautolist
+
+\table
+ \row
+ \li \l {Extending QML - Adding Types Example}
+ \li Exporting C++ Classes
+ \row
+ \li \l {Extending QML - Object and List Property Types Example}
+ \li Exporting C++ Properties
+ \row
+ \li \l {Extending QML - Extension Objects Example}
+ \li Extension Objects
+ \row
+ \li \l {Extending QML - Inheritance and Coercion Example}
+ \li C++ Inheritance and Coercion
+ \row
+ \li \l {Extending QML - Methods Example}
+ \li Methods Support
+ \row
+ \li \l {Extending QML - Attached Properties Example}
+ \li Attached Properties
+ \row
+ \li \l {Extending QML - Signal Support Example}
+ \li Signal Support
+ \row
+ \li \l {Extending QML - Property Value Source Example}
+ \li Property Value Source
+ \row
+ \li \l {Extending QML - Default Property Example}
+ \li Default Property
+ \row
+ \li \l {Extending QML - Grouped Properties Example}
+ \li Grouped Properties
+\endtable
+
*/
diff --git a/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc b/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc
index 7fa271c2d9..5cfd80f8a0 100644
--- a/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc
+++ b/src/qml/doc/src/qmllanguageref/documents/networktransparency.qdoc
@@ -48,12 +48,8 @@ Image {
}
\endqml
-Network transparency is supported throughout QML, for example:
-
-\list
-\li Fonts - the \c source property of FontLoader is a URL
-\li WebViews - the \c url property of WebView (obviously!)
-\endlist
+Network transparency is supported throughout QML, for example, both the FontLoader
+and Image elements support loading resources from a remote server.
Even QML types themselves can be on the network - if the \l {Prototyping with qmlscene} is used to load
\tt http://example.com/mystuff/Hello.qml and that content refers to a type "World", the engine
diff --git a/src/qml/doc/src/qmltypereference.qdoc b/src/qml/doc/src/qmltypereference.qdoc
index f32574fcc1..b2bb9ebd18 100644
--- a/src/qml/doc/src/qmltypereference.qdoc
+++ b/src/qml/doc/src/qmltypereference.qdoc
@@ -89,7 +89,7 @@ provided:
\ingroup qtquickbasictypes
\brief a date value.
-The \c date type refers to a date value.
+The \c date type refers to a date value, including the time of the day.
To create a \c date value, specify it as a "YYYY-MM-DD" string:
@@ -100,7 +100,7 @@ MyDatePicker { minDate: "2000-01-01"; maxDate: "2020-12-31" }
To read a date value returned from a C++ extension class, use
\l{QtQml::Qt::formatDate()}{Qt.formatDate()} and \l{QtQml::Qt::formatDateTime()}{Qt.formatDateTime()}.
-When integrating with C++, note that any QDate value
+When integrating with C++, note that any QDate or QDateTime value
\l{qtqml-cppintegration-data.html}{passed into QML from C++} is automatically
converted into a \c date value, and vice-versa.
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index e1acc33f82..018396318e 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -52,6 +52,8 @@
#include <WTFStubs.h>
#include <iostream>
+#include <QBuffer>
+#include <QCoreApplication>
#if ENABLE(ASSEMBLER)
@@ -146,11 +148,11 @@ bool CompilationUnit::memoryMapCode(QString *errorString)
const Assembler::VoidType Assembler::Void;
-Assembler::Assembler(InstructionSelection *isel, IR::Function* function, QV4::ExecutableAllocator *executableAllocator)
+Assembler::Assembler(QV4::Compiler::JSUnitGenerator *jsGenerator, IR::Function* function, QV4::ExecutableAllocator *executableAllocator)
: _function(function)
, _nextBlock(0)
, _executableAllocator(executableAllocator)
- , _isel(isel)
+ , _jsGenerator(jsGenerator)
{
_addrs.resize(_function->basicBlockCount());
_patches.resize(_function->basicBlockCount());
@@ -301,7 +303,7 @@ Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &s
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);
- const int id = _isel->registerString(string);
+ const int id = _jsGenerator->registerString(string);
return Pointer(reg, id * sizeof(QV4::String*));
}
@@ -314,13 +316,13 @@ Assembler::Address Assembler::loadConstant(const Primitive &v, RegisterID baseRe
{
loadPtr(Address(Assembler::EngineRegister, qOffsetOf(QV4::ExecutionEngine, current)), baseReg);
loadPtr(Address(baseReg, qOffsetOf(QV4::Heap::ExecutionContext, constantTable)), baseReg);
- const int index = _isel->jsUnitGenerator()->registerConstant(v.asReturnedValue());
+ const int index = _jsGenerator->registerConstant(v.asReturnedValue());
return Address(baseReg, index * sizeof(QV4::Value));
}
void Assembler::loadStringRef(RegisterID reg, const QString &string)
{
- const int id = _isel->registerString(string);
+ const int id = _jsGenerator->registerString(string);
move(TrustedImm32(id), reg);
}
@@ -496,4 +498,174 @@ void Assembler::setStackLayout(int maxArgCountForBuiltins, int regularRegistersT
_stackLayout.reset(new StackLayout(_function, maxArgCountForBuiltins, regularRegistersToSave, fpRegistersToSave));
}
+
+namespace {
+class QIODevicePrintStream: public FilePrintStream
+{
+ Q_DISABLE_COPY(QIODevicePrintStream)
+
+public:
+ explicit QIODevicePrintStream(QIODevice *dest)
+ : FilePrintStream(0)
+ , dest(dest)
+ , buf(4096, '0')
+ {
+ Q_ASSERT(dest);
+ }
+
+ ~QIODevicePrintStream()
+ {}
+
+ void vprintf(const char* format, va_list argList) WTF_ATTRIBUTE_PRINTF(2, 0)
+ {
+ const int written = qvsnprintf(buf.data(), buf.size(), format, argList);
+ if (written > 0)
+ dest->write(buf.constData(), written);
+ memset(buf.data(), 0, qMin(written, buf.size()));
+ }
+
+ void flush()
+ {}
+
+private:
+ QIODevice *dest;
+ QByteArray buf;
+};
+} // anonymous namespace
+
+static void printDisassembledOutputWithCalls(QByteArray processedOutput, const QHash<void*, const char*>& functions)
+{
+ for (QHash<void*, const char*>::ConstIterator it = functions.begin(), end = functions.end();
+ it != end; ++it) {
+ const QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
+ int idx = processedOutput.indexOf(ptrString);
+ if (idx < 0)
+ continue;
+ idx = processedOutput.lastIndexOf('\n', idx);
+ if (idx < 0)
+ continue;
+ processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; call ") + it.value());
+ }
+
+ qDebug("%s", processedOutput.constData());
+}
+
+#if defined(Q_OS_LINUX)
+static FILE *pmap;
+
+static void qt_closePmap()
+{
+ if (pmap) {
+ fclose(pmap);
+ pmap = 0;
+ }
+}
+
+#endif
+
+JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
+{
+ Label endOfCode = label();
+
+ {
+ for (size_t i = 0, ei = _patches.size(); i != ei; ++i) {
+ Label target = _addrs.at(i);
+ Q_ASSERT(target.isSet());
+ for (Jump jump : qAsConst(_patches.at(i)))
+ jump.linkTo(target, this);
+ }
+ }
+
+ JSC::JSGlobalData dummy(_executableAllocator);
+ JSC::LinkBuffer linkBuffer(dummy, this, 0);
+
+ for (const DataLabelPatch &p : qAsConst(_dataLabelPatches))
+ linkBuffer.patch(p.dataLabel, linkBuffer.locationOf(p.target));
+
+ // link exception handlers
+ for (Jump jump : qAsConst(exceptionPropagationJumps))
+ linkBuffer.link(jump, linkBuffer.locationOf(exceptionReturnLabel));
+
+ {
+ for (size_t i = 0, ei = _labelPatches.size(); i != ei; ++i) {
+ Label target = _addrs.at(i);
+ Q_ASSERT(target.isSet());
+ for (DataLabelPtr label : _labelPatches.at(i))
+ linkBuffer.patch(label, linkBuffer.locationOf(target));
+ }
+ }
+
+ *codeSize = linkBuffer.offsetOf(endOfCode);
+
+ QByteArray name;
+
+ JSC::MacroAssemblerCodeRef codeRef;
+
+ static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
+ if (showCode) {
+ QHash<void*, const char*> functions;
+#ifndef QT_NO_DEBUG
+ for (CallInfo call : qAsConst(_callInfos))
+ functions[linkBuffer.locationOf(call.label).dataLocation()] = call.functionName;
+#endif
+
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ WTF::setDataFile(new QIODevicePrintStream(&buf));
+
+ name = _function->name->toUtf8();
+ if (name.isEmpty())
+ name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
+ codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
+
+ WTF::setDataFile(stderr);
+ printDisassembledOutputWithCalls(buf.data(), functions);
+ } else {
+ codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
+ }
+
+#if defined(Q_OS_LINUX)
+ // This implements writing of JIT'd addresses so that perf can find the
+ // symbol names.
+ //
+ // Perf expects the mapping to be in a certain place and have certain
+ // content, for more information, see:
+ // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
+ static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
+ static bool profileInitialized = false;
+ if (doProfile && !profileInitialized) {
+ profileInitialized = true;
+
+ char pname[PATH_MAX];
+ snprintf(pname, PATH_MAX - 1, "/tmp/perf-%lu.map",
+ (unsigned long)QCoreApplication::applicationPid());
+
+ pmap = fopen(pname, "w");
+ if (!pmap)
+ qWarning("QV4: Can't write %s, call stacks will not contain JavaScript function names", pname);
+
+ // make sure we clean up nicely
+ std::atexit(qt_closePmap);
+ }
+
+ if (pmap) {
+ // this may have been pre-populated, if QV4_SHOW_ASM was on
+ if (name.isEmpty()) {
+ name = _function->name->toUtf8();
+ if (name.isEmpty())
+ name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
+ }
+
+ fprintf(pmap, "%llx %x %.*s\n",
+ (long long unsigned int)codeRef.code().executableAddress(),
+ *codeSize,
+ name.length(),
+ name.constData());
+ fflush(pmap);
+ }
+#endif
+
+ return codeRef;
+}
+
#endif
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 94478cd9cd..de9c246ed6 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -111,7 +111,7 @@ class Assembler : public JSC::MacroAssembler, public TargetPlatform
Q_DISABLE_COPY(Assembler)
public:
- Assembler(InstructionSelection *isel, IR::Function* function, QV4::ExecutableAllocator *executableAllocator);
+ Assembler(QV4::Compiler::JSUnitGenerator *jsGenerator, IR::Function* function, QV4::ExecutableAllocator *executableAllocator);
// Explicit type to allow distinguishing between
// pushing an address itself or the value it points
@@ -1092,7 +1092,7 @@ private:
IR::BasicBlock *_nextBlock;
QV4::ExecutableAllocator *_executableAllocator;
- InstructionSelection *_isel;
+ QV4::Compiler::JSUnitGenerator *_jsGenerator;
};
template <typename Result, typename Source>
diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp
index 9c535bb0bb..d2758c4a47 100644
--- a/src/qml/jit/qv4binop.cpp
+++ b/src/qml/jit/qv4binop.cpp
@@ -112,7 +112,7 @@ void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
return;
}
- Assembler::Jump done;
+ Jump done;
if (lhs->type != IR::StringType && rhs->type != IR::StringType)
done = genInlineBinop(lhs, rhs, target);
@@ -129,13 +129,13 @@ void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
RuntimeCall context(info.contextImplementation);
if (fallBack.isValid()) {
as->generateFunctionCallImp(info.needsExceptionCheck, target, info.name, fallBack,
- Assembler::PointerToValue(lhs),
- Assembler::PointerToValue(rhs));
+ PointerToValue(lhs),
+ PointerToValue(rhs));
} else if (context.isValid()) {
as->generateFunctionCallImp(info.needsExceptionCheck, target, info.name, context,
Assembler::EngineRegister,
- Assembler::PointerToValue(lhs),
- Assembler::PointerToValue(rhs));
+ PointerToValue(lhs),
+ PointerToValue(rhs));
} else {
Q_ASSERT(!"unreachable");
}
@@ -148,9 +148,9 @@ void Binop::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
{
IR::Temp *targetTemp = target->asTemp();
- Assembler::FPRegisterID targetReg;
+ FPRegisterID targetReg;
if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister)
- targetReg = (Assembler::FPRegisterID) targetTemp->index;
+ targetReg = (FPRegisterID) targetTemp->index;
else
targetReg = Assembler::FPGpr0;
@@ -162,7 +162,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
#if CPU(X86)
if (IR::Const *c = rhs->asConst()) { // Y = X + constant -> Y = X; Y += [constant-address]
as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister);
+ Address addr = as->loadConstant(c, Assembler::ScratchRegister);
as->addDouble(addr, targetReg);
break;
}
@@ -184,7 +184,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
#if CPU(X86)
if (IR::Const *c = rhs->asConst()) { // Y = X * constant -> Y = X; Y *= [constant-address]
as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister);
+ Address addr = as->loadConstant(c, Assembler::ScratchRegister);
as->mulDouble(addr, targetReg);
break;
}
@@ -203,7 +203,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
#if CPU(X86)
if (IR::Const *c = rhs->asConst()) { // Y = X - constant -> Y = X; Y -= [constant-address]
as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister);
+ Address addr = as->loadConstant(c, Assembler::ScratchRegister);
as->subDouble(addr, targetReg);
break;
}
@@ -231,7 +231,7 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
#if CPU(X86)
if (IR::Const *c = rhs->asConst()) { // Y = X / constant -> Y = X; Y /= [constant-address]
as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Assembler::Address addr = as->loadConstant(c, Assembler::ScratchRegister);
+ Address addr = as->loadConstant(c, Assembler::ScratchRegister);
as->divDouble(addr, targetReg);
break;
}
@@ -258,9 +258,9 @@ void Binop::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
default: {
Q_ASSERT(target->type == IR::BoolType);
- Assembler::Jump trueCase = as->branchDouble(false, op, lhs, rhs);
+ Jump trueCase = as->branchDouble(false, op, lhs, rhs);
as->storeBool(false, target);
- Assembler::Jump done = as->jump();
+ Jump done = as->jump();
trueCase.link(as);
as->storeBool(true, target);
done.link(as);
@@ -305,13 +305,13 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
bool inplaceOpWithAddress = false;
IR::Temp *targetTemp = target->asTemp();
- Assembler::RegisterID targetReg = Assembler::ReturnValueRegister;
+ RegisterID targetReg = Assembler::ReturnValueRegister;
if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) {
IR::Temp *rhs = rightSource->asTemp();
if (!rhs || rhs->kind != IR::Temp::PhysicalRegister || rhs->index != targetTemp->index) {
// We try to load leftSource into the target's register, but we can't do that if
// the target register is the same as rightSource.
- targetReg = (Assembler::RegisterID) targetTemp->index;
+ targetReg = (RegisterID) targetTemp->index;
} else if (rhs && rhs->kind == IR::Temp::PhysicalRegister && targetTemp->index == rhs->index) {
// However, if the target register is the same as the rightSource register, we can flip
// the operands for certain operations.
@@ -323,7 +323,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
case IR::OpMul:
// X = Y op X -> X = X op Y (or rephrased: X op= Y (so an in-place operation))
std::swap(leftSource, rightSource);
- targetReg = (Assembler::RegisterID) targetTemp->index;
+ targetReg = (RegisterID) targetTemp->index;
break;
case IR::OpLShift:
@@ -368,7 +368,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
&& targetTemp->kind == IR::Temp::PhysicalRegister
&& targetTemp->index == rightSource->asTemp()->index) {
// X = Y - X -> Tmp = X; X = Y; X -= Tmp
- targetReg = (Assembler::RegisterID) targetTemp->index;
+ targetReg = (RegisterID) targetTemp->index;
as->move(targetReg, Assembler::ScratchRegister);
as->move(as->toInt32Register(leftSource, targetReg), targetReg);
as->sub32(Assembler::ScratchRegister, targetReg);
@@ -384,7 +384,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
case IR::OpURShift:
if (IR::Const *c = rightSource->asConst()) {
if ((QV4::Primitive::toUInt32(c->value) & 0x1f) == 0) {
- Assembler::RegisterID r = as->toInt32Register(leftSource, targetReg);
+ RegisterID r = as->toInt32Register(leftSource, targetReg);
as->storeInt32(r, target);
return true;
}
@@ -395,10 +395,10 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
break;
}
- Assembler::RegisterID l = as->toInt32Register(leftSource, targetReg);
+ RegisterID l = as->toInt32Register(leftSource, targetReg);
if (IR::Const *c = rightSource->asConst()) { // All cases of Y = X op Const
- Assembler::TrustedImm32 r(int(c->value));
- Assembler::TrustedImm32 ur(QV4::Primitive::toUInt32(c->value) & 0x1f);
+ TrustedImm32 r(int(c->value));
+ TrustedImm32 ur(QV4::Primitive::toUInt32(c->value) & 0x1f);
switch (op) {
case IR::OpBitAnd: as->and32(r, l, targetReg); break;
@@ -419,7 +419,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
return false;
}
} else if (inplaceOpWithAddress) { // All cases of X = X op [address-of-Y]
- Assembler::Pointer rhsAddr = as->loadAddress(Assembler::ScratchRegister, rightSource);
+ Pointer rhsAddr = as->loadAddress(Assembler::ScratchRegister, rightSource);
switch (op) {
case IR::OpBitAnd: as->and32(rhsAddr, targetReg); break;
case IR::OpBitOr: as->or32 (rhsAddr, targetReg); break;
@@ -433,7 +433,7 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
return false;
}
} else { // All cases of Z = X op Y
- Assembler::RegisterID r = as->toInt32Register(rightSource, Assembler::ScratchRegister);
+ RegisterID r = as->toInt32Register(rightSource, Assembler::ScratchRegister);
switch (op) {
case IR::OpBitAnd: as->and32(l, r, targetReg); break;
case IR::OpBitOr: as->or32 (l, r, targetReg); break;
@@ -452,10 +452,10 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
// Not all CPUs accept shifts over more than 31 bits, and some CPUs (like ARM) will do
// surprising stuff when shifting over 0 bits.
#define CHECK_RHS(op) { \
- as->and32(Assembler::TrustedImm32(0x1f), r, Assembler::ScratchRegister); \
- Assembler::Jump notZero = as->branch32(Assembler::NotEqual, Assembler::ScratchRegister, Assembler::TrustedImm32(0)); \
+ as->and32(TrustedImm32(0x1f), r, Assembler::ScratchRegister); \
+ Jump notZero = as->branch32(RelationalCondition::NotEqual, Assembler::ScratchRegister, TrustedImm32(0)); \
as->move(l, targetReg); \
- Assembler::Jump done = as->jump(); \
+ Jump done = as->jump(); \
notZero.link(as); \
op; \
done.link(as); \
@@ -493,7 +493,7 @@ static inline Assembler::FPRegisterID getFreeFPReg(IR::Expr *shouldNotOverlap, u
Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target)
{
- Assembler::Jump done;
+ Jump done;
// Try preventing a call for a few common binary operations. This is used in two cases:
// - no register allocation was performed (not available for the platform, or the IR was
@@ -505,10 +505,10 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc
// register.
switch (op) {
case IR::OpAdd: {
- Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 2);
- Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 4);
- Assembler::Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Assembler::Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
+ FPRegisterID lReg = getFreeFPReg(rightSource, 2);
+ FPRegisterID rReg = getFreeFPReg(leftSource, 4);
+ Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
+ Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
as->addDouble(rReg, lReg);
as->storeDouble(lReg, target);
@@ -520,10 +520,10 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc
rightIsNoDbl.link(as);
} break;
case IR::OpMul: {
- Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 2);
- Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 4);
- Assembler::Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Assembler::Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
+ FPRegisterID lReg = getFreeFPReg(rightSource, 2);
+ FPRegisterID rReg = getFreeFPReg(leftSource, 4);
+ Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
+ Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
as->mulDouble(rReg, lReg);
as->storeDouble(lReg, target);
@@ -535,10 +535,10 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc
rightIsNoDbl.link(as);
} break;
case IR::OpSub: {
- Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 2);
- Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 4);
- Assembler::Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Assembler::Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
+ FPRegisterID lReg = getFreeFPReg(rightSource, 2);
+ FPRegisterID rReg = getFreeFPReg(leftSource, 4);
+ Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
+ Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
as->subDouble(rReg, lReg);
as->storeDouble(lReg, target);
@@ -550,10 +550,10 @@ Assembler::Jump Binop::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSourc
rightIsNoDbl.link(as);
} break;
case IR::OpDiv: {
- Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 2);
- Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 4);
- Assembler::Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Assembler::Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
+ FPRegisterID lReg = getFreeFPReg(rightSource, 2);
+ FPRegisterID rReg = getFreeFPReg(leftSource, 4);
+ Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
+ Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
as->divDouble(rReg, lReg);
as->storeDouble(lReg, target);
diff --git a/src/qml/jit/qv4binop_p.h b/src/qml/jit/qv4binop_p.h
index 37601f54ba..3742e99e5a 100644
--- a/src/qml/jit/qv4binop_p.h
+++ b/src/qml/jit/qv4binop_p.h
@@ -67,13 +67,23 @@ struct Binop {
, op(operation)
{}
+ using Jump = Assembler::Jump;
+ using Address = Assembler::Address;
+ using RegisterID = Assembler::RegisterID;
+ using FPRegisterID = Assembler::FPRegisterID;
+ using TrustedImm32 = Assembler::TrustedImm32;
+ using ResultCondition = Assembler::ResultCondition;
+ using RelationalCondition = Assembler::RelationalCondition;
+ using Pointer = Assembler::Pointer;
+ using PointerToValue = Assembler::PointerToValue;
+
void generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target);
void doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target);
bool int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
- Assembler::Jump genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
+ Jump genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
- typedef Assembler::Jump (Binop::*MemRegOp)(Assembler::Address, Assembler::RegisterID);
- typedef Assembler::Jump (Binop::*ImmRegOp)(Assembler::TrustedImm32, Assembler::RegisterID);
+ typedef Jump (Binop::*MemRegOp)(Address, RegisterID);
+ typedef Jump (Binop::*ImmRegOp)(TrustedImm32, RegisterID);
struct OpInfo {
const char *name;
@@ -88,97 +98,97 @@ struct Binop {
static const OpInfo &operation(IR::AluOp operation)
{ return operations[operation]; }
- Assembler::Jump inline_add32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_add32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- return as->branchAdd32(Assembler::Overflow, addr, reg);
+ return as->branchAdd32(ResultCondition::Overflow, addr, reg);
#else
as->load32(addr, Assembler::ScratchRegister);
- return as->branchAdd32(Assembler::Overflow, Assembler::ScratchRegister, reg);
+ return as->branchAdd32(ResultCondition::Overflow, Assembler::ScratchRegister, reg);
#endif
}
- Assembler::Jump inline_add32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_add32(TrustedImm32 imm, RegisterID reg)
{
- return as->branchAdd32(Assembler::Overflow, imm, reg);
+ return as->branchAdd32(ResultCondition::Overflow, imm, reg);
}
- Assembler::Jump inline_sub32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_sub32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- return as->branchSub32(Assembler::Overflow, addr, reg);
+ return as->branchSub32(ResultCondition::Overflow, addr, reg);
#else
as->load32(addr, Assembler::ScratchRegister);
- return as->branchSub32(Assembler::Overflow, Assembler::ScratchRegister, reg);
+ return as->branchSub32(ResultCondition::Overflow, Assembler::ScratchRegister, reg);
#endif
}
- Assembler::Jump inline_sub32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_sub32(TrustedImm32 imm, RegisterID reg)
{
- return as->branchSub32(Assembler::Overflow, imm, reg);
+ return as->branchSub32(ResultCondition::Overflow, imm, reg);
}
- Assembler::Jump inline_mul32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_mul32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
return as->branchMul32(Assembler::Overflow, addr, reg);
#else
as->load32(addr, Assembler::ScratchRegister);
- return as->branchMul32(Assembler::Overflow, Assembler::ScratchRegister, reg);
+ return as->branchMul32(ResultCondition::Overflow, Assembler::ScratchRegister, reg);
#endif
}
- Assembler::Jump inline_mul32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_mul32(TrustedImm32 imm, RegisterID reg)
{
- return as->branchMul32(Assembler::Overflow, imm, reg, reg);
+ return as->branchMul32(ResultCondition::Overflow, imm, reg, reg);
}
- Assembler::Jump inline_shl32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_shl32(Address addr, RegisterID reg)
{
as->load32(addr, Assembler::ScratchRegister);
- as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister);
+ as->and32(TrustedImm32(0x1f), Assembler::ScratchRegister);
as->lshift32(Assembler::ScratchRegister, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_shl32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_shl32(TrustedImm32 imm, RegisterID reg)
{
imm.m_value &= 0x1f;
as->lshift32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_shr32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_shr32(Address addr, RegisterID reg)
{
as->load32(addr, Assembler::ScratchRegister);
- as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister);
+ as->and32(TrustedImm32(0x1f), Assembler::ScratchRegister);
as->rshift32(Assembler::ScratchRegister, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_shr32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_shr32(TrustedImm32 imm, RegisterID reg)
{
imm.m_value &= 0x1f;
as->rshift32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_ushr32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_ushr32(Address addr, RegisterID reg)
{
as->load32(addr, Assembler::ScratchRegister);
- as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister);
+ as->and32(TrustedImm32(0x1f), Assembler::ScratchRegister);
as->urshift32(Assembler::ScratchRegister, reg);
- return as->branchTest32(Assembler::Signed, reg, reg);
+ return as->branchTest32(ResultCondition::Signed, reg, reg);
}
- Assembler::Jump inline_ushr32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_ushr32(TrustedImm32 imm, RegisterID reg)
{
imm.m_value &= 0x1f;
as->urshift32(imm, reg);
- return as->branchTest32(Assembler::Signed, reg, reg);
+ return as->branchTest32(ResultCondition::Signed, reg, reg);
}
- Assembler::Jump inline_and32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_and32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
as->and32(addr, reg);
@@ -186,16 +196,16 @@ struct Binop {
as->load32(addr, Assembler::ScratchRegister);
as->and32(Assembler::ScratchRegister, reg);
#endif
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_and32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_and32(TrustedImm32 imm, RegisterID reg)
{
as->and32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_or32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_or32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
as->or32(addr, reg);
@@ -203,16 +213,16 @@ struct Binop {
as->load32(addr, Assembler::ScratchRegister);
as->or32(Assembler::ScratchRegister, reg);
#endif
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_or32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_or32(TrustedImm32 imm, RegisterID reg)
{
as->or32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_xor32(Assembler::Address addr, Assembler::RegisterID reg)
+ Jump inline_xor32(Address addr, RegisterID reg)
{
#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
as->xor32(addr, reg);
@@ -220,13 +230,13 @@ struct Binop {
as->load32(addr, Assembler::ScratchRegister);
as->xor32(Assembler::ScratchRegister, reg);
#endif
- return Assembler::Jump();
+ return Jump();
}
- Assembler::Jump inline_xor32(Assembler::TrustedImm32 imm, Assembler::RegisterID reg)
+ Jump inline_xor32(TrustedImm32 imm, RegisterID reg)
{
as->xor32(imm, reg);
- return Assembler::Jump();
+ return Jump();
}
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index c5d612ae65..279ccabf81 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -68,175 +68,6 @@ using namespace QV4;
using namespace QV4::JIT;
-namespace {
-class QIODevicePrintStream: public FilePrintStream
-{
- Q_DISABLE_COPY(QIODevicePrintStream)
-
-public:
- explicit QIODevicePrintStream(QIODevice *dest)
- : FilePrintStream(0)
- , dest(dest)
- , buf(4096, '0')
- {
- Q_ASSERT(dest);
- }
-
- ~QIODevicePrintStream()
- {}
-
- void vprintf(const char* format, va_list argList) WTF_ATTRIBUTE_PRINTF(2, 0)
- {
- const int written = qvsnprintf(buf.data(), buf.size(), format, argList);
- if (written > 0)
- dest->write(buf.constData(), written);
- memset(buf.data(), 0, qMin(written, buf.size()));
- }
-
- void flush()
- {}
-
-private:
- QIODevice *dest;
- QByteArray buf;
-};
-} // anonymous namespace
-
-static void printDisassembledOutputWithCalls(QByteArray processedOutput, const QHash<void*, const char*>& functions)
-{
- for (QHash<void*, const char*>::ConstIterator it = functions.begin(), end = functions.end();
- it != end; ++it) {
- const QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
- int idx = processedOutput.indexOf(ptrString);
- if (idx < 0)
- continue;
- idx = processedOutput.lastIndexOf('\n', idx);
- if (idx < 0)
- continue;
- processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; call ") + it.value());
- }
-
- qDebug("%s", processedOutput.constData());
-}
-
-#if defined(Q_OS_LINUX)
-static FILE *pmap;
-
-static void qt_closePmap()
-{
- if (pmap) {
- fclose(pmap);
- pmap = 0;
- }
-}
-
-#endif
-
-JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
-{
- Label endOfCode = label();
-
- {
- for (size_t i = 0, ei = _patches.size(); i != ei; ++i) {
- Label target = _addrs.at(i);
- Q_ASSERT(target.isSet());
- for (Jump jump : qAsConst(_patches.at(i)))
- jump.linkTo(target, this);
- }
- }
-
- JSC::JSGlobalData dummy(_executableAllocator);
- JSC::LinkBuffer linkBuffer(dummy, this, 0);
-
- for (const DataLabelPatch &p : qAsConst(_dataLabelPatches))
- linkBuffer.patch(p.dataLabel, linkBuffer.locationOf(p.target));
-
- // link exception handlers
- for (Jump jump : qAsConst(exceptionPropagationJumps))
- linkBuffer.link(jump, linkBuffer.locationOf(exceptionReturnLabel));
-
- {
- for (size_t i = 0, ei = _labelPatches.size(); i != ei; ++i) {
- Label target = _addrs.at(i);
- Q_ASSERT(target.isSet());
- for (DataLabelPtr label : _labelPatches.at(i))
- linkBuffer.patch(label, linkBuffer.locationOf(target));
- }
- }
-
- *codeSize = linkBuffer.offsetOf(endOfCode);
-
- QByteArray name;
-
- JSC::MacroAssemblerCodeRef codeRef;
-
- static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
- if (showCode) {
- QHash<void*, const char*> functions;
-#ifndef QT_NO_DEBUG
- for (CallInfo call : qAsConst(_callInfos))
- functions[linkBuffer.locationOf(call.label).dataLocation()] = call.functionName;
-#endif
-
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- WTF::setDataFile(new QIODevicePrintStream(&buf));
-
- name = _function->name->toUtf8();
- if (name.isEmpty())
- name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
- codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
-
- WTF::setDataFile(stderr);
- printDisassembledOutputWithCalls(buf.data(), functions);
- } else {
- codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
- }
-
-#if defined(Q_OS_LINUX)
- // This implements writing of JIT'd addresses so that perf can find the
- // symbol names.
- //
- // Perf expects the mapping to be in a certain place and have certain
- // content, for more information, see:
- // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
- static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
- static bool profileInitialized = false;
- if (doProfile && !profileInitialized) {
- profileInitialized = true;
-
- char pname[PATH_MAX];
- snprintf(pname, PATH_MAX - 1, "/tmp/perf-%lu.map",
- (unsigned long)QCoreApplication::applicationPid());
-
- pmap = fopen(pname, "w");
- if (!pmap)
- qWarning("QV4: Can't write %s, call stacks will not contain JavaScript function names", pname);
-
- // make sure we clean up nicely
- std::atexit(qt_closePmap);
- }
-
- if (pmap) {
- // this may have been pre-populated, if QV4_SHOW_ASM was on
- if (name.isEmpty()) {
- name = _function->name->toUtf8();
- if (name.isEmpty())
- name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
- }
-
- fprintf(pmap, "%llx %x %.*s\n",
- (long long unsigned int)codeRef.code().executableAddress(),
- *codeSize,
- name.length(),
- name.constData());
- fflush(pmap);
- }
-#endif
-
- return codeRef;
-}
-
InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory)
: EvalInstructionSelection(execAllocator, module, jsGenerator, iselFactory)
, _block(0)
@@ -278,7 +109,7 @@ void InstructionSelection::run(int functionIndex)
qSwap(_removableJumps, removableJumps);
Assembler* oldAssembler = _as;
- _as = new Assembler(this, _function, executableAllocator);
+ _as = new Assembler(jsGenerator, _function, executableAllocator);
_as->setStackLayout(6, // 6 == max argc for calls to built-ins with an argument array
regularRegistersToSave.size(),
fpRegistersToSave.size());
@@ -1881,6 +1712,13 @@ bool InstructionSelection::visitCJumpStrictBool(IR::Binop *binop, IR::BasicBlock
// neither operands are statically typed as bool, so bail out.
return false;
}
+ if (otherSrc->type == IR::UnknownType) {
+ // Ok, we really need to call into the runtime.
+ // (This case doesn't happen when the optimizer ran, because everything will be typed (yes,
+ // possibly as "var" meaning anything), but it does happen for $0===true, which is generated
+ // for things where the optimizer didn't run (like functions with a try block).)
+ return false;
+ }
Assembler::RelationalCondition cond = binop->op == IR::OpStrictEqual ? Assembler::Equal
: Assembler::NotEqual;
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index 63d542b5c8..f2ae7e117a 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -973,7 +973,15 @@ private:
break;
Q_ASSERT(!i->isFixedInterval());
- _liveIntervals.push_back(i);
+ auto it = _liveIntervals.begin();
+ for (; it != _liveIntervals.end(); ++it) {
+ if ((*it)->temp() == i->temp()) {
+ *it = i;
+ break;
+ }
+ }
+ if (it == _liveIntervals.end())
+ _liveIntervals.push_back(i);
// qDebug() << "-- Activating interval for temp" << i->temp().index;
_unprocessedReverseOrder.removeLast();
@@ -1087,12 +1095,12 @@ private:
if (_info->def(it->temp()) != successorStart && !it->isSplitFromInterval()) {
const int successorEnd = successor->terminator()->id();
const int idx = successor->in.indexOf(predecessor);
- foreach (const Use &use, _info->uses(it->temp())) {
+ for (const Use &use : _info->uses(it->temp)) {
if (use.pos == static_cast<unsigned>(successorStart)) {
// only check the current edge, not all other possible ones. This is
// important for phi nodes: they have uses that are only valid when
// coming in over a specific edge.
- foreach (Stmt *s, successor->statements()) {
+ for (Stmt *s : successor->statements()) {
if (Phi *phi = s->asPhi()) {
Q_ASSERT(it->temp().index != phi->targetTemp->index);
Q_ASSERT(phi->d->incoming[idx]->asTemp() == 0
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index b473e96286..bab2e633a7 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -73,7 +73,8 @@
For the object-based types (including Date and RegExp), use the
newT() functions in QJSEngine (e.g. QJSEngine::newObject())
to create a QJSValue of the desired type. For the primitive types,
- use one of the QJSValue constructor overloads.
+ use one of the QJSValue constructor overloads. For other types, e.g.
+ registered gadget types such as QPoint, you can use QJSEngine::toScriptValue.
The methods named isT() (e.g. isBool(), isUndefined()) can be
used to test if a value is of a certain type. The methods named
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 5a190d6690..9354bcb1a3 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -88,10 +88,12 @@ void ArgumentsObject::fullyCreate()
Scope scope(engine());
Scoped<MemberData> md(scope, d()->mappedArguments);
- d()->mappedArguments = md->allocate(engine(), numAccessors);
- for (uint i = 0; i < numAccessors; ++i) {
- d()->mappedArguments->data[i] = context()->callData->args[i];
- arraySet(i, context()->engine->argumentsAccessors + i, Attr_Accessor);
+ if (numAccessors) {
+ d()->mappedArguments = md->allocate(engine(), numAccessors);
+ for (uint i = 0; i < numAccessors; ++i) {
+ d()->mappedArguments->data[i] = context()->callData->args[i];
+ arraySet(i, context()->engine->argumentsAccessors + i, Attr_Accessor);
+ }
}
arrayPut(numAccessors, context()->callData->args + numAccessors, argCount - numAccessors);
for (uint i = numAccessors; i < argCount; ++i)
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index 23075aa78c..ffe9aa846f 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -81,16 +81,19 @@ void ArrayBufferCtor::call(const Managed *that, Scope &scope, CallData *callData
construct(that, scope, callData);
}
-ReturnedValue ArrayBufferCtor::method_isView(CallContext *ctx)
+void ArrayBufferCtor::method_isView(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<TypedArray> a(scope, ctx->argument(0));
- if (!!a)
- return Encode(true);
- QV4::Scoped<DataView> v(scope, ctx->argument(0));
- if (!!v)
- return Encode(true);
- return Encode(false);
+ QV4::Scoped<TypedArray> a(scope, callData->argument(0));
+ if (!!a) {
+ scope.result = Encode(true);
+ return;
+ }
+ QV4::Scoped<DataView> v(scope, callData->argument(0));
+ if (!!v) {
+ scope.result = Encode(true);
+ return;
+ }
+ scope.result = Encode(false);
}
@@ -160,54 +163,48 @@ void ArrayBufferPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("toString"), method_toString, 0);
}
-ReturnedValue ArrayBufferPrototype::method_get_byteLength(CallContext *ctx)
+void ArrayBufferPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<ArrayBuffer> v(scope, ctx->thisObject());
+ Scoped<ArrayBuffer> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->data->size);
+ scope.result = Encode(v->d()->data->size);
}
-ReturnedValue ArrayBufferPrototype::method_slice(CallContext *ctx)
+void ArrayBufferPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<ArrayBuffer> a(scope, ctx->thisObject());
+ Scoped<ArrayBuffer> a(scope, callData->thisObject);
if (!a)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- double start = ctx->argc() > 0 ? ctx->args()[0].toInteger() : 0;
- double end = (ctx->argc() < 2 || ctx->args()[1].isUndefined()) ?
- a->d()->data->size : ctx->args()[1].toInteger();
- if (scope.engine->hasException)
- return Encode::undefined();
+ double start = callData->argc > 0 ? callData->args[0].toInteger() : 0;
+ double end = (callData->argc < 2 || callData->args[1].isUndefined()) ?
+ a->d()->data->size : callData->args[1].toInteger();
+ CHECK_EXCEPTION();
double first = (start < 0) ? qMax(a->d()->data->size + start, 0.) : qMin(start, (double)a->d()->data->size);
double final = (end < 0) ? qMax(a->d()->data->size + end, 0.) : qMin(end, (double)a->d()->data->size);
ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor()));
if (!constructor)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 1);
+ ScopedCallData cData(scope, 1);
double newLen = qMax(final - first, 0.);
- callData->args[0] = QV4::Encode(newLen);
- constructor->construct(scope, callData);
- QV4::Scoped<ArrayBuffer> newBuffer(scope, scope.result.asReturnedValue());
+ cData->args[0] = QV4::Encode(newLen);
+ constructor->construct(scope, cData);
+ QV4::Scoped<ArrayBuffer> newBuffer(scope, scope.result);
if (!newBuffer || newBuffer->d()->data->size < (int)newLen)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen);
-
- return newBuffer.asReturnedValue();
}
-ReturnedValue ArrayBufferPrototype::method_toString(CallContext *ctx)
+void ArrayBufferPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<ArrayBuffer> a(scope, ctx->thisObject());
+ Scoped<ArrayBuffer> a(scope, callData->thisObject);
if (!a)
- return Encode::undefined();
- return Encode(ctx->engine()->newString(QString::fromUtf8(a->asByteArray())));
+ RETURN_UNDEFINED();
+ scope.result = scope.engine->newString(QString::fromUtf8(a->asByteArray()));
}
diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h
index bc56d1ea31..4f7926d3dc 100644
--- a/src/qml/jsruntime/qv4arraybuffer_p.h
+++ b/src/qml/jsruntime/qv4arraybuffer_p.h
@@ -81,7 +81,7 @@ struct ArrayBufferCtor: FunctionObject
static void construct(const Managed *m, Scope &scope, CallData *callData);
static void call(const Managed *that, Scope &scope, CallData *callData);
- static ReturnedValue method_isView(CallContext *ctx);
+ static void method_isView(const BuiltinFunction *, Scope &scope, CallData *callData);
};
@@ -104,9 +104,9 @@ struct ArrayBufferPrototype: Object
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_get_byteLength(CallContext *ctx);
- static ReturnedValue method_slice(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
+ static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_slice(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index bfeb3d4699..d8a7de5466 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -237,8 +237,14 @@ void ArrayData::ensureAttributes(Object *o)
void SimpleArrayData::markObjects(Heap::Base *d, ExecutionEngine *e)
{
Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(d);
- for (uint i = 0; i < dd->len; ++i)
- dd->arrayData[dd->mappedIndex(i)].mark(e);
+ uint end = dd->offset + dd->len;
+ if (end > dd->alloc) {
+ for (uint i = 0; i < end - dd->alloc; ++i)
+ dd->arrayData[i].mark(e);
+ end = dd->alloc;
+ }
+ for (uint i = dd->offset; i < end; ++i)
+ dd->arrayData[i].mark(e);
}
ReturnedValue SimpleArrayData::get(const Heap::ArrayData *d, uint index)
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 20ba11fd75..759354f4e2 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -44,6 +44,7 @@
#include "qv4argumentsobject_p.h"
#include "qv4runtime_p.h"
#include "qv4string_p.h"
+#include <QtCore/qscopedvaluerollback.h>
using namespace QV4;
@@ -118,42 +119,40 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("reduceRight"), method_reduceRight, 1);
}
-ReturnedValue ArrayPrototype::method_isArray(CallContext *ctx)
+void ArrayPrototype::method_isArray(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- bool isArray = ctx->argc() && ctx->args()[0].as<ArrayObject>();
- return Encode(isArray);
+ bool isArray = callData->argc && callData->args[0].as<ArrayObject>();
+ scope.result = Encode(isArray);
}
-ReturnedValue ArrayPrototype::method_toString(CallContext *ctx)
+void ArrayPrototype::method_toString(const BuiltinFunction *builtin, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject(), ScopedObject::Convert);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
- ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("join")));
+ ScopedObject o(scope, callData->thisObject, ScopedObject::Convert);
+ CHECK_EXCEPTION();
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("join")));
ScopedFunctionObject f(scope, o->get(s));
if (!!f) {
ScopedCallData d(scope, 0);
- d->thisObject = ctx->thisObject();
+ d->thisObject = callData->thisObject;
f->call(scope, d);
- return scope.result.asReturnedValue();
+ return;
}
- return ObjectPrototype::method_toString(ctx);
+ ObjectPrototype::method_toString(builtin, scope, callData);
}
-ReturnedValue ArrayPrototype::method_toLocaleString(CallContext *ctx)
+void ArrayPrototype::method_toLocaleString(const BuiltinFunction *builtin, Scope &scope, CallData *callData)
{
- return method_toString(ctx);
+ return method_toString(builtin, scope, callData);
}
-ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
+void ArrayPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject result(scope, ctx->d()->engine->newArrayObject());
-
- ScopedObject thisObject(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject thisObject(scope, callData->thisObject.toObject(scope.engine));
if (!thisObject)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
+ ScopedArrayObject result(scope, scope.engine->newArrayObject());
+
if (thisObject->isArrayObject()) {
result->copyArrayData(thisObject);
} else {
@@ -163,9 +162,9 @@ ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
ScopedArrayObject elt(scope);
ScopedObject eltAsObj(scope);
ScopedValue entry(scope);
- for (int i = 0; i < ctx->argc(); ++i) {
- eltAsObj = ctx->args()[i];
- elt = ctx->args()[i];
+ for (int i = 0; i < callData->argc; ++i) {
+ eltAsObj = callData->args[i];
+ elt = callData->args[i];
if (elt) {
uint n = elt->getLength();
uint newLen = ArrayData::append(result, elt, n);
@@ -177,95 +176,90 @@ ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
result->putIndexed(startIndex + i, entry);
}
} else {
- result->arraySet(result->getLength(), ctx->args()[i]);
+ result->arraySet(result->getLength(), callData->args[i]);
}
}
- return result.asReturnedValue();
+ scope.result = result;
}
-ReturnedValue ArrayPrototype::method_find(CallContext *ctx)
+void ArrayPrototype::method_find(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
v = instance->getIndexed(k);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
- if (scope.hasException())
- return Encode::undefined();
- else if (scope.result.toBoolean())
- return v->asReturnedValue();
+ CHECK_EXCEPTION();
+ if (scope.result.toBoolean())
+ RETURN_RESULT(v);
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue ArrayPrototype::method_findIndex(CallContext *ctx)
+void ArrayPrototype::method_findIndex(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
v = instance->getIndexed(k);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
- if (scope.hasException())
- return Encode::undefined();
- else if (scope.result.toBoolean())
- return Encode(k);
+ CHECK_EXCEPTION();
+ if (scope.result.toBoolean())
+ RETURN_RESULT(Encode(k));
}
- return Encode(-1);
+ RETURN_RESULT(Encode(-1));
}
-ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
+void ArrayPrototype::method_join(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue arg(scope, ctx->argument(0));
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedValue arg(scope, callData->argument(0));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
- if (!instance)
- return ctx->d()->engine->newString()->asReturnedValue();
+ if (!instance) {
+ scope.result = scope.engine->newString();
+ return;
+ }
QString r4;
if (arg->isUndefined())
@@ -273,11 +267,13 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
else
r4 = arg->toQString();
- ScopedValue length(scope, instance->get(ctx->d()->engine->id_length()));
+ ScopedValue length(scope, instance->get(scope.engine->id_length()));
const quint32 r2 = length->isUndefined() ? 0 : length->toUInt32();
- if (!r2)
- return ctx->d()->engine->newString()->asReturnedValue();
+ if (!r2) {
+ scope.result = scope.engine->newString();
+ return;
+ }
QString R;
@@ -289,8 +285,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
R += r4;
e = a->getIndexed(i);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (!e->isNullOrUndefined())
R += e->toQString();
}
@@ -298,7 +293,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
//
// crazy!
//
- ScopedString name(scope, ctx->d()->engine->newString(QStringLiteral("0")));
+ ScopedString name(scope, scope.engine->newString(QStringLiteral("0")));
ScopedValue r6(scope, instance->get(name));
if (!r6->isNullOrUndefined())
R = r6->toQString();
@@ -309,99 +304,98 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
name = Primitive::fromDouble(k).toString(scope.engine);
r12 = instance->get(name);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (!r12->isNullOrUndefined())
R += r12->toQString();
}
}
- return ctx->d()->engine->newString(R)->asReturnedValue();
+ scope.result = scope.engine->newString(R);
}
-ReturnedValue ArrayPrototype::method_pop(CallContext *ctx)
+void ArrayPrototype::method_pop(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint len = instance->getLength();
if (!len) {
if (!instance->isArrayObject())
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0)));
- return Encode::undefined();
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0)));
+ RETURN_UNDEFINED();
}
ScopedValue result(scope, instance->getIndexed(len - 1));
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
instance->deleteIndexedProperty(len - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
+
if (instance->isArrayObject())
instance->setArrayLength(len - 1);
else
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
- return result->asReturnedValue();
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
+ scope.result = result;
}
-ReturnedValue ArrayPrototype::method_push(CallContext *ctx)
+void ArrayPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
instance->arrayCreate();
Q_ASSERT(instance->arrayData());
uint len = instance->getLength();
- if (len + ctx->argc() < len) {
+ if (len + callData->argc < len) {
// ughh...
double l = len;
ScopedString s(scope);
- for (int i = 0; i < ctx->argc(); ++i) {
+ for (int i = 0; i < callData->argc; ++i) {
s = Primitive::fromDouble(l + i).toString(scope.engine);
- instance->put(s, ctx->args()[i]);
+ instance->put(s, callData->args[i]);
}
- double newLen = l + ctx->argc();
+ double newLen = l + callData->argc;
if (!instance->isArrayObject())
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
else {
- ScopedString str(scope, ctx->d()->engine->newString(QStringLiteral("Array.prototype.push: Overflow")));
- return ctx->engine()->throwRangeError(str);
+ ScopedString str(scope, scope.engine->newString(QStringLiteral("Array.prototype.push: Overflow")));
+ scope.result = scope.engine->throwRangeError(str);
+ return;
}
- return Encode(newLen);
+ scope.result = Encode(newLen);
+ return;
}
- if (!ctx->argc())
+ if (!callData->argc)
;
else if (!instance->protoHasArray() && instance->arrayData()->length() <= len && instance->arrayData()->type == Heap::ArrayData::Simple) {
- instance->arrayData()->vtable()->putArray(instance, len, ctx->args(), ctx->argc());
+ instance->arrayData()->vtable()->putArray(instance, len, callData->args, callData->argc);
len = instance->arrayData()->length();
} else {
- for (int i = 0; i < ctx->argc(); ++i)
- instance->putIndexed(len + i, ctx->args()[i]);
- len += ctx->argc();
+ for (int i = 0; i < callData->argc; ++i)
+ instance->putIndexed(len + i, callData->args[i]);
+ len += callData->argc;
}
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(len);
else
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len)));
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len)));
- return Encode(len);
+ scope.result = Encode(len);
}
-ReturnedValue ArrayPrototype::method_reverse(CallContext *ctx)
+void ArrayPrototype::method_reverse(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint length = instance->getLength();
int lo = 0, hi = length - 1;
@@ -412,28 +406,25 @@ ReturnedValue ArrayPrototype::method_reverse(CallContext *ctx)
bool loExists, hiExists;
lval = instance->getIndexed(lo, &loExists);
hval = instance->getIndexed(hi, &hiExists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (hiExists)
instance->putIndexed(lo, hval);
else
instance->deleteIndexedProperty(lo);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (loExists)
instance->putIndexed(hi, lval);
else
instance->deleteIndexedProperty(hi);
}
- return instance.asReturnedValue();
+ scope.result = instance;
}
-ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
+void ArrayPrototype::method_shift(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
instance->arrayCreate();
Q_ASSERT(instance->arrayData());
@@ -442,54 +433,46 @@ ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
if (!len) {
if (!instance->isArrayObject())
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0)));
- return Encode::undefined();
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0)));
+ RETURN_UNDEFINED();
}
- ScopedValue result(scope);
-
if (!instance->protoHasArray() && !instance->arrayData()->attrs && instance->arrayData()->length() <= len && instance->arrayData()->type != Heap::ArrayData::Custom) {
- result = instance->arrayData()->vtable()->pop_front(instance);
+ scope.result = instance->arrayData()->vtable()->pop_front(instance);
} else {
- result = instance->getIndexed(0);
- if (scope.hasException())
- return Encode::undefined();
+ scope.result = instance->getIndexed(0);
+ CHECK_EXCEPTION();
ScopedValue v(scope);
// do it the slow way
for (uint k = 1; k < len; ++k) {
bool exists;
v = instance->getIndexed(k, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
instance->putIndexed(k - 1, v);
else
instance->deleteIndexedProperty(k - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
}
instance->deleteIndexedProperty(len - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
}
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(len - 1);
else
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
- return result->asReturnedValue();
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
}
-ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
+void ArrayPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject o(scope, callData->thisObject.toObject(scope.engine));
if (!o)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- ScopedArrayObject result(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject result(scope, scope.engine->newArrayObject());
uint len = o->getLength();
- double s = ScopedValue(scope, ctx->argument(0))->toInteger();
+ double s = ScopedValue(scope, callData->argument(0))->toInteger();
uint start;
if (s < 0)
start = (uint)qMax(len + s, 0.);
@@ -498,8 +481,8 @@ ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
else
start = (uint) s;
uint end = len;
- if (ctx->argc() > 1 && !ctx->args()[1].isUndefined()) {
- double e = ctx->args()[1].toInteger();
+ if (callData->argc > 1 && !callData->args[1].isUndefined()) {
+ double e = callData->args[1].toInteger();
if (e < 0)
end = (uint)qMax(len + e, 0.);
else if (e > len)
@@ -513,115 +496,107 @@ ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
for (uint i = start; i < end; ++i) {
bool exists;
v = o->getIndexed(i, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
result->arraySet(n, v);
++n;
}
- return result.asReturnedValue();
+ scope.result = result;
}
-ReturnedValue ArrayPrototype::method_sort(CallContext *ctx)
+void ArrayPrototype::method_sort(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedValue comparefn(scope, ctx->argument(0));
+ ScopedValue comparefn(scope, callData->argument(0));
ArrayData::sort(scope.engine, instance, comparefn, len);
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
-ReturnedValue ArrayPrototype::method_splice(CallContext *ctx)
+void ArrayPrototype::method_splice(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint len = instance->getLength();
- ScopedArrayObject newArray(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject newArray(scope, scope.engine->newArrayObject());
- double rs = ScopedValue(scope, ctx->argument(0))->toInteger();
+ double rs = ScopedValue(scope, callData->argument(0))->toInteger();
uint start;
if (rs < 0)
start = (uint) qMax(0., len + rs);
else
start = (uint) qMin(rs, (double)len);
- uint deleteCount = (uint)qMin(qMax(ScopedValue(scope, ctx->argument(1))->toInteger(), 0.), (double)(len - start));
+ uint deleteCount = (uint)qMin(qMax(ScopedValue(scope, callData->argument(1))->toInteger(), 0.), (double)(len - start));
newArray->arrayReserve(deleteCount);
ScopedValue v(scope);
for (uint i = 0; i < deleteCount; ++i) {
bool exists;
v = instance->getIndexed(start + i, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
newArray->arrayPut(i, v);
}
newArray->setArrayLengthUnchecked(deleteCount);
- uint itemCount = ctx->argc() < 2 ? 0 : ctx->argc() - 2;
+ uint itemCount = callData->argc < 2 ? 0 : callData->argc - 2;
if (itemCount < deleteCount) {
for (uint k = start; k < len - deleteCount; ++k) {
bool exists;
v = instance->getIndexed(k + deleteCount, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
instance->putIndexed(k + itemCount, v);
else
instance->deleteIndexedProperty(k + itemCount);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
}
for (uint k = len; k > len - deleteCount + itemCount; --k) {
instance->deleteIndexedProperty(k - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
}
} else if (itemCount > deleteCount) {
uint k = len - deleteCount;
while (k > start) {
bool exists;
v = instance->getIndexed(k + deleteCount - 1, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
instance->putIndexed(k + itemCount - 1, v);
else
instance->deleteIndexedProperty(k + itemCount - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
--k;
}
}
for (uint i = 0; i < itemCount; ++i) {
- instance->putIndexed(start + i, ctx->args()[i + 2]);
- if (scope.hasException())
- return Encode::undefined();
+ instance->putIndexed(start + i, callData->args[i + 2]);
+ CHECK_EXCEPTION();
}
- ctx->d()->strictMode = true;
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount)));
+ bool wasStrict = scope.engine->current->strictMode;
+ scope.engine->current->strictMode = true;
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount)));
- return newArray.asReturnedValue();
+ scope.result = newArray;
+ scope.engine->current->strictMode = wasStrict;
}
-ReturnedValue ArrayPrototype::method_unshift(CallContext *ctx)
+void ArrayPrototype::method_unshift(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
instance->arrayCreate();
Q_ASSERT(instance->arrayData());
@@ -630,50 +605,52 @@ ReturnedValue ArrayPrototype::method_unshift(CallContext *ctx)
if (!instance->protoHasArray() && !instance->arrayData()->attrs && instance->arrayData()->length() <= len &&
instance->arrayData()->type != Heap::ArrayData::Custom) {
- instance->arrayData()->vtable()->push_front(instance, ctx->args(), ctx->argc());
+ instance->arrayData()->vtable()->push_front(instance, callData->args, callData->argc);
} else {
ScopedValue v(scope);
for (uint k = len; k > 0; --k) {
bool exists;
v = instance->getIndexed(k - 1, &exists);
if (exists)
- instance->putIndexed(k + ctx->argc() - 1, v);
+ instance->putIndexed(k + callData->argc - 1, v);
else
- instance->deleteIndexedProperty(k + ctx->argc() - 1);
+ instance->deleteIndexedProperty(k + callData->argc - 1);
}
- for (int i = 0; i < ctx->argc(); ++i)
- instance->putIndexed(i, ctx->args()[i]);
+ for (int i = 0; i < callData->argc; ++i)
+ instance->putIndexed(i, callData->args[i]);
}
- uint newLen = len + ctx->argc();
+ uint newLen = len + callData->argc;
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(newLen);
else
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
- return Encode(newLen);
+ scope.result = Encode(newLen);
}
-ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
+void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint len = instance->getLength();
- if (!len)
- return Encode(-1);
+ if (!len) {
+ scope.result = Encode(-1);
+ return;
+ }
- ScopedValue searchValue(scope, ctx->argument(0));
+ ScopedValue searchValue(scope, callData->argument(0));
uint fromIndex = 0;
- if (ctx->argc() >= 2) {
- double f = ctx->args()[1].toInteger();
- if (scope.hasException())
- return Encode::undefined();
- if (f >= len)
- return Encode(-1);
+ if (callData->argc >= 2) {
+ double f = callData->args[1].toInteger();
+ CHECK_EXCEPTION();
+ if (f >= len) {
+ scope.result = Encode(-1);
+ return;
+ }
if (f < 0)
f = qMax(len + f, 0.);
fromIndex = (uint) f;
@@ -684,10 +661,13 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
for (uint k = fromIndex; k < len; ++k) {
bool exists;
v = instance->getIndexed(k, &exists);
- if (exists && RuntimeHelpers::strictEqual(v, searchValue))
- return Encode(k);
+ if (exists && RuntimeHelpers::strictEqual(v, searchValue)) {
+ scope.result = Encode(k);
+ return;
+ }
}
- return Encode(-1);
+ scope.result = Encode(-1);
+ return;
}
ScopedValue value(scope);
@@ -698,13 +678,15 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
for (uint i = fromIndex; i < len; ++i) {
bool exists;
value = instance->getIndexed(i, &exists);
- if (scope.hasException())
- return Encode::undefined();
- if (exists && RuntimeHelpers::strictEqual(value, searchValue))
- return Encode(i);
+ CHECK_EXCEPTION();
+ if (exists && RuntimeHelpers::strictEqual(value, searchValue)) {
+ scope.result = Encode(i);
+ return;
+ }
}
} else if (!instance->arrayData()) {
- return Encode(-1);
+ scope.result = Encode(-1);
+ return;
} else {
Q_ASSERT(instance->arrayType() == Heap::ArrayData::Simple || instance->arrayType() == Heap::ArrayData::Complex);
Heap::SimpleArrayData *sa = instance->d()->arrayData.cast<Heap::SimpleArrayData>();
@@ -713,45 +695,48 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
uint idx = fromIndex;
while (idx < len) {
value = sa->data(idx);
- if (scope.hasException())
- return Encode::undefined();
- if (RuntimeHelpers::strictEqual(value, searchValue))
- return Encode(idx);
+ CHECK_EXCEPTION();
+ if (RuntimeHelpers::strictEqual(value, searchValue)) {
+ scope.result = Encode(idx);
+ return;
+ }
++idx;
}
}
- return Encode(-1);
+ scope.result = Encode(-1);
}
-ReturnedValue ArrayPrototype::method_lastIndexOf(CallContext *ctx)
+void ArrayPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint len = instance->getLength();
- if (!len)
- return Encode(-1);
+ if (!len) {
+ scope.result = Encode(-1);
+ return;
+ }
ScopedValue searchValue(scope);
uint fromIndex = len;
- if (ctx->argc() >= 1)
- searchValue = ctx->argument(0);
+ if (callData->argc >= 1)
+ searchValue = callData->argument(0);
else
searchValue = Primitive::undefinedValue();
- if (ctx->argc() >= 2) {
- double f = ctx->args()[1].toInteger();
- if (scope.hasException())
- return Encode::undefined();
+ if (callData->argc >= 2) {
+ double f = callData->args[1].toInteger();
+ CHECK_EXCEPTION();
if (f > 0)
f = qMin(f, (double)(len - 1));
else if (f < 0) {
f = len + f;
- if (f < 0)
- return Encode(-1);
+ if (f < 0) {
+ scope.result = Encode(-1);
+ return;
+ }
}
fromIndex = (uint) f + 1;
}
@@ -761,30 +746,30 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(CallContext *ctx)
--k;
bool exists;
v = instance->getIndexed(k, &exists);
- if (scope.hasException())
- return Encode::undefined();
- if (exists && RuntimeHelpers::strictEqual(v, searchValue))
- return Encode(k);
+ CHECK_EXCEPTION();
+ if (exists && RuntimeHelpers::strictEqual(v, searchValue)) {
+ scope.result = Encode(k);
+ return;
+ }
}
- return Encode(-1);
+ scope.result = Encode(-1);
}
-ReturnedValue ArrayPrototype::method_every(CallContext *ctx)
+void ArrayPrototype::method_every(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->args[2] = instance;
- callData->thisObject = ctx->argument(1);
+ ScopedCallData cData(scope, 3);
+ cData->args[2] = instance;
+ cData->thisObject = callData->argument(1);
ScopedValue v(scope);
bool ok = true;
@@ -794,30 +779,29 @@ ReturnedValue ArrayPrototype::method_every(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
ok = scope.result.toBoolean();
}
- return Encode(ok);
+ scope.result = Encode(ok);
}
-ReturnedValue ArrayPrototype::method_some(CallContext *ctx)
+void ArrayPrototype::method_some(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -826,31 +810,32 @@ ReturnedValue ArrayPrototype::method_some(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
- if (scope.result.toBoolean())
- return Encode(true);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
+ if (scope.result.toBoolean()) {
+ scope.result = Encode(true);
+ return;
+ }
}
- return Encode(false);
+ scope.result = Encode(false);
}
-ReturnedValue ArrayPrototype::method_forEach(CallContext *ctx)
+void ArrayPrototype::method_forEach(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -859,33 +844,32 @@ ReturnedValue ArrayPrototype::method_forEach(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue ArrayPrototype::method_map(CallContext *ctx)
+void ArrayPrototype::method_map(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedArrayObject a(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject a(scope, scope.engine->newArrayObject());
a->arrayReserve(len);
a->setArrayLengthUnchecked(len);
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -894,33 +878,32 @@ ReturnedValue ArrayPrototype::method_map(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
a->arraySet(k, scope.result);
}
- return a.asReturnedValue();
+ scope.result = a.asReturnedValue();
}
-ReturnedValue ArrayPrototype::method_filter(CallContext *ctx)
+void ArrayPrototype::method_filter(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedArrayObject a(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject a(scope, scope.engine->newArrayObject());
a->arrayReserve(len);
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
@@ -931,35 +914,34 @@ ReturnedValue ArrayPrototype::method_filter(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
if (scope.result.toBoolean()) {
a->arraySet(to, v);
++to;
}
}
- return a.asReturnedValue();
+ scope.result = a.asReturnedValue();
}
-ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
+void ArrayPrototype::method_reduce(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
uint k = 0;
ScopedValue v(scope);
- if (ctx->argc() > 1) {
- scope.result = ctx->argument(1);
+ if (callData->argc > 1) {
+ scope.result = callData->argument(1);
} else {
bool kPresent = false;
while (k < len && !kPresent) {
@@ -969,51 +951,50 @@ ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
++k;
}
if (!kPresent)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
}
- ScopedCallData callData(scope, 4);
- callData->thisObject = Primitive::undefinedValue();
- callData->args[0] = scope.result;
- callData->args[3] = instance;
+ ScopedCallData cData(scope, 4);
+ cData->thisObject = Primitive::undefinedValue();
+ cData->args[0] = scope.result;
+ cData->args[3] = instance;
while (k < len) {
bool kPresent;
v = instance->getIndexed(k, &kPresent);
if (kPresent) {
- callData->args[0] = scope.result;
- callData->args[1] = v;
- callData->args[2] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = scope.result;
+ cData->args[1] = v;
+ cData->args[2] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
}
++k;
}
- return scope.result.asReturnedValue();
}
-ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
+void ArrayPrototype::method_reduceRight(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (len == 0) {
- if (ctx->argc() == 1)
- return ctx->engine()->throwTypeError();
- return ctx->argument(1);
+ if (callData->argc == 1)
+ THROW_TYPE_ERROR();
+ scope.result = callData->argument(1);
+ return;
}
uint k = len;
ScopedValue v(scope);
- if (ctx->argc() > 1) {
- scope.result = ctx->argument(1);
+ if (callData->argc > 1) {
+ scope.result = callData->argument(1);
} else {
bool kPresent = false;
while (k > 0 && !kPresent) {
@@ -1023,24 +1004,24 @@ ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
--k;
}
if (!kPresent)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
}
- ScopedCallData callData(scope, 4);
- callData->thisObject = Primitive::undefinedValue();
- callData->args[3] = instance;
+ ScopedCallData cData(scope, 4);
+ cData->thisObject = Primitive::undefinedValue();
+ cData->args[3] = instance;
while (k > 0) {
bool kPresent;
v = instance->getIndexed(k - 1, &kPresent);
if (kPresent) {
- callData->args[0] = scope.result;
- callData->args[1] = v;
- callData->args[2] = Primitive::fromDouble(k - 1);
- callback->call(scope, callData);
+ cData->args[0] = scope.result;
+ cData->args[1] = v;
+ cData->args[2] = Primitive::fromDouble(k - 1);
+ callback->call(scope, cData);
}
--k;
}
- return scope.result.asReturnedValue();
+ scope.result = scope.result.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index f00c0c0249..689752433b 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -78,30 +78,30 @@ struct ArrayPrototype: ArrayObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_isArray(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_toLocaleString(CallContext *ctx);
- static ReturnedValue method_concat(CallContext *ctx);
- static ReturnedValue method_find(CallContext *ctx);
- static ReturnedValue method_findIndex(CallContext *ctx);
- static ReturnedValue method_join(CallContext *ctx);
- static ReturnedValue method_pop(CallContext *ctx);
- static ReturnedValue method_push(CallContext *ctx);
- static ReturnedValue method_reverse(CallContext *ctx);
- static ReturnedValue method_shift(CallContext *ctx);
- static ReturnedValue method_slice(CallContext *ctx);
- static ReturnedValue method_sort(CallContext *ctx);
- static ReturnedValue method_splice(CallContext *ctx);
- static ReturnedValue method_unshift(CallContext *ctx);
- static ReturnedValue method_indexOf(CallContext *ctx);
- static ReturnedValue method_lastIndexOf(CallContext *ctx);
- static ReturnedValue method_every(CallContext *ctx);
- static ReturnedValue method_some(CallContext *ctx);
- static ReturnedValue method_forEach(CallContext *ctx);
- static ReturnedValue method_map(CallContext *ctx);
- static ReturnedValue method_filter(CallContext *ctx);
- static ReturnedValue method_reduce(CallContext *ctx);
- static ReturnedValue method_reduceRight(CallContext *ctx);
+ static void method_isArray(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_toLocaleString(const BuiltinFunction *builtin, Scope &, CallData *callData);
+ static void method_concat(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_find(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_findIndex(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_join(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_pop(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_push(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_reverse(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_shift(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_slice(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_sort(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_splice(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_unshift(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_indexOf(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_lastIndexOf(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_every(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_some(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_forEach(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_map(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_filter(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_reduce(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_reduceRight(const BuiltinFunction *, Scope &, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index 8047993266..601066110f 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -73,29 +73,31 @@ void BooleanPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(engine->id_valueOf(), method_valueOf);
}
-ReturnedValue BooleanPrototype::method_toString(CallContext *ctx)
+void BooleanPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
bool result;
- if (ctx->thisObject().isBoolean()) {
- result = ctx->thisObject().booleanValue();
+ if (callData->thisObject.isBoolean()) {
+ result = callData->thisObject.booleanValue();
} else {
- const BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>();
+ const BooleanObject *thisObject = callData->thisObject.as<BooleanObject>();
if (!thisObject)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
result = thisObject->value();
}
- return Encode(ctx->d()->engine->newString(QLatin1String(result ? "true" : "false")));
+ scope.result = scope.engine->newString(QLatin1String(result ? "true" : "false"));
}
-ReturnedValue BooleanPrototype::method_valueOf(CallContext *ctx)
+void BooleanPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->thisObject().isBoolean())
- return ctx->thisObject().asReturnedValue();
+ if (callData->thisObject.isBoolean()) {
+ scope.result = callData->thisObject.asReturnedValue();
+ return;
+ }
- const BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>();
+ const BooleanObject *thisObject = callData->thisObject.as<BooleanObject>();
if (!thisObject)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(thisObject->value());
+ scope.result = Encode(thisObject->value());
}
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index 4c2f3c09e7..9c8b1d67f1 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -78,8 +78,8 @@ struct BooleanPrototype: BooleanObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 544d39339b..60b90e4bf0 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -95,6 +95,17 @@ Heap::CallContext *ExecutionContext::newCallContext(Function *function, CallData
return c;
}
+Heap::CallContext *Heap::CallContext::createSimpleContext(ExecutionEngine *v4)
+{
+ Heap::CallContext *ctxt = v4->memoryManager->allocSimpleCallContext(v4);
+ return ctxt;
+}
+
+void Heap::CallContext::freeSimpleCallContext()
+{
+ engine->memoryManager->freeSimpleCallContext();
+}
+
Heap::WithContext *ExecutionContext::newWithContext(Heap::Object *with)
{
return d()->engine->memoryManager->alloc<WithContext>(d(), with);
@@ -325,26 +336,27 @@ void QV4::ExecutionContext::simpleCall(Scope &scope, CallData *callData, Functio
ExecutionContextSaver ctxSaver(scope);
- CallContext::Data ctx = CallContext::Data::createOnStack(scope.engine);
+ CallContext::Data *ctx = scope.engine->memoryManager->allocSimpleCallContext(scope.engine);
- ctx.strictMode = function->isStrict();
- ctx.callData = callData;
- ctx.v4Function = function;
- ctx.compilationUnit = function->compilationUnit;
- ctx.lookups = function->compilationUnit->runtimeLookups;
- ctx.constantTable = function->compilationUnit->constants;
- ctx.outer = this->d();
- ctx.locals = scope.alloc(function->compiledFunction->nLocals);
+ ctx->strictMode = function->isStrict();
+ ctx->callData = callData;
+ ctx->v4Function = function;
+ ctx->compilationUnit = function->compilationUnit;
+ ctx->lookups = function->compilationUnit->runtimeLookups;
+ ctx->constantTable = function->compilationUnit->constants;
+ ctx->outer = this->d();
+ ctx->locals = scope.alloc(function->compiledFunction->nLocals);
for (int i = callData->argc; i < (int)function->nFormals; ++i)
callData->args[i] = Encode::undefined();
- scope.engine->pushContext(&ctx);
- Q_ASSERT(scope.engine->current == &ctx);
+ scope.engine->pushContext(ctx);
+ Q_ASSERT(scope.engine->current == ctx);
scope.result = Q_V4_PROFILE(scope.engine, function);
if (function->hasQmlDependencies)
QQmlPropertyCapture::registerQmlDependencies(function->compiledFunction, scope);
+ scope.engine->memoryManager->freeSimpleCallContext();
}
void ExecutionContext::setProperty(String *name, const Value &value)
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index c985fdb24d..bcfee2e1f8 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -109,14 +109,8 @@ struct ExecutionContext : Base {
{
Base::init();
- callData = nullptr;
this->engine = engine;
- outer = nullptr;
- lookups = nullptr;
- constantTable = nullptr;
- compilationUnit = nullptr;
type = t;
- strictMode = false;
lineNumber = -1;
}
@@ -135,15 +129,12 @@ struct ExecutionContext : Base {
V4_ASSERT_IS_TRIVIAL(ExecutionContext)
struct CallContext : ExecutionContext {
- static CallContext createOnStack(ExecutionEngine *v4);
+ static CallContext *createSimpleContext(ExecutionEngine *v4);
+ void freeSimpleCallContext();
void init(ExecutionEngine *engine, ContextType t = Type_SimpleCallContext)
{
ExecutionContext::init(engine, t);
- function = 0;
- v4Function = 0;
- locals = 0;
- activation = 0;
}
inline unsigned int formalParameterCount() const;
@@ -247,6 +238,7 @@ struct Q_QML_EXPORT CallContext : public ExecutionContext
inline ReturnedValue argument(int i) const;
bool needsOwnArguments() const;
+
};
inline ReturnedValue CallContext::argument(int i) const {
@@ -289,16 +281,6 @@ inline const WithContext *ExecutionContext::asWithContext() const
return d()->type == Heap::ExecutionContext::Type_WithContext ? static_cast<const WithContext *>(this) : 0;
}
-inline Heap::CallContext Heap::CallContext::createOnStack(ExecutionEngine *v4)
-{
- Heap::CallContext ctxt;
- memset(&ctxt, 0, sizeof(Heap::CallContext));
- ctxt.mm_data = 0;
- ctxt.setVtable(QV4::CallContext::staticVTable());
- ctxt.init(v4);
- return ctxt;
-}
-
} // namespace QV4
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index db8376272d..a810b38f24 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -129,90 +129,84 @@ void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("setUInt32"), method_set<unsigned int>, 0);
}
-ReturnedValue DataViewPrototype::method_get_buffer(CallContext *ctx)
+void DataViewPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
+ Scoped<DataView> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->buffer->asReturnedValue());
+ scope.result = v->d()->buffer;
}
-ReturnedValue DataViewPrototype::method_get_byteLength(CallContext *ctx)
+void DataViewPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
+ Scoped<DataView> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteLength);
+ scope.result = Encode(v->d()->byteLength);
}
-ReturnedValue DataViewPrototype::method_get_byteOffset(CallContext *ctx)
+void DataViewPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
+ Scoped<DataView> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteOffset);
+ scope.result = Encode(v->d()->byteOffset);
}
template <typename T>
-ReturnedValue DataViewPrototype::method_getChar(CallContext *ctx)
+void DataViewPrototype::method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
T t = T(v->d()->buffer->data->data()[idx]);
- return Encode((int)t);
+ scope.result = Encode((int)t);
}
template <typename T>
-ReturnedValue DataViewPrototype::method_get(CallContext *ctx)
+void DataViewPrototype::method_get(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- bool littleEndian = ctx->argc() < 2 ? false : ctx->args()[1].toBoolean();
+ bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean();
T t = littleEndian
? qFromLittleEndian<T>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<T>((uchar *)v->d()->buffer->data->data() + idx);
- return Encode(t);
+ scope.result = Encode(t);
}
template <typename T>
-ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx)
+void DataViewPrototype::method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- bool littleEndian = ctx->argc() < 2 ? false : ctx->args()[1].toBoolean();
+ bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean();
if (sizeof(T) == 4) {
// float
@@ -223,7 +217,7 @@ ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx)
u.i = littleEndian
? qFromLittleEndian<uint>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<uint>((uchar *)v->d()->buffer->data->data() + idx);
- return Encode(u.f);
+ scope.result = Encode(u.f);
} else {
Q_ASSERT(sizeof(T) == 8);
union {
@@ -233,69 +227,66 @@ ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx)
u.i = littleEndian
? qFromLittleEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx);
- return Encode(u.d);
+ scope.result = Encode(u.d);
}
}
template <typename T>
-ReturnedValue DataViewPrototype::method_setChar(CallContext *ctx)
+void DataViewPrototype::method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- int val = ctx->argc() >= 2 ? ctx->args()[1].toInt32() : 0;
+ int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0;
v->d()->buffer->data->data()[idx] = (char)val;
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
template <typename T>
-ReturnedValue DataViewPrototype::method_set(CallContext *ctx)
+void DataViewPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- int val = ctx->argc() >= 2 ? ctx->args()[1].toInt32() : 0;
+ int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0;
- bool littleEndian = ctx->argc() < 3 ? false : ctx->args()[2].toBoolean();
+ bool littleEndian = callData->argc < 3 ? false : callData->args[2].toBoolean();
if (littleEndian)
qToLittleEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx);
else
qToBigEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
template <typename T>
-ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx)
+void DataViewPrototype::method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- double val = ctx->argc() >= 2 ? ctx->args()[1].toNumber() : qt_qnan();
- bool littleEndian = ctx->argc() < 3 ? false : ctx->args()[2].toBoolean();
+ double val = callData->argc >= 2 ? callData->args[1].toNumber() : qt_qnan();
+ bool littleEndian = callData->argc < 3 ? false : callData->args[2].toBoolean();
if (sizeof(T) == 4) {
// float
@@ -320,5 +311,5 @@ ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx)
else
qToBigEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx);
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h
index 246124394a..11cc0a6bd9 100644
--- a/src/qml/jsruntime/qv4dataview_p.h
+++ b/src/qml/jsruntime/qv4dataview_p.h
@@ -92,21 +92,21 @@ struct DataViewPrototype: Object
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_get_buffer(CallContext *ctx);
- static ReturnedValue method_get_byteLength(CallContext *ctx);
- static ReturnedValue method_get_byteOffset(CallContext *ctx);
+ static void method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_getChar(CallContext *ctx);
+ static void method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_get(CallContext *ctx);
+ static void method_get(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_getFloat(CallContext *ctx);
+ static void method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_setChar(CallContext *ctx);
+ static void method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_set(CallContext *ctx);
+ static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_setFloat(CallContext *ctx);
+ static void method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 8cc6a25fea..b90c335b1c 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -780,435 +780,435 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("toJSON"), method_toJSON, 1);
}
-double DatePrototype::getThisDate(ExecutionContext *ctx)
+double DatePrototype::getThisDate(Scope &scope, CallData *callData)
{
- if (DateObject *thisObject = ctx->thisObject().as<DateObject>())
+ if (DateObject *thisObject = callData->thisObject.as<DateObject>())
return thisObject->date();
else {
- ctx->engine()->throwTypeError();
+ scope.engine->throwTypeError();
return 0;
}
}
-ReturnedValue DatePrototype::method_parse(CallContext *ctx)
+void DatePrototype::method_parse(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
- return Encode(qt_qnan());
- return Encode(ParseString(ctx->args()[0].toQString()));
+ if (!callData->argc)
+ scope.result = Encode(qt_qnan());
+ else
+ scope.result = Encode(ParseString(callData->args[0].toQString()));
}
-ReturnedValue DatePrototype::method_UTC(CallContext *ctx)
+void DatePrototype::method_UTC(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const int numArgs = ctx->argc();
+ const int numArgs = callData->argc;
if (numArgs >= 2) {
- double year = ctx->args()[0].toNumber();
- double month = ctx->args()[1].toNumber();
- double day = numArgs >= 3 ? ctx->args()[2].toNumber() : 1;
- double hours = numArgs >= 4 ? ctx->args()[3].toNumber() : 0;
- double mins = numArgs >= 5 ? ctx->args()[4].toNumber() : 0;
- double secs = numArgs >= 6 ? ctx->args()[5].toNumber() : 0;
- double ms = numArgs >= 7 ? ctx->args()[6].toNumber() : 0;
+ double year = callData->args[0].toNumber();
+ double month = callData->args[1].toNumber();
+ double day = numArgs >= 3 ? callData->args[2].toNumber() : 1;
+ double hours = numArgs >= 4 ? callData->args[3].toNumber() : 0;
+ double mins = numArgs >= 5 ? callData->args[4].toNumber() : 0;
+ double secs = numArgs >= 6 ? callData->args[5].toNumber() : 0;
+ double ms = numArgs >= 7 ? callData->args[6].toNumber() : 0;
if (year >= 0 && year <= 99)
year += 1900;
double t = MakeDate(MakeDay(year, month, day),
MakeTime(hours, mins, secs, ms));
- return Encode(TimeClip(t));
+ scope.result = Encode(TimeClip(t));
+ return;
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue DatePrototype::method_now(CallContext *ctx)
+void DatePrototype::method_now(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Q_UNUSED(ctx);
+ Q_UNUSED(callData);
double t = currentTime();
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_toString(CallContext *ctx)
+void DatePrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToString(t));
}
-ReturnedValue DatePrototype::method_toDateString(CallContext *ctx)
+void DatePrototype::method_toDateString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToDateString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToDateString(t));
}
-ReturnedValue DatePrototype::method_toTimeString(CallContext *ctx)
+void DatePrototype::method_toTimeString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToTimeString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToTimeString(t));
}
-ReturnedValue DatePrototype::method_toLocaleString(CallContext *ctx)
+void DatePrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToLocaleString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToLocaleString(t));
}
-ReturnedValue DatePrototype::method_toLocaleDateString(CallContext *ctx)
+void DatePrototype::method_toLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToLocaleDateString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToLocaleDateString(t));
}
-ReturnedValue DatePrototype::method_toLocaleTimeString(CallContext *ctx)
+void DatePrototype::method_toLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToLocaleTimeString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToLocaleTimeString(t));
}
-ReturnedValue DatePrototype::method_valueOf(CallContext *ctx)
+void DatePrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return Encode(t);
+ double t = getThisDate(scope, callData);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getTime(CallContext *ctx)
+void DatePrototype::method_getTime(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return Encode(t);
+ double t = getThisDate(scope, callData);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getYear(CallContext *ctx)
+void DatePrototype::method_getYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = YearFromTime(LocalTime(t)) - 1900;
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getFullYear(CallContext *ctx)
+void DatePrototype::method_getFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = YearFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCFullYear(CallContext *ctx)
+void DatePrototype::method_getUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = YearFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getMonth(CallContext *ctx)
+void DatePrototype::method_getMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = MonthFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCMonth(CallContext *ctx)
+void DatePrototype::method_getUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = MonthFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getDate(CallContext *ctx)
+void DatePrototype::method_getDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = DateFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCDate(CallContext *ctx)
+void DatePrototype::method_getUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = DateFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getDay(CallContext *ctx)
+void DatePrototype::method_getDay(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = WeekDay(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCDay(CallContext *ctx)
+void DatePrototype::method_getUTCDay(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = WeekDay(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getHours(CallContext *ctx)
+void DatePrototype::method_getHours(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = HourFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCHours(CallContext *ctx)
+void DatePrototype::method_getUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = HourFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getMinutes(CallContext *ctx)
+void DatePrototype::method_getMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = MinFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCMinutes(CallContext *ctx)
+void DatePrototype::method_getUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = MinFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getSeconds(CallContext *ctx)
+void DatePrototype::method_getSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = SecFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCSeconds(CallContext *ctx)
+void DatePrototype::method_getUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = SecFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getMilliseconds(CallContext *ctx)
+void DatePrototype::method_getMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = msFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCMilliseconds(CallContext *ctx)
+void DatePrototype::method_getUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = msFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getTimezoneOffset(CallContext *ctx)
+void DatePrototype::method_getTimezoneOffset(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = (t - LocalTime(t)) / msPerMinute;
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_setTime(CallContext *ctx)
+void DatePrototype::method_setTime(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DateObject> self(scope, ctx->thisObject());
+ Scoped<DateObject> self(scope, callData->thisObject);
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- double t = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double t = callData->argc ? callData->args[0].toNumber() : qt_qnan();
self->setDate(TimeClip(t));
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx)
+void DatePrototype::method_setMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DateObject> self(scope, ctx->thisObject());
+ Scoped<DateObject> self(scope, callData->thisObject);
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double ms = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double ms = callData->argc ? callData->args[0].toNumber() : qt_qnan();
self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx)
+void DatePrototype::method_setUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double ms = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double ms = callData->argc ? callData->args[0].toNumber() : qt_qnan();
self->setDate(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))));
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx)
+void DatePrototype::method_setSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double sec = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber();
+ double sec = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double ms = (callData->argc < 2) ? msFromTime(t) : callData->args[1].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx)
+void DatePrototype::method_setUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double sec = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber();
+ double sec = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double ms = (callData->argc < 2) ? msFromTime(t) : callData->args[1].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx)
+void DatePrototype::method_setMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double min = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber();
- double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber();
+ double min = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double sec = (callData->argc < 2) ? SecFromTime(t) : callData->args[1].toNumber();
+ double ms = (callData->argc < 3) ? msFromTime(t) : callData->args[2].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx)
+void DatePrototype::method_setUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double min = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber();
- double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber();
+ double min = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double sec = (callData->argc < 2) ? SecFromTime(t) : callData->args[1].toNumber();
+ double ms = (callData->argc < 3) ? msFromTime(t) : callData->args[2].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setHours(CallContext *ctx)
+void DatePrototype::method_setHours(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double hour = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber();
- double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber();
- double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber();
+ double hour = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double min = (callData->argc < 2) ? MinFromTime(t) : callData->args[1].toNumber();
+ double sec = (callData->argc < 3) ? SecFromTime(t) : callData->args[2].toNumber();
+ double ms = (callData->argc < 4) ? msFromTime(t) : callData->args[3].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx)
+void DatePrototype::method_setUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double hour = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber();
- double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber();
- double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber();
+ double hour = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double min = (callData->argc < 2) ? MinFromTime(t) : callData->args[1].toNumber();
+ double sec = (callData->argc < 3) ? SecFromTime(t) : callData->args[2].toNumber();
+ double ms = (callData->argc < 4) ? msFromTime(t) : callData->args[3].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(hour, min, sec, ms)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setDate(CallContext *ctx)
+void DatePrototype::method_setDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double date = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double date = callData->argc ? callData->args[0].toNumber() : qt_qnan();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx)
+void DatePrototype::method_setUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double date = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double date = callData->argc ? callData->args[0].toNumber() : qt_qnan();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setMonth(CallContext *ctx)
+void DatePrototype::method_setMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double month = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber();
+ double month = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double date = (callData->argc < 2) ? DateFromTime(t) : callData->args[1].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx)
+void DatePrototype::method_setUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double month = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber();
+ double month = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double date = (callData->argc < 2) ? DateFromTime(t) : callData->args[1].toNumber();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
+void DatePrototype::method_setYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
if (std::isnan(t))
t = 0;
else
t = LocalTime(t);
- double year = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double year = callData->argc ? callData->args[0].toNumber() : qt_qnan();
double r;
if (std::isnan(year)) {
r = qt_qnan();
@@ -1220,49 +1220,49 @@ ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
r = TimeClip(r);
}
self->setDate(r);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx)
+void DatePrototype::method_setUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double year = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber();
- double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber();
+ double year = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double month = (callData->argc < 2) ? MonthFromTime(t) : callData->args[1].toNumber();
+ double date = (callData->argc < 3) ? DateFromTime(t) : callData->args[2].toNumber();
t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx)
+void DatePrototype::method_setFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
if (std::isnan(t))
t = 0;
- double year = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber();
- double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber();
+ double year = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double month = (callData->argc < 2) ? MonthFromTime(t) : callData->args[1].toNumber();
+ double date = (callData->argc < 3) ? DateFromTime(t) : callData->args[2].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_toUTCString(CallContext *ctx)
+void DatePrototype::method_toUTCString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- return ctx->d()->engine->newString(ToUTCString(t))->asReturnedValue();
+ scope.result = scope.engine->newString(ToUTCString(t));
}
static void addZeroPrefixedInt(QString &str, int num, int nDigits)
@@ -1278,21 +1278,21 @@ static void addZeroPrefixedInt(QString &str, int num, int nDigits)
}
}
-ReturnedValue DatePrototype::method_toISOString(CallContext *ctx)
+void DatePrototype::method_toISOString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
if (!std::isfinite(t))
- return ctx->engine()->throwRangeError(ctx->thisObject());
+ RETURN_RESULT(scope.engine->throwRangeError(callData->thisObject));
QString result;
int year = (int)YearFromTime(t);
if (year < 0 || year > 9999) {
if (qAbs(year) >= 1000000)
- return ctx->d()->engine->newString(QStringLiteral("Invalid Date"))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("Invalid Date")));
result += year < 0 ? QLatin1Char('-') : QLatin1Char('+');
year = qAbs(year);
addZeroPrefixedInt(result, year, 6);
@@ -1313,32 +1313,29 @@ ReturnedValue DatePrototype::method_toISOString(CallContext *ctx)
addZeroPrefixedInt(result, msFromTime(t), 3);
result += QLatin1Char('Z');
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
-ReturnedValue DatePrototype::method_toJSON(CallContext *ctx)
+void DatePrototype::method_toJSON(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject O(scope, ctx->thisObject().toObject(scope.engine));
- if (scope.hasException())
- return Encode::undefined();
+ ScopedObject O(scope, callData->thisObject.toObject(scope.engine));
+ CHECK_EXCEPTION();
ScopedValue tv(scope, RuntimeHelpers::toPrimitive(O, NUMBER_HINT));
if (tv->isNumber() && !std::isfinite(tv->toNumber()))
- return Encode::null();
+ RETURN_RESULT(Encode::null());
- ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("toISOString")));
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("toISOString")));
ScopedValue v(scope, O->get(s));
FunctionObject *toIso = v->as<FunctionObject>();
if (!toIso)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope);
- callData->thisObject = ctx->thisObject();
- toIso->call(scope, callData);
- return scope.result.asReturnedValue();
+ ScopedCallData cData(scope);
+ cData->thisObject = callData->thisObject;
+ toIso->call(scope, cData);
}
void DatePrototype::timezoneUpdated()
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 835f6adbe0..a56d17f9b1 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -116,57 +116,57 @@ struct DatePrototype: DateObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static double getThisDate(ExecutionContext *ctx);
-
- static ReturnedValue method_parse(CallContext *ctx);
- static ReturnedValue method_UTC(CallContext *ctx);
- static ReturnedValue method_now(CallContext *ctx);
-
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_toDateString(CallContext *ctx);
- static ReturnedValue method_toTimeString(CallContext *ctx);
- static ReturnedValue method_toLocaleString(CallContext *ctx);
- static ReturnedValue method_toLocaleDateString(CallContext *ctx);
- static ReturnedValue method_toLocaleTimeString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
- static ReturnedValue method_getTime(CallContext *ctx);
- static ReturnedValue method_getYear(CallContext *ctx);
- static ReturnedValue method_getFullYear(CallContext *ctx);
- static ReturnedValue method_getUTCFullYear(CallContext *ctx);
- static ReturnedValue method_getMonth(CallContext *ctx);
- static ReturnedValue method_getUTCMonth(CallContext *ctx);
- static ReturnedValue method_getDate(CallContext *ctx);
- static ReturnedValue method_getUTCDate(CallContext *ctx);
- static ReturnedValue method_getDay(CallContext *ctx);
- static ReturnedValue method_getUTCDay(CallContext *ctx);
- static ReturnedValue method_getHours(CallContext *ctx);
- static ReturnedValue method_getUTCHours(CallContext *ctx);
- static ReturnedValue method_getMinutes(CallContext *ctx);
- static ReturnedValue method_getUTCMinutes(CallContext *ctx);
- static ReturnedValue method_getSeconds(CallContext *ctx);
- static ReturnedValue method_getUTCSeconds(CallContext *ctx);
- static ReturnedValue method_getMilliseconds(CallContext *ctx);
- static ReturnedValue method_getUTCMilliseconds(CallContext *ctx);
- static ReturnedValue method_getTimezoneOffset(CallContext *ctx);
- static ReturnedValue method_setTime(CallContext *ctx);
- static ReturnedValue method_setMilliseconds(CallContext *ctx);
- static ReturnedValue method_setUTCMilliseconds(CallContext *ctx);
- static ReturnedValue method_setSeconds(CallContext *ctx);
- static ReturnedValue method_setUTCSeconds(CallContext *ctx);
- static ReturnedValue method_setMinutes(CallContext *ctx);
- static ReturnedValue method_setUTCMinutes(CallContext *ctx);
- static ReturnedValue method_setHours(CallContext *ctx);
- static ReturnedValue method_setUTCHours(CallContext *ctx);
- static ReturnedValue method_setDate(CallContext *ctx);
- static ReturnedValue method_setUTCDate(CallContext *ctx);
- static ReturnedValue method_setMonth(CallContext *ctx);
- static ReturnedValue method_setUTCMonth(CallContext *ctx);
- static ReturnedValue method_setYear(CallContext *ctx);
- static ReturnedValue method_setFullYear(CallContext *ctx);
- static ReturnedValue method_setUTCFullYear(CallContext *ctx);
- static ReturnedValue method_toUTCString(CallContext *ctx);
- static ReturnedValue method_toISOString(CallContext *ctx);
- static ReturnedValue method_toJSON(CallContext *ctx);
+ static double getThisDate(Scope &scope, CallData *callData);
+
+ static void method_parse(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_UTC(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_now(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toDateString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toTimeString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getTime(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getDay(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCDay(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getHours(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getTimezoneOffset(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setTime(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setHours(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toUTCString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toISOString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toJSON(const BuiltinFunction *, Scope &scope, CallData *callData);
static void timezoneUpdated();
};
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 8f2c5174da..a11f7f0875 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -158,8 +158,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
}
Q_ASSERT(maxCallDepth > 0);
- MemoryManager::GCBlocker gcBlocker(memoryManager);
-
if (!factory) {
#if QT_CONFIG(qml_interpreter)
bool jitDisabled = true;
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 597ded6ae1..f290bc5136 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -153,12 +153,11 @@ const char *ErrorObject::className(Heap::ErrorObject::ErrorType t)
Q_UNREACHABLE();
}
-ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
+void ErrorObject::method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<ErrorObject> This(scope, ctx->thisObject());
+ Scoped<ErrorObject> This(scope, callData->thisObject);
if (!This)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!This->d()->stack) {
QString trace;
for (int i = 0; i < This->d()->stackTrace->count(); ++i) {
@@ -169,9 +168,9 @@ ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
if (frame.line >= 0)
trace += QLatin1Char(':') + QString::number(frame.line);
}
- This->d()->stack = ctx->d()->engine->newString(trace);
+ This->d()->stack = scope.engine->newString(trace);
}
- return This->d()->stack->asReturnedValue();
+ scope.result = This->d()->stack;
}
void ErrorObject::markObjects(Heap::Base *that, ExecutionEngine *e)
@@ -335,22 +334,20 @@ void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, He
obj->defineDefaultProperty(engine->id_toString(), method_toString, 0);
}
-ReturnedValue ErrorPrototype::method_toString(CallContext *ctx)
+void ErrorPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
- Object *o = ctx->thisObject().as<Object>();
+ Object *o = callData->thisObject.as<Object>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedValue name(scope, o->get(ctx->d()->engine->id_name()));
+ ScopedValue name(scope, o->get(scope.engine->id_name()));
QString qname;
if (name->isUndefined())
qname = QStringLiteral("Error");
else
qname = name->toQString();
- ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("message")));
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("message")));
ScopedValue message(scope, o->get(s));
QString qmessage;
if (!message->isUndefined())
@@ -365,5 +362,5 @@ ReturnedValue ErrorPrototype::method_toString(CallContext *ctx)
str = qname + QLatin1String(": ") + qmessage;
}
- return ctx->d()->engine->newString(str)->asReturnedValue();
+ scope.result = scope.engine->newString(str)->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 2b3ab25e2d..9ba9f05234 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -172,7 +172,7 @@ struct ErrorObject: Object {
static const char *className(Heap::ErrorObject::ErrorType t);
- static ReturnedValue method_get_stack(CallContext *ctx);
+ static void method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData);
static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
@@ -282,7 +282,7 @@ struct ErrorPrototype : ErrorObject
void init(ExecutionEngine *engine, Object *ctor) { init(engine, ctor, this, Heap::ErrorObject::Error); }
static void init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t);
- static ReturnedValue method_toString(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
};
struct EvalErrorPrototype : ErrorObject
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 64f7b98618..b2d89220ea 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -270,23 +270,22 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor)
}
-ReturnedValue FunctionPrototype::method_toString(CallContext *ctx)
+void FunctionPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- FunctionObject *fun = ctx->thisObject().as<FunctionObject>();
+ FunctionObject *fun = callData->thisObject.as<FunctionObject>();
if (!fun)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return ctx->d()->engine->newString(QStringLiteral("function() { [code] }"))->asReturnedValue();
+ scope.result = scope.engine->newString(QStringLiteral("function() { [code] }"));
}
-ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
+void FunctionPrototype::method_apply(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- FunctionObject *o = ctx->thisObject().as<FunctionObject>();
+ FunctionObject *o = callData->thisObject.as<FunctionObject>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedValue arg(scope, ctx->argument(1));
+ ScopedValue arg(scope, callData->argument(1));
ScopedObject arr(scope, arg);
@@ -294,75 +293,71 @@ ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
if (!arr) {
len = 0;
if (!arg->isNullOrUndefined())
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
} else {
len = arr->getLength();
}
- ScopedCallData callData(scope, len);
+ ScopedCallData cData(scope, len);
if (len) {
if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast<ArgumentsObject>()->fullyCreated()) {
QV4::ArgumentsObject *a = arr->cast<ArgumentsObject>();
int l = qMin(len, (uint)a->d()->context->callData->argc);
- memcpy(callData->args, a->d()->context->callData->args, l*sizeof(Value));
+ memcpy(cData->args, a->d()->context->callData->args, l*sizeof(Value));
for (quint32 i = l; i < len; ++i)
- callData->args[i] = Primitive::undefinedValue();
+ cData->args[i] = Primitive::undefinedValue();
} else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) {
auto sad = static_cast<Heap::SimpleArrayData *>(arr->arrayData());
uint alen = sad ? sad->len : 0;
if (alen > len)
alen = len;
for (uint i = 0; i < alen; ++i)
- callData->args[i] = sad->data(i);
+ cData->args[i] = sad->data(i);
for (quint32 i = alen; i < len; ++i)
- callData->args[i] = Primitive::undefinedValue();
+ cData->args[i] = Primitive::undefinedValue();
} else {
for (quint32 i = 0; i < len; ++i)
- callData->args[i] = arr->getIndexed(i);
+ cData->args[i] = arr->getIndexed(i);
}
}
- callData->thisObject = ctx->argument(0);
- o->call(scope, callData);
- return scope.result.asReturnedValue();
+ cData->thisObject = callData->argument(0);
+ o->call(scope, cData);
}
-ReturnedValue FunctionPrototype::method_call(CallContext *ctx)
+void FunctionPrototype::method_call(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- FunctionObject *o = ctx->thisObject().as<FunctionObject>();
+ FunctionObject *o = callData->thisObject.as<FunctionObject>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedCallData callData(scope, ctx->argc() ? ctx->argc() - 1 : 0);
- if (ctx->argc()) {
- for (int i = 1; i < ctx->argc(); ++i)
- callData->args[i - 1] = ctx->args()[i];
+ ScopedCallData cData(scope, callData->argc ? callData->argc - 1 : 0);
+ if (callData->argc) {
+ for (int i = 1; i < callData->argc; ++i)
+ cData->args[i - 1] = callData->args[i];
}
- callData->thisObject = ctx->argument(0);
+ cData->thisObject = callData->argument(0);
- o->call(scope, callData);
- return scope.result.asReturnedValue();
+ o->call(scope, cData);
}
-ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
+void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- FunctionObject *target = ctx->thisObject().as<FunctionObject>();
+ FunctionObject *target = callData->thisObject.as<FunctionObject>();
if (!target)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedValue boundThis(scope, ctx->argument(0));
+ ScopedValue boundThis(scope, callData->argument(0));
Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)0);
- if (ctx->argc() > 1) {
- boundArgs = MemberData::allocate(scope.engine, ctx->argc() - 1);
- boundArgs->d()->size = ctx->argc() - 1;
- memcpy(boundArgs->data(), ctx->args() + 1, (ctx->argc() - 1)*sizeof(Value));
+ if (callData->argc > 1) {
+ boundArgs = MemberData::allocate(scope.engine, callData->argc - 1);
+ boundArgs->d()->size = callData->argc - 1;
+ memcpy(boundArgs->data(), callData->args + 1, (callData->argc - 1)*sizeof(Value));
}
ExecutionContext *global = scope.engine->rootContext();
- return BoundFunction::create(global, target, boundThis, boundArgs)->asReturnedValue();
+ scope.result = BoundFunction::create(global, target, boundThis, boundArgs);
}
DEFINE_OBJECT_VTABLE(ScriptFunction);
@@ -459,22 +454,22 @@ Heap::Object *ScriptFunction::protoForConstructor() const
-DEFINE_OBJECT_VTABLE(BuiltinFunction);
+DEFINE_OBJECT_VTABLE(OldBuiltinFunction);
-void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *))
+void Heap::OldBuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *))
{
Heap::FunctionObject::init(scope, name);
this->code = code;
}
-void BuiltinFunction::construct(const Managed *f, Scope &scope, CallData *)
+void OldBuiltinFunction::construct(const Managed *f, Scope &scope, CallData *)
{
- scope.result = static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError();
+ scope.result = static_cast<const OldBuiltinFunction *>(f)->internalClass()->engine->throwTypeError();
}
-void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
+void OldBuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
{
- const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that);
+ const OldBuiltinFunction *f = static_cast<const OldBuiltinFunction *>(that);
ExecutionEngine *v4 = scope.engine;
if (v4->hasException) {
scope.result = Encode::undefined();
@@ -484,15 +479,41 @@ void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData
ExecutionContextSaver ctxSaver(scope);
- CallContext::Data ctx = CallContext::Data::createOnStack(v4);
- ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
- ctx.callData = callData;
- v4->pushContext(&ctx);
- Q_ASSERT(v4->current == &ctx);
+ CallContext::Data *ctx = v4->memoryManager->allocSimpleCallContext(v4);
+ ctx->strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
+ ctx->callData = callData;
+ v4->pushContext(ctx);
+ Q_ASSERT(v4->current == ctx);
scope.result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext));
+ v4->memoryManager->freeSimpleCallContext();
+}
+
+DEFINE_OBJECT_VTABLE(BuiltinFunction);
+
+void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *))
+{
+ Heap::FunctionObject::init(scope, name);
+ this->code = code;
+}
+
+void BuiltinFunction::construct(const Managed *f, Scope &scope, CallData *)
+{
+ scope.result = static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError();
+}
+
+void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
+{
+ const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that);
+ ExecutionEngine *v4 = scope.engine;
+ if (v4->hasException) {
+ scope.result = Encode::undefined();
+ return;
+ }
+ f->d()->code(f, scope, callData);
}
+
void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
{
const IndexedBuiltinFunction *f = static_cast<const IndexedBuiltinFunction *>(that);
@@ -505,13 +526,14 @@ void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *c
ExecutionContextSaver ctxSaver(scope);
- CallContext::Data ctx = CallContext::Data::createOnStack(v4);
- ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
- ctx.callData = callData;
- v4->pushContext(&ctx);
- Q_ASSERT(v4->current == &ctx);
+ CallContext::Data *ctx = v4->memoryManager->allocSimpleCallContext(v4);
+ ctx->strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
+ ctx->callData = callData;
+ v4->pushContext(ctx);
+ Q_ASSERT(v4->current == ctx);
scope.result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext), f->d()->index);
+ v4->memoryManager->freeSimpleCallContext();
}
DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index a02e89e883..45d7485f1b 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -61,6 +61,8 @@ struct QQmlSourceLocation;
namespace QV4 {
+struct BuiltinFunction;
+
namespace Heap {
struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
@@ -93,11 +95,16 @@ struct FunctionPrototype : FunctionObject {
void init();
};
-struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
+struct Q_QML_EXPORT OldBuiltinFunction : FunctionObject {
void init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *));
ReturnedValue (*code)(QV4::CallContext *);
};
+struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
+ void init(QV4::ExecutionContext *scope, QV4::String *name, void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *));
+ void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *);
+};
+
struct IndexedBuiltinFunction : FunctionObject {
inline void init(QV4::ExecutionContext *scope, uint index, ReturnedValue (*code)(QV4::CallContext *ctx, uint index));
ReturnedValue (*code)(QV4::CallContext *, uint index);
@@ -177,16 +184,27 @@ struct FunctionPrototype: FunctionObject
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_apply(CallContext *ctx);
- static ReturnedValue method_call(CallContext *ctx);
- static ReturnedValue method_bind(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_apply(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_call(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_bind(const BuiltinFunction *, Scope &scope, CallData *callData);
};
-struct Q_QML_EXPORT BuiltinFunction: FunctionObject {
+struct Q_QML_EXPORT OldBuiltinFunction : FunctionObject {
+ V4_OBJECT2(OldBuiltinFunction, FunctionObject)
+
+ static void construct(const Managed *, Scope &scope, CallData *);
+ static void call(const Managed *that, Scope &scope, CallData *callData);
+};
+
+struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
V4_OBJECT2(BuiltinFunction, FunctionObject)
- static Heap::BuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *))
+ static Heap::OldBuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *))
+ {
+ return scope->engine()->memoryManager->allocObject<OldBuiltinFunction>(scope, name, code);
+ }
+ static Heap::BuiltinFunction *create(ExecutionContext *scope, String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *))
{
return scope->engine()->memoryManager->allocObject<BuiltinFunction>(scope, name, code);
}
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index c37ad1668d..66861bf697 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -97,19 +97,19 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
//
// NOTE: This should match the logic in qv4targetplatform_p.h!
-#if defined(Q_PROCESSOR_X86) && !defined(__ILP32__) \
+#if defined(Q_PROCESSOR_X86) && (QT_POINTER_SIZE == 4) \
&& (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD))
# define V4_ENABLE_JIT
-#elif defined(Q_PROCESSOR_X86_64) && !defined(__ILP32__) \
+#elif defined(Q_PROCESSOR_X86_64) && (QT_POINTER_SIZE == 8) \
&& (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD))
# define V4_ENABLE_JIT
-#elif defined(Q_PROCESSOR_ARM_32)
+#elif defined(Q_PROCESSOR_ARM_32) && (QT_POINTER_SIZE == 4)
# if defined(thumb2) || defined(__thumb2__) || ((defined(__thumb) || defined(__thumb__)) && __TARGET_ARCH_THUMB-0 == 4)
# define V4_ENABLE_JIT
# elif defined(__ARM_ARCH_ISA_THUMB) && __ARM_ARCH_ISA_THUMB == 2 // clang 3.5 and later will set this if the core supports the Thumb-2 ISA.
# define V4_ENABLE_JIT
# endif
-#elif defined(Q_PROCESSOR_ARM_64)
+#elif defined(Q_PROCESSOR_ARM_64) && (QT_POINTER_SIZE == 8)
# if defined(Q_OS_LINUX)
# define V4_ENABLE_JIT
# endif
@@ -208,6 +208,7 @@ struct StringObject;
struct ArrayObject;
struct DateObject;
struct FunctionObject;
+struct BuiltinFunction;
struct ErrorObject;
struct ArgumentsObject;
struct Managed;
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index af92ce1ad8..1bc91f832b 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -423,18 +423,15 @@ static inline int toInt(const QChar &qc, int R)
}
// parseInt [15.1.2.2]
-ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
+void GlobalFunctions::method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue inputString(scope, ctx->argument(0));
- ScopedValue radix(scope, ctx->argument(1));
+ ScopedValue inputString(scope, callData->argument(0));
+ ScopedValue radix(scope, callData->argument(1));
int R = radix->isUndefined() ? 0 : radix->toInt32();
// [15.1.2.2] step by step:
QString trimmed = inputString->toQString().trimmed(); // 1 + 2
-
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
+ CHECK_EXCEPTION();
const QChar *pos = trimmed.constData();
const QChar *end = pos + trimmed.length();
@@ -449,7 +446,7 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
bool stripPrefix = true; // 7
if (R) { // 8
if (R < 2 || R > 36)
- return Encode(std::numeric_limits<double>::quiet_NaN()); // 8a
+ RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN())); // 8a
if (R != 16)
stripPrefix = false; // 8b
} else { // 9
@@ -466,13 +463,13 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
// 11: Z is progressively built below
// 13: this is handled by the toInt function
if (pos == end) // 12
- return Encode(std::numeric_limits<double>::quiet_NaN());
+ RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN()));
bool overflow = false;
qint64 v_overflow = 0;
unsigned overflow_digit_count = 0;
int d = toInt(*pos++, R);
if (d == -1)
- return Encode(std::numeric_limits<double>::quiet_NaN());
+ RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN()));
qint64 v = d;
while (pos != end) {
d = toInt(*pos++, R);
@@ -499,155 +496,148 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
if (overflow) {
double result = (double) v_overflow * pow(static_cast<double>(R), static_cast<double>(overflow_digit_count));
result += v;
- return Encode(sign * result);
+ RETURN_RESULT(Encode(sign * result));
} else {
- return Encode(sign * (double) v); // 15
+ RETURN_RESULT(Encode(sign * (double) v)); // 15
}
}
// parseFloat [15.1.2.3]
-ReturnedValue GlobalFunctions::method_parseFloat(CallContext *ctx)
+void GlobalFunctions::method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
// [15.1.2.3] step by step:
- ScopedString inputString(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString inputString(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
QString trimmed = inputString->toQString().trimmed(); // 2
// 4:
if (trimmed.startsWith(QLatin1String("Infinity"))
|| trimmed.startsWith(QLatin1String("+Infinity")))
- return Encode(Q_INFINITY);
+ RETURN_RESULT(Encode(Q_INFINITY));
if (trimmed.startsWith(QLatin1String("-Infinity")))
- return Encode(-Q_INFINITY);
+ RETURN_RESULT(Encode(-Q_INFINITY));
QByteArray ba = trimmed.toLatin1();
bool ok;
const char *begin = ba.constData();
const char *end = 0;
double d = qstrtod(begin, &end, &ok);
if (end - begin == 0)
- return Encode(std::numeric_limits<double>::quiet_NaN()); // 3
+ RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN())); // 3
else
- return Encode(d);
+ RETURN_RESULT(Encode(d));
}
/// isNaN [15.1.2.4]
-ReturnedValue GlobalFunctions::method_isNaN(CallContext *ctx)
+void GlobalFunctions::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
+ if (!callData->argc)
// undefined gets converted to NaN
- return Encode(true);
+ RETURN_RESULT(Encode(true));
- if (ctx->args()[0].integerCompatible())
- return Encode(false);
+ if (callData->args[0].integerCompatible())
+ RETURN_RESULT(Encode(false));
- double d = ctx->args()[0].toNumber();
- return Encode((bool)std::isnan(d));
+ double d = callData->args[0].toNumber();
+ RETURN_RESULT(Encode((bool)std::isnan(d)));
}
/// isFinite [15.1.2.5]
-ReturnedValue GlobalFunctions::method_isFinite(CallContext *ctx)
+void GlobalFunctions::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
+ if (!callData->argc)
// undefined gets converted to NaN
- return Encode(false);
+ RETURN_RESULT(Encode(false));
- if (ctx->args()[0].integerCompatible())
- return Encode(true);
+ if (callData->args[0].integerCompatible())
+ RETURN_RESULT(Encode(true));
- double d = ctx->args()[0].toNumber();
- return Encode((bool)std::isfinite(d));
+ double d = callData->args[0].toNumber();
+ RETURN_RESULT(Encode((bool)std::isfinite(d)));
}
/// decodeURI [15.1.3.1]
-ReturnedValue GlobalFunctions::method_decodeURI(CallContext *context)
+void GlobalFunctions::method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->argc() == 0)
- return Encode::undefined();
+ if (callData->argc == 0)
+ RETURN_UNDEFINED();
- QString uriString = context->args()[0].toQString();
+ QString uriString = callData->args[0].toQString();
bool ok;
QString out = decode(uriString, DecodeNonReserved, &ok);
if (!ok) {
- Scope scope(context);
- ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->engine()->throwURIError(s);
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
+ RETURN_RESULT(scope.engine->throwURIError(s));
}
- return context->d()->engine->newString(out)->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(out));
}
/// decodeURIComponent [15.1.3.2]
-ReturnedValue GlobalFunctions::method_decodeURIComponent(CallContext *context)
+void GlobalFunctions::method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->argc() == 0)
- return Encode::undefined();
+ if (callData->argc == 0)
+ RETURN_UNDEFINED();
- QString uriString = context->args()[0].toQString();
+ QString uriString = callData->args[0].toQString();
bool ok;
QString out = decode(uriString, DecodeAll, &ok);
if (!ok) {
- Scope scope(context);
- ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->engine()->throwURIError(s);
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
+ RETURN_RESULT(scope.engine->throwURIError(s));
}
- return context->d()->engine->newString(out)->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(out));
}
/// encodeURI [15.1.3.3]
-ReturnedValue GlobalFunctions::method_encodeURI(CallContext *context)
+void GlobalFunctions::method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->argc() == 0)
- return Encode::undefined();
+ if (callData->argc == 0)
+ RETURN_UNDEFINED();
- QString uriString = context->args()[0].toQString();
+ QString uriString = callData->args[0].toQString();
bool ok;
QString out = encode(uriString, uriUnescapedReserved, &ok);
if (!ok) {
- Scope scope(context);
- ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->engine()->throwURIError(s);
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
+ RETURN_RESULT(scope.engine->throwURIError(s));
}
- return context->d()->engine->newString(out)->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(out));
}
/// encodeURIComponent [15.1.3.4]
-ReturnedValue GlobalFunctions::method_encodeURIComponent(CallContext *context)
+void GlobalFunctions::method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->argc() == 0)
- return Encode::undefined();
+ if (callData->argc == 0)
+ RETURN_UNDEFINED();
- QString uriString = context->args()[0].toQString();
+ QString uriString = callData->args[0].toQString();
bool ok;
QString out = encode(uriString, uriUnescaped, &ok);
if (!ok) {
- Scope scope(context);
- ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->engine()->throwURIError(s);
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
+ RETURN_RESULT(scope.engine->throwURIError(s));
}
- return context->d()->engine->newString(out)->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(out));
}
-ReturnedValue GlobalFunctions::method_escape(CallContext *context)
+void GlobalFunctions::method_escape(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!context->argc())
- return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
+ if (!callData->argc)
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined")));
- QString str = context->args()[0].toQString();
- return context->d()->engine->newString(escape(str))->asReturnedValue();
+ QString str = callData->args[0].toQString();
+ RETURN_RESULT(scope.engine->newString(escape(str)));
}
-ReturnedValue GlobalFunctions::method_unescape(CallContext *context)
+void GlobalFunctions::method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!context->argc())
- return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
+ if (!callData->argc)
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined")));
- QString str = context->args()[0].toQString();
- return context->d()->engine->newString(unescape(str))->asReturnedValue();
+ QString str = callData->args[0].toQString();
+ RETURN_RESULT(scope.engine->newString(unescape(str)));
}
diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h
index e8b3a92d34..273f1ba7ea 100644
--- a/src/qml/jsruntime/qv4globalobject_p.h
+++ b/src/qml/jsruntime/qv4globalobject_p.h
@@ -76,16 +76,16 @@ struct Q_QML_EXPORT EvalFunction : FunctionObject
struct GlobalFunctions
{
- static ReturnedValue method_parseInt(CallContext *context);
- static ReturnedValue method_parseFloat(CallContext *context);
- static ReturnedValue method_isNaN(CallContext *context);
- static ReturnedValue method_isFinite(CallContext *ctx);
- static ReturnedValue method_decodeURI(CallContext *context);
- static ReturnedValue method_decodeURIComponent(CallContext *context);
- static ReturnedValue method_encodeURI(CallContext *context);
- static ReturnedValue method_encodeURIComponent(CallContext *context);
- static ReturnedValue method_escape(CallContext *context);
- static ReturnedValue method_unescape(CallContext *context);
+ static void method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_escape(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 1d393cf0aa..f033eb2d2d 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -195,23 +195,22 @@ void QV4Include::finished()
/*
Documented in qv8engine.cpp
*/
-QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
+void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- if (!ctx->argc())
- return QV4::Encode::undefined();
+ if (!callData->argc)
+ RETURN_UNDEFINED();
- QV4::Scope scope(ctx->engine());
QQmlContextData *context = scope.engine->callingQmlContext();
if (!context || !context->isJSContext)
- V4THROW_ERROR("Qt.include(): Can only be called from JavaScript files");
+ RETURN_RESULT(scope.engine->throwError(QString::fromUtf8("Qt.include(): Can only be called from JavaScript files")));
QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue());
- if (ctx->argc() >= 2 && ctx->args()[1].as<QV4::FunctionObject>())
- callbackFunction = ctx->args()[1];
+ if (callData->argc >= 2 && callData->args[1].as<QV4::FunctionObject>())
+ callbackFunction = callData->args[1];
#if QT_CONFIG(qml_network)
- QUrl url(scope.engine->resolvedUrl(ctx->args()[0].toQStringNoThrow()));
+ QUrl url(scope.engine->resolvedUrl(callData->args[0].toQStringNoThrow()));
if (scope.engine->qmlEngine() && scope.engine->qmlEngine()->urlInterceptor())
url = scope.engine->qmlEngine()->urlInterceptor()->intercept(url, QQmlAbstractUrlInterceptor::JavaScriptFile);
@@ -261,12 +260,12 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
callback(callbackFunction, result);
}
- return result->asReturnedValue();
+ scope.result = result;
#else
QV4::ScopedValue result(scope);
result = resultValue(scope.engine, NetworkError);
callback(callbackFunction, result);
- return result->asReturnedValue();
+ scope.result = result;
#endif
}
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index 4c601a5e7b..5908d6bfde 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -77,7 +77,7 @@ public:
Exception = 3
};
- static QV4::ReturnedValue method_include(QV4::CallContext *ctx);
+ static void method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
private Q_SLOTS:
void finished();
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index d17da9af0c..bac71b4537 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -128,48 +128,22 @@ InternalClass::InternalClass(const QV4::InternalClass &other)
static void insertHoleIntoPropertyData(Object *object, int idx)
{
- int inlineSize = object->d()->inlineMemberSize;
int icSize = object->internalClass()->size;
- int from = qMax(idx, inlineSize);
+ int from = idx;
int to = from + 1;
- if (from < icSize) {
+ if (from < icSize)
memmove(object->propertyData(to), object->propertyData(from),
(icSize - from - 1) * sizeof(Value));
- }
- if (from == idx)
- return;
- if (inlineSize < icSize)
- *object->propertyData(inlineSize) = *object->propertyData(inlineSize - 1);
- from = idx;
- to = from + 1;
- if (from < inlineSize - 1) {
- memmove(object->propertyData(to), object->propertyData(from),
- (inlineSize - from - 1) * sizeof(Value));
- }
}
static void removeFromPropertyData(Object *object, int idx, bool accessor = false)
{
- int inlineSize = object->d()->inlineMemberSize;
int delta = (accessor ? 2 : 1);
int oldSize = object->internalClass()->size + delta;
int to = idx;
int from = to + delta;
- if (from < inlineSize) {
- memmove(object->propertyData(to), object->d()->propertyData(from), (inlineSize - from)*sizeof(Value));
- to = inlineSize - delta;
- from = inlineSize;
- }
- if (to < inlineSize && from < oldSize) {
- Q_ASSERT(from >= inlineSize);
- memcpy(object->propertyData(to), object->d()->propertyData(from), (inlineSize - to)*sizeof(Value));
- to = inlineSize;
- from = inlineSize + delta;
- }
- if (from < oldSize) {
- Q_ASSERT(to >= inlineSize && from > to);
+ if (from < oldSize)
memmove(object->propertyData(to), object->d()->propertyData(from), (oldSize - to)*sizeof(Value));
- }
}
void InternalClass::changeMember(Object *object, String *string, PropertyAttributes data, uint *index)
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index dcda949c97..1d8ef4b0fb 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -234,7 +234,7 @@ struct InternalClassTransition
{ return id == other.id && flags == other.flags; }
bool operator<(const InternalClassTransition &other) const
- { return id < other.id; }
+ { return id < other.id || (id == other.id && flags < other.flags); }
};
struct InternalClass : public QQmlJS::Managed {
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index d79e6242ba..1d571f53f3 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -883,10 +883,9 @@ void Heap::JsonObject::init()
}
-ReturnedValue JsonObject::method_parse(CallContext *ctx)
+void JsonObject::method_parse(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue v(scope, ctx->argument(0));
+ ScopedValue v(scope, callData->argument(0));
QString jtext = v->toQString();
DEBUG << "parsing source = " << jtext;
@@ -895,19 +894,17 @@ ReturnedValue JsonObject::method_parse(CallContext *ctx)
ScopedValue result(scope, parser.parse(&error));
if (error.error != QJsonParseError::NoError) {
DEBUG << "parse error" << error.errorString();
- return ctx->engine()->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"));
+ RETURN_RESULT(scope.engine->throwSyntaxError(QStringLiteral("JSON.parse: Parse error")));
}
- return result->asReturnedValue();
+ scope.result = result;
}
-ReturnedValue JsonObject::method_stringify(CallContext *ctx)
+void JsonObject::method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
Stringify stringify(scope.engine);
- ScopedObject o(scope, ctx->argument(1));
+ ScopedObject o(scope, callData->argument(1));
if (o) {
stringify.replacerFunction = o->as<FunctionObject>();
if (o->isArrayObject()) {
@@ -932,7 +929,7 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
}
}
- ScopedValue s(scope, ctx->argument(2));
+ ScopedValue s(scope, callData->argument(2));
if (NumberObject *n = s->as<NumberObject>())
s = Encode(n->value());
else if (StringObject *so = s->as<StringObject>())
@@ -945,11 +942,11 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
}
- ScopedValue arg0(scope, ctx->argument(0));
+ ScopedValue arg0(scope, callData->argument(0));
QString result = stringify.Str(QString(), arg0);
if (result.isEmpty() || scope.engine->hasException)
- return Encode::undefined();
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ RETURN_UNDEFINED();
+ scope.result = scope.engine->newString(result);
}
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index 43248a214d..a73ce1c74e 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -88,8 +88,8 @@ private:
typedef QSet<ObjectItem> V4ObjectSet;
public:
- static ReturnedValue method_parse(CallContext *ctx);
- static ReturnedValue method_stringify(CallContext *ctx);
+ static void method_parse(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData);
static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value);
static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object);
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index e03b2762cc..2d9d81c64b 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -92,160 +92,160 @@ static Q_ALWAYS_INLINE double copySign(double x, double y)
return ::copysign(x, y);
}
-ReturnedValue MathObject::method_abs(CallContext *context)
+void MathObject::method_abs(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!context->argc())
- return Encode(qt_qnan());
+ if (!callData->argc)
+ RETURN_RESULT(Encode(qt_qnan()));
- if (context->args()[0].isInteger()) {
- int i = context->args()[0].integerValue();
- return Encode(i < 0 ? - i : i);
+ if (callData->args[0].isInteger()) {
+ int i = callData->args[0].integerValue();
+ RETURN_RESULT(Encode(i < 0 ? - i : i));
}
- double v = context->args()[0].toNumber();
+ double v = callData->args[0].toNumber();
if (v == 0) // 0 | -0
- return Encode(0);
+ RETURN_RESULT(Encode(0));
- return Encode(v < 0 ? -v : v);
+ RETURN_RESULT(Encode(v < 0 ? -v : v));
}
-ReturnedValue MathObject::method_acos(CallContext *context)
+void MathObject::method_acos(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : 2;
+ double v = callData->argc ? callData->args[0].toNumber() : 2;
if (v > 1)
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
- return Encode(std::acos(v));
+ RETURN_RESULT(Encode(std::acos(v)));
}
-ReturnedValue MathObject::method_asin(CallContext *context)
+void MathObject::method_asin(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : 2;
+ double v = callData->argc ? callData->args[0].toNumber() : 2;
if (v > 1)
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
else
- return Encode(std::asin(v));
+ RETURN_RESULT(Encode(std::asin(v)));
}
-ReturnedValue MathObject::method_atan(CallContext *context)
+void MathObject::method_atan(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (v == 0.0)
- return Encode(v);
+ RETURN_RESULT(Encode(v));
else
- return Encode(std::atan(v));
+ RETURN_RESULT(Encode(std::atan(v)));
}
-ReturnedValue MathObject::method_atan2(CallContext *context)
+void MathObject::method_atan2(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v1 = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- double v2 = context->argc() > 1 ? context->args()[1].toNumber() : qt_qnan();
+ double v1 = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v2 = callData->argc > 1 ? callData->args[1].toNumber() : qt_qnan();
if ((v1 < 0) && qt_is_finite(v1) && qt_is_inf(v2) && (copySign(1.0, v2) == 1.0))
- return Encode(copySign(0, -1.0));
+ RETURN_RESULT(Encode(copySign(0, -1.0)));
if ((v1 == 0.0) && (v2 == 0.0)) {
if ((copySign(1.0, v1) == 1.0) && (copySign(1.0, v2) == -1.0)) {
- return Encode(M_PI);
+ RETURN_RESULT(Encode(M_PI));
} else if ((copySign(1.0, v1) == -1.0) && (copySign(1.0, v2) == -1.0)) {
- return Encode(-M_PI);
+ RETURN_RESULT(Encode(-M_PI));
}
}
- return Encode(std::atan2(v1, v2));
+ RETURN_RESULT(Encode(std::atan2(v1, v2)));
}
-ReturnedValue MathObject::method_ceil(CallContext *context)
+void MathObject::method_ceil(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (v < 0.0 && v > -1.0)
- return Encode(copySign(0, -1.0));
+ RETURN_RESULT(Encode(copySign(0, -1.0)));
else
- return Encode(std::ceil(v));
+ RETURN_RESULT(Encode(std::ceil(v)));
}
-ReturnedValue MathObject::method_cos(CallContext *context)
+void MathObject::method_cos(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- return Encode(std::cos(v));
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ RETURN_RESULT(Encode(std::cos(v)));
}
-ReturnedValue MathObject::method_exp(CallContext *context)
+void MathObject::method_exp(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (qt_is_inf(v)) {
if (copySign(1.0, v) == -1.0)
- return Encode(0);
+ RETURN_RESULT(Encode(0));
else
- return Encode(qt_inf());
+ RETURN_RESULT(Encode(qt_inf()));
} else {
- return Encode(std::exp(v));
+ RETURN_RESULT(Encode(std::exp(v)));
}
}
-ReturnedValue MathObject::method_floor(CallContext *context)
+void MathObject::method_floor(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- return Encode(std::floor(v));
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ RETURN_RESULT(Encode(std::floor(v)));
}
-ReturnedValue MathObject::method_log(CallContext *context)
+void MathObject::method_log(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (v < 0)
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
else
- return Encode(std::log(v));
+ RETURN_RESULT(Encode(std::log(v)));
}
-ReturnedValue MathObject::method_max(CallContext *context)
+void MathObject::method_max(const BuiltinFunction *, Scope &scope, CallData *callData)
{
double mx = -qt_inf();
- for (int i = 0; i < context->argc(); ++i) {
- double x = context->args()[i].toNumber();
+ for (int i = 0; i < callData->argc; ++i) {
+ double x = callData->args[i].toNumber();
if (x > mx || std::isnan(x))
mx = x;
}
- return Encode(mx);
+ RETURN_RESULT(Encode(mx));
}
-ReturnedValue MathObject::method_min(CallContext *context)
+void MathObject::method_min(const BuiltinFunction *, Scope &scope, CallData *callData)
{
double mx = qt_inf();
- for (int i = 0; i < context->argc(); ++i) {
- double x = context->args()[i].toNumber();
+ for (int i = 0; i < callData->argc; ++i) {
+ double x = callData->args[i].toNumber();
if ((x == 0 && mx == x && copySign(1.0, x) == -1.0)
|| (x < mx) || std::isnan(x)) {
mx = x;
}
}
- return Encode(mx);
+ RETURN_RESULT(Encode(mx));
}
-ReturnedValue MathObject::method_pow(CallContext *context)
+void MathObject::method_pow(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double x = context->argc() > 0 ? context->args()[0].toNumber() : qt_qnan();
- double y = context->argc() > 1 ? context->args()[1].toNumber() : qt_qnan();
+ double x = callData->argc > 0 ? callData->args[0].toNumber() : qt_qnan();
+ double y = callData->argc > 1 ? callData->args[1].toNumber() : qt_qnan();
if (std::isnan(y))
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
if (y == 0) {
- return Encode(1);
+ RETURN_RESULT(Encode(1));
} else if (((x == 1) || (x == -1)) && std::isinf(y)) {
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
} else if (((x == 0) && copySign(1.0, x) == 1.0) && (y < 0)) {
- return Encode(qInf());
+ RETURN_RESULT(Encode(qInf()));
} else if ((x == 0) && copySign(1.0, x) == -1.0) {
if (y < 0) {
if (std::fmod(-y, 2.0) == 1.0)
- return Encode(-qt_inf());
+ RETURN_RESULT(Encode(-qt_inf()));
else
- return Encode(qt_inf());
+ RETURN_RESULT(Encode(qt_inf()));
} else if (y > 0) {
if (std::fmod(y, 2.0) == 1.0)
- return Encode(copySign(0, -1.0));
+ RETURN_RESULT(Encode(copySign(0, -1.0)));
else
- return Encode(0);
+ RETURN_RESULT(Encode(0));
}
}
@@ -253,78 +253,78 @@ ReturnedValue MathObject::method_pow(CallContext *context)
else if (qt_is_inf(x) && copySign(1.0, x) == -1.0) {
if (y > 0) {
if (std::fmod(y, 2.0) == 1.0)
- return Encode(-qt_inf());
+ RETURN_RESULT(Encode(-qt_inf()));
else
- return Encode(qt_inf());
+ RETURN_RESULT(Encode(qt_inf()));
} else if (y < 0) {
if (std::fmod(-y, 2.0) == 1.0)
- return Encode(copySign(0, -1.0));
+ RETURN_RESULT(Encode(copySign(0, -1.0)));
else
- return Encode(0);
+ RETURN_RESULT(Encode(0));
}
}
#endif
else {
- return Encode(std::pow(x, y));
+ RETURN_RESULT(Encode(std::pow(x, y)));
}
// ###
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
}
Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage);
-ReturnedValue MathObject::method_random(CallContext *context)
+void MathObject::method_random(const BuiltinFunction *, Scope &scope, CallData *)
{
if (!seedCreatedStorage()->hasLocalData()) {
int msecs = QTime(0,0,0).msecsTo(QTime::currentTime());
Q_ASSERT(msecs >= 0);
- qsrand(uint(uint(msecs) ^ reinterpret_cast<quintptr>(context)));
+ qsrand(uint(uint(msecs) ^ reinterpret_cast<quintptr>(scope.engine)));
seedCreatedStorage()->setLocalData(new bool(true));
}
// rand()/qrand() return a value where the upperbound is RAND_MAX inclusive. So, instead of
// dividing by RAND_MAX (which would return 0..RAND_MAX inclusive), we divide by RAND_MAX + 1.
qint64 upperLimit = qint64(RAND_MAX) + 1;
- return Encode(qrand() / double(upperLimit));
+ RETURN_RESULT(Encode(qrand() / double(upperLimit)));
}
-ReturnedValue MathObject::method_round(CallContext *context)
+void MathObject::method_round(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
v = copySign(std::floor(v + 0.5), v);
- return Encode(v);
+ RETURN_RESULT(Encode(v));
}
-ReturnedValue MathObject::method_sign(CallContext *context)
+void MathObject::method_sign(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (std::isnan(v))
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
if (qIsNull(v))
- return v;
+ RETURN_RESULT(Encode(v));
- return Encode(std::signbit(v) ? -1 : 1);
+ RETURN_RESULT(Encode(std::signbit(v) ? -1 : 1));
}
-ReturnedValue MathObject::method_sin(CallContext *context)
+void MathObject::method_sin(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- return Encode(std::sin(v));
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ RETURN_RESULT(Encode(std::sin(v)));
}
-ReturnedValue MathObject::method_sqrt(CallContext *context)
+void MathObject::method_sqrt(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- return Encode(std::sqrt(v));
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ RETURN_RESULT(Encode(std::sqrt(v)));
}
-ReturnedValue MathObject::method_tan(CallContext *context)
+void MathObject::method_tan(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (v == 0.0)
- return Encode(v);
+ RETURN_RESULT(Encode(v));
else
- return Encode(std::tan(v));
+ RETURN_RESULT(Encode(std::tan(v)));
}
diff --git a/src/qml/jsruntime/qv4mathobject_p.h b/src/qml/jsruntime/qv4mathobject_p.h
index f6b1a4395f..e617712905 100644
--- a/src/qml/jsruntime/qv4mathobject_p.h
+++ b/src/qml/jsruntime/qv4mathobject_p.h
@@ -69,25 +69,25 @@ struct MathObject: Object
V4_OBJECT2(MathObject, Object)
Q_MANAGED_TYPE(MathObject)
- static ReturnedValue method_abs(CallContext *context);
- static ReturnedValue method_acos(CallContext *context);
- static ReturnedValue method_asin(CallContext *context);
- static ReturnedValue method_atan(CallContext *context);
- static ReturnedValue method_atan2(CallContext *context);
- static ReturnedValue method_ceil(CallContext *context);
- static ReturnedValue method_cos(CallContext *context);
- static ReturnedValue method_exp(CallContext *context);
- static ReturnedValue method_floor(CallContext *context);
- static ReturnedValue method_log(CallContext *context);
- static ReturnedValue method_max(CallContext *context);
- static ReturnedValue method_min(CallContext *context);
- static ReturnedValue method_pow(CallContext *context);
- static ReturnedValue method_random(CallContext *context);
- static ReturnedValue method_round(CallContext *context);
- static ReturnedValue method_sign(CallContext *context);
- static ReturnedValue method_sin(CallContext *context);
- static ReturnedValue method_sqrt(CallContext *context);
- static ReturnedValue method_tan(CallContext *context);
+ static void method_abs(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_acos(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_asin(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_atan(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_atan2(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_ceil(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_cos(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_exp(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_floor(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_log(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_max(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_min(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_pow(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_random(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_round(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_sign(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_sin(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_sqrt(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_tan(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp
index d5f75415cc..db45c77472 100644
--- a/src/qml/jsruntime/qv4memberdata.cpp
+++ b/src/qml/jsruntime/qv4memberdata.cpp
@@ -55,13 +55,14 @@ void MemberData::markObjects(Heap::Base *that, ExecutionEngine *e)
Heap::MemberData *MemberData::allocate(ExecutionEngine *e, uint n, Heap::MemberData *old)
{
Q_ASSERT(!old || old->size < n);
+ Q_ASSERT(n);
- uint alloc = sizeof(Heap::MemberData) + (n)*sizeof(Value);
+ size_t alloc = MemoryManager::align(sizeof(Heap::MemberData) + (n - 1)*sizeof(Value));
Heap::MemberData *m = e->memoryManager->allocManaged<MemberData>(alloc);
if (old)
- memcpy(m, old, sizeof(Heap::MemberData) + old->size * sizeof(Value));
+ memcpy(m, old, sizeof(Heap::MemberData) + (old->size - 1)* sizeof(Value));
else
m->init();
- m->size = n;
+ m->size = static_cast<uint>((alloc - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
return m;
}
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 3a6b9da763..09644c161d 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -120,61 +120,71 @@ QT_WARNING_POP
defineDefaultProperty(QStringLiteral("toPrecision"), method_toPrecision);
}
-inline ReturnedValue thisNumberValue(ExecutionContext *ctx)
+inline ReturnedValue thisNumberValue(Scope &scope, CallData *callData)
{
- if (ctx->thisObject().isNumber())
- return ctx->thisObject().asReturnedValue();
- NumberObject *n = ctx->thisObject().as<NumberObject>();
- if (!n)
- return ctx->engine()->throwTypeError();
+ if (callData->thisObject.isNumber())
+ return callData->thisObject.asReturnedValue();
+ NumberObject *n = callData->thisObject.as<NumberObject>();
+ if (!n) {
+ scope.engine->throwTypeError();
+ return Encode::undefined();
+ }
return Encode(n->value());
}
-inline double thisNumber(ExecutionContext *ctx)
+inline double thisNumber(Scope &scope, CallData *callData)
{
- if (ctx->thisObject().isNumber())
- return ctx->thisObject().asDouble();
- NumberObject *n = ctx->thisObject().as<NumberObject>();
- if (!n)
- return ctx->engine()->throwTypeError();
+ if (callData->thisObject.isNumber())
+ return callData->thisObject.asDouble();
+ NumberObject *n = callData->thisObject.as<NumberObject>();
+ if (!n) {
+ scope.engine->throwTypeError();
+ return 0;
+ }
return n->value();
}
-ReturnedValue NumberPrototype::method_isFinite(CallContext *ctx)
+void NumberPrototype::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
- return Encode(false);
+ if (!callData->argc) {
+ scope.result = Encode(false);
+ return;
+ }
- double v = ctx->args()[0].toNumber();
- return Encode(!std::isnan(v) && !qt_is_inf(v));
+ double v = callData->args[0].toNumber();
+ scope.result = Encode(!std::isnan(v) && !qt_is_inf(v));
}
-ReturnedValue NumberPrototype::method_isNaN(CallContext *ctx)
+void NumberPrototype::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
- return Encode(false);
+ if (!callData->argc) {
+ scope.result = Encode(false);
+ return;
+ }
- double v = ctx->args()[0].toNumber();
- return Encode(std::isnan(v));
+ double v = callData->args[0].toNumber();
+ scope.result = Encode(std::isnan(v));
}
-ReturnedValue NumberPrototype::method_toString(CallContext *ctx)
+void NumberPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- double num = thisNumber(ctx);
- if (scope.engine->hasException)
- return Encode::undefined();
+ double num = thisNumber(scope, callData);
+ CHECK_EXCEPTION();
- if (ctx->argc() && !ctx->args()[0].isUndefined()) {
- int radix = ctx->args()[0].toInt32();
- if (radix < 2 || radix > 36)
- return ctx->engine()->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix")
+ if (callData->argc && !callData->args[0].isUndefined()) {
+ int radix = callData->args[0].toInt32();
+ if (radix < 2 || radix > 36) {
+ scope.result = scope.engine->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix")
.arg(radix));
+ return;
+ }
if (std::isnan(num)) {
- return scope.engine->newString(QStringLiteral("NaN"))->asReturnedValue();
+ scope.result = scope.engine->newString(QStringLiteral("NaN"));
+ return;
} else if (qt_is_inf(num)) {
- return scope.engine->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity"))->asReturnedValue();
+ scope.result = scope.engine->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity"));
+ return;
}
if (radix != 10) {
@@ -204,45 +214,43 @@ ReturnedValue NumberPrototype::method_toString(CallContext *ctx)
}
if (negative)
str.prepend(QLatin1Char('-'));
- return scope.engine->newString(str)->asReturnedValue();
+ scope.result = scope.engine->newString(str);
+ return;
}
}
- return Primitive::fromDouble(num).toString(scope.engine)->asReturnedValue();
+ scope.result = Primitive::fromDouble(num).toString(scope.engine);
}
-ReturnedValue NumberPrototype::method_toLocaleString(CallContext *ctx)
+void NumberPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue v(scope, thisNumberValue(ctx));
- ScopedString str(scope, v->toString(scope.engine));
- if (scope.engine->hasException)
- return Encode::undefined();
- return str.asReturnedValue();
+ ScopedValue v(scope, thisNumberValue(scope, callData));
+ scope.result = v->toString(scope.engine);
+ CHECK_EXCEPTION();
}
-ReturnedValue NumberPrototype::method_valueOf(CallContext *ctx)
+void NumberPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- return thisNumberValue(ctx);
+ scope.result = thisNumberValue(scope, callData);
}
-ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx)
+void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- double v = thisNumber(ctx);
- if (scope.engine->hasException)
- return Encode::undefined();
+ double v = thisNumber(scope, callData);
+ CHECK_EXCEPTION();
double fdigits = 0;
- if (ctx->argc() > 0)
- fdigits = ctx->args()[0].toInteger();
+ if (callData->argc > 0)
+ fdigits = callData->args[0].toInteger();
if (std::isnan(fdigits))
fdigits = 0;
- if (fdigits < 0 || fdigits > 20)
- return ctx->engine()->throwRangeError(ctx->thisObject());
+ if (fdigits < 0 || fdigits > 20) {
+ scope.result = scope.engine->throwRangeError(callData->thisObject);
+ return;
+ }
QString str;
if (std::isnan(v))
@@ -251,48 +259,50 @@ ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx)
str = QString::fromLatin1(v < 0 ? "-Infinity" : "Infinity");
else if (v < 1.e21)
str = NumberLocale::instance()->toString(v, 'f', int(fdigits));
- else
- return RuntimeHelpers::stringFromNumber(ctx->engine(), v)->asReturnedValue();
- return scope.engine->newString(str)->asReturnedValue();
+ else {
+ scope.result = RuntimeHelpers::stringFromNumber(scope.engine, v);
+ return;
+ }
+ scope.result = scope.engine->newString(str);
}
-ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx)
+void NumberPrototype::method_toExponential(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- double d = thisNumber(ctx);
- if (scope.engine->hasException)
- return Encode::undefined();
+ double d = thisNumber(scope, callData);
+ CHECK_EXCEPTION();
int fdigits = NumberLocale::instance()->defaultDoublePrecision;
- if (ctx->argc() && !ctx->args()[0].isUndefined()) {
- fdigits = ctx->args()[0].toInt32();
+ if (callData->argc && !callData->args[0].isUndefined()) {
+ fdigits = callData->args[0].toInt32();
if (fdigits < 0 || fdigits > 20) {
ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range")));
- return ctx->engine()->throwRangeError(error);
+ scope.result = scope.engine->throwRangeError(error);
+ return;
}
}
QString result = NumberLocale::instance()->toString(d, 'e', fdigits);
- return scope.engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
-ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx)
+void NumberPrototype::method_toPrecision(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue v(scope, thisNumberValue(ctx));
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedValue v(scope, thisNumberValue(scope, callData));
+ CHECK_EXCEPTION();
- if (!ctx->argc() || ctx->args()[0].isUndefined())
- return Encode(v->toString(scope.engine));
+ if (!callData->argc || callData->args[0].isUndefined()) {
+ scope.result = v->toString(scope.engine);
+ return;
+ }
- int precision = ctx->args()[0].toInt32();
+ int precision = callData->args[0].toInt32();
if (precision < 1 || precision > 21) {
ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range")));
- return ctx->engine()->throwRangeError(error);
+ scope.result = scope.engine->throwRangeError(error);
+ return;
}
QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision);
- return scope.engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index 6022b3a029..364b866a16 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -87,14 +87,14 @@ struct NumberPrototype: NumberObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_isFinite(CallContext *ctx);
- static ReturnedValue method_isNaN(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_toLocaleString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
- static ReturnedValue method_toFixed(CallContext *ctx);
- static ReturnedValue method_toExponential(CallContext *ctx);
- static ReturnedValue method_toPrecision(CallContext *ctx);
+ static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toFixed(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toExponential(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toPrecision(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 8acca16dd0..eb9cb80cee 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -61,9 +61,8 @@ DEFINE_OBJECT_VTABLE(Object);
void Object::setInternalClass(InternalClass *ic)
{
d()->internalClass = ic;
- if ((ic->size > d()->inlineMemberSize && !d()->memberData) ||
- (d()->memberData && d()->memberData->size < ic->size - d()->inlineMemberSize))
- d()->memberData = MemberData::allocate(ic->engine, ic->size - d()->inlineMemberSize, d()->memberData);
+ if ((!d()->memberData && ic->size) || (d()->memberData->size < ic->size))
+ d()->memberData = MemberData::allocate(ic->engine, ic->size, d()->memberData);
}
void Object::getProperty(uint index, Property *p, PropertyAttributes *attrs) const
@@ -167,6 +166,17 @@ void Object::defineDefaultProperty(const QString &name, ReturnedValue (*code)(Ca
defineDefaultProperty(s, function);
}
+void Object::defineDefaultProperty(const QString &name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount)
+{
+ ExecutionEngine *e = engine();
+ Scope scope(e);
+ ScopedString s(scope, e->newIdentifier(name));
+ ExecutionContext *global = e->rootContext();
+ ScopedFunctionObject function(scope, BuiltinFunction::create(global, s, code));
+ function->defineReadonlyProperty(e->id_length(), Primitive::fromInt32(argumentCount));
+ defineDefaultProperty(s, function);
+}
+
void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(CallContext *), int argumentCount)
{
ExecutionEngine *e = engine();
@@ -177,6 +187,16 @@ void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(CallConte
defineDefaultProperty(name, function);
}
+void Object::defineDefaultProperty(String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount)
+{
+ ExecutionEngine *e = engine();
+ Scope scope(e);
+ ExecutionContext *global = e->rootContext();
+ ScopedFunctionObject function(scope, BuiltinFunction::create(global, name, code));
+ function->defineReadonlyProperty(e->id_length(), Primitive::fromInt32(argumentCount));
+ defineDefaultProperty(name, function);
+}
+
void Object::defineAccessorProperty(const QString &name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *))
{
ExecutionEngine *e = engine();
@@ -196,6 +216,27 @@ void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(CallCo
insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
+void Object::defineAccessorProperty(const QString &name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
+ void (*setter)(const BuiltinFunction *, Scope &, CallData *))
+{
+ ExecutionEngine *e = engine();
+ Scope scope(e);
+ ScopedString s(scope, e->newIdentifier(name));
+ defineAccessorProperty(s, getter, setter);
+}
+
+void Object::defineAccessorProperty(String *name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
+ void (*setter)(const BuiltinFunction *, Scope &, CallData *))
+{
+ ExecutionEngine *v4 = engine();
+ QV4::Scope scope(v4);
+ ScopedProperty p(scope);
+ ExecutionContext *global = v4->rootContext();
+ p->setGetter(ScopedFunctionObject(scope, (getter ? BuiltinFunction::create(global, name, getter) : 0)));
+ p->setSetter(ScopedFunctionObject(scope, (setter ? BuiltinFunction::create(global, name, setter) : 0)));
+ insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
+}
+
void Object::defineReadonlyProperty(const QString &name, const Value &value)
{
QV4::ExecutionEngine *e = engine();
@@ -213,12 +254,6 @@ void Object::markObjects(Heap::Base *that, ExecutionEngine *e)
{
Heap::Object *o = static_cast<Heap::Object *>(that);
- if (o->inlineMemberSize) {
- Value *v = o->propertyData(0);
- for (uint i = 0; i < o->inlineMemberSize; ++i)
- v[i].mark(e);
- }
-
if (o->memberData)
o->memberData->mark(e);
if (o->arrayData)
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 6c679deb10..4a78690f47 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -63,17 +63,17 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+struct BuiltinFunction;
+
namespace Heap {
struct Object : Base {
void init() { Base::init(); }
void destroy() { Base::destroy(); }
- const Value *propertyData(uint index) const { if (index < inlineMemberSize) return reinterpret_cast<const Value *>(this) + inlineMemberOffset + index; return memberData->data + index - inlineMemberSize; }
- Value *propertyData(uint index) { if (index < inlineMemberSize) return reinterpret_cast<Value *>(this) + inlineMemberOffset + index; return memberData->data + index - inlineMemberSize; }
+ const Value *propertyData(uint index) const { return memberData->data + index; }
+ Value *propertyData(uint index) { return memberData->data + index; }
- uint inlineMemberOffset;
- uint inlineMemberSize;
InternalClass *internalClass;
Pointer<Object> prototype;
Pointer<MemberData> memberData;
@@ -238,9 +238,15 @@ struct Q_QML_EXPORT Object: Managed {
}
void defineDefaultProperty(const QString &name, const Value &value);
void defineDefaultProperty(const QString &name, ReturnedValue (*code)(CallContext *), int argumentCount = 0);
+ void defineDefaultProperty(const QString &name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount = 0);
void defineDefaultProperty(String *name, ReturnedValue (*code)(CallContext *), int argumentCount = 0);
+ void defineDefaultProperty(String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount = 0);
void defineAccessorProperty(const QString &name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *));
void defineAccessorProperty(String *name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *));
+ void defineAccessorProperty(const QString &name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
+ void (*setter)(const BuiltinFunction *, Scope &, CallData *));
+ void defineAccessorProperty(String *name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
+ void (*setter)(const BuiltinFunction *, Scope &, CallData *));
/* Fixed: Writable: false, Enumerable: false, Configurable: false */
void defineReadonlyProperty(const QString &name, const Value &value);
void defineReadonlyProperty(String *name, const Value &value);
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 8191083544..97dbe24339 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -121,100 +121,100 @@ void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
insertMember(v4->id___proto__(), p, Attr_Accessor|Attr_NotEnumerable);
}
-ReturnedValue ObjectPrototype::method_getPrototypeOf(CallContext *ctx)
+void ObjectPrototype::method_getPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
ScopedObject p(scope, o->prototype());
- return !!p ? p->asReturnedValue() : Encode::null();
+ scope.result = !!p ? p->asReturnedValue() : Encode::null();
}
-ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(CallContext *ctx)
+void ObjectPrototype::method_getOwnPropertyDescriptor(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject O(scope, ctx->argument(0));
- if (!O)
- return ctx->engine()->throwTypeError();
+ ScopedObject O(scope, callData->argument(0));
+ if (!O) {
+ scope.result = scope.engine->throwTypeError();
+ return;
+ }
if (ArgumentsObject::isNonStrictArgumentsObject(O))
static_cast<ArgumentsObject *>(O.getPointer())->fullyCreate();
- ScopedValue v(scope, ctx->argument(1));
+ ScopedValue v(scope, callData->argument(1));
ScopedString name(scope, v->toString(scope.engine));
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
+
PropertyAttributes attrs;
ScopedProperty desc(scope);
O->getOwnProperty(name, &attrs, desc);
- return fromPropertyDescriptor(scope.engine, desc, attrs);
+ scope.result = fromPropertyDescriptor(scope.engine, desc, attrs);
}
-ReturnedValue ObjectPrototype::method_getOwnPropertyNames(CallContext *context)
+void ObjectPrototype::method_getOwnPropertyNames(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(context);
- ScopedObject O(scope, context->argument(0));
- if (!O)
- return context->engine()->throwTypeError();
+ ScopedObject O(scope, callData->argument(0));
+ if (!O) {
+ scope.result = scope.engine->throwTypeError();
+ return;
+ }
- ScopedArrayObject array(scope, getOwnPropertyNames(context->d()->engine, context->args()[0]));
- return array.asReturnedValue();
+ scope.result = getOwnPropertyNames(scope.engine, callData->args[0]);
}
-ReturnedValue ObjectPrototype::method_create(CallContext *ctx)
+void ObjectPrototype::method_create(const BuiltinFunction *builtin, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue O(scope, ctx->argument(0));
- if (!O->isObject() && !O->isNull())
- return ctx->engine()->throwTypeError();
+ ScopedValue O(scope, callData->argument(0));
+ if (!O->isObject() && !O->isNull()) {
+ scope.result = scope.engine->throwTypeError();
+ return;
+ }
- ScopedObject newObject(scope, ctx->d()->engine->newObject());
+ ScopedObject newObject(scope, scope.engine->newObject());
newObject->setPrototype(O->as<Object>());
- if (ctx->argc() > 1 && !ctx->args()[1].isUndefined()) {
- ctx->d()->callData->args[0] = newObject.asReturnedValue();
- return method_defineProperties(ctx);
+ if (callData->argc > 1 && !callData->args[1].isUndefined()) {
+ callData->args[0] = newObject;
+ method_defineProperties(builtin, scope, callData);
+ return;
}
- return newObject.asReturnedValue();
+ scope.result = newObject;
}
-ReturnedValue ObjectPrototype::method_defineProperty(CallContext *ctx)
+void ObjectPrototype::method_defineProperty(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject O(scope, ctx->argument(0));
- if (!O)
- return ctx->engine()->throwTypeError();
+ ScopedObject O(scope, callData->argument(0));
+ if (!O) {
+ scope.result = scope.engine->throwTypeError();
+ return;
+ }
- ScopedString name(scope, ctx->argument(1), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString name(scope, callData->argument(1), ScopedString::Convert);
+ CHECK_EXCEPTION();
- ScopedValue attributes(scope, ctx->argument(2));
+ ScopedValue attributes(scope, callData->argument(2));
ScopedProperty pd(scope);
PropertyAttributes attrs;
toPropertyDescriptor(scope.engine, attributes, pd, &attrs);
- if (scope.engine->hasException)
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (!O->__defineOwnProperty__(scope.engine, name, pd, attrs))
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return O.asReturnedValue();
+ scope.result = O;
}
-ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
+void ObjectPrototype::method_defineProperties(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject O(scope, ctx->argument(0));
+ ScopedObject O(scope, callData->argument(0));
if (!O)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
+
+ ScopedObject o(scope, callData->argument(1), ScopedObject::Convert);
+ CHECK_EXCEPTION();
- ScopedObject o(scope, ctx->argument(1), ScopedObject::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
ScopedValue val(scope);
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
@@ -230,26 +230,24 @@ ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
PropertyAttributes nattrs;
val = o->getValue(pd->value, attrs);
toPropertyDescriptor(scope.engine, val, n, &nattrs);
- if (scope.engine->hasException)
- return Encode::undefined();
+ CHECK_EXCEPTION();
bool ok;
if (name)
ok = O->__defineOwnProperty__(scope.engine, name, n, nattrs);
else
ok = O->__defineOwnProperty__(scope.engine, index, n, nattrs);
if (!ok)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
}
- return O.asReturnedValue();
+ scope.result = O;
}
-ReturnedValue ObjectPrototype::method_seal(CallContext *ctx)
+void ObjectPrototype::method_seal(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
o->setInternalClass(o->internalClass()->sealed());
@@ -261,15 +259,14 @@ ReturnedValue ObjectPrototype::method_seal(CallContext *ctx)
}
}
- return o.asReturnedValue();
+ scope.result = o;
}
-ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx)
+void ObjectPrototype::method_freeze(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (ArgumentsObject::isNonStrictArgumentsObject(o))
static_cast<ArgumentsObject *>(o.getPointer())->fullyCreate();
@@ -285,96 +282,111 @@ ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx)
o->arrayData()->attrs[i].setWritable(false);
}
}
- return o.asReturnedValue();
+ scope.result = o;
}
-ReturnedValue ObjectPrototype::method_preventExtensions(CallContext *ctx)
+void ObjectPrototype::method_preventExtensions(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
o->setInternalClass(o->internalClass()->nonExtensible());
- return o.asReturnedValue();
+ scope.result = o;
}
-ReturnedValue ObjectPrototype::method_isSealed(CallContext *ctx)
+void ObjectPrototype::method_isSealed(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- if (o->isExtensible())
- return Encode(false);
+ if (o->isExtensible()) {
+ scope.result = Encode(false);
+ return;
+ }
- if (o->internalClass() != o->internalClass()->sealed())
- return Encode(false);
+ if (o->internalClass() != o->internalClass()->sealed()) {
+ scope.result = Encode(false);
+ return;
+ }
- if (!o->arrayData() || !o->arrayData()->length())
- return Encode(true);
+ if (!o->arrayData() || !o->arrayData()->length()) {
+ scope.result = Encode(true);
+ return;
+ }
Q_ASSERT(o->arrayData() && o->arrayData()->length());
- if (!o->arrayData()->attrs)
- return Encode(false);
+ if (!o->arrayData()->attrs) {
+ scope.result = Encode(false);
+ return;
+ }
for (uint i = 0; i < o->arrayData()->alloc; ++i) {
if (!o->arrayData()->isEmpty(i))
- if (o->arrayData()->attributes(i).isConfigurable())
- return Encode(false);
+ if (o->arrayData()->attributes(i).isConfigurable()) {
+ scope.result = Encode(false);
+ return;
+ }
}
- return Encode(true);
+ scope.result = Encode(true);
}
-ReturnedValue ObjectPrototype::method_isFrozen(CallContext *ctx)
+void ObjectPrototype::method_isFrozen(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- if (o->isExtensible())
- return Encode(false);
+ if (o->isExtensible()) {
+ scope.result = Encode(false);
+ return;
+ }
- if (o->internalClass() != o->internalClass()->frozen())
- return Encode(false);
+ if (o->internalClass() != o->internalClass()->frozen()) {
+ scope.result = Encode(false);
+ return;
+ }
- if (!o->arrayData() || !o->arrayData()->length())
- return Encode(true);
+ if (!o->arrayData() || !o->arrayData()->length()) {
+ scope.result = Encode(true);
+ return;
+ }
Q_ASSERT(o->arrayData() && o->arrayData()->length());
- if (!o->arrayData()->attrs)
- return Encode(false);
+ if (!o->arrayData()->attrs) {
+ scope.result = Encode(false);
+ return;
+ }
for (uint i = 0; i < o->arrayData()->alloc; ++i) {
if (!o->arrayData()->isEmpty(i))
- if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable())
- return Encode(false);
+ if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable()) {
+ scope.result = Encode(false);
+ return;
+ }
}
- return Encode(true);
+ scope.result = Encode(true);
}
-ReturnedValue ObjectPrototype::method_isExtensible(CallContext *ctx)
+void ObjectPrototype::method_isExtensible(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode((bool)o->isExtensible());
+ scope.result = Encode((bool)o->isExtensible());
}
-ReturnedValue ObjectPrototype::method_keys(CallContext *ctx)
+void ObjectPrototype::method_keys(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedArrayObject a(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject a(scope, scope.engine->newArrayObject());
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
ScopedValue name(scope);
@@ -385,175 +397,159 @@ ReturnedValue ObjectPrototype::method_keys(CallContext *ctx)
a->push_back(name);
}
- return a.asReturnedValue();
+ scope.result = a;
}
-ReturnedValue ObjectPrototype::method_toString(CallContext *ctx)
+void ObjectPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- if (ctx->thisObject().isUndefined()) {
- return ctx->d()->engine->newString(QStringLiteral("[object Undefined]"))->asReturnedValue();
- } else if (ctx->thisObject().isNull()) {
- return ctx->d()->engine->newString(QStringLiteral("[object Null]"))->asReturnedValue();
+ if (callData->thisObject.isUndefined()) {
+ scope.result = scope.engine->newString(QStringLiteral("[object Undefined]"));
+ } else if (callData->thisObject.isNull()) {
+ scope.result = scope.engine->newString(QStringLiteral("[object Null]"));
} else {
- ScopedObject obj(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject obj(scope, callData->thisObject.toObject(scope.engine));
QString className = obj->className();
- return ctx->d()->engine->newString(QStringLiteral("[object %1]").arg(className))->asReturnedValue();
+ scope.result = scope.engine->newString(QStringLiteral("[object %1]").arg(className));
}
}
-ReturnedValue ObjectPrototype::method_toLocaleString(CallContext *ctx)
+void ObjectPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject o(scope, callData->thisObject.toObject(scope.engine));
if (!o)
- return Encode::undefined();
- ScopedFunctionObject f(scope, o->get(ctx->d()->engine->id_toString()));
+ RETURN_UNDEFINED();
+
+ ScopedFunctionObject f(scope, o->get(scope.engine->id_toString()));
if (!f)
- return ctx->engine()->throwTypeError();
- ScopedCallData callData(scope);
- callData->thisObject = o;
+ THROW_TYPE_ERROR();
+ ScopedCallData cData(scope);
+ cData->thisObject = o;
f->call(scope, callData);
- return scope.result.asReturnedValue();
}
-ReturnedValue ObjectPrototype::method_valueOf(CallContext *ctx)
+void ObjectPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue v(scope, ctx->thisObject().toObject(scope.engine));
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
- return v->asReturnedValue();
+ scope.result = callData->thisObject.toObject(scope.engine);
}
-ReturnedValue ObjectPrototype::method_hasOwnProperty(CallContext *ctx)
+void ObjectPrototype::method_hasOwnProperty(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedString P(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
- ScopedObject O(scope, ctx->thisObject(), ScopedObject::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString P(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
+ ScopedObject O(scope, callData->thisObject, ScopedObject::Convert);
+ CHECK_EXCEPTION();
bool r = O->hasOwnProperty(P);
if (!r)
r = !O->query(P).isEmpty();
- return Encode(r);
+ scope.result = Encode(r);
}
-ReturnedValue ObjectPrototype::method_isPrototypeOf(CallContext *ctx)
+void ObjectPrototype::method_isPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject V(scope, ctx->argument(0));
- if (!V)
- return Encode(false);
+ ScopedObject V(scope, callData->argument(0));
+ if (!V) {
+ scope.result = Encode(false);
+ return;
+ }
- ScopedObject O(scope, ctx->thisObject(), ScopedObject::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedObject O(scope, callData->thisObject, ScopedObject::Convert);
+ CHECK_EXCEPTION();
ScopedObject proto(scope, V->prototype());
while (proto) {
- if (O->d() == proto->d())
- return Encode(true);
+ if (O->d() == proto->d()) {
+ scope.result = Encode(true);
+ return;
+ }
proto = proto->prototype();
}
- return Encode(false);
+ scope.result = Encode(false);
}
-ReturnedValue ObjectPrototype::method_propertyIsEnumerable(CallContext *ctx)
+void ObjectPrototype::method_propertyIsEnumerable(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedString p(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString p(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
- ScopedObject o(scope, ctx->thisObject(), ScopedObject::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedObject o(scope, callData->thisObject, ScopedObject::Convert);
+ CHECK_EXCEPTION();
PropertyAttributes attrs;
o->getOwnProperty(p, &attrs);
- return Encode(attrs.isEnumerable());
+ scope.result = Encode(attrs.isEnumerable());
}
-ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx)
+void ObjectPrototype::method_defineGetter(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 2)
- return ctx->engine()->throwTypeError();
+ if (callData->argc < 2)
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedFunctionObject f(scope, ctx->argument(1));
+ ScopedFunctionObject f(scope, callData->argument(1));
if (!f)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedString prop(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString prop(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
- ScopedObject o(scope, ctx->thisObject());
+ ScopedObject o(scope, callData->thisObject);
if (!o) {
- if (!ctx->thisObject().isUndefined())
- return Encode::undefined();
- o = ctx->d()->engine->globalObject;
+ if (!callData->thisObject.isUndefined())
+ RETURN_UNDEFINED();
+ o = scope.engine->globalObject;
}
ScopedProperty pd(scope);
pd->value = f;
pd->set = Primitive::emptyValue();
o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx)
+void ObjectPrototype::method_defineSetter(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 2)
- return ctx->engine()->throwTypeError();
+ if (callData->argc < 2)
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedFunctionObject f(scope, ctx->argument(1));
+ ScopedFunctionObject f(scope, callData->argument(1));
if (!f)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedString prop(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString prop(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
- ScopedObject o(scope, ctx->thisObject());
+ ScopedObject o(scope, callData->thisObject);
if (!o) {
- if (!ctx->thisObject().isUndefined())
- return Encode::undefined();
- o = ctx->d()->engine->globalObject;
+ if (!callData->thisObject.isUndefined())
+ RETURN_UNDEFINED();
+ o = scope.engine->globalObject;
}
ScopedProperty pd(scope);
pd->value = Primitive::emptyValue();
pd->set = f;
o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue ObjectPrototype::method_get_proto(CallContext *ctx)
+void ObjectPrototype::method_get_proto(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject().as<Object>());
+ ScopedObject o(scope, callData->thisObject.as<Object>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return o->prototype()->asReturnedValue();
+ scope.result = o->prototype();
}
-ReturnedValue ObjectPrototype::method_set_proto(CallContext *ctx)
+void ObjectPrototype::method_set_proto(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject());
- if (!o || !ctx->argc())
- return ctx->engine()->throwTypeError();
+ ScopedObject o(scope, callData->thisObject);
+ if (!o || !callData->argc)
+ THROW_TYPE_ERROR();
- if (ctx->args()[0].isNull()) {
+ if (callData->args[0].isNull()) {
o->setPrototype(0);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
- ScopedObject p(scope, ctx->args()[0]);
+ ScopedObject p(scope, callData->args[0]);
bool ok = false;
if (!!p) {
if (o->prototype() == p->d()) {
@@ -562,9 +558,11 @@ ReturnedValue ObjectPrototype::method_set_proto(CallContext *ctx)
ok = o->setPrototype(p);
}
}
- if (!ok)
- return ctx->engine()->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
- return Encode::undefined();
+ if (!ok) {
+ scope.result = scope.engine->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
+ return;
+ }
+ RETURN_UNDEFINED();
}
void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value &v, Property *desc, PropertyAttributes *attrs)
diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h
index e3d85782d5..1db8615511 100644
--- a/src/qml/jsruntime/qv4objectproto_p.h
+++ b/src/qml/jsruntime/qv4objectproto_p.h
@@ -78,32 +78,32 @@ struct ObjectPrototype: Object
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_getPrototypeOf(CallContext *ctx);
- static ReturnedValue method_getOwnPropertyDescriptor(CallContext *ctx);
- static ReturnedValue method_getOwnPropertyNames(CallContext *context);
- static ReturnedValue method_create(CallContext *ctx);
- static ReturnedValue method_defineProperty(CallContext *ctx);
- static ReturnedValue method_defineProperties(CallContext *ctx);
- static ReturnedValue method_seal(CallContext *ctx);
- static ReturnedValue method_freeze(CallContext *ctx);
- static ReturnedValue method_preventExtensions(CallContext *ctx);
- static ReturnedValue method_isSealed(CallContext *ctx);
- static ReturnedValue method_isFrozen(CallContext *ctx);
- static ReturnedValue method_isExtensible(CallContext *ctx);
- static ReturnedValue method_keys(CallContext *ctx);
-
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_toLocaleString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
- static ReturnedValue method_hasOwnProperty(CallContext *ctx);
- static ReturnedValue method_isPrototypeOf(CallContext *ctx);
- static ReturnedValue method_propertyIsEnumerable(CallContext *ctx);
-
- static ReturnedValue method_defineGetter(CallContext *ctx);
- static ReturnedValue method_defineSetter(CallContext *ctx);
-
- static ReturnedValue method_get_proto(CallContext *ctx);
- static ReturnedValue method_set_proto(CallContext *ctx);
+ static void method_getPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getOwnPropertyDescriptor(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getOwnPropertyNames(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_create(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_defineProperty(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_defineProperties(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_seal(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_freeze(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_preventExtensions(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isSealed(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isFrozen(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isExtensible(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_keys(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_hasOwnProperty(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_propertyIsEnumerable(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_defineGetter(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_defineSetter(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_get_proto(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_set_proto(const BuiltinFunction *, Scope &scope, CallData *callData);
static void toPropertyDescriptor(ExecutionEngine *engine, const Value &v, Property *desc, PropertyAttributes *attrs);
static ReturnedValue fromPropertyDescriptor(ExecutionEngine *engine, const Property *desc, PropertyAttributes attrs);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 77dbb18b50..7260e71fab 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -826,40 +826,39 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
} // namespace QV4
-ReturnedValue QObjectWrapper::method_connect(CallContext *ctx)
+void QObjectWrapper::method_connect(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- V4THROW_ERROR("Function.prototype.connect: no arguments given");
+ if (callData->argc == 0)
+ THROW_GENERIC_ERROR("Function.prototype.connect: no arguments given");
- QPair<QObject *, int> signalInfo = extractQtSignal(ctx->thisObject());
+ QPair<QObject *, int> signalInfo = extractQtSignal(callData->thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second; // in method range, not signal range!
if (signalIndex < 0)
- V4THROW_ERROR("Function.prototype.connect: this object is not a signal");
+ THROW_GENERIC_ERROR("Function.prototype.connect: this object is not a signal");
if (!signalObject)
- V4THROW_ERROR("Function.prototype.connect: cannot connect to deleted QObject");
+ THROW_GENERIC_ERROR("Function.prototype.connect: cannot connect to deleted QObject");
if (signalObject->metaObject()->method(signalIndex).methodType() != QMetaMethod::Signal)
- V4THROW_ERROR("Function.prototype.connect: this object is not a signal");
+ THROW_GENERIC_ERROR("Function.prototype.connect: this object is not a signal");
- QV4::Scope scope(ctx);
QV4::ScopedFunctionObject f(scope);
QV4::ScopedValue thisObject (scope, QV4::Encode::undefined());
- if (ctx->argc() == 1) {
- f = ctx->args()[0];
- } else if (ctx->argc() >= 2) {
- thisObject = ctx->args()[0];
- f = ctx->args()[1];
+ if (callData->argc == 1) {
+ f = callData->args[0];
+ } else if (callData->argc >= 2) {
+ thisObject = callData->args[0];
+ f = callData->args[1];
}
if (!f)
- V4THROW_ERROR("Function.prototype.connect: target is not a function");
+ THROW_GENERIC_ERROR("Function.prototype.connect: target is not a function");
if (!thisObject->isUndefined() && !thisObject->isObject())
- V4THROW_ERROR("Function.prototype.connect: target this is not an object");
+ THROW_GENERIC_ERROR("Function.prototype.connect: target this is not an object");
QV4::QObjectSlotDispatcher *slot = new QV4::QObjectSlotDispatcher;
slot->signalIndex = signalIndex;
@@ -874,49 +873,47 @@ ReturnedValue QObjectWrapper::method_connect(CallContext *ctx)
}
QObjectPrivate::connect(signalObject, signalIndex, slot, Qt::AutoConnection);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue QObjectWrapper::method_disconnect(CallContext *ctx)
+void QObjectWrapper::method_disconnect(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- V4THROW_ERROR("Function.prototype.disconnect: no arguments given");
-
- QV4::Scope scope(ctx);
+ if (callData->argc == 0)
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: no arguments given");
- QPair<QObject *, int> signalInfo = extractQtSignal(ctx->thisObject());
+ QPair<QObject *, int> signalInfo = extractQtSignal(callData->thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second;
if (signalIndex == -1)
- V4THROW_ERROR("Function.prototype.disconnect: this object is not a signal");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: this object is not a signal");
if (!signalObject)
- V4THROW_ERROR("Function.prototype.disconnect: cannot disconnect from deleted QObject");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: cannot disconnect from deleted QObject");
if (signalIndex < 0 || signalObject->metaObject()->method(signalIndex).methodType() != QMetaMethod::Signal)
- V4THROW_ERROR("Function.prototype.disconnect: this object is not a signal");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: this object is not a signal");
QV4::ScopedFunctionObject functionValue(scope);
QV4::ScopedValue functionThisValue(scope, QV4::Encode::undefined());
- if (ctx->argc() == 1) {
- functionValue = ctx->args()[0];
- } else if (ctx->argc() >= 2) {
- functionThisValue = ctx->args()[0];
- functionValue = ctx->args()[1];
+ if (callData->argc == 1) {
+ functionValue = callData->args[0];
+ } else if (callData->argc >= 2) {
+ functionThisValue = callData->args[0];
+ functionValue = callData->args[1];
}
if (!functionValue)
- V4THROW_ERROR("Function.prototype.disconnect: target is not a function");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: target is not a function");
if (!functionThisValue->isUndefined() && !functionThisValue->isObject())
- V4THROW_ERROR("Function.prototype.disconnect: target this is not an object");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: target this is not an object");
QPair<QObject *, int> functionData = QObjectMethod::extractQtMethod(functionValue);
void *a[] = {
- ctx->d()->engine,
+ scope.engine,
functionValue.ptr,
functionThisValue.ptr,
functionData.first,
@@ -925,7 +922,7 @@ ReturnedValue QObjectWrapper::method_disconnect(CallContext *ctx)
QObjectPrivate::disconnect(signalObject, signalIndex, reinterpret_cast<void**>(&a));
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
static void markChildQObjectsRecursively(QObject *parent, QV4::ExecutionEngine *e)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index c7c4f4dd77..b09e06cec5 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -197,8 +197,8 @@ protected:
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
- static ReturnedValue method_connect(CallContext *ctx);
- static ReturnedValue method_disconnect(CallContext *ctx);
+ static void method_connect(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_disconnect(const BuiltinFunction *, Scope &scope, CallData *callData);
private:
Q_NEVER_INLINE static ReturnedValue wrap_slowPath(ExecutionEngine *engine, QObject *object);
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 218695624b..40682aaa4b 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -307,7 +307,8 @@ void RegExpCtor::markObjects(Heap::Base *that, ExecutionEngine *e)
{
RegExpCtor::Data *This = static_cast<RegExpCtor::Data *>(that);
This->lastMatch.mark(e);
- This->lastInput->mark(e);
+ if (This->lastInput)
+ This->lastInput->mark(e);
FunctionObject::markObjects(that, e);
}
@@ -348,34 +349,33 @@ void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
defineDefaultProperty(QStringLiteral("compile"), method_compile, 2);
}
-ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
+void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<RegExpObject> r(scope, ctx->thisObject().as<RegExpObject>());
+ Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedValue arg(scope, ctx->argument(0));
+ ScopedValue arg(scope, callData->argument(0));
ScopedString str(scope, arg->toString(scope.engine));
if (scope.hasException())
- return Encode::undefined();
+ RETURN_UNDEFINED();
QString s = str->toQString();
int offset = r->global() ? r->lastIndexProperty()->toInt32() : 0;
if (offset < 0 || offset > s.length()) {
*r->lastIndexProperty() = Primitive::fromInt32(0);
- return Encode::null();
+ RETURN_RESULT(Encode::null());
}
uint* matchOffsets = (uint*)alloca(r->value()->captureCount() * 2 * sizeof(uint));
const int result = Scoped<RegExp>(scope, r->value())->match(s, offset, matchOffsets);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor());
+ Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
regExpCtor->d()->clearLastMatch();
if (result == -1) {
*r->lastIndexProperty() = Primitive::fromInt32(0);
- return Encode::null();
+ RETURN_RESULT(Encode::null());
}
// fill in result data
@@ -386,7 +386,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
for (int i = 0; i < len; ++i) {
int start = matchOffsets[i * 2];
int end = matchOffsets[i * 2 + 1];
- v = (start != -1) ? ctx->d()->engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
+ v = (start != -1) ? scope.engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
array->arrayPut(i, v);
}
array->setArrayLengthUnchecked(len);
@@ -402,84 +402,75 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
if (r->global())
*r->lastIndexProperty() = Primitive::fromInt32(matchOffsets[1]);
- return array.asReturnedValue();
+ scope.result = array;
}
-ReturnedValue RegExpPrototype::method_test(CallContext *ctx)
+void RegExpPrototype::method_test(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue r(scope, method_exec(ctx));
- return Encode(!r->isNull());
+ method_exec(b, scope, callData);
+ scope.result = Encode(!scope.result.isNull());
}
-ReturnedValue RegExpPrototype::method_toString(CallContext *ctx)
+void RegExpPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<RegExpObject> r(scope, ctx->thisObject().as<RegExpObject>());
+ Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return ctx->d()->engine->newString(r->toString())->asReturnedValue();
+ scope.result = scope.engine->newString(r->toString());
}
-ReturnedValue RegExpPrototype::method_compile(CallContext *ctx)
+void RegExpPrototype::method_compile(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<RegExpObject> r(scope, ctx->thisObject().as<RegExpObject>());
+ Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, ctx->argc());
- memcpy(callData->args, ctx->args(), ctx->argc()*sizeof(Value));
+ ScopedCallData cData(scope, callData->argc);
+ memcpy(cData->args, callData->args, callData->argc*sizeof(Value));
- ctx->d()->engine->regExpCtor()->as<FunctionObject>()->construct(scope, callData);
+ scope.engine->regExpCtor()->as<FunctionObject>()->construct(scope, cData);
Scoped<RegExpObject> re(scope, scope.result.asReturnedValue());
r->d()->value = re->value();
r->d()->global = re->global();
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
template <int index>
-ReturnedValue RegExpPrototype::method_get_lastMatch_n(CallContext *ctx)
+void RegExpPrototype::method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *)
{
- Scope scope(ctx);
- ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastMatch());
- ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(index) : Encode::undefined());
- if (result->isUndefined())
- return ctx->d()->engine->newString()->asReturnedValue();
- return result->asReturnedValue();
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch());
+ scope.result = lastMatch ? lastMatch->getIndexed(index) : Encode::undefined();
+ if (scope.result.isUndefined())
+ scope.result = scope.engine->newString();
}
-ReturnedValue RegExpPrototype::method_get_lastParen(CallContext *ctx)
+void RegExpPrototype::method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *)
{
- Scope scope(ctx);
- ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastMatch());
- ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined());
- if (result->isUndefined())
- return ctx->d()->engine->newString()->asReturnedValue();
- return result->asReturnedValue();
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch());
+ scope.result = lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined();
+ if (scope.result.isUndefined())
+ scope.result = scope.engine->newString();
}
-ReturnedValue RegExpPrototype::method_get_input(CallContext *ctx)
+void RegExpPrototype::method_get_input(const BuiltinFunction *, Scope &scope, CallData *)
{
- return static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastInput()->asReturnedValue();
+ scope.result = static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastInput();
}
-ReturnedValue RegExpPrototype::method_get_leftContext(CallContext *ctx)
+void RegExpPrototype::method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *)
{
- Scope scope(ctx);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor());
+ Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
QString lastInput = regExpCtor->lastInput()->toQString();
- return ctx->d()->engine->newString(lastInput.left(regExpCtor->lastMatchStart()))->asReturnedValue();
+ scope.result = scope.engine->newString(lastInput.left(regExpCtor->lastMatchStart()));
}
-ReturnedValue RegExpPrototype::method_get_rightContext(CallContext *ctx)
+void RegExpPrototype::method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *)
{
- Scope scope(ctx);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor());
+ Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
QString lastInput = regExpCtor->lastInput()->toQString();
- return ctx->d()->engine->newString(lastInput.mid(regExpCtor->lastMatchEnd()))->asReturnedValue();
+ scope.result = scope.engine->newString(lastInput.mid(regExpCtor->lastMatchEnd()));
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index 2c82cfdfd1..c0c7dfa78a 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -149,17 +149,17 @@ struct RegExpPrototype: RegExpObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_exec(CallContext *ctx);
- static ReturnedValue method_test(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_compile(CallContext *ctx);
+ static void method_exec(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_test(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_compile(const BuiltinFunction *, Scope &scope, CallData *callData);
template <int index>
- static ReturnedValue method_get_lastMatch_n(CallContext *ctx);
- static ReturnedValue method_get_lastParen(CallContext *ctx);
- static ReturnedValue method_get_input(CallContext *ctx);
- static ReturnedValue method_get_leftContext(CallContext *ctx);
- static ReturnedValue method_get_rightContext(CallContext *ctx);
+ static void method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_input(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index d6c55926b1..023a739e33 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -499,6 +499,7 @@ Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, const Val
{
Scope scope(engine);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, STRING_HINT));
+ Q_ASSERT(!prim->isManaged() || prim->isString());
return RuntimeHelpers::convertToString(engine, prim);
}
case Value::Integer_Type:
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 4e627e003f..6775028272 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -68,6 +68,38 @@ namespace QV4 {
struct ScopedValue;
+#define CHECK_EXCEPTION() \
+ do { \
+ if (scope.hasException()) { \
+ scope.result = QV4::Encode::undefined(); \
+ return; \
+ } \
+ } while (false)
+
+#define RETURN_UNDEFINED() \
+ do { \
+ scope.result = QV4::Encode::undefined(); \
+ return; \
+ } while (false)
+
+#define RETURN_RESULT(r) \
+ do { \
+ scope.result = r; \
+ return; \
+ } while (false)
+
+#define THROW_TYPE_ERROR() \
+ do { \
+ scope.result = scope.engine->throwTypeError(); \
+ return; \
+ } while (false)
+
+#define THROW_GENERIC_ERROR(str) \
+ do { \
+ scope.result = scope.engine->throwError(QString::fromUtf8(str)); \
+ return; \
+ } while (false)
+
struct Scope {
inline Scope(ExecutionContext *ctx)
: engine(ctx->d()->engine)
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index b54177bee9..62145f36cc 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -88,8 +88,6 @@ void Script::parse()
ExecutionEngine *v4 = scope->engine();
Scope valueScope(v4);
- MemoryManager::GCBlocker gcBlocker(v4->memoryManager);
-
IR::Module module(v4->debugger() != 0);
QQmlJS::Engine ee, *engine = &ee;
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 58da7b9f68..8ce10e326d 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -404,28 +404,28 @@ public:
struct CompareFunctor
{
- CompareFunctor(QV4::ExecutionContext *ctx, const QV4::Value &compareFn)
- : m_ctx(ctx), m_compareFn(&compareFn)
+ CompareFunctor(QV4::ExecutionEngine *v4, const QV4::Value &compareFn)
+ : m_v4(v4), m_compareFn(&compareFn)
{}
bool operator()(typename Container::value_type lhs, typename Container::value_type rhs)
{
- QV4::Scope scope(m_ctx);
+ QV4::Scope scope(m_v4);
ScopedObject compare(scope, m_compareFn);
ScopedCallData callData(scope, 2);
- callData->args[0] = convertElementToValue(this->m_ctx->d()->engine, lhs);
- callData->args[1] = convertElementToValue(this->m_ctx->d()->engine, rhs);
- callData->thisObject = this->m_ctx->d()->engine->globalObject;
+ callData->args[0] = convertElementToValue(m_v4, lhs);
+ callData->args[1] = convertElementToValue(m_v4, rhs);
+ callData->thisObject = m_v4->globalObject;
compare->call(scope, callData);
return scope.result.toNumber() < 0;
}
private:
- QV4::ExecutionContext *m_ctx;
+ QV4::ExecutionEngine *m_v4;
const QV4::Value *m_compareFn;
};
- void sort(QV4::CallContext *ctx)
+ void sort(const BuiltinFunction *, Scope &scope, CallData *callData)
{
if (d()->isReference) {
if (!d()->object)
@@ -433,9 +433,8 @@ public:
loadReference();
}
- QV4::Scope scope(ctx);
- if (ctx->argc() == 1 && ctx->args()[0].as<FunctionObject>()) {
- CompareFunctor cf(ctx, ctx->args()[0]);
+ if (callData->argc == 1 && callData->args[0].as<FunctionObject>()) {
+ CompareFunctor cf(scope.engine, callData->args[0]);
std::sort(d()->container->begin(), d()->container->end(), cf);
} else {
DefaultCompareFunctor cf;
@@ -446,45 +445,43 @@ public:
storeReference();
}
- static QV4::ReturnedValue method_get_length(QV4::CallContext *ctx)
+ static void method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->thisObject().as<QQmlSequence<Container> >());
+ QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >());
if (!This)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (This->d()->isReference) {
if (!This->d()->object)
- return QV4::Encode(0);
+ RETURN_RESULT(Encode(0));
This->loadReference();
}
- return QV4::Encode(This->d()->container->count());
+ RETURN_RESULT(Encode(This->d()->container->count()));
}
- static QV4::ReturnedValue method_set_length(QV4::CallContext* ctx)
+ static void method_set_length(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->thisObject().as<QQmlSequence<Container> >());
+ QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >());
if (!This)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- quint32 newLength = ctx->args()[0].toUInt32();
+ quint32 newLength = callData->args[0].toUInt32();
/* Qt containers have int (rather than uint) allowable indexes. */
if (newLength > INT_MAX) {
generateWarning(scope.engine, QLatin1String("Index out of range during length set"));
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/* Read the sequence from the QObject property if we're a reference */
if (This->d()->isReference) {
if (!This->d()->object)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
This->loadReference();
}
/* Determine whether we need to modify the sequence */
qint32 newCount = static_cast<qint32>(newLength);
qint32 count = This->d()->container->count();
if (newCount == count) {
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
} else if (newCount > count) {
/* according to ECMA262r3 we need to insert */
/* undefined values increasing length to newLength. */
@@ -506,7 +503,7 @@ public:
/* write back. already checked that object is non-null, so skip that check here. */
This->storeReference();
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
QVariant toVariant() const
@@ -625,26 +622,25 @@ void SequencePrototype::init()
}
#undef REGISTER_QML_SEQUENCE_METATYPE
-QV4::ReturnedValue SequencePrototype::method_sort(QV4::CallContext *ctx)
+void SequencePrototype::method_sort(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::ScopedObject o(scope, ctx->thisObject());
+ QV4::ScopedObject o(scope, callData->thisObject);
if (!o || !o->isListType())
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- if (ctx->argc() >= 2)
- return o.asReturnedValue();
+ if (callData->argc >= 2)
+ RETURN_RESULT(o);
#define CALL_SORT(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue) \
if (QQml##SequenceElementTypeName##List *s = o->as<QQml##SequenceElementTypeName##List>()) { \
- s->sort(ctx); \
+ s->sort(b, scope, callData); \
} else
FOREACH_QML_SEQUENCE_TYPE(CALL_SORT)
#undef CALL_SORT
{}
- return o.asReturnedValue();
+ RETURN_RESULT(o);
}
#define IS_SEQUENCE(unused1, unused2, SequenceType, unused3) \
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index c0416ad639..6f96b9f760 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -67,12 +67,12 @@ struct SequencePrototype : public QV4::Object
{
void init();
- static ReturnedValue method_valueOf(QV4::CallContext *ctx)
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- return ctx->thisObject().toString(ctx->engine())->asReturnedValue();
+ scope.result = callData->thisObject.toString(scope.engine);
}
- static ReturnedValue method_sort(QV4::CallContext *ctx);
+ static void method_sort(const BuiltinFunction *, Scope &scope, CallData *callData);
static bool isSequenceType(int sequenceTypeId);
static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 1efd8cb714..cde2131aab 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -102,6 +102,7 @@ void Heap::String::init(MemoryManager *mm, String *l, String *r)
stringHash = UINT_MAX;
largestSubLength = qMax(l->largestSubLength, r->largestSubLength);
len = l->len + r->len;
+ Q_ASSERT(largestSubLength <= len);
if (!l->largestSubLength && l->len > largestSubLength)
largestSubLength = l->len;
@@ -113,6 +114,15 @@ void Heap::String::init(MemoryManager *mm, String *l, String *r)
simplifyString();
}
+void Heap::String::destroy() {
+ if (!largestSubLength) {
+ mm->changeUnmanagedHeapSizeUsage(qptrdiff(-text->size) * (int)sizeof(QChar));
+ if (!text->ref.deref())
+ QStringData::deallocate(text);
+ }
+ Base::destroy();
+}
+
uint String::toUInt(bool *ok) const
{
*ok = true;
@@ -151,7 +161,7 @@ void Heap::String::simplifyString() const
text->ref.ref();
identifier = 0;
largestSubLength = 0;
- mm->growUnmanagedHeapSizeUsage(size_t(text->size) * sizeof(QChar));
+ mm->changeUnmanagedHeapSizeUsage(qptrdiff(text->size) * (qptrdiff)sizeof(QChar));
}
void Heap::String::append(const String *data, QChar *ch)
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 4890a85724..5b0fd292d6 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -73,11 +73,7 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
#ifndef V4_BOOTSTRAP
void init(MemoryManager *mm, const QString &text);
void init(MemoryManager *mm, String *l, String *n);
- void destroy() {
- if (!largestSubLength && !text->ref.deref())
- QStringData::deallocate(text);
- Base::destroy();
- }
+ void destroy();
void simplifyString() const;
int length() const {
Q_ASSERT((largestSubLength &&
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 6fbf1c3c85..3c6a24e035 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -214,10 +214,9 @@ void StringPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("trim"), method_trim);
}
-static QString getThisString(ExecutionContext *ctx)
+static QString getThisString(Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue t(scope, ctx->thisObject());
+ ScopedValue t(scope, callData->thisObject);
if (String *s = t->stringValue())
return s->toQString();
if (StringObject *thisString = t->as<StringObject>())
@@ -229,158 +228,146 @@ static QString getThisString(ExecutionContext *ctx)
return t->toQString();
}
-ReturnedValue StringPrototype::method_toString(CallContext *context)
+void StringPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->thisObject().isString())
- return context->thisObject().asReturnedValue();
+ if (callData->thisObject.isString())
+ RETURN_RESULT(callData->thisObject);
- StringObject *o = context->thisObject().as<StringObject>();
+ StringObject *o = callData->thisObject.as<StringObject>();
if (!o)
- return context->engine()->throwTypeError();
- return Encode(o->d()->string);
+ THROW_TYPE_ERROR();
+ scope.result = o->d()->string;
}
-ReturnedValue StringPrototype::method_charAt(CallContext *context)
+void StringPrototype::method_charAt(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const QString str = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ const QString str = getThisString(scope, callData);
+ CHECK_EXCEPTION();
int pos = 0;
- if (context->argc() > 0)
- pos = (int) context->args()[0].toInteger();
+ if (callData->argc > 0)
+ pos = (int) callData->args[0].toInteger();
QString result;
if (pos >= 0 && pos < str.length())
result += str.at(pos);
- return context->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
-ReturnedValue StringPrototype::method_charCodeAt(CallContext *context)
+void StringPrototype::method_charCodeAt(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const QString str = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ const QString str = getThisString(scope, callData);
+ CHECK_EXCEPTION();
int pos = 0;
- if (context->argc() > 0)
- pos = (int) context->args()[0].toInteger();
+ if (callData->argc > 0)
+ pos = (int) callData->args[0].toInteger();
if (pos >= 0 && pos < str.length())
- return Encode(str.at(pos).unicode());
+ RETURN_RESULT(Encode(str.at(pos).unicode()));
- return Encode(qt_qnan());
+ scope.result = Encode(qt_qnan());
}
-ReturnedValue StringPrototype::method_concat(CallContext *context)
+void StringPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(context);
-
- QString value = getThisString(context);
- if (scope.engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
ScopedString s(scope);
- for (int i = 0; i < context->argc(); ++i) {
- s = context->args()[i].toString(scope.engine);
- if (scope.hasException())
- return Encode::undefined();
+ for (int i = 0; i < callData->argc; ++i) {
+ s = callData->args[i].toString(scope.engine);
+ CHECK_EXCEPTION();
+
Q_ASSERT(s->isString());
value += s->toQString();
}
- return context->d()->engine->newString(value)->asReturnedValue();
+ scope.result = scope.engine->newString(value);
}
-ReturnedValue StringPrototype::method_endsWith(CallContext *context)
+void StringPrototype::method_endsWith(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc()) {
- if (context->args()[0].as<RegExpObject>())
- return context->engine()->throwTypeError();
- searchString = context->args()[0].toQString();
+ if (callData->argc) {
+ if (callData->args[0].as<RegExpObject>())
+ THROW_TYPE_ERROR();
+ searchString = callData->args[0].toQString();
}
int pos = value.length();
- if (context->argc() > 1)
- pos = (int) context->args()[1].toInteger();
+ if (callData->argc > 1)
+ pos = (int) callData->args[1].toInteger();
if (pos == value.length())
- return Encode(value.endsWith(searchString));
+ RETURN_RESULT(Encode(value.endsWith(searchString)));
QStringRef stringToSearch = value.leftRef(pos);
- return Encode(stringToSearch.endsWith(searchString));
+ scope.result = Encode(stringToSearch.endsWith(searchString));
}
-ReturnedValue StringPrototype::method_indexOf(CallContext *context)
+void StringPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc())
- searchString = context->args()[0].toQString();
+ if (callData->argc)
+ searchString = callData->args[0].toQString();
int pos = 0;
- if (context->argc() > 1)
- pos = (int) context->args()[1].toInteger();
+ if (callData->argc > 1)
+ pos = (int) callData->args[1].toInteger();
int index = -1;
if (! value.isEmpty())
index = value.indexOf(searchString, qMin(qMax(pos, 0), value.length()));
- return Encode(index);
+ scope.result = Encode(index);
}
-ReturnedValue StringPrototype::method_includes(CallContext *context)
+void StringPrototype::method_includes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc()) {
- if (context->args()[0].as<RegExpObject>())
- return context->engine()->throwTypeError();
- searchString = context->args()[0].toQString();
+ if (callData->argc) {
+ if (callData->args[0].as<RegExpObject>())
+ THROW_TYPE_ERROR();
+ searchString = callData->args[0].toQString();
}
int pos = 0;
- if (context->argc() > 1) {
- Scope scope(context);
- ScopedValue posArg(scope, context->argument(1));
+ if (callData->argc > 1) {
+ ScopedValue posArg(scope, callData->argument(1));
pos = (int) posArg->toInteger();
if (!posArg->isInteger() && posArg->isNumber() && qIsInf(posArg->toNumber()))
pos = value.length();
}
if (pos == 0)
- return Encode(value.contains(searchString));
+ RETURN_RESULT(Encode(value.contains(searchString)));
QStringRef stringToSearch = value.midRef(pos);
- return Encode(stringToSearch.contains(searchString));
+ scope.result = Encode(stringToSearch.contains(searchString));
}
-ReturnedValue StringPrototype::method_lastIndexOf(CallContext *context)
+void StringPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(context);
-
- const QString value = getThisString(context);
- if (scope.engine->hasException)
- return Encode::undefined();
+ const QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc())
- searchString = context->args()[0].toQString();
+ if (callData->argc)
+ searchString = callData->args[0].toQString();
- ScopedValue posArg(scope, context->argument(1));
+ ScopedValue posArg(scope, callData->argument(1));
double position = RuntimeHelpers::toNumber(posArg);
if (std::isnan(position))
position = +qInf();
@@ -391,43 +378,40 @@ ReturnedValue StringPrototype::method_lastIndexOf(CallContext *context)
if (!searchString.isEmpty() && pos == value.length())
--pos;
if (searchString.isNull() && pos == 0)
- return Encode(-1);
+ RETURN_RESULT(Encode(-1));
int index = value.lastIndexOf(searchString, pos);
- return Encode(index);
+ scope.result = Encode(index);
}
-ReturnedValue StringPrototype::method_localeCompare(CallContext *context)
+void StringPrototype::method_localeCompare(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(context);
- const QString value = getThisString(context);
- if (scope.engine->hasException)
- return Encode::undefined();
+ const QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
- ScopedValue v(scope, context->argument(0));
+ ScopedValue v(scope, callData->argument(0));
const QString that = v->toQString();
- return Encode(QString::localeAwareCompare(value, that));
+ scope.result = Encode(QString::localeAwareCompare(value, that));
}
-ReturnedValue StringPrototype::method_match(CallContext *context)
+void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->thisObject().isUndefined() || context->thisObject().isNull())
- return context->engine()->throwTypeError();
+ if (callData->thisObject.isUndefined() || callData->thisObject.isNull())
+ THROW_TYPE_ERROR();
- Scope scope(context);
- ScopedString s(scope, context->thisObject().toString(scope.engine));
+ ScopedString s(scope, callData->thisObject.toString(scope.engine));
- ScopedValue regexp(scope, context->argument(0));
+ ScopedValue regexp(scope, callData->argument(0));
Scoped<RegExpObject> rx(scope, regexp);
if (!rx) {
ScopedCallData callData(scope, 1);
callData->args[0] = regexp;
- context->d()->engine->regExpCtor()->construct(scope, callData);
+ scope.engine->regExpCtor()->construct(scope, callData);
rx = scope.result.asReturnedValue();
}
if (!rx)
// ### CHECK
- return context->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
bool global = rx->global();
@@ -435,24 +419,24 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
ScopedString execString(scope, scope.engine->newString(QStringLiteral("exec")));
ScopedFunctionObject exec(scope, scope.engine->regExpPrototype()->get(execString));
- ScopedCallData callData(scope, 1);
- callData->thisObject = rx;
- callData->args[0] = s;
+ ScopedCallData cData(scope, 1);
+ cData->thisObject = rx;
+ cData->args[0] = s;
if (!global) {
- exec->call(scope, callData);
- return scope.result.asReturnedValue();
+ exec->call(scope, cData);
+ return;
}
- ScopedString lastIndex(scope, context->d()->engine->newString(QStringLiteral("lastIndex")));
+ ScopedString lastIndex(scope, scope.engine->newString(QStringLiteral("lastIndex")));
rx->put(lastIndex, ScopedValue(scope, Primitive::fromInt32(0)));
- ScopedArrayObject a(scope, context->d()->engine->newArrayObject());
+ ScopedArrayObject a(scope, scope.engine->newArrayObject());
double previousLastIndex = 0;
uint n = 0;
ScopedValue matchStr(scope);
ScopedValue index(scope);
while (1) {
- exec->call(scope, callData);
+ exec->call(scope, cData);
if (scope.result.isNull())
break;
assert(scope.result.isObject());
@@ -469,10 +453,9 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
++n;
}
if (!n)
- return Encode::null();
-
- return a.asReturnedValue();
-
+ scope.result = Encode::null();
+ else
+ scope.result = a;
}
static void appendReplacementString(QString *result, const QString &input, const QString& replaceValue, uint* matchOffsets, int captureCount)
@@ -521,14 +504,13 @@ static void appendReplacementString(QString *result, const QString &input, const
}
}
-ReturnedValue StringPrototype::method_replace(CallContext *ctx)
+void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
QString string;
- if (StringObject *thisString = ctx->thisObject().as<StringObject>())
+ if (StringObject *thisString = callData->thisObject.as<StringObject>())
string = thisString->d()->string->toQString();
else
- string = ctx->thisObject().toQString();
+ string = callData->thisObject.toQString();
int numCaptures = 0;
int numStringMatches = 0;
@@ -537,7 +519,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
uint _matchOffsets[64];
uint *matchOffsets = _matchOffsets;
- ScopedValue searchValue(scope, ctx->argument(0));
+ ScopedValue searchValue(scope, callData->argument(0));
Scoped<RegExpObject> regExp(scope, searchValue);
if (regExp) {
uint offset = 0;
@@ -580,7 +562,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
}
QString result;
- ScopedValue replaceValue(scope, ctx->argument(1));
+ ScopedValue replaceValue(scope, callData->argument(1));
ScopedFunctionObject searchCallback(scope, replaceValue);
if (!!searchCallback) {
result.reserve(string.length() + 10*numStringMatches);
@@ -595,14 +577,14 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
uint end = matchOffsets[idx + 1];
entry = Primitive::undefinedValue();
if (start != JSC::Yarr::offsetNoMatch && end != JSC::Yarr::offsetNoMatch)
- entry = ctx->d()->engine->newString(string.mid(start, end - start));
+ entry = scope.engine->newString(string.mid(start, end - start));
callData->args[k] = entry;
}
uint matchStart = matchOffsets[i * numCaptures * 2];
Q_ASSERT(matchStart >= static_cast<uint>(lastEnd));
uint matchEnd = matchOffsets[i * numCaptures * 2 + 1];
callData->args[numCaptures] = Primitive::fromUInt32(matchStart);
- callData->args[numCaptures + 1] = ctx->d()->engine->newString(string);
+ callData->args[numCaptures + 1] = scope.engine->newString(string);
searchCallback->call(scope, callData);
result += string.midRef(lastEnd, matchStart - lastEnd);
@@ -632,23 +614,22 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
if (matchOffsets != _matchOffsets)
free(matchOffsets);
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
-ReturnedValue StringPrototype::method_search(CallContext *ctx)
+void StringPrototype::method_search(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- QString string = getThisString(ctx);
- scope.result = ctx->argument(0);
- if (scope.engine->hasException)
- return Encode::undefined();
+ QString string = getThisString(scope, callData);
+ scope.result = callData->argument(0);
+ CHECK_EXCEPTION();
+
Scoped<RegExpObject> regExp(scope, scope.result.as<RegExpObject>());
if (!regExp) {
ScopedCallData callData(scope, 1);
callData->args[0] = scope.result;
- ctx->d()->engine->regExpCtor()->construct(scope, callData);
- if (scope.engine->hasException)
- return Encode::undefined();
+ scope.engine->regExpCtor()->construct(scope, callData);
+ CHECK_EXCEPTION();
+
regExp = scope.result.as<RegExpObject>();
Q_ASSERT(regExp);
}
@@ -656,21 +637,21 @@ ReturnedValue StringPrototype::method_search(CallContext *ctx)
uint* matchOffsets = (uint*)alloca(regExp->value()->captureCount() * 2 * sizeof(uint));
uint result = re->match(string, /*offset*/0, matchOffsets);
if (result == JSC::Yarr::offsetNoMatch)
- return Encode(-1);
- return Encode(result);
+ scope.result = Encode(-1);
+ else
+ scope.result = Encode(result);
}
-ReturnedValue StringPrototype::method_slice(CallContext *ctx)
+void StringPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const QString text = getThisString(ctx);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
+ const QString text = getThisString(scope, callData);
+ CHECK_EXCEPTION();
const double length = text.length();
- double start = ctx->argc() ? ctx->args()[0].toInteger() : 0;
- double end = (ctx->argc() < 2 || ctx->args()[1].isUndefined())
- ? length : ctx->args()[1].toInteger();
+ double start = callData->argc ? callData->args[0].toInteger() : 0;
+ double end = (callData->argc < 2 || callData->args[1].isUndefined())
+ ? length : callData->args[1].toInteger();
if (start < 0)
start = qMax(length + start, 0.);
@@ -686,40 +667,38 @@ ReturnedValue StringPrototype::method_slice(CallContext *ctx)
const int intEnd = int(end);
int count = qMax(0, intEnd - intStart);
- return ctx->d()->engine->newString(text.mid(intStart, count))->asReturnedValue();
+ scope.result = scope.engine->newString(text.mid(intStart, count));
}
-ReturnedValue StringPrototype::method_split(CallContext *ctx)
+void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- QString text = getThisString(ctx);
- if (scope.engine->hasException)
- return Encode::undefined();
+ QString text = getThisString(scope, callData);
+ CHECK_EXCEPTION();
- ScopedValue separatorValue(scope, ctx->argument(0));
- ScopedValue limitValue(scope, ctx->argument(1));
+ ScopedValue separatorValue(scope, callData->argument(0));
+ ScopedValue limitValue(scope, callData->argument(1));
- ScopedArrayObject array(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject array(scope, scope.engine->newArrayObject());
if (separatorValue->isUndefined()) {
if (limitValue->isUndefined()) {
- ScopedString s(scope, ctx->d()->engine->newString(text));
+ ScopedString s(scope, scope.engine->newString(text));
array->push_back(s);
- return array.asReturnedValue();
+ RETURN_RESULT(array);
}
- return ctx->d()->engine->newString(text.left(limitValue->toInteger()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(text.left(limitValue->toInteger())));
}
uint limit = limitValue->isUndefined() ? UINT_MAX : limitValue->toUInt32();
if (limit == 0)
- return array.asReturnedValue();
+ RETURN_RESULT(array);
Scoped<RegExpObject> re(scope, separatorValue);
if (re) {
if (re->value()->pattern->isEmpty()) {
re = (RegExpObject *)0;
- separatorValue = ctx->d()->engine->newString();
+ separatorValue = scope.engine->newString();
}
}
@@ -733,7 +712,7 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
if (result == JSC::Yarr::offsetNoMatch)
break;
- array->push_back((s = ctx->d()->engine->newString(text.mid(offset, matchOffsets[0] - offset))));
+ array->push_back((s = scope.engine->newString(text.mid(offset, matchOffsets[0] - offset))));
offset = qMax(offset + 1, matchOffsets[1]);
if (array->getLength() >= limit)
@@ -742,72 +721,70 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
for (int i = 1; i < re->value()->captureCount(); ++i) {
uint start = matchOffsets[i * 2];
uint end = matchOffsets[i * 2 + 1];
- array->push_back((s = ctx->d()->engine->newString(text.mid(start, end - start))));
+ array->push_back((s = scope.engine->newString(text.mid(start, end - start))));
if (array->getLength() >= limit)
break;
}
}
if (array->getLength() < limit)
- array->push_back((s = ctx->d()->engine->newString(text.mid(offset))));
+ array->push_back((s = scope.engine->newString(text.mid(offset))));
} else {
QString separator = separatorValue->toQString();
if (separator.isEmpty()) {
for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
- array->push_back((s = ctx->d()->engine->newString(text.mid(i, 1))));
- return array.asReturnedValue();
+ array->push_back((s = scope.engine->newString(text.mid(i, 1))));
+ RETURN_RESULT(array);
}
int start = 0;
int end;
while ((end = text.indexOf(separator, start)) != -1) {
- array->push_back((s = ctx->d()->engine->newString(text.mid(start, end - start))));
+ array->push_back((s = scope.engine->newString(text.mid(start, end - start))));
start = end + separator.size();
if (array->getLength() >= limit)
break;
}
if (array->getLength() < limit && start != -1)
- array->push_back((s = ctx->d()->engine->newString(text.mid(start))));
+ array->push_back((s = scope.engine->newString(text.mid(start))));
}
- return array.asReturnedValue();
+ RETURN_RESULT(array);
}
-ReturnedValue StringPrototype::method_startsWith(CallContext *context)
+void StringPrototype::method_startsWith(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc()) {
- if (context->args()[0].as<RegExpObject>())
- return context->engine()->throwTypeError();
- searchString = context->args()[0].toQString();
+ if (callData->argc) {
+ if (callData->args[0].as<RegExpObject>())
+ THROW_TYPE_ERROR();
+ searchString = callData->args[0].toQString();
}
int pos = 0;
- if (context->argc() > 1)
- pos = (int) context->args()[1].toInteger();
+ if (callData->argc > 1)
+ pos = (int) callData->args[1].toInteger();
if (pos == 0)
- return Encode(value.startsWith(searchString));
+ RETURN_RESULT(Encode(value.startsWith(searchString)));
QStringRef stringToSearch = value.midRef(pos);
- return Encode(stringToSearch.startsWith(searchString));
+ RETURN_RESULT(Encode(stringToSearch.startsWith(searchString)));
}
-ReturnedValue StringPrototype::method_substr(CallContext *context)
+void StringPrototype::method_substr(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ const QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
double start = 0;
- if (context->argc() > 0)
- start = context->args()[0].toInteger();
+ if (callData->argc > 0)
+ start = callData->args[0].toInteger();
double length = +qInf();
- if (context->argc() > 1)
- length = context->args()[1].toInteger();
+ if (callData->argc > 1)
+ length = callData->args[1].toInteger();
double count = value.length();
if (start < 0)
@@ -817,24 +794,23 @@ ReturnedValue StringPrototype::method_substr(CallContext *context)
qint32 x = Primitive::toInt32(start);
qint32 y = Primitive::toInt32(length);
- return context->d()->engine->newString(value.mid(x, y))->asReturnedValue();
+ scope.result = scope.engine->newString(value.mid(x, y));
}
-ReturnedValue StringPrototype::method_substring(CallContext *context)
+void StringPrototype::method_substring(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
+
int length = value.length();
double start = 0;
double end = length;
- if (context->argc() > 0)
- start = context->args()[0].toInteger();
+ if (callData->argc > 0)
+ start = callData->args[0].toInteger();
- Scope scope(context);
- ScopedValue endValue(scope, context->argument(1));
+ ScopedValue endValue(scope, callData->argument(1));
if (!endValue->isUndefined())
end = endValue->toInteger();
@@ -858,51 +834,50 @@ ReturnedValue StringPrototype::method_substring(CallContext *context)
qint32 x = (int)start;
qint32 y = (int)(end - start);
- return context->d()->engine->newString(value.mid(x, y))->asReturnedValue();
+ scope.result = scope.engine->newString(value.mid(x, y));
}
-ReturnedValue StringPrototype::method_toLowerCase(CallContext *ctx)
+void StringPrototype::method_toLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(ctx);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
- return ctx->d()->engine->newString(value.toLower())->asReturnedValue();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
+
+ scope.result = scope.engine->newString(value.toLower());
}
-ReturnedValue StringPrototype::method_toLocaleLowerCase(CallContext *ctx)
+void StringPrototype::method_toLocaleLowerCase(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return method_toLowerCase(ctx);
+ method_toLowerCase(b, scope, callData);
}
-ReturnedValue StringPrototype::method_toUpperCase(CallContext *ctx)
+void StringPrototype::method_toUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(ctx);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
- return ctx->d()->engine->newString(value.toUpper())->asReturnedValue();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
+
+ scope.result = scope.engine->newString(value.toUpper());
}
-ReturnedValue StringPrototype::method_toLocaleUpperCase(CallContext *ctx)
+void StringPrototype::method_toLocaleUpperCase(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return method_toUpperCase(ctx);
+ return method_toUpperCase(b, scope, callData);
}
-ReturnedValue StringPrototype::method_fromCharCode(CallContext *context)
+void StringPrototype::method_fromCharCode(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString str(context->argc(), Qt::Uninitialized);
+ QString str(callData->argc, Qt::Uninitialized);
QChar *ch = str.data();
- for (int i = 0; i < context->argc(); ++i) {
- *ch = QChar(context->args()[i].toUInt16());
+ for (int i = 0; i < callData->argc; ++i) {
+ *ch = QChar(callData->args[i].toUInt16());
++ch;
}
- return context->d()->engine->newString(str)->asReturnedValue();
+ scope.result = scope.engine->newString(str);
}
-ReturnedValue StringPrototype::method_trim(CallContext *ctx)
+void StringPrototype::method_trim(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString s = getThisString(ctx);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
+ QString s = getThisString(scope, callData);
+ CHECK_EXCEPTION();
const QChar *chars = s.constData();
int start, end;
@@ -915,5 +890,5 @@ ReturnedValue StringPrototype::method_trim(CallContext *ctx)
break;
}
- return ctx->d()->engine->newString(QString(chars + start, end - start + 1))->asReturnedValue();
+ scope.result = scope.engine->newString(QString(chars + start, end - start + 1));
}
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index b9f9d44fe8..0ee7a6ece9 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -111,29 +111,29 @@ struct StringPrototype: StringObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_toString(CallContext *context);
- static ReturnedValue method_charAt(CallContext *context);
- static ReturnedValue method_charCodeAt(CallContext *context);
- static ReturnedValue method_concat(CallContext *context);
- static ReturnedValue method_endsWith(CallContext *ctx);
- static ReturnedValue method_indexOf(CallContext *context);
- static ReturnedValue method_includes(CallContext *context);
- static ReturnedValue method_lastIndexOf(CallContext *context);
- static ReturnedValue method_localeCompare(CallContext *context);
- static ReturnedValue method_match(CallContext *context);
- static ReturnedValue method_replace(CallContext *ctx);
- static ReturnedValue method_search(CallContext *ctx);
- static ReturnedValue method_slice(CallContext *ctx);
- static ReturnedValue method_split(CallContext *ctx);
- static ReturnedValue method_startsWith(CallContext *ctx);
- static ReturnedValue method_substr(CallContext *context);
- static ReturnedValue method_substring(CallContext *context);
- static ReturnedValue method_toLowerCase(CallContext *ctx);
- static ReturnedValue method_toLocaleLowerCase(CallContext *ctx);
- static ReturnedValue method_toUpperCase(CallContext *ctx);
- static ReturnedValue method_toLocaleUpperCase(CallContext *ctx);
- static ReturnedValue method_fromCharCode(CallContext *context);
- static ReturnedValue method_trim(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_charAt(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_charCodeAt(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_concat(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_endsWith(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_includes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_localeCompare(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_match(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_replace(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_search(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_slice(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_split(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_startsWith(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_substr(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_substring(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_fromCharCode(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_trim(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 009c573bf8..cecd1e6958 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -438,79 +438,74 @@ void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor)
defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 0);
}
-ReturnedValue TypedArrayPrototype::method_get_buffer(CallContext *ctx)
+void TypedArrayPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> v(scope, ctx->thisObject());
+ Scoped<TypedArray> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->buffer->asReturnedValue());
+ scope.result = v->d()->buffer;
}
-ReturnedValue TypedArrayPrototype::method_get_byteLength(CallContext *ctx)
+void TypedArrayPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> v(scope, ctx->thisObject());
+ Scoped<TypedArray> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteLength);
+ scope.result = Encode(v->d()->byteLength);
}
-ReturnedValue TypedArrayPrototype::method_get_byteOffset(CallContext *ctx)
+void TypedArrayPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> v(scope, ctx->thisObject());
+ Scoped<TypedArray> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteOffset);
+ scope.result = Encode(v->d()->byteOffset);
}
-ReturnedValue TypedArrayPrototype::method_get_length(CallContext *ctx)
+void TypedArrayPrototype::method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> v(scope, ctx->thisObject());
+ Scoped<TypedArray> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteLength/v->d()->type->bytesPerElement);
+ scope.result = Encode(v->d()->byteLength/v->d()->type->bytesPerElement);
}
-ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx)
+void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> a(scope, ctx->thisObject());
+ Scoped<TypedArray> a(scope, callData->thisObject);
if (!a)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
if (!buffer)
scope.engine->throwTypeError();
- double doffset = ctx->argc() >= 2 ? ctx->args()[1].toInteger() : 0;
+ double doffset = callData->argc >= 2 ? callData->args[1].toInteger() : 0;
if (scope.engine->hasException)
- return Encode::undefined();
+ RETURN_UNDEFINED();
if (doffset < 0 || doffset >= UINT_MAX)
- return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"));
+ RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")));
uint offset = (uint)doffset;
uint elementSize = a->d()->type->bytesPerElement;
- Scoped<TypedArray> srcTypedArray(scope, ctx->args()[0]);
+ Scoped<TypedArray> srcTypedArray(scope, callData->args[0]);
if (!srcTypedArray) {
// src is a regular object
- ScopedObject o(scope, ctx->args()[0].toObject(scope.engine));
+ ScopedObject o(scope, callData->args[0].toObject(scope.engine));
if (scope.engine->hasException || !o)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
double len = ScopedValue(scope, o->get(scope.engine->id_length()))->toNumber();
uint l = (uint)len;
if (scope.engine->hasException || l != len)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
if (offset + l > a->length())
- return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"));
+ RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")));
uint idx = 0;
char *b = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize;
@@ -519,28 +514,28 @@ ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx)
val = o->getIndexed(idx);
a->d()->type->write(scope.engine, b, 0, val);
if (scope.engine->hasException)
- return Encode::undefined();
+ RETURN_UNDEFINED();
++idx;
b += elementSize;
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
// src is a typed array
Scoped<ArrayBuffer> srcBuffer(scope, srcTypedArray->d()->buffer);
if (!srcBuffer)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
uint l = srcTypedArray->length();
if (offset + l > a->length())
- return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"));
+ RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")));
char *dest = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize;
const char *src = srcBuffer->d()->data->data() + srcTypedArray->d()->byteOffset;
if (srcTypedArray->d()->type == a->d()->type) {
// same type of typed arrays, use memmove (as srcbuffer and buffer could be the same)
memmove(dest, src, srcTypedArray->d()->byteLength);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
char *srcCopy = 0;
@@ -564,28 +559,27 @@ ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx)
if (srcCopy)
delete [] srcCopy;
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue TypedArrayPrototype::method_subarray(CallContext *ctx)
+void TypedArrayPrototype::method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> a(scope, ctx->thisObject());
+ Scoped<TypedArray> a(scope, callData->thisObject);
if (!a)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
if (!buffer)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
int len = a->length();
- double b = ctx->argc() > 0 ? ctx->args()[0].toInteger() : 0;
+ double b = callData->argc > 0 ? callData->args[0].toInteger() : 0;
if (b < 0)
b = len + b;
uint begin = (uint)qBound(0., b, (double)len);
- double e = ctx->argc() < 2 || ctx->args()[1].isUndefined() ? len : ctx->args()[1].toInteger();
+ double e = callData->argc < 2 || callData->args[1].isUndefined() ? len : callData->args[1].toInteger();
if (e < 0)
e = len + e;
uint end = (uint)qBound(0., e, (double)len);
@@ -593,18 +587,17 @@ ReturnedValue TypedArrayPrototype::method_subarray(CallContext *ctx)
end = begin;
if (scope.engine->hasException)
- return Encode::undefined();
+ RETURN_UNDEFINED();
int newLen = end - begin;
ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor()));
if (!constructor)
- return scope.engine->throwTypeError();
-
- ScopedCallData callData(scope, 3);
- callData->args[0] = buffer;
- callData->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement);
- callData->args[2] = Encode(newLen);
- constructor->construct(scope, callData);
- return scope.result.asReturnedValue();
+ THROW_TYPE_ERROR();
+
+ ScopedCallData cData(scope, 3);
+ cData->args[0] = buffer;
+ cData->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement);
+ cData->args[2] = Encode(newLen);
+ constructor->construct(scope, cData);
}
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index 0112d2e4a1..eefed2db4b 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -151,13 +151,13 @@ struct TypedArrayPrototype : Object
void init(ExecutionEngine *engine, TypedArrayCtor *ctor);
- static ReturnedValue method_get_buffer(CallContext *ctx);
- static ReturnedValue method_get_byteLength(CallContext *ctx);
- static ReturnedValue method_get_byteOffset(CallContext *ctx);
- static ReturnedValue method_get_length(CallContext *ctx);
+ static void method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData);
- static ReturnedValue method_set(CallContext *ctx);
- static ReturnedValue method_subarray(CallContext *ctx);
+ static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData);
};
inline void
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 816b8fb11b..64f0f3a86f 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -544,7 +544,7 @@ inline bool Value::asArrayIndex(uint &idx) const
}
double d = doubleValue();
idx = (uint)d;
- return (idx == d);
+ return (idx == d && idx != UINT_MAX);
}
#endif
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index 455a7ccb65..5cab4c5386 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -113,67 +113,68 @@ void VariantPrototype::init()
defineDefaultProperty(engine()->id_toString(), method_toString, 0);
}
-QV4::ReturnedValue VariantPrototype::method_preserve(CallContext *ctx)
+void VariantPrototype::method_preserve(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->thisObject().as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
if (o && o->d()->isScarce())
o->d()->addVmePropertyReference();
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-QV4::ReturnedValue VariantPrototype::method_destroy(CallContext *ctx)
+void VariantPrototype::method_destroy(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->thisObject().as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
if (o) {
if (o->d()->isScarce())
o->d()->addVmePropertyReference();
o->d()->data() = QVariant();
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-QV4::ReturnedValue VariantPrototype::method_toString(CallContext *ctx)
+void VariantPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->thisObject().as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
if (!o)
- return Encode::undefined();
+ RETURN_UNDEFINED();
QString result = o->d()->data().toString();
if (result.isEmpty() && !o->d()->data().canConvert(QVariant::String)) {
result = QLatin1String("QVariant(")
+ QLatin1String(o->d()->data().typeName())
+ QLatin1Char(')');
}
- return Encode(ctx->d()->engine->newString(result));
+ scope.result = scope.engine->newString(result);
}
-QV4::ReturnedValue VariantPrototype::method_valueOf(CallContext *ctx)
+void VariantPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->thisObject().as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
if (o) {
QVariant v = o->d()->data();
switch (v.type()) {
case QVariant::Invalid:
- return Encode::undefined();
+ scope.result = Encode::undefined();
+ return;
case QVariant::String:
- return Encode(ctx->d()->engine->newString(v.toString()));
+ scope.result = scope.engine->newString(v.toString());
+ return;
case QVariant::Int:
- return Encode(v.toInt());
+ scope.result = Encode(v.toInt());
+ return;
case QVariant::Double:
case QVariant::UInt:
- return Encode(v.toDouble());
+ scope.result = Encode(v.toDouble());
+ return;
case QVariant::Bool:
- return Encode(v.toBool());
+ scope.result = Encode(v.toBool());
+ return;
default:
if (QMetaType::typeFlags(v.userType()) & QMetaType::IsEnumeration)
- return Encode(v.toInt());
+ RETURN_RESULT(Encode(v.toInt()));
break;
}
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index 9a04069c12..ef51b6632d 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -107,10 +107,10 @@ struct VariantPrototype : VariantObject
public:
void init();
- static ReturnedValue method_preserve(CallContext *ctx);
- static ReturnedValue method_destroy(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
+ static void method_preserve(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_destroy(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 622359a7d9..b9183313cd 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -347,6 +347,10 @@ Param traceParam(const Param &param)
goto catchException; \
VALUE(param) = tmp; \
}
+// qv4scopedvalue_p.h also defines a CHECK_EXCEPTION macro
+#ifdef CHECK_EXCEPTION
+#undef CHECK_EXCEPTION
+#endif
#define CHECK_EXCEPTION \
if (engine->hasException) \
goto catchException
diff --git a/src/qml/memory/memory.pri b/src/qml/memory/memory.pri
index 04b7566ccc..38fadbf23f 100644
--- a/src/qml/memory/memory.pri
+++ b/src/qml/memory/memory.pri
@@ -6,8 +6,8 @@ SOURCES += \
$$PWD/qv4mm.cpp \
HEADERS += \
- $$PWD/qv4mm_p.h
-
+ $$PWD/qv4mm_p.h \
+ $$PWD/qv4mmdefs_p.h
}
HEADERS += \
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index 5a3797f397..8285ef4de7 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -52,6 +52,7 @@
#include <QtCore/QString>
#include <private/qv4global_p.h>
+#include <private/qv4mmdefs_p.h>
#include <QSharedPointer>
// To check if Heap::Base::init is called (meaning, all subclasses did their init and called their
@@ -90,43 +91,31 @@ namespace Heap {
struct Q_QML_EXPORT Base {
void *operator new(size_t) = delete;
- quintptr mm_data; // vtable and markbit
+ const VTable *vt;
inline ReturnedValue asReturnedValue() const;
inline void mark(QV4::ExecutionEngine *engine);
- enum {
- MarkBit = 0x1,
- NotInUse = 0x2,
- PointerMask = ~0x3
- };
-
- void setVtable(const VTable *v) {
- Q_ASSERT(!(mm_data & MarkBit));
- mm_data = reinterpret_cast<quintptr>(v);
- }
- VTable *vtable() const {
- return reinterpret_cast<VTable *>(mm_data & PointerMask);
- }
+ void setVtable(const VTable *v) { vt = v; }
+ const VTable *vtable() const { return vt; }
inline bool isMarked() const {
- return mm_data & MarkBit;
+ const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
+ Chunk *c = h->chunk();
+ Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
+ return Chunk::testBit(c->blackBitmap, h - c->realBase());
}
inline void setMarkBit() {
- mm_data |= MarkBit;
- }
- inline void clearMarkBit() {
- mm_data &= ~MarkBit;
+ const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
+ Chunk *c = h->chunk();
+ Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
+ return Chunk::setBit(c->blackBitmap, h - c->realBase());
}
inline bool inUse() const {
- return !(mm_data & NotInUse);
- }
-
- Base *nextFree() {
- return reinterpret_cast<Base *>(mm_data & PointerMask);
- }
- void setNextFree(Base *m) {
- mm_data = (reinterpret_cast<quintptr>(m) | NotInUse);
+ const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
+ Chunk *c = h->chunk();
+ Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
+ return Chunk::testBit(c->objectBitmap, h - c->realBase());
}
void *operator new(size_t, Managed *m) { return m; }
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 606d3ec162..6330ef6038 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -42,8 +42,12 @@
#include "qv4objectproto_p.h"
#include "qv4mm_p.h"
#include "qv4qobjectwrapper_p.h"
+#include <QtCore/qalgorithms.h>
+#include <QtCore/private/qnumeric_p.h>
#include <qqmlengine.h>
+#include "PageReservation.h"
#include "PageAllocation.h"
+#include "PageAllocationAligned.h"
#include "StdLibExtras.h"
#include <QElapsedTimer>
@@ -56,6 +60,14 @@
#include "qv4alloca_p.h"
#include "qv4profiling_p.h"
+#define MM_DEBUG 0
+
+#if MM_DEBUG
+#define DEBUG qDebug() << "MM:"
+#else
+#define DEBUG if (1) ; else qDebug() << "MM:"
+#endif
+
#ifdef V4_USE_VALGRIND
#include <valgrind/valgrind.h>
#include <valgrind/memcheck.h>
@@ -79,319 +91,616 @@ using namespace WTF;
QT_BEGIN_NAMESPACE
-static uint maxShiftValue()
-{
- static uint result = 0;
- if (!result) {
- result = 6;
- if (Q_UNLIKELY(qEnvironmentVariableIsSet(QV4_MM_MAXBLOCK_SHIFT))) {
- bool ok;
- const uint overrideValue = qgetenv(QV4_MM_MAXBLOCK_SHIFT).toUInt(&ok);
- if (ok && overrideValue <= 11 && overrideValue > 0)
- result = overrideValue;
+namespace QV4 {
+
+enum {
+ MinSlotsGCLimit = QV4::Chunk::AvailableSlots*16,
+ GCOverallocation = 200 /* Max overallocation by the GC in % */
+};
+
+struct MemorySegment {
+ enum {
+ NumChunks = 8*sizeof(quint64),
+ SegmentSize = NumChunks*Chunk::ChunkSize,
+ };
+
+ MemorySegment(size_t size)
+ {
+ size += Chunk::ChunkSize; // make sure we can get enough 64k aligment memory
+ if (size < SegmentSize)
+ size = SegmentSize;
+
+ 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())
+ --nChunks;
+ }
+ MemorySegment(MemorySegment &&other) {
+ qSwap(pageReservation, other.pageReservation);
+ qSwap(base, other.base);
+ qSwap(nChunks, other.nChunks);
+ qSwap(allocatedMap, other.allocatedMap);
+ }
+
+ ~MemorySegment() {
+ if (base)
+ pageReservation.deallocate();
+ }
+
+ void setBit(size_t index) {
+ Q_ASSERT(index < nChunks);
+ quint64 bit = static_cast<quint64>(1) << index;
+// qDebug() << " setBit" << hex << index << (index & (Bits - 1)) << bit;
+ allocatedMap |= bit;
+ }
+ void clearBit(size_t index) {
+ Q_ASSERT(index < nChunks);
+ quint64 bit = static_cast<quint64>(1) << index;
+// qDebug() << " setBit" << hex << index << (index & (Bits - 1)) << bit;
+ allocatedMap &= ~bit;
+ }
+ bool testBit(size_t index) const {
+ Q_ASSERT(index < nChunks);
+ quint64 bit = static_cast<quint64>(1) << index;
+ return (allocatedMap & bit);
+ }
+
+ Chunk *allocate(size_t size);
+ 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;
+ while (index < end) {
+ Q_ASSERT(testBit(index));
+ clearBit(index);
+ ++index;
}
+
+ size_t pageSize = WTF::pageSize();
+ size = (size + pageSize - 1) & ~(pageSize - 1);
+ pageReservation.decommit(chunk, size);
+ }
+
+ bool contains(Chunk *c) const {
+ return c >= base && c < base + nChunks;
}
- return result;
-}
-static std::size_t maxChunkSizeValue()
+ PageReservation pageReservation;
+ Chunk *base = 0;
+ quint64 allocatedMap = 0;
+ uint nChunks = 0;
+};
+
+Chunk *MemorySegment::allocate(size_t size)
{
- static std::size_t result = 0;
- if (!result) {
- result = 32 * 1024;
- if (Q_UNLIKELY(qEnvironmentVariableIsSet(QV4_MM_MAX_CHUNK_SIZE))) {
- bool ok;
- const std::size_t overrideValue = qgetenv(QV4_MM_MAX_CHUNK_SIZE).toUInt(&ok);
- if (ok)
- result = overrideValue;
+ size_t requiredChunks = (size + sizeof(Chunk) - 1)/sizeof(Chunk);
+ uint sequence = 0;
+ Chunk *candidate = 0;
+ for (uint i = 0; i < nChunks; ++i) {
+ if (!testBit(i)) {
+ if (!candidate)
+ candidate = base + i;
+ ++sequence;
+ } else {
+ candidate = 0;
+ sequence = 0;
+ }
+ if (sequence == requiredChunks) {
+ pageReservation.commit(candidate, size);
+ for (uint i = 0; i < requiredChunks; ++i)
+ setBit(candidate - base + i);
+ DEBUG << "allocated chunk " << candidate << hex << size;
+ return candidate;
}
}
- return result;
+ return 0;
}
-using namespace QV4;
-
-struct MemoryManager::Data
-{
- const size_t pageSize;
-
- struct ChunkHeader {
- Heap::Base freeItems;
- ChunkHeader *nextNonFull;
- char *itemStart;
- char *itemEnd;
- unsigned itemSize;
- };
+struct ChunkAllocator {
+ ChunkAllocator() {}
- ExecutionEngine *engine;
+ size_t requiredChunkSize(size_t size) {
+ size += Chunk::HeaderSize; // space required for the Chunk header
+ size_t pageSize = WTF::pageSize();
+ size = (size + pageSize - 1) & ~(pageSize - 1); // align to page sizes
+ if (size < Chunk::ChunkSize)
+ size = Chunk::ChunkSize;
+ return size;
+ }
- std::size_t maxChunkSize;
- std::vector<PageAllocation> heapChunks;
- std::size_t unmanagedHeapSize; // the amount of bytes of heap that is not managed by the memory manager, but which is held onto by managed items.
- std::size_t unmanagedHeapSizeGCLimit;
+ Chunk *allocate(size_t size = 0);
+ void free(Chunk *chunk, size_t size = 0);
- struct LargeItem {
- LargeItem *next;
- size_t size;
- void *data;
+ std::vector<MemorySegment> memorySegments;
+};
- Heap::Base *heapObject() {
- return reinterpret_cast<Heap::Base *>(&data);
+Chunk *ChunkAllocator::allocate(size_t size)
+{
+ size = requiredChunkSize(size);
+ for (auto &m : memorySegments) {
+ if (~m.allocatedMap) {
+ Chunk *c = m.allocate(size);
+ if (c)
+ return c;
}
- };
+ }
- LargeItem *largeItems;
- std::size_t totalLargeItemsAllocated;
+ // allocate a new segment
+ memorySegments.push_back(MemorySegment(size));
+ Chunk *c = memorySegments.back().allocate(size);
+ Q_ASSERT(c);
+ return c;
+}
- enum { MaxItemSize = 512 };
- ChunkHeader *nonFullChunks[MaxItemSize/16];
- uint nChunks[MaxItemSize/16];
- uint availableItems[MaxItemSize/16];
- uint allocCount[MaxItemSize/16];
- int totalItems;
- int totalAlloc;
- uint maxShift;
+void ChunkAllocator::free(Chunk *chunk, size_t size)
+{
+ size = requiredChunkSize(size);
+ for (auto &m : memorySegments) {
+ if (m.contains(chunk)) {
+ m.free(chunk, size);
+ return;
+ }
+ }
+ Q_ASSERT(false);
+}
- bool gcBlocked;
- bool aggressiveGC;
- bool gcStats;
- bool unused; // suppress padding warning
- // statistics:
-#ifdef DETAILED_MM_STATS
- QVector<unsigned> allocSizeCounters;
-#endif // DETAILED_MM_STATS
+void Chunk::sweep()
+{
+ // DEBUG << "sweeping chunk" << this << (*freeList);
+ HeapItem *o = realBase();
+ for (uint i = 0; i < Chunk::EntriesInBitmap; ++i) {
+ Q_ASSERT((grayBitmap[i] | blackBitmap[i]) == blackBitmap[i]); // check that we don't have gray only objects
+ quintptr toFree = objectBitmap[i] ^ blackBitmap[i];
+ Q_ASSERT((toFree & objectBitmap[i]) == toFree); // check all black objects are marked as being used
+ quintptr e = extendsBitmap[i];
+ // DEBUG << hex << " index=" << i << toFree;
+ while (toFree) {
+ uint index = qCountTrailingZeroBits(toFree);
+ quintptr bit = (static_cast<quintptr>(1) << index);
+
+ toFree ^= bit; // mask out freed slot
+ // DEBUG << " index" << hex << index << toFree;
+
+ // remove all extends slots that have been freed
+ // this is a bit of bit trickery.
+ quintptr mask = (bit << 1) - 1; // create a mask of 1's to the right of and up to the current bit
+ quintptr objmask = e | mask; // or'ing mask with e gives all ones until the end of the current object
+ quintptr result = objmask + 1;
+ Q_ASSERT(qCountTrailingZeroBits(result) - index != 0); // ensure we freed something
+ result |= mask; // ensure we don't clear stuff to the right of the current object
+ e &= result;
+
+ HeapItem *itemToFree = o + index;
+ Heap::Base *b = *itemToFree;
+ if (b->vtable()->destroy) {
+ b->vtable()->destroy(b);
+ b->_checkIsDestroyed();
+ }
+ }
+ objectBitmap[i] = blackBitmap[i];
+ blackBitmap[i] = 0;
+ extendsBitmap[i] = e;
+ o += Chunk::Bits;
+ }
+ // DEBUG << "swept chunk" << this << "freed" << slotsFreed << "slots.";
+}
- Data()
- : pageSize(WTF::pageSize())
- , engine(0)
- , maxChunkSize(maxChunkSizeValue())
- , unmanagedHeapSize(0)
- , unmanagedHeapSizeGCLimit(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT)
- , largeItems(0)
- , totalLargeItemsAllocated(0)
- , totalItems(0)
- , totalAlloc(0)
- , maxShift(maxShiftValue())
- , gcBlocked(false)
- , aggressiveGC(!qEnvironmentVariableIsEmpty("QV4_MM_AGGRESSIVE_GC"))
- , gcStats(!qEnvironmentVariableIsEmpty(QV4_MM_STATS))
- {
- memset(nonFullChunks, 0, sizeof(nonFullChunks));
- memset(nChunks, 0, sizeof(nChunks));
- memset(availableItems, 0, sizeof(availableItems));
- memset(allocCount, 0, sizeof(allocCount));
+void Chunk::freeAll()
+{
+ // DEBUG << "sweeping chunk" << this << (*freeList);
+ HeapItem *o = realBase();
+ for (uint i = 0; i < Chunk::EntriesInBitmap; ++i) {
+ quintptr toFree = objectBitmap[i];
+ quintptr e = extendsBitmap[i];
+ // DEBUG << hex << " index=" << i << toFree;
+ while (toFree) {
+ uint index = qCountTrailingZeroBits(toFree);
+ quintptr bit = (static_cast<quintptr>(1) << index);
+
+ toFree ^= bit; // mask out freed slot
+ // DEBUG << " index" << hex << index << toFree;
+
+ // remove all extends slots that have been freed
+ // this is a bit of bit trickery.
+ quintptr mask = (bit << 1) - 1; // create a mask of 1's to the right of and up to the current bit
+ quintptr objmask = e | mask; // or'ing mask with e gives all ones until the end of the current object
+ quintptr result = objmask + 1;
+ Q_ASSERT(qCountTrailingZeroBits(result) - index != 0); // ensure we freed something
+ result |= mask; // ensure we don't clear stuff to the right of the current object
+ e &= result;
+
+ HeapItem *itemToFree = o + index;
+ Heap::Base *b = *itemToFree;
+ if (b->vtable()->destroy) {
+ b->vtable()->destroy(b);
+ b->_checkIsDestroyed();
+ }
+ }
+ objectBitmap[i] = 0;
+ blackBitmap[i] = 0;
+ extendsBitmap[i] = e;
+ o += Chunk::Bits;
}
+ // DEBUG << "swept chunk" << this << "freed" << slotsFreed << "slots.";
+}
- ~Data()
- {
- for (std::vector<PageAllocation>::iterator i = heapChunks.begin(), ei = heapChunks.end(); i != ei; ++i) {
- Q_V4_PROFILE_DEALLOC(engine, i->size(), Profiling::HeapPage);
- i->deallocate();
+void Chunk::sortIntoBins(HeapItem **bins, uint nBins)
+{
+ HeapItem *base = realBase();
+#if QT_POINTER_SIZE == 8
+ const int start = 0;
+#else
+ const int start = 1;
+#endif
+ for (int i = start; i < EntriesInBitmap; ++i) {
+ quintptr usedSlots = (objectBitmap[i]|extendsBitmap[i]);
+#if QT_POINTER_SIZE == 8
+ if (!i)
+ usedSlots |= (static_cast<quintptr>(1) << (HeaderSize/SlotSize)) - 1;
+#endif
+ uint index = qCountTrailingZeroBits(usedSlots + 1);
+ if (index == Bits)
+ continue;
+ uint freeStart = i*Bits + index;
+ usedSlots &= ~((static_cast<quintptr>(1) << index) - 1);
+ while (i < EntriesInBitmap && !usedSlots) {
+ ++i;
+ usedSlots = (objectBitmap[i]|extendsBitmap[i]);
}
+ if (i == EntriesInBitmap)
+ usedSlots = 1;
+ HeapItem *freeItem = base + freeStart;
+
+ uint freeEnd = i*Bits + qCountTrailingZeroBits(usedSlots);
+ uint nSlots = freeEnd - freeStart;
+ Q_ASSERT(freeEnd > freeStart && freeEnd <= NumSlots);
+ freeItem->freeData.availableSlots = nSlots;
+ uint bin = qMin(nBins - 1, nSlots);
+ freeItem->freeData.next = bins[bin];
+ bins[bin] = freeItem;
+ // DEBUG << "binnig item" << freeItem << nSlots << bin << freeItem->freeData.availableSlots;
}
-};
+}
-namespace {
-bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, ExecutionEngine *engine, std::size_t *unmanagedHeapSize)
+template<typename T>
+StackAllocator<T>::StackAllocator(ChunkAllocator *chunkAlloc)
+ : chunkAllocator(chunkAlloc)
{
- Q_ASSERT(unmanagedHeapSize);
+ chunks.push_back(chunkAllocator->allocate());
+ firstInChunk = chunks.back()->first();
+ nextFree = firstInChunk;
+ lastInChunk = firstInChunk + (Chunk::AvailableSlots - 1)/requiredSlots*requiredSlots;
+}
- bool isEmpty = true;
- Heap::Base *tail = &header->freeItems;
-// qDebug("chunkStart @ %p, size=%x, pos=%x", header->itemStart, header->itemSize, header->itemSize>>4);
-#ifdef V4_USE_VALGRIND
- VALGRIND_DISABLE_ERROR_REPORTING;
-#endif
- for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) {
- Heap::Base *m = reinterpret_cast<Heap::Base *>(item);
-// qDebug("chunk @ %p, in use: %s, mark bit: %s",
-// item, (m->inUse() ? "yes" : "no"), (m->isMarked() ? "true" : "false"));
-
- Q_ASSERT(qintptr(item) % 16 == 0);
-
- if (m->isMarked()) {
- Q_ASSERT(m->inUse());
- m->clearMarkBit();
- isEmpty = false;
- ++(*itemsInUse);
- } else {
- if (m->inUse()) {
-// qDebug() << "-- collecting it." << m << tail << m->nextFree();
-#ifdef V4_USE_VALGRIND
- VALGRIND_ENABLE_ERROR_REPORTING;
-#endif
- if (std::size_t(header->itemSize) == MemoryManager::align(sizeof(Heap::String)) && m->vtable()->isString) {
- std::size_t heapBytes = static_cast<Heap::String *>(m)->retainedTextSize();
- Q_ASSERT(*unmanagedHeapSize >= heapBytes);
-// qDebug() << "-- it's a string holding on to" << heapBytes << "bytes";
- *unmanagedHeapSize -= heapBytes;
- }
+template<typename T>
+void StackAllocator<T>::freeAll()
+{
+ for (auto c : chunks)
+ chunkAllocator->free(c);
+}
- if (m->vtable()->destroy) {
- m->vtable()->destroy(m);
- m->_checkIsDestroyed();
- }
+template<typename T>
+void StackAllocator<T>::nextChunk() {
+ Q_ASSERT(nextFree == lastInChunk);
+ ++currentChunk;
+ if (currentChunk >= chunks.size()) {
+ Chunk *newChunk = chunkAllocator->allocate();
+ chunks.push_back(newChunk);
+ }
+ firstInChunk = chunks.at(currentChunk)->first();
+ nextFree = firstInChunk;
+ lastInChunk = firstInChunk + (Chunk::AvailableSlots - 1)/requiredSlots*requiredSlots;
+}
- memset(m, 0, sizeof(Heap::Base));
-#ifdef V4_USE_VALGRIND
- VALGRIND_DISABLE_ERROR_REPORTING;
- VALGRIND_MEMPOOL_FREE(engine->memoryManager, m);
+template<typename T>
+void QV4::StackAllocator<T>::prevChunk() {
+ Q_ASSERT(nextFree == firstInChunk);
+ Q_ASSERT(chunks.at(currentChunk) == nextFree->chunk());
+ Q_ASSERT(currentChunk > 0);
+ --currentChunk;
+ firstInChunk = chunks.at(currentChunk)->first();
+ lastInChunk = firstInChunk + (Chunk::AvailableSlots - 1)/requiredSlots*requiredSlots;
+ nextFree = lastInChunk;
+}
+
+template struct StackAllocator<Heap::CallContext>;
+
+
+HeapItem *BlockAllocator::allocate(size_t size, bool forceAllocation) {
+ Q_ASSERT((size % Chunk::SlotSize) == 0);
+ size_t slotsRequired = size >> Chunk::SlotSizeShift;
+#if MM_DEBUG
+ ++allocations[bin];
#endif
-#ifdef V4_USE_HEAPTRACK
- heaptrack_report_free(m);
+
+ HeapItem **last;
+
+ HeapItem *m;
+
+ if (slotsRequired < NumBins - 1) {
+ m = freeBins[slotsRequired];
+ if (m) {
+ freeBins[slotsRequired] = m->freeData.next;
+ goto done;
+ }
+ }
+#if 0
+ for (uint b = bin + 1; b < NumBins - 1; ++b) {
+ if ((m = freeBins[b])) {
+ Q_ASSERT(binForSlots(m->freeData.availableSlots) == b);
+ freeBins[b] = m->freeData.next;
+ // DEBUG << "looking for empty bin" << bin << "size" << size << "found" << b;
+ uint remainingSlots = m->freeData.availableSlots - slotsRequired;
+ // DEBUG << "found free slots of size" << m->freeData.availableSlots << m << "remaining" << remainingSlots;
+ if (remainingSlots < 2) {
+ // avoid too much fragmentation and rather mark the memory as used
+ size += remainingSlots*Chunk::SlotSize;
+ goto done;
+ }
+ HeapItem *remainder = m + slotsRequired;
+ remainder->freeData.availableSlots = remainingSlots;
+ uint binForRemainder = binForSlots(remainingSlots);
+ remainder->freeData.next = freeBins[binForRemainder];
+ freeBins[binForRemainder] = remainder;
+ goto done;
+ }
+ }
#endif
- Q_V4_PROFILE_DEALLOC(engine, header->itemSize, Profiling::SmallItem);
- ++(*itemsInUse);
+ if (nFree >= slotsRequired) {
+ // use bump allocation
+ Q_ASSERT(nextFree);
+ m = nextFree;
+ nextFree += slotsRequired;
+ nFree -= slotsRequired;
+ goto done;
+ }
+
+ // DEBUG << "No matching bin found for item" << size << bin;
+ // search last bin for a large enough item
+ last = &freeBins[NumBins - 1];
+ while ((m = *last)) {
+ if (m->freeData.availableSlots >= slotsRequired) {
+ *last = m->freeData.next; // take it out of the list
+
+ size_t remainingSlots = m->freeData.availableSlots - slotsRequired;
+ // DEBUG << "found large free slots of size" << m->freeData.availableSlots << m << "remaining" << remainingSlots;
+ if (remainingSlots < 2) {
+ // avoid too much fragmentation and rather mark the memory as used
+ size += remainingSlots*Chunk::SlotSize;
+ goto done;
+ }
+ HeapItem *remainder = m + slotsRequired;
+ if (remainingSlots >= 2*NumBins) {
+ if (nFree) {
+ size_t bin = binForSlots(nFree);
+ nextFree->freeData.next = freeBins[bin];
+ nextFree->freeData.availableSlots = nFree;
+ freeBins[bin] = nextFree;
+ }
+ nextFree = remainder;
+ nFree = remainingSlots;
+ } else {
+ remainder->freeData.availableSlots = remainingSlots;
+ size_t binForRemainder = binForSlots(remainingSlots);
+ remainder->freeData.next = freeBins[binForRemainder];
+ freeBins[binForRemainder] = remainder;
}
- // Relink all free blocks to rewrite references to any released chunk.
- tail->setNextFree(m);
- tail = m;
+ goto done;
}
+ last = &m->freeData.next;
}
- tail->setNextFree(0);
-#ifdef V4_USE_VALGRIND
- VALGRIND_ENABLE_ERROR_REPORTING;
+
+ if (!m) {
+ if (!forceAllocation)
+ return 0;
+ Chunk *newChunk = chunkAllocator->allocate();
+ chunks.push_back(newChunk);
+ nextFree = newChunk->first();
+ nFree = Chunk::AvailableSlots;
+ m = nextFree;
+ nextFree += slotsRequired;
+ nFree -= slotsRequired;
+ }
+
+done:
+ m->setAllocatedSlots(slotsRequired);
+ // DEBUG << " " << hex << m->chunk() << m->chunk()->objectBitmap[0] << m->chunk()->extendsBitmap[0] << (m - m->chunk()->realBase());
+ return m;
+}
+
+void BlockAllocator::sweep()
+{
+ nextFree = 0;
+ nFree = 0;
+ memset(freeBins, 0, sizeof(freeBins));
+
+// qDebug() << "BlockAlloc: sweep";
+ usedSlotsAfterLastSweep = 0;
+ for (auto c : chunks) {
+ c->sweep();
+ c->sortIntoBins(freeBins, NumBins);
+// qDebug() << "used slots in chunk" << c << ":" << c->nUsedSlots();
+ usedSlotsAfterLastSweep += c->nUsedSlots();
+ }
+}
+
+void BlockAllocator::freeAll()
+{
+ for (auto c : chunks) {
+ c->freeAll();
+ chunkAllocator->free(c);
+ }
+}
+
+#if MM_DEBUG
+void BlockAllocator::stats() {
+ DEBUG << "MM stats:";
+ QString s;
+ for (int i = 0; i < 10; ++i) {
+ uint c = 0;
+ HeapItem *item = freeBins[i];
+ while (item) {
+ ++c;
+ item = item->freeData.next;
+ }
+ s += QString::number(c) + QLatin1String(", ");
+ }
+ HeapItem *item = freeBins[NumBins - 1];
+ uint c = 0;
+ while (item) {
+ ++c;
+ item = item->freeData.next;
+ }
+ s += QLatin1String("..., ") + QString::number(c);
+ DEBUG << "bins:" << s;
+ QString a;
+ for (int i = 0; i < 10; ++i)
+ a += QString::number(allocations[i]) + QLatin1String(", ");
+ a += QLatin1String("..., ") + QString::number(allocations[NumBins - 1]);
+ DEBUG << "allocs:" << a;
+ memset(allocations, 0, sizeof(allocations));
+}
#endif
- return isEmpty;
+
+
+HeapItem *HugeItemAllocator::allocate(size_t size) {
+ Chunk *c = chunkAllocator->allocate(size);
+ chunks.push_back(HugeChunk{c, size});
+ Chunk::setBit(c->objectBitmap, c->first() - c->realBase());
+ return c->first();
+}
+
+static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocator::HugeChunk &c)
+{
+ HeapItem *itemToFree = c.chunk->first();
+ Heap::Base *b = *itemToFree;
+ if (b->vtable()->destroy) {
+ b->vtable()->destroy(b);
+ b->_checkIsDestroyed();
+ }
+ chunkAllocator->free(c.chunk, c.size);
+}
+
+void HugeItemAllocator::sweep() {
+ auto isBlack = [this] (const HugeChunk &c) {
+ bool b = c.chunk->first()->isBlack();
+ Chunk::clearBit(c.chunk->blackBitmap, c.chunk->first() - c.chunk->realBase());
+ if (!b)
+ freeHugeChunk(chunkAllocator, c);
+ return !b;
+ };
+
+ auto newEnd = std::remove_if(chunks.begin(), chunks.end(), isBlack);
+ chunks.erase(newEnd, chunks.end());
+}
+
+void HugeItemAllocator::freeAll()
+{
+ for (auto &c : chunks) {
+ freeHugeChunk(chunkAllocator, c);
+ }
}
-} // namespace
MemoryManager::MemoryManager(ExecutionEngine *engine)
: engine(engine)
- , m_d(new Data)
+ , chunkAllocator(new ChunkAllocator)
+ , stackAllocator(chunkAllocator)
+ , blockAllocator(chunkAllocator)
+ , hugeItemAllocator(chunkAllocator)
, m_persistentValues(new PersistentValueStorage(engine))
, m_weakValues(new PersistentValueStorage(engine))
+ , unmanagedHeapSizeGCLimit(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT)
+ , aggressiveGC(!qEnvironmentVariableIsEmpty("QV4_MM_AGGRESSIVE_GC"))
+ , gcStats(!qEnvironmentVariableIsEmpty(QV4_MM_STATS))
{
#ifdef V4_USE_VALGRIND
VALGRIND_CREATE_MEMPOOL(this, 0, true);
#endif
- m_d->engine = engine;
}
-Heap::Base *MemoryManager::allocData(std::size_t size, std::size_t unmanagedSize)
+Heap::Base *MemoryManager::allocString(std::size_t unmanagedSize)
{
- if (m_d->aggressiveGC)
+ if (aggressiveGC)
runGC();
-#ifdef DETAILED_MM_STATS
- willAllocate(size);
-#endif // DETAILED_MM_STATS
- Q_ASSERT(size >= 16);
- Q_ASSERT(size % 16 == 0);
-
-// qDebug() << "unmanagedHeapSize:" << m_d->unmanagedHeapSize << "limit:" << m_d->unmanagedHeapSizeGCLimit << "unmanagedSize:" << unmanagedSize;
- m_d->unmanagedHeapSize += unmanagedSize;
+ const size_t stringSize = align(sizeof(Heap::String));
+ unmanagedHeapSize += unmanagedSize;
bool didGCRun = false;
- if (m_d->unmanagedHeapSize > m_d->unmanagedHeapSizeGCLimit) {
+ if (unmanagedHeapSize > unmanagedHeapSizeGCLimit) {
runGC();
- if (3*m_d->unmanagedHeapSizeGCLimit <= 4*m_d->unmanagedHeapSize)
+ if (3*unmanagedHeapSizeGCLimit <= 4*unmanagedHeapSize)
// more than 75% full, raise limit
- m_d->unmanagedHeapSizeGCLimit = std::max(m_d->unmanagedHeapSizeGCLimit, m_d->unmanagedHeapSize) * 2;
- else if (m_d->unmanagedHeapSize * 4 <= m_d->unmanagedHeapSizeGCLimit)
+ unmanagedHeapSizeGCLimit = std::max(unmanagedHeapSizeGCLimit, unmanagedHeapSize) * 2;
+ else if (unmanagedHeapSize * 4 <= unmanagedHeapSizeGCLimit)
// less than 25% full, lower limit
- m_d->unmanagedHeapSizeGCLimit = qMax(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT, m_d->unmanagedHeapSizeGCLimit/2);
+ unmanagedHeapSizeGCLimit = qMax(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT, unmanagedHeapSizeGCLimit/2);
didGCRun = true;
}
- size_t pos = size >> 4;
-
- // doesn't fit into a small bucket
- if (size >= MemoryManager::Data::MaxItemSize) {
- if (!didGCRun && m_d->totalLargeItemsAllocated > 8 * 1024 * 1024)
+ HeapItem *m = blockAllocator.allocate(stringSize);
+ if (!m) {
+ if (!didGCRun && shouldRunGC())
runGC();
-
- // we use malloc for this
- const size_t totalSize = size + sizeof(MemoryManager::Data::LargeItem);
- Q_V4_PROFILE_ALLOC(engine, totalSize, Profiling::LargeItem);
- MemoryManager::Data::LargeItem *item =
- static_cast<MemoryManager::Data::LargeItem *>(malloc(totalSize));
- memset(item, 0, totalSize);
- item->next = m_d->largeItems;
- item->size = size;
- m_d->largeItems = item;
- m_d->totalLargeItemsAllocated += size;
- return item->heapObject();
+ m = blockAllocator.allocate(stringSize, true);
}
- Heap::Base *m = 0;
- Data::ChunkHeader *header = m_d->nonFullChunks[pos];
- if (header) {
- m = header->freeItems.nextFree();
- goto found;
- }
+ memset(m, 0, stringSize);
+ return *m;
+}
- // try to free up space, otherwise allocate
- if (!didGCRun && m_d->allocCount[pos] > (m_d->availableItems[pos] >> 1) && m_d->totalAlloc > (m_d->totalItems >> 1) && !m_d->aggressiveGC) {
+Heap::Base *MemoryManager::allocData(std::size_t size)
+{
+ if (aggressiveGC)
runGC();
- header = m_d->nonFullChunks[pos];
- if (header) {
- m = header->freeItems.nextFree();
- goto found;
- }
- }
+#ifdef DETAILED_MM_STATS
+ willAllocate(size);
+#endif // DETAILED_MM_STATS
- // no free item available, allocate a new chunk
- {
- // allocate larger chunks at a time to avoid excessive GC, but cap at maximum chunk size (2MB by default)
- uint shift = ++m_d->nChunks[pos];
- if (shift > m_d->maxShift)
- shift = m_d->maxShift;
- std::size_t allocSize = m_d->maxChunkSize*(size_t(1) << shift);
- allocSize = roundUpToMultipleOf(m_d->pageSize, allocSize);
- Q_V4_PROFILE_ALLOC(engine, allocSize, Profiling::HeapPage);
- PageAllocation allocation = PageAllocation::allocate(allocSize, OSAllocator::JSGCHeapPages);
- m_d->heapChunks.push_back(allocation);
-
- header = reinterpret_cast<Data::ChunkHeader *>(allocation.base());
- Q_ASSERT(size <= UINT_MAX);
- header->itemSize = unsigned(size);
- header->itemStart = reinterpret_cast<char *>(allocation.base()) + roundUpToMultipleOf(16, sizeof(Data::ChunkHeader));
- header->itemEnd = reinterpret_cast<char *>(allocation.base()) + allocation.size() - header->itemSize;
-
- header->nextNonFull = m_d->nonFullChunks[pos];
- m_d->nonFullChunks[pos] = header;
-
- Heap::Base *last = &header->freeItems;
- for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) {
- Heap::Base *o = reinterpret_cast<Heap::Base *>(item);
- last->setNextFree(o);
- last = o;
+ Q_ASSERT(size >= Chunk::SlotSize);
+ Q_ASSERT(size % Chunk::SlotSize == 0);
- }
- last->setNextFree(0);
- m = header->freeItems.nextFree();
- Q_ASSERT(header->itemEnd >= header->itemStart);
- const size_t increase = quintptr(header->itemEnd - header->itemStart) / header->itemSize;
- m_d->availableItems[pos] += uint(increase);
- m_d->totalItems += int(increase);
-#ifdef V4_USE_VALGRIND
- VALGRIND_MAKE_MEM_NOACCESS(allocation.base(), allocSize);
- VALGRIND_MEMPOOL_ALLOC(this, header, sizeof(Data::ChunkHeader));
-#endif
-#ifdef V4_USE_HEAPTRACK
- heaptrack_report_alloc(header, sizeof(Data::ChunkHeader));
-#endif
+// qDebug() << "unmanagedHeapSize:" << unmanagedHeapSize << "limit:" << unmanagedHeapSizeGCLimit << "unmanagedSize:" << unmanagedSize;
+
+ if (size > Chunk::DataSize)
+ return *hugeItemAllocator.allocate(size);
+
+ HeapItem *m = blockAllocator.allocate(size);
+ if (!m) {
+ if (shouldRunGC())
+ runGC();
+ m = blockAllocator.allocate(size, true);
}
- found:
-#ifdef V4_USE_VALGRIND
- VALGRIND_MEMPOOL_ALLOC(this, m, size);
-#endif
-#ifdef V4_USE_HEAPTRACK
- heaptrack_report_alloc(m, size);
-#endif
- Q_V4_PROFILE_ALLOC(engine, size, Profiling::SmallItem);
+ memset(m, 0, size);
+ return *m;
+}
- ++m_d->allocCount[pos];
- ++m_d->totalAlloc;
- header->freeItems.setNextFree(m->nextFree());
- if (!header->freeItems.nextFree())
- m_d->nonFullChunks[pos] = header->nextNonFull;
- return m;
+Heap::Object *MemoryManager::allocObjectWithMemberData(std::size_t size, uint nMembers)
+{
+ Heap::Object *o = static_cast<Heap::Object *>(allocData(size));
+
+ // ### Could optimize this and allocate both in one go through the block allocator
+ if (nMembers) {
+ std::size_t memberSize = align(sizeof(Heap::MemberData) + (nMembers - 1)*sizeof(Value));
+// qDebug() << "allocating member data for" << o << nMembers << memberSize;
+ Heap::Base *m;
+ if (memberSize > Chunk::DataSize)
+ m = *hugeItemAllocator.allocate(memberSize);
+ else
+ m = *blockAllocator.allocate(memberSize, true);
+ memset(m, 0, memberSize);
+ o->memberData = static_cast<Heap::MemberData *>(m);
+ o->memberData->setVtable(MemberData::staticVTable());
+ o->memberData->size = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
+ o->memberData->init();
+// qDebug() << " got" << o->memberData << o->memberData->size;
+ }
+ return o;
}
static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase)
@@ -495,98 +804,34 @@ void MemoryManager::sweep(bool lastSweep)
}
}
- bool *chunkIsEmpty = static_cast<bool *>(alloca(m_d->heapChunks.size() * sizeof(bool)));
- uint itemsInUse[MemoryManager::Data::MaxItemSize/16];
- memset(itemsInUse, 0, sizeof(itemsInUse));
- memset(m_d->nonFullChunks, 0, sizeof(m_d->nonFullChunks));
-
- for (size_t i = 0; i < m_d->heapChunks.size(); ++i) {
- Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(m_d->heapChunks[i].base());
- chunkIsEmpty[i] = sweepChunk(header, &itemsInUse[header->itemSize >> 4], engine, &m_d->unmanagedHeapSize);
- }
-
- std::vector<PageAllocation>::iterator chunkIter = m_d->heapChunks.begin();
- for (size_t i = 0; i < m_d->heapChunks.size(); ++i) {
- Q_ASSERT(chunkIter != m_d->heapChunks.end());
- Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(chunkIter->base());
- const size_t pos = header->itemSize >> 4;
- Q_ASSERT(header->itemEnd >= header->itemStart);
- const size_t decrease = quintptr(header->itemEnd - header->itemStart) / header->itemSize;
-
- // Release that chunk if it could have been spared since the last GC run without any difference.
- if (chunkIsEmpty[i] && m_d->availableItems[pos] - decrease >= itemsInUse[pos]) {
- Q_V4_PROFILE_DEALLOC(engine, chunkIter->size(), Profiling::HeapPage);
-#ifdef V4_USE_VALGRIND
- VALGRIND_MEMPOOL_FREE(this, header);
-#endif
-#ifdef V4_USE_HEAPTRACK
- heaptrack_report_free(header);
-#endif
- --m_d->nChunks[pos];
- m_d->availableItems[pos] -= uint(decrease);
- m_d->totalItems -= int(decrease);
- chunkIter->deallocate();
- chunkIter = m_d->heapChunks.erase(chunkIter);
- continue;
- } else if (header->freeItems.nextFree()) {
- header->nextNonFull = m_d->nonFullChunks[pos];
- m_d->nonFullChunks[pos] = header;
- }
- ++chunkIter;
- }
-
- Data::LargeItem *i = m_d->largeItems;
- Data::LargeItem **last = &m_d->largeItems;
- while (i) {
- Heap::Base *m = i->heapObject();
- Q_ASSERT(m->inUse());
- if (m->isMarked()) {
- m->clearMarkBit();
- last = &i->next;
- i = i->next;
- continue;
- }
- if (m->vtable()->destroy)
- m->vtable()->destroy(m);
-
- *last = i->next;
- Q_V4_PROFILE_DEALLOC(engine, i->size + sizeof(Data::LargeItem), Profiling::LargeItem);
- free(i);
- i = *last;
- }
-
- // some execution contexts are allocated on the stack, make sure we clear their markBit as well
- if (!lastSweep) {
- QV4::ExecutionContext *ctx = engine->currentContext;
- while (ctx) {
- ctx->d()->clearMarkBit();
- ctx = engine->parentContext(ctx);
- }
- }
+ blockAllocator.sweep();
+ hugeItemAllocator.sweep();
}
-bool MemoryManager::isGCBlocked() const
+bool MemoryManager::shouldRunGC() const
{
- return m_d->gcBlocked;
+ size_t total = blockAllocator.totalSlots();
+ size_t usedSlots = blockAllocator.usedSlotsAfterLastSweep;
+ if (total > MinSlotsGCLimit && usedSlots * GCOverallocation < total * 100)
+ return true;
+ return false;
}
-void MemoryManager::setGCBlocked(bool blockGC)
-{
- m_d->gcBlocked = blockGC;
-}
void MemoryManager::runGC()
{
- if (m_d->gcBlocked) {
+ if (gcBlocked) {
// qDebug() << "Not running GC.";
return;
}
- QScopedValueRollback<bool> gcBlocker(m_d->gcBlocked, true);
+ QScopedValueRollback<bool> gcBlocker(gcBlocked, true);
- if (!m_d->gcStats) {
+ if (!gcStats) {
+// uint oldUsed = allocator.usedMem();
mark();
sweep();
+// DEBUG << "RUN GC: allocated:" << allocator.allocatedMem() << "used before" << oldUsed << "used now" << allocator.usedMem();
} else {
const size_t totalMem = getAllocatedMem();
@@ -596,7 +841,6 @@ void MemoryManager::runGC()
qint64 markTime = t.restart();
const size_t usedBefore = getUsedMem();
const size_t largeItemsBefore = getLargeItemsMem();
- size_t chunksBefore = m_d->heapChunks.size();
sweep();
const size_t usedAfter = getUsedMem();
const size_t largeItemsAfter = getLargeItemsMem();
@@ -605,56 +849,30 @@ void MemoryManager::runGC()
qDebug() << "========== GC ==========";
qDebug() << "Marked object in" << markTime << "ms.";
qDebug() << "Sweeped object in" << sweepTime << "ms.";
- qDebug() << "Allocated" << totalMem << "bytes in" << m_d->heapChunks.size() << "chunks.";
+ qDebug() << "Allocated" << totalMem << "bytes";
qDebug() << "Used memory before GC:" << usedBefore;
qDebug() << "Used memory after GC:" << usedAfter;
qDebug() << "Freed up bytes:" << (usedBefore - usedAfter);
- qDebug() << "Released chunks:" << (chunksBefore - m_d->heapChunks.size());
qDebug() << "Large item memory before GC:" << largeItemsBefore;
qDebug() << "Large item memory after GC:" << largeItemsAfter;
qDebug() << "Large item memory freed up:" << (largeItemsBefore - largeItemsAfter);
qDebug() << "======== End GC ========";
}
-
- memset(m_d->allocCount, 0, sizeof(m_d->allocCount));
- m_d->totalAlloc = 0;
- m_d->totalLargeItemsAllocated = 0;
}
size_t MemoryManager::getUsedMem() const
{
- size_t usedMem = 0;
- for (std::vector<PageAllocation>::const_iterator i = m_d->heapChunks.cbegin(), ei = m_d->heapChunks.cend(); i != ei; ++i) {
- Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(i->base());
- for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) {
- Heap::Base *m = reinterpret_cast<Heap::Base *>(item);
- Q_ASSERT(qintptr(item) % 16 == 0);
- if (m->inUse())
- usedMem += header->itemSize;
- }
- }
- return usedMem;
+ return blockAllocator.usedMem();
}
size_t MemoryManager::getAllocatedMem() const
{
- size_t total = 0;
- for (size_t i = 0; i < m_d->heapChunks.size(); ++i)
- total += m_d->heapChunks.at(i).size();
- return total;
+ return blockAllocator.allocatedMem() + hugeItemAllocator.usedMem();
}
size_t MemoryManager::getLargeItemsMem() const
{
- size_t total = 0;
- for (const Data::LargeItem *i = m_d->largeItems; i != 0; i = i->next)
- total += i->size;
- return total;
-}
-
-void MemoryManager::growUnmanagedHeapSizeUsage(size_t delta)
-{
- m_d->unmanagedHeapSize += delta;
+ return hugeItemAllocator.usedMem();
}
MemoryManager::~MemoryManager()
@@ -662,23 +880,26 @@ MemoryManager::~MemoryManager()
delete m_persistentValues;
sweep(/*lastSweep*/true);
+ blockAllocator.freeAll();
+ hugeItemAllocator.freeAll();
+ stackAllocator.freeAll();
delete m_weakValues;
#ifdef V4_USE_VALGRIND
VALGRIND_DESTROY_MEMPOOL(this);
#endif
+ delete chunkAllocator;
}
-
void MemoryManager::dumpStats() const
{
#ifdef DETAILED_MM_STATS
std::cerr << "=================" << std::endl;
std::cerr << "Allocation stats:" << std::endl;
std::cerr << "Requests for each chunk size:" << std::endl;
- for (int i = 0; i < m_d->allocSizeCounters.size(); ++i) {
- if (unsigned count = m_d->allocSizeCounters[i]) {
+ for (int i = 0; i < allocSizeCounters.size(); ++i) {
+ if (unsigned count = allocSizeCounters[i]) {
std::cerr << "\t" << (i << 4) << " bytes chunks: " << count << std::endl;
}
}
@@ -689,7 +910,7 @@ void MemoryManager::dumpStats() const
void MemoryManager::willAllocate(std::size_t size)
{
unsigned alignedSize = (size + 15) >> 4;
- QVector<unsigned> &counters = m_d->allocSizeCounters;
+ QVector<unsigned> &counters = allocSizeCounters;
if ((unsigned) counters.size() < alignedSize + 1)
counters.resize(alignedSize + 1);
counters[alignedSize]++;
@@ -709,4 +930,7 @@ void MemoryManager::collectFromJSStack() const
++v;
}
}
+
+} // namespace QV4
+
QT_END_NAMESPACE
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index dfa0d85dff..00daf8a622 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -55,6 +55,7 @@
#include <private/qv4value_p.h>
#include <private/qv4scopedvalue_p.h>
#include <private/qv4object_p.h>
+#include <private/qv4mmdefs_p.h>
#include <QVector>
//#define DETAILED_MM_STATS
@@ -63,55 +64,166 @@
#define QV4_MM_MAX_CHUNK_SIZE "QV4_MM_MAX_CHUNK_SIZE"
#define QV4_MM_STATS "QV4_MM_STATS"
+#define MM_DEBUG 0
+
QT_BEGIN_NAMESPACE
namespace QV4 {
-struct GCDeletable;
+struct ChunkAllocator;
-class Q_QML_EXPORT MemoryManager
-{
- Q_DISABLE_COPY(MemoryManager);
+template<typename T>
+struct StackAllocator {
+ Q_STATIC_ASSERT(sizeof(T) < Chunk::DataSize);
+ static const uint requiredSlots = (sizeof(T) + sizeof(HeapItem) - 1)/sizeof(HeapItem);
-public:
- struct Data;
+ StackAllocator(ChunkAllocator *chunkAlloc);
- class GCBlocker
- {
- public:
- GCBlocker(MemoryManager *mm)
- : mm(mm)
- , wasBlocked(mm->isGCBlocked())
- {
- mm->setGCBlocked(true);
+ T *allocate() {
+ T *m = nextFree->as<T>();
+ if (Q_UNLIKELY(nextFree == lastInChunk)) {
+ nextChunk();
+ } else {
+ nextFree += requiredSlots;
}
-
- ~GCBlocker()
- {
- mm->setGCBlocked(wasBlocked);
+#if MM_DEBUG
+ Chunk *c = m->chunk();
+ Chunk::setBit(c->objectBitmap, m - c->realBase());
+#endif
+ return m;
+ }
+ void free() {
+#if MM_DEBUG
+ Chunk::clearBit(item->chunk()->objectBitmap, item - item->chunk()->realBase());
+#endif
+ if (Q_UNLIKELY(nextFree == firstInChunk)) {
+ prevChunk();
+ } else {
+ nextFree -= requiredSlots;
}
+ }
+
+ void nextChunk();
+ void prevChunk();
+
+ void freeAll();
+
+ ChunkAllocator *chunkAllocator;
+ HeapItem *nextFree = 0;
+ HeapItem *firstInChunk = 0;
+ HeapItem *lastInChunk = 0;
+ std::vector<Chunk *> chunks;
+ uint currentChunk = 0;
+};
+
+struct BlockAllocator {
+ BlockAllocator(ChunkAllocator *chunkAllocator)
+ : chunkAllocator(chunkAllocator)
+ {
+ memset(freeBins, 0, sizeof(freeBins));
+#if MM_DEBUG
+ memset(allocations, 0, sizeof(allocations));
+#endif
+ }
+
+ enum { NumBins = 8 };
+
+ static inline size_t binForSlots(size_t nSlots) {
+ return nSlots >= NumBins ? NumBins - 1 : nSlots;
+ }
+
+#if MM_DEBUG
+ void stats();
+#endif
+
+ HeapItem *allocate(size_t size, bool forceAllocation = false);
+
+ size_t totalSlots() const {
+ return Chunk::AvailableSlots*chunks.size();
+ }
+
+ size_t allocatedMem() const {
+ return chunks.size()*Chunk::DataSize;
+ }
+ size_t usedMem() const {
+ uint used = 0;
+ for (auto c : chunks)
+ used += c->nUsedSlots()*Chunk::SlotSize;
+ return used;
+ }
- private:
- MemoryManager *mm;
- bool wasBlocked;
+ void sweep();
+ void freeAll();
+
+ // bump allocations
+ HeapItem *nextFree = 0;
+ size_t nFree = 0;
+ size_t usedSlotsAfterLastSweep = 0;
+ HeapItem *freeBins[NumBins];
+ ChunkAllocator *chunkAllocator;
+ std::vector<Chunk *> chunks;
+#if MM_DEBUG
+ uint allocations[NumBins];
+#endif
+};
+
+struct HugeItemAllocator {
+ HugeItemAllocator(ChunkAllocator *chunkAllocator)
+ : chunkAllocator(chunkAllocator)
+ {}
+
+ HeapItem *allocate(size_t size);
+ void sweep();
+ void freeAll();
+
+ size_t usedMem() const {
+ size_t used = 0;
+ for (const auto &c : chunks)
+ used += c.size;
+ return used;
+ }
+
+ ChunkAllocator *chunkAllocator;
+ struct HugeChunk {
+ Chunk *chunk;
+ size_t size;
};
+ std::vector<HugeChunk> chunks;
+};
+
+
+class Q_QML_EXPORT MemoryManager
+{
+ Q_DISABLE_COPY(MemoryManager);
+
public:
MemoryManager(ExecutionEngine *engine);
~MemoryManager();
// TODO: this is only for 64bit (and x86 with SSE/AVX), so exend it for other architectures to be slightly more efficient (meaning, align on 8-byte boundaries).
// Note: all occurrences of "16" in alloc/dealloc are also due to the alignment.
- static inline std::size_t align(std::size_t size)
- { return (size + 15) & ~0xf; }
+ Q_DECL_CONSTEXPR static inline std::size_t align(std::size_t size)
+ { return (size + Chunk::SlotSize - 1) & ~(Chunk::SlotSize - 1); }
+
+ QV4::Heap::CallContext *allocSimpleCallContext(QV4::ExecutionEngine *v4)
+ {
+ Heap::CallContext *ctxt = stackAllocator.allocate();
+ memset(ctxt, 0, sizeof(Heap::CallContext));
+ ctxt->setVtable(QV4::CallContext::staticVTable());
+ ctxt->init(v4);
+ return ctxt;
+
+ }
+ void freeSimpleCallContext()
+ { stackAllocator.free(); }
template<typename ManagedType>
- inline typename ManagedType::Data *allocManaged(std::size_t size, std::size_t unmanagedSize = 0)
+ inline typename ManagedType::Data *allocManaged(std::size_t size)
{
V4_ASSERT_IS_TRIVIAL(typename ManagedType::Data)
size = align(size);
- Heap::Base *o = allocData(size, unmanagedSize);
- memset(o, 0, size);
+ Heap::Base *o = allocData(size);
o->setVtable(ManagedType::staticVTable());
return static_cast<typename ManagedType::Data *>(o);
}
@@ -119,35 +231,31 @@ public:
template <typename ObjectType>
typename ObjectType::Data *allocateObject(InternalClass *ic)
{
- const int size = (sizeof(typename ObjectType::Data) + (sizeof(Value) - 1)) & ~(sizeof(Value) - 1);
- typename ObjectType::Data *o = allocManaged<ObjectType>(size + ic->size*sizeof(Value));
+ Heap::Object *o = allocObjectWithMemberData(align(sizeof(typename ObjectType::Data)), ic->size);
+ o->setVtable(ObjectType::staticVTable());
o->internalClass = ic;
- o->inlineMemberSize = ic->size;
- o->inlineMemberOffset = size/sizeof(Value);
- return o;
+ return static_cast<typename ObjectType::Data *>(o);
}
template <typename ObjectType>
typename ObjectType::Data *allocateObject()
{
InternalClass *ic = ObjectType::defaultInternalClass(engine);
- const int size = (sizeof(typename ObjectType::Data) + (sizeof(Value) - 1)) & ~(sizeof(Value) - 1);
- typename ObjectType::Data *o = allocManaged<ObjectType>(size + ic->size*sizeof(Value));
+ Heap::Object *o = allocObjectWithMemberData(align(sizeof(typename ObjectType::Data)), ic->size);
+ o->setVtable(ObjectType::staticVTable());
Object *prototype = ObjectType::defaultPrototype(engine);
o->internalClass = ic;
o->prototype = prototype->d();
- o->inlineMemberSize = ic->size;
- o->inlineMemberOffset = size/sizeof(Value);
- return o;
+ return static_cast<typename ObjectType::Data *>(o);
}
template <typename ManagedType, typename Arg1>
typename ManagedType::Data *allocWithStringData(std::size_t unmanagedSize, Arg1 arg1)
{
- Scope scope(engine);
- Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data), unmanagedSize));
- t->d_unchecked()->init(this, arg1);
- return t->d();
+ typename ManagedType::Data *o = reinterpret_cast<typename ManagedType::Data *>(allocString(unmanagedSize));
+ o->setVtable(ManagedType::staticVTable());
+ o->init(this, arg1);
+ return o;
}
template <typename ObjectType>
@@ -309,8 +417,6 @@ public:
return t->d();
}
- bool isGCBlocked() const;
- void setGCBlocked(bool blockGC);
void runGC();
void dumpStats() const;
@@ -319,12 +425,15 @@ public:
size_t getAllocatedMem() const;
size_t getLargeItemsMem() const;
- void growUnmanagedHeapSizeUsage(size_t delta); // called when a JS object grows itself. Specifically: Heap::String::append
+ // called when a JS object grows itself. Specifically: Heap::String::append
+ void changeUnmanagedHeapSizeUsage(qptrdiff delta) { unmanagedHeapSize += delta; }
+
protected:
/// expects size to be aligned
- // TODO: try to inline
- Heap::Base *allocData(std::size_t size, std::size_t unmanagedSize);
+ Heap::Base *allocString(std::size_t unmanagedSize);
+ Heap::Base *allocData(std::size_t size);
+ Heap::Object *allocObjectWithMemberData(std::size_t size, uint nMembers);
#ifdef DETAILED_MM_STATS
void willAllocate(std::size_t size);
@@ -334,13 +443,24 @@ private:
void collectFromJSStack() const;
void mark();
void sweep(bool lastSweep = false);
+ bool shouldRunGC() const;
public:
QV4::ExecutionEngine *engine;
- QScopedPointer<Data> m_d;
+ ChunkAllocator *chunkAllocator;
+ StackAllocator<Heap::CallContext> stackAllocator;
+ BlockAllocator blockAllocator;
+ HugeItemAllocator hugeItemAllocator;
PersistentValueStorage *m_persistentValues;
PersistentValueStorage *m_weakValues;
QVector<Value *> m_pendingFreedObjectWrapperValue;
+
+ std::size_t unmanagedHeapSize = 0; // the amount of bytes of heap that is not managed by the memory manager, but which is held onto by managed items.
+ std::size_t unmanagedHeapSizeGCLimit;
+
+ bool gcBlocked = false;
+ bool aggressiveGC = false;
+ bool gcStats = false;
};
}
diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h
new file mode 100644
index 0000000000..588ae21ee0
--- /dev/null
+++ b/src/qml/memory/qv4mmdefs_p.h
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4MMDEFS_P_H
+#define QV4MMDEFS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qv4global_p.h>
+#include <QtCore/qalgorithms.h>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+/*
+ * Chunks are the basic structure containing GC managed objects.
+ *
+ * Chunks are 64k aligned in memory, so that retrieving the Chunk pointer from a Heap object
+ * is a simple masking operation. Each Chunk has 4 bitmaps for managing purposes,
+ * and 32byte wide slots for the objects following afterwards.
+ *
+ * The gray and black bitmaps are used for mark/sweep.
+ * The object bitmap has a bit set if this location represents the start of a Heap object.
+ * The extends bitmap denotes the extend of an object. It has a cleared bit at the start of the object
+ * and a set bit for all following slots used by the object.
+ *
+ * Free memory has both used and extends bits set to 0.
+ *
+ * This gives the following operations when allocating an object of size s:
+ * Find s/Alignment consecutive free slots in the chunk. Set the object bit for the first
+ * slot to 1. Set the extends bits for all following slots to 1.
+ *
+ * All used slots can be found by object|extents.
+ *
+ * When sweeping, simply copy the black bits over to the object bits.
+ *
+ */
+struct HeapItem;
+struct Chunk {
+ enum {
+ ChunkSize = 64*1024,
+ ChunkShift = 16,
+ SlotSize = 32,
+ SlotSizeShift = 5,
+ NumSlots = ChunkSize/SlotSize,
+ BitmapSize = NumSlots/8,
+ HeaderSize = 4*BitmapSize,
+ DataSize = ChunkSize - HeaderSize,
+ AvailableSlots = DataSize/SlotSize,
+#if QT_POINTER_SIZE == 8
+ Bits = 64,
+ BitShift = 6,
+#else
+ Bits = 32,
+ BitShift = 5,
+#endif
+ EntriesInBitmap = BitmapSize/sizeof(quintptr)
+ };
+ quintptr grayBitmap[BitmapSize/sizeof(quintptr)];
+ quintptr blackBitmap[BitmapSize/sizeof(quintptr)];
+ quintptr objectBitmap[BitmapSize/sizeof(quintptr)];
+ quintptr extendsBitmap[BitmapSize/sizeof(quintptr)];
+ char data[ChunkSize - HeaderSize];
+
+ HeapItem *realBase();
+ HeapItem *first();
+
+ static void setBit(quintptr *bitmap, size_t index) {
+// Q_ASSERT(index >= HeaderSize/SlotSize && index < ChunkSize/SlotSize);
+ bitmap += index >> BitShift;
+ quintptr bit = static_cast<quintptr>(1) << (index & (Bits - 1));
+ *bitmap |= bit;
+ }
+ static void clearBit(quintptr *bitmap, size_t index) {
+// Q_ASSERT(index >= HeaderSize/SlotSize && index < ChunkSize/SlotSize);
+ bitmap += index >> BitShift;
+ quintptr bit = static_cast<quintptr>(1) << (index & (Bits - 1));
+ *bitmap &= ~bit;
+ }
+ static bool testBit(quintptr *bitmap, size_t index) {
+// Q_ASSERT(index >= HeaderSize/SlotSize && index < ChunkSize/SlotSize);
+ bitmap += index >> BitShift;
+ quintptr bit = static_cast<quintptr>(1) << (index & (Bits - 1));
+ return (*bitmap & bit);
+ }
+ static void setBits(quintptr *bitmap, size_t index, size_t nBits) {
+// Q_ASSERT(index >= HeaderSize/SlotSize && index + nBits <= ChunkSize/SlotSize);
+ if (!nBits)
+ return;
+ bitmap += index >> BitShift;
+ index &= (Bits - 1);
+ while (1) {
+ size_t bitsToSet = qMin(nBits, Bits - index);
+ quintptr mask = static_cast<quintptr>(-1) >> (Bits - bitsToSet) << index;
+ *bitmap |= mask;
+ nBits -= bitsToSet;
+ if (!nBits)
+ return;
+ index = 0;
+ ++bitmap;
+ }
+ }
+ static bool hasNonZeroBit(quintptr *bitmap) {
+ for (uint i = 0; i < EntriesInBitmap; ++i)
+ if (bitmap[i])
+ return true;
+ return false;
+ }
+ static uint lowestNonZeroBit(quintptr *bitmap) {
+ for (uint i = 0; i < EntriesInBitmap; ++i) {
+ if (bitmap[i]) {
+ quintptr b = bitmap[i];
+ return i*Bits + qCountTrailingZeroBits(b);
+ }
+ }
+ return 0;
+ }
+
+ uint nFreeSlots() const {
+ return AvailableSlots - nUsedSlots();
+ }
+ uint nUsedSlots() const {
+ uint usedSlots = 0;
+ for (uint i = 0; i < EntriesInBitmap; ++i) {
+ quintptr used = objectBitmap[i] | extendsBitmap[i];
+ usedSlots += qPopulationCount(used);
+ }
+ return usedSlots;
+ }
+
+ void sweep();
+ void freeAll();
+
+ void sortIntoBins(HeapItem **bins, uint nBins);
+};
+
+struct HeapItem {
+ union {
+ struct {
+ HeapItem *next;
+ size_t availableSlots;
+ } freeData;
+ quint64 payload[Chunk::SlotSize/sizeof(quint64)];
+ };
+ operator Heap::Base *() { return reinterpret_cast<Heap::Base *>(this); }
+
+ template<typename T>
+ T *as() { return static_cast<T *>(reinterpret_cast<Heap::Base *>(this)); }
+
+ Chunk *chunk() const {
+ return reinterpret_cast<Chunk *>(reinterpret_cast<quintptr>(this) >> Chunk::ChunkShift << Chunk::ChunkShift);
+ }
+
+ bool isGray() const {
+ Chunk *c = chunk();
+ uint index = this - c->realBase();
+ return Chunk::testBit(c->grayBitmap, index);
+ }
+ bool isBlack() const {
+ Chunk *c = chunk();
+ uint index = this - c->realBase();
+ return Chunk::testBit(c->blackBitmap, index);
+ }
+ bool isInUse() const {
+ Chunk *c = chunk();
+ uint index = this - c->realBase();
+ return Chunk::testBit(c->objectBitmap, index);
+ }
+
+ void setAllocatedSlots(size_t nSlots) {
+// Q_ASSERT(size && !(size % sizeof(HeapItem)));
+ Chunk *c = chunk();
+ size_t index = this - c->realBase();
+// Q_ASSERT(!Chunk::testBit(c->objectBitmap, index));
+ Chunk::setBit(c->objectBitmap, index);
+ Chunk::setBits(c->extendsBitmap, index + 1, nSlots - 1);
+// for (uint i = index + 1; i < nBits - 1; ++i)
+// Q_ASSERT(Chunk::testBit(c->extendsBitmap, i));
+// Q_ASSERT(!Chunk::testBit(c->extendsBitmap, index));
+ }
+
+ // Doesn't report correctly for huge items
+ size_t size() const {
+ Chunk *c = chunk();
+ uint index = this - c->realBase();
+ Q_ASSERT(Chunk::testBit(c->objectBitmap, index));
+ // ### optimize me
+ uint end = index + 1;
+ while (end < Chunk::NumSlots && Chunk::testBit(c->extendsBitmap, end))
+ ++end;
+ return (end - index)*sizeof(HeapItem);
+ }
+};
+
+inline HeapItem *Chunk::realBase()
+{
+ return reinterpret_cast<HeapItem *>(this);
+}
+
+inline HeapItem *Chunk::first()
+{
+ return reinterpret_cast<HeapItem *>(data);
+}
+
+Q_STATIC_ASSERT(sizeof(Chunk) == Chunk::ChunkSize);
+Q_STATIC_ASSERT((1 << Chunk::ChunkShift) == Chunk::ChunkSize);
+Q_STATIC_ASSERT(1 << Chunk::SlotSizeShift == Chunk::SlotSize);
+Q_STATIC_ASSERT(sizeof(HeapItem) == Chunk::SlotSize);
+Q_STATIC_ASSERT(QT_POINTER_SIZE*8 == Chunk::Bits);
+Q_STATIC_ASSERT((1 << Chunk::BitShift) == Chunk::Bits);
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index 826a074701..8f9e4b7f83 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -14,6 +14,8 @@ solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
# Ensure this gcc optimization is switched off for mips platforms to avoid trouble with JIT.
gcc:isEqual(QT_ARCH, "mips"): QMAKE_CXXFLAGS += -fno-reorder-blocks
+DEFINES += QT_NO_FOREACH
+
exists("qqml_enable_gcov") {
QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -fno-elide-constructors
LIBS_PRIVATE += -lgcov
diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp
index 39d609454f..b1c320afd4 100644
--- a/src/qml/qml/qqmlabstractbinding.cpp
+++ b/src/qml/qml/qqmlabstractbinding.cpp
@@ -191,7 +191,7 @@ void QQmlAbstractBinding::removeFromObject()
void QQmlAbstractBinding::printBindingLoopError(QQmlProperty &prop)
{
- qmlInfo(prop.object()) << QString(QLatin1String("Binding loop detected for property \"%1\"")).arg(prop.name());
+ qmlWarning(prop.object()) << QString(QLatin1String("Binding loop detected for property \"%1\"")).arg(prop.name());
}
QString QQmlAbstractBinding::expression() const
diff --git a/src/qml/qml/qqmlabstracturlinterceptor.h b/src/qml/qml/qqmlabstracturlinterceptor.h
index dfb8a46027..665b37fb3a 100644
--- a/src/qml/qml/qqmlabstracturlinterceptor.h
+++ b/src/qml/qml/qqmlabstracturlinterceptor.h
@@ -47,7 +47,6 @@ QT_BEGIN_NAMESPACE
class Q_QML_EXPORT QQmlAbstractUrlInterceptor
{
- Q_FLAGS(InterceptionPoint)
public:
enum DataType { //Matches QQmlDataBlob::Type
QmlFile = 0,
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 8a97b7eba7..2a96d96302 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -190,9 +190,14 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o)
/*!
\fn QQmlApplicationEngine::objectCreated(QObject *object, const QUrl &url)
- This signal is emitted when an object finishes loading. If loading was successful, \a object contains a pointer to the loaded object.
- Otherwise the pointer is NULL. The \a url loaded is also provided, note that if a QString file path was initially passed to the
- QQmlApplicationEngine, this url will be the equivalent of QUrl::fromLocalFile(filePath).
+ This signal is emitted when an object finishes loading. If loading was
+ successful, \a object contains a pointer to the loaded object, otherwise
+ the pointer is NULL.
+
+ The \a url to the component the \a object came from is also provided.
+
+ \note If the path to the component was provided as a QString containing a
+ relative path, the \a url will contain a fully resolved path to the file.
*/
/*!
@@ -226,7 +231,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QUrl &url, QObject *parent)
This is provided as a convenience, and is the same as using the empty constructor and calling load afterwards.
*/
QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *parent)
- : QQmlApplicationEngine(QUrl::fromLocalFile(filePath), parent)
+ : QQmlApplicationEngine(QUrl::fromUserInput(filePath, QLatin1String("."), QUrl::AssumeLocalFile), parent)
{
}
@@ -265,7 +270,7 @@ void QQmlApplicationEngine::load(const QUrl &url)
void QQmlApplicationEngine::load(const QString &filePath)
{
Q_D(QQmlApplicationEngine);
- d->startLoad(QUrl::fromLocalFile(filePath));
+ d->startLoad(QUrl::fromUserInput(filePath, QLatin1String("."), QUrl::AssumeLocalFile));
}
/*!
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 254d5e1907..19ece44beb 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -91,7 +91,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
function += QQmlPropertyCache::signalParameterStringForJS(v4, signal.parameterNames(), &error);
if (!error.isEmpty()) {
- qmlInfo(scopeObject()) << error;
+ qmlWarning(scopeObject()) << error;
return;
}
} else
@@ -129,7 +129,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
QString error;
QQmlPropertyCache::signalParameterStringForJS(engine, signalParameters, &error);
if (!error.isEmpty()) {
- qmlInfo(scopeObject()) << error;
+ qmlWarning(scopeObject()) << error;
return;
}
runtimeFunction->updateInternalClass(engine, signalParameters);
@@ -199,7 +199,10 @@ void QQmlBoundSignalExpression::evaluate(void **a)
// for several cases (such as QVariant type and QObject-derived types)
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
if (type == qMetaTypeId<QJSValue>()) {
- callData->args[ii] = *QJSValuePrivate::getValue(reinterpret_cast<QJSValue *>(a[ii + 1]));
+ if (QV4::Value *v4Value = QJSValuePrivate::valueForData(reinterpret_cast<QJSValue *>(a[ii + 1]), &callData->args[ii]))
+ callData->args[ii] = *v4Value;
+ else
+ callData->args[ii] = QV4::Encode::undefined();
} else if (type == QMetaType::QVariant) {
callData->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
} else if (type == QMetaType::Int) {
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 6ebcd142fb..a04f47e6a4 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -47,8 +47,6 @@
#include "qqml.h"
#include "qqmlengine.h"
#include "qqmlbinding_p.h"
-#include <private/qqmldebugconnector_p.h>
-#include <private/qqmldebugserviceinterfaces_p.h>
#include "qqmlincubator.h"
#include "qqmlincubator_p.h"
#include <private/qqmljavascriptexpression_p.h>
@@ -876,15 +874,6 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
depthIncreased = false;
}
- if (rv) {
- if (QQmlEngineDebugService *service =
- QQmlDebugConnector::service<QQmlEngineDebugService>()) {
- if (!context->isInternal)
- context->asQQmlContextPrivate()->instances.append(rv);
- service->objectCreated(engine, rv);
- }
- }
-
return rv;
}
@@ -1074,11 +1063,11 @@ struct QmlIncubatorObject : public QV4::Object
V4_OBJECT2(QmlIncubatorObject, Object)
V4_NEEDS_DESTROY
- static QV4::ReturnedValue method_get_statusChanged(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_statusChanged(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_status(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_object(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_forceCompletion(QV4::CallContext *ctx);
+ static void method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData);
static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e);
@@ -1244,7 +1233,7 @@ void QQmlComponent::createObject(QQmlV4Function *args)
if (args->length() >= 2) {
QV4::ScopedValue v(scope, (*args)[1]);
if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) {
- qmlInfo(this) << tr("createObject: value is not an object");
+ qmlWarning(this) << tr("createObject: value is not an object");
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -1361,7 +1350,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
QV4::ScopedValue v(scope, (*args)[1]);
if (v->isNull()) {
} else if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) {
- qmlInfo(this) << tr("createObject: value is not an object");
+ qmlWarning(this) << tr("createObject: value is not an object");
args->setReturnValue(QV4::Encode::null());
return;
} else {
@@ -1426,58 +1415,53 @@ QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4)
incubationProto.set(v4, proto);
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_object(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, o->d()->incubator->object());
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object());
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_forceCompletion(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
o->d()->incubator->forceCompletion();
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_status(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return QV4::Encode(o->d()->incubator->status());
+ scope.result = QV4::Encode(o->d()->incubator->status());
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_statusChanged(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return o->d()->statusChanged.asReturnedValue();
+ scope.result = o->d()->statusChanged;
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_set_statusChanged(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
- if (!o || ctx->argc() < 1)
- return ctx->engine()->throwTypeError();
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ if (!o || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ o->d()->statusChanged = callData->args[0];
- o->d()->statusChanged = ctx->args()[0];
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
QQmlComponentExtension::~QQmlComponentExtension()
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index 85c91a592a..0b0bbef795 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -83,7 +83,7 @@ QT_BEGIN_NAMESPACE
by \a data, which is a block of data previously returned by a call
to compile().
- Errors should be reported using qmlInfo(object).
+ Errors should be reported using qmlWarning(object).
The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
*/
diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp
index 7552e1e82b..d5d2c9a28d 100644
--- a/src/qml/qml/qqmldelayedcallqueue.cpp
+++ b/src/qml/qml/qqmldelayedcallqueue.cpp
@@ -105,17 +105,15 @@ void QQmlDelayedCallQueue::init(QV4::ExecutionEngine* engine)
m_tickedMethod = metaObject.method(methodIndex);
}
-QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(QV4::CallContext *ctx)
+void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- const QV4::CallData *callData = ctx->d()->callData;
-
if (callData->argc == 0)
- V4THROW_ERROR("Qt.callLater: no arguments given");
+ THROW_GENERIC_ERROR("Qt.callLater: no arguments given");
const QV4::FunctionObject *func = callData->args[0].as<QV4::FunctionObject>();
if (!func)
- V4THROW_ERROR("Qt.callLater: first argument not a function or signal");
+ THROW_GENERIC_ERROR("Qt.callLater: first argument not a function or signal");
QPair<QObject *, int> functionData = QV4::QObjectMethod::extractQtMethod(func);
@@ -171,7 +169,7 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(QV4::CallCon
m_tickedMethod.invoke(this, Qt::QueuedConnection);
m_callbackOutstanding = true;
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4::CallData *callData, int offset, QV4::ExecutionEngine *engine)
diff --git a/src/qml/qml/qqmldelayedcallqueue_p.h b/src/qml/qml/qqmldelayedcallqueue_p.h
index ef899170a2..cffde4f0c0 100644
--- a/src/qml/qml/qqmldelayedcallqueue_p.h
+++ b/src/qml/qml/qqmldelayedcallqueue_p.h
@@ -70,7 +70,7 @@ public:
void init(QV4::ExecutionEngine *);
- QV4::ReturnedValue addUniquelyAndExecuteLater(QV4::CallContext *ctx);
+ void addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
public Q_SLOTS:
void ticked();
diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qml/qqmldirparser.cpp
index fde7cc4cef..4cca8a4d58 100644
--- a/src/qml/qml/qqmldirparser.cpp
+++ b/src/qml/qml/qqmldirparser.cpp
@@ -188,6 +188,15 @@ bool QQmlDirParser::parse(const QString &source)
_plugins.append(entry);
+ } else if (sections[0] == QLatin1String("classname")) {
+ if (sectionCount < 2) {
+ reportError(lineNumber, 0,
+ QStringLiteral("classname directive requires an argument, but %1 were provided").arg(sectionCount - 1));
+
+ continue;
+ }
+
+ // Ignore these. qmlimportscanner uses them.
} else if (sections[0] == QLatin1String("internal")) {
if (sectionCount != 3) {
reportError(lineNumber, 0,
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index c2915c840b..e1fa97b52f 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -436,7 +436,6 @@ The following functions are also on the Qt object.
\list
\li \c "android" - Android
- \li \c "blackberry" - BlackBerry OS
\li \c "ios" - iOS
\li \c "tvos" - tvOS
\li \c "linux" - Linux
@@ -444,7 +443,6 @@ The following functions are also on the Qt object.
\li \c "unix" - Other Unix-based OS
\li \c "windows" - Windows
\li \c "winrt" - WinRT / UWP
- \li \c "winphone" - Windows Phone
\endlist
\endtable
*/
@@ -1914,9 +1912,29 @@ void QQmlEnginePrivate::sendExit(int retCode)
static void dumpwarning(const QQmlError &error)
{
- QMessageLogger(error.url().toString().toLatin1().constData(),
- error.line(), 0).warning().nospace()
- << qPrintable(error.toString());
+ switch (error.messageType()) {
+ case QtDebugMsg:
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).debug().nospace()
+ << qPrintable(error.toString());
+ break;
+ case QtInfoMsg:
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).info().nospace()
+ << qPrintable(error.toString());
+ break;
+ case QtWarningMsg:
+ case QtFatalMsg: // fatal does not support streaming, and furthermore, is actually fatal. Probably not desirable for QML.
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).warning().nospace()
+ << qPrintable(error.toString());
+ break;
+ case QtCriticalMsg:
+ QMessageLogger(error.url().toString().toLatin1().constData(),
+ error.line(), 0).critical().nospace()
+ << qPrintable(error.toString());
+ break;
+ }
}
static void dumpwarning(const QList<QQmlError> &errors)
@@ -2129,8 +2147,7 @@ bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList
Returns the directory where SQL and other offline
storage is placed.
- QQuickWebView and the SQL databases created with openDatabase()
- are stored here.
+ The SQL databases created with openDatabase() are stored here.
The default is QML/OfflineStorage in the platform-standard
user application data directory.
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 0a6c7b4960..7a1e02eec6 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -85,11 +85,12 @@ public:
QString description;
quint16 line;
quint16 column;
+ QtMsgType messageType;
QObject *object;
};
QQmlErrorPrivate::QQmlErrorPrivate()
-: line(0), column(0), object()
+: line(0), column(0), messageType(QtMsgType::QtWarningMsg), object()
{
}
@@ -119,12 +120,14 @@ QQmlError &QQmlError::operator=(const QQmlError &other)
delete d;
d = 0;
} else {
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->url = other.d->url;
d->description = other.d->description;
d->line = other.d->line;
d->column = other.d->column;
d->object = other.d->object;
+ d->messageType = other.d->messageType;
}
return *this;
}
@@ -150,8 +153,9 @@ bool QQmlError::isValid() const
*/
QUrl QQmlError::url() const
{
- if (d) return d->url;
- else return QUrl();
+ if (d)
+ return d->url;
+ return QUrl();
}
/*!
@@ -159,7 +163,8 @@ QUrl QQmlError::url() const
*/
void QQmlError::setUrl(const QUrl &url)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->url = url;
}
@@ -168,8 +173,9 @@ void QQmlError::setUrl(const QUrl &url)
*/
QString QQmlError::description() const
{
- if (d) return d->description;
- else return QString();
+ if (d)
+ return d->description;
+ return QString();
}
/*!
@@ -177,7 +183,8 @@ QString QQmlError::description() const
*/
void QQmlError::setDescription(const QString &description)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->description = description;
}
@@ -186,8 +193,9 @@ void QQmlError::setDescription(const QString &description)
*/
int QQmlError::line() const
{
- if (d) return qmlSourceCoordinate(d->line);
- else return -1;
+ if (d)
+ return qmlSourceCoordinate(d->line);
+ return -1;
}
/*!
@@ -195,7 +203,8 @@ int QQmlError::line() const
*/
void QQmlError::setLine(int line)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->line = qmlSourceCoordinate(line);
}
@@ -204,8 +213,9 @@ void QQmlError::setLine(int line)
*/
int QQmlError::column() const
{
- if (d) return qmlSourceCoordinate(d->column);
- else return -1;
+ if (d)
+ return qmlSourceCoordinate(d->column);
+ return -1;
}
/*!
@@ -213,7 +223,8 @@ int QQmlError::column() const
*/
void QQmlError::setColumn(int column)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->column = qmlSourceCoordinate(column);
}
@@ -225,8 +236,9 @@ void QQmlError::setColumn(int column)
*/
QObject *QQmlError::object() const
{
- if (d) return d->object;
- else return 0;
+ if (d)
+ return d->object;
+ return 0;
}
/*!
@@ -234,11 +246,37 @@ QObject *QQmlError::object() const
*/
void QQmlError::setObject(QObject *object)
{
- if (!d) d = new QQmlErrorPrivate;
+ if (!d)
+ d = new QQmlErrorPrivate;
d->object = object;
}
/*!
+ \since 5.9
+
+ Returns the message type.
+ */
+QtMsgType QQmlError::messageType() const
+{
+ if (d)
+ return d->messageType;
+ return QtMsgType::QtWarningMsg;
+}
+
+/*!
+ \since 5.9
+
+ Sets the \a messageType for this message. The message type determines which
+ QDebug handlers are responsible for recieving the message.
+ */
+void QQmlError::setMessageType(QtMsgType messageType)
+{
+ if (!d)
+ d = new QQmlErrorPrivate;
+ d->messageType = messageType;
+}
+
+/*!
Returns the error as a human readable string.
*/
QString QQmlError::toString() const
diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h
index e4c42223cf..ef529e3828 100644
--- a/src/qml/qml/qqmlerror.h
+++ b/src/qml/qml/qqmlerror.h
@@ -47,6 +47,7 @@
QT_BEGIN_NAMESPACE
+// ### Qt 6: should this be called QQmlMessage, since it can have a message type?
class QDebug;
class QQmlErrorPrivate;
class Q_QML_EXPORT QQmlError
@@ -69,6 +70,8 @@ public:
void setColumn(int);
QObject *object() const;
void setObject(QObject *);
+ QtMsgType messageType() const;
+ void setMessageType(QtMsgType messageType);
QString toString() const;
private:
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index ca19691e93..097fa71200 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -117,4 +117,14 @@ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
Q_UNUSED(uri);
}
+/*!
+ \class QQmlExtensionInterface
+ \internal
+ \inmodule QtQml
+
+ \class QQmlTypesExtensionInterface
+ \internal
+ \inmodule QtQml
+*/
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 8712b638c5..bd41659f27 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -130,42 +130,74 @@ bool isPathAbsolute(const QString &path)
#endif
}
-// If the type does not already exist as a file import, add the type and return the new type
-QQmlType *getTypeForUrl(const QString &urlString, const QHashedStringRef& typeName,
+/*
+ \internal
+
+ Fetches the QQmlType instance registered for \a urlString, creating a
+ registration for it if it is not already registered, using the associated
+ \a typeName, \a isCompositeSingleton, \a majorVersion and \a minorVersion
+ details.
+
+ Errors (if there are any) are placed into \a errors, if it is nonzero. Note
+ that errors are treated as fatal if \a errors is not set.
+*/
+QQmlType *fetchOrCreateTypeForUrl(const QString &urlString, const QHashedStringRef& typeName,
bool isCompositeSingleton, QList<QQmlError> *errors,
int majorVersion=-1, int minorVersion=-1)
{
- QUrl url(urlString);
+ QUrl url(urlString); // ### unfortunate (costly) conversion
QQmlType *ret = QQmlMetaType::qmlType(url);
- if (!ret) { //QQmlType not yet existing for composite or composite singleton type
- int dot = typeName.indexOf(QLatin1Char('.'));
- QHashedStringRef unqualifiedtype = dot < 0 ? typeName : QHashedStringRef(typeName.constData() + dot + 1, typeName.length() - dot - 1);
-
- //XXX: The constData of the string ref is pointing somewhere unsafe in qmlregister, so we need to create a temporary copy
- QByteArray buf(unqualifiedtype.toString().toUtf8());
-
- if (isCompositeSingleton) {
- QQmlPrivate::RegisterCompositeSingletonType reg = {
- url,
- "", //Empty URI indicates loaded via file imports
- majorVersion,
- minorVersion,
- buf.constData()
- };
- ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeSingletonRegistration, &reg));
- } else {
- QQmlPrivate::RegisterCompositeType reg = {
- url,
- "", //Empty URI indicates loaded via file imports
- majorVersion,
- minorVersion,
- buf.constData()
- };
- ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &reg));
- }
+ if (ret)
+ return ret;
+
+ int dot = typeName.indexOf(QLatin1Char('.'));
+ QHashedStringRef unqualifiedtype = dot < 0 ? typeName : QHashedStringRef(typeName.constData() + dot + 1, typeName.length() - dot - 1);
+
+ // We need a pointer, but we were passed a string. Take a copy so we
+ // can guarentee it will live long enough to reach qmlregister.
+ QByteArray buf(unqualifiedtype.toString().toUtf8());
+
+ // Register the type. Note that the URI parameters here are empty; for
+ // file type imports, we do not place them in a URI as we don't
+ // necessarily have a good and unique one (picture a library import,
+ // which may be found in multiple plugin locations on disk), but there
+ // are other reasons for this too.
+ //
+ // By not putting them in a URI, we prevent the types from being
+ // registered on a QQmlTypeModule; this is important, as once types are
+ // placed on there, they cannot be easily removed, meaning if the
+ // developer subsequently loads a different import (meaning different
+ // types) with the same URI (using, say, a different plugin path), it is
+ // very undesirable that we continue to associate the types from the
+ // "old" URI with that new module.
+ //
+ // Not having URIs also means that the types cannot be found by name
+ // etc, the only way to look them up is through QQmlImports -- for
+ // better or worse.
+ if (isCompositeSingleton) {
+ QQmlPrivate::RegisterCompositeSingletonType reg = {
+ url,
+ "", // uri
+ majorVersion,
+ minorVersion,
+ buf.constData()
+ };
+ ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeSingletonRegistration, &reg));
+ } else {
+ QQmlPrivate::RegisterCompositeType reg = {
+ url,
+ "", // uri
+ majorVersion,
+ minorVersion,
+ buf.constData()
+ };
+ ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &reg));
}
- if (!ret) {//Usually when a type name is "found" but invalid
- //qDebug() << ret << urlString << QQmlMetaType::qmlType(url);
+
+ // This means that the type couldn't be found by URL, but could not be
+ // registered either, meaning we most likely were passed some kind of bad
+ // data.
+ if (!ret) {
if (!errors) // Cannot list errors properly, just quit
qFatal("%s", QQmlMetaType::typeRegistrationFailures().join('\n').toLatin1().constData());
QQmlError error;
@@ -204,20 +236,49 @@ void qmlClearEnginePlugins()
typedef QPair<QStaticPlugin, QJsonArray> StaticPluginPair;
#endif
+/*!
+ \internal
+
+ A QQmlImportNamespace is a way of seperating imports into a local namespace.
+
+ Within a QML document, there is at least one namespace (the
+ "unqualified set") where imports without a qualifier are placed, i.e:
+
+ import QtQuick 2.6
+
+ will have a single namespace (the unqualified set) containing a single import
+ for QtQuick 2.6. However, there may be others if an import statement gives
+ a qualifier, i.e the following will result in an additional new
+ QQmlImportNamespace in the qualified set:
+
+ import MyFoo 1.0 as Foo
+*/
class QQmlImportNamespace
{
public:
QQmlImportNamespace() : nextNamespace(0) {}
~QQmlImportNamespace() { qDeleteAll(imports); }
+ /*!
+ \internal
+
+ A QQmlImportNamespace::Import represents an actual instance of an import
+ within a namespace.
+
+ \note The uri here may not necessarily be unique (e.g. for file imports).
+
+ \note Version numbers may be -1 for file imports: this means that no
+ version was specified as part of the import. Type resolution will be
+ responsible for attempting to find the "best" possible version.
+ */
struct Import {
- QString uri;
- QString url;
- int majversion;
- int minversion;
- bool isLibrary;
- QQmlDirComponents qmlDirComponents;
- QQmlDirScripts qmlDirScripts;
+ QString uri; // e.g. QtQuick
+ QString url; // the base path of the import
+ int majversion; // the major version imported
+ int minversion; // the minor version imported
+ bool isLibrary; // true means that this is not a file import
+ QQmlDirComponents qmlDirComponents; // a copy of the components listed in the qmldir
+ QQmlDirScripts qmlDirScripts; // a copy of the scripts in the qmldir
bool setQmldirContent(const QString &resolvedUrl, const QQmlTypeLoader::QmldirContent *qmldir,
QQmlImportNamespace *nameSpace, QList<QQmlError> *errors);
@@ -273,9 +334,12 @@ public:
QString base;
int ref;
+ // storage of data related to imports without a namespace
mutable QQmlImportNamespace unqualifiedset;
QQmlImportNamespace *findQualifiedNamespace(const QHashedStringRef &) const;
+
+ // storage of data related to imports with a namespace
mutable QFieldList<QQmlImportNamespace, &QQmlImportNamespace::nextNamespace> qualifiedSets;
QQmlTypeLoader *typeLoader;
@@ -683,15 +747,17 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
if ((candidate == end) ||
(c.majorVersion > candidate->majorVersion) ||
((c.majorVersion == candidate->majorVersion) && (c.minorVersion > candidate->minorVersion))) {
- componentUrl = resolveLocalUrl(QString(url + c.typeName + dotqml_string), c.fileName);
- if (c.internal && base) {
- if (resolveLocalUrl(*base, c.fileName) != componentUrl)
- continue; // failed attempt to access an internal type
- }
- if (base && (*base == componentUrl)) {
- if (typeRecursionDetected)
- *typeRecursionDetected = true;
- continue; // no recursion
+ if (base) {
+ componentUrl = resolveLocalUrl(QString(url + c.typeName + dotqml_string), c.fileName);
+ if (c.internal) {
+ if (resolveLocalUrl(*base, c.fileName) != componentUrl)
+ continue; // failed attempt to access an internal type
+ }
+ if (*base == componentUrl) {
+ if (typeRecursionDetected)
+ *typeRecursionDetected = true;
+ continue; // no recursion
+ }
}
// This is our best candidate so far
@@ -702,9 +768,11 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
}
if (candidate != end) {
+ if (!base) // ensure we have a componentUrl
+ componentUrl = resolveLocalUrl(QString(url + candidate->typeName + dotqml_string), candidate->fileName);
int major = vmajor ? *vmajor : -1;
int minor = vminor ? *vminor : -1;
- QQmlType *returnType = getTypeForUrl(componentUrl, type, isCompositeSingleton, 0,
+ QQmlType *returnType = fetchOrCreateTypeForUrl(componentUrl, type, isCompositeSingleton, 0,
major, minor);
if (type_return)
*type_return = returnType;
@@ -732,7 +800,7 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
if (typeRecursionDetected)
*typeRecursionDetected = true;
} else {
- QQmlType *returnType = getTypeForUrl(qmlUrl, type, false, 0);
+ QQmlType *returnType = fetchOrCreateTypeForUrl(qmlUrl, type, false, 0);
if (type_return)
*type_return = returnType;
return returnType != 0;
@@ -777,7 +845,7 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor,
return true;
if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && type_return && s != &unqualifiedset) {
// qualified, and only 1 url
- *type_return = getTypeForUrl(resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")), type, false, errors);
+ *type_return = fetchOrCreateTypeForUrl(resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")), type, false, errors);
return (*type_return != 0);
}
}
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 963638ca34..54d0b240f5 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -380,6 +380,23 @@ finishIncubate:
}
}
+void QQmlIncubatorPrivate::cancel(QObject *object, QQmlContext *context)
+{
+ if (!context)
+ context = qmlContext(object);
+ if (!context)
+ return;
+
+ QQmlContextData *data = QQmlContextData::get(context);
+ QQmlIncubatorPrivate *p = (QQmlIncubatorPrivate *)data->activeVMEData;
+ if (!p)
+ return;
+
+ p->vmeGuard.unguard(object);
+ if (!p->creator.isNull())
+ p->creator->cancel(object);
+}
+
/*!
Incubate objects for \a msecs, or until there are no more objects to incubate.
*/
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h
index ecf3b6d2ca..758e0a29f6 100644
--- a/src/qml/qml/qqmlincubator_p.h
+++ b/src/qml/qml/qqmlincubator_p.h
@@ -40,6 +40,8 @@
#ifndef QQMLINCUBATOR_P_H
#define QQMLINCUBATOR_P_H
+#include "qqmlincubator.h"
+
#include <private/qintrusivelist_p.h>
#include <private/qqmlvme_p.h>
#include <private/qrecursionwatcher_p.h>
@@ -100,6 +102,9 @@ public:
void forceCompletion(QQmlInstantiationInterrupt &i);
void incubate(QQmlInstantiationInterrupt &i);
+
+ // used by Qt Quick Controls 2
+ Q_QML_PRIVATE_EXPORT static void cancel(QObject *object, QQmlContext *context = 0);
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp
index 5b6e02d5b1..dae15e2eca 100644
--- a/src/qml/qml/qqmlinfo.cpp
+++ b/src/qml/qml/qqmlinfo.cpp
@@ -50,13 +50,45 @@
QT_BEGIN_NAMESPACE
/*!
+ \fn QQmlInfo QtQml::qmlDebug(const QObject *object)
+ \relates QQmlEngine
+ \since 5.9
+
+ Prints debug messages that include the file and line number for the
+ specified QML \a object.
+
+ When QML types produce logging messages, it improves traceability
+ if they include the QML file and line number on which the
+ particular instance was instantiated.
+
+ To include the file and line number, an object must be passed. If
+ the file and line number is not available for that instance
+ (either it was not instantiated by the QML engine or location
+ information is disabled), "unknown location" will be used instead.
+
+ For example,
+
+ \code
+ qmlDebug(object) << "Internal state: 42";
+ \endcode
+
+ prints
+
+ \code
+ QML MyCustomType (unknown location): Internal state: 42
+ \endcode
+
+ \sa QtQml::qmlInfo, QtQml::qmlWarning
+*/
+
+/*!
\fn QQmlInfo QtQml::qmlInfo(const QObject *object)
\relates QQmlEngine
- Prints warning messages that include the file and line number for the
+ Prints informational messages that include the file and line number for the
specified QML \a object.
- When QML types display warning messages, it improves traceability
+ When QML types produce logging messages, it improves traceability
if they include the QML file and line number on which the
particular instance was instantiated.
@@ -76,14 +108,58 @@ QT_BEGIN_NAMESPACE
\code
QML MyCustomType (unknown location): component property is a write-once property
\endcode
+
+ \note In versions prior to Qt 5.9, qmlInfo reported messages using a warning
+ QtMsgType. For Qt 5.9 and above, qmlInfo uses an info QtMsgType. To send
+ warnings, use qmlWarning.
+
+ \sa QtQml::qmlDebug, QtQml::qmlWarning
+*/
+
+
+/*!
+ \fn QQmlInfo QtQml::qmlWarning(const QObject *object)
+ \relates QQmlEngine
+ \since 5.9
+
+ Prints warning messages that include the file and line number for the
+ specified QML \a object.
+
+ When QML types produce logging messages, it improves traceability
+ if they include the QML file and line number on which the
+ particular instance was instantiated.
+
+ To include the file and line number, an object must be passed. If
+ the file and line number is not available for that instance
+ (either it was not instantiated by the QML engine or location
+ information is disabled), "unknown location" will be used instead.
+
+ For example,
+
+ \code
+ qmlInfo(object) << tr("property cannot be set to 0");
+ \endcode
+
+ prints
+
+ \code
+ QML MyCustomType (unknown location): property cannot be set to 0
+ \endcode
+
+ \sa QtQml::qmlDebug, QtQml::qmlInfo
*/
class QQmlInfoPrivate
{
public:
- QQmlInfoPrivate() : ref (1), object(0) {}
+ QQmlInfoPrivate(QtMsgType type)
+ : ref (1)
+ , msgType(type)
+ , object(nullptr)
+ {}
int ref;
+ QtMsgType msgType;
const QObject *object;
QString buffer;
QList<QQmlError> errors;
@@ -110,6 +186,7 @@ QQmlInfo::~QQmlInfo()
if (!d->buffer.isEmpty()) {
QQmlError error;
+ error.setMessageType(d->msgType);
QObject *object = const_cast<QObject *>(d->object);
@@ -139,28 +216,32 @@ QQmlInfo::~QQmlInfo()
namespace QtQml {
-QQmlInfo qmlInfo(const QObject *me)
-{
- QQmlInfoPrivate *d = new QQmlInfoPrivate;
- d->object = me;
- return QQmlInfo(d);
-}
+#define MESSAGE_FUNCS(FuncName, MessageLevel) \
+ QQmlInfo FuncName(const QObject *me) \
+ { \
+ QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \
+ d->object = me; \
+ return QQmlInfo(d); \
+ } \
+ QQmlInfo FuncName(const QObject *me, const QQmlError &error) \
+ { \
+ QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \
+ d->object = me; \
+ d->errors << error; \
+ return QQmlInfo(d); \
+ } \
+ QQmlInfo FuncName(const QObject *me, const QList<QQmlError> &errors) \
+ { \
+ QQmlInfoPrivate *d = new QQmlInfoPrivate(MessageLevel); \
+ d->object = me; \
+ d->errors = errors; \
+ return QQmlInfo(d); \
+ }
-QQmlInfo qmlInfo(const QObject *me, const QQmlError &error)
-{
- QQmlInfoPrivate *d = new QQmlInfoPrivate;
- d->object = me;
- d->errors << error;
- return QQmlInfo(d);
-}
+MESSAGE_FUNCS(qmlDebug, QtMsgType::QtDebugMsg)
+MESSAGE_FUNCS(qmlInfo, QtMsgType::QtInfoMsg)
+MESSAGE_FUNCS(qmlWarning, QtMsgType::QtWarningMsg)
-QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors)
-{
- QQmlInfoPrivate *d = new QQmlInfoPrivate;
- d->object = me;
- d->errors = errors;
- return QQmlInfo(d);
-}
} // namespace QtQml
diff --git a/src/qml/qml/qqmlinfo.h b/src/qml/qml/qqmlinfo.h
index ab0281a688..673125632e 100644
--- a/src/qml/qml/qqmlinfo.h
+++ b/src/qml/qml/qqmlinfo.h
@@ -48,11 +48,19 @@ QT_BEGIN_NAMESPACE
class QQmlInfo;
+// declared in namespace to avoid symbol conflicts with QtDeclarative
namespace QtQml {
- // declared in namespace to avoid symbol conflicts with QtDeclarative
+ Q_QML_EXPORT QQmlInfo qmlDebug(const QObject *me);
+ Q_QML_EXPORT QQmlInfo qmlDebug(const QObject *me, const QQmlError &error);
+ Q_QML_EXPORT QQmlInfo qmlDebug(const QObject *me, const QList<QQmlError> &errors);
+
Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me);
Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QQmlError &error);
Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors);
+
+ Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me);
+ Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me, const QQmlError &error);
+ Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me, const QList<QQmlError> &errors);
}
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wheader-hygiene")
@@ -93,9 +101,15 @@ public:
#endif
private:
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlDebug(const QObject *me);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlDebug(const QObject *me, const QQmlError &error);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlDebug(const QObject *me, const QList<QQmlError> &errors);
friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me);
friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me, const QQmlError &error);
friend Q_QML_EXPORT QQmlInfo QtQml::qmlInfo(const QObject *me, const QList<QQmlError> &errors);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlWarning(const QObject *me);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlWarning(const QObject *me, const QQmlError &error);
+ friend Q_QML_EXPORT QQmlInfo QtQml::qmlWarning(const QObject *me, const QList<QQmlError> &errors);
QQmlInfo(QQmlInfoPrivate *);
QQmlInfoPrivate *d;
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index a719956483..edd93ef03d 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -335,7 +335,7 @@ int QQmlListReference::count() const
\since 5.0
\inmodule QtQml
\brief The QQmlListProperty class allows applications to expose list-like
-properties to QML.
+properties of QObject-derived classes to QML.
QML has many list properties, where more than one object value can be assigned.
The use of a list property from QML looks like this:
@@ -369,7 +369,8 @@ QML list properties are type-safe - in this case \c {Fruit} is a QObject type th
The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty.
-\note QQmlListProperty can only be used for lists of QObject-derived object pointers.
+\sa {Extending QML - Object and List Property Types Example}
+
*/
/*!
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 3876e774c3..712da78807 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -56,10 +56,17 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(QQmlLocaleData);
+#define THROW_ERROR(string) \
+ do { \
+ scope.result = scope.engine->throwError(QString::fromUtf8(string)); \
+ return; \
+ } while (false)
+
+
#define GET_LOCALE_DATA_RESOURCE(OBJECT) \
QV4::Scoped<QQmlLocaleData> r(scope, OBJECT.as<QQmlLocaleData>()); \
if (!r) \
- V4THROW_ERROR("Not a valid Locale object")
+ THROW_ERROR("Not a valid Locale object")
static bool isLocaleObject(const QV4::Value &val)
{
@@ -80,215 +87,219 @@ void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine)
engine->dateCtor()->defineDefaultProperty(QStringLiteral("timeZoneUpdated"), method_timeZoneUpdated);
}
-QV4::ReturnedValue QQmlDateExtension::method_toLocaleString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 2)
- return QV4::DatePrototype::method_toLocaleString(ctx);
-
- QV4::Scope scope(ctx);
+ if (callData->argc > 2) {
+ QV4::DatePrototype::method_toLocaleString(b, scope, callData);
+ return;
+ }
- QV4::DateObject *date = ctx->thisObject().as<DateObject>();
- if (!date)
- return QV4::DatePrototype::method_toLocaleString(ctx);
+ QV4::DateObject *date = callData->thisObject.as<DateObject>();
+ if (!date) {
+ QV4::DatePrototype::method_toLocaleString(b, scope, callData);
+ return;
+ }
QDateTime dt = date->toQDateTime();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(dt))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(dt)));
}
- if (!isLocaleObject(ctx->args()[0]))
- return QV4::DatePrototype::method_toLocaleString(ctx); // Use the default Date toLocaleString()
+ if (!isLocaleObject(callData->args[0])) {
+ QV4::DatePrototype::method_toLocaleString(b, scope, callData); // Use the default Date toLocaleString()
+ return;
+ }
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedDt;
- if (ctx->argc() == 2) {
- if (String *s = ctx->args()[1].stringValue()) {
+ if (callData->argc == 2) {
+ if (String *s = callData->args[1].stringValue()) {
QString format = s->toQString();
formattedDt = r->d()->locale->toString(dt, format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].toNumber();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDt = r->d()->locale->toString(dt, format);
} else {
- V4THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format");
+ THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format");
}
} else {
formattedDt = r->d()->locale->toString(dt, enumFormat);
}
- return ctx->d()->engine->newString(formattedDt)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedDt);
}
-QV4::ReturnedValue QQmlDateExtension::method_toLocaleTimeString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 2)
- return QV4::DatePrototype::method_toLocaleTimeString(ctx);
-
- QV4::Scope scope(ctx);
+ if (callData->argc > 2) {
+ QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData);
+ return;
+ }
- QV4::DateObject *date = ctx->thisObject().as<DateObject>();
- if (!date)
- return QV4::DatePrototype::method_toLocaleTimeString(ctx);
+ QV4::DateObject *date = callData->thisObject.as<DateObject>();
+ if (!date) {
+ QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData);
+ return;
+ }
QDateTime dt = date->toQDateTime();
QTime time = dt.time();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(time))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(time)));
}
- if (!isLocaleObject(ctx->args()[0]))
- return QV4::DatePrototype::method_toLocaleTimeString(ctx); // Use the default Date toLocaleTimeString()
+ if (!isLocaleObject(callData->args[0]))
+ return QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData); // Use the default Date toLocaleTimeString()
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedTime;
- if (ctx->argc() == 2) {
- if (String *s = ctx->args()[1].stringValue()) {
+ if (callData->argc == 2) {
+ if (String *s = callData->args[1].stringValue()) {
QString format = s->toQString();
formattedTime = r->d()->locale->toString(time, format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].toNumber();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedTime = r->d()->locale->toString(time, format);
} else {
- V4THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format");
+ THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format");
}
} else {
formattedTime = r->d()->locale->toString(time, enumFormat);
}
- return ctx->d()->engine->newString(formattedTime)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedTime);
}
-QV4::ReturnedValue QQmlDateExtension::method_toLocaleDateString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 2)
- return QV4::DatePrototype::method_toLocaleDateString(ctx);
-
- QV4::Scope scope(ctx);
+ if (callData->argc > 2) {
+ QV4::DatePrototype::method_toLocaleDateString(b, scope, callData);
+ return;
+ }
- QV4::DateObject *dateObj = ctx->thisObject().as<DateObject>();
- if (!dateObj)
- return QV4::DatePrototype::method_toLocaleDateString(ctx);
+ QV4::DateObject *dateObj = callData->thisObject.as<DateObject>();
+ if (!dateObj) {
+ QV4::DatePrototype::method_toLocaleDateString(b, scope, callData);
+ return;
+ }
QDateTime dt = dateObj->toQDateTime();
QDate date = dt.date();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(date))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(date)));
}
- if (!isLocaleObject(ctx->args()[0]))
- return QV4::DatePrototype::method_toLocaleDateString(ctx); // Use the default Date toLocaleDateString()
+ if (!isLocaleObject(callData->args[0]))
+ return QV4::DatePrototype::method_toLocaleDateString(b, scope, callData); // Use the default Date toLocaleDateString()
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedDate;
- if (ctx->argc() == 2) {
- if (String *s = ctx->args()[1].stringValue()) {
+ if (callData->argc == 2) {
+ if (String *s = callData->args[1].stringValue()) {
QString format = s->toQString();
formattedDate = r->d()->locale->toString(date, format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].toNumber();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDate = r->d()->locale->toString(date, format);
} else {
- V4THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format");
+ THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format");
}
} else {
formattedDate = r->d()->locale->toString(date, enumFormat);
}
- return ctx->d()->engine->newString(formattedDate)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedDate);
}
-QV4::ReturnedValue QQmlDateExtension::method_fromLocaleString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::ExecutionEngine * const engine = ctx->d()->engine;
- if (ctx->argc() == 1) {
- if (String *s = ctx->args()[0].stringValue()) {
+ QV4::ExecutionEngine * const engine = scope.engine;
+ if (callData->argc == 1) {
+ if (String *s = callData->args[0].stringValue()) {
QLocale locale;
QString dateString = s->toQString();
QDateTime dt = locale.toDateTime(dateString);
- return QV4::Encode(engine->newDateObject(dt));
+ RETURN_RESULT(engine->newDateObject(dt));
}
}
- QV4::Scope scope(ctx);
-
- if (ctx->argc() < 1 || ctx->argc() > 3 || !isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments");
+ if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDateTime dt;
- QString dateString = ctx->args()[1].toQStringNoThrow();
- if (ctx->argc() == 3) {
- if (String *s = ctx->args()[2].stringValue()) {
+ QString dateString = callData->args[1].toQStringNoThrow();
+ if (callData->argc == 3) {
+ if (String *s = callData->args[2].stringValue()) {
QString format = s->toQString();
dt = r->d()->locale->toDateTime(dateString, format);
- } else if (ctx->args()[2].isNumber()) {
- quint32 intFormat = ctx->args()[2].toNumber();
+ } else if (callData->args[2].isNumber()) {
+ quint32 intFormat = callData->args[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale->toDateTime(dateString, format);
} else {
- V4THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format");
+ THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format");
}
} else {
dt = r->d()->locale->toDateTime(dateString, enumFormat);
}
- return QV4::Encode(engine->newDateObject(dt));
+ scope.result = engine->newDateObject(dt);
}
-QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::ExecutionEngine * const engine = ctx->d()->engine;
+ QV4::ExecutionEngine * const engine = scope.engine;
- if (ctx->argc() == 1) {
- if (String *s = ctx->args()[0].stringValue()) {
+ if (callData->argc == 1) {
+ if (String *s = callData->args[0].stringValue()) {
QLocale locale;
QString timeString = s->toQString();
QTime time = locale.toTime(timeString);
QDateTime dt = QDateTime::currentDateTime();
dt.setTime(time);
- return QV4::Encode(engine->newDateObject(dt));
+ RETURN_RESULT(engine->newDateObject(dt));
}
}
- if (ctx->argc() < 1 || ctx->argc() > 3 || !isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments");
-
- QV4::Scope scope(ctx);
+ if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QTime tm;
- QString dateString = ctx->args()[1].toQStringNoThrow();
- if (ctx->argc() == 3) {
- if (String *s = ctx->args()[2].stringValue()) {
+ QString dateString = callData->args[1].toQStringNoThrow();
+ if (callData->argc == 3) {
+ if (String *s = callData->args[2].stringValue()) {
QString format = s->toQString();
tm = r->d()->locale->toTime(dateString, format);
- } else if (ctx->args()[2].isNumber()) {
- quint32 intFormat = ctx->args()[2].toNumber();
+ } else if (callData->args[2].isNumber()) {
+ quint32 intFormat = callData->args[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
tm = r->d()->locale->toTime(dateString, format);
} else {
- V4THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format");
+ THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format");
}
} else {
tm = r->d()->locale->toTime(dateString, enumFormat);
@@ -300,58 +311,56 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::CallConte
dt.setTime(tm);
}
- return QV4::Encode(engine->newDateObject(dt));
+ RETURN_RESULT(engine->newDateObject(dt));
}
-QV4::ReturnedValue QQmlDateExtension::method_fromLocaleDateString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::ExecutionEngine * const engine = ctx->d()->engine;
+ QV4::ExecutionEngine * const engine = scope.engine;
- if (ctx->argc() == 1) {
- if (String *s = ctx->args()[0].stringValue()) {
+ if (callData->argc == 1) {
+ if (String *s = callData->args[0].stringValue()) {
QLocale locale;
QString dateString = s->toQString();
QDate date = locale.toDate(dateString);
- return QV4::Encode(engine->newDateObject(QDateTime(date)));
+ RETURN_RESULT(engine->newDateObject(QDateTime(date)));
}
}
- if (ctx->argc() < 1 || ctx->argc() > 3 || !isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments");
+ if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments");
- QV4::Scope scope(ctx);
-
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDate dt;
- QString dateString = ctx->args()[1].toQStringNoThrow();
- if (ctx->argc() == 3) {
- if (String *s = ctx->args()[2].stringValue()) {
+ QString dateString = callData->args[1].toQStringNoThrow();
+ if (callData->argc == 3) {
+ if (String *s = callData->args[2].stringValue()) {
QString format = s->toQString();
dt = r->d()->locale->toDate(dateString, format);
- } else if (ctx->args()[2].isNumber()) {
- quint32 intFormat = ctx->args()[2].toNumber();
+ } else if (callData->args[2].isNumber()) {
+ quint32 intFormat = callData->args[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale->toDate(dateString, format);
} else {
- V4THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format");
+ THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format");
}
} else {
dt = r->d()->locale->toDate(dateString, enumFormat);
}
- return QV4::Encode(engine->newDateObject(QDateTime(dt)));
+ RETURN_RESULT(engine->newDateObject(QDateTime(dt)));
}
-QV4::ReturnedValue QQmlDateExtension::method_timeZoneUpdated(QV4::CallContext *ctx)
+void QQmlDateExtension::method_timeZoneUpdated(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 0)
- V4THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments");
+ if (callData->argc != 0)
+ THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments");
QV4::DatePrototype::timezoneUpdated();
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
//-----------------
@@ -364,148 +373,143 @@ void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine)
engine->numberCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
}
-QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(QV4::CallContext *ctx)
+void QQmlNumberExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 3)
- V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ if (callData->argc > 3)
+ THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- double number = ctx->thisObject().toNumber();
+ double number = callData->thisObject.toNumber();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(number))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(number)));
}
- if (!isLocaleObject(ctx->args()[0]))
- return QV4::NumberPrototype::method_toLocaleString(ctx); // Use the default Number toLocaleString()
-
- QV4::Scope scope(ctx);
+ if (!isLocaleObject(callData->args[0])) {
+ QV4::NumberPrototype::method_toLocaleString(b, scope, callData); // Use the default Number toLocaleString()
+ return;
+ }
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
quint16 format = 'f';
- if (ctx->argc() > 1) {
- if (!ctx->args()[1].isString())
- V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- QString fs = ctx->args()[1].toQString();
+ if (callData->argc > 1) {
+ if (!callData->args[1].isString())
+ THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ QString fs = callData->args[1].toQString();
if (fs.length())
format = fs.at(0).unicode();
}
int prec = 2;
- if (ctx->argc() > 2) {
- if (!ctx->args()[2].isNumber())
- V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- prec = ctx->args()[2].toInt32();
+ if (callData->argc > 2) {
+ if (!callData->args[2].isNumber())
+ THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ prec = callData->args[2].toInt32();
}
- return ctx->d()->engine->newString(r->d()->locale->toString(number, (char)format, prec))->asReturnedValue();
+ scope.result = scope.engine->newString(r->d()->locale->toString(number, (char)format, prec));
}
-QV4::ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(QV4::CallContext *ctx)
+void QQmlNumberExtension::method_toLocaleCurrencyString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 2)
- V4THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
+ if (callData->argc > 2)
+ THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
- double number = ctx->thisObject().toNumber();
+ double number = callData->thisObject.toNumber();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(number))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(number)));
}
- if (!isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
-
- QV4::Scope scope(ctx);
+ if (!isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QString symbol;
- if (ctx->argc() > 1) {
- if (!ctx->args()[1].isString())
- V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- symbol = ctx->args()[1].toQStringNoThrow();
+ if (callData->argc > 1) {
+ if (!callData->args[1].isString())
+ THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ symbol = callData->args[1].toQStringNoThrow();
}
- return ctx->d()->engine->newString(r->d()->locale->toCurrencyString(number, symbol))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(r->d()->locale->toCurrencyString(number, symbol)));
}
-QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::CallContext *ctx)
+void QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 2)
- V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
+ if (callData->argc < 1 || callData->argc > 2)
+ THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
int numberIdx = 0;
QLocale locale;
- QV4::Scope scope(ctx);
-
- if (ctx->argc() == 2) {
- if (!isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
+ if (callData->argc == 2) {
+ if (!isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
locale = *r->d()->locale;
numberIdx = 1;
}
- QString ns = ctx->args()[numberIdx].toQString();
+ QString ns = callData->args[numberIdx].toQString();
if (!ns.length())
- return QV4::Encode(Q_QNAN);
+ RETURN_RESULT(QV4::Encode(Q_QNAN));
bool ok = false;
double val = locale.toDouble(ns, &ok);
if (!ok)
- V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format")
+ THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format");
- return QV4::Encode(val);
+ scope.result = QV4::Encode(val);
}
//--------------
// Locale object
-QV4::ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_firstDayOfWeek(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
int fdow = int(locale->firstDayOfWeek());
if (fdow == 7)
fdow = 0; // Qt::Sunday = 7, but Sunday is 0 in JS Date
- return QV4::Encode(fdow);
+ scope.result = QV4::Encode(fdow);
}
-QV4::ReturnedValue QQmlLocaleData::method_get_measurementSystem(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_measurementSystem(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
- return QV4::Encode(locale->measurementSystem());
+ return;
+ scope.result = QV4::Encode(locale->measurementSystem());
}
-QV4::ReturnedValue QQmlLocaleData::method_get_textDirection(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_textDirection(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
- return QV4::Encode(locale->textDirection());
+ scope.result = QV4::Encode(locale->textDirection());
}
-QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_weekDays(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
QList<Qt::DayOfWeek> days = locale->weekdays();
- QV4::ScopedArrayObject result(scope, ctx->d()->engine->newArrayObject());
+ QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject());
result->arrayReserve(days.size());
for (int i = 0; i < days.size(); ++i) {
int day = days.at(i);
@@ -515,59 +519,58 @@ QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::CallContext *ctx)
}
result->setArrayLengthUnchecked(days.size());
- return result.asReturnedValue();
+ scope.result = result.asReturnedValue();
}
-QV4::ReturnedValue QQmlLocaleData::method_get_uiLanguages(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
QStringList langs = locale->uiLanguages();
- QV4::ScopedArrayObject result(scope, ctx->d()->engine->newArrayObject());
+ QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject());
result->arrayReserve(langs.size());
QV4::ScopedValue v(scope);
for (int i = 0; i < langs.size(); ++i)
- result->arrayPut(i, (v = ctx->d()->engine->newString(langs.at(i))));
+ result->arrayPut(i, (v = scope.engine->newString(langs.at(i))));
result->setArrayLengthUnchecked(langs.size());
- return result.asReturnedValue();
+ scope.result = result.asReturnedValue();
}
-QV4::ReturnedValue QQmlLocaleData::method_currencySymbol(QV4::CallContext *ctx)
+void QQmlLocaleData::method_currencySymbol(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
- if (ctx->argc() > 1)
- V4THROW_ERROR("Locale: currencySymbol(): Invalid arguments");
+ if (callData->argc > 1)
+ THROW_ERROR("Locale: currencySymbol(): Invalid arguments");
QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol;
- if (ctx->argc() == 1) {
- quint32 intFormat = ctx->args()[0].toNumber();
+ if (callData->argc == 1) {
+ quint32 intFormat = callData->args[0].toNumber();
format = QLocale::CurrencySymbolFormat(intFormat);
}
- return ctx->d()->engine->newString(locale->currencySymbol(format))->asReturnedValue();
+ scope.result = scope.engine->newString(locale->currencySymbol(format));
}
#define LOCALE_FORMAT(FUNC) \
-QV4::ReturnedValue QQmlLocaleData::method_ ##FUNC (QV4::CallContext *ctx) { \
- QLocale *locale = getThisLocale(ctx); \
+void QQmlLocaleData::method_ ##FUNC (const BuiltinFunction *, Scope &scope, CallData *callData) { \
+ QLocale *locale = getThisLocale(scope, callData); \
if (!locale) \
- return QV4::Encode::undefined(); \
- if (ctx->argc() > 1) \
- V4THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
+ return; \
+ if (callData->argc > 1) \
+ THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
QLocale::FormatType format = QLocale::LongFormat;\
- if (ctx->argc() == 1) { \
- quint32 intFormat = ctx->args()[0].toUInt32(); \
+ if (callData->argc == 1) { \
+ quint32 intFormat = callData->args[0].toUInt32(); \
format = QLocale::FormatType(intFormat); \
} \
- return ctx->engine()->newString(locale-> FUNC (format))->asReturnedValue(); \
+ scope.result = scope.engine->newString(locale-> FUNC (format)); \
}
LOCALE_FORMAT(dateTimeFormat)
@@ -576,57 +579,57 @@ LOCALE_FORMAT(dateFormat)
// +1 added to idx because JS is 0-based, whereas QLocale months begin at 1.
#define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \
-QV4::ReturnedValue QQmlLocaleData::method_ ## VARIABLE (QV4::CallContext *ctx) {\
- QLocale *locale = getThisLocale(ctx); \
+void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\
+ QLocale *locale = getThisLocale(scope, callData); \
if (!locale) \
- return QV4::Encode::undefined(); \
- if (ctx->argc() < 1 || ctx->argc() > 2) \
- V4THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
+ return; \
+ if (callData->argc < 1 || callData->argc > 2) \
+ THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
QLocale::FormatType enumFormat = QLocale::LongFormat; \
- int idx = ctx->args()[0].toInt32() + 1; \
+ int idx = callData->args[0].toInt32() + 1; \
if (idx < 1 || idx > 12) \
- V4THROW_ERROR("Locale: Invalid month"); \
+ THROW_ERROR("Locale: Invalid month"); \
QString name; \
- if (ctx->argc() == 2) { \
- if (ctx->args()[1].isNumber()) { \
- quint32 intFormat = ctx->args()[1].toUInt32(); \
+ if (callData->argc == 2) { \
+ if (callData->args[1].isNumber()) { \
+ quint32 intFormat = callData->args[1].toUInt32(); \
QLocale::FormatType format = QLocale::FormatType(intFormat); \
name = locale-> VARIABLE(idx, format); \
} else { \
- V4THROW_ERROR("Locale: Invalid datetime format"); \
+ THROW_ERROR("Locale: Invalid datetime format"); \
} \
} else { \
name = locale-> VARIABLE(idx, enumFormat); \
} \
- return ctx->engine()->newString(name)->asReturnedValue(); \
+ scope.result = scope.engine->newString(name); \
}
// 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date
#define LOCALE_FORMATTED_DAYNAME(VARIABLE) \
-QV4::ReturnedValue QQmlLocaleData::method_ ## VARIABLE (QV4::CallContext *ctx) {\
- QLocale *locale = getThisLocale(ctx); \
+void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\
+ QLocale *locale = getThisLocale(scope, callData); \
if (!locale) \
- return QV4::Encode::undefined(); \
- if (ctx->argc() < 1 || ctx->argc() > 2) \
- V4THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
+ return; \
+ if (callData->argc < 1 || callData->argc > 2) \
+ THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
QLocale::FormatType enumFormat = QLocale::LongFormat; \
- int idx = ctx->args()[0].toInt32(); \
+ int idx = callData->args[0].toInt32(); \
if (idx < 0 || idx > 7) \
- V4THROW_ERROR("Locale: Invalid day"); \
+ THROW_ERROR("Locale: Invalid day"); \
if (idx == 0) idx = 7; \
QString name; \
- if (ctx->argc() == 2) { \
- if (ctx->args()[1].isNumber()) { \
- quint32 intFormat = ctx->args()[1].toUInt32(); \
+ if (callData->argc == 2) { \
+ if (callData->args[1].isNumber()) { \
+ quint32 intFormat = callData->args[1].toUInt32(); \
QLocale::FormatType format = QLocale::FormatType(intFormat); \
name = locale-> VARIABLE(idx, format); \
} else { \
- V4THROW_ERROR("Locale: Invalid datetime format"); \
+ THROW_ERROR("Locale: Invalid datetime format"); \
} \
} else { \
name = locale-> VARIABLE(idx, enumFormat); \
} \
- return ctx->engine()->newString(name)->asReturnedValue(); \
+ scope.result = scope.engine->newString(name); \
}
LOCALE_FORMATTED_MONTHNAME(monthName)
@@ -634,12 +637,12 @@ LOCALE_FORMATTED_MONTHNAME(standaloneMonthName)
LOCALE_FORMATTED_DAYNAME(dayName)
LOCALE_FORMATTED_DAYNAME(standaloneDayName)
-#define LOCALE_STRING_PROPERTY(VARIABLE) QV4::ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (QV4::CallContext* ctx) \
+#define LOCALE_STRING_PROPERTY(VARIABLE) void QQmlLocaleData::method_get_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) \
{ \
- QLocale *locale = getThisLocale(ctx); \
+ QLocale *locale = getThisLocale(scope, callData); \
if (!locale) \
- return QV4::Encode::undefined(); \
- return ctx->engine()->newString(locale-> VARIABLE())->asReturnedValue();\
+ return; \
+ scope.result = scope.engine->newString(locale-> VARIABLE());\
}
LOCALE_STRING_PROPERTY(name)
@@ -830,18 +833,22 @@ void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine)
engine->stringPrototype()->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare);
}
-QV4::ReturnedValue QQmlLocale::method_localeCompare(QV4::CallContext *ctx)
+void QQmlLocale::method_localeCompare(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1 || (!ctx->args()[0].isString() && !ctx->args()[0].as<StringObject>()))
- return QV4::StringPrototype::method_localeCompare(ctx);
+ if (callData->argc != 1 || (!callData->args[0].isString() && !callData->args[0].as<StringObject>())) {
+ QV4::StringPrototype::method_localeCompare(b, scope, callData);
+ return;
+ }
- if (!ctx->thisObject().isString() && !ctx->thisObject().as<StringObject>())
- return QV4::StringPrototype::method_localeCompare(ctx);
+ if (!callData->thisObject.isString() && !callData->thisObject.as<StringObject>()) {
+ QV4::StringPrototype::method_localeCompare(b, scope, callData);
+ return;
+ }
- QString thisString = ctx->thisObject().toQStringNoThrow();
- QString thatString = ctx->args()[0].toQStringNoThrow();
+ QString thisString = callData->thisObject.toQStringNoThrow();
+ QString thatString = callData->args[0].toQStringNoThrow();
- return QV4::Encode(QString::localeAwareCompare(thisString, thatString));
+ scope.result = QV4::Encode(QString::localeAwareCompare(thisString, thatString));
}
/*!
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 275f58db7d..1a2ffc72b0 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -67,13 +67,13 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static QV4::ReturnedValue method_toLocaleString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_toLocaleTimeString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_toLocaleDateString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fromLocaleString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fromLocaleTimeString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fromLocaleDateString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_timeZoneUpdated(QV4::CallContext *ctx);
+ static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_toLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_toLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fromLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fromLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_timeZoneUpdated(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
@@ -83,9 +83,9 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static QV4::ReturnedValue method_toLocaleString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fromLocaleString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_toLocaleCurrencyString(QV4::CallContext *ctx);
+ static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_toLocaleCurrencyString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
@@ -135,7 +135,7 @@ public:
private:
QQmlLocale();
- static QV4::ReturnedValue method_localeCompare(QV4::CallContext *ctx);
+ static void method_localeCompare(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
namespace QV4 {
@@ -158,43 +158,43 @@ struct QQmlLocaleData : public QV4::Object
V4_OBJECT2(QQmlLocaleData, Object)
V4_NEEDS_DESTROY
- static QLocale *getThisLocale(QV4::CallContext *ctx) {
- QV4::Object *o = ctx->thisObject().as<Object>();
+ static QLocale *getThisLocale(QV4::Scope &scope, QV4::CallData *callData) {
+ QV4::Object *o = callData->thisObject.as<Object>();
QQmlLocaleData *thisObject = o ? o->as<QQmlLocaleData>() : 0;
if (!thisObject) {
- ctx->engine()->throwTypeError();
+ scope.engine->throwTypeError();
return 0;
}
return thisObject->d()->locale;
}
- static QV4::ReturnedValue method_currencySymbol(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_dateTimeFormat(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_timeFormat(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_dateFormat(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_monthName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_standaloneMonthName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_dayName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_standaloneDayName(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_firstDayOfWeek(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_measurementSystem(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_textDirection(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_weekDays(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_uiLanguages(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_name(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_nativeLanguageName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_nativeCountryName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_decimalPoint(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_groupSeparator(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_percent(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_zeroDigit(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_negativeSign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_positiveSign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_exponential(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_amText(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_pmText(QV4::CallContext *ctx);
+ static void method_currencySymbol(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_dateTimeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_timeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_dateFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_monthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_standaloneMonthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_dayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_standaloneDayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_firstDayOfWeek(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_measurementSystem(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_textDirection(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_weekDays(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_uiLanguages(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nativeLanguageName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nativeCountryName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_decimalPoint(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_groupSeparator(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_percent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_zeroDigit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_negativeSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_positiveSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_exponential(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_amText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_pmText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
}
diff --git a/src/qml/qml/qqmlloggingcategory.cpp b/src/qml/qml/qqmlloggingcategory.cpp
index 70e59db07b..764b874131 100644
--- a/src/qml/qml/qqmlloggingcategory.cpp
+++ b/src/qml/qml/qqmlloggingcategory.cpp
@@ -112,13 +112,13 @@ void QQmlLoggingCategory::componentComplete()
{
m_initialized = true;
if (m_name.isNull())
- qmlInfo(this) << QLatin1String("Declaring the name of the LoggingCategory is mandatory and cannot be changed later !");
+ qmlWarning(this) << QLatin1String("Declaring the name of the LoggingCategory is mandatory and cannot be changed later !");
}
void QQmlLoggingCategory::setName(const QString &name)
{
if (m_initialized) {
- qmlInfo(this) << QLatin1String("The name of a LoggingCategory cannot be changed after the Item is created");
+ qmlWarning(this) << QLatin1String("The name of a LoggingCategory cannot be changed after the Item is created");
return;
}
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 520c44f4da..bd6b9a1599 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -79,7 +79,7 @@ struct QQmlMetaTypeData
Files urlToNonFileImportType; // For non-file imported composite and composite
// singleton types. This way we can locate any
// of them by url, even if it was registered as
- // a module via qmlRegisterCompositeType.
+ // a module via QQmlPrivate::RegisterCompositeType
typedef QHash<const QMetaObject *, QQmlType *> MetaObjects;
MetaObjects metaObjectToType;
typedef QHash<int, QQmlMetaType::StringConverter> StringConverters;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 2e2a3fb303..85fbd86dc4 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -53,6 +53,8 @@
#include <private/qqmlscriptstring_p.h>
#include <private/qqmlpropertyvalueinterceptor_p.h>
#include <private/qqmlvaluetypeproxybinding_p.h>
+#include <private/qqmldebugconnector_p.h>
+#include <private/qqmldebugserviceinterfaces_p.h>
QT_USE_NAMESPACE
@@ -168,7 +170,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
context = new QQmlContextData;
context->isInternal = true;
- context->imports = compilationUnit->importCache;
+ context->imports = compilationUnit->typeNameCache;
context->initFromTypeCompilationUnit(compilationUnit, subComponentIndex);
context->setParent(parentContext);
@@ -216,6 +218,17 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
phase = ObjectsCreated;
+ if (instance) {
+ if (QQmlEngineDebugService *service
+ = QQmlDebugConnector::service<QQmlEngineDebugService>()) {
+ if (!parentContext->isInternal)
+ parentContext->asQQmlContextPrivate()->instances.append(instance);
+ service->objectCreated(engine, instance);
+ } else if (!parentContext->isInternal && QQmlDebugConnector::service<QV4DebugService>()) {
+ parentContext->asQQmlContextPrivate()->instances.append(instance);
+ }
+ }
+
return instance;
}
@@ -1137,7 +1150,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
if (customParser && obj->flags & QV4::CompiledData::Object::HasCustomParserBindings) {
customParser->engine = QQmlEnginePrivate::get(engine);
- customParser->imports = compilationUnit->importCache;
+ customParser->imports = compilationUnit->typeNameCache;
QList<const QV4::CompiledData::Binding *> bindings;
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
@@ -1257,6 +1270,21 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
return sharedState->rootContext;
}
+void QQmlObjectCreator::cancel(QObject *object)
+{
+ int last = sharedState->allCreatedObjects.count() - 1;
+ int i = last;
+ while (i >= 0) {
+ if (sharedState->allCreatedObjects.at(i) == object) {
+ if (i < last)
+ qSwap(sharedState->allCreatedObjects[i], sharedState->allCreatedObjects[last]);
+ sharedState->allCreatedObjects.pop();
+ break;
+ }
+ --i;
+ }
+}
+
void QQmlObjectCreator::clear()
{
if (phase == Done || phase == Finalizing || phase == Startup)
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index caee7b9d1d..982324be3c 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -90,6 +90,7 @@ public:
QObject *create(int subComponentIndex = -1, QObject *parent = 0, QQmlInstantiationInterrupt *interrupt = 0);
bool populateDeferredProperties(QObject *instance);
QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
+ void cancel(QObject *object);
void clear();
QQmlComponentAttached **componentAttachment() const { return &sharedState->componentAttached; }
diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp
index a47a0ab4a4..64ca208f1b 100644
--- a/src/qml/qml/qqmlplatform.cpp
+++ b/src/qml/qml/qqmlplatform.cpp
@@ -59,16 +59,12 @@ QString QQmlPlatform::os()
{
#if defined(Q_OS_ANDROID)
return QStringLiteral("android");
-#elif defined(Q_OS_BLACKBERRY)
- return QStringLiteral("blackberry");
#elif defined(Q_OS_IOS)
return QStringLiteral("ios");
#elif defined(Q_OS_TVOS)
return QStringLiteral("tvos");
#elif defined(Q_OS_MAC)
return QStringLiteral("osx");
-#elif defined(Q_OS_WINPHONE)
- return QStringLiteral("winphone");
#elif defined(Q_OS_WINRT)
return QStringLiteral("winrt");
#elif defined(Q_OS_WIN)
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 76ac15e2f1..13ad02f7cb 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2127,11 +2127,11 @@ bool QQmlTypeData::tryLoadFromDiskCache()
return true;
}
-void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &importCache,
+void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache)
{
Q_ASSERT(m_compiledData);
- m_compiledData->importCache = importCache;
+ m_compiledData->typeNameCache = typeNameCache;
m_compiledData->resolvedTypes = resolvedTypeCache;
QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine());
@@ -2217,10 +2217,10 @@ void QQmlTypeData::done()
}
}
- QQmlRefPointer<QQmlTypeNameCache> importCache;
+ QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
QV4::CompiledData::ResolvedTypeReferenceMap resolvedTypeCache;
{
- QQmlCompileError error = buildTypeResolutionCaches(&importCache, &resolvedTypeCache);
+ QQmlCompileError error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache);
if (error.isSet()) {
setError(error);
return;
@@ -2240,9 +2240,9 @@ void QQmlTypeData::done()
if (!m_document.isNull()) {
// Compile component
- compile(importCache, resolvedTypeCache);
+ compile(typeNameCache, resolvedTypeCache);
} else {
- createTypeAndPropertyCaches(importCache, resolvedTypeCache);
+ createTypeAndPropertyCaches(typeNameCache, resolvedTypeCache);
}
if (isError())
@@ -2303,7 +2303,7 @@ void QQmlTypeData::done()
qualifier = qualifier.mid(lastDotIndex+1);
}
- m_compiledData->importCache->add(qualifier.toString(), scriptIndex, enclosingNamespace);
+ m_compiledData->typeNameCache->add(qualifier.toString(), scriptIndex, enclosingNamespace);
QQmlScriptData *scriptData = script.script->scriptData();
scriptData->addref();
m_compiledData->dependentScripts << scriptData;
@@ -2428,7 +2428,7 @@ void QQmlTypeData::continueLoadFromIR()
QList<QQmlError> errors;
- foreach (const QV4::CompiledData::Import *import, m_document->imports) {
+ for (const QV4::CompiledData::Import *import : qAsConst(m_document->imports)) {
if (!addImport(import, &errors)) {
Q_ASSERT(errors.size());
QQmlError error(errors.takeFirst());
@@ -2489,12 +2489,12 @@ QString QQmlTypeData::stringAt(int index) const
return m_document->jsGenerator.stringTable.stringForIndex(index);
}
-void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &importCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache)
+void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache)
{
Q_ASSERT(m_compiledData.isNull());
QQmlEnginePrivate * const enginePrivate = QQmlEnginePrivate::get(typeLoader()->engine());
- QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), importCache, resolvedTypeCache);
+ QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), typeNameCache, resolvedTypeCache);
m_compiledData = compiler.compile();
if (!m_compiledData) {
setError(compiler.compilationErrors());
@@ -2575,50 +2575,11 @@ void QQmlTypeData::resolveTypes()
int majorVersion = -1;
int minorVersion = -1;
- QQmlImportNamespace *typeNamespace = 0;
- QList<QQmlError> errors;
const QString name = stringAt(unresolvedRef.key());
- bool typeFound = m_importCache.resolveType(name, &ref.type,
- &majorVersion, &minorVersion, &typeNamespace, &errors);
- if (!typeNamespace && !typeFound && !m_implicitImportLoaded) {
- // Lazy loading of implicit import
- if (loadImplicitImport()) {
- // Try again to find the type
- errors.clear();
- typeFound = m_importCache.resolveType(name, &ref.type,
- &majorVersion, &minorVersion, &typeNamespace, &errors);
- } else {
- return; //loadImplicitImport() hit an error, and called setError already
- }
- }
-
- if ((!typeFound || typeNamespace) && reportErrors) {
- // Known to not be a type:
- // - known to be a namespace (Namespace {})
- // - type with unknown namespace (UnknownNamespace.SomeType {})
- QQmlError error;
- if (typeNamespace) {
- error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(name));
- } else {
- if (errors.size()) {
- error = errors.takeFirst();
- } else {
- // this should not be possible!
- // Description should come from error provided by addImport() function.
- error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database"));
- }
- error.setUrl(m_importCache.baseUrl());
- error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(name).arg(error.description()));
- }
- error.setLine(unresolvedRef->location.line);
- error.setColumn(unresolvedRef->location.column);
-
- errors.prepend(error);
- setError(errors);
+ if (!resolveType(name, majorVersion, minorVersion, ref, unresolvedRef->location.line, unresolvedRef->location.column, reportErrors) && reportErrors)
return;
- }
if (ref.type && ref.type->isComposite()) {
ref.typeData = typeLoader()->getType(ref.type->sourceUrl());
@@ -2637,20 +2598,20 @@ void QQmlTypeData::resolveTypes()
}
QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
- QQmlRefPointer<QQmlTypeNameCache> *importCache,
+ QQmlRefPointer<QQmlTypeNameCache> *typeNameCache,
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache
) const
{
- importCache->adopt(new QQmlTypeNameCache);
+ typeNameCache->adopt(new QQmlTypeNameCache);
for (const QString &ns: m_namespaces)
- (*importCache)->add(ns);
+ (*typeNameCache)->add(ns);
// Add any Composite Singletons that were used to the import cache
for (const QQmlTypeData::TypeReference &singleton: m_compositeSingletons)
- (*importCache)->add(singleton.type->qmlTypeName(), singleton.type->sourceUrl(), singleton.prefix);
+ (*typeNameCache)->add(singleton.type->qmlTypeName(), singleton.type->sourceUrl(), singleton.prefix);
- m_importCache.populateCache(*importCache);
+ m_importCache.populateCache(*typeNameCache);
QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine());
@@ -2687,7 +2648,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
return noError;
}
-bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref)
+bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref, int lineNumber, int columnNumber, bool reportErrors)
{
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
@@ -2706,7 +2667,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &
}
}
- if (!typeFound || typeNamespace) {
+ if ((!typeFound || typeNamespace) && reportErrors) {
// Known to not be a type:
// - known to be a namespace (Namespace {})
// - type with unknown namespace (UnknownNamespace.SomeType {})
@@ -2725,6 +2686,11 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &
error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(typeName).arg(error.description()));
}
+ if (lineNumber != -1)
+ error.setLine(lineNumber);
+ if (columnNumber != -1)
+ error.setColumn(columnNumber);
+
errors.prepend(error);
setError(errors);
return false;
@@ -2744,7 +2710,7 @@ void QQmlTypeData::scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData:
}
QQmlScriptData::QQmlScriptData()
- : importCache(0)
+ : typeNameCache(0)
, m_loaded(false)
, m_program(0)
{
@@ -2801,8 +2767,8 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent
// For backward compatibility, if there are no imports, we need to use the
// imports from the parent context. See QTBUG-17518.
- if (!importCache->isEmpty()) {
- ctxt->imports = importCache;
+ if (!typeNameCache->isEmpty()) {
+ ctxt->imports = typeNameCache;
} else if (effectiveCtxt) {
ctxt->imports = effectiveCtxt->imports;
ctxt->importedScripts = effectiveCtxt->importedScripts;
@@ -2857,9 +2823,9 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent
void QQmlScriptData::clear()
{
- if (importCache) {
- importCache->release();
- importCache = 0;
+ if (typeNameCache) {
+ typeNameCache->release();
+ typeNameCache = 0;
}
for (int ii = 0; ii < scripts.count(); ++ii)
@@ -2980,7 +2946,7 @@ void QQmlScriptBlob::done()
}
}
- m_scriptData->importCache = new QQmlTypeNameCache();
+ m_scriptData->typeNameCache = new QQmlTypeNameCache();
QSet<QString> ns;
@@ -2992,13 +2958,13 @@ void QQmlScriptBlob::done()
if (!script.nameSpace.isNull()) {
if (!ns.contains(script.nameSpace)) {
ns.insert(script.nameSpace);
- m_scriptData->importCache->add(script.nameSpace);
+ m_scriptData->typeNameCache->add(script.nameSpace);
}
}
- m_scriptData->importCache->add(script.qualifier, scriptIndex, script.nameSpace);
+ m_scriptData->typeNameCache->add(script.qualifier, scriptIndex, script.nameSpace);
}
- m_importCache.populateCache(m_scriptData->importCache);
+ m_importCache.populateCache(m_scriptData->typeNameCache);
}
QString QQmlScriptBlob::stringAt(int index) const
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index b1d6451974..14141db180 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -449,14 +449,14 @@ private:
void continueLoadFromIR();
void resolveTypes();
QQmlCompileError buildTypeResolutionCaches(
- QQmlRefPointer<QQmlTypeNameCache> *importCache,
+ QQmlRefPointer<QQmlTypeNameCache> *typeNameCache,
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache
) const;
- void compile(const QQmlRefPointer<QQmlTypeNameCache> &importCache,
+ void compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
- void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &importCache,
+ void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
- bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref);
+ bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref, int lineNumber = -1, int columnNumber = -1, bool reportErrors = true);
void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override;
@@ -504,7 +504,7 @@ public:
QUrl url;
QString urlString;
- QQmlTypeNameCache *importCache;
+ QQmlTypeNameCache *typeNameCache;
QList<QQmlScriptBlob *> scripts;
QV4::ReturnedValue scriptValueForContext(QQmlContextData *parentCtxt);
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 6ce52bb9e5..44b612e7d2 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -312,18 +312,18 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
return true;
}
-ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx)
+void QQmlValueTypeWrapper::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Object *o = ctx->thisObject().as<Object>();
+ Object *o = callData->thisObject.as<Object>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QQmlValueTypeWrapper *w = o->as<QQmlValueTypeWrapper>();
if (!w)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (QQmlValueTypeReference *ref = w->as<QQmlValueTypeReference>())
if (!ref->readReferenceValue())
- return Encode::undefined();
+ RETURN_UNDEFINED();
QString result;
// Prepare a buffer to pass to QMetaType::convert()
@@ -346,7 +346,7 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx)
}
result += QLatin1Char(')');
}
- return Encode(ctx->engine()->newString(result));
+ scope.result = scope.engine->newString(result);
}
ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *hasProperty)
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index fec54df770..87f9116056 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -111,7 +111,7 @@ public:
static PropertyAttributes query(const Managed *, String *name);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static QV4::ReturnedValue method_toString(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
static void initProto(ExecutionEngine *v4);
};
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 72d4ab7e8f..c60f4edc80 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -120,6 +120,18 @@ void QQmlVMEGuard::guard(QQmlObjectCreator *creator)
m_contexts[0] = creator->parentContextData();
}
+void QQmlVMEGuard::unguard(QObject *object)
+{
+ for (int ii = 0; ii < m_objectCount; ++ii) {
+ if (m_objects[ii] == object) {
+ if (ii < m_objectCount - 1)
+ ::memmove((void *) m_objects[ii], (void *) m_objects[ii + 1], sizeof(QPointer<QObject> *));
+ delete m_objects[--m_objectCount];
+ break;
+ }
+ }
+}
+
void QQmlVMEGuard::clear()
{
delete [] m_objects;
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index 99d63380ad..9585b5b6df 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -131,6 +131,7 @@ public:
~QQmlVMEGuard();
void guard(QQmlObjectCreator *);
+ void unguard(QObject *);
void clear();
bool isOK() const;
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 545daa96f8..490a4e19ab 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -325,9 +325,12 @@ QQmlVMEMetaObject::QQmlVMEMetaObject(QObject *obj,
if (compiledObject->nProperties || compiledObject->nFunctions) {
Q_ASSERT(cache && cache->engine);
QV4::ExecutionEngine *v4 = cache->engine;
- QV4::Heap::MemberData *data = QV4::MemberData::allocate(v4, compiledObject->nProperties + compiledObject->nFunctions);
- propertyAndMethodStorage.set(v4, data);
- std::fill(data->data, data->data + data->size, QV4::Encode::undefined());
+ uint size = compiledObject->nProperties + compiledObject->nFunctions;
+ if (size) {
+ QV4::Heap::MemberData *data = QV4::MemberData::allocate(v4, size);
+ propertyAndMethodStorage.set(v4, data);
+ std::fill(data->data, data->data + data->size, QV4::Encode::undefined());
+ }
// Need JS wrapper to ensure properties/methods are marked.
ensureQObjectWrapper();
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 22c3c49c58..d0d9f080da 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -71,10 +71,12 @@ using namespace QV4;
#if QT_CONFIG(xmlstreamreader) && QT_CONFIG(qml_network)
-#define V4THROW_REFERENCE(string) { \
- ScopedObject error(scope, ctx->engine()->newReferenceErrorObject(QStringLiteral(string))); \
- return ctx->engine()->throwError(error); \
- }
+#define V4THROW_REFERENCE(string) \
+ do { \
+ ScopedObject error(scope, scope.engine->newReferenceErrorObject(QStringLiteral(string))); \
+ scope.result = scope.engine->throwError(error); \
+ return; \
+ } while (false)
QT_BEGIN_NAMESPACE
@@ -274,25 +276,25 @@ public:
static void initClass(ExecutionEngine *engine);
// JS API
- static ReturnedValue method_get_nodeName(CallContext *ctx);
- static ReturnedValue method_get_nodeValue(CallContext *ctx);
- static ReturnedValue method_get_nodeType(CallContext *ctx);
- static ReturnedValue method_get_namespaceUri(CallContext *ctx);
-
- static ReturnedValue method_get_parentNode(CallContext *ctx);
- static ReturnedValue method_get_childNodes(CallContext *ctx);
- static ReturnedValue method_get_firstChild(CallContext *ctx);
- static ReturnedValue method_get_lastChild(CallContext *ctx);
- static ReturnedValue method_get_previousSibling(CallContext *ctx);
- static ReturnedValue method_get_nextSibling(CallContext *ctx);
- static ReturnedValue method_get_attributes(CallContext *ctx);
-
- //static ReturnedValue ownerDocument(CallContext *ctx);
- //static ReturnedValue namespaceURI(CallContext *ctx);
- //static ReturnedValue prefix(CallContext *ctx);
- //static ReturnedValue localName(CallContext *ctx);
- //static ReturnedValue baseURI(CallContext *ctx);
- //static ReturnedValue textContent(CallContext *ctx);
+ static void method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ //static void ownerDocument(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void namespaceURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void prefix(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void localName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void baseURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void textContent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static ReturnedValue getProto(ExecutionEngine *v4);
@@ -353,12 +355,12 @@ class Attr : public Node
{
public:
// JS API
- static ReturnedValue method_name(CallContext *ctx);
-// static ReturnedValue specified(CallContext *);
- static ReturnedValue method_value(CallContext *ctx);
- static ReturnedValue method_ownerElement(CallContext *ctx);
-// static ReturnedValue schemaTypeInfo(CallContext *);
-// static ReturnedValue isId(CallContext *c);
+ static void method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+// static void specified(CallContext *);
+ static void method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+// static void schemaTypeInfo(CallContext *);
+// static void isId(CallContext *c);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -368,7 +370,7 @@ class CharacterData : public Node
{
public:
// JS API
- static ReturnedValue method_length(CallContext *ctx);
+ static void method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
// C++ API
static ReturnedValue prototype(ExecutionEngine *v4);
@@ -378,8 +380,8 @@ class Text : public CharacterData
{
public:
// JS API
- static ReturnedValue method_isElementContentWhitespace(CallContext *ctx);
- static ReturnedValue method_wholeText(CallContext *ctx);
+ static void method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -396,10 +398,10 @@ class Document : public Node
{
public:
// JS API
- static ReturnedValue method_xmlVersion(CallContext *ctx);
- static ReturnedValue method_xmlEncoding(CallContext *ctx);
- static ReturnedValue method_xmlStandalone(CallContext *ctx);
- static ReturnedValue method_documentElement(CallContext *ctx);
+ static void method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -418,12 +420,11 @@ void NodeImpl::release()
document->release();
}
-ReturnedValue NodePrototype::method_get_nodeName(CallContext *ctx)
+void NodePrototype::method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QString name;
switch (r->d()->d->type) {
@@ -440,15 +441,14 @@ ReturnedValue NodePrototype::method_get_nodeName(CallContext *ctx)
name = r->d()->d->name;
break;
}
- return Encode(ctx->d()->engine->newString(name));
+ scope.result = Encode(scope.engine->newString(name));
}
-ReturnedValue NodePrototype::method_get_nodeValue(CallContext *ctx)
+void NodePrototype::method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->type == NodeImpl::Document ||
r->d()->d->type == NodeImpl::DocumentFragment ||
@@ -457,135 +457,128 @@ ReturnedValue NodePrototype::method_get_nodeValue(CallContext *ctx)
r->d()->d->type == NodeImpl::Entity ||
r->d()->d->type == NodeImpl::EntityReference ||
r->d()->d->type == NodeImpl::Notation)
- return Encode::null();
+ RETURN_RESULT(Encode::null());
- return Encode(ctx->d()->engine->newString(r->d()->d->data));
+ scope.result = Encode(scope.engine->newString(r->d()->d->data));
}
-ReturnedValue NodePrototype::method_get_nodeType(CallContext *ctx)
+void NodePrototype::method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(r->d()->d->type);
+ scope.result = Encode(r->d()->d->type);
}
-ReturnedValue NodePrototype::method_get_namespaceUri(CallContext *ctx)
+void NodePrototype::method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(ctx->d()->engine->newString(r->d()->d->namespaceUri));
+ scope.result = Encode(scope.engine->newString(r->d()->d->namespaceUri));
}
-ReturnedValue NodePrototype::method_get_parentNode(CallContext *ctx)
+void NodePrototype::method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->parent)
- return Node::create(scope.engine, r->d()->d->parent);
+ scope.result = Node::create(scope.engine, r->d()->d->parent);
else
- return Encode::null();
+ scope.result = Encode::null();
}
-ReturnedValue NodePrototype::method_get_childNodes(CallContext *ctx)
+void NodePrototype::method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return NodeList::create(scope.engine, r->d()->d);
+ scope.result = NodeList::create(scope.engine, r->d()->d);
}
-ReturnedValue NodePrototype::method_get_firstChild(CallContext *ctx)
+void NodePrototype::method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->children.isEmpty())
- return Encode::null();
+ scope.result = Encode::null();
else
- return Node::create(scope.engine, r->d()->d->children.constFirst());
+ scope.result = Node::create(scope.engine, r->d()->d->children.constFirst());
}
-ReturnedValue NodePrototype::method_get_lastChild(CallContext *ctx)
+void NodePrototype::method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->children.isEmpty())
- return Encode::null();
+ scope.result = Encode::null();
else
- return Node::create(scope.engine, r->d()->d->children.constLast());
+ scope.result = Node::create(scope.engine, r->d()->d->children.constLast());
}
-ReturnedValue NodePrototype::method_get_previousSibling(CallContext *ctx)
+void NodePrototype::method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!r->d()->d->parent)
- return Encode::null();
+ RETURN_RESULT(Encode::null());
for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
if (ii == 0)
- return Encode::null();
+ scope.result = Encode::null();
else
- return Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1));
+ scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1));
+ return;
}
}
- return Encode::null();
+ scope.result = Encode::null();
}
-ReturnedValue NodePrototype::method_get_nextSibling(CallContext *ctx)
+void NodePrototype::method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!r->d()->d->parent)
- return Encode::null();
+ RETURN_RESULT(Encode::null());
for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
if ((ii + 1) == r->d()->d->parent->children.count())
- return Encode::null();
+ scope.result = Encode::null();
else
- return Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
+ scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
+ return;
}
}
- return Encode::null();
+ scope.result = Encode::null();
}
-ReturnedValue NodePrototype::method_get_attributes(CallContext *ctx)
+void NodePrototype::method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->type != NodeImpl::Element)
- return Encode::null();
+ scope.result = Encode::null();
else
- return NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes);
+ scope.result = NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes);
}
ReturnedValue NodePrototype::getProto(ExecutionEngine *v4)
@@ -666,44 +659,40 @@ ReturnedValue Attr::prototype(ExecutionEngine *engine)
return d->attrPrototype.value();
}
-ReturnedValue Attr::method_name(CallContext *ctx)
+void Attr::method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(r->d()->d->name));
+ scope.result = scope.engine->newString(r->d()->d->name);
}
-ReturnedValue Attr::method_value(CallContext *ctx)
+void Attr::method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(r->d()->d->data));
+ scope.result = scope.engine->newString(r->d()->d->data);
}
-ReturnedValue Attr::method_ownerElement(CallContext *ctx)
+void Attr::method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return Node::create(scope.engine, r->d()->d->parent);
+ scope.result = Node::create(scope.engine, r->d()->d->parent);
}
-ReturnedValue CharacterData::method_length(CallContext *ctx)
+void CharacterData::method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return Encode(r->d()->d->data.length());
+ scope.result = Encode(r->d()->d->data.length());
}
ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
@@ -722,23 +711,22 @@ ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
return d->characterDataPrototype.value();
}
-ReturnedValue Text::method_isElementContentWhitespace(CallContext *ctx)
+void Text::method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
- if (!r) return Encode::undefined();
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ if (!r)
+ RETURN_UNDEFINED();
- return Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty());
+ scope.result = Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty());
}
-ReturnedValue Text::method_wholeText(CallContext *ctx)
+void Text::method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(r->d()->d->data));
+ scope.result = scope.engine->newString(r->d()->d->data);
}
ReturnedValue Text::prototype(ExecutionEngine *v4)
@@ -964,44 +952,40 @@ ReturnedValue NodeList::create(ExecutionEngine *v4, NodeImpl *data)
return (v4->memoryManager->allocObject<NodeList>(data))->asReturnedValue();
}
-ReturnedValue Document::method_documentElement(CallContext *ctx)
+void Document::method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root);
+ scope.result = Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root);
}
-ReturnedValue Document::method_xmlStandalone(CallContext *ctx)
+void Document::method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone);
+ scope.result = Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone);
}
-ReturnedValue Document::method_xmlVersion(CallContext *ctx)
+void Document::method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version));
+ scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version);
}
-ReturnedValue Document::method_xmlEncoding(CallContext *ctx)
+void Document::method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding));
+ scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding);
}
class QQmlXMLHttpRequest : public QObject
@@ -1657,21 +1641,21 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
void setupProto();
- static ReturnedValue method_open(CallContext *ctx);
- static ReturnedValue method_setRequestHeader(CallContext *ctx);
- static ReturnedValue method_send(CallContext *ctx);
- static ReturnedValue method_abort(CallContext *ctx);
- static ReturnedValue method_getResponseHeader(CallContext *ctx);
- static ReturnedValue method_getAllResponseHeaders(CallContext *ctx);
-
- static ReturnedValue method_get_readyState(CallContext *ctx);
- static ReturnedValue method_get_status(CallContext *ctx);
- static ReturnedValue method_get_statusText(CallContext *ctx);
- static ReturnedValue method_get_responseText(CallContext *ctx);
- static ReturnedValue method_get_responseXML(CallContext *ctx);
- static ReturnedValue method_get_response(CallContext *ctx);
- static ReturnedValue method_get_responseType(CallContext *ctx);
- static ReturnedValue method_set_responseType(CallContext *ctx);
+ static void method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
}
@@ -1733,19 +1717,18 @@ void QQmlXMLHttpRequestCtor::setupProto()
// XMLHttpRequest methods
-ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() < 2 || ctx->argc() > 5)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc < 2 || callData->argc > 5)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
// Argument 0 - Method
- QString method = ctx->args()[0].toQStringNoThrow().toUpper();
+ QString method = callData->args[0].toQStringNoThrow().toUpper();
if (method != QLatin1String("GET") &&
method != QLatin1String("PUT") &&
method != QLatin1String("HEAD") &&
@@ -1754,26 +1737,26 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx)
method != QLatin1String("OPTIONS") &&
method != QLatin1String("PROPFIND") &&
method != QLatin1String("PATCH"))
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type");
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type");
// Argument 1 - URL
- QUrl url = QUrl(ctx->args()[1].toQStringNoThrow());
+ QUrl url = QUrl(callData->args[1].toQStringNoThrow());
if (url.isRelative())
url = scope.engine->callingQmlContext()->resolvedUrl(url);
bool async = true;
// Argument 2 - async (optional)
- if (ctx->argc() > 2) {
- async = ctx->args()[2].booleanValue();
+ if (callData->argc > 2) {
+ async = callData->args[2].booleanValue();
}
// Argument 3/4 - user/pass (optional)
QString username, password;
- if (ctx->argc() > 3)
- username = ctx->args()[3].toQStringNoThrow();
- if (ctx->argc() > 4)
- password = ctx->args()[4].toQStringNoThrow();
+ if (callData->argc > 3)
+ username = callData->args[3].toQStringNoThrow();
+ if (callData->argc > 4)
+ password = callData->args[4].toQStringNoThrow();
// Clear the fragment (if any)
url.setFragment(QString());
@@ -1782,25 +1765,24 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx)
if (!username.isNull()) url.setUserName(username);
if (!password.isNull()) url.setPassword(password);
- return r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad);
+ scope.result = r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad);
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() != 2)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc != 2)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Opened || r->sendFlag())
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- QString name = ctx->args()[0].toQStringNoThrow();
- QString value = ctx->args()[1].toQStringNoThrow();
+ QString name = callData->args[0].toQStringNoThrow();
+ QString value = callData->args[1].toQStringNoThrow();
// ### Check that name and value are well formed
@@ -1825,148 +1807,139 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(CallContext *ctx)
nameUpper == QLatin1String("VIA") ||
nameUpper.startsWith(QLatin1String("PROXY-")) ||
nameUpper.startsWith(QLatin1String("SEC-")))
- return Encode::undefined();
+ RETURN_UNDEFINED();
r->addHeader(name, value);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_send(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() != QQmlXMLHttpRequest::Opened ||
r->sendFlag())
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
QByteArray data;
- if (ctx->argc() > 0)
- data = ctx->args()[0].toQStringNoThrow().toUtf8();
+ if (callData->argc > 0)
+ data = callData->args[0].toQStringNoThrow().toUtf8();
- return r->send(w, scope.engine->callingQmlContext(), data);
+ scope.result = r->send(w, scope.engine->callingQmlContext(), data);
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_abort(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- return r->abort(w, scope.engine->callingQmlContext());
+ scope.result = r->abort(w, scope.engine->callingQmlContext());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() != 1)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc != 1)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done &&
r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- return QV4::Encode(scope.engine->newString(r->header(ctx->args()[0].toQStringNoThrow())));
+ scope.result = scope.engine->newString(r->header(callData->args[0].toQStringNoThrow()));
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() != 0)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc != 0)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done &&
r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- return QV4::Encode(scope.engine->newString(r->headers()));
+ scope.result = scope.engine->newString(r->headers());
}
// XMLHttpRequest properties
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- return Encode(r->readyState());
+ scope.result = Encode(r->readyState());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() == QQmlXMLHttpRequest::Unsent ||
r->readyState() == QQmlXMLHttpRequest::Opened)
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
if (r->errorFlag())
- return Encode(0);
+ scope.result = Encode(0);
else
- return Encode(r->replyStatus());
+ scope.result = Encode(r->replyStatus());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() == QQmlXMLHttpRequest::Unsent ||
r->readyState() == QQmlXMLHttpRequest::Opened)
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
if (r->errorFlag())
- return QV4::Encode(scope.engine->newString(QString()));
+ scope.result = scope.engine->newString(QString());
else
- return QV4::Encode(scope.engine->newString(r->replyStatusText()));
+ scope.result = scope.engine->newString(r->replyStatusText());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)
- return QV4::Encode(scope.engine->newString(QString()));
+ scope.result = scope.engine->newString(QString());
else
- return QV4::Encode(scope.engine->newString(r->responseBody()));
+ scope.result = scope.engine->newString(r->responseBody());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1974,66 +1947,63 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(CallContext *ctx)
if (!r->receivedXml() ||
(r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)) {
- return Encode::null();
+ scope.result = Encode::null();
} else {
if (r->responseType().isEmpty())
r->setResponseType(QLatin1String("document"));
- return r->xmlResponseBody(scope.engine);
+ scope.result = r->xmlResponseBody(scope.engine);
}
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)
- return QV4::Encode(scope.engine->newString(QString()));
+ RETURN_RESULT(scope.engine->newString(QString()));
const QString& responseType = r->responseType();
if (responseType.compare(QLatin1String("text"), Qt::CaseInsensitive) == 0 || responseType.isEmpty()) {
- return QV4::Encode(scope.engine->newString(r->responseBody()));
+ RETURN_RESULT(scope.engine->newString(r->responseBody()));
} else if (responseType.compare(QLatin1String("arraybuffer"), Qt::CaseInsensitive) == 0) {
- return QV4::Encode(scope.engine->newArrayBuffer(r->rawResponseBody()));
+ RETURN_RESULT(scope.engine->newArrayBuffer(r->rawResponseBody()));
} else if (responseType.compare(QLatin1String("json"), Qt::CaseInsensitive) == 0) {
- return r->jsonResponseBody(scope.engine);
+ RETURN_RESULT(r->jsonResponseBody(scope.engine));
} else if (responseType.compare(QLatin1String("document"), Qt::CaseInsensitive) == 0) {
- return r->xmlResponseBody(scope.engine);
+ RETURN_RESULT(r->xmlResponseBody(scope.engine));
} else {
- return QV4::Encode(scope.engine->newString(QString()));
+ RETURN_RESULT(scope.engine->newString(QString()));
}
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseType(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- return QV4::Encode(scope.engine->newString(r->responseType()));
+ scope.result = scope.engine->newString(r->responseType());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() < 1)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc < 1)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
// Argument 0 - response type
- r->setResponseType(ctx->args()[0].toQStringNoThrow());
+ r->setResponseType(callData->args[0].toQStringNoThrow());
- return Encode::undefined();
+ scope.result = Encode::undefined();
}
void qt_rem_qmlxmlhttprequest(ExecutionEngine * /* engine */, void *d)
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 19dc100f40..d359a0f62f 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -85,6 +85,12 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(QtObject);
+#define THROW_TYPE_ERROR_WITH_MESSAGE(msg) \
+ do { \
+ scope.result = scope.engine->throwTypeError(QString::fromUtf8(msg)); \
+ return; \
+ } while (false)
+
struct StaticQtMetaObject : public QObject
{
static const QMetaObject *get()
@@ -223,12 +229,12 @@ void QtObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint
\qmlmethod bool Qt::isQtObject(object)
Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
*/
-ReturnedValue QtObject::method_isQtObject(QV4::CallContext *ctx)
+void QtObject::method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- return QV4::Encode(false);
+ if (callData->argc == 0)
+ RETURN_RESULT(QV4::Encode(false));
- return QV4::Encode(ctx->args()[0].as<QV4::QObjectWrapper>() != 0);
+ scope.result = QV4::Encode(callData->args[0].as<QV4::QObjectWrapper>() != 0);
}
/*!
@@ -237,16 +243,16 @@ ReturnedValue QtObject::method_isQtObject(QV4::CallContext *ctx)
Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx)
+void QtObject::method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- int argCount = ctx->argc();
+ int argCount = callData->argc;
if (argCount < 3 || argCount > 4)
- V4THROW_ERROR("Qt.rgba(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.rgba(): Invalid arguments");
- double r = ctx->args()[0].toNumber();
- double g = ctx->args()[1].toNumber();
- double b = ctx->args()[2].toNumber();
- double a = (argCount == 4) ? ctx->args()[3].toNumber() : 1;
+ double r = callData->args[0].toNumber();
+ double g = callData->args[1].toNumber();
+ double b = callData->args[2].toNumber();
+ double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
if (r < 0.0) r=0.0;
if (r > 1.0) r=1.0;
@@ -257,7 +263,7 @@ ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx)
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return ctx->engine()->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
}
/*!
@@ -266,16 +272,16 @@ ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx)
Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-ReturnedValue QtObject::method_hsla(QV4::CallContext *ctx)
+void QtObject::method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- int argCount = ctx->argc();
+ int argCount = callData->argc;
if (argCount < 3 || argCount > 4)
- V4THROW_ERROR("Qt.hsla(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.hsla(): Invalid arguments");
- double h = ctx->args()[0].toNumber();
- double s = ctx->args()[1].toNumber();
- double l = ctx->args()[2].toNumber();
- double a = (argCount == 4) ? ctx->args()[3].toNumber() : 1;
+ double h = callData->args[0].toNumber();
+ double s = callData->args[1].toNumber();
+ double l = callData->args[2].toNumber();
+ double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
if (h < 0.0) h=0.0;
if (h > 1.0) h=1.0;
@@ -286,7 +292,7 @@ ReturnedValue QtObject::method_hsla(QV4::CallContext *ctx)
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return ctx->engine()->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
}
/*!
@@ -297,23 +303,23 @@ All components should be in the range 0-1 inclusive.
\since 5.5
*/
-ReturnedValue QtObject::method_hsva(QV4::CallContext *ctx)
+void QtObject::method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- int argCount = ctx->argc();
+ int argCount = callData->argc;
if (argCount < 3 || argCount > 4)
- V4THROW_ERROR("Qt.hsva(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.hsva(): Invalid arguments");
- double h = ctx->args()[0].toNumber();
- double s = ctx->args()[1].toNumber();
- double v = ctx->args()[2].toNumber();
- double a = (argCount == 4) ? ctx->args()[3].toNumber() : 1;
+ double h = callData->args[0].toNumber();
+ double s = callData->args[1].toNumber();
+ double v = callData->args[2].toNumber();
+ double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
h = qBound(0.0, h, 1.0);
s = qBound(0.0, s, 1.0);
v = qBound(0.0, v, 1.0);
a = qBound(0.0, a, 1.0);
- return ctx->engine()->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a));
}
/*!
@@ -324,35 +330,35 @@ may be either color values or string values. If a string value is supplied it
must be convertible to a color, as described for the \l{colorbasictypedocs}{color}
basic type.
*/
-ReturnedValue QtObject::method_colorEqual(QV4::CallContext *ctx)
+void QtObject::method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
bool ok = false;
- QVariant lhs = ctx->d()->engine->toVariant(ctx->args()[0], -1);
+ QVariant lhs = scope.engine->toVariant(callData->args[0], -1);
if (lhs.userType() == QVariant::String) {
lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok);
if (!ok) {
- V4THROW_ERROR("Qt.colorEqual(): Invalid color name");
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
}
} else if (lhs.userType() != QVariant::Color) {
- V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
- QVariant rhs = ctx->engine()->toVariant(ctx->args()[1], -1);
+ QVariant rhs = scope.engine->toVariant(callData->args[1], -1);
if (rhs.userType() == QVariant::String) {
rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok);
if (!ok) {
- V4THROW_ERROR("Qt.colorEqual(): Invalid color name");
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
}
} else if (rhs.userType() != QVariant::Color) {
- V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
bool equal = (lhs == rhs);
- return QV4::Encode(equal);
+ scope.result = QV4::Encode(equal);
}
/*!
@@ -362,47 +368,47 @@ Returns a \c rect with the top-left corner at \c x, \c y and the specified \c wi
The returned object has \c x, \c y, \c width and \c height attributes with the given values.
*/
-ReturnedValue QtObject::method_rect(QV4::CallContext *ctx)
+void QtObject::method_rect(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 4)
- V4THROW_ERROR("Qt.rect(): Invalid arguments");
+ if (callData->argc != 4)
+ THROW_GENERIC_ERROR("Qt.rect(): Invalid arguments");
- double x = ctx->args()[0].toNumber();
- double y = ctx->args()[1].toNumber();
- double w = ctx->args()[2].toNumber();
- double h = ctx->args()[3].toNumber();
+ double x = callData->args[0].toNumber();
+ double y = callData->args[1].toNumber();
+ double w = callData->args[2].toNumber();
+ double h = callData->args[3].toNumber();
- return ctx->engine()->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
+ scope.result = scope.engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
}
/*!
\qmlmethod point Qt::point(int x, int y)
Returns a Point with the specified \c x and \c y coordinates.
*/
-ReturnedValue QtObject::method_point(QV4::CallContext *ctx)
+void QtObject::method_point(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.point(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.point(): Invalid arguments");
- double x = ctx->args()[0].toNumber();
- double y = ctx->args()[1].toNumber();
+ double x = callData->args[0].toNumber();
+ double y = callData->args[1].toNumber();
- return ctx->engine()->fromVariant(QVariant::fromValue(QPointF(x, y)));
+ scope.result = scope.engine->fromVariant(QVariant::fromValue(QPointF(x, y)));
}
/*!
\qmlmethod Qt::size(int width, int height)
Returns a Size with the specified \c width and \c height.
*/
-ReturnedValue QtObject::method_size(QV4::CallContext *ctx)
+void QtObject::method_size(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.size(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.size(): Invalid arguments");
- double w = ctx->args()[0].toNumber();
- double h = ctx->args()[1].toNumber();
+ double w = callData->args[0].toNumber();
+ double h = callData->args[1].toNumber();
- return ctx->engine()->fromVariant(QVariant::fromValue(QSizeF(w, h)));
+ scope.result = scope.engine->fromVariant(QVariant::fromValue(QSizeF(w, h)));
}
/*!
@@ -413,17 +419,17 @@ key-value pairs where valid keys are the \l{fontbasictypedocs}{font} type's
subproperty names, and the values are valid values for each subproperty.
Invalid keys will be ignored.
*/
-ReturnedValue QtObject::method_font(QV4::CallContext *ctx)
+void QtObject::method_font(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1 || !ctx->args()[0].isObject())
- V4THROW_ERROR("Qt.font(): Invalid arguments");
+ if (callData->argc != 1 || !callData->args[0].isObject())
+ THROW_GENERIC_ERROR("Qt.font(): Invalid arguments");
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(ctx->args()[0]), v4, &ok);
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(callData->args[0]), v4, &ok);
if (!ok)
- V4THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
- return ctx->engine()->fromVariant(v);
+ THROW_GENERIC_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
+ scope.result = scope.engine->fromVariant(v);
}
@@ -432,73 +438,73 @@ ReturnedValue QtObject::method_font(QV4::CallContext *ctx)
\qmlmethod Qt::vector2d(real x, real y)
Returns a Vector2D with the specified \c x and \c y.
*/
-ReturnedValue QtObject::method_vector2d(QV4::CallContext *ctx)
+void QtObject::method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.vector2d(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.vector2d(): Invalid arguments");
float xy[3]; // qvector2d uses float internally
- xy[0] = ctx->args()[0].toNumber();
- xy[1] = ctx->args()[1].toNumber();
+ xy[0] = callData->args[0].toNumber();
+ xy[1] = callData->args[1].toNumber();
const void *params[] = { xy };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
}
/*!
\qmlmethod Qt::vector3d(real x, real y, real z)
Returns a Vector3D with the specified \c x, \c y and \c z.
*/
-ReturnedValue QtObject::method_vector3d(QV4::CallContext *ctx)
+void QtObject::method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 3)
- V4THROW_ERROR("Qt.vector3d(): Invalid arguments");
+ if (callData->argc != 3)
+ THROW_GENERIC_ERROR("Qt.vector3d(): Invalid arguments");
float xyz[3]; // qvector3d uses float internally
- xyz[0] = ctx->args()[0].toNumber();
- xyz[1] = ctx->args()[1].toNumber();
- xyz[2] = ctx->args()[2].toNumber();
+ xyz[0] = callData->args[0].toNumber();
+ xyz[1] = callData->args[1].toNumber();
+ xyz[2] = callData->args[2].toNumber();
const void *params[] = { xyz };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
}
/*!
\qmlmethod Qt::vector4d(real x, real y, real z, real w)
Returns a Vector4D with the specified \c x, \c y, \c z and \c w.
*/
-ReturnedValue QtObject::method_vector4d(QV4::CallContext *ctx)
+void QtObject::method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 4)
- V4THROW_ERROR("Qt.vector4d(): Invalid arguments");
+ if (callData->argc != 4)
+ THROW_GENERIC_ERROR("Qt.vector4d(): Invalid arguments");
float xyzw[4]; // qvector4d uses float internally
- xyzw[0] = ctx->args()[0].toNumber();
- xyzw[1] = ctx->args()[1].toNumber();
- xyzw[2] = ctx->args()[2].toNumber();
- xyzw[3] = ctx->args()[3].toNumber();
+ xyzw[0] = callData->args[0].toNumber();
+ xyzw[1] = callData->args[1].toNumber();
+ xyzw[2] = callData->args[2].toNumber();
+ xyzw[3] = callData->args[3].toNumber();
const void *params[] = { xyzw };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
}
/*!
\qmlmethod Qt::quaternion(real scalar, real x, real y, real z)
Returns a Quaternion with the specified \c scalar, \c x, \c y, and \c z.
*/
-ReturnedValue QtObject::method_quaternion(QV4::CallContext *ctx)
+void QtObject::method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 4)
- V4THROW_ERROR("Qt.quaternion(): Invalid arguments");
+ if (callData->argc != 4)
+ THROW_GENERIC_ERROR("Qt.quaternion(): Invalid arguments");
qreal sxyz[4]; // qquaternion uses qreal internally
- sxyz[0] = ctx->args()[0].toNumber();
- sxyz[1] = ctx->args()[1].toNumber();
- sxyz[2] = ctx->args()[2].toNumber();
- sxyz[3] = ctx->args()[3].toNumber();
+ sxyz[0] = callData->args[0].toNumber();
+ sxyz[1] = callData->args[1].toNumber();
+ sxyz[2] = callData->args[2].toNumber();
+ sxyz[3] = callData->args[3].toNumber();
const void *params[] = { sxyz };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
}
/*!
@@ -510,44 +516,47 @@ matrix values.
Finally, the function may be called with no arguments and the resulting
matrix will be the identity matrix.
*/
-ReturnedValue QtObject::method_matrix4x4(QV4::CallContext *ctx)
+void QtObject::method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
- if (ctx->argc() == 0)
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, Q_NULLPTR));
+ if (callData->argc == 0) {
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, Q_NULLPTR));
+ return;
+ }
- if (ctx->argc() == 1 && ctx->args()[0].isObject()) {
+ if (callData->argc == 1 && callData->args[0].isObject()) {
bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(ctx->args()[0]), v4, &ok);
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(callData->args[0]), v4, &ok);
if (!ok)
- V4THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
- return ctx->engine()->fromVariant(v);
+ THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
+ scope.result = scope.engine->fromVariant(v);
+ return;
}
- if (ctx->argc() != 16)
- V4THROW_ERROR("Qt.matrix4x4(): Invalid arguments");
+ if (callData->argc != 16)
+ THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid arguments");
qreal vals[16]; // qmatrix4x4 uses qreal internally
- vals[0] = ctx->args()[0].toNumber();
- vals[1] = ctx->args()[1].toNumber();
- vals[2] = ctx->args()[2].toNumber();
- vals[3] = ctx->args()[3].toNumber();
- vals[4] = ctx->args()[4].toNumber();
- vals[5] = ctx->args()[5].toNumber();
- vals[6] = ctx->args()[6].toNumber();
- vals[7] = ctx->args()[7].toNumber();
- vals[8] = ctx->args()[8].toNumber();
- vals[9] = ctx->args()[9].toNumber();
- vals[10] = ctx->args()[10].toNumber();
- vals[11] = ctx->args()[11].toNumber();
- vals[12] = ctx->args()[12].toNumber();
- vals[13] = ctx->args()[13].toNumber();
- vals[14] = ctx->args()[14].toNumber();
- vals[15] = ctx->args()[15].toNumber();
+ vals[0] = callData->args[0].toNumber();
+ vals[1] = callData->args[1].toNumber();
+ vals[2] = callData->args[2].toNumber();
+ vals[3] = callData->args[3].toNumber();
+ vals[4] = callData->args[4].toNumber();
+ vals[5] = callData->args[5].toNumber();
+ vals[6] = callData->args[6].toNumber();
+ vals[7] = callData->args[7].toNumber();
+ vals[8] = callData->args[8].toNumber();
+ vals[9] = callData->args[9].toNumber();
+ vals[10] = callData->args[10].toNumber();
+ vals[11] = callData->args[11].toNumber();
+ vals[12] = callData->args[12].toNumber();
+ vals[13] = callData->args[13].toNumber();
+ vals[14] = callData->args[14].toNumber();
+ vals[15] = callData->args[15].toNumber();
const void *params[] = { vals };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
}
/*!
@@ -564,27 +573,29 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
*/
-ReturnedValue QtObject::method_lighter(QV4::CallContext *ctx)
+void QtObject::method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1 && ctx->argc() != 2)
- V4THROW_ERROR("Qt.lighter(): Invalid arguments");
+ if (callData->argc != 1 && callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.lighter(): Invalid arguments");
- QVariant v = ctx->engine()->toVariant(ctx->args()[0], -1);
+ QVariant v = scope.engine->toVariant(callData->args[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
} else if (v.userType() != QVariant::Color) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
qreal factor = 1.5;
- if (ctx->argc() == 2)
- factor = ctx->args()[1].toNumber();
+ if (callData->argc == 2)
+ factor = callData->args[1].toNumber();
- return ctx->engine()->fromVariant(QQml_colorProvider()->lighter(v, factor));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->lighter(v, factor));
}
/*!
@@ -602,27 +613,29 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
*/
-ReturnedValue QtObject::method_darker(QV4::CallContext *ctx)
+void QtObject::method_darker(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1 && ctx->argc() != 2)
- V4THROW_ERROR("Qt.darker(): Invalid arguments");
+ if (callData->argc != 1 && callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.darker(): Invalid arguments");
- QVariant v = ctx->engine()->toVariant(ctx->args()[0], -1);
+ QVariant v = scope.engine->toVariant(callData->args[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
} else if (v.userType() != QVariant::Color) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
qreal factor = 2.0;
- if (ctx->argc() == 2)
- factor = ctx->args()[1].toNumber();
+ if (callData->argc == 2)
+ factor = callData->args[1].toNumber();
- return ctx->engine()->fromVariant(QQml_colorProvider()->darker(v, factor));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->darker(v, factor));
}
/*!
@@ -649,36 +662,40 @@ ReturnedValue QtObject::method_darker(QV4::CallContext *ctx)
Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color.
*/
-ReturnedValue QtObject::method_tint(QV4::CallContext *ctx)
+void QtObject::method_tint(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.tint(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.tint(): Invalid arguments");
// base color
- QVariant v1 = ctx->engine()->toVariant(ctx->args()[0], -1);
+ QVariant v1 = scope.engine->toVariant(callData->args[0], -1);
if (v1.userType() == QVariant::String) {
bool ok = false;
v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
if (!ok) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
} else if (v1.userType() != QVariant::Color) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
// tint color
- QVariant v2 = ctx->engine()->toVariant(ctx->args()[1], -1);
+ QVariant v2 = scope.engine->toVariant(callData->args[1], -1);
if (v2.userType() == QVariant::String) {
bool ok = false;
v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
if (!ok) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
} else if (v2.userType() != QVariant::Color) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
- return ctx->engine()->fromVariant(QQml_colorProvider()->tint(v1, v2));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->tint(v1, v2));
}
/*!
@@ -697,32 +714,31 @@ If \a format is not specified, \a date is formatted using
\sa Locale
*/
-ReturnedValue QtObject::method_formatDate(QV4::CallContext *ctx)
+void QtObject::method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 2)
- V4THROW_ERROR("Qt.formatDate(): Invalid arguments");
- QV4::Scope scope(ctx);
+ if (callData->argc < 1 || callData->argc > 2)
+ THROW_GENERIC_ERROR("Qt.formatDate(): Invalid arguments");
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDate date = ctx->engine()->toVariant(ctx->args()[0], -1).toDateTime().date();
+ QDate date = scope.engine->toVariant(callData->args[0], -1).toDateTime().date();
QString formattedDate;
- if (ctx->argc() == 2) {
- QV4::ScopedString s(scope, ctx->args()[1]);
+ if (callData->argc == 2) {
+ QV4::ScopedString s(scope, callData->args[1]);
if (s) {
QString format = s->toQString();
formattedDate = date.toString(format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].asDouble();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDate = date.toString(format);
} else {
- V4THROW_ERROR("Qt.formatDate(): Invalid date format");
+ THROW_GENERIC_ERROR("Qt.formatDate(): Invalid date format");
}
} else {
formattedDate = date.toString(enumFormat);
}
- return ctx->d()->engine->newString(formattedDate)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedDate);
}
/*!
@@ -740,38 +756,37 @@ If \a format is not specified, \a time is formatted using
\sa Locale
*/
-ReturnedValue QtObject::method_formatTime(QV4::CallContext *ctx)
+void QtObject::method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 2)
- V4THROW_ERROR("Qt.formatTime(): Invalid arguments");
- QV4::Scope scope(ctx);
+ if (callData->argc < 1 || callData->argc > 2)
+ THROW_GENERIC_ERROR("Qt.formatTime(): Invalid arguments");
- QVariant argVariant = ctx->engine()->toVariant(ctx->args()[0], -1);
+ QVariant argVariant = scope.engine->toVariant(callData->args[0], -1);
QTime time;
- if (ctx->args()[0].as<DateObject>() || (argVariant.type() == QVariant::String))
+ if (callData->args[0].as<DateObject>() || (argVariant.type() == QVariant::String))
time = argVariant.toDateTime().time();
else // if (argVariant.type() == QVariant::Time), or invalid.
time = argVariant.toTime();
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
QString formattedTime;
- if (ctx->argc() == 2) {
- QV4::ScopedString s(scope, ctx->args()[1]);
+ if (callData->argc == 2) {
+ QV4::ScopedString s(scope, callData->args[1]);
if (s) {
QString format = s->toQString();
formattedTime = time.toString(format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].asDouble();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedTime = time.toString(format);
} else {
- V4THROW_ERROR("Qt.formatTime(): Invalid time format");
+ THROW_GENERIC_ERROR("Qt.formatTime(): Invalid time format");
}
} else {
formattedTime = time.toString(enumFormat);
}
- return ctx->d()->engine->newString(formattedTime)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedTime);
}
/*!
@@ -864,32 +879,31 @@ with the \a format values below to produce the following results:
\sa Locale
*/
-ReturnedValue QtObject::method_formatDateTime(QV4::CallContext *ctx)
+void QtObject::method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 2)
- V4THROW_ERROR("Qt.formatDateTime(): Invalid arguments");
- QV4::Scope scope(ctx);
+ if (callData->argc < 1 || callData->argc > 2)
+ THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid arguments");
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDateTime dt = ctx->engine()->toVariant(ctx->args()[0], -1).toDateTime();
+ QDateTime dt = scope.engine->toVariant(callData->args[0], -1).toDateTime();
QString formattedDt;
- if (ctx->argc() == 2) {
- QV4::ScopedString s(scope, ctx->args()[1]);
+ if (callData->argc == 2) {
+ QV4::ScopedString s(scope, callData->args[1]);
if (s) {
QString format = s->toQString();
formattedDt = dt.toString(format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].asDouble();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDt = dt.toString(format);
} else {
- V4THROW_ERROR("Qt.formatDateTime(): Invalid datetime format");
+ THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid datetime format");
}
} else {
formattedDt = dt.toString(enumFormat);
}
- return ctx->d()->engine->newString(formattedDt)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedDt);
}
/*!
@@ -903,90 +917,94 @@ ReturnedValue QtObject::method_formatDateTime(QV4::CallContext *ctx)
still fail to launch or fail to open the requested URL. This result will not be reported back
to the application.
*/
-ReturnedValue QtObject::method_openUrlExternally(QV4::CallContext *ctx)
+void QtObject::method_openUrlExternally(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- return QV4::Encode(false);
+ if (callData->argc != 1) {
+ scope.result = QV4::Encode(false);
+ return;
+ }
- QUrl url(Value::fromReturnedValue(method_resolvedUrl(ctx)).toQStringNoThrow());
- return ctx->engine()->fromVariant(QQml_guiProvider()->openUrlExternally(url));
+ method_resolvedUrl(b, scope, callData);
+ QUrl url(scope.result.toQStringNoThrow());
+ scope.result = scope.engine->fromVariant(QQml_guiProvider()->openUrlExternally(url));
}
/*!
\qmlmethod url Qt::resolvedUrl(url url)
Returns \a url resolved relative to the URL of the caller.
*/
-ReturnedValue QtObject::method_resolvedUrl(QV4::CallContext *ctx)
+void QtObject::method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- ExecutionEngine *v4 = ctx->engine();
+ ExecutionEngine *v4 = scope.engine;
- QUrl url = v4->toVariant(ctx->args()[0], -1).toUrl();
+ QUrl url = v4->toVariant(callData->args[0], -1).toUrl();
QQmlEngine *e = v4->qmlEngine();
QQmlEnginePrivate *p = 0;
if (e) p = QQmlEnginePrivate::get(e);
if (p) {
QQmlContextData *ctxt = v4->callingQmlContext();
if (ctxt)
- return v4->newString(ctxt->resolvedUrl(url).toString())->asReturnedValue();
+ scope.result = v4->newString(ctxt->resolvedUrl(url).toString());
else
- return v4->newString(url.toString())->asReturnedValue();
+ scope.result = v4->newString(url.toString());
+ return;
}
- return v4->newString(e->baseUrl().resolved(url).toString())->asReturnedValue();
+ scope.result = v4->newString(e->baseUrl().resolved(url).toString());
}
/*!
\qmlmethod list<string> Qt::fontFamilies()
Returns a list of the font families available to the application.
*/
-ReturnedValue QtObject::method_fontFamilies(CallContext *ctx)
+void QtObject::method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 0)
- V4THROW_ERROR("Qt.fontFamilies(): Invalid arguments");
+ if (callData->argc != 0)
+ THROW_GENERIC_ERROR("Qt.fontFamilies(): Invalid arguments");
- return ctx->engine()->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
+ scope.result = scope.engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
}
/*!
\qmlmethod string Qt::md5(data)
Returns a hex string of the md5 hash of \c data.
*/
-ReturnedValue QtObject::method_md5(CallContext *ctx)
+void QtObject::method_md5(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("Qt.md5(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("Qt.md5(): Invalid arguments");
- QByteArray data = ctx->args()[0].toQStringNoThrow().toUtf8();
+ QByteArray data = callData->args[0].toQStringNoThrow().toUtf8();
QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
- return ctx->d()->engine->newString(QLatin1String(result.toHex()))->asReturnedValue();
+ scope.result = scope.engine->newString(QLatin1String(result.toHex()));
}
/*!
\qmlmethod string Qt::btoa(data)
Binary to ASCII - this function returns a base64 encoding of \c data.
*/
-ReturnedValue QtObject::method_btoa(CallContext *ctx)
+void QtObject::method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("Qt.btoa(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("Qt.btoa(): Invalid arguments");
- QByteArray data = ctx->args()[0].toQStringNoThrow().toUtf8();
+ QByteArray data = callData->args[0].toQStringNoThrow().toUtf8();
- return ctx->d()->engine->newString(QLatin1String(data.toBase64()))->asReturnedValue();
+ scope.result = scope.engine->newString(QLatin1String(data.toBase64()));
}
/*!
\qmlmethod string Qt::atob(data)
ASCII to binary - this function decodes the base64 encoded \a data string and returns it.
*/
-ReturnedValue QtObject::method_atob(CallContext *ctx)
+void QtObject::method_atob(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("Qt.atob(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("Qt.atob(): Invalid arguments");
- QByteArray data = ctx->args()[0].toQStringNoThrow().toLatin1();
+ QByteArray data = callData->args[0].toQStringNoThrow().toLatin1();
- return ctx->d()->engine->newString(QString::fromUtf8(QByteArray::fromBase64(data)))->asReturnedValue();
+ scope.result = scope.engine->newString(QString::fromUtf8(QByteArray::fromBase64(data)));
}
/*!
@@ -998,10 +1016,10 @@ QQmlEngine::quit() signal to the QCoreApplication::quit() slot.
\sa exit()
*/
-ReturnedValue QtObject::method_quit(CallContext *ctx)
+void QtObject::method_quit(const BuiltinFunction *, Scope &scope, CallData *)
{
- QQmlEnginePrivate::get(ctx->engine()->qmlEngine())->sendQuit();
- return QV4::Encode::undefined();
+ QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendQuit();
+ scope.result = Encode::undefined();
}
/*!
@@ -1015,15 +1033,15 @@ ReturnedValue QtObject::method_quit(CallContext *ctx)
\sa quit()
*/
-ReturnedValue QtObject::method_exit(CallContext *ctx)
+void QtObject::method_exit(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("Qt.exit(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("Qt.exit(): Invalid arguments");
- int retCode = ctx->args()[0].toNumber();
+ int retCode = callData->args[0].toNumber();
- QQmlEnginePrivate::get(ctx->engine()->qmlEngine())->sendExit(retCode);
- return QV4::Encode::undefined();
+ QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendExit(retCode);
+ scope.result = QV4::Encode::undefined();
}
/*!
@@ -1050,11 +1068,10 @@ If this is the case, consider using \l{QtQml::Qt::createComponent()}{Qt.createCo
See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function.
*/
-ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
+void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- if (ctx->argc() < 2 || ctx->argc() > 3)
- V4THROW_ERROR("Qt.createQmlObject(): Invalid arguments");
+ if (callData->argc < 2 || callData->argc > 3)
+ THROW_GENERIC_ERROR("Qt.createQmlObject(): Invalid arguments");
struct Error {
static ReturnedValue create(QV4::ExecutionEngine *v4, const QList<QQmlError> &errors) {
@@ -1085,7 +1102,7 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
}
};
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
QQmlEngine *engine = v8engine->engine();
QQmlContextData *context = scope.engine->callingQmlContext();
@@ -1097,13 +1114,13 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
effectiveContext = context->asQQmlContext();
Q_ASSERT(effectiveContext);
- QString qml = ctx->args()[0].toQStringNoThrow();
+ QString qml = callData->args[0].toQStringNoThrow();
if (qml.isEmpty())
- return QV4::Encode::null();
+ RETURN_RESULT(Encode::null());
QUrl url;
- if (ctx->argc() > 2)
- url = QUrl(ctx->args()[2].toQStringNoThrow());
+ if (callData->argc > 2)
+ url = QUrl(callData->args[2].toQStringNoThrow());
else
url = QUrl(QLatin1String("inline"));
@@ -1111,11 +1128,11 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
url = context->resolvedUrl(url);
QObject *parentArg = 0;
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, ctx->args()[1]);
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, callData->args[1]);
if (!!qobjectWrapper)
parentArg = qobjectWrapper->object();
if (!parentArg)
- V4THROW_ERROR("Qt.createQmlObject(): Missing parent object");
+ THROW_GENERIC_ERROR("Qt.createQmlObject(): Missing parent object");
QQmlTypeData *typeData = QQmlEnginePrivate::get(engine)->typeLoader.getType(
qml.toUtf8(), url, QQmlTypeLoader::Synchronous);
@@ -1126,12 +1143,12 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
componentPrivate->progress = 1.0;
if (component.isError()) {
- ScopedValue v(scope, Error::create(ctx->d()->engine, component.errors()));
- return ctx->engine()->throwError(v);
+ ScopedValue v(scope, Error::create(scope.engine, component.errors()));
+ RETURN_RESULT(scope.engine->throwError(v));
}
if (!component.isReady())
- V4THROW_ERROR("Qt.createQmlObject(): Component is not ready");
+ THROW_GENERIC_ERROR("Qt.createQmlObject(): Component is not ready");
QObject *obj = component.beginCreate(effectiveContext);
if (obj) {
@@ -1150,13 +1167,14 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
component.completeCreate();
if (component.isError()) {
- ScopedValue v(scope, Error::create(ctx->d()->engine, component.errors()));
- return ctx->engine()->throwError(v);
+ ScopedValue v(scope, Error::create(scope.engine, component.errors()));
+ scope.result = scope.engine->throwError(v);
+ return;
}
Q_ASSERT(obj);
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, obj);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, obj);
}
/*!
@@ -1203,14 +1221,12 @@ See \l {Dynamic QML Object Creation from JavaScript} for more information on usi
To create a QML object from an arbitrary string of QML (instead of a file),
use \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}.
*/
-ReturnedValue QtObject::method_createComponent(CallContext *ctx)
+void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 3)
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
+ if (callData->argc < 1 || callData->argc > 3)
+ THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
- Scope scope(ctx);
-
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
QQmlEngine *engine = v8engine->engine();
QQmlContextData *context = scope.engine->callingQmlContext();
@@ -1219,41 +1235,41 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
if (context->isPragmaLibraryContext)
effectiveContext = 0;
- QString arg = ctx->args()[0].toQStringNoThrow();
+ QString arg = callData->args[0].toQStringNoThrow();
if (arg.isEmpty())
- return QV4::Encode::null();
+ RETURN_RESULT(QV4::Encode::null());
QQmlComponent::CompilationMode compileMode = QQmlComponent::PreferSynchronous;
QObject *parentArg = 0;
int consumedCount = 1;
- if (ctx->argc() > 1) {
- ScopedValue lastArg(scope, ctx->args()[ctx->argc()-1]);
+ if (callData->argc > 1) {
+ ScopedValue lastArg(scope, callData->args[callData->argc-1]);
// The second argument could be the mode enum
- if (ctx->args()[1].isInteger()) {
- int mode = ctx->args()[1].integerValue();
+ if (callData->args[1].isInteger()) {
+ int mode = callData->args[1].integerValue();
if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous))
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
+ THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
compileMode = QQmlComponent::CompilationMode(mode);
consumedCount += 1;
} else {
// The second argument could be the parent only if there are exactly two args
- if ((ctx->argc() != 2) || !(lastArg->isObject() || lastArg->isNull()))
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
+ if ((callData->argc != 2) || !(lastArg->isObject() || lastArg->isNull()))
+ THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
}
- if (consumedCount < ctx->argc()) {
+ if (consumedCount < callData->argc) {
if (lastArg->isObject()) {
Scoped<QObjectWrapper> qobjectWrapper(scope, lastArg);
if (qobjectWrapper)
parentArg = qobjectWrapper->object();
if (!parentArg)
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object"));
+ THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object");
} else if (lastArg->isNull()) {
parentArg = 0;
} else {
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object"));
+ THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object");
}
}
}
@@ -1264,7 +1280,7 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
QQmlData::get(c, true)->explicitIndestructibleSet = false;
QQmlData::get(c)->indestructible = false;
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, c);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, c);
}
/*!
@@ -1287,18 +1303,18 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
\sa Locale
*/
-ReturnedValue QtObject::method_locale(CallContext *ctx)
+void QtObject::method_locale(const BuiltinFunction *, Scope &scope, CallData *callData)
{
QString code;
- if (ctx->argc() > 1)
- V4THROW_ERROR("locale() requires 0 or 1 argument");
- if (ctx->argc() == 1 && !ctx->args()[0].isString())
- V4THROW_TYPE("locale(): argument (locale code) must be a string");
+ if (callData->argc > 1)
+ THROW_GENERIC_ERROR("locale() requires 0 or 1 argument");
+ if (callData->argc == 1 && !callData->args[0].isString())
+ THROW_TYPE_ERROR_WITH_MESSAGE("locale(): argument (locale code) must be a string");
- if (ctx->argc() == 1)
- code = ctx->args()[0].toQStringNoThrow();
+ if (callData->argc == 1)
+ code = callData->args[0].toQStringNoThrow();
- return QQmlLocale::locale(ctx->engine(), code);
+ scope.result = QQmlLocale::locale(scope.engine, code);
}
void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *originalFunction)
@@ -1360,62 +1376,62 @@ DEFINE_OBJECT_VTABLE(QQmlBindingFunction);
\since 5.0
*/
-ReturnedValue QtObject::method_binding(CallContext *ctx)
+void QtObject::method_binding(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("binding() requires 1 argument");
- const QV4::FunctionObject *f = ctx->args()[0].as<FunctionObject>();
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("binding() requires 1 argument");
+ const QV4::FunctionObject *f = callData->args[0].as<FunctionObject>();
if (!f)
- V4THROW_TYPE("binding(): argument (binding expression) must be a function");
+ THROW_TYPE_ERROR_WITH_MESSAGE("binding(): argument (binding expression) must be a function");
- return (ctx->d()->engine->memoryManager->allocObject<QQmlBindingFunction>(f))->asReturnedValue();
+ scope.result = scope.engine->memoryManager->allocObject<QQmlBindingFunction>(f);
}
-ReturnedValue QtObject::method_get_platform(CallContext *ctx)
+void QtObject::method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData)
{
// ### inefficient. Should be just a value based getter
- Object *o = ctx->thisObject().as<Object>();
+ Object *o = callData->thisObject.as<Object>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QtObject *qt = o->as<QtObject>();
if (!qt)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!qt->d()->platform)
// Only allocate a platform object once
- qt->d()->platform = new QQmlPlatform(ctx->d()->engine->jsEngine());
+ qt->d()->platform = new QQmlPlatform(scope.engine->jsEngine());
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, qt->d()->platform);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->platform);
}
-ReturnedValue QtObject::method_get_application(CallContext *ctx)
+void QtObject::method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData)
{
// ### inefficient. Should be just a value based getter
- Object *o = ctx->thisObject().as<Object>();
+ Object *o = callData->thisObject.as<Object>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QtObject *qt = o->as<QtObject>();
if (!qt)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!qt->d()->application)
// Only allocate an application object once
- qt->d()->application = QQml_guiProvider()->application(ctx->d()->engine->jsEngine());
+ qt->d()->application = QQml_guiProvider()->application(scope.engine->jsEngine());
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, qt->d()->application);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->application);
}
-ReturnedValue QtObject::method_get_inputMethod(CallContext *ctx)
+void QtObject::method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *)
{
QObject *o = QQml_guiProvider()->inputMethod();
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, o);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, o);
}
-ReturnedValue QtObject::method_get_styleHints(CallContext *ctx)
+void QtObject::method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *)
{
QObject *o = QQml_guiProvider()->styleHints();
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, o);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, o);
}
@@ -1475,35 +1491,35 @@ static QString jsStack(QV4::ExecutionEngine *engine) {
return stack;
}
-static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *ctx,
- bool printStack = false)
+static void writeToConsole(const BuiltinFunction *, Scope &scope, CallData *callData,
+ ConsoleLogTypes logType, bool printStack = false)
{
QLoggingCategory *loggingCategory = 0;
QString result;
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
int start = 0;
- if (ctx->argc() > 0) {
- if (const QObjectWrapper* wrapper = ctx->args()[0].as<QObjectWrapper>()) {
+ if (callData->argc > 0) {
+ if (const QObjectWrapper* wrapper = callData->args[0].as<QObjectWrapper>()) {
if (QQmlLoggingCategory* category = qobject_cast<QQmlLoggingCategory*>(wrapper->object())) {
if (category->category())
loggingCategory = category->category();
else
- V4THROW_ERROR("A QmlLoggingCatgory was provided without a valid name");
+ THROW_GENERIC_ERROR("A QmlLoggingCatgory was provided without a valid name");
start = 1;
}
}
}
- for (int i = start; i < ctx->argc(); ++i) {
+ for (int i = start; i < callData->argc; ++i) {
if (i != start)
result.append(QLatin1Char(' '));
- if (ctx->args()[i].as<ArrayObject>())
- result += QLatin1Char('[') + ctx->args()[i].toQStringNoThrow() + QLatin1Char(']');
+ if (callData->args[i].as<ArrayObject>())
+ result += QLatin1Char('[') + callData->args[i].toQStringNoThrow() + QLatin1Char(']');
else
- result.append(ctx->args()[i].toQStringNoThrow());
+ result.append(callData->args[i].toQStringNoThrow());
}
if (printStack)
@@ -1540,32 +1556,32 @@ static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *c
break;
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
DEFINE_OBJECT_VTABLE(ConsoleObject);
-QV4::ReturnedValue ConsoleObject::method_error(CallContext *ctx)
+void ConsoleObject::method_error(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return writeToConsole(Error, ctx);
+ writeToConsole(b, scope, callData, Error);
}
-QV4::ReturnedValue ConsoleObject::method_log(CallContext *ctx)
+void ConsoleObject::method_log(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
//console.log
//console.debug
//print
- return writeToConsole(Log, ctx);
+ writeToConsole(b, scope, callData, Log);
}
-QV4::ReturnedValue ConsoleObject::method_info(CallContext *ctx)
+void ConsoleObject::method_info(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return writeToConsole(Info, ctx);
+ writeToConsole(b, scope, callData, Info);
}
-QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx)
+void ConsoleObject::method_profile(const BuiltinFunction *, Scope &scope, CallData *)
{
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
QV4::StackFrame frame = v4->currentStackFrame();
const QByteArray baSource = frame.source.toUtf8();
@@ -1579,12 +1595,12 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx)
logger.debug("Profiling started.");
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx)
+void ConsoleObject::method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *)
{
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
QV4::StackFrame frame = v4->currentStackFrame();
const QByteArray baSource = frame.source.toUtf8();
@@ -1599,46 +1615,46 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx)
logger.debug("Profiling ended.");
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_time(CallContext *ctx)
+void ConsoleObject::method_time(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("console.time(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("console.time(): Invalid arguments");
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
- QString name = ctx->args()[0].toQStringNoThrow();
+ QString name = callData->args[0].toQStringNoThrow();
v8engine->startTimer(name);
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_timeEnd(CallContext *ctx)
+void ConsoleObject::method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("console.timeEnd(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("console.timeEnd(): Invalid arguments");
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
- QString name = ctx->args()[0].toQStringNoThrow();
+ QString name = callData->args[0].toQStringNoThrow();
bool wasRunning;
qint64 elapsed = v8engine->stopTimer(name, &wasRunning);
if (wasRunning) {
qDebug("%s: %llims", qPrintable(name), elapsed);
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_count(CallContext *ctx)
+void ConsoleObject::method_count(const BuiltinFunction *, Scope &scope, CallData *callData)
{
// first argument: name to print. Ignore any additional arguments
QString name;
- if (ctx->argc() > 0)
- name = ctx->args()[0].toQStringNoThrow();
+ if (callData->argc > 0)
+ name = callData->args[0].toQStringNoThrow();
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
QV4::StackFrame frame = v4->currentStackFrame();
@@ -1651,15 +1667,15 @@ QV4::ReturnedValue ConsoleObject::method_count(CallContext *ctx)
qPrintable(frame.function))
.debug("%s", qPrintable(message));
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_trace(CallContext *ctx)
+void ConsoleObject::method_trace(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 0)
- V4THROW_ERROR("console.trace(): Invalid arguments");
+ if (callData->argc != 0)
+ THROW_GENERIC_ERROR("console.trace(): Invalid arguments");
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
QString stack = jsStack(v4);
@@ -1668,28 +1684,28 @@ QV4::ReturnedValue ConsoleObject::method_trace(CallContext *ctx)
frame.function.toUtf8().constData())
.debug("%s", qPrintable(stack));
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_warn(CallContext *ctx)
+void ConsoleObject::method_warn(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return writeToConsole(Warn, ctx);
+ return writeToConsole(b, scope, callData, Warn);
}
-QV4::ReturnedValue ConsoleObject::method_assert(CallContext *ctx)
+void ConsoleObject::method_assert(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- V4THROW_ERROR("console.assert(): Missing argument");
+ if (callData->argc == 0)
+ THROW_GENERIC_ERROR("console.assert(): Missing argument");
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
- if (!ctx->args()[0].toBoolean()) {
+ if (!callData->args[0].toBoolean()) {
QString message;
- for (int i = 1; i < ctx->argc(); ++i) {
+ for (int i = 1; i < callData->argc; ++i) {
if (i != 1)
message.append(QLatin1Char(' '));
- message.append(ctx->args()[i].toQStringNoThrow());
+ message.append(callData->args[i].toQStringNoThrow());
}
QString stack = jsStack(v4);
@@ -1700,17 +1716,17 @@ QV4::ReturnedValue ConsoleObject::method_assert(CallContext *ctx)
.critical("%s\n%s",qPrintable(message), qPrintable(stack));
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_exception(CallContext *ctx)
+void ConsoleObject::method_exception(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- V4THROW_ERROR("console.exception(): Missing argument");
+ if (callData->argc == 0)
+ THROW_GENERIC_ERROR("console.exception(): Missing argument");
- writeToConsole(Error, ctx, true);
+ writeToConsole(b, scope, callData, Error, true);
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
@@ -1766,38 +1782,38 @@ void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions ext
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTranslate(CallContext *ctx)
-{
- if (ctx->argc() < 2)
- V4THROW_ERROR("qsTranslate() requires at least two arguments");
- if (!ctx->args()[0].isString())
- V4THROW_ERROR("qsTranslate(): first argument (context) must be a string");
- if (!ctx->args()[1].isString())
- V4THROW_ERROR("qsTranslate(): second argument (sourceText) must be a string");
- if ((ctx->argc() > 2) && !ctx->args()[2].isString())
- V4THROW_ERROR("qsTranslate(): third argument (disambiguation) must be a string");
-
- QString context = ctx->args()[0].toQStringNoThrow();
- QString text = ctx->args()[1].toQStringNoThrow();
+void GlobalExtensions::method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData)
+{
+ if (callData->argc < 2)
+ THROW_GENERIC_ERROR("qsTranslate() requires at least two arguments");
+ if (!callData->args[0].isString())
+ THROW_GENERIC_ERROR("qsTranslate(): first argument (context) must be a string");
+ if (!callData->args[1].isString())
+ THROW_GENERIC_ERROR("qsTranslate(): second argument (sourceText) must be a string");
+ if ((callData->argc > 2) && !callData->args[2].isString())
+ THROW_GENERIC_ERROR("qsTranslate(): third argument (disambiguation) must be a string");
+
+ QString context = callData->args[0].toQStringNoThrow();
+ QString text = callData->args[1].toQStringNoThrow();
QString comment;
- if (ctx->argc() > 2) comment = ctx->args()[2].toQStringNoThrow();
+ if (callData->argc > 2) comment = callData->args[2].toQStringNoThrow();
int i = 3;
- if (ctx->argc() > i && ctx->args()[i].isString()) {
+ if (callData->argc > i && callData->args[i].isString()) {
qWarning("qsTranslate(): specifying the encoding as fourth argument is deprecated");
++i;
}
int n = -1;
- if (ctx->argc() > i)
- n = ctx->args()[i].toInt32();
+ if (callData->argc > i)
+ n = callData->args[i].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(),
text.toUtf8().constData(),
comment.toUtf8().constData(),
n);
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
/*!
@@ -1822,11 +1838,12 @@ ReturnedValue GlobalExtensions::method_qsTranslate(CallContext *ctx)
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTranslateNoOp(CallContext *ctx)
+void GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 2)
- return QV4::Encode::undefined();
- return ctx->args()[1].asReturnedValue();
+ if (callData->argc < 2)
+ scope.result = QV4::Encode::undefined();
+ else
+ scope.result = callData->args[1];
}
/*!
@@ -1846,18 +1863,17 @@ ReturnedValue GlobalExtensions::method_qsTranslateNoOp(CallContext *ctx)
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
-{
- if (ctx->argc() < 1)
- V4THROW_ERROR("qsTr() requires at least one argument");
- if (!ctx->args()[0].isString())
- V4THROW_ERROR("qsTr(): first argument (sourceText) must be a string");
- if ((ctx->argc() > 1) && !ctx->args()[1].isString())
- V4THROW_ERROR("qsTr(): second argument (disambiguation) must be a string");
- if ((ctx->argc() > 2) && !ctx->args()[2].isNumber())
- V4THROW_ERROR("qsTr(): third argument (n) must be a number");
-
- Scope scope(ctx);
+void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData)
+{
+ if (callData->argc < 1)
+ THROW_GENERIC_ERROR("qsTr() requires at least one argument");
+ if (!callData->args[0].isString())
+ THROW_GENERIC_ERROR("qsTr(): first argument (sourceText) must be a string");
+ if ((callData->argc > 1) && !callData->args[1].isString())
+ THROW_GENERIC_ERROR("qsTr(): second argument (disambiguation) must be a string");
+ if ((callData->argc > 2) && !callData->args[2].isNumber())
+ THROW_GENERIC_ERROR("qsTr(): third argument (n) must be a number");
+
QString context;
if (QQmlContextData *ctxt = scope.engine->callingQmlContext()) {
QString path = ctxt->urlString();
@@ -1866,7 +1882,7 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
int length = lastDot - (lastSlash + 1);
context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString();
} else {
- ExecutionContext *parentCtx = scope.engine->parentContext(ctx);
+ 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) {
@@ -1885,18 +1901,18 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
}
}
- QString text = ctx->args()[0].toQStringNoThrow();
+ QString text = callData->args[0].toQStringNoThrow();
QString comment;
- if (ctx->argc() > 1)
- comment = ctx->args()[1].toQStringNoThrow();
+ if (callData->argc > 1)
+ comment = callData->args[1].toQStringNoThrow();
int n = -1;
- if (ctx->argc() > 2)
- n = ctx->args()[2].toInt32();
+ if (callData->argc > 2)
+ n = callData->args[2].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(),
comment.toUtf8().constData(), n);
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
/*!
@@ -1921,11 +1937,12 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTrNoOp(CallContext *ctx)
+void GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1)
- return QV4::Encode::undefined();
- return ctx->args()[0].asReturnedValue();
+ if (callData->argc < 1)
+ scope.result = QV4::Encode::undefined();
+ else
+ scope.result = callData->args[0];
}
/*!
@@ -1958,20 +1975,20 @@ ReturnedValue GlobalExtensions::method_qsTrNoOp(CallContext *ctx)
\sa QT_TRID_NOOP(), {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTrId(CallContext *ctx)
+void GlobalExtensions::method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1)
- V4THROW_ERROR("qsTrId() requires at least one argument");
- if (!ctx->args()[0].isString())
- V4THROW_TYPE("qsTrId(): first argument (id) must be a string");
- if (ctx->argc() > 1 && !ctx->args()[1].isNumber())
- V4THROW_TYPE("qsTrId(): second argument (n) must be a number");
+ if (callData->argc < 1)
+ THROW_GENERIC_ERROR("qsTrId() requires at least one argument");
+ if (!callData->args[0].isString())
+ THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): first argument (id) must be a string");
+ if (callData->argc > 1 && !callData->args[1].isNumber())
+ THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): second argument (n) must be a number");
int n = -1;
- if (ctx->argc() > 1)
- n = ctx->args()[1].toInt32();
+ if (callData->argc > 1)
+ n = callData->args[1].toInt32();
- return ctx->d()->engine->newString(qtTrId(ctx->args()[0].toQStringNoThrow().toUtf8().constData(), n))->asReturnedValue();
+ scope.result = scope.engine->newString(qtTrId(callData->args[0].toQStringNoThrow().toUtf8().constData(), n));
}
/*!
@@ -1990,41 +2007,41 @@ ReturnedValue GlobalExtensions::method_qsTrId(CallContext *ctx)
\sa qsTrId(), {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTrIdNoOp(CallContext *ctx)
+void GlobalExtensions::method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1)
- return QV4::Encode::undefined();
- return ctx->args()[0].asReturnedValue();
+ if (callData->argc < 1)
+ scope.result = QV4::Encode::undefined();
+ else
+ scope.result = callData->args[0];
}
#endif // translation
-QV4::ReturnedValue GlobalExtensions::method_gc(CallContext *ctx)
+void GlobalExtensions::method_gc(const BuiltinFunction *, Scope &scope, CallData *)
{
- ctx->d()->engine->memoryManager->runGC();
+ scope.engine->memoryManager->runGC();
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-ReturnedValue GlobalExtensions::method_string_arg(CallContext *ctx)
+void GlobalExtensions::method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("String.arg(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("String.arg(): Invalid arguments");
- QString value = ctx->thisObject().toQString();
+ QString value = callData->thisObject.toQString();
- QV4::Scope scope(ctx);
- QV4::ScopedValue arg(scope, ctx->args()[0]);
+ QV4::ScopedValue arg(scope, callData->args[0]);
if (arg->isInteger())
- return ctx->d()->engine->newString(value.arg(arg->integerValue()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(value.arg(arg->integerValue())));
else if (arg->isDouble())
- return ctx->d()->engine->newString(value.arg(arg->doubleValue()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(value.arg(arg->doubleValue())));
else if (arg->isBoolean())
- return ctx->d()->engine->newString(value.arg(arg->booleanValue()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(value.arg(arg->booleanValue())));
- return ctx->d()->engine->newString(value.arg(arg->toQString()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(value.arg(arg->toQString())));
}
/*!
@@ -2047,10 +2064,10 @@ be passed on to the function invoked. Note that if redundant calls
are eliminated, then only the last set of arguments will be passed to the
function.
*/
-ReturnedValue QtObject::method_callLater(CallContext *ctx)
+void QtObject::method_callLater(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- QV8Engine *v8engine = ctx->engine()->v8Engine;
- return v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(ctx);
+ QV8Engine *v8engine = scope.engine->v8Engine;
+ v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, scope, callData);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index fe43532647..21613b7c10 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -93,45 +93,45 @@ struct QtObject : Object
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static ReturnedValue method_isQtObject(CallContext *ctx);
- static ReturnedValue method_rgba(CallContext *ctx);
- static ReturnedValue method_hsla(CallContext *ctx);
- static ReturnedValue method_hsva(CallContext *ctx);
- static ReturnedValue method_colorEqual(CallContext *ctx);
- static ReturnedValue method_font(CallContext *ctx);
- static ReturnedValue method_rect(CallContext *ctx);
- static ReturnedValue method_point(CallContext *ctx);
- static ReturnedValue method_size(CallContext *ctx);
- static ReturnedValue method_vector2d(CallContext *ctx);
- static ReturnedValue method_vector3d(CallContext *ctx);
- static ReturnedValue method_vector4d(CallContext *ctx);
- static ReturnedValue method_quaternion(CallContext *ctx);
- static ReturnedValue method_matrix4x4(CallContext *ctx);
- static ReturnedValue method_lighter(CallContext *ctx);
- static ReturnedValue method_darker(CallContext *ctx);
- static ReturnedValue method_tint(CallContext *ctx);
- static ReturnedValue method_formatDate(CallContext *ctx);
- static ReturnedValue method_formatTime(CallContext *ctx);
- static ReturnedValue method_formatDateTime(CallContext *ctx);
- static ReturnedValue method_openUrlExternally(CallContext *ctx);
- static ReturnedValue method_fontFamilies(CallContext *ctx);
- static ReturnedValue method_md5(CallContext *ctx);
- static ReturnedValue method_btoa(CallContext *ctx);
- static ReturnedValue method_atob(CallContext *ctx);
- static ReturnedValue method_quit(CallContext *ctx);
- static ReturnedValue method_exit(CallContext *ctx);
- static ReturnedValue method_resolvedUrl(CallContext *ctx);
- static ReturnedValue method_createQmlObject(CallContext *ctx);
- static ReturnedValue method_createComponent(CallContext *ctx);
- static ReturnedValue method_locale(CallContext *ctx);
- static ReturnedValue method_binding(CallContext *ctx);
-
- static ReturnedValue method_get_platform(CallContext *ctx);
- static ReturnedValue method_get_application(CallContext *ctx);
- static ReturnedValue method_get_inputMethod(CallContext *ctx);
- static ReturnedValue method_get_styleHints(CallContext *ctx);
-
- static ReturnedValue method_callLater(CallContext *ctx);
+ static void method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_font(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_rect(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_point(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_size(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_darker(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_tint(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_openUrlExternally(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_md5(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_atob(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_quit(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_exit(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_locale(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_binding(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_callLater(const BuiltinFunction *, Scope &scope, CallData *callData);
private:
void addAll();
@@ -142,18 +142,18 @@ struct ConsoleObject : Object
{
V4_OBJECT2(ConsoleObject, Object)
- static ReturnedValue method_error(CallContext *ctx);
- static ReturnedValue method_log(CallContext *ctx);
- static ReturnedValue method_info(CallContext *ctx);
- static ReturnedValue method_profile(CallContext *ctx);
- static ReturnedValue method_profileEnd(CallContext *ctx);
- static ReturnedValue method_time(CallContext *ctx);
- static ReturnedValue method_timeEnd(CallContext *ctx);
- static ReturnedValue method_count(CallContext *ctx);
- static ReturnedValue method_trace(CallContext *ctx);
- static ReturnedValue method_warn(CallContext *ctx);
- static ReturnedValue method_assert(CallContext *ctx);
- static ReturnedValue method_exception(CallContext *ctx);
+ static void method_error(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_log(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_info(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_profile(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_time(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_count(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_trace(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_warn(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_assert(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_exception(const BuiltinFunction *, Scope &scope, CallData *callData);
};
@@ -161,17 +161,17 @@ struct Q_QML_PRIVATE_EXPORT GlobalExtensions {
static void init(Object *globalObject, QJSEngine::Extensions extensions);
#if QT_CONFIG(translation)
- static ReturnedValue method_qsTranslate(CallContext *ctx);
- static ReturnedValue method_qsTranslateNoOp(CallContext *ctx);
- static ReturnedValue method_qsTr(CallContext *ctx);
- static ReturnedValue method_qsTrNoOp(CallContext *ctx);
- static ReturnedValue method_qsTrId(CallContext *ctx);
- static ReturnedValue method_qsTrIdNoOp(CallContext *ctx);
+ static void method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData);
#endif
- static ReturnedValue method_gc(CallContext *ctx);
+ static void method_gc(const BuiltinFunction *, Scope &scope, CallData *callData);
// on String:prototype
- static ReturnedValue method_string_arg(CallContext *ctx);
+ static void method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/qml/v8/qv4domerrors_p.h b/src/qml/qml/v8/qv4domerrors_p.h
index faa9dd8bc7..a9bdbe01ae 100644
--- a/src/qml/qml/v8/qv4domerrors_p.h
+++ b/src/qml/qml/v8/qv4domerrors_p.h
@@ -74,11 +74,12 @@ QT_BEGIN_NAMESPACE
#define DOMEXCEPTION_VALIDATION_ERR 16
#define DOMEXCEPTION_TYPE_MISMATCH_ERR 17
-#define V4THROW_DOM(error, string) { \
+#define THROW_DOM(error, string) { \
QV4::ScopedValue v(scope, scope.engine->newString(QStringLiteral(string))); \
QV4::ScopedObject ex(scope, scope.engine->newErrorObject(v)); \
ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(error))); \
- return ctx->engine()->throwError(ex); \
+ scope.result = scope.engine->throwError(ex); \
+ return; \
}
namespace QV4 {
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index a545fe57ca..2ded9c13c8 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -82,12 +82,12 @@ void QQmlBindPrivate::validate(QObject *binding) const
return;
if (!prop.isValid()) {
- qmlInfo(binding) << "Property '" << propName << "' does not exist on " << QQmlMetaType::prettyTypeName(obj) << ".";
+ qmlWarning(binding) << "Property '" << propName << "' does not exist on " << QQmlMetaType::prettyTypeName(obj) << ".";
return;
}
if (!prop.isWritable()) {
- qmlInfo(binding) << "Property '" << propName << "' on " << QQmlMetaType::prettyTypeName(obj) << " is read-only.";
+ qmlWarning(binding) << "Property '" << propName << "' on " << QQmlMetaType::prettyTypeName(obj) << " is read-only.";
return;
}
}
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 2aed4d9972..870aeaa6e2 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -168,7 +168,7 @@ void QQmlConnections::setTarget(QObject *obj)
if (d->targetSet && d->target == obj)
return;
d->targetSet = true; // even if setting to 0, it is *set*
- foreach (QQmlBoundSignal *s, d->boundsignals) {
+ for (QQmlBoundSignal *s : qAsConst(d->boundsignals)) {
// It is possible that target is being changed due to one of our signal
// handlers -> use deleteLater().
if (s->isNotifying())
@@ -278,7 +278,7 @@ void QQmlConnections::connectSignals()
QQmlContextData *ctxtdata = ddata ? ddata->outerContext : 0;
const QV4::CompiledData::Unit *qmlUnit = d->compilationUnit->data;
- foreach (const QV4::CompiledData::Binding *binding, d->bindings) {
+ for (const QV4::CompiledData::Binding *binding : qAsConst(d->bindings)) {
Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script);
QString propName = qmlUnit->stringAt(binding->propertyNameIndex);
@@ -295,7 +295,7 @@ void QQmlConnections::connectSignals()
d->boundsignals += signal;
} else {
if (!d->ignoreUnknownSignals)
- qmlInfo(this) << tr("Cannot assign to non-existent property \"%1\"").arg(propName);
+ qmlWarning(this) << tr("Cannot assign to non-existent property \"%1\"").arg(propName);
}
}
}
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index be10b270ae..a5878dcffd 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -264,7 +264,7 @@ QQmlDelegateModel::~QQmlDelegateModel()
{
Q_D(QQmlDelegateModel);
- foreach (QQmlDelegateModelItem *cacheItem, d->m_cache) {
+ for (QQmlDelegateModelItem *cacheItem : qAsConst(d->m_cache)) {
if (cacheItem->object) {
delete cacheItem->object;
@@ -310,7 +310,7 @@ void QQmlDelegateModel::componentComplete()
--d->m_groupCount;
--i;
} else if (name.at(0).isUpper()) {
- qmlInfo(d->m_groups[i]) << QQmlDelegateModelGroup::tr("Group names must start with a lower case letter");
+ qmlWarning(d->m_groups[i]) << QQmlDelegateModelGroup::tr("Group names must start with a lower case letter");
d->m_groups[i] = d->m_groups[d->m_groupCount - 1];
--d->m_groupCount;
--i;
@@ -404,7 +404,7 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
{
Q_D(QQmlDelegateModel);
if (d->m_transaction) {
- qmlInfo(this) << tr("The delegate of a DelegateModel cannot be changed within onUpdated.");
+ qmlWarning(this) << tr("The delegate of a DelegateModel cannot be changed within onUpdated.");
return;
}
bool wasValid = d->m_delegate != 0;
@@ -610,7 +610,7 @@ void QQmlDelegateModelPrivate::group_append(
if (d->m_complete)
return;
if (d->m_groupCount == Compositor::MaximumGroupCount) {
- qmlInfo(d->q_func()) << QQmlDelegateModel::tr("The maximum number of supported DelegateModelGroups is 8");
+ qmlWarning(d->q_func()) << QQmlDelegateModel::tr("The maximum number of supported DelegateModelGroups is 8");
return;
}
d->m_groups[d->m_groupCount] = group;
@@ -719,7 +719,7 @@ void QQmlDelegateModel::setFilterGroup(const QString &group)
Q_D(QQmlDelegateModel);
if (d->m_transaction) {
- qmlInfo(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
+ qmlWarning(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
return;
}
@@ -764,7 +764,8 @@ void QQmlDelegateModelPrivate::updateFilterGroup()
emit q->countChanged();
if (m_parts) {
- foreach (QQmlPartsModel *model, m_parts->models)
+ auto partsCopy = m_parts->models; // deliberate; this may alter m_parts
+ for (QQmlPartsModel *model : qAsConst(partsCopy))
model->updateFilterGroup(m_compositorGroup, changeSet);
}
}
@@ -889,7 +890,7 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba
emitCreatedItem(incubationTask, cacheItem->object);
cacheItem->releaseObject();
} else if (status == QQmlIncubator::Error) {
- qmlInfo(q, m_delegate->errors()) << "Error creating delegate";
+ qmlWarning(q, m_delegate->errors()) << "Error creating delegate";
}
if (!cacheItem->isObjectReferenced()) {
@@ -1472,7 +1473,8 @@ void QQmlDelegateModelPrivate::emitChanges()
for (int i = 1; i < m_groupCount; ++i)
QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitModelUpdated(reset);
- foreach (QQmlDelegateModelItem *cacheItem, m_cache) {
+ auto cacheCopy = m_cache; // deliberate; emitChanges may alter m_cache
+ for (QQmlDelegateModelItem *cacheItem : qAsConst(cacheCopy)) {
if (cacheItem->attached)
cacheItem->attached->emitChanges();
}
@@ -1793,24 +1795,26 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const
return groupFlags;
}
-QV4::ReturnedValue QQmlDelegateModelItem::get_model(QV4::CallContext *ctx)
+void QQmlDelegateModelItem::get_model(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->thisObject().as<QQmlDelegateModelItemObject>());
- if (!o)
- return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ if (!o) {
+ scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return;
+ }
if (!o->d()->item->metaType->model)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
- return o->d()->item->get();
+ scope.result = o->d()->item->get();
}
-QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::CallContext *ctx)
+void QQmlDelegateModelItem::get_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->thisObject().as<QQmlDelegateModelItemObject>());
- if (!o)
- return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ if (!o) {
+ scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return;
+ }
QStringList groups;
for (int i = 1; i < o->d()->item->metaType->groupCount; ++i) {
@@ -1818,27 +1822,29 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::CallContext *ctx)
groups.append(o->d()->item->metaType->groupNames.at(i - 1));
}
- return scope.engine->fromVariant(groups);
+ scope.result = scope.engine->fromVariant(groups);
}
-QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::CallContext *ctx)
+void QQmlDelegateModelItem::set_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->thisObject().as<QQmlDelegateModelItemObject>());
- if (!o)
- return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- if (!ctx->argc())
- return ctx->engine()->throwTypeError();
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ if (!o) {
+ scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return;
+ }
+
+ if (!callData->argc)
+ THROW_TYPE_ERROR();
if (!o->d()->item->metaType->model)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(o->d()->item->metaType->model);
- const int groupFlags = model->m_cacheMetaType->parseGroups(ctx->args()[0]);
+ const int groupFlags = model->m_cacheMetaType->parseGroups(callData->args[0]);
const int cacheIndex = model->m_cache.indexOf(o->d()->item);
Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
model->setGroups(it, 1, Compositor::Cache, groupFlags);
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
QV4::ReturnedValue QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
@@ -2459,7 +2465,7 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index)
if (!model->m_context || !model->m_context->isValid()) {
return QQmlV4Handle(QV4::Encode::undefined());
} else if (index < 0 || index >= model->m_compositor.count(d->group)) {
- qmlInfo(this) << tr("get: index out of range");
+ qmlWarning(this) << tr("get: index out of range");
return QQmlV4Handle(QV4::Encode::undefined());
}
@@ -2552,7 +2558,7 @@ void QQmlDelegateModelGroup::insert(QQmlV4Function *args)
QV4::ScopedValue v(scope, (*args)[i]);
if (d->parseIndex(v, &index, &group)) {
if (index < 0 || index > model->m_compositor.count(group)) {
- qmlInfo(this) << tr("insert: index out of range");
+ qmlWarning(this) << tr("insert: index out of range");
return;
}
if (++i == args->length())
@@ -2637,7 +2643,7 @@ void QQmlDelegateModelGroup::create(QQmlV4Function *args)
}
}
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("create: index out of range");
+ qmlWarning(this) << tr("create: index out of range");
return;
}
@@ -2690,22 +2696,22 @@ void QQmlDelegateModelGroup::resolve(QQmlV4Function *args)
QV4::ScopedValue v(scope, (*args)[0]);
if (d->parseIndex(v, &from, &fromGroup)) {
if (from < 0 || from >= model->m_compositor.count(fromGroup)) {
- qmlInfo(this) << tr("resolve: from index out of range");
+ qmlWarning(this) << tr("resolve: from index out of range");
return;
}
} else {
- qmlInfo(this) << tr("resolve: from index invalid");
+ qmlWarning(this) << tr("resolve: from index invalid");
return;
}
v = (*args)[1];
if (d->parseIndex(v, &to, &toGroup)) {
if (to < 0 || to >= model->m_compositor.count(toGroup)) {
- qmlInfo(this) << tr("resolve: to index out of range");
+ qmlWarning(this) << tr("resolve: to index out of range");
return;
}
} else {
- qmlInfo(this) << tr("resolve: to index invalid");
+ qmlWarning(this) << tr("resolve: to index invalid");
return;
}
@@ -2713,11 +2719,11 @@ void QQmlDelegateModelGroup::resolve(QQmlV4Function *args)
Compositor::iterator toIt = model->m_compositor.find(toGroup, to);
if (!fromIt->isUnresolved()) {
- qmlInfo(this) << tr("resolve: from is not an unresolved item");
+ qmlWarning(this) << tr("resolve: from is not an unresolved item");
return;
}
if (!toIt->list) {
- qmlInfo(this) << tr("resolve: to is not a model item");
+ qmlWarning(this) << tr("resolve: to is not a model item");
return;
}
@@ -2787,7 +2793,7 @@ void QQmlDelegateModelGroup::remove(QQmlV4Function *args)
QV4::Scope scope(args->v4engine());
QV4::ScopedValue v(scope, (*args)[0]);
if (!d->parseIndex(v, &index, &group)) {
- qmlInfo(this) << tr("remove: invalid index");
+ qmlWarning(this) << tr("remove: invalid index");
return;
}
@@ -2799,11 +2805,11 @@ void QQmlDelegateModelGroup::remove(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("remove: index out of range");
+ qmlWarning(this) << tr("remove: index out of range");
} else if (count != 0) {
Compositor::iterator it = model->m_compositor.find(group, index);
if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlInfo(this) << tr("remove: invalid count");
+ qmlWarning(this) << tr("remove: invalid count");
} else {
model->removeGroups(it, count, d->group, 1 << d->group);
}
@@ -2858,11 +2864,11 @@ void QQmlDelegateModelGroup::addGroups(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("addGroups: index out of range");
+ qmlWarning(this) << tr("addGroups: index out of range");
} else if (count != 0) {
Compositor::iterator it = model->m_compositor.find(group, index);
if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlInfo(this) << tr("addGroups: invalid count");
+ qmlWarning(this) << tr("addGroups: invalid count");
} else {
model->addGroups(it, count, d->group, groups);
}
@@ -2888,11 +2894,11 @@ void QQmlDelegateModelGroup::removeGroups(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("removeGroups: index out of range");
+ qmlWarning(this) << tr("removeGroups: index out of range");
} else if (count != 0) {
Compositor::iterator it = model->m_compositor.find(group, index);
if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlInfo(this) << tr("removeGroups: invalid count");
+ qmlWarning(this) << tr("removeGroups: invalid count");
} else {
model->removeGroups(it, count, d->group, groups);
}
@@ -2918,11 +2924,11 @@ void QQmlDelegateModelGroup::setGroups(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (index < 0 || index >= model->m_compositor.count(group)) {
- qmlInfo(this) << tr("setGroups: index out of range");
+ qmlWarning(this) << tr("setGroups: index out of range");
} else if (count != 0) {
Compositor::iterator it = model->m_compositor.find(group, index);
if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) {
- qmlInfo(this) << tr("setGroups: invalid count");
+ qmlWarning(this) << tr("setGroups: invalid count");
} else {
model->setGroups(it, count, d->group, groups);
}
@@ -2957,13 +2963,13 @@ void QQmlDelegateModelGroup::move(QQmlV4Function *args)
QV4::Scope scope(args->v4engine());
QV4::ScopedValue v(scope, (*args)[0]);
if (!d->parseIndex(v, &from, &fromGroup)) {
- qmlInfo(this) << tr("move: invalid from index");
+ qmlWarning(this) << tr("move: invalid from index");
return;
}
v = (*args)[1];
if (!d->parseIndex(v, &to, &toGroup)) {
- qmlInfo(this) << tr("move: invalid to index");
+ qmlWarning(this) << tr("move: invalid to index");
return;
}
@@ -2976,11 +2982,11 @@ void QQmlDelegateModelGroup::move(QQmlV4Function *args)
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(d->model);
if (count < 0) {
- qmlInfo(this) << tr("move: invalid count");
+ qmlWarning(this) << tr("move: invalid count");
} else if (from < 0 || from + count > model->m_compositor.count(fromGroup)) {
- qmlInfo(this) << tr("move: from index out of range");
+ qmlWarning(this) << tr("move: from index out of range");
} else if (!model->m_compositor.verifyMoveTo(fromGroup, from, toGroup, to, count, d->group)) {
- qmlInfo(this) << tr("move: to index out of range");
+ qmlWarning(this) << tr("move: to index out of range");
} else if (count > 0) {
QVector<Compositor::Remove> removes;
QVector<Compositor::Insert> inserts;
@@ -3038,7 +3044,7 @@ QString QQmlPartsModel::filterGroup() const
void QQmlPartsModel::setFilterGroup(const QString &group)
{
if (QQmlDelegateModelPrivate::get(m_model)->m_transaction) {
- qmlInfo(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
+ qmlWarning(this) << tr("The group of a DelegateModel cannot be changed within onChanged");
return;
}
@@ -3151,7 +3157,7 @@ QObject *QQmlPartsModel::object(int index, bool asynchronous)
model->release(object);
if (!model->m_delegateValidated) {
if (object)
- qmlInfo(model->m_delegate) << tr("Delegate component must be Package type.");
+ qmlWarning(model->m_delegate) << tr("Delegate component must be Package type.");
model->m_delegateValidated = true;
}
@@ -3232,28 +3238,25 @@ struct QQmlDelegateModelGroupChange : QV4::Object
return e->memoryManager->allocObject<QQmlDelegateModelGroupChange>();
}
- static QV4::ReturnedValue method_get_index(QV4::CallContext *ctx) {
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, ctx->thisObject().as<QQmlDelegateModelGroupChange>());
+ static void method_get_index(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) {
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
if (!that)
- return ctx->engine()->throwTypeError();
- return QV4::Encode(that->d()->change.index);
+ THROW_TYPE_ERROR();
+ scope.result = QV4::Encode(that->d()->change.index);
}
- static QV4::ReturnedValue method_get_count(QV4::CallContext *ctx) {
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, ctx->thisObject().as<QQmlDelegateModelGroupChange>());
+ static void method_get_count(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) {
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
if (!that)
- return ctx->engine()->throwTypeError();
- return QV4::Encode(that->d()->change.count);
+ THROW_TYPE_ERROR();
+ scope.result = QV4::Encode(that->d()->change.count);
}
- static QV4::ReturnedValue method_get_moveId(QV4::CallContext *ctx) {
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, ctx->thisObject().as<QQmlDelegateModelGroupChange>());
+ static void method_get_moveId(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) {
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
if (!that)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (that->d()->change.moveId < 0)
- return QV4::Encode::undefined();
- return QV4::Encode(that->d()->change.moveId);
+ RETURN_UNDEFINED();
+ scope.result = QV4::Encode(that->d()->change.moveId);
}
};
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index 4c2841b8ba..cb4a1f79ba 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -131,9 +131,9 @@ public:
virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; }
- static QV4::ReturnedValue get_model(QV4::CallContext *ctx);
- static QV4::ReturnedValue get_groups(QV4::CallContext *ctx);
- static QV4::ReturnedValue set_groups(QV4::CallContext *ctx);
+ static void get_model(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void get_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void set_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &);
static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 1a2e4c7f6f..cc4ccbaeb1 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -99,7 +99,7 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(const QString &key, Role::Da
if (node) {
const Role &r = *node->value;
if (type != r.type)
- qmlInfo(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
+ qmlWarning(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
return r;
}
@@ -112,7 +112,7 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(QV4::String *key, Role::Data
if (node) {
const Role &r = *node->value;
if (type != r.type)
- qmlInfo(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
+ qmlWarning(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
return r;
}
@@ -226,7 +226,7 @@ const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QV
}
if (type == Role::Invalid) {
- qmlInfo(0) << "Can't create role for unsupported data type";
+ qmlWarning(0) << "Can't create role for unsupported data type";
return 0;
}
@@ -1201,7 +1201,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
}
roleIndex = setListProperty(role, subModel);
} else {
- qmlInfo(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List));
+ qmlWarning(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List));
}
} else if (d.isBoolean()) {
roleIndex = setBoolProperty(role, d.booleanValue());
@@ -1267,10 +1267,12 @@ void ModelNodeMetaObject::updateValues()
{
const int roleCount = m_model->m_listModel->roleCount();
if (!m_initialized) {
- int *changedRoles = reinterpret_cast<int *>(alloca(roleCount * sizeof(int)));
- for (int i = 0; i < roleCount; ++i)
- changedRoles[i] = i;
- emitDirectNotifies(changedRoles, roleCount);
+ if (roleCount) {
+ int *changedRoles = reinterpret_cast<int *>(alloca(roleCount * sizeof(int)));
+ for (int i = 0; i < roleCount; ++i)
+ changedRoles[i] = i;
+ emitDirectNotifies(changedRoles, roleCount);
+ }
return;
}
for (int i=0 ; i < roleCount ; ++i) {
@@ -1984,18 +1986,18 @@ void QQmlListModel::setDynamicRoles(bool enableDynamicRoles)
if (m_mainThread && m_agent == 0) {
if (enableDynamicRoles) {
if (m_layout->roleCount())
- qmlInfo(this) << tr("unable to enable dynamic roles as this model is not empty!");
+ qmlWarning(this) << tr("unable to enable dynamic roles as this model is not empty!");
else
m_dynamicRoles = true;
} else {
if (m_roles.count()) {
- qmlInfo(this) << tr("unable to enable static roles as this model is not empty!");
+ qmlWarning(this) << tr("unable to enable static roles as this model is not empty!");
} else {
m_dynamicRoles = false;
}
}
} else {
- qmlInfo(this) << tr("dynamic role setting must be made from the main thread, before any worker scripts are created");
+ qmlWarning(this) << tr("dynamic role setting must be made from the main thread, before any worker scripts are created");
}
}
@@ -2048,7 +2050,7 @@ void QQmlListModel::remove(QQmlV4Function *args)
int removeCount = (argLength == 2 ? QV4::ScopedValue(scope, (*args)[1])->toInt32() : 1);
if (index < 0 || index+removeCount > count() || removeCount <= 0) {
- qmlInfo(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+removeCount).arg(count());
+ qmlWarning(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+removeCount).arg(count());
return;
}
@@ -2064,7 +2066,7 @@ void QQmlListModel::remove(QQmlV4Function *args)
emitItemsRemoved(index, removeCount);
} else {
- qmlInfo(this) << tr("remove: incorrect number of arguments");
+ qmlWarning(this) << tr("remove: incorrect number of arguments");
}
}
@@ -2092,7 +2094,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
int index = arg0->toInt32();
if (index < 0 || index > count()) {
- qmlInfo(this) << tr("insert: index %1 out of range").arg(index);
+ qmlWarning(this) << tr("insert: index %1 out of range").arg(index);
return;
}
@@ -2124,10 +2126,10 @@ void QQmlListModel::insert(QQmlV4Function *args)
emitItemsInserted(index, 1);
} else {
- qmlInfo(this) << tr("insert: value is not an object");
+ qmlWarning(this) << tr("insert: value is not an object");
}
} else {
- qmlInfo(this) << tr("insert: value is not an object");
+ qmlWarning(this) << tr("insert: value is not an object");
}
}
@@ -2150,7 +2152,7 @@ void QQmlListModel::move(int from, int to, int n)
if (n==0 || from==to)
return;
if (!canMove(from, to, n)) {
- qmlInfo(this) << tr("move: out of range");
+ qmlWarning(this) << tr("move: out of range");
return;
}
@@ -2239,10 +2241,10 @@ void QQmlListModel::append(QQmlV4Function *args)
emitItemsInserted(index, 1);
} else {
- qmlInfo(this) << tr("append: value is not an object");
+ qmlWarning(this) << tr("append: value is not an object");
}
} else {
- qmlInfo(this) << tr("append: value is not an object");
+ qmlWarning(this) << tr("append: value is not an object");
}
}
@@ -2321,11 +2323,11 @@ void QQmlListModel::set(int index, const QQmlV4Handle &handle)
QV4::ScopedObject object(scope, handle);
if (!object) {
- qmlInfo(this) << tr("set: value is not an object");
+ qmlWarning(this) << tr("set: value is not an object");
return;
}
if (index > count() || index < 0) {
- qmlInfo(this) << tr("set: index %1 out of range").arg(index);
+ qmlWarning(this) << tr("set: index %1 out of range").arg(index);
return;
}
@@ -2371,7 +2373,7 @@ void QQmlListModel::set(int index, const QQmlV4Handle &handle)
void QQmlListModel::setProperty(int index, const QString& property, const QVariant& value)
{
if (count() == 0 || index >= count() || index < 0) {
- qmlInfo(this) << tr("set: index %1 out of range").arg(index);
+ qmlWarning(this) << tr("set: index %1 out of range").arg(index);
return;
}
@@ -2401,7 +2403,7 @@ void QQmlListModel::sync()
// This is just a dummy method to make it look like sync() exists in
// ListModel (and not just QQmlListModelWorkerAgent) and to let
// us document sync().
- qmlInfo(this) << "List sync() can only be called from a WorkerScript";
+ qmlWarning(this) << "List sync() can only be called from a WorkerScript";
}
bool QQmlListModelParser::verifyProperty(const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding)
@@ -2543,7 +2545,7 @@ void QQmlListModelParser::applyBindings(QObject *obj, QV4::CompiledData::Compila
}
if (setRoles == false)
- qmlInfo(obj) << "All ListElement declarations are empty, no roles can be created unless dynamicRoles is set.";
+ qmlWarning(obj) << "All ListElement declarations are empty, no roles can be created unless dynamicRoles is set.";
}
bool QQmlListModelParser::definesEmptyList(const QString &s)
diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp
index 695043b592..21205f4490 100644
--- a/src/qml/types/qqmlobjectmodel.cpp
+++ b/src/qml/types/qqmlobjectmodel.cpp
@@ -373,7 +373,7 @@ void QQmlObjectModel::insert(int index, QObject *object)
{
Q_D(QQmlObjectModel);
if (index < 0 || index > count()) {
- qmlInfo(this) << tr("insert: index %1 out of range").arg(index);
+ qmlWarning(this) << tr("insert: index %1 out of range").arg(index);
return;
}
d->insert(index, object);
@@ -400,7 +400,7 @@ void QQmlObjectModel::move(int from, int to, int n)
if (n <= 0 || from == to)
return;
if (from < 0 || to < 0 || from + n > count() || to + n > count()) {
- qmlInfo(this) << tr("move: out of range");
+ qmlWarning(this) << tr("move: out of range");
return;
}
d->move(from, to, n);
@@ -418,7 +418,7 @@ void QQmlObjectModel::remove(int index, int n)
{
Q_D(QQmlObjectModel);
if (index < 0 || n <= 0 || index + n > count()) {
- qmlInfo(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+n).arg(count());
+ qmlWarning(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+n).arg(count());
return;
}
d->remove(index, n);
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 5f716da17a..f35e17c34d 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -185,7 +185,7 @@ public:
int m_nextId;
- static QV4::ReturnedValue method_sendMessage(QV4::CallContext *ctx);
+ static void method_sendMessage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
signals:
void stopThread();
@@ -292,14 +292,13 @@ QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *eng
{
}
-QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(QV4::CallContext *ctx)
+void QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- WorkerEngine *engine = (WorkerEngine*)ctx->engine()->v8Engine;
+ WorkerEngine *engine = (WorkerEngine*)scope.engine->v8Engine;
- int id = ctx->argc() > 1 ? ctx->args()[1].toInt32() : 0;
+ int id = callData->argc > 1 ? callData->args[1].toInt32() : 0;
- QV4::Scope scope(ctx);
- QV4::ScopedValue v(scope, ctx->argument(2));
+ QV4::ScopedValue v(scope, callData->argument(2));
QByteArray data = QV4::Serialize::serialize(v, scope.engine);
QMutexLocker locker(&engine->p->m_lock);
@@ -307,7 +306,7 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(QV4::Call
if (script && script->owner)
QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data));
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script)
diff --git a/src/quick/doc/images/touchpoint-metrics.png b/src/quick/doc/images/touchpoint-metrics.png
new file mode 100644
index 0000000000..9b0bf22e25
--- /dev/null
+++ b/src/quick/doc/images/touchpoint-metrics.png
Binary files differ
diff --git a/src/quick/doc/snippets/qml/listview/listview.qml b/src/quick/doc/snippets/qml/listview/listview.qml
index 31896626a4..ecb5fea076 100644
--- a/src/quick/doc/snippets/qml/listview/listview.qml
+++ b/src/quick/doc/snippets/qml/listview/listview.qml
@@ -146,4 +146,19 @@ ListView {
}
//![isCurrentItem]
+//![flickBothDirections]
+ListView {
+ width: 180; height: 200
+
+ contentWidth: 320
+ flickableDirection: Flickable.AutoFlickDirection
+
+ model: ContactModel {}
+ delegate: Row {
+ Text { text: '<b>Name:</b> ' + name; width: 160 }
+ Text { text: '<b>Number:</b> ' + number; width: 160 }
+ }
+}
+//![flickBothDirections]
+
}
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 78db92ba8a..b772ed97d2 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -354,7 +354,7 @@ void QQuickCanvasItem::setContextType(const QString &contextType)
return;
if (d->context) {
- qmlInfo(this) << "Canvas already initialized with a different context type";
+ qmlWarning(this) << "Canvas already initialized with a different context type";
return;
}
@@ -517,7 +517,7 @@ void QQuickCanvasItem::setRenderTarget(QQuickCanvasItem::RenderTarget target)
Q_D(QQuickCanvasItem);
if (d->renderTarget != target) {
if (d->context) {
- qmlInfo(this) << "Canvas:renderTarget not changeble once context is active.";
+ qmlWarning(this) << "Canvas:renderTarget not changeble once context is active.";
return;
}
@@ -561,7 +561,7 @@ void QQuickCanvasItem::setRenderStrategy(QQuickCanvasItem::RenderStrategy strate
Q_D(QQuickCanvasItem);
if (d->renderStrategy != strategy) {
if (d->context) {
- qmlInfo(this) << "Canvas:renderStrategy not changeable once context is active.";
+ qmlWarning(this) << "Canvas:renderStrategy not changeable once context is active.";
return;
}
d->renderStrategy = strategy;
@@ -766,7 +766,6 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
if (!texture) {
delete node;
d->node = 0;
- delete d->nodeTexture;
d->nodeTexture = 0;
if (d->textureProvider) {
d->textureProvider->tex = 0;
@@ -840,13 +839,13 @@ void QQuickCanvasItem::getContext(QQmlV4Function *args)
QV4::Scope scope(args->v4engine());
QV4::ScopedString str(scope, (*args)[0]);
if (!str) {
- qmlInfo(this) << "getContext should be called with a string naming the required context type";
+ qmlWarning(this) << "getContext should be called with a string naming the required context type";
args->setReturnValue(QV4::Encode::null());
return;
}
if (!d->available) {
- qmlInfo(this) << "Unable to use getContext() at this time, please wait for available: true";
+ qmlWarning(this) << "Unable to use getContext() at this time, please wait for available: true";
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -859,7 +858,7 @@ void QQuickCanvasItem::getContext(QQmlV4Function *args)
return;
}
- qmlInfo(this) << "Canvas already initialized with a different context type";
+ qmlWarning(this) << "Canvas already initialized with a different context type";
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -882,7 +881,7 @@ void QQuickCanvasItem::requestAnimationFrame(QQmlV4Function *args)
QV4::Scope scope(args->v4engine());
QV4::ScopedFunctionObject f(scope, (*args)[0]);
if (!f) {
- qmlInfo(this) << "requestAnimationFrame should be called with an animation callback function";
+ qmlWarning(this) << "requestAnimationFrame should be called with an animation callback function";
args->setReturnValue(QV4::Encode::null());
return;
}
@@ -910,7 +909,7 @@ void QQuickCanvasItem::cancelRequestAnimationFrame(QQmlV4Function *args)
QV4::Scope scope(args->v4engine());
QV4::ScopedValue v(scope, (*args)[0]);
if (!v->isInteger()) {
- qmlInfo(this) << "cancelRequestAnimationFrame should be called with an animation callback id";
+ qmlWarning(this) << "cancelRequestAnimationFrame should be called with an animation callback id";
args->setReturnValue(QV4::Encode::null());
return;
}
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index bcaedd67b4..b0c1d50907 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -129,10 +129,10 @@ Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
#define DEGREES(t) ((t) * 180.0 / M_PI)
#define CHECK_CONTEXT(r) if (!r || !r->d()->context || !r->d()->context->bufferValid()) \
- V4THROW_ERROR("Not a Context2D object");
+ THROW_GENERIC_ERROR("Not a Context2D object");
#define CHECK_CONTEXT_SETTER(r) if (!r || !r->d()->context || !r->d()->context->bufferValid()) \
- V4THROW_ERROR("Not a Context2D object");
+ THROW_GENERIC_ERROR("Not a Context2D object");
#define qClamp(val, min, max) qMin(qMax(val, min), max)
#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0 && c <= 9))
QColor qt_color_from_string(const QV4::Value &name)
@@ -537,45 +537,45 @@ struct QQuickJSContext2D : public QV4::Object
{
V4_OBJECT2(QQuickJSContext2D, QV4::Object)
- static QV4::ReturnedValue method_get_globalAlpha(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_globalAlpha(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_globalCompositeOperation(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_globalCompositeOperation(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_fillStyle(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_fillStyle(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_fillRule(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_fillRule(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_strokeStyle(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_strokeStyle(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_lineCap(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_lineCap(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_lineJoin(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_lineJoin(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_lineWidth(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_lineWidth(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_miterLimit(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_miterLimit(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_shadowBlur(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_shadowBlur(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_shadowColor(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_shadowColor(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_shadowOffsetX(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_shadowOffsetX(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_shadowOffsetY(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_shadowOffsetY(QV4::CallContext *ctx);
+ static void method_get_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
// should these two be on the proto?
- static QV4::ReturnedValue method_get_path(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_path(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_font(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_font(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_textAlign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_textAlign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_textBaseline(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_textBaseline(QV4::CallContext *ctx);
+ 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);
+
+ 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);
+ static void method_set_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
DEFINE_OBJECT_VTABLE(QQuickJSContext2D);
@@ -638,50 +638,50 @@ public:
return o->d();
}
- static QV4::ReturnedValue method_get_canvas(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_restore(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_reset(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_save(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_rotate(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_scale(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_translate(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_setTransform(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_transform(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_resetTransform(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_shear(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createLinearGradient(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createRadialGradient(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createConicalGradient(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createPattern(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_clearRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fillRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_strokeRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_arc(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_arcTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_beginPath(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_bezierCurveTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_clip(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_closePath(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fill(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_lineTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_moveTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_quadraticCurveTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_rect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_roundedRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_ellipse(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_text(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_stroke(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_isPointInPath(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_drawFocusRing(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_setCaretSelectionRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_caretBlinkRate(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fillText(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_strokeText(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_measureText(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_drawImage(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createImageData(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_getImageData(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_putImageData(QV4::CallContext *ctx);
+ static void method_get_canvas(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_restore(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_reset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_save(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_rotate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_scale(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_translate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_setTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_transform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_resetTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_shear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createLinearGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createRadialGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createConicalGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_clearRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fillRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_strokeRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_arc(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_arcTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_beginPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_bezierCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_clip(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_closePath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fill(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_lineTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_moveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_quadraticCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_rect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_roundedRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_ellipse(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_text(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_stroke(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_isPointInPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_drawFocusRing(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_setCaretSelectionRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_caretBlinkRate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fillText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_strokeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_measureText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_drawImage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_getImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_putImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
@@ -693,7 +693,7 @@ struct QQuickContext2DStyle : public QV4::Object
V4_OBJECT2(QQuickContext2DStyle, QV4::Object)
V4_NEEDS_DESTROY
- static QV4::ReturnedValue gradient_proto_addColorStop(QV4::CallContext *ctx);
+ static void gradient_proto_addColorStop(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
@@ -903,7 +903,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object
static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty);
static void putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
- static QV4::ReturnedValue proto_get_length(QV4::CallContext *ctx);
+ static void proto_get_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
void QV4::Heap::QQuickJSContext2DPixelData::init()
@@ -921,9 +921,9 @@ struct QQuickJSContext2DImageData : public QV4::Object
{
V4_OBJECT2(QQuickJSContext2DImageData, QV4::Object)
- static QV4::ReturnedValue method_get_width(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_height(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_data(QV4::CallContext *ctx);
+ static void method_get_width(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_height(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_data(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *engine) {
static_cast<QQuickJSContext2DImageData::Data *>(that)->pixelData.mark(engine);
@@ -975,13 +975,12 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE
This property is read only.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_get_canvas(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- return QV4::QObjectWrapper::wrap(scope.engine, r->d()->context->canvas());
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, r->d()->context->canvas());
}
/*!
@@ -990,29 +989,27 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(QV4::CallContex
\sa save()
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_restore(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_restore(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->popState();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject.asReturnedValue();
}
/*!
\qmlmethod object QtQuick::Context2D::reset()
Resets the context state and properties to the default values.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_reset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->reset();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject.asReturnedValue();
}
/*!
@@ -1045,15 +1042,14 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(QV4::CallContext *ct
The current path is NOT part of the drawing state. The path can be reset by
invoking the beginPath() method.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_save(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->pushState();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
// transformations
@@ -1074,15 +1070,14 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(QV4::CallContext *ctx
where the \a angle of rotation is in radians.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_rotate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 1)
- r->d()->context->rotate(ctx->args()[0].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 1)
+ r->d()->context->rotate(callData->args[0].toNumber());
+ scope.result = callData->thisObject;
}
/*!
@@ -1102,16 +1097,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(QV4::CallContext *c
\image qml-item-canvas-scale.png
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_scale(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2)
- r->d()->context->scale(ctx->args()[0].toNumber(), ctx->args()[1].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 2)
+ r->d()->context->scale(callData->args[0].toNumber(), callData->args[1].toNumber());
+ scope.result = callData->thisObject;
+
}
/*!
@@ -1148,22 +1143,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(QV4::CallContext *ct
\sa transform()
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_setTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 6)
- r->d()->context->setTransform( ctx->args()[0].toNumber()
- , ctx->args()[1].toNumber()
- , ctx->args()[2].toNumber()
- , ctx->args()[3].toNumber()
- , ctx->args()[4].toNumber()
- , ctx->args()[5].toNumber());
+ if (callData->argc >= 6)
+ r->d()->context->setTransform( callData->args[0].toNumber()
+ , callData->args[1].toNumber()
+ , callData->args[2].toNumber()
+ , callData->args[3].toNumber()
+ , callData->args[4].toNumber()
+ , callData->args[5].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -1177,21 +1172,21 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(QV4::CallCont
\sa setTransform()
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_transform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 6)
- r->d()->context->transform( ctx->args()[0].toNumber()
- , ctx->args()[1].toNumber()
- , ctx->args()[2].toNumber()
- , ctx->args()[3].toNumber()
- , ctx->args()[4].toNumber()
- , ctx->args()[5].toNumber());
+ if (callData->argc >= 6)
+ r->d()->context->transform( callData->args[0].toNumber()
+ , callData->args[1].toNumber()
+ , callData->args[2].toNumber()
+ , callData->args[3].toNumber()
+ , callData->args[4].toNumber()
+ , callData->args[5].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -1203,15 +1198,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(QV4::CallContext
Translating the origin enables you to draw patterns of different objects on the canvas
without having to measure the coordinates manually for each shape.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_translate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2)
- r->d()->context->translate(ctx->args()[0].toNumber(), ctx->args()[1].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 2)
+ r->d()->context->translate(callData->args[0].toNumber(), callData->args[1].toNumber());
+ scope.result = callData->thisObject;
+
}
@@ -1223,15 +1218,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(QV4::CallContext
\sa transform(), setTransform(), reset()
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_resetTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->setTransform(1, 0, 0, 1, 0, 0);
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
@@ -1241,16 +1236,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(QV4::CallCo
Shears the transformation matrix by \a sh in the horizontal direction and
\a sv in the vertical direction.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_shear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2)
- r->d()->context->shear(ctx->args()[0].toNumber(), ctx->args()[1].toNumber());
+ if (callData->argc >= 2)
+ r->d()->context->shear(callData->args[0].toNumber(), callData->args[1].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
// compositing
@@ -1261,31 +1256,30 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(QV4::CallContext *ct
The value must be in the range from \c 0.0 (fully transparent) to \c 1.0 (fully opaque).
The default value is \c 1.0.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_globalAlpha(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.globalAlpha);
+ scope.result = QV4::Encode(r->d()->context->state.globalAlpha);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- double globalAlpha = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double globalAlpha = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+
+ scope.result = QV4::Encode::undefined();
if (!qt_is_finite(globalAlpha))
- return QV4::Encode::undefined();
+ return;
if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->d()->context->state.globalAlpha != globalAlpha) {
r->d()->context->state.globalAlpha = globalAlpha;
r->d()->context->buffer()->setGlobalAlpha(r->d()->context->state.globalAlpha);
}
- return QV4::Encode::undefined();
}
/*!
@@ -1314,34 +1308,33 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(QV4::CallContext *c
extension composition modes are provided as "vendorName-operationName" syntax, for example: QPainter::CompositionMode_Exclusion is provided as
"qt-exclusion".
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_globalCompositeOperation(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- return QV4::Encode(scope.engine->newString(qt_composite_mode_to_string(r->d()->context->state.globalCompositeOperation)));
+ scope.result = scope.engine->newString(qt_composite_mode_to_string(r->d()->context->state.globalCompositeOperation));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- if (!ctx->argc())
- return ctx->engine()->throwTypeError();
+ if (!callData->argc)
+ THROW_TYPE_ERROR();
- QString mode = ctx->args()[0].toQString();
+ scope.result = QV4::Encode::undefined();
+
+ QString mode = callData->args[0].toQString();
QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
if (cm == QPainter::CompositionMode_SourceOver && mode != QLatin1String("source-over"))
- return QV4::Encode::undefined();
+ return;
if (cm != r->d()->context->state.globalCompositeOperation) {
r->d()->context->state.globalCompositeOperation = cm;
r->d()->context->buffer()->setGlobalCompositeOperation(cm);
}
- return QV4::Encode::undefined();
}
// colors and styles
@@ -1367,34 +1360,32 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(QV4::C
\sa createPattern()
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_fillStyle(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
QColor color = r->d()->context->state.fillStyle.color();
if (color.isValid()) {
if (color.alpha() == 255)
- return QV4::Encode(scope.engine->newString(color.name()));
+ RETURN_RESULT(scope.engine->newString(color.name()));
QString alphaString = QString::number(color.alphaF(), 'f');
while (alphaString.endsWith(QLatin1Char('0')))
alphaString.chop(1);
if (alphaString.endsWith(QLatin1Char('.')))
alphaString += QLatin1Char('0');
QString str = QString::fromLatin1("rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
- return QV4::Encode(scope.engine->newString(str));
+ RETURN_RESULT(scope.engine->newString(str));
}
- return r->d()->context->m_fillStyle.value();
+ scope.result = r->d()->context->m_fillStyle.value();
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, ctx->argument(0));
+ QV4::ScopedValue value(scope, callData->argument(0));
if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
@@ -1420,7 +1411,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx
r->d()->context->m_fillStyle.set(scope.engine, value);
}
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
/*!
\qmlproperty enumeration QtQuick::Context2D::fillRule
@@ -1434,22 +1425,20 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- return scope.engine->fromVariant(r->d()->context->state.fillRule);
+ scope.result = scope.engine->fromVariant(r->d()->context->state.fillRule);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, ctx->argument(0));
+ QV4::ScopedValue value(scope, callData->argument(0));
if ((value->isString() && value->toQString() == QLatin1String("WindingFill"))
|| (value->isInt32() && value->integerValue() == Qt::WindingFill)) {
@@ -1461,7 +1450,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::CallContext *ctx)
//error
}
r->d()->context->m_path.setFillRule(r->d()->context->state.fillRule);
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
/*!
\qmlproperty variant QtQuick::Context2D::strokeStyle
@@ -1476,34 +1465,32 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::CallContext *ctx)
\sa createPattern()
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_strokeStyle(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
QColor color = r->d()->context->state.strokeStyle.color();
if (color.isValid()) {
if (color.alpha() == 255)
- return QV4::Encode(scope.engine->newString(color.name()));
+ RETURN_RESULT(scope.engine->newString(color.name()));
QString alphaString = QString::number(color.alphaF(), 'f');
while (alphaString.endsWith(QLatin1Char('0')))
alphaString.chop(1);
if (alphaString.endsWith(QLatin1Char('.')))
alphaString += QLatin1Char('0');
QString str = QString::fromLatin1("rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
- return QV4::Encode(scope.engine->newString(str));
+ RETURN_RESULT(scope.engine->newString(str));
}
- return r->d()->context->m_strokeStyle.value();
+ scope.result = r->d()->context->m_strokeStyle.value();
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, ctx->argument(0));
+ QV4::ScopedValue value(scope, callData->argument(0));
if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
@@ -1530,7 +1517,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *c
r->d()->context->m_strokeStyle.set(scope.engine, value);
}
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
/*!
@@ -1550,23 +1537,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *c
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createLinearGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4) {
- qreal x0 = ctx->args()[0].toNumber();
- qreal y0 = ctx->args()[1].toNumber();
- qreal x1 = ctx->args()[2].toNumber();
- qreal y1 = ctx->args()[3].toNumber();
+ if (callData->argc >= 4) {
+ qreal x0 = callData->args[0].toNumber();
+ qreal y0 = callData->args[1].toNumber();
+ qreal x1 = callData->args[2].toNumber();
+ qreal y1 = callData->args[3].toNumber();
if (!qt_is_finite(x0)
|| !qt_is_finite(y0)
|| !qt_is_finite(x1)
|| !qt_is_finite(y1)) {
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createLinearGradient(): Incorrect arguments")
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createLinearGradient(): Incorrect arguments")
}
QQuickContext2DEngineData *ed = engineData(scope.engine);
@@ -1574,10 +1560,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
*gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
- return gradient.asReturnedValue();
+ RETURN_RESULT(gradient);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -1593,19 +1580,18 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createRadialGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 6) {
- qreal x0 = ctx->args()[0].toNumber();
- qreal y0 = ctx->args()[1].toNumber();
- qreal r0 = ctx->args()[2].toNumber();
- qreal x1 = ctx->args()[3].toNumber();
- qreal y1 = ctx->args()[4].toNumber();
- qreal r1 = ctx->args()[5].toNumber();
+ if (callData->argc >= 6) {
+ qreal x0 = callData->args[0].toNumber();
+ qreal y0 = callData->args[1].toNumber();
+ qreal r0 = callData->args[2].toNumber();
+ qreal x1 = callData->args[3].toNumber();
+ qreal y1 = callData->args[4].toNumber();
+ qreal r1 = callData->args[5].toNumber();
if (!qt_is_finite(x0)
|| !qt_is_finite(y0)
@@ -1613,11 +1599,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
|| !qt_is_finite(r0)
|| !qt_is_finite(r1)
|| !qt_is_finite(y1)) {
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createRadialGradient(): Incorrect arguments")
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createRadialGradient(): Incorrect arguments")
}
if (r0 < 0 || r1 < 0)
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createRadialGradient(): Incorrect arguments")
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createRadialGradient(): Incorrect arguments")
QQuickContext2DEngineData *ed = engineData(scope.engine);
@@ -1625,10 +1611,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
*gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
- return gradient.asReturnedValue();
+ RETURN_RESULT(gradient);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -1644,22 +1631,21 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createConicalGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 3) {
- qreal x = ctx->args()[0].toNumber();
- qreal y = ctx->args()[1].toNumber();
- qreal angle = DEGREES(ctx->args()[2].toNumber());
+ if (callData->argc >= 3) {
+ qreal x = callData->args[0].toNumber();
+ qreal y = callData->args[1].toNumber();
+ qreal angle = DEGREES(callData->args[2].toNumber());
if (!qt_is_finite(x) || !qt_is_finite(y)) {
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createConicalGradient(): Incorrect arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createConicalGradient(): Incorrect arguments");
}
if (!qt_is_finite(angle)) {
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createConicalGradient(): Incorrect arguments");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createConicalGradient(): Incorrect arguments");
}
QQuickContext2DEngineData *ed = engineData(scope.engine);
@@ -1668,10 +1654,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4:
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
*gradient->d()->brush = QConicalGradient(x, y, angle);
- return gradient.asReturnedValue();
+ RETURN_RESULT(gradient);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
\qmlmethod variant QtQuick::Context2D::createPattern(color color, enumeration patternMode)
@@ -1716,18 +1703,17 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4:
\sa strokeStyle
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2) {
+ if (callData->argc >= 2) {
QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
- QColor color = scope.engine->toVariant(ctx->args()[0], qMetaTypeId<QColor>()).value<QColor>();
+ QColor color = scope.engine->toVariant(callData->args[0], qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
- int patternMode = ctx->args()[1].toInt32();
+ int patternMode = callData->args[1].toInt32();
Qt::BrushStyle style = Qt::SolidPattern;
if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) {
style = static_cast<Qt::BrushStyle>(patternMode);
@@ -1736,20 +1722,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
} else {
QImage patternTexture;
- if (const QV4::Object *o = ctx->args()[0].as<Object>()) {
+ if (const QV4::Object *o = callData->args[0].as<Object>()) {
QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral("data")));
QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
if (!!pixelData) {
patternTexture = *pixelData->d()->image;
}
} else {
- patternTexture = r->d()->context->createPixmap(QUrl(ctx->args()[0].toQStringNoThrow()))->image();
+ patternTexture = r->d()->context->createPixmap(QUrl(callData->args[0].toQStringNoThrow()))->image();
}
if (!patternTexture.isNull()) {
pattern->d()->brush->setTextureImage(patternTexture);
- QString repetition = ctx->args()[1].toQStringNoThrow();
+ QString repetition = callData->args[1].toQStringNoThrow();
if (repetition == QLatin1String("repeat") || repetition.isEmpty()) {
pattern->d()->patternRepeatX = true;
pattern->d()->patternRepeatY = true;
@@ -1769,10 +1755,10 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
}
}
- return pattern.asReturnedValue();
+ RETURN_RESULT(pattern);
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
// line styles
@@ -1787,31 +1773,29 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
\endlist
Other values are ignored.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.lineCap) {
case Qt::RoundCap:
- return QV4::Encode(scope.engine->newString(QStringLiteral("round")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("round")));
case Qt::SquareCap:
- return QV4::Encode(scope.engine->newString(QStringLiteral("square")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("square")));
case Qt::FlatCap:
default:
break;
}
- return QV4::Encode(scope.engine->newString(QStringLiteral("butt")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("butt")));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QString lineCap = ctx->args()[0].toQString();
+ QString lineCap = callData->args[0].toQString();
Qt::PenCapStyle cap;
if (lineCap == QLatin1String("round"))
cap = Qt::RoundCap;
@@ -1820,13 +1804,13 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(QV4::CallContext *ctx)
else if (lineCap == QLatin1String("square"))
cap = Qt::SquareCap;
else
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
if (cap != r->d()->context->state.lineCap) {
r->d()->context->state.lineCap = cap;
r->d()->context->buffer()->setLineCap(cap);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -1843,34 +1827,32 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(QV4::CallContext *ctx)
\endlist
Other values are ignored.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.lineJoin) {
case Qt::RoundJoin:
- return QV4::Encode(scope.engine->newString(QStringLiteral("round")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("round")));
case Qt::BevelJoin:
- return QV4::Encode(scope.engine->newString(QStringLiteral("bevel")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("bevel")));
case Qt::MiterJoin:
default:
break;
}
- return QV4::Encode(scope.engine->newString(QStringLiteral("miter")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("miter")));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- if (!ctx->argc())
- return ctx->engine()->throwTypeError();
+ if (!callData->argc)
+ THROW_TYPE_ERROR();
- QString lineJoin = ctx->args()[0].toQString();
+ QString lineJoin = callData->args[0].toQString();
Qt::PenJoinStyle join;
if (lineJoin == QLatin1String("round"))
join = Qt::RoundJoin;
@@ -1879,41 +1861,39 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(QV4::CallContext *ctx)
else if (lineJoin == QLatin1String("miter"))
join = Qt::SvgMiterJoin;
else
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
if (join != r->d()->context->state.lineJoin) {
r->d()->context->state.lineJoin = join;
r->d()->context->buffer()->setLineJoin(join);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlproperty real QtQuick::Context2D::lineWidth
Holds the current line width. Values that are not finite values greater than zero are ignored.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_lineWidth(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.lineWidth);
+ RETURN_RESULT(r->d()->context->state.lineWidth);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal w = ctx->argc() ? ctx->args()[0].toNumber() : -1;
+ qreal w = callData->argc ? callData->args[0].toNumber() : -1;
if (w > 0 && qt_is_finite(w) && w != r->d()->context->state.lineWidth) {
r->d()->context->state.lineWidth = w;
r->d()->context->buffer()->setLineWidth(w);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -1921,28 +1901,26 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(QV4::CallContext *ctx
Holds the current miter limit ratio.
The default miter limit value is 10.0.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_miterLimit(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.miterLimit);
+ RETURN_RESULT(r->d()->context->state.miterLimit);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal ml = ctx->argc() ? ctx->args()[0].toNumber() : -1;
+ qreal ml = callData->argc ? callData->args[0].toNumber() : -1;
if (ml > 0 && qt_is_finite(ml) && ml != r->d()->context->state.miterLimit) {
r->d()->context->state.miterLimit = ml;
r->d()->context->buffer()->setMiterLimit(ml);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
// shadows
@@ -1950,58 +1928,54 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(QV4::CallContext *ct
\qmlproperty real QtQuick::Context2D::shadowBlur
Holds the current level of blur applied to shadows
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_shadowBlur(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.shadowBlur);
+ RETURN_RESULT(r->d()->context->state.shadowBlur);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_shadowBlur(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal blur = ctx->argc() ? ctx->args()[0].toNumber() : -1;
+ qreal blur = callData->argc ? callData->args[0].toNumber() : -1;
if (blur > 0 && qt_is_finite(blur) && blur != r->d()->context->state.shadowBlur) {
r->d()->context->state.shadowBlur = blur;
r->d()->context->buffer()->setShadowBlur(blur);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlproperty string QtQuick::Context2D::shadowColor
Holds the current shadow color.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_shadowColor(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(scope.engine->newString(r->d()->context->state.shadowColor.name()));
+ RETURN_RESULT(scope.engine->newString(r->d()->context->state.shadowColor.name()));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
QColor color;
- if (ctx->argc())
- color = qt_color_from_string(ctx->args()[0]);
+ if (callData->argc)
+ color = qt_color_from_string(callData->args[0]);
if (color.isValid() && color != r->d()->context->state.shadowColor) {
r->d()->context->state.shadowColor = color;
r->d()->context->buffer()->setShadowColor(color);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
@@ -2011,27 +1985,25 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(QV4::CallContext *c
\sa shadowOffsetY
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetX(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.shadowOffsetX);
+ RETURN_RESULT(r->d()->context->state.shadowOffsetX);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal offsetX = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ qreal offsetX = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (qt_is_finite(offsetX) && offsetX != r->d()->context->state.shadowOffsetX) {
r->d()->context->state.shadowOffsetX = offsetX;
r->d()->context->buffer()->setShadowOffsetX(offsetX);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlproperty qreal QtQuick::Context2D::shadowOffsetY
@@ -2039,45 +2011,41 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(QV4::CallContext
\sa shadowOffsetX
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetY(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.shadowOffsetY);
+ RETURN_RESULT(r->d()->context->state.shadowOffsetY);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal offsetY = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ qreal offsetY = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (qt_is_finite(offsetY) && offsetY != r->d()->context->state.shadowOffsetY) {
r->d()->context->state.shadowOffsetY = offsetY;
r->d()->context->buffer()->setShadowOffsetY(offsetY);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
-QV4::ReturnedValue QQuickJSContext2D::method_get_path(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return r->d()->context->m_v4path.value();
+ scope.result = r->d()->context->m_v4path.value();
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, ctx->argument(0));
+ QV4::ScopedValue value(scope, callData->argument(0));
r->d()->context->beginPath();
QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value);
if (!!qobjectWrapper) {
@@ -2088,7 +2056,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::CallContext *ctx)
QQuickSvgParser::parsePathDataFast(path, r->d()->context->m_path);
}
r->d()->context->m_v4path.set(scope.engine, value);
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
//rects
@@ -2096,20 +2064,20 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::CallContext *ctx)
\qmlmethod object QtQuick::Context2D::clearRect(real x, real y, real w, real h)
Clears all pixels on the canvas in the given rectangle to transparent black.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_clearRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->clearRect(ctx->args()[0].toNumber(),
- ctx->args()[1].toNumber(),
- ctx->args()[2].toNumber(),
- ctx->args()[3].toNumber());
+ if (callData->argc >= 4)
+ r->d()->context->clearRect(callData->args[0].toNumber(),
+ callData->args[1].toNumber(),
+ callData->args[2].toNumber(),
+ callData->args[3].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
/*!
\qmlmethod object QtQuick::Context2D::fillRect(real x, real y, real w, real h)
@@ -2117,15 +2085,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(QV4::CallContext
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_fillRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->fillRect(ctx->args()[0].toNumber(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), ctx->args()[3].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 4)
+ r->d()->context->fillRect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2138,16 +2106,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(QV4::CallContext
\sa lineJoin
\sa miterLimit
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_strokeRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->strokeRect(ctx->args()[0].toNumber(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), ctx->args()[3].toNumber());
+ if (callData->argc >= 4)
+ r->d()->context->strokeRect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
// Complex shapes (paths) API
@@ -2171,32 +2139,32 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(QV4::CallContex
\sa arcTo, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arc}{W3C's 2D
Context Standard for arc()}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_arc(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 5) {
+ if (callData->argc >= 5) {
bool antiClockwise = false;
- if (ctx->argc() == 6)
- antiClockwise = ctx->args()[5].toBoolean();
+ if (callData->argc == 6)
+ antiClockwise = callData->args[5].toBoolean();
- qreal radius = ctx->args()[2].toNumber();
+ qreal radius = callData->args[2].toNumber();
if (qt_is_finite(radius) && radius < 0)
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
- r->d()->context->arc(ctx->args()[0].toNumber(),
- ctx->args()[1].toNumber(),
+ r->d()->context->arc(callData->args[0].toNumber(),
+ callData->args[1].toNumber(),
radius,
- ctx->args()[3].toNumber(),
- ctx->args()[4].toNumber(),
+ callData->args[3].toNumber(),
+ callData->args[4].toNumber(),
antiClockwise);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2222,26 +2190,26 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(QV4::CallContext *ctx)
\sa arc, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arcto}{W3C's 2D
Context Standard for arcTo()}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_arcTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 5) {
- qreal radius = ctx->args()[4].toNumber();
+ if (callData->argc >= 5) {
+ qreal radius = callData->args[4].toNumber();
if (qt_is_finite(radius) && radius < 0)
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
- r->d()->context->arcTo(ctx->args()[0].toNumber(),
- ctx->args()[1].toNumber(),
- ctx->args()[2].toNumber(),
- ctx->args()[3].toNumber(),
+ r->d()->context->arcTo(callData->args[0].toNumber(),
+ callData->args[1].toNumber(),
+ callData->args[2].toNumber(),
+ callData->args[3].toNumber(),
radius);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2249,15 +2217,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(QV4::CallContext *ct
Resets the current path to a new path.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_beginPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
r->d()->context->beginPath();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2279,28 +2247,26 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(QV4::CallContext
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-beziercurveto}{W3C 2d context standard for bezierCurveTo}
\sa {http://www.openrise.com/lab/FlowerPower/}{The beautiful flower demo by using bezierCurveTo}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_bezierCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
+ scope.result = callData->thisObject;
- if (ctx->argc() >= 6) {
- qreal cp1x = ctx->args()[0].toNumber();
- qreal cp1y = ctx->args()[1].toNumber();
- qreal cp2x = ctx->args()[2].toNumber();
- qreal cp2y = ctx->args()[3].toNumber();
- qreal x = ctx->args()[4].toNumber();
- qreal y = ctx->args()[5].toNumber();
+ if (callData->argc >= 6) {
+ qreal cp1x = callData->args[0].toNumber();
+ qreal cp1y = callData->args[1].toNumber();
+ qreal cp2x = callData->args[2].toNumber();
+ qreal cp2y = callData->args[3].toNumber();
+ qreal x = callData->args[4].toNumber();
+ qreal y = callData->args[5].toNumber();
if (!qt_is_finite(cp1x) || !qt_is_finite(cp1y) || !qt_is_finite(cp2x) || !qt_is_finite(cp2y) || !qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
+ return;
r->d()->context->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
}
-
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2327,14 +2293,13 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::CallCon
\sa fill()
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-clip}{W3C 2d context standard for clip}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_clip(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
r->d()->context->clip();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
/*!
@@ -2344,16 +2309,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(QV4::CallContext *ctx
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-closepath}{W3C 2d context standard for closePath}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_closePath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
r->d()->context->closePath();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
/*!
@@ -2365,13 +2329,12 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(QV4::CallContext
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_fill(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r);
r->d()->context->fill();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
/*!
@@ -2379,24 +2342,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(QV4::CallContext *ctx
Draws a line from the current position to the point (x, y).
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_lineTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
+ scope.result = callData->thisObject;
- if (ctx->argc() >= 2) {
- qreal x = ctx->args()[0].toNumber();
- qreal y = ctx->args()[1].toNumber();
+ if (callData->argc >= 2) {
+ qreal x = callData->args[0].toNumber();
+ qreal y = callData->args[1].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
+ return;
r->d()->context->lineTo(x, y);
}
-
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2404,21 +2365,21 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(QV4::CallContext *c
Creates a new subpath with the given point.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_moveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2) {
- qreal x = ctx->args()[0].toNumber();
- qreal y = ctx->args()[1].toNumber();
+ scope.result = callData->thisObject;
+
+ if (callData->argc >= 2) {
+ qreal x = callData->args[0].toNumber();
+ qreal y = callData->args[1].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
+ return;
r->d()->context->moveTo(x, y);
}
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2428,25 +2389,24 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(QV4::CallContext *c
See \l{http://www.w3.org/TR/2dcontext/#dom-context-2d-quadraticcurveto}{W3C 2d context standard for quadraticCurveTo}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_quadraticCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4) {
- qreal cpx = ctx->args()[0].toNumber();
- qreal cpy = ctx->args()[1].toNumber();
- qreal x = ctx->args()[2].toNumber();
- qreal y = ctx->args()[3].toNumber();
+ scope.result = callData->thisObject;
+
+ if (callData->argc >= 4) {
+ qreal cpx = callData->args[0].toNumber();
+ qreal cpy = callData->args[1].toNumber();
+ qreal x = callData->args[2].toNumber();
+ qreal y = callData->args[3].toNumber();
if (!qt_is_finite(cpx) || !qt_is_finite(cpy) || !qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
+ return;
r->d()->context->quadraticCurveTo(cpx, cpy, x, y);
}
-
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2454,15 +2414,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(QV4::Call
Adds a rectangle at position (\c x, \c y), with the given width \c w and height \c h, as a closed subpath.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_rect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->rect(ctx->args()[0].toNumber(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), ctx->args()[3].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 4)
+ r->d()->context->rect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2471,20 +2431,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(QV4::CallContext *ctx
Adds the given rectangle rect with rounded corners to the path. The \c xRadius and \c yRadius arguments specify the radius of the
ellipses defining the corners of the rounded rectangle.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_roundedRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 6)
- r->d()->context->roundedRect(ctx->args()[0].toNumber()
- , ctx->args()[1].toNumber()
- , ctx->args()[2].toNumber()
- , ctx->args()[3].toNumber()
- , ctx->args()[4].toNumber()
- , ctx->args()[5].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 6)
+ r->d()->context->roundedRect(callData->args[0].toNumber()
+ , callData->args[1].toNumber()
+ , callData->args[2].toNumber()
+ , callData->args[3].toNumber()
+ , callData->args[4].toNumber()
+ , callData->args[5].toNumber());
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2495,17 +2455,17 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(QV4::CallConte
The ellipse is composed of a clockwise curve, starting and finishing at zero degrees (the 3 o'clock position).
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_ellipse(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->ellipse(ctx->args()[0].toNumber(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), ctx->args()[3].toNumber());
+ if (callData->argc >= 4)
+ r->d()->context->ellipse(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2514,21 +2474,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(QV4::CallContext *
Adds the given \c text to the path as a set of closed subpaths created from the current context font supplied.
The subpaths are positioned so that the left end of the text's baseline lies at the point specified by (\c x, \c y).
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_text(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 3) {
- qreal x = ctx->args()[1].toNumber();
- qreal y = ctx->args()[2].toNumber();
+ scope.result = callData->thisObject;
+
+ if (callData->argc >= 3) {
+ qreal x = callData->args[1].toNumber();
+ qreal y = callData->args[2].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
- r->d()->context->text(ctx->args()[0].toQStringNoThrow(), x, y);
+ return;
+ r->d()->context->text(callData->args[0].toQStringNoThrow(), x, y);
}
- return ctx->thisObject().asReturnedValue();
+
}
/*!
@@ -2540,14 +2501,14 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(QV4::CallContext *ctx
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_stroke(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
r->d()->context->stroke();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2557,37 +2518,30 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(QV4::CallContext *c
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath}{W3C 2d context standard for isPointInPath}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_isPointInPath(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_isPointInPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
bool pointInPath = false;
- if (ctx->argc() >= 2)
- pointInPath = r->d()->context->isPointInPath(ctx->args()[0].toNumber(), ctx->args()[1].toNumber());
- return QV4::Primitive::fromBoolean(pointInPath).asReturnedValue();
+ if (callData->argc >= 2)
+ pointInPath = r->d()->context->isPointInPath(callData->args[0].toNumber(), callData->args[1].toNumber());
+ scope.result = QV4::Primitive::fromBoolean(pointInPath).asReturnedValue();
}
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawFocusRing(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_drawFocusRing(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
{
- QV4::Scope scope(ctx);
-
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::drawFocusRing is not supported");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::drawFocusRing is not supported");
}
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_setCaretSelectionRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_setCaretSelectionRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
{
- QV4::Scope scope(ctx);
-
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::setCaretSelectionRect is not supported");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::setCaretSelectionRect is not supported");
}
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_caretBlinkRate(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_caretBlinkRate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
{
- QV4::Scope scope(ctx);
-
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
}
/*!
@@ -2613,29 +2567,27 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_caretBlinkRate(QV4::CallCo
The default font value is "10px sans-serif".
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_font(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(scope.engine->newString(r->d()->context->state.font.toString()));
+ RETURN_RESULT(scope.engine->newString(r->d()->context->state.font.toString()));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_font(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedString s(scope, ctx->argument(0), QV4::ScopedString::Convert);
+ QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert);
if (scope.engine->hasException)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
QFont font = qt_font_from_string(s->toQString(), r->d()->context->state.font);
if (font != r->d()->context->state.font) {
r->d()->context->state.font = font;
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -2652,37 +2604,35 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_font(QV4::CallContext *ctx)
\endlist
Other values are ignored. The default value is "start".
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_textAlign(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.textAlign) {
case QQuickContext2D::End:
- return QV4::Encode(scope.engine->newString(QStringLiteral("end")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("end")));
case QQuickContext2D::Left:
- return QV4::Encode(scope.engine->newString(QStringLiteral("left")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("left")));
case QQuickContext2D::Right:
- return QV4::Encode(scope.engine->newString(QStringLiteral("right")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("right")));
case QQuickContext2D::Center:
- return QV4::Encode(scope.engine->newString(QStringLiteral("center")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("center")));
case QQuickContext2D::Start:
default:
break;
}
- return QV4::Encode(scope.engine->newString(QStringLiteral("start")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("start")));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedString s(scope, ctx->argument(0), QV4::ScopedString::Convert);
+ QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert);
if (scope.engine->hasException)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
QString textAlign = s->toQString();
QQuickContext2D::TextAlignType ta;
@@ -2697,12 +2647,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(QV4::CallContext *ctx
else if (textAlign == QLatin1String("center"))
ta = QQuickContext2D::Center;
else
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
if (ta != r->d()->context->state.textAlign)
r->d()->context->state.textAlign = ta;
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -2720,36 +2670,34 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(QV4::CallContext *ctx
\endlist
Other values are ignored. The default value is "alphabetic".
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_textBaseline(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.textBaseline) {
case QQuickContext2D::Hanging:
- return QV4::Encode(scope.engine->newString(QStringLiteral("hanging")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("hanging")));
case QQuickContext2D::Top:
- return QV4::Encode(scope.engine->newString(QStringLiteral("top")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("top")));
case QQuickContext2D::Bottom:
- return QV4::Encode(scope.engine->newString(QStringLiteral("bottom")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("bottom")));
case QQuickContext2D::Middle:
- return QV4::Encode(scope.engine->newString(QStringLiteral("middle")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("middle")));
case QQuickContext2D::Alphabetic:
default:
break;
}
- return QV4::Encode(scope.engine->newString(QStringLiteral("alphabetic")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("alphabetic")));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedString s(scope, ctx->argument(0), QV4::ScopedString::Convert);
+ QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert);
if (scope.engine->hasException)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
QString textBaseline = s->toQString();
QQuickContext2D::TextBaseLineType tb;
@@ -2764,12 +2712,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(QV4::CallContext *
else if (textBaseline == QLatin1String("middle"))
tb = QQuickContext2D::Middle;
else
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
if (tb != r->d()->context->state.textBaseline)
r->d()->context->state.textBaseline = tb;
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -2780,21 +2728,21 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(QV4::CallContext *
\sa textBaseline
\sa strokeText
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_fillText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 3) {
- qreal x = ctx->args()[1].toNumber();
- qreal y = ctx->args()[2].toNumber();
+ scope.result = callData->thisObject;
+
+ if (callData->argc >= 3) {
+ qreal x = callData->args[1].toNumber();
+ qreal y = callData->args[2].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
- QPainterPath textPath = r->d()->context->createTextGlyphs(x, y, ctx->args()[0].toQStringNoThrow());
+ return;
+ QPainterPath textPath = r->d()->context->createTextGlyphs(x, y, callData->args[0].toQStringNoThrow());
r->d()->context->buffer()->fill(textPath);
}
- return ctx->thisObject().asReturnedValue();
}
/*!
\qmlmethod object QtQuick::Context2D::strokeText(text, x, y)
@@ -2804,15 +2752,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(QV4::CallContext
\sa textBaseline
\sa fillText
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_strokeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 3)
- r->d()->context->drawText(ctx->args()[0].toQStringNoThrow(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), false);
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 3)
+ r->d()->context->drawText(callData->args[0].toQStringNoThrow(), callData->args[1].toNumber(), callData->args[2].toNumber(), false);
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2821,21 +2769,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(QV4::CallContex
Returns an object with a \c width property, whose value is equivalent to
calling \l {QFontMetrics::width()} with the given \a text in the current font.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_measureText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 1) {
+ if (callData->argc >= 1) {
QFontMetrics fm(r->d()->context->state.font);
- uint width = fm.width(ctx->args()[0].toQStringNoThrow());
+ uint width = fm.width(callData->args[0].toQStringNoThrow());
QV4::ScopedObject tm(scope, scope.engine->newObject());
tm->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("width"))).getPointer(),
QV4::ScopedValue(scope, QV4::Primitive::fromDouble(width)));
- return tm.asReturnedValue();
+ RETURN_RESULT(tm);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
// drawing images
@@ -2897,28 +2844,29 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::CallConte
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_drawImage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
+ scope.result = callData->thisObject;
+
qreal sx, sy, sw, sh, dx, dy, dw, dh;
- if (!ctx->argc())
- return ctx->thisObject().asReturnedValue();
+ if (!callData->argc)
+ return;
//FIXME:This function should be moved to QQuickContext2D::drawImage(...)
if (!r->d()->context->state.invertibleCTM)
- return ctx->thisObject().asReturnedValue();
+ return;
QQmlRefPointer<QQuickCanvasPixmap> pixmap;
- QV4::ScopedValue arg(scope, ctx->args()[0]);
+ QV4::ScopedValue arg(scope, callData->args[0]);
if (arg->isString()) {
QUrl url(arg->toQString());
if (!url.isValid())
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
pixmap = r->d()->context->createPixmap(url);
} else if (arg->isObject()) {
@@ -2931,7 +2879,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
if (!img.isNull())
pixmap.adopt(new QQuickCanvasPixmap(img));
} else {
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
} else {
QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg);
@@ -2940,44 +2888,44 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
if (pix && !pix->d()->image->isNull()) {
pixmap.adopt(new QQuickCanvasPixmap(*pix->d()->image));
} else {
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
} else {
QUrl url(arg->toQStringNoThrow());
if (url.isValid())
pixmap = r->d()->context->createPixmap(url);
else
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
}
} else {
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
if (pixmap.isNull() || !pixmap->isValid())
- return ctx->thisObject().asReturnedValue();
-
- if (ctx->argc() >= 9) {
- sx = ctx->args()[1].toNumber();
- sy = ctx->args()[2].toNumber();
- sw = ctx->args()[3].toNumber();
- sh = ctx->args()[4].toNumber();
- dx = ctx->args()[5].toNumber();
- dy = ctx->args()[6].toNumber();
- dw = ctx->args()[7].toNumber();
- dh = ctx->args()[8].toNumber();
- } else if (ctx->argc() >= 5) {
+ return;
+
+ if (callData->argc >= 9) {
+ sx = callData->args[1].toNumber();
+ sy = callData->args[2].toNumber();
+ sw = callData->args[3].toNumber();
+ sh = callData->args[4].toNumber();
+ dx = callData->args[5].toNumber();
+ dy = callData->args[6].toNumber();
+ dw = callData->args[7].toNumber();
+ dh = callData->args[8].toNumber();
+ } else if (callData->argc >= 5) {
sx = 0;
sy = 0;
sw = pixmap->width();
sh = pixmap->height();
- dx = ctx->args()[1].toNumber();
- dy = ctx->args()[2].toNumber();
- dw = ctx->args()[3].toNumber();
- dh = ctx->args()[4].toNumber();
- } else if (ctx->argc() >= 3) {
- dx = ctx->args()[1].toNumber();
- dy = ctx->args()[2].toNumber();
+ dx = callData->args[1].toNumber();
+ dy = callData->args[2].toNumber();
+ dw = callData->args[3].toNumber();
+ dh = callData->args[4].toNumber();
+ } else if (callData->argc >= 3) {
+ dx = callData->args[1].toNumber();
+ dy = callData->args[2].toNumber();
sx = 0;
sy = 0;
sw = pixmap->width();
@@ -2985,7 +2933,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
dw = sw;
dh = sh;
} else {
- return ctx->thisObject().asReturnedValue();
+ return;
}
if (!qt_is_finite(sx)
@@ -2996,7 +2944,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
|| !qt_is_finite(dy)
|| !qt_is_finite(dw)
|| !qt_is_finite(dh))
- return ctx->thisObject().asReturnedValue();
+ return;
if (sx < 0
|| sy < 0
@@ -3005,12 +2953,10 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
|| sx + sw > pixmap->width()
|| sy + sh > pixmap->height()
|| sx + sw < 0 || sy + sh < 0) {
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "drawImage(), index size error");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "drawImage(), index size error");
}
r->d()->context->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh));
-
- return ctx->thisObject().asReturnedValue();
}
// pixel manipulation
@@ -3037,45 +2983,40 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
\qmlproperty int QtQuick::CanvasImageData::width
Holds the actual width dimension of the data in the ImageData object, in device pixels.
*/
-QV4::ReturnedValue QQuickJSContext2DImageData::method_get_width(QV4::CallContext *ctx)
+void QQuickJSContext2DImageData::method_get_width(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject);
if (!imageData)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
- if (!r)
- return QV4::Encode(0);
- return QV4::Encode(r->d()->image->width());
+ int width = r ? r->d()->image->width() : 0;
+ scope.result = QV4::Encode(width);
}
/*!
\qmlproperty int QtQuick::CanvasImageData::height
Holds the actual height dimension of the data in the ImageData object, in device pixels.
*/
-QV4::ReturnedValue QQuickJSContext2DImageData::method_get_height(QV4::CallContext *ctx)
+void QQuickJSContext2DImageData::method_get_height(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject);
if (!imageData)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
- if (!r)
- return QV4::Encode(0);
- return QV4::Encode(r->d()->image->height());
+ int height = r ? r->d()->image->height() : 0;
+ scope.result = QV4::Encode(height);
}
/*!
\qmlproperty object QtQuick::CanvasImageData::data
Holds the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.
*/
-QV4::ReturnedValue QQuickJSContext2DImageData::method_get_data(QV4::CallContext *ctx)
+void QQuickJSContext2DImageData::method_get_data(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject);
if (!imageData)
- return ctx->engine()->throwTypeError();
- return imageData->d()->pixelData.asReturnedValue();
+ THROW_TYPE_ERROR();
+ scope.result = imageData->d()->pixelData;
}
/*!
@@ -3096,14 +3037,13 @@ QV4::ReturnedValue QQuickJSContext2DImageData::method_get_data(QV4::CallContext
The length attribute of a CanvasPixelArray object must return this h×w×4 number value.
This property is read only.
*/
-QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(QV4::CallContext *ctx)
+void QQuickJSContext2DPixelData::proto_get_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2DPixelData> r(scope, ctx->thisObject().as<QQuickJSContext2DPixelData>());
+ QV4::Scoped<QQuickJSContext2DPixelData> r(scope, callData->thisObject.as<QQuickJSContext2DPixelData>());
if (!r || r->d()->image->isNull())
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4);
+ RETURN_RESULT(r->d()->image->width() * r->d()->image->height() * 4);
}
QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m, uint index, bool *hasProperty)
@@ -3192,108 +3132,107 @@ void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q
\sa Canvas::loadImage(), QtQuick::Canvas::unloadImage(),
QtQuick::Canvas::isImageLoaded
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() == 1) {
- QV4::ScopedValue arg0(scope, ctx->args()[0]);
+ if (callData->argc == 1) {
+ QV4::ScopedValue arg0(scope, callData->args[0]);
QV4::Scoped<QQuickJSContext2DImageData> imgData(scope, arg0);
if (!!imgData) {
QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (pa) {
qreal w = pa->d()->image->width();
qreal h = pa->d()->image->height();
- return qt_create_image_data(w, h, scope.engine, QImage());
+ RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
}
} else if (arg0->isString()) {
QImage image = r->d()->context->createPixmap(QUrl(arg0->toQStringNoThrow()))->image();
- return qt_create_image_data(image.width(), image.height(), scope.engine, image);
+ RETURN_RESULT(qt_create_image_data(image.width(), image.height(), scope.engine, image));
}
- } else if (ctx->argc() == 2) {
- qreal w = ctx->args()[0].toNumber();
- qreal h = ctx->args()[1].toNumber();
+ } else if (callData->argc == 2) {
+ qreal w = callData->args[0].toNumber();
+ qreal h = callData->args[1].toNumber();
if (!qt_is_finite(w) || !qt_is_finite(h))
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createImageData(): invalid arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createImageData(): invalid arguments");
if (w > 0 && h > 0)
- return qt_create_image_data(w, h, scope.engine, QImage());
+ RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
else
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createImageData(): invalid arguments");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createImageData(): invalid arguments");
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlmethod CanvasImageData QtQuick::Context2D::getImageData(real sx, real sy, real sw, real sh)
Returns an CanvasImageData object containing the image data for the given rectangle of the canvas.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_getImageData(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_getImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4) {
- qreal x = ctx->args()[0].toNumber();
- qreal y = ctx->args()[1].toNumber();
- qreal w = ctx->args()[2].toNumber();
- qreal h = ctx->args()[3].toNumber();
+ if (callData->argc >= 4) {
+ qreal x = callData->args[0].toNumber();
+ qreal y = callData->args[1].toNumber();
+ qreal w = callData->args[2].toNumber();
+ qreal h = callData->args[3].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "getImageData(): Invalid arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "getImageData(): Invalid arguments");
if (w <= 0 || h <= 0)
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "getImageData(): Invalid arguments");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "getImageData(): Invalid arguments");
QImage image = r->d()->context->canvas()->toImage(QRectF(x, y, w, h));
- return qt_create_image_data(w, h, scope.engine, image);
+ RETURN_RESULT(qt_create_image_data(w, h, scope.engine, image));
}
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
}
/*!
\qmlmethod object QtQuick::Context2D::putImageData(CanvasImageData imageData, real dx, real dy, real dirtyX, real dirtyY, real dirtyWidth, real dirtyHeight)
Paints the data from the given ImageData object onto the canvas. If a dirty rectangle (\a dirtyX, \a dirtyY, \a dirtyWidth, \a dirtyHeight) is provided, only the pixels from that rectangle are painted.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_putImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() < 7)
- return QV4::Encode::undefined();
+ if (callData->argc < 7)
+ RETURN_UNDEFINED();
- QV4::ScopedValue arg0(scope, ctx->args()[0]);
+ QV4::ScopedValue arg0(scope, callData->args[0]);
if (!arg0->isObject())
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "Context2D::putImageData, the image data type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "Context2D::putImageData, the image data type mismatch");
- qreal dx = ctx->args()[1].toNumber();
- qreal dy = ctx->args()[2].toNumber();
+ qreal dx = callData->args[1].toNumber();
+ qreal dy = callData->args[2].toNumber();
qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight;
if (!qt_is_finite(dx) || !qt_is_finite(dy))
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
+
+ scope.result = callData->thisObject;
QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg0);
if (!imageData)
- return ctx->thisObject().asReturnedValue();
+ return;
QV4::Scoped<QQuickJSContext2DPixelData> pixelArray(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (pixelArray) {
w = pixelArray->d()->image->width();
h = pixelArray->d()->image->height();
- if (ctx->argc() == 7) {
- dirtyX = ctx->args()[3].toNumber();
- dirtyY = ctx->args()[4].toNumber();
- dirtyWidth = ctx->args()[5].toNumber();
- dirtyHeight = ctx->args()[6].toNumber();
+ if (callData->argc == 7) {
+ dirtyX = callData->args[3].toNumber();
+ dirtyY = callData->args[4].toNumber();
+ dirtyWidth = callData->args[5].toNumber();
+ dirtyHeight = callData->args[6].toNumber();
if (!qt_is_finite(dirtyX) || !qt_is_finite(dirtyY) || !qt_is_finite(dirtyWidth) || !qt_is_finite(dirtyHeight))
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
if (dirtyWidth < 0) {
@@ -3325,7 +3264,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
}
if (dirtyWidth <=0 || dirtyHeight <= 0)
- return ctx->thisObject().asReturnedValue();
+ return;
} else {
dirtyX = 0;
dirtyY = 0;
@@ -3336,7 +3275,6 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
QImage image = pixelArray->d()->image->copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
r->d()->context->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
}
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -3359,39 +3297,38 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
gradient.addColorStop(0.7, 'rgba(0, 255, 255, 1');
\endcode
*/
-QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(QV4::CallContext *ctx)
+void QQuickContext2DStyle::gradient_proto_addColorStop(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickContext2DStyle> style(scope, ctx->thisObject().as<QQuickContext2DStyle>());
+ QV4::Scoped<QQuickContext2DStyle> style(scope, callData->thisObject.as<QQuickContext2DStyle>());
if (!style)
- V4THROW_ERROR("Not a CanvasGradient object");
+ THROW_GENERIC_ERROR("Not a CanvasGradient object");
- if (ctx->argc() == 2) {
+ if (callData->argc == 2) {
if (!style->d()->brush->gradient())
- V4THROW_ERROR("Not a valid CanvasGradient object, can't get the gradient information");
+ THROW_GENERIC_ERROR("Not a valid CanvasGradient object, can't get the gradient information");
QGradient gradient = *(style->d()->brush->gradient());
- qreal pos = ctx->args()[0].toNumber();
+ qreal pos = callData->args[0].toNumber();
QColor color;
- if (ctx->args()[1].as<Object>()) {
- color = scope.engine->toVariant(ctx->args()[1], qMetaTypeId<QColor>()).value<QColor>();
+ if (callData->args[1].as<Object>()) {
+ color = scope.engine->toVariant(callData->args[1], qMetaTypeId<QColor>()).value<QColor>();
} else {
- color = qt_color_from_string(ctx->args()[1]);
+ color = qt_color_from_string(callData->args[1]);
}
if (pos < 0.0 || pos > 1.0 || !qt_is_finite(pos)) {
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "CanvasGradient: parameter offset out of range");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "CanvasGradient: parameter offset out of range");
}
if (color.isValid()) {
gradient.setColorAt(pos, color);
} else {
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "CanvasGradient: parameter color is not a valid color string");
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "CanvasGradient: parameter color is not a valid color string");
}
*style->d()->brush = gradient;
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
void QQuickContext2D::scale(qreal x, qreal y)
diff --git a/src/quick/items/qquickanchors.cpp b/src/quick/items/qquickanchors.cpp
index 4162314cd3..c0bec7d716 100644
--- a/src/quick/items/qquickanchors.cpp
+++ b/src/quick/items/qquickanchors.cpp
@@ -214,7 +214,7 @@ void QQuickAnchorsPrivate::fillChanged()
--updatingFill;
} else {
// ### Make this certain :)
- qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on fill.");
+ qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on fill.");
}
}
@@ -243,7 +243,7 @@ void QQuickAnchorsPrivate::centerInChanged()
--updatingCenterIn;
} else {
// ### Make this certain :)
- qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on centerIn.");
+ qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on centerIn.");
}
}
@@ -529,7 +529,7 @@ void QQuickAnchors::setFill(QQuickItem *f)
return;
}
if (f != readParentItem(d->item) && readParentItem(f) != readParentItem(d->item)){
- qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
+ qmlWarning(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
return;
}
QQuickItem *oldFill = d->fill;
@@ -565,7 +565,7 @@ void QQuickAnchors::setCenterIn(QQuickItem* c)
return;
}
if (c != readParentItem(d->item) && readParentItem(c) != readParentItem(d->item)){
- qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
+ qmlWarning(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
return;
}
QQuickItem *oldCI = d->centerIn;
@@ -619,7 +619,7 @@ void QQuickAnchorsPrivate::updateVerticalAnchors()
if (Q_UNLIKELY(updatingVerticalAnchor > 1)) {
// ### Make this certain :)
- qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor.");
+ qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor.");
return;
}
@@ -794,7 +794,7 @@ void QQuickAnchorsPrivate::updateHorizontalAnchors()
--updatingHorizontalAnchor;
} else {
// ### Make this certain :)
- qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on horizontal anchor.");
+ qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on horizontal anchor.");
}
}
@@ -1329,7 +1329,7 @@ bool QQuickAnchorsPrivate::checkHValid() const
if (usedAnchors & QQuickAnchors::LeftAnchor &&
usedAnchors & QQuickAnchors::RightAnchor &&
usedAnchors & QQuickAnchors::HCenterAnchor) {
- qmlInfo(item) << QQuickAnchors::tr("Cannot specify left, right, and horizontalCenter anchors at the same time.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot specify left, right, and horizontalCenter anchors at the same time.");
return false;
}
@@ -1339,17 +1339,17 @@ bool QQuickAnchorsPrivate::checkHValid() const
bool QQuickAnchorsPrivate::checkHAnchorValid(QQuickAnchorLine anchor) const
{
if (!anchor.item) {
- qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
return false;
} else if (anchor.anchorLine & QQuickAnchors::Vertical_Mask) {
- qmlInfo(item) << QQuickAnchors::tr("Cannot anchor a horizontal edge to a vertical edge.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot anchor a horizontal edge to a vertical edge.");
return false;
} else if (anchor.item != readParentItem(item)
&& readParentItem(anchor.item) != readParentItem(item)) {
- qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
return false;
} else if (anchor.item == item) {
- qmlInfo(item) << QQuickAnchors::tr("Cannot anchor item to self.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot anchor item to self.");
return false;
}
@@ -1361,13 +1361,13 @@ bool QQuickAnchorsPrivate::checkVValid() const
if (usedAnchors & QQuickAnchors::TopAnchor &&
usedAnchors & QQuickAnchors::BottomAnchor &&
usedAnchors & QQuickAnchors::VCenterAnchor) {
- qmlInfo(item) << QQuickAnchors::tr("Cannot specify top, bottom, and verticalCenter anchors at the same time.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot specify top, bottom, and verticalCenter anchors at the same time.");
return false;
} else if (usedAnchors & QQuickAnchors::BaselineAnchor &&
(usedAnchors & QQuickAnchors::TopAnchor ||
usedAnchors & QQuickAnchors::BottomAnchor ||
usedAnchors & QQuickAnchors::VCenterAnchor)) {
- qmlInfo(item) << QQuickAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or verticalCenter anchors.");
+ qmlWarning(item) << QQuickAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or verticalCenter anchors.");
return false;
}
@@ -1377,17 +1377,17 @@ bool QQuickAnchorsPrivate::checkVValid() const
bool QQuickAnchorsPrivate::checkVAnchorValid(QQuickAnchorLine anchor) const
{
if (!anchor.item) {
- qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
return false;
} else if (anchor.anchorLine & QQuickAnchors::Horizontal_Mask) {
- qmlInfo(item) << QQuickAnchors::tr("Cannot anchor a vertical edge to a horizontal edge.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot anchor a vertical edge to a horizontal edge.");
return false;
} else if (anchor.item != readParentItem(item)
&& readParentItem(anchor.item) != readParentItem(item)) {
- qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
return false;
} else if (anchor.item == item){
- qmlInfo(item) << QQuickAnchors::tr("Cannot anchor item to self.");
+ qmlWarning(item) << QQuickAnchors::tr("Cannot anchor item to self.");
return false;
}
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index 81c649dbd5..a1833081c8 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -371,7 +371,7 @@ void QQuickAnimatedImage::movieRequestFinished()
#endif
if (!d->_movie->isValid()) {
- qmlInfo(this) << "Error Reading Animated Image File " << d->url.toString();
+ qmlWarning(this) << "Error Reading Animated Image File " << d->url.toString();
delete d->_movie;
d->_movie = 0;
d->setImage(QImage());
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
index 8aeef4ef4a..76c2146ddb 100644
--- a/src/quick/items/qquickanimatedsprite.cpp
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -626,7 +626,7 @@ QSGSpriteNode* QQuickAnimatedSprite::initNode()
Q_D(QQuickAnimatedSprite);
if (!d->m_spriteEngine) {
- qmlInfo(this) << "No sprite engine...";
+ qmlWarning(this) << "No sprite engine...";
return nullptr;
} else if (d->m_spriteEngine->status() == QQuickPixmap::Null) {
d->m_spriteEngine->startAssemblingImage();
diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp
index 67b99bfbc6..28d834f9e2 100644
--- a/src/quick/items/qquickborderimage.cpp
+++ b/src/quick/items/qquickborderimage.cpp
@@ -515,7 +515,7 @@ void QQuickBorderImage::requestFinished()
QSize impsize = d->pix.implicitSize();
if (d->pix.isError()) {
d->status = Error;
- qmlInfo(this) << d->pix.error();
+ qmlWarning(this) << d->pix.error();
if (d->progress != 0) {
d->progress = 0;
emit progressChanged(d->progress);
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 7a112e840a..e5969eed7f 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -307,7 +307,7 @@ void QQuickDragAttached::setActive(bool active)
Q_D(QQuickDragAttached);
if (d->active != active) {
if (d->inEvent)
- qmlInfo(this) << "active cannot be changed from within a drag event handler";
+ qmlWarning(this) << "active cannot be changed from within a drag event handler";
else if (active) {
if (d->dragType == QQuickDrag::Internal) {
d->start(d->supportedActions);
@@ -629,7 +629,7 @@ void QQuickDragAttached::start(QQmlV4Function *args)
{
Q_D(QQuickDragAttached);
if (d->inEvent) {
- qmlInfo(this) << "start() cannot be called from within a drag event handler";
+ qmlWarning(this) << "start() cannot be called from within a drag event handler";
return;
}
@@ -675,7 +675,7 @@ int QQuickDragAttached::drop()
Qt::DropAction acceptedAction = Qt::IgnoreAction;
if (d->inEvent) {
- qmlInfo(this) << "drop() cannot be called from within a drag event handler";
+ qmlWarning(this) << "drop() cannot be called from within a drag event handler";
return acceptedAction;
}
@@ -722,7 +722,7 @@ void QQuickDragAttached::cancel()
Q_D(QQuickDragAttached);
if (d->inEvent) {
- qmlInfo(this) << "cancel() cannot be called from within a drag event handler";
+ qmlWarning(this) << "cancel() cannot be called from within a drag event handler";
return;
}
@@ -809,12 +809,12 @@ void QQuickDragAttached::startDrag(QQmlV4Function *args)
Q_D(QQuickDragAttached);
if (d->inEvent) {
- qmlInfo(this) << "startDrag() cannot be called from within a drag event handler";
+ qmlWarning(this) << "startDrag() cannot be called from within a drag event handler";
return;
}
if (!d->active) {
- qmlInfo(this) << "startDrag() drag must be active";
+ qmlWarning(this) << "startDrag() drag must be active";
return;
}
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 2b145044e8..0c18cb4104 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -139,6 +139,7 @@ Item {
\li Qt.AltModifier - An Alt key on the keyboard is pressed.
\li Qt.MetaModifier - A Meta key on the keyboard is pressed.
\li Qt.KeypadModifier - A keypad button is pressed.
+ \li Qt.GroupSwitchModifier - X11 only. A Mode_switch key on the keyboard is pressed.
\endlist
For example, to react to a Shift key + Enter key combination:
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 7fc50ab682..4a78e98705 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -109,7 +109,9 @@ public:
bool isAccepted() { return event.isAccepted(); }
void setAccepted(bool accepted) { event.setAccepted(accepted); }
+#if QT_CONFIG(shortcut)
Q_REVISION(2) Q_INVOKABLE bool matches(QKeySequence::StandardKey key) const { return event.matches(key); }
+#endif
private:
QKeyEvent event;
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 80e34b033d..45bb2a367d 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -1571,12 +1571,52 @@ void QQuickFlickablePrivate::replayDelayedPress()
//XXX pixelAligned ignores the global position of the Flickable, i.e. assumes Flickable itself is pixel aligned.
void QQuickFlickablePrivate::setViewportX(qreal x)
{
- contentItem->setX(pixelAligned ? -Round(-x) : x);
+ Q_Q(QQuickFlickable);
+ if (pixelAligned)
+ x = -Round(-x);
+
+ contentItem->setX(x);
+ if (contentItem->x() != x)
+ return; // reentered
+
+ const qreal maxX = q->maxXExtent();
+ const qreal minX = q->minXExtent();
+
+ qreal overshoot = 0.0;
+ if (x <= maxX)
+ overshoot = maxX - x;
+ else if (x >= minX)
+ overshoot = minX - x;
+
+ if (overshoot != hData.overshoot) {
+ hData.overshoot = overshoot;
+ emit q->horizontalOvershootChanged();
+ }
}
void QQuickFlickablePrivate::setViewportY(qreal y)
{
- contentItem->setY(pixelAligned ? -Round(-y) : y);
+ Q_Q(QQuickFlickable);
+ if (pixelAligned)
+ y = -Round(-y);
+
+ contentItem->setY(y);
+ if (contentItem->y() != y)
+ return; // reentered
+
+ const qreal maxY = q->maxYExtent();
+ const qreal minY = q->minYExtent();
+
+ qreal overshoot = 0.0;
+ if (y <= maxY)
+ overshoot = maxY - y;
+ else if (y >= minY)
+ overshoot = minY - y;
+
+ if (overshoot != vData.overshoot) {
+ vData.overshoot = overshoot;
+ emit q->verticalOvershootChanged();
+ }
}
void QQuickFlickable::timerEvent(QTimerEvent *event)
@@ -1842,6 +1882,8 @@ QQmlListProperty<QQuickItem> QQuickFlickable::flickableChildren()
beyond the boundary of the Flickable, and can overshoot the
boundary when flicked.
\endlist
+
+ \sa horizontalOvershoot, verticalOvershoot
*/
QQuickFlickable::BoundsBehavior QQuickFlickable::boundsBehavior() const
{
@@ -2639,4 +2681,38 @@ void QQuickFlickablePrivate::updateVelocity()
emit q->verticalVelocityChanged();
}
+/*!
+ \qmlproperty real QtQuick::Flickable::horizontalOvershoot
+ \since 5.9
+
+ This property holds the horizontal overshoot, that is, the horizontal distance by
+ which the contents has been dragged or flicked past the bounds of the flickable.
+ The value is negative when the content is dragged or flicked beyond the beginning,
+ and positive when beyond the end; \c 0.0 otherwise.
+
+ \sa verticalOvershoot, boundsBehavior
+*/
+qreal QQuickFlickable::horizontalOvershoot() const
+{
+ Q_D(const QQuickFlickable);
+ return d->hData.overshoot;
+}
+
+/*!
+ \qmlproperty real QtQuick::Flickable::verticalOvershoot
+ \since 5.9
+
+ This property holds the vertical overshoot, that is, the vertical distance by
+ which the contents has been dragged or flicked past the bounds of the flickable.
+ The value is negative when the content is dragged or flicked beyond the beginning,
+ and positive when beyond the end; \c 0.0 otherwise.
+
+ \sa horizontalOvershoot, boundsBehavior
+*/
+qreal QQuickFlickable::verticalOvershoot() const
+{
+ Q_D(const QQuickFlickable);
+ return d->vData.overshoot;
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index 7384c7271a..52cade1472 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -106,12 +106,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem
Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY pixelAlignedChanged)
+ Q_PROPERTY(qreal horizontalOvershoot READ horizontalOvershoot NOTIFY horizontalOvershootChanged REVISION 9)
+ Q_PROPERTY(qreal verticalOvershoot READ verticalOvershoot NOTIFY verticalOvershootChanged REVISION 9)
+
Q_PROPERTY(QQmlListProperty<QObject> flickableData READ flickableData)
Q_PROPERTY(QQmlListProperty<QQuickItem> flickableChildren READ flickableChildren)
Q_CLASSINFO("DefaultProperty", "flickableData")
- Q_FLAGS(BoundsBehavior)
-
public:
QQuickFlickable(QQuickItem *parent=0);
~QQuickFlickable();
@@ -126,6 +127,7 @@ public:
DragAndOvershootBounds = DragOverBounds | OvershootBounds
};
Q_DECLARE_FLAGS(BoundsBehavior, BoundsBehaviorFlag)
+ Q_FLAG(BoundsBehavior)
BoundsBehavior boundsBehavior() const;
void setBoundsBehavior(BoundsBehavior);
@@ -201,6 +203,9 @@ public:
bool pixelAligned() const;
void setPixelAligned(bool align);
+ qreal horizontalOvershoot() const;
+ qreal verticalOvershoot() const;
+
Q_INVOKABLE void resizeContent(qreal w, qreal h, QPointF center);
Q_INVOKABLE void returnToBounds();
Q_INVOKABLE void flick(qreal xVelocity, qreal yVelocity);
@@ -243,6 +248,8 @@ Q_SIGNALS:
void dragStarted();
void dragEnded();
void pixelAlignedChanged();
+ Q_REVISION(9) void horizontalOvershootChanged();
+ Q_REVISION(9) void verticalOvershootChanged();
protected:
bool childMouseEventFilter(QQuickItem *, QEvent *) Q_DECL_OVERRIDE;
@@ -286,6 +293,7 @@ protected:
private:
Q_DISABLE_COPY(QQuickFlickable)
Q_DECLARE_PRIVATE(QQuickFlickable)
+ friend class QQuickFlickableContentItem;
friend class QQuickFlickableVisibleArea;
friend class QQuickFlickableReboundTransition;
};
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 0c3bc21071..1ceff22dfc 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -101,7 +101,7 @@ public:
: move(fp, func)
, transitionToBounds(0)
, viewSize(-1), lastPos(0), previousDragDelta(0), velocity(0), startMargin(0), endMargin(0)
- , origin(0)
+ , origin(0), overshoot(0)
, transitionTo(0)
, continuousFlickVelocity(0), velocityTime(), vTime(0)
, smoothVelocity(fp), atEnd(false), atBeginning(true)
@@ -148,6 +148,7 @@ public:
qreal startMargin;
qreal endMargin;
qreal origin;
+ qreal overshoot;
qreal transitionTo;
qreal continuousFlickVelocity;
QElapsedTimer velocityTime;
diff --git a/src/quick/items/qquickflickablebehavior_p.h b/src/quick/items/qquickflickablebehavior_p.h
index 3377728d3f..ae7fe71359 100644
--- a/src/quick/items/qquickflickablebehavior_p.h
+++ b/src/quick/items/qquickflickablebehavior_p.h
@@ -75,20 +75,12 @@
// The default maximum velocity of a flick.
#ifndef QML_FLICK_DEFAULTMAXVELOCITY
-#ifdef Q_OS_BLACKBERRY
-#define QML_FLICK_DEFAULTMAXVELOCITY 10000
-#else
-#define QML_FLICK_DEFAULTMAXVELOCITY 2500
-#endif
+# define QML_FLICK_DEFAULTMAXVELOCITY 2500
#endif
// The default deceleration of a flick.
#ifndef QML_FLICK_DEFAULTDECELERATION
-#ifdef Q_OS_BLACKBERRY
-#define QML_FLICK_DEFAULTDECELERATION 5000
-#else
-#define QML_FLICK_DEFAULTDECELERATION 1500
-#endif
+# define QML_FLICK_DEFAULTDECELERATION 1500
#endif
// How much faster to decelerate when overshooting
diff --git a/src/quick/items/qquickflipable.cpp b/src/quick/items/qquickflipable.cpp
index 6a6b6c00a9..f452893528 100644
--- a/src/quick/items/qquickflipable.cpp
+++ b/src/quick/items/qquickflipable.cpp
@@ -153,7 +153,7 @@ void QQuickFlipable::setFront(QQuickItem *front)
{
Q_D(QQuickFlipable);
if (d->front) {
- qmlInfo(this) << tr("front is a write-once property");
+ qmlWarning(this) << tr("front is a write-once property");
return;
}
d->front = front;
@@ -175,7 +175,7 @@ void QQuickFlipable::setBack(QQuickItem *back)
{
Q_D(QQuickFlipable);
if (d->back) {
- qmlInfo(this) << tr("back is a write-once property");
+ qmlWarning(this) << tr("back is a write-once property");
return;
}
if (back == 0)
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 14ea43f123..e6a7a0acd0 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -66,19 +66,19 @@ public:
{
}
- qreal position() const Q_DECL_OVERRIDE {
+ qreal position() const override {
return rowPos();
}
- qreal endPosition() const Q_DECL_OVERRIDE {
+ qreal endPosition() const override {
return endRowPos();
}
- qreal size() const Q_DECL_OVERRIDE {
+ qreal size() const override {
return view->flow() == QQuickGridView::FlowLeftToRight ? view->cellHeight() : view->cellWidth();
}
- qreal sectionSize() const Q_DECL_OVERRIDE {
+ qreal sectionSize() const override {
return 0.0;
}
@@ -122,7 +122,7 @@ public:
void setPosition(qreal col, qreal row, bool immediate = false) {
moveTo(pointForPosition(col, row), immediate);
}
- bool contains(qreal x, qreal y) const Q_DECL_OVERRIDE {
+ bool contains(qreal x, qreal y) const override {
return (x >= itemX() && x < itemX() + view->cellWidth() &&
y >= itemY() && y < itemY() + view->cellHeight());
}
@@ -159,13 +159,13 @@ class QQuickGridViewPrivate : public QQuickItemViewPrivate
Q_DECLARE_PUBLIC(QQuickGridView)
public:
- Qt::Orientation layoutOrientation() const Q_DECL_OVERRIDE;
- bool isContentFlowReversed() const Q_DECL_OVERRIDE;
+ Qt::Orientation layoutOrientation() const override;
+ bool isContentFlowReversed() const override;
- qreal positionAt(int index) const Q_DECL_OVERRIDE;
- qreal endPositionAt(int index) const Q_DECL_OVERRIDE;
- qreal originPosition() const Q_DECL_OVERRIDE;
- qreal lastPosition() const Q_DECL_OVERRIDE;
+ qreal positionAt(int index) const override;
+ qreal endPositionAt(int index) const override;
+ qreal originPosition() const override;
+ qreal lastPosition() const override;
qreal rowSize() const;
qreal colSize() const;
@@ -179,43 +179,43 @@ public:
void resetColumns();
- bool addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer) Q_DECL_OVERRIDE;
- bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) Q_DECL_OVERRIDE;
+ bool addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer) override;
+ bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) override;
void removeItem(FxViewItem *item);
- FxViewItem *newViewItem(int index, QQuickItem *item) Q_DECL_OVERRIDE;
- void initializeViewItem(FxViewItem *item) Q_DECL_OVERRIDE;
- void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) Q_DECL_OVERRIDE;
- void repositionPackageItemAt(QQuickItem *item, int index) Q_DECL_OVERRIDE;
- void resetFirstItemPosition(qreal pos = 0.0) Q_DECL_OVERRIDE;
- void adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible) Q_DECL_OVERRIDE;
-
- void createHighlight() Q_DECL_OVERRIDE;
- void updateHighlight() Q_DECL_OVERRIDE;
- void resetHighlightPosition() Q_DECL_OVERRIDE;
-
- void setPosition(qreal pos) Q_DECL_OVERRIDE;
- void layoutVisibleItems(int fromModelIndex = 0) Q_DECL_OVERRIDE;
- bool applyInsertionChange(const QQmlChangeSet::Change &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView) Q_DECL_OVERRIDE;
- void translateAndTransitionItemsAfter(int afterModelIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult) Q_DECL_OVERRIDE;
- bool needsRefillForAddedOrRemovedIndex(int index) const Q_DECL_OVERRIDE;
-
- qreal headerSize() const Q_DECL_OVERRIDE;
- qreal footerSize() const Q_DECL_OVERRIDE;
- bool showHeaderForIndex(int index) const Q_DECL_OVERRIDE;
- bool showFooterForIndex(int index) const Q_DECL_OVERRIDE;
- void updateHeader() Q_DECL_OVERRIDE;
- void updateFooter() Q_DECL_OVERRIDE;
-
- void changedVisibleIndex(int newIndex) Q_DECL_OVERRIDE;
- void initializeCurrentItem() Q_DECL_OVERRIDE;
-
- void updateViewport() Q_DECL_OVERRIDE;
- void fixupPosition() Q_DECL_OVERRIDE;
- void fixup(AxisData &data, qreal minExtent, qreal maxExtent) Q_DECL_OVERRIDE;
+ FxViewItem *newViewItem(int index, QQuickItem *item) override;
+ void initializeViewItem(FxViewItem *item) override;
+ void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) override;
+ void repositionPackageItemAt(QQuickItem *item, int index) override;
+ void resetFirstItemPosition(qreal pos = 0.0) override;
+ void adjustFirstItem(qreal forwards, qreal backwards, int changeBeforeVisible) override;
+
+ void createHighlight() override;
+ void updateHighlight() override;
+ void resetHighlightPosition() override;
+
+ void setPosition(qreal pos) override;
+ void layoutVisibleItems(int fromModelIndex = 0) override;
+ bool applyInsertionChange(const QQmlChangeSet::Change &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView) override;
+ void translateAndTransitionItemsAfter(int afterModelIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult) override;
+ bool needsRefillForAddedOrRemovedIndex(int index) const override;
+
+ qreal headerSize() const override;
+ qreal footerSize() const override;
+ bool showHeaderForIndex(int index) const override;
+ bool showFooterForIndex(int index) const override;
+ void updateHeader() override;
+ void updateFooter() override;
+
+ void changedVisibleIndex(int newIndex) override;
+ void initializeCurrentItem() override;
+
+ void updateViewport() override;
+ void fixupPosition() override;
+ void fixup(AxisData &data, qreal minExtent, qreal maxExtent) override;
bool flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
- QQuickTimeLineCallback::Callback fixupCallback, qreal velocity) Q_DECL_OVERRIDE;
+ QQuickTimeLineCallback::Callback fixupCallback, qreal velocity) override;
QQuickGridView::Flow flow;
qreal cellWidth;
@@ -383,8 +383,7 @@ qreal QQuickGridViewPrivate::snapPosAt(qreal pos) const
FxViewItem *QQuickGridViewPrivate::snapItemAt(qreal pos) const
{
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
+ for (FxViewItem *item : visibleItems) {
if (item->index == -1)
continue;
qreal itemTop = item->position();
@@ -397,16 +396,16 @@ FxViewItem *QQuickGridViewPrivate::snapItemAt(qreal pos) const
int QQuickGridViewPrivate::snapIndex() const
{
int index = currentIndex;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxGridItemSG *item = static_cast<FxGridItemSG*>(visibleItems.at(i));
+ for (FxViewItem *item : visibleItems) {
if (item->index == -1)
continue;
qreal itemTop = item->position();
FxGridItemSG *hItem = static_cast<FxGridItemSG*>(highlight);
if (itemTop >= hItem->rowPos()-rowSize()/2 && itemTop < hItem->rowPos()+rowSize()/2) {
- index = item->index;
- if (item->colPos() >= hItem->colPos()-colSize()/2 && item->colPos() < hItem->colPos()+colSize()/2)
- return item->index;
+ FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(item);
+ index = gridItem->index;
+ if (gridItem->colPos() >= hItem->colPos()-colSize()/2 && gridItem->colPos() < hItem->colPos()+colSize()/2)
+ return gridItem->index;
}
}
return index;
@@ -496,8 +495,8 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
// We've jumped more than a page. Estimate which items are now
// visible and fill from there.
int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
- for (int i = 0; i < visibleItems.count(); ++i)
- releaseItem(visibleItems.at(i));
+ for (FxViewItem *item : qAsConst(visibleItems))
+ releaseItem(item);
visibleItems.clear();
modelIndex += count;
if (modelIndex >= model->count())
@@ -2055,9 +2054,9 @@ void QQuickGridView::viewportMoved(Qt::Orientations orient)
// Set visibility of items to eliminate cost of items outside the visible area.
qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
- for (int i = 0; i < d->visibleItems.count(); ++i) {
- FxGridItemSG *item = static_cast<FxGridItemSG*>(d->visibleItems.at(i));
- QQuickItemPrivate::get(item->item)->setCulled(item->rowPos() + d->rowSize() < from || item->rowPos() > to);
+ for (FxViewItem *item : qAsConst(d->visibleItems)) {
+ FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(item);
+ QQuickItemPrivate::get(gridItem->item)->setCulled(gridItem->rowPos() + d->rowSize() < from || gridItem->rowPos() > to);
}
if (d->currentItem) {
FxGridItemSG *item = static_cast<FxGridItemSG*>(d->currentItem);
@@ -2357,8 +2356,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
if (modelIndex <= visibleIndex) {
// Insert before visible items
visibleIndex += count;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
+ for (FxViewItem *item : qAsConst(visibleItems)) {
if (item->index != -1 && item->index >= modelIndex)
item->index += count;
}
@@ -2391,8 +2389,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
}
// Update the indexes of the following visible items.
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
+ for (FxViewItem *item : qAsConst(visibleItems)) {
if (item->index != -1 && item->index >= modelIndex) {
item->index += count;
if (change.isMove())
@@ -2535,8 +2532,10 @@ void QQuickGridViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
countItemsRemoved -= removalResult.countChangeAfterVisibleItems;
- for (int i=markerItemIndex+1; i<visibleItems.count() && visibleItems.at(i)->position() < viewEndPos; i++) {
+ for (int i=markerItemIndex+1; i<visibleItems.count(); i++) {
FxGridItemSG *gridItem = static_cast<FxGridItemSG *>(visibleItems.at(i));
+ if (gridItem->position() >= viewEndPos)
+ break;
if (!gridItem->transitionScheduledOrRunning()) {
qreal origRowPos = gridItem->colPos();
qreal origColPos = gridItem->rowPos();
diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h
index aaf6e4a75b..5c6da2b433 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -84,8 +84,8 @@ public:
QQuickGridView(QQuickItem *parent=0);
~QQuickGridView();
- void setHighlightFollowsCurrentItem(bool) Q_DECL_OVERRIDE;
- void setHighlightMoveDuration(int) Q_DECL_OVERRIDE;
+ void setHighlightFollowsCurrentItem(bool) override;
+ void setHighlightMoveDuration(int) override;
Flow flow() const;
void setFlow(Flow);
@@ -117,10 +117,10 @@ Q_SIGNALS:
void snapModeChanged();
protected:
- void viewportMoved(Qt::Orientations) Q_DECL_OVERRIDE;
- void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- void initItem(int index, QObject *item) Q_DECL_OVERRIDE;
+ void viewportMoved(Qt::Orientations) override;
+ void keyPressEvent(QKeyEvent *) override;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void initItem(int index, QObject *item) override;
};
class QQuickGridViewAttached : public QQuickItemViewAttached
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index a6bf6b4e8a..22d631e917 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -281,7 +281,7 @@ void QQuickImageBase::requestFinished()
Q_D(QQuickImageBase);
if (d->pix.isError()) {
- qmlInfo(this) << d->pix.error();
+ qmlWarning(this) << d->pix.error();
d->pix.clear(this);
d->status = Error;
if (d->progress != 0.0) {
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 55e82a7a4d..98cc3112df 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1568,7 +1568,7 @@ QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) :
if (itemPrivate)
itemPrivate->extra.value().layoutDirectionAttached = this;
else
- qmlInfo(parent) << tr("LayoutDirection attached property only works with Items and Windows");
+ qmlWarning(parent) << tr("LayoutDirection attached property only works with Items and Windows");
}
QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
@@ -1716,7 +1716,7 @@ QQuickEnterKeyAttached::QQuickEnterKeyAttached(QObject *parent)
itemPrivate = QQuickItemPrivate::get(item);
itemPrivate->extra.value().enterKeyAttached = this;
} else
- qmlInfo(parent) << tr("EnterKey attached property only works with Items");
+ qmlWarning(parent) << tr("EnterKey attached property only works with Items");
}
QQuickEnterKeyAttached *QQuickEnterKeyAttached::qmlAttachedProperties(QObject *object)
@@ -4383,7 +4383,7 @@ void QQuickItem::mapFromItem(QQmlV4Function *args) const
}
if (!itemObj && !item->isNull()) {
- qmlInfo(this) << "mapFromItem() given argument \"" << item->toQStringNoThrow()
+ qmlWarning(this) << "mapFromItem() given argument \"" << item->toQStringNoThrow()
<< "\" which is neither null nor an Item";
v4->throwTypeError();
return;
@@ -4471,7 +4471,7 @@ void QQuickItem::mapToItem(QQmlV4Function *args) const
}
if (!itemObj && !item->isNull()) {
- qmlInfo(this) << "mapToItem() given argument \"" << item->toQStringNoThrow()
+ qmlWarning(this) << "mapToItem() given argument \"" << item->toQStringNoThrow()
<< "\" which is neither null nor an Item";
v4->throwTypeError();
return;
@@ -8409,7 +8409,7 @@ void QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine
{
QObjectWrapper::Data *This = static_cast<QObjectWrapper::Data *>(that);
if (QQuickItem *item = static_cast<QQuickItem*>(This->object())) {
- foreach (QQuickItem *child, QQuickItemPrivate::get(item)->childItems)
+ for (QQuickItem *child : qAsConst(QQuickItemPrivate::get(item)->childItems))
QV4::QObjectWrapper::markWrapper(child, e);
}
QV4::QObjectWrapper::markObjects(that, e);
diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp
index fd4a7d733f..9873622f41 100644
--- a/src/quick/items/qquickitemanimation.cpp
+++ b/src/quick/items/qquickitemanimation.cpp
@@ -304,7 +304,7 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act
bool ok;
const QTransform &transform = targetParent->itemTransform(d->via, &ok);
if (transform.type() >= QTransform::TxShear || !ok) {
- qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under complex transform");
+ qmlWarning(this) << QQuickParentAnimation::tr("Unable to preserve appearance under complex transform");
ok = false;
}
@@ -315,21 +315,21 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act
if (transform.m11() == transform.m22())
scale = transform.m11();
else {
- qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
+ qmlWarning(this) << QQuickParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
ok = false;
}
} else if (ok && isRotate) {
if (transform.m11() == transform.m22())
scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
else {
- qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
+ qmlWarning(this) << QQuickParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
ok = false;
}
if (scale != 0)
rotation = qAtan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
else {
- qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under scale of 0");
+ qmlWarning(this) << QQuickParentAnimation::tr("Unable to preserve appearance under scale of 0");
ok = false;
}
}
@@ -474,7 +474,7 @@ int QQuickAnchorAnimation::duration() const
void QQuickAnchorAnimation::setDuration(int duration)
{
if (duration < 0) {
- qmlInfo(this) << tr("Cannot set a duration of < 0");
+ qmlWarning(this) << tr("Cannot set a duration of < 0");
return;
}
@@ -613,7 +613,7 @@ int QQuickPathAnimation::duration() const
void QQuickPathAnimation::setDuration(int duration)
{
if (duration < 0) {
- qmlInfo(this) << tr("Cannot set a duration of < 0");
+ qmlWarning(this) << tr("Cannot set a duration of < 0");
return;
}
@@ -869,7 +869,7 @@ QAbstractAnimationJob* QQuickPathAnimation::transition(QQuickStateActions &actio
data->reverse = direction == Backward ? true : false;
data->fromSourced = false;
data->fromDefined = (d->path && d->path->hasStartX() && d->path->hasStartY()) ? true : false;
- data->toDefined = d->path ? d->path->hasEnd() : false;
+ data->toDefined = d->path ? true : false;
int origModifiedSize = modified.count();
for (int i = 0; i < actions.count(); ++i) {
diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp
index c6355ceed2..07c2cb607c 100644
--- a/src/quick/items/qquickitemgrabresult.cpp
+++ b/src/quick/items/qquickitemgrabresult.cpp
@@ -47,6 +47,7 @@
#endif
#include <QtQml/QQmlEngine>
+#include <QtQml/QQmlInfo>
#include <private/qquickpixmapcache_p.h>
#include <private/qquickitem_p.h>
@@ -279,17 +280,17 @@ QQuickItemGrabResult *QQuickItemGrabResultPrivate::create(QQuickItem *item, cons
size = QSize(item->width(), item->height());
if (size.width() < 1 || size.height() < 1) {
- qWarning("Item::grabToImage: item has invalid dimensions");
+ qmlWarning(item) << "grabToImage: item has invalid dimensions";
return 0;
}
if (!item->window()) {
- qWarning("Item::grabToImage: item is not attached to a window");
+ qmlWarning(item) << "grabToImage: item is not attached to a window";
return 0;
}
if (!item->window()->isVisible()) {
- qWarning("Item::grabToImage: item's window is not visible");
+ qmlWarning(item) << "grabToImage: item's window is not visible";
return 0;
}
@@ -377,12 +378,12 @@ bool QQuickItem::grabToImage(const QJSValue &callback, const QSize &targetSize)
{
QQmlEngine *engine = qmlEngine(this);
if (!engine) {
- qWarning("Item::grabToImage: no QML Engine");
+ qmlWarning(this) << "grabToImage: item has no QML engine";
return false;
}
if (!callback.isCallable()) {
- qWarning("Item::grabToImage: 'callback' is not a function");
+ qmlWarning(this) << "grabToImage: 'callback' is not a function";
return false;
}
@@ -391,12 +392,12 @@ bool QQuickItem::grabToImage(const QJSValue &callback, const QSize &targetSize)
size = QSize(width(), height());
if (size.width() < 1 || size.height() < 1) {
- qWarning("Item::grabToImage: item has invalid dimensions");
+ qmlWarning(this) << "grabToImage: item has invalid dimensions";
return false;
}
if (!window()) {
- qWarning("Item::grabToImage: item is not attached to a window");
+ qmlWarning(this) << "grabToImage: item is not attached to a window";
return false;
}
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index b0ddbb0034..a8824de9c8 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -374,7 +374,17 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickBorderImageMesh>("QtQuick", 2, 8, "BorderImageMesh");
#endif
+ qmlRegisterType<QQuickFlickable, 9>(uri, 2, 9, "Flickable");
qmlRegisterType<QQuickMouseArea, 9>(uri, 2, 9, "MouseArea");
+ qmlRegisterType<QQuickText, 9>(uri, 2, 9, "Text");
+ qmlRegisterType<QQuickTextInput, 9>(uri, 2, 9, "TextInput");
+ qmlRegisterType<QQuickTouchPoint>(uri, 2, 9, "TouchPoint");
+ qRegisterMetaType<QPointingDeviceUniqueId>("QPointingDeviceUniqueId");
+ qmlRegisterUncreatableType<QPointingDeviceUniqueId>(uri, 2, 9, "PointingDeviceUniqueId", QQuickTouchPoint::tr("PointingDeviceUniqueId is only available via read-only properties"));
+#if QT_CONFIG(quick_positioners)
+ qmlRegisterUncreatableType<QQuickBasePositioner, 9>(uri, 2, 9, "Positioner",
+ QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
+#endif
}
static void initResources()
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 7d98cc2693..a8bac633cc 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -380,8 +380,8 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate)
int oldCount = dataModel->count();
dataModel->setDelegate(delegate);
if (isComponentComplete()) {
- for (int i = 0; i < d->visibleItems.count(); ++i)
- d->releaseItem(d->visibleItems.at(i));
+ for (FxViewItem *item : qAsConst(d->visibleItems))
+ d->releaseItem(item);
d->visibleItems.clear();
d->releaseItem(d->currentItem);
d->currentItem = 0;
@@ -487,7 +487,7 @@ void QQuickItemView::setCacheBuffer(int b)
{
Q_D(QQuickItemView);
if (b < 0) {
- qmlInfo(this) << "Cannot set a negative cache buffer";
+ qmlWarning(this) << "Cannot set a negative cache buffer";
return;
}
@@ -946,12 +946,12 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
qreal itemPos = positionAt(idx);
changedVisibleIndex(idx);
// save the currently visible items in case any of them end up visible again
- QList<FxViewItem *> oldVisible = visibleItems;
+ const QList<FxViewItem *> oldVisible = visibleItems;
visibleItems.clear();
setPosition(qMin(itemPos, maxExtent));
// now release the reference to all the old visible items.
- for (int i = 0; i < oldVisible.count(); ++i)
- releaseItem(oldVisible.at(i));
+ for (FxViewItem *item : oldVisible)
+ releaseItem(item);
item = visibleItem(idx);
}
if (item) {
@@ -1199,10 +1199,10 @@ void QQuickItemViewPrivate::checkVisible() const
void QQuickItemViewPrivate::showVisibleItems() const
{
qDebug() << "Visible items:";
- for (int i = 0; i < visibleItems.count(); ++i) {
- qDebug() << "\t" << visibleItems.at(i)->index
- << visibleItems.at(i)->item->objectName()
- << visibleItems.at(i)->position();
+ for (FxViewItem *item : visibleItems) {
+ qDebug() << "\t" << item->index
+ << item->item->objectName()
+ << item->position();
}
}
@@ -1646,8 +1646,7 @@ FxViewItem *QQuickItemViewPrivate::visibleItem(int modelIndex) const {
// that don't look at the view position and size
FxViewItem *QQuickItemViewPrivate::firstVisibleItem() const {
const qreal pos = isContentFlowReversed() ? -position()-size() : position();
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
+ for (FxViewItem *item : visibleItems) {
if (item->index != -1 && item->endPosition() > pos)
return item;
}
@@ -1744,14 +1743,14 @@ void QQuickItemViewPrivate::clear()
currentChanges.reset();
timeline.clear();
- for (int i = 0; i < visibleItems.count(); ++i)
- releaseItem(visibleItems.at(i));
+ for (FxViewItem *item : qAsConst(visibleItems))
+ releaseItem(item);
visibleItems.clear();
visibleIndex = 0;
- for (int i = 0; i < releasePendingTransition.count(); ++i) {
- releasePendingTransition.at(i)->releaseAfterTransition = false;
- releaseItem(releasePendingTransition.at(i));
+ for (FxViewItem *item : qAsConst(releasePendingTransition)) {
+ item->releaseAfterTransition = false;
+ releaseItem(item);
}
releasePendingTransition.clear();
@@ -1912,9 +1911,9 @@ void QQuickItemViewPrivate::layout()
forceLayout = false;
if (transitioner && transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) {
- for (int i=0; i<visibleItems.count(); i++) {
- if (!visibleItems.at(i)->transitionScheduledOrRunning())
- visibleItems.at(i)->transitionNextReposition(transitioner, QQuickItemViewTransitioner::PopulateTransition, true);
+ for (FxViewItem *item : qAsConst(visibleItems)) {
+ if (!item->transitionScheduledOrRunning())
+ item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::PopulateTransition, true);
}
}
@@ -2010,18 +2009,18 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
ChangeResult removalResult(prevViewPos);
int removedCount = 0;
- for (int i=0; i<removals.count(); i++) {
- itemCount -= removals[i].count;
- if (applyRemovalChange(removals[i], &removalResult, &removedCount))
+ for (const QQmlChangeSet::Change &r : removals) {
+ itemCount -= r.count;
+ if (applyRemovalChange(r, &removalResult, &removedCount))
visibleAffected = true;
- if (!visibleAffected && needsRefillForAddedOrRemovedIndex(removals[i].index))
+ if (!visibleAffected && needsRefillForAddedOrRemovedIndex(r.index))
visibleAffected = true;
const int correctedFirstVisibleIndex = prevFirstVisibleIndex - removalResult.countChangeBeforeVisible;
- if (correctedFirstVisibleIndex >= 0 && removals[i].index < correctedFirstVisibleIndex) {
- if (removals[i].index + removals[i].count < correctedFirstVisibleIndex)
- removalResult.countChangeBeforeVisible += removals[i].count;
+ if (correctedFirstVisibleIndex >= 0 && r.index < correctedFirstVisibleIndex) {
+ if (r.index + r.count < correctedFirstVisibleIndex)
+ removalResult.countChangeBeforeVisible += r.count;
else
- removalResult.countChangeBeforeVisible += (correctedFirstVisibleIndex - removals[i].index);
+ removalResult.countChangeBeforeVisible += (correctedFirstVisibleIndex - r.index);
}
}
if (runDelayedRemoveTransition) {
@@ -2068,23 +2067,23 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
}
itemCount += insertions[i].count;
}
- for (int i=0; i<newItems.count(); i++) {
- if (newItems.at(i)->attached)
- newItems.at(i)->attached->emitAdd();
+ for (FxViewItem *item : qAsConst(newItems)) {
+ if (item->attached)
+ item->attached->emitAdd();
}
// for each item that was moved directly into the view as a result of a move(),
// find the index it was moved from in order to set its initial position, so that we
// can transition it from this "original" position to its new position in the view
if (transitioner && transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition, true)) {
- for (int i=0; i<movingIntoView.count(); i++) {
- int fromIndex = findMoveKeyIndex(movingIntoView.at(i).moveKey, removals);
+ for (const MovedItem &m : qAsConst(movingIntoView)) {
+ int fromIndex = findMoveKeyIndex(m.moveKey, removals);
if (fromIndex >= 0) {
if (prevFirstVisibleIndex >= 0 && fromIndex < prevFirstVisibleIndex)
- repositionItemAt(movingIntoView.at(i).item, fromIndex, -totalInsertionResult->sizeChangesAfterVisiblePos);
+ repositionItemAt(m.item, fromIndex, -totalInsertionResult->sizeChangesAfterVisiblePos);
else
- repositionItemAt(movingIntoView.at(i).item, fromIndex, totalInsertionResult->sizeChangesAfterVisiblePos);
- movingIntoView.at(i).item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true);
+ repositionItemAt(m.item, fromIndex, totalInsertionResult->sizeChangesAfterVisiblePos);
+ m.item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true);
}
}
}
@@ -2345,7 +2344,7 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous)
if (!delegateValidated) {
delegateValidated = true;
QObject* delegate = q->delegate();
- qmlInfo(delegate ? delegate : q) << QQuickItemView::tr("Delegate must be of Item type");
+ qmlWarning(delegate ? delegate : q) << QQuickItemView::tr("Delegate must be of Item type");
}
}
inRequest = false;
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 3ac54ea3dc..b38bc6174f 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -232,10 +232,10 @@ public:
Q_INVOKABLE void positionViewAtEnd();
Q_REVISION(1) Q_INVOKABLE void forceLayout();
- void setContentX(qreal pos) Q_DECL_OVERRIDE;
- void setContentY(qreal pos) Q_DECL_OVERRIDE;
- qreal originX() const Q_DECL_OVERRIDE;
- qreal originY() const Q_DECL_OVERRIDE;
+ void setContentX(qreal pos) override;
+ void setContentY(qreal pos) override;
+ qreal originX() const override;
+ qreal originY() const override;
Q_SIGNALS:
void modelChanged();
@@ -277,13 +277,13 @@ Q_SIGNALS:
void highlightMoveDurationChanged();
protected:
- void updatePolish() Q_DECL_OVERRIDE;
- void componentComplete() Q_DECL_OVERRIDE;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- qreal minYExtent() const Q_DECL_OVERRIDE;
- qreal maxYExtent() const Q_DECL_OVERRIDE;
- qreal minXExtent() const Q_DECL_OVERRIDE;
- qreal maxXExtent() const Q_DECL_OVERRIDE;
+ void updatePolish() override;
+ void componentComplete() override;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ qreal minYExtent() const override;
+ qreal maxYExtent() const override;
+ qreal minXExtent() const override;
+ qreal maxXExtent() const override;
protected Q_SLOTS:
void destroyRemoved();
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index a8e66301c1..3087682ac7 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -201,10 +201,10 @@ public:
void regenerate(bool orientationChanged=false);
void layout();
- virtual void animationFinished(QAbstractAnimationJob *) Q_DECL_OVERRIDE;
+ virtual void animationFinished(QAbstractAnimationJob *) override;
void refill();
void refill(qreal from, qreal to);
- void mirrorChange() Q_DECL_OVERRIDE;
+ void mirrorChange() override;
FxViewItem *createItem(int modelIndex, bool asynchronous = false);
virtual bool releaseItem(FxViewItem *item);
@@ -236,7 +236,7 @@ public:
void prepareVisibleItemTransitions();
void prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems);
bool prepareNonVisibleItemTransition(FxViewItem *item, const QRectF &viewBounds);
- void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) Q_DECL_OVERRIDE;
+ void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) override;
int findMoveKeyIndex(QQmlChangeSet::MoveKey key, const QVector<QQmlChangeSet::Change> &changes) const;
@@ -348,8 +348,8 @@ protected:
virtual bool showFooterForIndex(int index) const = 0;
virtual void updateHeader() = 0;
virtual void updateFooter() = 0;
- virtual bool hasStickyHeader() const { return false; };
- virtual bool hasStickyFooter() const { return false; };
+ virtual bool hasStickyHeader() const { return false; }
+ virtual bool hasStickyFooter() const { return false; }
virtual void createHighlight() = 0;
virtual void updateHighlight() = 0;
@@ -382,7 +382,7 @@ protected:
virtual void updateSectionCriteria() {}
virtual void updateSections() {}
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) override;
};
diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp
index 83c451613e..700c4cc620 100644
--- a/src/quick/items/qquickitemviewtransition.cpp
+++ b/src/quick/items/qquickitemviewtransition.cpp
@@ -64,7 +64,7 @@ public:
bool *m_wasDeleted;
protected:
- void finished() Q_DECL_OVERRIDE;
+ void finished() override;
};
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index f89a995e76..0351077f20 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -65,51 +65,51 @@ class QQuickListViewPrivate : public QQuickItemViewPrivate
public:
static QQuickListViewPrivate* get(QQuickListView *item) { return item->d_func(); }
- Qt::Orientation layoutOrientation() const Q_DECL_OVERRIDE;
- bool isContentFlowReversed() const Q_DECL_OVERRIDE;
+ Qt::Orientation layoutOrientation() const override;
+ bool isContentFlowReversed() const override;
bool isRightToLeft() const;
bool isBottomToTop() const;
- qreal positionAt(int index) const Q_DECL_OVERRIDE;
- qreal endPositionAt(int index) const Q_DECL_OVERRIDE;
- qreal originPosition() const Q_DECL_OVERRIDE;
- qreal lastPosition() const Q_DECL_OVERRIDE;
+ qreal positionAt(int index) const override;
+ qreal endPositionAt(int index) const override;
+ qreal originPosition() const override;
+ qreal lastPosition() const override;
FxViewItem *itemBefore(int modelIndex) const;
QString sectionAt(int modelIndex);
qreal snapPosAt(qreal pos);
FxViewItem *snapItemAt(qreal pos);
- void init() Q_DECL_OVERRIDE;
- void clear() Q_DECL_OVERRIDE;
+ void init() override;
+ void clear() override;
- bool addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer) Q_DECL_OVERRIDE;
- bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) Q_DECL_OVERRIDE;
- void visibleItemsChanged() Q_DECL_OVERRIDE;
+ bool addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer) override;
+ bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) override;
+ void visibleItemsChanged() override;
void removeItem(FxViewItem *item);
- FxViewItem *newViewItem(int index, QQuickItem *item) Q_DECL_OVERRIDE;
- void initializeViewItem(FxViewItem *item) Q_DECL_OVERRIDE;
- bool releaseItem(FxViewItem *item) Q_DECL_OVERRIDE;
- void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) Q_DECL_OVERRIDE;
- void repositionPackageItemAt(QQuickItem *item, int index) Q_DECL_OVERRIDE;
- void resetFirstItemPosition(qreal pos = 0.0) Q_DECL_OVERRIDE;
- void adjustFirstItem(qreal forwards, qreal backwards, int) Q_DECL_OVERRIDE;
- void updateSizeChangesBeforeVisiblePos(FxViewItem *item, ChangeResult *removeResult) Q_DECL_OVERRIDE;
+ FxViewItem *newViewItem(int index, QQuickItem *item) override;
+ void initializeViewItem(FxViewItem *item) override;
+ bool releaseItem(FxViewItem *item) override;
+ void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) override;
+ void repositionPackageItemAt(QQuickItem *item, int index) override;
+ void resetFirstItemPosition(qreal pos = 0.0) override;
+ void adjustFirstItem(qreal forwards, qreal backwards, int) override;
+ void updateSizeChangesBeforeVisiblePos(FxViewItem *item, ChangeResult *removeResult) override;
- void createHighlight() Q_DECL_OVERRIDE;
- void updateHighlight() Q_DECL_OVERRIDE;
- void resetHighlightPosition() Q_DECL_OVERRIDE;
+ void createHighlight() override;
+ void updateHighlight() override;
+ void resetHighlightPosition() override;
- void setPosition(qreal pos) Q_DECL_OVERRIDE;
- void layoutVisibleItems(int fromModelIndex = 0) Q_DECL_OVERRIDE;
+ void setPosition(qreal pos) override;
+ void layoutVisibleItems(int fromModelIndex = 0) override;
- bool applyInsertionChange(const QQmlChangeSet::Change &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView) Q_DECL_OVERRIDE;
- void translateAndTransitionItemsAfter(int afterIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult) Q_DECL_OVERRIDE;
+ bool applyInsertionChange(const QQmlChangeSet::Change &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView) override;
+ void translateAndTransitionItemsAfter(int afterIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult) override;
- void updateSectionCriteria() Q_DECL_OVERRIDE;
- void updateSections() Q_DECL_OVERRIDE;
+ void updateSectionCriteria() override;
+ void updateSections() override;
QQuickItem *getSectionItem(const QString &section);
void releaseSectionItem(QQuickItem *item);
void releaseSectionItems();
@@ -117,25 +117,25 @@ public:
void updateCurrentSection();
void updateStickySections();
- qreal headerSize() const Q_DECL_OVERRIDE;
- qreal footerSize() const Q_DECL_OVERRIDE;
- bool showHeaderForIndex(int index) const Q_DECL_OVERRIDE;
- bool showFooterForIndex(int index) const Q_DECL_OVERRIDE;
- void updateHeader() Q_DECL_OVERRIDE;
- void updateFooter() Q_DECL_OVERRIDE;
- bool hasStickyHeader() const Q_DECL_OVERRIDE;
- bool hasStickyFooter() const Q_DECL_OVERRIDE;
+ qreal headerSize() const override;
+ qreal footerSize() const override;
+ bool showHeaderForIndex(int index) const override;
+ bool showFooterForIndex(int index) const override;
+ void updateHeader() override;
+ void updateFooter() override;
+ bool hasStickyHeader() const override;
+ bool hasStickyFooter() const override;
- void changedVisibleIndex(int newIndex) Q_DECL_OVERRIDE;
- void initializeCurrentItem() Q_DECL_OVERRIDE;
+ void changedVisibleIndex(int newIndex) override;
+ void initializeCurrentItem() override;
void updateAverage();
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- void fixupPosition() Q_DECL_OVERRIDE;
- void fixup(AxisData &data, qreal minExtent, qreal maxExtent) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) override;
+ void fixupPosition() override;
+ void fixup(AxisData &data, qreal minExtent, qreal maxExtent) override;
bool flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
- QQuickTimeLineCallback::Callback fixupCallback, qreal velocity) Q_DECL_OVERRIDE;
+ QQuickTimeLineCallback::Callback fixupCallback, qreal velocity) override;
QQuickListView::Orientation orient;
qreal visiblePos;
@@ -263,7 +263,7 @@ public:
static_cast<QQuickListViewAttached*>(attached)->m_sectionItem = s;
}
- qreal position() const Q_DECL_OVERRIDE {
+ qreal position() const override {
if (section()) {
if (view->orientation() == QQuickListView::Vertical)
return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop ? -section()->height()-section()->y() : section()->y());
@@ -279,7 +279,7 @@ public:
else
return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -itemWidth()-itemX() : itemX());
}
- qreal size() const Q_DECL_OVERRIDE {
+ qreal size() const override {
if (section())
return (view->orientation() == QQuickListView::Vertical ? itemHeight()+section()->height() : itemWidth()+section()->width());
else
@@ -288,12 +288,12 @@ public:
qreal itemSize() const {
return (view->orientation() == QQuickListView::Vertical ? itemHeight() : itemWidth());
}
- qreal sectionSize() const Q_DECL_OVERRIDE {
+ qreal sectionSize() const override {
if (section())
return (view->orientation() == QQuickListView::Vertical ? section()->height() : section()->width());
return 0.0;
}
- qreal endPosition() const Q_DECL_OVERRIDE {
+ qreal endPosition() const override {
if (view->orientation() == QQuickListView::Vertical) {
return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop
? -itemY()
@@ -327,7 +327,7 @@ public:
else
item->setWidth(size);
}
- bool contains(qreal x, qreal y) const Q_DECL_OVERRIDE {
+ bool contains(qreal x, qreal y) const override {
return (x >= itemX() && x < itemX() + itemWidth() &&
y >= itemY() && y < itemY() + itemHeight());
}
@@ -438,11 +438,12 @@ qreal QQuickListViewPrivate::lastPosition() const
int invisibleCount = INT_MIN;
int delayRemovedCount = 0;
for (int i = visibleItems.count()-1; i >= 0; --i) {
- if (visibleItems.at(i)->index != -1) {
+ FxViewItem *item = visibleItems.at(i);
+ if (item->index != -1) {
// Find the invisible count after the last visible item with known index
- invisibleCount = model->count() - (visibleItems.at(i)->index + 1 + delayRemovedCount);
+ invisibleCount = model->count() - (item->index + 1 + delayRemovedCount);
break;
- } else if (visibleItems.at(i)->attached->delayRemove()) {
+ } else if (item->attached->delayRemove()) {
++delayRemovedCount;
}
}
@@ -530,8 +531,7 @@ FxViewItem *QQuickListViewPrivate::snapItemAt(qreal pos)
{
FxViewItem *snapItem = 0;
qreal prevItemSize = 0;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
+ for (FxViewItem *item : qAsConst(visibleItems)) {
if (item->index == -1)
continue;
qreal itemTop = item->position();
@@ -660,8 +660,8 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
int newModelIdx = qBound(0, modelIndex + count, model->count());
count = newModelIdx - modelIndex;
if (count) {
- for (int i = 0; i < visibleItems.count(); ++i)
- releaseItem(visibleItems.at(i));
+ for (FxViewItem *item : qAsConst(visibleItems))
+ releaseItem(item);
visibleItems.clear();
modelIndex = newModelIdx;
visibleIndex = modelIndex;
@@ -1008,8 +1008,8 @@ void QQuickListViewPrivate::releaseSectionItem(QQuickItem *item)
void QQuickListViewPrivate::releaseSectionItems()
{
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxListItemSG *listItem = static_cast<FxListItemSG *>(visibleItems.at(i));
+ for (FxViewItem *item : qAsConst(visibleItems)) {
+ FxListItemSG *listItem = static_cast<FxListItemSG *>(item);
if (listItem->section()) {
qreal pos = listItem->position();
releaseSectionItem(listItem->section());
@@ -1168,16 +1168,15 @@ void QQuickListViewPrivate::updateSections()
QQuickListViewAttached *prevAtt = 0;
int prevIdx = -1;
int idx = -1;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
+ for (FxViewItem *item : qAsConst(visibleItems)) {
QQuickListViewAttached *attached = static_cast<QQuickListViewAttached*>(item->attached);
attached->setPrevSection(prevSection);
- if (visibleItems.at(i)->index != -1) {
- QString propValue = model->stringValue(visibleItems.at(i)->index, sectionCriteria->property());
+ if (item->index != -1) {
+ QString propValue = model->stringValue(item->index, sectionCriteria->property());
attached->setSection(sectionCriteria->sectionString(propValue));
- idx = visibleItems.at(i)->index;
+ idx = item->index;
}
- updateInlineSection(static_cast<FxListItemSG*>(visibleItems.at(i)));
+ updateInlineSection(static_cast<FxListItemSG*>(item));
if (prevAtt)
prevAtt->setNextSection(sectionAt(prevIdx+1));
prevSection = attached->section();
@@ -1210,9 +1209,12 @@ void QQuickListViewPrivate::updateCurrentSection()
qreal startPos = hasStickyHeader() ? header->endPosition() : viewPos;
int index = 0;
int modelIndex = visibleIndex;
- while (index < visibleItems.count() && visibleItems.at(index)->endPosition() <= startPos) {
- if (visibleItems.at(index)->index != -1)
- modelIndex = visibleItems.at(index)->index;
+ while (index < visibleItems.count()) {
+ FxViewItem *item = visibleItems.at(index);
+ if (item->endPosition() > startPos)
+ break;
+ if (item->index != -1)
+ modelIndex = item->index;
++index;
}
@@ -1236,10 +1238,13 @@ void QQuickListViewPrivate::updateCurrentSection()
qreal endPos = hasStickyFooter() ? footer->position() : viewPos + size();
if (nextSectionItem && !inlineSections)
endPos -= orient == QQuickListView::Vertical ? nextSectionItem->height() : nextSectionItem->width();
- while (index < visibleItems.count() && static_cast<FxListItemSG*>(visibleItems.at(index))->itemPosition() < endPos) {
- if (visibleItems.at(index)->index != -1)
- modelIndex = visibleItems.at(index)->index;
- lastSection = visibleItems.at(index)->attached->section();
+ while (index < visibleItems.count()) {
+ FxListItemSG *listItem = static_cast<FxListItemSG *>(visibleItems.at(index));
+ if (listItem->itemPosition() >= endPos)
+ break;
+ if (listItem->index != -1)
+ modelIndex = listItem->index;
+ lastSection = listItem->attached->section();
++index;
}
@@ -1288,8 +1293,8 @@ void QQuickListViewPrivate::updateAverage()
if (!visibleItems.count())
return;
qreal sum = 0.0;
- for (int i = 0; i < visibleItems.count(); ++i)
- sum += visibleItems.at(i)->size();
+ for (FxViewItem *item : qAsConst(visibleItems))
+ sum += item->size();
averageSize = qRound(sum / visibleItems.count());
}
@@ -1462,9 +1467,15 @@ void QQuickListViewPrivate::fixupPosition()
void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
{
- if ((orient == QQuickListView::Horizontal && &data == &vData)
- || (orient == QQuickListView::Vertical && &data == &hData))
+ if (orient == QQuickListView::Horizontal && &data == &vData) {
+ if (flickableDirection != QQuickFlickable::HorizontalFlick)
+ QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
+ return;
+ } else if (orient == QQuickListView::Vertical && &data == &hData) {
+ if (flickableDirection != QQuickFlickable::VerticalFlick)
+ QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
return;
+ }
correctFlick = false;
fixupMode = moveReason == Mouse ? fixupMode : Immediate;
@@ -1813,6 +1824,19 @@ bool QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
\image listview-layout-righttoleft.png
\endtable
+ \section1 Flickable Direction
+
+ By default, a vertical ListView sets \l {Flickable::}{flickableDirection} to \e Flickable.Vertical,
+ and a horizontal ListView sets it to \e Flickable.Horizontal. Furthermore, a vertical ListView only
+ calculates (estimates) the \l {Flickable::}{contentHeight}, and a horizontal ListView only calculates
+ the \l {Flickable::}{contentWidth}. The other dimension is set to \e -1.
+
+ Since Qt 5.9 (Qt Quick 2.9), it is possible to make a ListView that can be flicked to both directions.
+ In order to do this, the \l {Flickable::}{flickableDirection} can be set to \e Flickable.AutoFlickDirection
+ or \e Flickable.AutoFlickIfNeeded, and the desired \e contentWidth or \e contentHeight must be provided.
+
+ \snippet qml/listview/listview.qml flickBothDirections
+
\sa {QML Data Models}, GridView, PathView, {Qt Quick Examples - Views}
*/
QQuickListView::QQuickListView(QQuickItem *parent)
@@ -2099,6 +2123,8 @@ void QQuickListView::setSpacing(qreal spacing)
\li Vertical orientation:
\image listview-highlight.png
\endtable
+
+ \sa {Flickable Direction}
*/
QQuickListView::Orientation QQuickListView::orientation() const
{
@@ -2112,12 +2138,18 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
if (d->orient != orientation) {
d->orient = orientation;
if (d->orient == Vertical) {
- setContentWidth(-1);
- setFlickableDirection(VerticalFlick);
+ if (d->flickableDirection == HorizontalFlick) {
+ setFlickableDirection(VerticalFlick);
+ if (isComponentComplete())
+ setContentWidth(-1);
+ }
setContentX(0);
} else {
- setContentHeight(-1);
- setFlickableDirection(HorizontalFlick);
+ if (d->flickableDirection == VerticalFlick) {
+ setFlickableDirection(HorizontalFlick);
+ if (isComponentComplete())
+ setContentHeight(-1);
+ }
setContentY(0);
}
d->regenerate(true);
@@ -2899,8 +2931,7 @@ void QQuickListView::viewportMoved(Qt::Orientations orient)
// Set visibility of items to eliminate cost of items outside the visible area.
qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
- for (int i = 0; i < d->visibleItems.count(); ++i) {
- FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i));
+ for (FxViewItem *item : qAsConst(d->visibleItems)) {
if (item->item)
QQuickItemPrivate::get(item->item)->setCulled(item->endPosition() < from || item->position() > to);
}
@@ -3042,6 +3073,21 @@ void QQuickListView::initItem(int index, QObject *object)
}
}
+qreal QQuickListView::maxYExtent() const
+{
+ Q_D(const QQuickListView);
+ if (d->layoutOrientation() == Qt::Horizontal && d->flickableDirection != HorizontalFlick)
+ return QQuickFlickable::maxYExtent();
+ return QQuickItemView::maxYExtent();
+}
+
+qreal QQuickListView::maxXExtent() const
+{
+ Q_D(const QQuickListView);
+ if (d->layoutOrientation() == Qt::Vertical && d->flickableDirection != VerticalFlick)
+ return QQuickFlickable::maxXExtent();
+ return QQuickItemView::maxXExtent();
+}
/*!
\qmlmethod QtQuick::ListView::incrementCurrentIndex()
@@ -3120,8 +3166,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
if (modelIndex < visibleIndex) {
// Insert before visible items
visibleIndex += count;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
+ for (FxViewItem *item : qAsConst(visibleItems)) {
if (item->index != -1 && item->index >= modelIndex)
item->index += count;
}
@@ -3138,8 +3183,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
}
// Update the indexes of the following visible items.
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
+ for (FxViewItem *item : qAsConst(visibleItems)) {
if (item->index != -1 && item->index >= modelIndex) {
item->index += count;
if (change.isMove())
@@ -3281,8 +3325,10 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
qreal sizeRemoved = -removalResult.sizeChangesAfterVisiblePos
- (removalResult.countChangeAfterVisibleItems * (averageSize + spacing));
- for (int i=markerItemIndex+1; i<visibleItems.count() && visibleItems.at(i)->position() < viewEndPos; i++) {
+ for (int i=markerItemIndex+1; i<visibleItems.count(); i++) {
FxListItemSG *listItem = static_cast<FxListItemSG *>(visibleItems.at(i));
+ if (listItem->position() >= viewEndPos)
+ break;
if (!listItem->transitionScheduledOrRunning()) {
qreal pos = listItem->position();
listItem->setPosition(pos - sizeRemoved);
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index 3a871e88e9..f8db0f0f8f 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -146,7 +146,7 @@ public:
QQuickViewSection *sectionCriteria();
QString currentSection() const;
- void setHighlightFollowsCurrentItem(bool) Q_DECL_OVERRIDE;
+ void setHighlightFollowsCurrentItem(bool) override;
qreal highlightMoveVelocity() const;
void setHighlightMoveVelocity(qreal);
@@ -157,7 +157,7 @@ public:
int highlightResizeDuration() const;
void setHighlightResizeDuration(int);
- void setHighlightMoveDuration(int) Q_DECL_OVERRIDE;
+ void setHighlightMoveDuration(int) override;
enum SnapMode { NoSnap, SnapToItem, SnapOneItem };
Q_ENUM(SnapMode)
@@ -192,10 +192,12 @@ Q_SIGNALS:
Q_REVISION(2) void footerPositioningChanged();
protected:
- void viewportMoved(Qt::Orientations orient) Q_DECL_OVERRIDE;
- void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;
- void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- void initItem(int index, QObject *item) Q_DECL_OVERRIDE;
+ void viewportMoved(Qt::Orientations orient) override;
+ void keyPressEvent(QKeyEvent *) override;
+ void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry) override;
+ void initItem(int index, QObject *item) override;
+ qreal maxYExtent() const override;
+ qreal maxXExtent() const override;
};
class QQuickListViewAttached : public QQuickItemViewAttached
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index eeec562e3c..5d5934bbd2 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -971,7 +971,7 @@ QV4::ReturnedValue QQuickLoaderPrivate::extractInitialPropertyValues(QQmlV4Funct
QV4::ScopedValue v(scope, (*args)[1]);
if (!v->isObject() || v->as<QV4::ArrayObject>()) {
*error = true;
- qmlInfo(loader) << QQuickLoader::tr("setSource: value is not an object");
+ qmlWarning(loader) << QQuickLoader::tr("setSource: value is not an object");
} else {
*error = false;
valuemap = v;
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 79c957832a..bb23b1fd54 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -206,6 +206,9 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
the proxied item. When disabled, the mouse area becomes transparent to
mouse events.
+ MouseArea is an invisible Item, but it has a visible property.
+ When set to false, the mouse area becomes transparent to mouse events.
+
The \l pressed read-only property indicates whether or not the user is
holding down a mouse button over the mouse area. This property is often
used in bindings between properties in a user interface. The containsMouse
@@ -341,7 +344,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
position of the release of the click, and whether the click was held.
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
- parameter has no effect.
+ parameter has no effect, unless the \l propagateComposedEvents property is \c true.
The corresponding handler is \c onClicked.
*/
@@ -385,7 +388,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
position of the press, and which button is pressed.
When handling this signal, changing the \l {MouseEvent::}{accepted} property of the \a mouse
- parameter has no effect.
+ parameter has no effect, unless the \l propagateComposedEvents property is \c true.
The corresponding handler is \c onPressAndHold.
*/
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 706980cd13..62119effb2 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -60,6 +60,8 @@ DEFINE_BOOL_CONFIG_OPTION(qmlVisualTouchDebugging, QML_VISUAL_TOUCH_DEBUGGING)
The TouchPoint type contains information about a touch point, such as the current
position, pressure, and area.
+
+ \image touchpoint-metrics.png
*/
/*!
@@ -101,16 +103,29 @@ void QQuickTouchPoint::setY(qreal y)
}
/*!
+ \qmlproperty size QtQuick::TouchPoint::ellipseDiameters
+ \since 5.9
+
+ This property holds the major and minor axes of the ellipse representing
+ the covered area of the touch point.
+*/
+void QQuickTouchPoint::setEllipseDiameters(const QSizeF &d)
+{
+ if (_ellipseDiameters == d)
+ return;
+ _ellipseDiameters = d;
+ emit ellipseDiametersChanged();
+}
+
+/*!
\qmlproperty real QtQuick::TouchPoint::pressure
\qmlproperty vector2d QtQuick::TouchPoint::velocity
- \qmlproperty rectangle QtQuick::TouchPoint::area
These properties hold additional information about the current state of the touch point.
\list
\li \c pressure is a value in the range of 0.0 to 1.0.
\li \c velocity is a vector with magnitude reported in pixels per second.
- \li \c area is a rectangle covering the area of the touch point, centered on the current position of the touch point.
\endlist
Not all touch devices support velocity. If velocity is not supported, it will be reported
@@ -124,6 +139,26 @@ void QQuickTouchPoint::setPressure(qreal pressure)
emit pressureChanged();
}
+/*!
+ \qmlproperty real QtQuick::TouchPoint::rotation
+ \since 5.9
+
+ This property holds the angular orientation of this touch point. The return
+ value is in degrees, where zero (the default) indicates the finger or token
+ is pointing upwards, a negative angle means it's rotated to the left, and a
+ positive angle means it's rotated to the right. Most touchscreens do not
+ detect rotation, so zero is the most common value.
+
+ \sa QTouchEvent::TouchPoint::rotation()
+*/
+void QQuickTouchPoint::setRotation(qreal r)
+{
+ if (_rotation == r)
+ return;
+ _rotation = r;
+ emit rotationChanged();
+}
+
void QQuickTouchPoint::setVelocity(const QVector2D &velocity)
{
if (_velocity == velocity)
@@ -132,6 +167,18 @@ void QQuickTouchPoint::setVelocity(const QVector2D &velocity)
emit velocityChanged();
}
+/*!
+ \deprecated
+ \qmlproperty rectangle QtQuick::TouchPoint::area
+
+ A rectangle covering the area of the touch point, centered on the current
+ position of the touch point.
+
+ It is deprecated because a touch point is more correctly modeled as an ellipse,
+ whereas this rectangle represents the outer bounds of the ellipse after \l rotation.
+
+ \sa horizontalDiameter, verticalDiameter
+*/
void QQuickTouchPoint::setArea(const QRectF &area)
{
if (_area == area)
@@ -222,6 +269,25 @@ void QQuickTouchPoint::setSceneY(qreal sceneY)
}
/*!
+ \qmlproperty PointingDeviceUniqueId QtQuick::TouchPoint::uniqueId
+ \since 5.9
+
+ This property holds the unique ID of the touch point or token.
+
+ It is normally empty, because touchscreens cannot uniquely identify fingers.
+ But when it is set, it is expected to uniquely identify a specific token
+ (fiducial object).
+
+ Interpreting the contents of this ID requires knowledge of the hardware and
+ drivers in use (e.g. various TUIO-based touch surfaces).
+*/
+void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
+{
+ _uniqueId = id;
+ emit uniqueIdChanged();
+}
+
+/*!
\qmltype MultiPointTouchArea
\instantiates QQuickMultiPointTouchArea
\inqmlmodule QtQuick
@@ -691,9 +757,12 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QT
{
//TODO: if !qmlDefined, could bypass setters.
// also, should only emit signals after all values have been set
+ dtp->setUniqueId(p->uniqueId());
dtp->setX(p->pos().x());
dtp->setY(p->pos().y());
+ dtp->setEllipseDiameters(p->ellipseDiameters());
dtp->setPressure(p->pressure());
+ dtp->setRotation(p->rotation());
dtp->setVelocity(p->velocity());
dtp->setArea(p->rect());
dtp->setStartX(p->startPos().x());
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index 541eb04764..25e1056712 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -67,10 +67,13 @@ class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject
{
Q_OBJECT
Q_PROPERTY(int pointId READ pointId NOTIFY pointIdChanged)
+ Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId NOTIFY uniqueIdChanged REVISION 9)
Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
Q_PROPERTY(qreal x READ x NOTIFY xChanged)
Q_PROPERTY(qreal y READ y NOTIFY yChanged)
+ Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters NOTIFY ellipseDiametersChanged REVISION 9)
Q_PROPERTY(qreal pressure READ pressure NOTIFY pressureChanged)
+ Q_PROPERTY(qreal rotation READ rotation NOTIFY rotationChanged REVISION 9)
Q_PROPERTY(QVector2D velocity READ velocity NOTIFY velocityChanged)
Q_PROPERTY(QRectF area READ area NOTIFY areaChanged)
@@ -86,6 +89,7 @@ public:
: _id(0),
_x(0.0), _y(0.0),
_pressure(0.0),
+ _rotation(0),
_qmlDefined(qmlDefined),
_inUse(false),
_pressed(false),
@@ -97,15 +101,24 @@ public:
int pointId() const { return _id; }
void setPointId(int id);
+ QPointingDeviceUniqueId uniqueId() const { return _uniqueId; }
+ void setUniqueId(const QPointingDeviceUniqueId &id);
+
qreal x() const { return _x; }
void setX(qreal x);
qreal y() const { return _y; }
void setY(qreal y);
+ QSizeF ellipseDiameters() const { return _ellipseDiameters; }
+ void setEllipseDiameters(const QSizeF &d);
+
qreal pressure() const { return _pressure; }
void setPressure(qreal pressure);
+ qreal rotation() const { return _rotation; }
+ void setRotation(qreal r);
+
QVector2D velocity() const { return _velocity; }
void setVelocity(const QVector2D &velocity);
@@ -141,9 +154,12 @@ public:
Q_SIGNALS:
void pressedChanged();
void pointIdChanged();
+ Q_REVISION(9) void uniqueIdChanged();
void xChanged();
void yChanged();
+ Q_REVISION(9) void ellipseDiametersChanged();
void pressureChanged();
+ Q_REVISION(9) void rotationChanged();
void velocityChanged();
void areaChanged();
void startXChanged();
@@ -159,6 +175,8 @@ private:
qreal _x;
qreal _y;
qreal _pressure;
+ qreal _rotation;
+ QSizeF _ellipseDiameters;
QVector2D _velocity;
QRectF _area;
bool _qmlDefined;
@@ -170,6 +188,7 @@ private:
qreal _previousY;
qreal _sceneX;
qreal _sceneY;
+ QPointingDeviceUniqueId _uniqueId;
};
class QQuickGrabGestureEvent : public QObject
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 11881ae0ab..53e547fe98 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -137,7 +137,7 @@ QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool async)
if (!delegateValidated) {
delegateValidated = true;
QObject* delegate = q->delegate();
- qmlInfo(delegate ? delegate : q) << QQuickPathView::tr("Delegate must be of Item type");
+ qmlWarning(delegate ? delegate : q) << QQuickPathView::tr("Delegate must be of Item type");
}
}
} else {
@@ -704,16 +704,23 @@ void QQuickPathView::setPath(QQuickPath *path)
qmlobject_disconnect(d->path, QQuickPath, SIGNAL(changed()),
this, QQuickPathView, SLOT(pathUpdated()));
d->path = path;
- qmlobject_connect(d->path, QQuickPath, SIGNAL(changed()),
- this, QQuickPathView, SLOT(pathUpdated()));
- if (d->isValid() && isComponentComplete()) {
+
+ if (path) {
+ qmlobject_connect(d->path, QQuickPath, SIGNAL(changed()),
+ this, QQuickPathView, SLOT(pathUpdated()));
+ }
+
+ if (isComponentComplete()) {
d->clear();
- if (d->attType) {
- d->attType->release();
- d->attType = nullptr;
+ if (d->isValid()) {
+ if (d->attType) {
+ d->attType->release();
+ d->attType = nullptr;
+ }
+ d->regenerate();
}
- d->regenerate();
}
+
emit pathChanged();
}
diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h
index 669ef60ef7..0e237b7b74 100644
--- a/src/quick/items/qquickpathview_p.h
+++ b/src/quick/items/qquickpathview_p.h
@@ -221,14 +221,14 @@ Q_SIGNALS:
void cacheItemCountChanged();
protected:
- void updatePolish() Q_DECL_OVERRIDE;
- void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;
+ void updatePolish() override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *) override;
bool sendMouseEvent(QMouseEvent *event);
- bool childMouseEventFilter(QQuickItem *, QEvent *) Q_DECL_OVERRIDE;
- void mouseUngrabEvent() Q_DECL_OVERRIDE;
- void componentComplete() Q_DECL_OVERRIDE;
+ bool childMouseEventFilter(QQuickItem *, QEvent *) override;
+ void mouseUngrabEvent() override;
+ void componentComplete() override;
private Q_SLOTS:
void refill();
diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h
index 082f427f2c..d58c986d1a 100644
--- a/src/quick/items/qquickpathview_p_p.h
+++ b/src/quick/items/qquickpathview_p_p.h
@@ -80,7 +80,7 @@ public:
void init();
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) Q_DECL_OVERRIDE {
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) override {
if (change.sizeChange() && (!highlightItem || item != highlightItem)) {
if (QQuickPathViewAttached *att = attached(item))
att->m_percent = -1;
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index e22427ca49..05d3ae0191 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -290,6 +290,11 @@ void QQuickBasePositioner::itemChange(ItemChange change, const ItemChangeData &v
QQuickItem::itemChange(change, value);
}
+void QQuickBasePositioner::forceLayout()
+{
+ updatePolish();
+}
+
void QQuickBasePositioner::prePositioning()
{
Q_D(QQuickBasePositioner);
@@ -401,6 +406,8 @@ void QQuickBasePositioner::prePositioning()
//Set implicit size to the size of its children
setImplicitSize(contentSize.width(), contentSize.height());
+
+ emit positioningComplete();
}
void QQuickBasePositioner::positionItem(qreal x, qreal y, PositionedItem *target)
@@ -910,6 +917,28 @@ void QQuickPositionerAttached::setIsLastItem(bool isLastItem)
\sa Grid::spacing
*/
+/*!
+ \qmlmethod QtQuick::Column::forceLayout()
+ \since 5.9
+
+ Column typically positions its children once per frame. This means that
+ inside script blocks it is possible for the underlying children to have changed,
+ but the Column to have not yet been updated accordingly.
+
+ This method forces the Column to immediately respond to any outstanding
+ changes in its children.
+
+ \b Note: methods in general should only be called after the Component has completed.
+*/
+/*!
+ \qmlsignal QtQuick::Column::positioningComplete()
+ \since 5.9
+
+ This signal is emitted when positioning has been completed.
+
+ The corresponding handler is \c onPositioningComplete.
+*/
+
QQuickColumn::QQuickColumn(QQuickItem *parent)
: QQuickBasePositioner(Vertical, parent)
{
@@ -957,7 +986,7 @@ void QQuickColumn::reportConflictingAnchors()
}
}
if (d->anchorConflict) {
- qmlInfo(this) << "Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column."
+ qmlWarning(this) << "Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column."
<< " Column will not function.";
}
}
@@ -1077,6 +1106,27 @@ void QQuickColumn::reportConflictingAnchors()
\sa Grid::spacing
*/
+/*!
+ \qmlmethod QtQuick::Row::forceLayout()
+ \since 5.9
+
+ Row typically positions its children once per frame. This means that
+ inside script blocks it is possible for the underlying children to have changed,
+ but the Row to have not yet been updated accordingly.
+
+ This method forces the Row to immediately respond to any outstanding
+ changes in its children.
+
+ \b Note: methods in general should only be called after the Component has completed.
+*/
+/*!
+ \qmlsignal QtQuick::Row::positioningComplete()
+ \since 5.9
+
+ This signal is emitted when positioning has been completed.
+
+ The corresponding handler is \c onPositioningComplete.
+*/
class QQuickRowPrivate : public QQuickBasePositionerPrivate
{
@@ -1224,7 +1274,7 @@ void QQuickRow::reportConflictingAnchors()
}
}
if (d->anchorConflict)
- qmlInfo(this) << "Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row."
+ qmlWarning(this) << "Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row."
<< " Row will not function.";
}
@@ -1355,6 +1405,27 @@ void QQuickRow::reportConflictingAnchors()
\sa rows, columns
*/
+/*!
+ \qmlmethod QtQuick::Grid::forceLayout()
+ \since 5.9
+
+ Grid typically positions its children once per frame. This means that
+ inside script blocks it is possible for the underlying children to have changed,
+ but the Grid to have not yet been updated accordingly.
+
+ This method forces the Grid to immediately respond to any outstanding
+ changes in its children.
+
+ \b Note: methods in general should only be called after the Component has completed.
+*/
+/*!
+ \qmlsignal QtQuick::Grid::positioningComplete()
+ \since 5.9
+
+ This signal is emitted when positioning has been completed.
+
+ The corresponding handler is \c onPositioningComplete.
+*/
class QQuickGridPrivate : public QQuickBasePositionerPrivate
{
@@ -1808,7 +1879,7 @@ void QQuickGrid::reportConflictingAnchors()
}
}
if (d->anchorConflict)
- qmlInfo(this) << "Cannot specify anchors for items inside Grid." << " Grid will not function.";
+ qmlWarning(this) << "Cannot specify anchors for items inside Grid." << " Grid will not function.";
}
/*!
@@ -1920,6 +1991,28 @@ void QQuickGrid::reportConflictingAnchors()
\sa Grid::spacing
*/
+/*!
+ \qmlmethod QtQuick::Flow::forceLayout()
+ \since 5.9
+
+ Flow typically positions its children once per frame. This means that
+ inside script blocks it is possible for the underlying children to have changed,
+ but the Flow to have not yet been updated accordingly.
+
+ This method forces the Flow to immediately respond to any outstanding
+ changes in its children.
+
+
+ \b Note: methods in general should only be called after the Component has completed.
+*/
+/*!
+ \qmlsignal QtQuick::Flow::positioningComplete()
+ \since 5.9
+
+ This signal is emitted when positioning has been completed.
+
+ The corresponding handler is \c onPositioningComplete.
+*/
class QQuickFlowPrivate : public QQuickBasePositionerPrivate
{
@@ -2121,7 +2214,7 @@ void QQuickFlow::reportConflictingAnchors()
}
}
if (d->anchorConflict)
- qmlInfo(this) << "Cannot specify anchors for items inside Flow." << " Flow will not function.";
+ qmlWarning(this) << "Cannot specify anchors for items inside Flow." << " Flow will not function.";
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index c25ecd6dbc..ae6e795794 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -155,6 +155,8 @@ public:
void setBottomPadding(qreal padding);
void resetBottomPadding();
+ Q_REVISION(9) Q_INVOKABLE void forceLayout();
+
protected:
QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent);
void componentComplete() Q_DECL_OVERRIDE;
@@ -172,6 +174,7 @@ Q_SIGNALS:
Q_REVISION(6) void leftPaddingChanged();
Q_REVISION(6) void rightPaddingChanged();
Q_REVISION(6) void bottomPaddingChanged();
+ Q_REVISION(9) void positioningComplete();
protected Q_SLOTS:
void prePositioning();
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index 4f46f41b0d..a7254464ed 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -423,7 +423,7 @@ void QQuickRepeater::initItem(int index, QObject *object)
if (!d->delegateValidated) {
d->delegateValidated = true;
QObject* delegate = this->delegate();
- qmlInfo(delegate ? delegate : this) << QQuickRepeater::tr("Delegate must be of Item type");
+ qmlWarning(delegate ? delegate : this) << QQuickRepeater::tr("Delegate must be of Item type");
}
}
return;
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index f54a8911b2..d26a1f8a64 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -378,7 +378,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize)
if (!m_errorsPrinted && stat == QQuickPixmap::Error) {
for (QQuickSprite* s : qAsConst(m_sprites))
if (s->m_pix.isError())
- qmlInfo(s) << s->m_pix.error();
+ qmlWarning(s) << s->m_pix.error();
m_errorsPrinted = true;
}
@@ -399,7 +399,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize)
{
const QSize frameSize(state->m_frameWidth, state->m_frameHeight);
if (!(img.size() - frameSize).isValid()) {
- qmlInfo(state).nospace() << "SpriteEngine: Invalid frame size " << frameSize << "."
+ qmlWarning(state).nospace() << "SpriteEngine: Invalid frame size " << frameSize << "."
" It's bigger than image size " << img.size() << ".";
return QImage();
}
@@ -419,10 +419,10 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize)
int rowsNeeded = helper::divRoundUp(state->frames(), (maxSize / state->frameWidth()));
if (h + rowsNeeded * state->frameHeight() > maxSize){
if (rowsNeeded * state->frameHeight() > maxSize)
- qmlInfo(state) << "SpriteEngine: Animation too large to fit in one texture:" << state->source().toLocalFile();
+ qmlWarning(state) << "SpriteEngine: Animation too large to fit in one texture:" << state->source().toLocalFile();
else
- qmlInfo(state) << "SpriteEngine: Animations too large to fit in one texture, pushed over the edge by:" << state->source().toLocalFile();
- qmlInfo(state) << "SpriteEngine: Your texture max size today is " << maxSize;
+ qmlWarning(state) << "SpriteEngine: Animations too large to fit in one texture, pushed over the edge by:" << state->source().toLocalFile();
+ qmlWarning(state) << "SpriteEngine: Your texture max size today is " << maxSize;
return QImage();
}
state->m_generatedCount = rowsNeeded;
diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp
index 25a39f951a..858a3c0576 100644
--- a/src/quick/items/qquickspritesequence.cpp
+++ b/src/quick/items/qquickspritesequence.cpp
@@ -209,7 +209,7 @@ QSGSpriteNode *QQuickSpriteSequence::initNode()
Q_D(QQuickSpriteSequence);
if (!d->m_spriteEngine) {
- qmlInfo(this) << "No sprite engine...";
+ qmlWarning(this) << "No sprite engine...";
return nullptr;
} else if (d->m_spriteEngine->status() == QQuickPixmap::Null) {
d->m_spriteEngine->startAssemblingImage();
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index 9cd3b6a5f5..b40a9e2843 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -78,7 +78,7 @@ void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *s
bool ok;
const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
if (transform.type() >= QTransform::TxShear || !ok) {
- qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under complex transform");
+ qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under complex transform");
ok = false;
}
@@ -89,21 +89,21 @@ void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *s
if (transform.m11() == transform.m22())
scale = transform.m11();
else {
- qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
+ qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
ok = false;
}
} else if (ok && isRotate) {
if (transform.m11() == transform.m22())
scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
else {
- qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
+ qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
ok = false;
}
if (scale != 0)
rotation = qAtan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
else {
- qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
+ qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
ok = false;
}
}
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index e37a7e6d5e..965fb0102f 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -1135,7 +1135,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
needToUpdateLayout = true;
}
} else if (image->pix->isError()) {
- qmlInfo(q) << image->pix->error();
+ qmlWarning(q) << image->pix->error();
}
}
@@ -2795,11 +2795,23 @@ void QQuickText::setRenderType(QQuickText::RenderType renderType)
/*!
\qmlmethod QtQuick::Text::doLayout()
+ \deprecated
- Triggers a re-layout of the displayed text.
+ Use \l forceLayout() instead.
*/
void QQuickText::doLayout()
{
+ forceLayout();
+}
+
+/*!
+ \qmlmethod QtQuick::Text::forceLayout()
+ \since 5.9
+
+ Triggers a re-layout of the displayed text.
+*/
+void QQuickText::forceLayout()
+{
Q_D(QQuickText);
d->updateSize();
}
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 40dbd51f39..c3d3906e7e 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -218,7 +218,8 @@ public:
QRectF boundingRect() const Q_DECL_OVERRIDE;
QRectF clipRect() const Q_DECL_OVERRIDE;
- Q_INVOKABLE void doLayout();
+ Q_INVOKABLE void doLayout(); // ### Qt 6: remove
+ Q_REVISION(9) Q_INVOKABLE void forceLayout();
RenderType renderType() const;
void setRenderType(RenderType renderType);
diff --git a/src/quick/items/qquicktextdocument.cpp b/src/quick/items/qquicktextdocument.cpp
index 61d75fe99b..c272503480 100644
--- a/src/quick/items/qquicktextdocument.cpp
+++ b/src/quick/items/qquicktextdocument.cpp
@@ -211,7 +211,7 @@ QQuickPixmap *QQuickTextDocumentWithImageResources::loadPixmap(
if (p->isError()) {
if (!errors.contains(url)) {
errors.insert(url);
- qmlInfo(parent()) << p->error();
+ qmlWarning(parent()) << p->error();
}
}
return p;
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 106acf57cf..075fd48a46 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -1729,7 +1729,9 @@ void QQuickTextEdit::select(int start, int end)
// QTBUG-11100
updateSelection();
+#if QT_CONFIG(im)
updateInputMethod();
+#endif
}
/*!
@@ -1741,7 +1743,7 @@ void QQuickTextEdit::select(int start, int end)
bool QQuickTextEdit::isRightToLeft(int start, int end)
{
if (start > end) {
- qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
+ qmlWarning(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
return false;
} else {
return getText(start, end).isRightToLeft();
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 27f3dcecfa..a023ad8a8c 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1152,6 +1152,17 @@ bool QQuickTextInput::hasAcceptableInput() const
The corresponding handler is \c onEditingFinished.
*/
+/*!
+ \qmlsignal QtQuick::TextInput::textEdited()
+ \since 5.9
+
+ This signal is emitted whenever the text is edited. Unlike \c textChanged(),
+ this signal is not emitted when the text is changed programmatically, for example,
+ by changing the value of the \c text property or by calling \c clear().
+
+ The corresponding handler is \c onTextEdited.
+*/
+
#if QT_CONFIG(im)
Qt::InputMethodHints QQuickTextInputPrivate::effectiveInputMethodHints() const
{
@@ -1991,7 +2002,7 @@ void QQuickTextInput::selectAll()
bool QQuickTextInput::isRightToLeft(int start, int end)
{
if (start > end) {
- qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
+ qmlWarning(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
return false;
} else {
return text().midRef(start, end - start).isRightToLeft();
@@ -3499,7 +3510,7 @@ void QQuickTextInputPrivate::selectWordAtPos(int cursor)
The \a update value is currently unused.
*/
-bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bool /*edited*/)
+bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bool edited)
{
Q_Q(QQuickTextInput);
@@ -3570,6 +3581,8 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo
m_preeditDirty = false;
#endif
alignmentChanged = determineHorizontalAlignment();
+ if (edited)
+ emit q->textEdited();
emit q->textChanged();
}
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index f4545e1574..c4da807471 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -319,6 +319,7 @@ Q_SIGNALS:
void accepted();
void acceptableInputChanged();
Q_REVISION(2) void editingFinished();
+ Q_REVISION(9) void textEdited();
void colorChanged();
void selectionColorChanged();
void selectedTextColorChanged();
diff --git a/src/quick/items/qquicktextutil.cpp b/src/quick/items/qquicktextutil.cpp
index 8bcdb0b5f6..b07289f4a3 100644
--- a/src/quick/items/qquicktextutil.cpp
+++ b/src/quick/items/qquicktextutil.cpp
@@ -61,7 +61,7 @@ QQuickItem *QQuickTextUtil::createCursor(
item->setPosition(rectangle.topLeft());
item->setHeight(rectangle.height());
} else {
- qmlInfo(parent) << tr("%1 does not support loading non-visual cursor delegates.")
+ qmlWarning(parent) << tr("%1 does not support loading non-visual cursor delegates.")
.arg(QString::fromUtf8(className));
}
component->completeCreate();
@@ -72,7 +72,7 @@ QQuickItem *QQuickTextUtil::createCursor(
parent, SLOT(createCursor()), Qt::UniqueConnection);
return item;
}
- qmlInfo(parent, component->errors()) << tr("Could not load cursor delegate");
+ qmlWarning(parent, component->errors()) << tr("Could not load cursor delegate");
return item;
}
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 573440ff7f..d7171bf910 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -62,6 +62,8 @@ void QQuickViewPrivate::init(QQmlEngine* e)
if (engine.isNull())
engine = new QQmlEngine(q);
+ QQmlEngine::setContextForObject(contentItem, engine.data()->rootContext());
+
if (!engine.data()->incubationController())
engine.data()->setIncubationController(q->incubationController());
diff --git a/src/quick/items/qquickview.h b/src/quick/items/qquickview.h
index 1fcc34e3a1..6d3b30e4c4 100644
--- a/src/quick/items/qquickview.h
+++ b/src/quick/items/qquickview.h
@@ -97,14 +97,14 @@ private Q_SLOTS:
void continueExecute();
protected:
- void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE;
- void timerEvent(QTimerEvent*) Q_DECL_OVERRIDE;
-
- void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;
- void keyReleaseEvent(QKeyEvent *) Q_DECL_OVERRIDE;
- void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;
- void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE;
+ void resizeEvent(QResizeEvent *) override;
+ void timerEvent(QTimerEvent*) override;
+
+ void keyPressEvent(QKeyEvent *) override;
+ void keyReleaseEvent(QKeyEvent *) override;
+ void mousePressEvent(QMouseEvent *) override;
+ void mouseReleaseEvent(QMouseEvent *) override;
+ void mouseMoveEvent(QMouseEvent *) override;
private:
Q_DISABLE_COPY(QQuickView)
Q_DECLARE_PRIVATE(QQuickView)
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index a090bdc9f7..f92d4b95d6 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -88,7 +88,7 @@ public:
~QQuickViewPrivate();
void execute();
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) override;
void initResize();
void updateSize();
void setRootObject(QObject *);
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 0c5f9fe024..fa3093c245 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2095,11 +2095,12 @@ void QQuickWindowPrivate::flushFrameSynchronousEvents()
ut->startAnimations();
}
- // Once per frame, send a synthetic hover, in case items have changed position.
+ // Once per frame, if any items are dirty, send a synthetic hover,
+ // in case items have changed position, visibility, etc.
// For instance, during animation (including the case of a ListView
// whose delegates contain MouseAreas), a MouseArea needs to know
// whether it has moved into a position where it is now under the cursor.
- if (!q->mouseGrabberItem() && !lastMousePosition.isNull()) {
+ if (!q->mouseGrabberItem() && !lastMousePosition.isNull() && dirtyItemList) {
bool accepted = false;
bool delivered = deliverHoverEvent(contentItem, lastMousePosition, lastMousePosition, QGuiApplication::keyboardModifiers(), 0, accepted);
if (!delivered)
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index ea1fc2f106..42313e4584 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -102,6 +102,9 @@ void QQuickWindowQmlImpl::classBegin()
{
Q_D(QQuickWindowQmlImpl);
QQmlEngine* e = qmlEngine(this);
+
+ QQmlEngine::setContextForObject(contentItem(), e->rootContext());
+
//Give QQuickView behavior when created from QML with QQmlApplicationEngine
if (QCoreApplication::instance()->property("__qml_using_qqmlapplicationengine") == QVariant(true)) {
if (e && !e->incubationController())
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index 2f49a53aa1..e9a8b84b2a 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -9,6 +9,8 @@ win32-msvc*:DEFINES *= _CRT_SECURE_NO_WARNINGS
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
win32:!winrt: LIBS += -luser32
+DEFINES += QT_NO_FOREACH
+
exists("qqml_enable_gcov") {
QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -fno-elide-constructors
LIBS_PRIVATE += -lgcov
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index df5ec9b745..8abbefdd48 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -618,6 +618,11 @@ void QSGSoftwareThreadedRenderLoop::windowDestroyed(QQuickWindow *window)
break;
}
}
+
+ // Now that we altered the window list, we may need to stop the animation
+ // timer even if we didn't via handleObscurity. This covers the case where
+ // we destroy a visible & exposed QQuickWindow.
+ startOrStopAnimationTimer();
}
void QSGSoftwareThreadedRenderLoop::exposureChanged(QQuickWindow *window)
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 6db96f369c..d4324bc489 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -979,6 +979,10 @@ void Renderer::nodeChangedBatchRoot(Node *node, Node *root)
e->root = root;
e->boundsComputed = false;
}
+ } else if (node->type() == QSGNode::RenderNodeType) {
+ RenderNodeElement *e = node->renderNodeElement();
+ if (e)
+ e->root = root;
}
SHADOWNODE_TRAVERSE(node)
@@ -2022,6 +2026,8 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
}
ClipType clipType = NoClip;
+ GLuint vbo = 0;
+ int vboSize = 0;
glDisable(GL_SCISSOR_TEST);
@@ -2106,7 +2112,21 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
const QSGGeometry *g = clip->geometry();
Q_ASSERT(g->attributeCount() > 0);
const QSGGeometry::Attribute *a = g->attributes();
- glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), g->vertexData());
+
+ if (!vbo)
+ glGenBuffers(1, &vbo);
+
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+
+ const int vertexByteSize = g->sizeOfVertex() * g->vertexCount();
+ if (vboSize < vertexByteSize) {
+ vboSize = vertexByteSize;
+ glBufferData(GL_ARRAY_BUFFER, vertexByteSize, g->vertexData(), GL_STATIC_DRAW);
+ } else {
+ glBufferSubData(GL_ARRAY_BUFFER, 0, vertexByteSize, g->vertexData());
+ }
+
+ glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), 0);
m_clipProgram.setUniformValue(m_clipMatrixId, m);
if (g->indexCount()) {
@@ -2115,12 +2135,17 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip)
glDrawArrays(g->drawingMode(), 0, g->vertexCount());
}
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
++m_currentStencilValue;
}
clip = clip->clipList();
}
+ if (vbo)
+ glDeleteBuffers(1, &vbo);
+
if (clipType & StencilClip) {
m_clipProgram.disableAttributeArray(0);
glStencilFunc(GL_EQUAL, m_currentStencilValue, 0xff); // stencil test, ref, test mask
@@ -2778,8 +2803,13 @@ void Renderer::renderRenderNode(Batch *batch)
updateClip(rd->m_clip_list, batch);
- RenderNodeState state;
QMatrix4x4 pm = projectionMatrix();
+ if (m_useDepthBuffer) {
+ pm(2, 2) = m_zRange;
+ pm(2, 3) = 1.0f - e->order * m_zRange;
+ }
+
+ RenderNodeState state;
state.m_projectionMatrix = &pm;
state.m_scissorEnabled = m_currentClipType & ScissorClip;
state.m_stencilEnabled = m_currentClipType & StencilClip;
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index a1e1ef8c27..7ef75d4b4c 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -337,13 +337,6 @@ QSGNode::~QSGNode()
to the scene graph and will cause the preprocess() function to be called
for every frame the node is rendered.
- The preprocess function is called before the update pass that propagates
- opacity and transformations through the scene graph. That means that
- functions like QSGOpacityNode::combinedOpacity() and
- QSGTransformNode::combinedMatrix() will not contain up-to-date values.
- If such values are changed during the preprocess, these changes will be
- propagated through the scene graph before it is rendered.
-
\warning Beware of deleting nodes while they are being preprocessed. It is
possible, with a small performance hit, to delete a single node during its
own preprocess call. Deleting a subtree which has nodes that also use
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index 5915d51f2b..1bc0210b72 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -160,10 +160,7 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
\list
\li glDepthMask(false)
\li glDisable(GL_DEPTH_TEST)
- \li glStencilMask(0)
- \li glEnable(GL_STENCIL_TEST)/glDisable(GL_STENCIL_TEST) depending on clip
\li glStencilFunc(GL_EQUAL, state.stencilValue, 0xff) depending on clip
- \li glEnable(GL_SCISSOR_TEST)/glDisable(GL_SCISSOR_TEST) depending on clip
\li glScissor(state.scissorRect.x(), state.scissorRect.y(),
state.scissorRect.width(), state.scissorRect.height()) depending on clip
\li glEnable(GL_BLEND)
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index bf267ccf92..03a1f7f281 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -87,6 +87,8 @@ class QSGRenderNode;
class Q_QUICK_PRIVATE_EXPORT QSGNodeVisitorEx
{
public:
+ virtual ~QSGNodeVisitorEx() {}
+
// visit(...) returns true if the children are supposed to be
// visisted and false if they're supposed to be skipped by the visitor.
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 4543782d5b..5fa74027c1 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -280,7 +280,7 @@ public:
, stopEventProcessing(false)
{
sgrc = static_cast<QSGDefaultRenderContext *>(renderContext);
-#if defined(Q_OS_QNX) && !defined(Q_OS_BLACKBERRY) && defined(Q_PROCESSOR_X86)
+#if defined(Q_OS_QNX) && defined(Q_PROCESSOR_X86)
// The SDP 6.6.0 x86 MESA driver requires a larger stack than the default.
setStackSize(1024 * 1024);
#endif
@@ -826,13 +826,14 @@ void QSGThreadedRenderLoop::startOrStopAnimationTimer()
}
if (m_animation_timer != 0 && (exposedWindows == 1 || !m_animation_driver->isRunning())) {
+ qCDebug(QSG_LOG_RENDERLOOP) << "*** Stopping animation timer";
killTimer(m_animation_timer);
m_animation_timer = 0;
// If animations are running, make sure we keep on animating
if (m_animation_driver->isRunning())
maybePostPolishRequest(const_cast<Window *>(theOne));
-
} else if (m_animation_timer == 0 && exposedWindows != 1 && m_animation_driver->isRunning()) {
+ qCDebug(QSG_LOG_RENDERLOOP) << "*** Starting animation timer";
m_animation_timer = startTimer(qsgrl_animation_interval());
}
}
@@ -888,6 +889,11 @@ void QSGThreadedRenderLoop::windowDestroyed(QQuickWindow *window)
}
}
+ // Now that we altered the window list, we may need to stop the animation
+ // timer even if we didn't via handleObscurity. This covers the case where
+ // we destroy a visible & exposed QQuickWindow.
+ startOrStopAnimationTimer();
+
qCDebug(QSG_LOG_RENDERLOOP) << "done windowDestroyed()" << window;
}
diff --git a/src/quick/scenegraph/util/qsgdefaultimagenode.cpp b/src/quick/scenegraph/util/qsgdefaultimagenode.cpp
index 63773887a0..7186ee4265 100644
--- a/src/quick/scenegraph/util/qsgdefaultimagenode.cpp
+++ b/src/quick/scenegraph/util/qsgdefaultimagenode.cpp
@@ -94,6 +94,21 @@ QSGTexture::Filtering QSGDefaultImageNode::mipmapFiltering() const
return m_material.mipmapFiltering();
}
+void QSGDefaultImageNode::setAnisotropyLevel(QSGTexture::AnisotropyLevel level)
+{
+ if (m_material.anisotropyLevel() == level)
+ return;
+
+ m_material.setAnisotropyLevel(level);
+ m_opaque_material.setAnisotropyLevel(level);
+ markDirty(DirtyMaterial);
+}
+
+QSGTexture::AnisotropyLevel QSGDefaultImageNode::anisotropyLevel() const
+{
+ return m_material.anisotropyLevel();
+}
+
void QSGDefaultImageNode::setRect(const QRectF &r)
{
if (m_rect == r)
diff --git a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
index bb9ebec885..cb23e759d3 100644
--- a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
+++ b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h
@@ -85,6 +85,10 @@ public:
void setOwnsTexture(bool owns) override;
bool ownsTexture() const override;
+ // QSGImageNode now being a public class does not allow any additional virtual methods. Placing these here, non-virtual.
+ void setAnisotropyLevel(QSGTexture::AnisotropyLevel level);
+ QSGTexture::AnisotropyLevel anisotropyLevel() const;
+
private:
QSGGeometry m_geometry;
QSGOpaqueTextureMaterial m_opaque_material;
diff --git a/src/quick/scenegraph/util/qsgimagenode.h b/src/quick/scenegraph/util/qsgimagenode.h
index d25e732e4b..0e053c307f 100644
--- a/src/quick/scenegraph/util/qsgimagenode.h
+++ b/src/quick/scenegraph/util/qsgimagenode.h
@@ -67,6 +67,8 @@ public:
virtual void setMipmapFiltering(QSGTexture::Filtering filtering) = 0;
virtual QSGTexture::Filtering mipmapFiltering() const = 0;
+ // ### Qt6: Add anisotropy support here, and possibly a virtual hook or another mean to extend this class.
+
enum TextureCoordinatesTransformFlag {
NoTransform = 0x00,
MirrorHorizontally = 0x01,
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index 47248f2f37..bc59c49162 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -83,6 +83,9 @@ static const bool qsg_leak_check = !qEnvironmentVariableIsEmpty("QML_LEAK_CHECK"
#define GL_BGRA 0x80E1
#endif
+#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#endif
QT_BEGIN_NAMESPACE
@@ -97,10 +100,12 @@ inline static bool isPowerOfTwo(int x)
QSGTexturePrivate::QSGTexturePrivate()
: wrapChanged(false)
, filteringChanged(false)
+ , anisotropyChanged(false)
, horizontalWrap(QSGTexture::ClampToEdge)
, verticalWrap(QSGTexture::ClampToEdge)
, mipmapMode(QSGTexture::None)
, filterMode(QSGTexture::Nearest)
+ , anisotropyLevel(QSGTexture::AnisotropyNone)
{
}
@@ -274,6 +279,23 @@ static void qt_debug_remove_texture(QSGTexture* texture)
*/
/*!
+ \enum QSGTexture::AnisotropyLevel
+
+ Specifies the anisotropic filtering level to be used when
+ the texture is not screen aligned.
+
+ \value AnisotropyNone No anisotropic filtering.
+
+ \value Anisotropy2x 2x anisotropic filtering.
+
+ \value Anisotropy4x 4x anisotropic filtering.
+
+ \value Anisotropy8x 8x anisotropic filtering.
+
+ \value Anisotropy16x 16x anisotropic filtering.
+*/
+
+/*!
\fn QSGTexture::QSGTexture(QSGTexturePrivate &dd)
\internal
*/
@@ -472,6 +494,31 @@ QSGTexture::Filtering QSGTexture::filtering() const
return (QSGTexture::Filtering) d_func()->filterMode;
}
+/*!
+ Sets the level of anisotropic filtering to be used for the upcoming bind() call to \a level.
+ The default value is QSGTexture::AnisotropyNone, which means no anisotropic filtering is enabled.
+
+ \since 5.9
+ */
+void QSGTexture::setAnisotropyLevel(AnisotropyLevel level)
+{
+ Q_D(QSGTexture);
+ if (d->anisotropyLevel != (uint) level) {
+ d->anisotropyLevel = level;
+ d->anisotropyChanged = true;
+ }
+}
+
+/*!
+ Returns the anisotropy level in use for filtering this texture.
+
+ \since 5.9
+ */
+QSGTexture::AnisotropyLevel QSGTexture::anisotropyLevel() const
+{
+ return (QSGTexture::AnisotropyLevel) d_func()->anisotropyLevel;
+}
+
/*!
@@ -548,6 +595,12 @@ void QSGTexture::updateBindOptions(bool force)
d->filteringChanged = false;
}
+ if (force || d->anisotropyChanged) {
+ d->anisotropyChanged = false;
+ if (QOpenGLContext::currentContext()->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic")))
+ funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, float(1 << (d->anisotropyLevel)));
+ }
+
if (force || d->wrapChanged) {
#ifndef QT_NO_DEBUG
if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat) {
diff --git a/src/quick/scenegraph/util/qsgtexture.h b/src/quick/scenegraph/util/qsgtexture.h
index f0509b58ae..035acc02b1 100644
--- a/src/quick/scenegraph/util/qsgtexture.h
+++ b/src/quick/scenegraph/util/qsgtexture.h
@@ -67,6 +67,14 @@ public:
Linear
};
+ enum AnisotropyLevel {
+ AnisotropyNone,
+ Anisotropy2x,
+ Anisotropy4x,
+ Anisotropy8x,
+ Anisotropy16x
+ };
+
virtual int textureId() const = 0;
virtual QSize textureSize() const = 0;
virtual bool hasAlphaChannel() const = 0;
@@ -87,6 +95,9 @@ public:
void setFiltering(Filtering filter);
QSGTexture::Filtering filtering() const;
+ void setAnisotropyLevel(AnisotropyLevel level);
+ QSGTexture::AnisotropyLevel anisotropyLevel() const;
+
void setHorizontalWrapMode(WrapMode hwrap);
QSGTexture::WrapMode horizontalWrapMode() const;
diff --git a/src/quick/scenegraph/util/qsgtexture_p.h b/src/quick/scenegraph/util/qsgtexture_p.h
index b6fcfc31c4..36f9b802ba 100644
--- a/src/quick/scenegraph/util/qsgtexture_p.h
+++ b/src/quick/scenegraph/util/qsgtexture_p.h
@@ -69,11 +69,13 @@ public:
uint wrapChanged : 1;
uint filteringChanged : 1;
+ uint anisotropyChanged : 1;
uint horizontalWrap : 1;
uint verticalWrap : 1;
uint mipmapMode : 2;
uint filterMode : 2;
+ uint anisotropyLevel: 3;
};
class Q_QUICK_PRIVATE_EXPORT QSGPlainTexture : public QSGTexture
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp
index 9326ea640d..c536445e82 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.cpp
+++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp
@@ -110,6 +110,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa
Q_UNUSED(state)
#endif
t->setMipmapFiltering(tx->mipmapFiltering());
+ t->setAnisotropyLevel(tx->anisotropyLevel());
if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId())
t->bind();
@@ -173,6 +174,7 @@ QSGOpaqueTextureMaterial::QSGOpaqueTextureMaterial()
, m_mipmap_filtering(QSGTexture::None)
, m_horizontal_wrap(QSGTexture::ClampToEdge)
, m_vertical_wrap(QSGTexture::ClampToEdge)
+ , m_anisotropy_level(QSGTexture::AnisotropyNone)
{
}
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.h b/src/quick/scenegraph/util/qsgtexturematerial.h
index dc87131773..87d8e5fd49 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.h
+++ b/src/quick/scenegraph/util/qsgtexturematerial.h
@@ -69,6 +69,9 @@ public:
void setVerticalWrapMode(QSGTexture::WrapMode mode) { m_vertical_wrap = mode; }
QSGTexture::WrapMode verticalWrapMode() const { return QSGTexture::WrapMode(m_vertical_wrap); }
+ void setAnisotropyLevel(QSGTexture::AnisotropyLevel level) { m_anisotropy_level = level; }
+ QSGTexture::AnisotropyLevel anisotropyLevel() const { return QSGTexture::AnisotropyLevel(m_anisotropy_level); }
+
protected:
QSGTexture *m_texture;
@@ -76,8 +79,8 @@ protected:
uint m_mipmap_filtering: 2;
uint m_horizontal_wrap : 1;
uint m_vertical_wrap: 1;
-
- uint m_reserved : 26;
+ uint m_anisotropy_level : 3;
+ uint m_reserved : 23;
};
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index 9de474ac36..1a2441171d 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -192,14 +192,14 @@ QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const
if (errorMessage)
*errorMessage = message;
else
- qmlInfo(infoObj) << message;
+ qmlWarning(infoObj) << message;
return QQmlProperty();
} else if (!prop.isWritable()) {
const QString message = QQuickAbstractAnimation::tr("Cannot animate read-only property \"%1\"").arg(str);
if (errorMessage)
*errorMessage = message;
else
- qmlInfo(infoObj) << message;
+ qmlWarning(infoObj) << message;
return QQmlProperty();
}
return prop;
@@ -256,7 +256,7 @@ void QQuickAbstractAnimation::setRunning(bool r)
return;
if (d->group || d->disableUserControl) {
- qmlInfo(this) << "setRunning() cannot be used on non-root animation nodes.";
+ qmlWarning(this) << "setRunning() cannot be used on non-root animation nodes.";
return;
}
@@ -322,12 +322,12 @@ void QQuickAbstractAnimation::setPaused(bool p)
return;
if (!d->running) {
- qmlInfo(this) << "setPaused() cannot be used when animation isn't running.";
+ qmlWarning(this) << "setPaused() cannot be used when animation isn't running.";
return;
}
if (d->group || d->disableUserControl) {
- qmlInfo(this) << "setPaused() cannot be used on non-root animation nodes.";
+ qmlWarning(this) << "setPaused() cannot be used on non-root animation nodes.";
return;
}
@@ -709,7 +709,7 @@ int QQuickPauseAnimation::duration() const
void QQuickPauseAnimation::setDuration(int duration)
{
if (duration < 0) {
- qmlInfo(this) << tr("Cannot set a duration of < 0");
+ qmlWarning(this) << tr("Cannot set a duration of < 0");
return;
}
@@ -1004,7 +1004,7 @@ void QQuickScriptActionPrivate::execute()
QQmlExpression expr(scriptStr);
expr.evaluate();
if (expr.hasError())
- qmlInfo(q) << expr.error();
+ qmlWarning(q) << expr.error();
}
}
@@ -2077,7 +2077,7 @@ int QQuickPropertyAnimation::duration() const
void QQuickPropertyAnimation::setDuration(int duration)
{
if (duration < 0) {
- qmlInfo(this) << tr("Cannot set a duration of < 0");
+ qmlWarning(this) << tr("Cannot set a duration of < 0");
return;
}
@@ -2644,7 +2644,7 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA
if (!successfullyCreatedDefaultProperty) {
for (const QString &errorMessage : qAsConst(errorMessages))
- qmlInfo(this) << errorMessage;
+ qmlWarning(this) << errorMessage;
}
}
diff --git a/src/quick/util/qquickanimationcontroller.cpp b/src/quick/util/qquickanimationcontroller.cpp
index 4bc2d6319e..fa1ade50d1 100644
--- a/src/quick/util/qquickanimationcontroller.cpp
+++ b/src/quick/util/qquickanimationcontroller.cpp
@@ -169,7 +169,7 @@ void QQuickAnimationController::setAnimation(QQuickAbstractAnimation *animation)
if (animation != d->animation) {
if (animation) {
if (animation->userControlDisabled()) {
- qmlInfo(this) << "QQuickAnimationController::setAnimation: the animation is controlled by others, can't be used in AnimationController.";
+ qmlWarning(this) << "QQuickAnimationController::setAnimation: the animation is controlled by others, can't be used in AnimationController.";
return;
}
animation->setDisableUserControl();
diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp
index 5d2af0f940..c3b5865369 100644
--- a/src/quick/util/qquickanimator.cpp
+++ b/src/quick/util/qquickanimator.cpp
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
\inqmlmodule QtQuick
\since 5.2
\ingroup qtquick-transitions-animations
+ \inherits Animation
\brief Is the base of all QML animators.
Animator types are a special type of animation which operate
diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp
index 9af1d41b29..1b2d9afb7c 100644
--- a/src/quick/util/qquickbehavior.cpp
+++ b/src/quick/util/qquickbehavior.cpp
@@ -129,7 +129,7 @@ void QQuickBehavior::setAnimation(QQuickAbstractAnimation *animation)
{
Q_D(QQuickBehavior);
if (d->animation) {
- qmlInfo(this) << tr("Cannot change the animation assigned to a Behavior.");
+ qmlWarning(this) << tr("Cannot change the animation assigned to a Behavior.");
return;
}
diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp
index d13291c30a..3761a37a6d 100644
--- a/src/quick/util/qquickfontloader.cpp
+++ b/src/quick/util/qquickfontloader.cpp
@@ -307,7 +307,7 @@ void QQuickFontLoader::updateFontInfo(const QString& name, QQuickFontLoader::Sta
}
if (status != d->status) {
if (status == Error)
- qmlInfo(this) << "Cannot load font: \"" << d->url.toString() << '"';
+ qmlWarning(this) << "Cannot load font: \"" << d->url.toString() << '"';
d->status = status;
emit statusChanged();
}
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index c4182d9f93..7788635e3e 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -514,9 +514,9 @@ public:
/*!
\class QQuickImageProviderOptions
- \since 5.9
\brief The QQuickImageProviderOptions class provides options for QQuickImageProviderWithOptions image requests.
\inmodule QtQuick
+ \internal
\sa QQuickImageProviderWithOptions
*/
diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp
index 25a4433a9b..e31aed7b6d 100644
--- a/src/quick/util/qquickpath.cpp
+++ b/src/quick/util/qquickpath.cpp
@@ -149,20 +149,6 @@ bool QQuickPath::isClosed() const
return d->closed;
}
-bool QQuickPath::hasEnd() const
-{
- Q_D(const QQuickPath);
- for (int i = d->_pathElements.count() - 1; i > -1; --i) {
- if (QQuickCurve *curve = qobject_cast<QQuickCurve *>(d->_pathElements.at(i))) {
- if ((!curve->hasX() && !curve->hasRelativeX()) || (!curve->hasY() && !curve->hasRelativeY()))
- return false;
- else
- return true;
- }
- }
- return hasStartX() && hasStartY();
-}
-
/*!
\qmlproperty list<PathElement> QtQuick::Path::pathElements
This property holds the objects composing the path.
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index 06ad389b49..c0a96cad4f 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -390,7 +390,6 @@ public:
bool hasStartY() const;
bool isClosed() const;
- bool hasEnd() const;
QPainterPath path() const;
QStringList attributes() const;
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 7b369a2d0f..1c6b2afb54 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -695,15 +695,6 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
QQuickImageProviderWithOptions *providerV2 = provider->d->isProviderWithOptions ? static_cast<QQuickImageProviderWithOptions *>(provider)
: nullptr;
- if (!provider->d->isProviderWithOptions &&
- (providerOptions.autoTransform() != QQuickImageProviderOptions::UsePluginDefaultTransform
- || providerOptions.preserveAspectRatioCrop()
- || providerOptions.preserveAspectRatioFit())
- )
- {
- qWarning() << "Trying to pass extra request flags to provider but it is not a QQuickImageProviderWithOptions";
- }
-
switch (imageType) {
case QQuickImageProvider::Invalid:
{
diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h
index eea6a7a454..f7cdfa7d07 100644
--- a/src/quick/util/qquickpixmapcache_p.h
+++ b/src/quick/util/qquickpixmapcache_p.h
@@ -91,7 +91,7 @@ public:
};
// ### Qt 6: Make public moving to qquickimageprovider.h
-class Q_QUICK_EXPORT QQuickImageProviderOptions
+class Q_QUICK_PRIVATE_EXPORT QQuickImageProviderOptions
{
public:
enum AutoTransform {
@@ -188,7 +188,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPixmap::Options)
// This class will disappear with Qt6 and will just be the regular QQuickImageProvider
// ### Qt 6: Remove this class and fold it with QQuickImageProvider
-class Q_QUICK_EXPORT QQuickImageProviderWithOptions : public QQuickAsyncImageProvider
+class Q_QUICK_PRIVATE_EXPORT QQuickImageProviderWithOptions : public QQuickAsyncImageProvider
{
public:
QQuickImageProviderWithOptions(ImageType type, Flags flags = Flags());
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index fafa2edd0b..20aa52e472 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -397,10 +397,10 @@ QQuickPropertyChangesPrivate::property(const QString &property)
Q_Q(QQuickPropertyChanges);
QQmlProperty prop(object, property, qmlContext(q));
if (!prop.isValid()) {
- qmlInfo(q) << QQuickPropertyChanges::tr("Cannot assign to non-existent property \"%1\"").arg(property);
+ qmlWarning(q) << QQuickPropertyChanges::tr("Cannot assign to non-existent property \"%1\"").arg(property);
return QQmlProperty();
} else if (!(prop.type() & QQmlProperty::SignalProperty) && !prop.isWritable()) {
- qmlInfo(q) << QQuickPropertyChanges::tr("Cannot assign to read-only property \"%1\"").arg(property);
+ qmlWarning(q) << QQuickPropertyChanges::tr("Cannot assign to read-only property \"%1\"").arg(property);
return QQmlProperty();
}
return prop;
diff --git a/src/quick/util/qquickstatechangescript.cpp b/src/quick/util/qquickstatechangescript.cpp
index 86b70fe879..a70fa1a676 100644
--- a/src/quick/util/qquickstatechangescript.cpp
+++ b/src/quick/util/qquickstatechangescript.cpp
@@ -131,7 +131,7 @@ void QQuickStateChangeScript::execute()
QQmlExpression expr(d->script);
expr.evaluate();
if (expr.hasError())
- qmlInfo(this, expr.error());
+ qmlWarning(this, expr.error());
}
}
diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp
index 200f243a1b..f2cd4638fc 100644
--- a/src/quick/util/qquickstategroup.cpp
+++ b/src/quick/util/qquickstategroup.cpp
@@ -438,7 +438,7 @@ void QQuickStateGroupPrivate::setCurrentStateInternal(const QString &state,
}
if (applyingState) {
- qmlInfo(q) << "Can't apply a state change as part of a state definition.";
+ qmlWarning(q) << "Can't apply a state change as part of a state definition.";
return;
}
diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp
index 77dae0d001..b2e5b84cf4 100644
--- a/src/quick/util/qquickutilmodule.cpp
+++ b/src/quick/util/qquickutilmodule.cpp
@@ -54,7 +54,9 @@
#include "qquicktextmetrics_p.h"
#include "qquicktransition_p.h"
#include "qquickanimator_p.h"
+#if QT_CONFIG(shortcut)
#include "qquickshortcut_p.h"
+#endif
#include "qquickvalidator_p.h"
#include <qqmlinfo.h>
#include <private/qqmltypenotavailable_p.h>
@@ -63,7 +65,9 @@
#include <QtGui/QInputMethod>
#include <QtGui/QKeySequence>
+#if QT_CONFIG(shortcut)
Q_DECLARE_METATYPE(QKeySequence::StandardKey)
+#endif
void QQuickUtilModule::defineModule()
{
@@ -114,15 +118,18 @@ void QQuickUtilModule::defineModule()
qmlRegisterCustomType<QQuickPropertyChanges>("QtQuick",2,0,"PropertyChanges", new QQuickPropertyChangesParser);
+#if QT_CONFIG(shortcut)
qRegisterMetaType<QKeySequence::StandardKey>();
qmlRegisterUncreatableType<QKeySequence, 2>("QtQuick", 2, 2, "StandardKey", QStringLiteral("Cannot create an instance of StandardKey."));
+#endif
qmlRegisterType<QQuickFontMetrics>("QtQuick", 2, 4, "FontMetrics");
qmlRegisterType<QQuickTextMetrics>("QtQuick", 2, 4, "TextMetrics");
+#if QT_CONFIG(shortcut)
qmlRegisterType<QQuickShortcut>("QtQuick", 2, 5, "Shortcut");
-
qmlRegisterType<QQuickShortcut,1>("QtQuick", 2, 6, "Shortcut");
qmlRegisterType<QQuickShortcut,9>("QtQuick", 2, 9, "Shortcut");
+#endif
}
diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri
index 1ef1018a31..b53b132cce 100644
--- a/src/quick/util/util.pri
+++ b/src/quick/util/util.pri
@@ -26,7 +26,6 @@ SOURCES += \
$$PWD/qquickanimatorcontroller.cpp \
$$PWD/qquickfontmetrics.cpp \
$$PWD/qquicktextmetrics.cpp \
- $$PWD/qquickshortcut.cpp \
$$PWD/qquickvalidator.cpp
!contains(QT_CONFIG, no-qml-debug): SOURCES += $$PWD/qquickprofiler.cpp
@@ -63,9 +62,15 @@ HEADERS += \
$$PWD/qquickprofiler_p.h \
$$PWD/qquickfontmetrics_p.h \
$$PWD/qquicktextmetrics_p.h \
- $$PWD/qquickshortcut_p.h \
$$PWD/qquickvalidator_p.h
+qtConfig(shortcut) {
+ SOURCES += \
+ $$PWD/qquickshortcut.cpp
+ HEADERS += \
+ $$PWD/qquickshortcut_p.h
+}
+
qtConfig(quick-path) {
SOURCES += \
$$PWD/qquickpath.cpp \
diff --git a/src/src.pro b/src/src.pro
index f585ef15ca..21925c9330 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,7 +1,7 @@
TEMPLATE = subdirs
CONFIG += ordered
include($$OUT_PWD/quick/qtquick-config.pri)
-QT_FOR_CONFIG += quick-private
+QT_FOR_CONFIG += network quick-private
SUBDIRS += \
qml
@@ -20,6 +20,6 @@ SUBDIRS += \
imports \
qmldevtools
-!contains(QT_CONFIG, no-qml-debug): SUBDIRS += qmldebug
+qtConfig(localserver):!contains(QT_CONFIG, no-qml-debug): SUBDIRS += qmldebug
qmldevtools.CONFIG = host_build
diff --git a/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp b/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp
index 1791407934..ff295c5409 100644
--- a/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp
+++ b/tests/auto/qml/animation/qpauseanimationjob/tst_qpauseanimationjob.cpp
@@ -392,8 +392,10 @@ void tst_QPauseAnimationJob::multipleSequentialGroups()
#ifdef Q_OS_WIN
if (group.state() != QAbstractAnimationJob::Stopped)
QEXPECT_FAIL("", winTimerError, Abort);
-#endif
+ QCOMPARE(group.state(), QAbstractAnimationJob::Stopped);
+#else
QTRY_COMPARE(group.state(), QAbstractAnimationJob::Stopped);
+#endif
#ifdef Q_OS_WIN
if (subgroup1.state() != QAbstractAnimationJob::Stopped)
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
index 40e19d375d..8c30a82317 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
@@ -45,6 +45,7 @@
#include <QtQml/qqmlcomponent.h>
#include <QtQml/qqmlexpression.h>
#include <QtQml/qqmlproperty.h>
+#include <QtQml/qqmlincubator.h>
#include <QtQuick/qquickitem.h>
#include <QtNetwork/qhostaddress.h>
@@ -136,6 +137,7 @@ private slots:
void regression_QTCREATORBUG_7451();
void queryObjectWithNonStreamableTypes();
+ void asynchronousCreate();
};
QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject(
@@ -1220,6 +1222,32 @@ void tst_QQmlEngineDebugService::queryObjectTree()
QCOMPARE(findProperty(animation.properties,"duration").value.toInt(), 100);
}
+void tst_QQmlEngineDebugService::asynchronousCreate() {
+ QmlDebugObjectReference object;
+ auto connection = connect(m_dbg, &QQmlEngineDebugClient::newObject, this, [&](int objectId) {
+ object.debugId = objectId;
+ });
+
+ QByteArray asynchronousComponent = "import QtQuick 2.5\n"
+ "Rectangle { id: asyncRect }";
+ QQmlComponent component(m_engine);
+ component.setData(asynchronousComponent, QUrl::fromLocalFile(""));
+ QVERIFY(component.isReady()); // fails if bad syntax
+ QQmlIncubator incubator(QQmlIncubator::Asynchronous);
+ component.create(incubator);
+
+ QVERIFY(m_dbg->object().idString != QLatin1String("asyncRect"));
+
+ QTRY_VERIFY(object.debugId != -1);
+ disconnect(connection);
+
+ bool success = false;
+ m_dbg->queryObject(object, &success);
+ QVERIFY(success);
+
+ QTRY_COMPARE(m_dbg->object().idString, QLatin1String("asyncRect"));
+}
+
int main(int argc, char *argv[])
{
int _argc = argc + 1;
diff --git a/tests/auto/qml/debugger/qqmlinspector/data/qtquick2.qml b/tests/auto/qml/debugger/qqmlinspector/data/qtquick2.qml
index f44c653840..f43cff15e4 100644
--- a/tests/auto/qml/debugger/qqmlinspector/data/qtquick2.qml
+++ b/tests/auto/qml/debugger/qqmlinspector/data/qtquick2.qml
@@ -29,16 +29,15 @@ Rectangle {
}
var milliDelta = millis - prevHit;
- if (milliDelta < 0)
+ if (milliDelta <= 0)
milliDelta += 1000;
- console.log(milliDelta, "milliseconds ");
prevHit = millis;
var delta = parent.rotation - prevRotation;
if (delta < 0)
delta += 360
prevRotation = parent.rotation
- console.log(delta, "degrees ");
+ console.log(milliDelta, delta, "ms/degrees ");
}
}
}
diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
index f55fef232e..9461922eff 100644
--- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
+++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
@@ -102,29 +102,46 @@ void tst_QQmlInspector::startQmlProcess(const QString &qmlFile, bool restrictSer
void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
{
- QString degreesString = QStringLiteral("degrees");
- QString millisecondsString = QStringLiteral("milliseconds");
- for (int i = 0; i < 2; ++i) { // skip one period; the change might have happened inside it
- int position = m_process->output().length();
- while (!m_process->output().mid(position).contains(degreesString) ||
- !m_process->output().mid(position).contains(millisecondsString)) {
+ const QString markerString = QStringLiteral("ms/degrees");
+
+ // Funny things can happen with time and VMs. Also the change might take a while to propagate.
+ // Thus, we wait until we either have 3 passes or 3 failures in a row, or 10 loops have passed.
+
+ int numFailures = 0;
+ int numPasses = 0;
+
+ for (int i = 0; i < 10; ++i) {
+ QString output = m_process->output();
+ int position = output.length();
+ do {
QVERIFY(QQmlDebugTest::waitForSignal(m_process.data(),
SIGNAL(readyReadStandardOutput())));
+ output = m_process->output();
+ } while (!output.mid(position).contains(markerString));
+
+
+ QStringList words = output.split(QLatin1Char(' '));
+ const int marker = words.lastIndexOf(markerString);
+ QVERIFY(marker > 1);
+ const double degrees = words[marker - 1].toDouble();
+ const int milliseconds = words[marker - 2].toInt();
+ const double millisecondsPerDegree = milliseconds / degrees;
+
+ if (millisecondsPerDegree > targetMillisPerDegree - 3
+ || millisecondsPerDegree < targetMillisPerDegree + 3) {
+ if (++numPasses == 3)
+ return; // pass
+ numFailures = 0;
+ } else {
+ QVERIFY2(++numFailures < 3,
+ QString("3 consecutive failures when checking for %1 milliseconds per degree")
+ .arg(targetMillisPerDegree).toLocal8Bit().constData());
+ numPasses = 0;
}
}
- QStringList words = m_process->output().split(QLatin1Char(' '));
- int degreesMarker = words.lastIndexOf(degreesString);
- QVERIFY(degreesMarker > 1);
- double degrees = words[degreesMarker - 1].toDouble();
- int millisecondsMarker = words.lastIndexOf(millisecondsString);
- QVERIFY(millisecondsMarker > 1);
- int milliseconds = words[millisecondsMarker - 1].toInt();
-
- double millisecondsPerDegree = milliseconds / degrees;
- QVERIFY(millisecondsPerDegree > targetMillisPerDegree - 3);
- QVERIFY(millisecondsPerDegree < targetMillisPerDegree + 3);
-
+ QFAIL(QString("Animation speed won't settle to %1 milliseconds per degree")
+ .arg(targetMillisPerDegree).toLocal8Bit().constData());
}
void tst_QQmlInspector::cleanup()
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
index 3ad7beb7ff..3e27951d78 100644
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
+++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
@@ -489,7 +489,9 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
return;
} else if (type == "OBJECT_CREATED") {
- emit newObjects();
+ int engineId, objectId, parentId;
+ ds >> engineId >> objectId >> parentId;
+ emit newObject(objectId);
return;
} else if (type == "SET_BINDING_R") {
ds >> m_valid;
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
index a64a77e13e..5d74f2d43c 100644
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
+++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
@@ -213,7 +213,7 @@ public:
bool valid() { return m_valid; }
signals:
- void newObjects();
+ void newObject(int objectId);
void valueChanged(QByteArray,QVariant);
void result();
diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
index 8af446173d..b265607fd1 100644
--- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -53,6 +53,7 @@ private slots:
void registerImportForImplicitComponent();
void basicVersionChecks();
void recompileAfterChange();
+ void recompileAfterDirectoryChange();
void fileSelectors();
void localAliases();
void cacheResources();
@@ -95,11 +96,17 @@ struct TestCompiler
TestCompiler(QQmlEngine *engine)
: engine(engine)
, tempDir()
- , testFilePath(tempDir.path() + QStringLiteral("/test.qml"))
- , cacheFilePath(tempDir.path() + QStringLiteral("/test.qmlc"))
- , mappedFile(cacheFilePath)
, currentMapping(nullptr)
{
+ init(tempDir.path());
+ }
+
+ void init(const QString &baseDirectory)
+ {
+ closeMapping();
+ testFilePath = baseDirectory + QStringLiteral("/test.qml");
+ cacheFilePath = baseDirectory + QStringLiteral("/test.qmlc");
+ mappedFile.setFileName(cacheFilePath);
}
bool compile(const QByteArray &contents)
@@ -187,8 +194,8 @@ struct TestCompiler
QQmlEngine *engine;
const QTemporaryDir tempDir;
- const QString testFilePath;
- const QString cacheFilePath;
+ QString testFilePath;
+ QString cacheFilePath;
QString lastErrorString;
QFile mappedFile;
uchar *currentMapping;
@@ -441,6 +448,47 @@ void tst_qmldiskcache::recompileAfterChange()
}
}
+void tst_qmldiskcache::recompileAfterDirectoryChange()
+{
+ QQmlEngine engine;
+ TestCompiler testCompiler(&engine);
+
+ QVERIFY(testCompiler.tempDir.isValid());
+
+ QVERIFY(QDir(testCompiler.tempDir.path()).mkdir("source1"));
+ testCompiler.init(testCompiler.tempDir.path() + QLatin1String("/source1"));
+
+ {
+ const QByteArray contents = QByteArrayLiteral("import QtQml 2.0\n"
+ "QtObject {\n"
+ " property int blah: 42;\n"
+ "}");
+
+ testCompiler.clearCache();
+ QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
+ QVERIFY2(testCompiler.verify(), qPrintable(testCompiler.lastErrorString));
+ testCompiler.closeMapping();
+ }
+
+ const QDateTime initialCacheTimeStamp = QFileInfo(testCompiler.cacheFilePath).lastModified();
+
+ QDir(testCompiler.tempDir.path()).rename(QStringLiteral("source1"), QStringLiteral("source2"));
+ waitForFileSystem();
+
+ testCompiler.init(testCompiler.tempDir.path() + QLatin1String("/source2"));
+
+ {
+ CleanlyLoadingComponent component(&engine, testCompiler.testFilePath);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("blah").toInt(), 42);
+ }
+
+ QFile cacheFile(testCompiler.cacheFilePath);
+ QVERIFY2(cacheFile.exists(), qPrintable(cacheFile.fileName()));
+ QVERIFY(QFileInfo(testCompiler.cacheFilePath).lastModified() > initialCacheTimeStamp);
+}
+
void tst_qmldiskcache::fileSelectors()
{
QQmlEngine engine;
diff --git a/tests/auto/qml/qqmlapplicationengine/data/LocalComponent.qml b/tests/auto/qml/qqmlapplicationengine/data/LocalComponent.qml
new file mode 100644
index 0000000000..ece4f45b4a
--- /dev/null
+++ b/tests/auto/qml/qqmlapplicationengine/data/LocalComponent.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+
+// used in nonResolvedLocal
+QtObject {
+
+}
diff --git a/tests/auto/qml/qqmlapplicationengine/data/nonResolvedLocal.qml b/tests/auto/qml/qqmlapplicationengine/data/nonResolvedLocal.qml
new file mode 100644
index 0000000000..45a235346d
--- /dev/null
+++ b/tests/auto/qml/qqmlapplicationengine/data/nonResolvedLocal.qml
@@ -0,0 +1,9 @@
+import QtQml 2.0
+
+QtObject {
+ property bool success: true
+
+ property QtObject local: LocalComponent {
+ }
+}
+
diff --git a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
index 98b92e5fab..74add85cb0 100644
--- a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
+++ b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
@@ -42,6 +42,7 @@ public:
private slots:
void initTestCase();
void basicLoading();
+ void testNonResolvedPath();
void application();
void applicationProperties();
private:
@@ -83,6 +84,29 @@ void tst_qqmlapplicationengine::basicLoading()
delete test;
}
+// make sure we resolve a relative URL to an absolute one, otherwise things
+// will break.
+void tst_qqmlapplicationengine::testNonResolvedPath()
+{
+ {
+ // NOTE NOTE NOTE! Missing testFileUrl is *WANTED* here! We want a
+ // non-resolved URL.
+ QQmlApplicationEngine test("data/nonResolvedLocal.qml");
+ QCOMPARE(test.rootObjects().size(), 1);
+ QVERIFY(test.rootObjects()[0]);
+ QVERIFY(test.rootObjects()[0]->property("success").toBool());
+ }
+ {
+ QQmlApplicationEngine test;
+ // NOTE NOTE NOTE! Missing testFileUrl is *WANTED* here! We want a
+ // non-resolved URL.
+ test.load("data/nonResolvedLocal.qml");
+ QCOMPARE(test.rootObjects().size(), 1);
+ QVERIFY(test.rootObjects()[0]);
+ QVERIFY(test.rootObjects()[0]->property("success").toBool());
+ }
+}
+
void tst_qqmlapplicationengine::application()
{
/* This test batches together some tests about running an external application
diff --git a/tests/auto/qml/qqmldirparser/data/classname/qmldir b/tests/auto/qml/qqmldirparser/data/classname/qmldir
new file mode 100644
index 0000000000..8167e813df
--- /dev/null
+++ b/tests/auto/qml/qqmldirparser/data/classname/qmldir
@@ -0,0 +1,5 @@
+module QtQuick
+plugin qtquick2plugin
+classname QtQuick2Plugin
+typeinfo plugins.qmltypes
+designersupported
diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
index 7d154d0ea6..3643ca65c6 100644
--- a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
+++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
@@ -325,6 +325,15 @@ void tst_qqmldirparser::parse_data()
<< QStringList()
<< (QStringList() << "bar||1|0|true")
<< false;
+
+ QTest::newRow("classname")
+ << "classname/qmldir"
+ << QStringList()
+ << (QStringList() << "qtquick2plugin|")
+ << QStringList()
+ << QStringList()
+ << QStringList()
+ << true;
}
void tst_qqmldirparser::parse()
diff --git a/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml b/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml
index 4fc2dab943..54d29dfc94 100644
--- a/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml
+++ b/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml
@@ -15,4 +15,12 @@ MyQmlObject
onMySignal: { intProperty = a; realProperty = b; colorProperty = c; variantProperty = d; enumProperty = e; qtEnumProperty = f; }
onBasicSignal: root.mySignal(10, 19.2, Qt.rgba(1, 1, 0, 1), Qt.rgba(1, 0, 1, 1), MyQmlObject.EnumValue3, Qt.LeftButton)
+
+ property bool emittedQjsValueWasUndefined
+ property int emittedQjsValueAsInt
+
+ onQjsValueEmittingSignal: {
+ emittedQjsValueWasUndefined = value === undefined;
+ emittedQjsValueAsInt = value
+ }
}
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index 47fb2a56e7..1f7f3344ef 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -244,6 +244,7 @@ signals:
void signalWithGlobalName(int parseInt);
void intChanged();
void qjsvalueChanged();
+ void qjsValueEmittingSignal(QJSValue value);
public slots:
void deleteMe() { delete this; }
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 88a8886ecb..89dac33671 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -331,6 +331,8 @@ private slots:
void qtbug_54589();
void qtbug_54687();
void stringify_qtbug_50592();
+ void instanceof_data();
+ void instanceof();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -1418,6 +1420,12 @@ void tst_qqmlecmascript::signalParameterTypes()
QVERIFY(object->property("enumProperty") == MyQmlObject::EnumValue3);
QVERIFY(object->property("qtEnumProperty") == Qt::LeftButton);
+ emit object->qjsValueEmittingSignal(QJSValue());
+ QVERIFY(object->property("emittedQjsValueWasUndefined").toBool());
+ emit object->qjsValueEmittingSignal(QJSValue(42));
+ QVERIFY(!object->property("emittedQjsValueWasUndefined").toBool());
+ QCOMPARE(object->property("emittedQjsValueAsInt").value<int>(), 42);
+
delete object;
}
@@ -8113,6 +8121,68 @@ void tst_qqmlecmascript::stringify_qtbug_50592()
QCOMPARE(obj->property("source").toString(), QString::fromLatin1("http://example.org/some_nonexistant_image.png"));
}
+void tst_qqmlecmascript::instanceof_data()
+{
+ QTest::addColumn<QString>("setupCode");
+ QTest::addColumn<QVariant>("expectedValue");
+
+ // so the way this works is that the name of the test tag defines the test
+ // to run. the code in setupCode defines code run before the actual test
+ // (e.g. to create vars).
+ //
+ // the expectedValue is either a boolean true or false for whether the two
+ // operands are indeed an instanceof each other, or a string for the
+ // expected error message.
+ QTest::newRow("String instanceof String")
+ << ""
+ << QVariant(false);
+ QTest::newRow("s instanceof String")
+ << "var s = \"hello\""
+ << QVariant(false);
+ QTest::newRow("objectString instanceof String")
+ << "var objectString = new String(\"hello\")"
+ << QVariant(true);
+ QTest::newRow("o instanceof Object")
+ << "var o = new Object()"
+ << QVariant(true);
+ QTest::newRow("o instanceof String")
+ << "var o = new Object()"
+ << QVariant(false);
+ QTest::newRow("true instanceof true")
+ << ""
+ << QVariant("TypeError: Type error");
+ QTest::newRow("1 instanceof Math")
+ << ""
+ << QVariant("TypeError: Type error");
+ QTest::newRow("date instanceof Date")
+ << "var date = new Date"
+ << QVariant(true);
+ QTest::newRow("date instanceof Object")
+ << "var date = new Date"
+ << QVariant(true);
+ QTest::newRow("date instanceof String")
+ << "var date = new Date"
+ << QVariant(false);
+}
+
+void tst_qqmlecmascript::instanceof()
+{
+ QFETCH(QString, setupCode);
+ QFETCH(QVariant, expectedValue);
+
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate(setupCode + ";\n" + QTest::currentDataTag());
+
+ if (expectedValue.type() == QMetaType::Bool) {
+ bool returnValue = ret.toBool();
+ QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
+ QCOMPARE(returnValue, expectedValue.toBool());
+ } else {
+ QVERIFY2(ret.isError(), qPrintable(ret.toString()));
+ QCOMPARE(ret.toString(), expectedValue.toString());
+ }
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/qml/qqmlinfo/tst_qqmlinfo.cpp b/tests/auto/qml/qqmlinfo/tst_qqmlinfo.cpp
index acda06c8d8..3f6c200027 100644
--- a/tests/auto/qml/qqmlinfo/tst_qqmlinfo.cpp
+++ b/tests/auto/qml/qqmlinfo/tst_qqmlinfo.cpp
@@ -49,6 +49,7 @@ private slots:
void nonQmlContextedObject();
void types();
void chaining();
+ void messageTypes();
private:
QQmlEngine engine;
@@ -62,14 +63,14 @@ void tst_qqmlinfo::qmlObject()
QVERIFY(object != 0);
QString message = component.url().toString() + ":3:1: QML QtObject: Test Message";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
+ QTest::ignoreMessage(QtInfoMsg, qPrintable(message));
qmlInfo(object) << "Test Message";
QObject *nested = qvariant_cast<QObject *>(object->property("nested"));
QVERIFY(nested != 0);
message = component.url().toString() + ":6:13: QML QtObject: Second Test Message";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
+ QTest::ignoreMessage(QtInfoMsg, qPrintable(message));
qmlInfo(nested) << "Second Test Message";
}
@@ -86,11 +87,11 @@ void tst_qqmlinfo::nestedQmlObject()
QVERIFY(nested2 != 0);
QString message = component.url().toString() + ":5:13: QML NestedObject: Outer Object";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
+ QTest::ignoreMessage(QtInfoMsg, qPrintable(message));
qmlInfo(nested) << "Outer Object";
message = testFileUrl("NestedObject.qml").toString() + ":6:14: QML QtObject: Inner Object";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
+ QTest::ignoreMessage(QtInfoMsg, qPrintable(message));
qmlInfo(nested2) << "Inner Object";
}
@@ -107,28 +108,28 @@ void tst_qqmlinfo::nestedComponent()
QVERIFY(nested2 != 0);
QString message = component.url().toString() + ":10:9: QML NestedObject: Complex Object";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
+ QTest::ignoreMessage(QtInfoMsg, qPrintable(message));
qmlInfo(nested) << "Complex Object";
message = component.url().toString() + ":16:9: QML Image: Simple Object";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
+ QTest::ignoreMessage(QtInfoMsg, qPrintable(message));
qmlInfo(nested2) << "Simple Object";
}
void tst_qqmlinfo::nonQmlObject()
{
QObject object;
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML QtObject: Test Message");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: QML QtObject: Test Message");
qmlInfo(&object) << "Test Message";
QTimer nonQmlObject;
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML QTimer: Test Message");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: QML QTimer: Test Message");
qmlInfo(&nonQmlObject) << "Test Message";
}
void tst_qqmlinfo::nullObject()
{
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Null Object Test Message");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: Null Object Test Message");
qmlInfo(0) << "Null Object Test Message";
}
@@ -137,50 +138,50 @@ void tst_qqmlinfo::nonQmlContextedObject()
QObject object;
QQmlContext context(&engine);
QQmlEngine::setContextForObject(&object, &context);
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML QtObject: Test Message");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: QML QtObject: Test Message");
qmlInfo(&object) << "Test Message";
}
void tst_qqmlinfo::types()
{
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: false");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: false");
qmlInfo(0) << false;
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: 1.1");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: 1.1");
qmlInfo(0) << 1.1;
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: 1.2");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: 1.2");
qmlInfo(0) << 1.2f;
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: 15");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: 15");
qmlInfo(0) << 15;
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: 'b'");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: 'b'");
qmlInfo(0) << QChar('b');
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: \"Qt\"");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: \"Qt\"");
qmlInfo(0) << QByteArray("Qt");
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: true");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: true");
qmlInfo(0) << bool(true);
//### do we actually want QUrl to show up in the output?
//### why the extra space at the end?
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QUrl(\"http://www.qt-project.org\") ");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: QUrl(\"http://www.qt-project.org\") ");
qmlInfo(0) << QUrl("http://www.qt-project.org");
//### should this be quoted?
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: hello");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: hello");
qmlInfo(0) << QLatin1String("hello");
//### should this be quoted?
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: World");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: World");
QString str("Hello World");
QStringRef ref(&str, 6, 5);
qmlInfo(0) << ref;
//### should this be quoted?
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Quick");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: Quick");
qmlInfo(0) << QString ("Quick");
}
@@ -188,7 +189,7 @@ void tst_qqmlinfo::chaining()
{
QString str("Hello World");
QStringRef ref(&str, 6, 5);
- QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: false 1.1 1.2 15 hello 'b' World \"Qt\" true Quick QUrl(\"http://www.qt-project.org\") ");
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: false 1.1 1.2 15 hello 'b' World \"Qt\" true Quick QUrl(\"http://www.qt-project.org\") ");
qmlInfo(0) << false << ' '
<< 1.1 << ' '
<< 1.2f << ' '
@@ -202,6 +203,19 @@ void tst_qqmlinfo::chaining()
<< QUrl("http://www.qt-project.org");
}
+// Ensure that messages of different types are sent with the correct QtMsgType.
+void tst_qqmlinfo::messageTypes()
+{
+ QTest::ignoreMessage(QtDebugMsg, "<Unknown File>: debug");
+ qmlDebug(0) << QLatin1String("debug");
+
+ QTest::ignoreMessage(QtInfoMsg, "<Unknown File>: info");
+ qmlInfo(0) << QLatin1String("info");
+
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: warning");
+ qmlWarning(0) << QLatin1String("warning");
+}
+
QTEST_MAIN(tst_qqmlinfo)
#include "tst_qqmlinfo.moc"
diff --git a/tests/auto/qml/qqmllocale/data/date.qml b/tests/auto/qml/qqmllocale/data/date.qml
index 3f58497d22..d8cd043cdf 100644
--- a/tests/auto/qml/qqmllocale/data/date.qml
+++ b/tests/auto/qml/qqmllocale/data/date.qml
@@ -7,6 +7,7 @@ QtObject {
locale = Qt.locale(l)
}
+ // Month number 9 is October: JS Date()'s month range is 0 to 11.
function toLocaleString(fmt) {
var d = new Date(2011, 9, 7, 18, 53, 48, 345);
if (fmt < 0)
diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
index 4d2cae1523..d0ce83b997 100644
--- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
+++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
@@ -640,9 +640,7 @@ void tst_qqmllocale::dateToLocaleString()
QObject *obj = c.create();
QVERIFY(obj);
- QDateTime dt;
- dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
- dt.setTime(QTime(18, 53, 48, 345));
+ const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345));
QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
Q_ARG(QVariant, QVariant(locale)));
@@ -701,9 +699,7 @@ void tst_qqmllocale::dateToLocaleStringFormatted()
QObject *obj = c.create();
QVERIFY(obj);
- QDateTime dt;
- dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
- dt.setTime(QTime(18, 53, 48, 345));
+ const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345));
QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
Q_ARG(QVariant, QVariant(locale)));
@@ -732,9 +728,7 @@ void tst_qqmllocale::dateToLocaleDateString()
QObject *obj = c.create();
QVERIFY(obj);
- QDateTime dt;
- dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
- dt.setTime(QTime(18, 53, 48, 345));
+ const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345));
QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
Q_ARG(QVariant, QVariant(locale)));
@@ -793,9 +787,7 @@ void tst_qqmllocale::dateToLocaleDateStringFormatted()
QObject *obj = c.create();
QVERIFY(obj);
- QDateTime dt;
- dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
- dt.setTime(QTime(18, 53, 48, 345));
+ const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345));
QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
Q_ARG(QVariant, QVariant(locale)));
@@ -824,9 +816,7 @@ void tst_qqmllocale::dateToLocaleTimeString()
QObject *obj = c.create();
QVERIFY(obj);
- QDateTime dt;
- dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
- dt.setTime(QTime(18, 53, 48, 345));
+ const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345));
QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
Q_ARG(QVariant, QVariant(locale)));
@@ -885,9 +875,7 @@ void tst_qqmllocale::dateToLocaleTimeStringFormatted()
QObject *obj = c.create();
QVERIFY(obj);
- QDateTime dt;
- dt.setDate(QDate(2011, 10, 7)); // weirdly, JS Date month range is 0-11
- dt.setTime(QTime(18, 53, 48, 345));
+ const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345));
QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
Q_ARG(QVariant, QVariant(locale)));
@@ -927,21 +915,20 @@ void tst_qqmllocale::dateFromLocaleString()
QObject *obj = c.create();
QVERIFY(obj);
- QDateTime dt;
- dt.setDate(QDate(2011, 10, 7));
- dt.setTime(QTime(18, 53, 48, 345));
+ const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345));
QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
Q_ARG(QVariant, QVariant(locale)));
QLocale l(locale);
+ const QString localeText(l.toString(dt, format));
QVariant val;
QMetaObject::invokeMethod(obj, "fromLocaleString", Qt::DirectConnection,
Q_RETURN_ARG(QVariant, val),
- Q_ARG(QVariant, QVariant(l.toString(dt, format))),
+ Q_ARG(QVariant, QVariant(localeText)),
Q_ARG(QVariant, QVariant(format)));
- QDateTime pd = l.toDateTime(l.toString(dt, format), format);
+ QDateTime pd = l.toDateTime(localeText, format);
QCOMPARE(val.toDateTime(), pd);
}
@@ -971,21 +958,20 @@ void tst_qqmllocale::dateFromLocaleDateString()
QObject *obj = c.create();
QVERIFY(obj);
- QDateTime dt;
- dt.setDate(QDate(2011, 10, 7));
- dt.setTime(QTime(18, 53, 48, 345));
+ const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345));
QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
Q_ARG(QVariant, QVariant(locale)));
QLocale l(locale);
+ const QString localeText(l.toString(dt, format));
QVariant val;
QMetaObject::invokeMethod(obj, "fromLocaleDateString", Qt::DirectConnection,
Q_RETURN_ARG(QVariant, val),
- Q_ARG(QVariant, QVariant(l.toString(dt, format))),
+ Q_ARG(QVariant, QVariant(localeText)),
Q_ARG(QVariant, QVariant(format)));
- QDate pd = l.toDate(l.toString(dt, format), format);
+ QDate pd = l.toDate(localeText, format);
QCOMPARE(val.toDate(), pd);
}
@@ -1015,21 +1001,20 @@ void tst_qqmllocale::dateFromLocaleTimeString()
QObject *obj = c.create();
QVERIFY(obj);
- QDateTime dt;
- dt.setDate(QDate(2011, 10, 7));
- dt.setTime(QTime(18, 53, 48, 345));
+ const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345));
QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection,
Q_ARG(QVariant, QVariant(locale)));
QLocale l(locale);
+ const QString localeText(l.toString(dt, format));
QVariant val;
QMetaObject::invokeMethod(obj, "fromLocaleTimeString", Qt::DirectConnection,
Q_RETURN_ARG(QVariant, val),
- Q_ARG(QVariant, QVariant(l.toString(dt, format))),
+ Q_ARG(QVariant, QVariant(localeText)),
Q_ARG(QVariant, QVariant(format)));
- QTime pd = l.toTime(l.toString(dt, format), format);
+ QTime pd = l.toTime(localeText, format);
QCOMPARE(val.toTime(), pd);
}
@@ -1267,7 +1252,10 @@ QString DateFormatter::getLocalizedForm(const QString &isoTimestamp)
// which will require linking to a different library to access that API.
static void setTimeZone(const QByteArray &tz)
{
- qputenv("TZ", tz);
+ if (tz.isEmpty())
+ qunsetenv("TZ");
+ else
+ qputenv("TZ", tz);
::tzset();
// following left for future reference, see comment above
@@ -1291,7 +1279,7 @@ void tst_qqmllocale::timeZoneUpdated()
QQmlComponent c(&e, testFileUrl("timeZoneUpdated.qml"));
QScopedPointer<QObject> obj(c.create());
QVERIFY(obj);
- QCOMPARE(obj->property("success").toBool(), true);
+ QVERIFY(obj->property("success").toBool());
// Change to Indian time
setTimeZone(QByteArray("IST-05:30"));
@@ -1302,7 +1290,7 @@ void tst_qqmllocale::timeZoneUpdated()
setTimeZone(original);
QMetaObject::invokeMethod(obj.data(), "resetTimeZone");
- QCOMPARE(obj->property("success").toBool(), true);
+ QVERIFY(obj->property("success").toBool());
}
#endif
diff --git a/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp b/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp
index e16bfb08a2..3b982d1ab7 100644
--- a/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp
+++ b/tests/auto/qml/qqmlsqldatabase/tst_qqmlsqldatabase.cpp
@@ -31,12 +31,6 @@
#include <QtQuick/private/qquicktext_p.h>
#include <private/qqmlengine_p.h>
#include <QtCore/qcryptographichash.h>
-/*
-#include <QtWebKit/qwebpage.h>
-#include <QtWebKit/qwebframe.h>
-#include <QtWebKit/qwebdatabase.h>
-#include <QtWebKit/qwebsecurityorigin.h>
-*/
#include <QtSql/qsqldatabase.h>
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
@@ -150,42 +144,6 @@ void tst_qqmlsqldatabase::testQml_data()
// test - in which case increment total_databases_created_by_tests above.
}
-/*
-class QWebPageWithJavaScriptConsoleMessages : public QWebPage {
-public:
- void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID)
- {
- qWarning() << sourceID << ":" << lineNumber << ":" << message;
- }
-};
-
-void tst_qqmlsqldatabase::validateAgainstWebkit()
-{
- // Validates tests against WebKit (HTML5) support.
- //
- QFETCH(QString, jsfile);
- QFETCH(QString, result);
- QFETCH(int, databases);
-
- QFile f(jsfile);
- QVERIFY(f.open(QIODevice::ReadOnly));
- QString js=f.readAll();
-
- QWebPageWithJavaScriptConsoleMessages webpage;
- webpage.settings()->setOfflineStoragePath(dbDir());
- webpage.settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
-
- QEXPECT_FAIL("","WebKit doesn't support openDatabaseSync yet", Continue);
- QCOMPARE(webpage.mainFrame()->evaluateJavaScript(js).toString(),result);
-
- QTest::qWait(100); // WebKit crashes if you quit it too fast
-
- QWebSecurityOrigin origin = webpage.mainFrame()->securityOrigin();
- QList<QWebDatabase> dbs = origin.databases();
- QCOMPARE(dbs.count(), databases);
-}
-*/
-
void tst_qqmlsqldatabase::testQml()
{
if (engine->offlineStoragePath().isEmpty())
diff --git a/tests/auto/qmltest/BLACKLIST b/tests/auto/qmltest/BLACKLIST
index c38347b42a..fd796fcdb4 100644
--- a/tests/auto/qmltest/BLACKLIST
+++ b/tests/auto/qmltest/BLACKLIST
@@ -9,3 +9,5 @@ linux
linux
[ListView::test_listInteractiveCurrentIndexEnforce]
linux
+[mouserelease::test_mouseDrag]
+rhel-7.2
diff --git a/examples/quick/demos/samegame/content/BBSettings.qml b/tests/auto/qmltest/layout/Container.qml
index cd6be7dcf5..db3d68c485 100644
--- a/examples/quick/demos/samegame/content/BBSettings.qml
+++ b/tests/auto/qmltest/layout/Container.qml
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
@@ -38,24 +38,18 @@
**
****************************************************************************/
-import QtQml 2.0
+import QtQuick 2.5
+import QtQuick.Layouts 1.2
-QtObject {
- // This height/width is here for desktop testing, otherwise
- // we could just use Screen.width/Screen.height.
- property int screenHeight: 1280
- property int screenWidth: 768
+Item {
+ objectName: "qtbug51927-window"
+ visible: true
- property int menuDelay: 500
+ default property alias _contents: customContent.data
- property int headerHeight: 70
- property int footerHeight: 100
-
- property int fontPixelSize: 55
-
- property int blockSize: 64
-
- property int toolButtonHeight: 64
-
- property int menuButtonSpacing: 15
+ ColumnLayout {
+ id: customContent
+ objectName: "qtbug51927-columnLayout"
+ anchors.fill: parent
+ }
}
diff --git a/examples/quick/demos/samegame/content/+blackberry/Settings.qml b/tests/auto/qmltest/layout/ContainerUser.qml
index c744ca6f51..ff7ce6221b 100644
--- a/examples/quick/demos/samegame/content/+blackberry/Settings.qml
+++ b/tests/auto/qmltest/layout/ContainerUser.qml
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
@@ -38,10 +38,16 @@
**
****************************************************************************/
-pragma Singleton
-import QtQml 2.0
+import QtQuick 2.6
+import QtQuick.Window 2.2
-// Instantiating a BBSettings class that can be easily tweaked for future
-// BB devices (we may have more selectors added)
-BBSettings {
+Container {
+ visible: true
+
+ Text {
+ objectName: "qtbug51927-text"
+ text: qsTr("Hello World")
+ anchors.centerIn: parent
+ renderType: Text.QtRendering
+ }
}
diff --git a/tests/auto/qmltest/layout/tst_layout.qml b/tests/auto/qmltest/layout/tst_layout.qml
new file mode 100644
index 0000000000..ee44a01080
--- /dev/null
+++ b/tests/auto/qmltest/layout/tst_layout.qml
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtTest 1.0
+
+TestCase {
+ id: testCase
+ name: "Tests_Layout"
+ when:windowShown
+ width:400
+ height:400
+
+ function test_invalidParent() {
+ ignoreWarning('<Unknown File>:1:49: QML QtObject: Layout must be attached to Item elements')
+ var object = Qt.createQmlObject('import QtQuick 2.2; import QtQuick.Layouts 1.0; QtObject { Layout.fillWidth: true }', testCase, '');
+ object.destroy()
+ }
+
+ function test_defaultPropertyAliasCrash() {
+ var containerUserComponent = Qt.createComponent("ContainerUser.qml");
+ compare(containerUserComponent.status, Component.Ready);
+
+ var containerUser = containerUserComponent.createObject(testCase);
+ verify(containerUser);
+
+ // Shouldn't crash.
+ containerUser.destroy();
+ }
+}
+
diff --git a/tests/auto/qmltest/positioners/tst_positioners.qml b/tests/auto/qmltest/positioners/tst_positioners.qml
new file mode 100644
index 0000000000..03a0e13225
--- /dev/null
+++ b/tests/auto/qmltest/positioners/tst_positioners.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtTest 1.1
+
+Item {
+ Column {
+ id: column
+ Repeater {
+ id: repeater
+ model: 2
+ Rectangle {
+ width: 100
+ height: 30
+ border.width: 1
+ }
+ }
+ }
+
+ SignalSpy {
+ id: spy
+ target: column
+ signalName: "positioningComplete"
+ }
+
+ TestCase {
+ function test_forceLayout() {
+ compare(column.height, 60)
+ repeater.model = 4
+ column.forceLayout()
+ compare(column.height, 120)
+
+ // initial positioning and our forced layout
+ compare(spy.count, 2)
+ }
+ }
+}
diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp
index 1ca809c05f..d5c9aaeb90 100644
--- a/tests/auto/quick/examples/tst_examples.cpp
+++ b/tests/auto/quick/examples/tst_examples.cpp
@@ -88,12 +88,6 @@ tst_examples::tst_examples()
excludedDirs << "snippets/qml/qtbinding";
excludedDirs << "snippets/qml/imports";
-#ifdef QT_NO_WEBKIT
- excludedDirs << "qtquick/modelviews/webview";
- excludedDirs << "demos/webbrowser";
- excludedDirs << "doc/src/snippets/qml/webview";
-#endif
-
#ifdef QT_NO_XMLPATTERNS
excludedDirs << "demos/twitter";
excludedDirs << "demos/flickr";
diff --git a/tests/auto/quick/qquickanimations/data/pathLineUnspecifiedXYBug.qml b/tests/auto/quick/qquickanimations/data/pathLineUnspecifiedXYBug.qml
new file mode 100644
index 0000000000..426360bbcc
--- /dev/null
+++ b/tests/auto/quick/qquickanimations/data/pathLineUnspecifiedXYBug.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400
+ height: 400
+
+ Rectangle {
+ id: redRect
+ color: "red"
+ width: 100; height: 100
+ x: 50; y: 50
+ }
+
+ PathAnimation {
+ target: redRect
+ duration: 1000
+ path: Path {
+ startX: 100; startY: 100
+
+ PathLine {
+ x: 200
+ y: 200
+ }
+
+ PathLine {}
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickanimations/data/pathSvgAnimation.qml b/tests/auto/quick/qquickanimations/data/pathSvgAnimation.qml
new file mode 100644
index 0000000000..e409bb031f
--- /dev/null
+++ b/tests/auto/quick/qquickanimations/data/pathSvgAnimation.qml
@@ -0,0 +1,25 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400
+ height: 400
+
+ Rectangle {
+ id: redRect
+ color: "red"
+ width: 100; height: 100
+ x: 50; y: 50
+ }
+
+ PathAnimation {
+ target: redRect
+ duration: 1000;
+ path: Path {
+ startX: 100; startY: 100
+
+ PathSvg {
+ path: "M 200 200"
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
index 6e265503a1..fbd6c9c97e 100644
--- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
+++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
@@ -101,6 +101,8 @@ private slots:
void scriptActionCrash();
void animatorInvalidTargetCrash();
void defaultPropertyWarning();
+ void pathSvgAnimation();
+ void pathLineUnspecifiedXYBug();
};
#define QTIMED_COMPARE(lhs, rhs) do { \
@@ -1523,6 +1525,48 @@ void tst_qquickanimations::defaultPropertyWarning()
QVERIFY(warnings.isEmpty());
}
+// QTBUG-57666
+void tst_qquickanimations::pathSvgAnimation()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("pathSvgAnimation.qml"));
+ QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(component.create()));
+ QVERIFY(rect);
+
+ QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
+ QVERIFY(redRect);
+ QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
+ QVERIFY(pathAnim);
+
+ QCOMPARE(redRect->x(), qreal(50));
+ QCOMPARE(redRect->y(), qreal(50));
+
+ pathAnim->start();
+ QTRY_COMPARE(redRect->x(), qreal(200));
+ QCOMPARE(redRect->y(), qreal(200));
+}
+
+// QTBUG-57666
+void tst_qquickanimations::pathLineUnspecifiedXYBug()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("pathLineUnspecifiedXYBug.qml"));
+ QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(component.create()));
+ QVERIFY(rect);
+
+ QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
+ QVERIFY(redRect);
+ QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
+ QVERIFY(pathAnim);
+
+ QCOMPARE(redRect->x(), qreal(50));
+ QCOMPARE(redRect->y(), qreal(50));
+
+ pathAnim->start();
+ QTRY_COMPARE(redRect->x(), qreal(0));
+ QCOMPARE(redRect->y(), qreal(0));
+}
+
QTEST_MAIN(tst_qquickanimations)
#include "tst_qquickanimations.moc"
diff --git a/tests/auto/quick/qquickflickable/data/overshoot.qml b/tests/auto/quick/qquickflickable/data/overshoot.qml
new file mode 100644
index 0000000000..4235156479
--- /dev/null
+++ b/tests/auto/quick/qquickflickable/data/overshoot.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+
+Flickable {
+ width: 200; height: 200
+ contentWidth: rect.width; contentHeight: rect.height
+
+ property real minContentY: 0
+ property real maxContentY: 0
+ onContentYChanged: {
+ minContentY = Math.min(contentY, minContentY)
+ maxContentY = Math.max(contentY, maxContentY)
+ }
+
+ property real minContentX: 0
+ property real maxContentX: 0
+ onContentXChanged: {
+ minContentX = Math.min(contentX, minContentX)
+ maxContentX = Math.max(contentX, maxContentX)
+ }
+
+ property real minVerticalOvershoot: 0
+ property real maxVerticalOvershoot: 0
+ onVerticalOvershootChanged: {
+ minVerticalOvershoot = Math.min(verticalOvershoot, minVerticalOvershoot)
+ maxVerticalOvershoot = Math.max(verticalOvershoot, maxVerticalOvershoot)
+ }
+
+ property real minHorizontalOvershoot: 0
+ property real maxHorizontalOvershoot: 0
+ onHorizontalOvershootChanged: {
+ minHorizontalOvershoot = Math.min(horizontalOvershoot, minHorizontalOvershoot)
+ maxHorizontalOvershoot = Math.max(horizontalOvershoot, maxHorizontalOvershoot)
+ }
+
+ function reset() {
+ minContentY = contentY
+ maxContentY = contentY
+ minContentX = contentX
+ maxContentX = contentX
+ minVerticalOvershoot = 0
+ maxVerticalOvershoot = 0
+ minHorizontalOvershoot = 0
+ maxHorizontalOvershoot = 0
+ }
+
+ Rectangle {
+ id: rect
+ color: "red"
+ width: 400; height: 400
+ }
+}
diff --git a/tests/auto/quick/qquickflickable/data/overshoot_reentrant.qml b/tests/auto/quick/qquickflickable/data/overshoot_reentrant.qml
new file mode 100644
index 0000000000..bc7abba25a
--- /dev/null
+++ b/tests/auto/quick/qquickflickable/data/overshoot_reentrant.qml
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+
+Flickable {
+ width: 200; height: 200
+ contentWidth: rect.width; contentHeight: rect.height
+
+ property real contentPosAdjustment: 0.0
+
+ onContentXChanged: {
+ var adjustment = contentPosAdjustment
+ contentPosAdjustment = 0.0
+ contentX += adjustment
+ }
+
+ onContentYChanged: {
+ var adjustment = contentPosAdjustment
+ contentPosAdjustment = 0.0
+ contentY += adjustment
+ }
+
+ Rectangle {
+ id: rect
+ border.color: "red"
+ border.width: 5
+ width: 400; height: 400
+ }
+}
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 942e99018f..1ad691d1c1 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -95,6 +95,9 @@ private slots:
void ratios_smallContent();
void contentXYNotTruncatedToInt();
void keepGrab();
+ void overshoot();
+ void overshoot_data();
+ void overshoot_reentrant();
private:
void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to);
@@ -2037,6 +2040,199 @@ void tst_qquickflickable::keepGrab()
QVERIFY(flickable->contentY() != 0.0);
}
+Q_DECLARE_METATYPE(QQuickFlickable::BoundsBehavior)
+
+void tst_qquickflickable::overshoot()
+{
+ QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior);
+
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("overshoot.qml"));
+ window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
+ QVERIFY(flickable);
+
+ QCOMPARE(flickable->width(), 200.0);
+ QCOMPARE(flickable->height(), 200.0);
+ QCOMPARE(flickable->contentWidth(), 400.0);
+ QCOMPARE(flickable->contentHeight(), 400.0);
+
+ flickable->setBoundsBehavior(boundsBehavior);
+
+ // drag past the beginning
+ QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(10, 10));
+ QTest::mouseMove(window.data(), QPoint(20, 20));
+ QTest::mouseMove(window.data(), QPoint(30, 30));
+ QTest::mouseMove(window.data(), QPoint(40, 40));
+ QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(50, 50));
+
+ if (boundsBehavior & QQuickFlickable::DragOverBounds) {
+ QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0);
+ QVERIFY(flickable->property("minHorizontalOvershoot").toReal() < 0.0);
+ QCOMPARE(flickable->property("minContentY").toReal(),
+ flickable->property("minVerticalOvershoot").toReal());
+ QCOMPARE(flickable->property("minContentX").toReal(),
+ flickable->property("minHorizontalOvershoot").toReal());
+ } else {
+ QCOMPARE(flickable->property("minContentY").toReal(), 0.0);
+ QCOMPARE(flickable->property("minContentX").toReal(), 0.0);
+ QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0);
+ }
+ QCOMPARE(flickable->property("maxContentY").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxContentX").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0);
+
+ flickable->setContentX(20.0);
+ flickable->setContentY(20.0);
+ QMetaObject::invokeMethod(flickable, "reset");
+
+ // flick past the beginning
+ flick(window.data(), QPoint(10, 10), QPoint(50, 50), 100);
+ QTRY_VERIFY(!flickable->property("flicking").toBool());
+
+ if (boundsBehavior & QQuickFlickable::OvershootBounds) {
+ QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0);
+ QVERIFY(flickable->property("minHorizontalOvershoot").toReal() < 0.0);
+ QCOMPARE(flickable->property("minContentY").toReal(),
+ flickable->property("minVerticalOvershoot").toReal());
+ QCOMPARE(flickable->property("minContentX").toReal(),
+ flickable->property("minHorizontalOvershoot").toReal());
+ } else {
+ QCOMPARE(flickable->property("minContentY").toReal(), 0.0);
+ QCOMPARE(flickable->property("minContentX").toReal(), 0.0);
+ QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0);
+ }
+ QCOMPARE(flickable->property("maxContentY").toReal(), 20.0);
+ QCOMPARE(flickable->property("maxContentX").toReal(), 20.0);
+ QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0);
+
+ flickable->setContentX(200.0);
+ flickable->setContentY(200.0);
+ QMetaObject::invokeMethod(flickable, "reset");
+
+ // drag past the end
+ QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(50, 50));
+ QTest::mouseMove(window.data(), QPoint(40, 40));
+ QTest::mouseMove(window.data(), QPoint(30, 30));
+ QTest::mouseMove(window.data(), QPoint(20, 20));
+ QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(10, 10));
+
+ if (boundsBehavior & QQuickFlickable::DragOverBounds) {
+ QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0);
+ QVERIFY(flickable->property("maxHorizontalOvershoot").toReal() > 0.0);
+ QCOMPARE(flickable->property("maxContentY").toReal() - 200.0,
+ flickable->property("maxVerticalOvershoot").toReal());
+ QCOMPARE(flickable->property("maxContentX").toReal() - 200.0,
+ flickable->property("maxHorizontalOvershoot").toReal());
+ } else {
+ QCOMPARE(flickable->property("maxContentY").toReal(), 200.0);
+ QCOMPARE(flickable->property("maxContentX").toReal(), 200.0);
+ QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0);
+ }
+ QCOMPARE(flickable->property("minContentY").toReal(), 200.0);
+ QCOMPARE(flickable->property("minContentX").toReal(), 200.0);
+ QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0);
+
+ flickable->setContentX(180.0);
+ flickable->setContentY(180.0);
+ QMetaObject::invokeMethod(flickable, "reset");
+
+ // flick past the end
+ flick(window.data(), QPoint(50, 50), QPoint(10, 10), 100);
+ QTRY_VERIFY(!flickable->property("flicking").toBool());
+
+ if (boundsBehavior & QQuickFlickable::OvershootBounds) {
+ QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0);
+ QVERIFY(flickable->property("maxHorizontalOvershoot").toReal() > 0.0);
+ QCOMPARE(flickable->property("maxContentY").toReal() - 200.0,
+ flickable->property("maxVerticalOvershoot").toReal());
+ QCOMPARE(flickable->property("maxContentX").toReal() - 200.0,
+ flickable->property("maxHorizontalOvershoot").toReal());
+ } else {
+ QCOMPARE(flickable->property("maxContentY").toReal(), 200.0);
+ QCOMPARE(flickable->property("maxContentX").toReal(), 200.0);
+ QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0);
+ }
+ QCOMPARE(flickable->property("minContentY").toReal(), 180.0);
+ QCOMPARE(flickable->property("minContentX").toReal(), 180.0);
+ QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0);
+}
+
+void tst_qquickflickable::overshoot_data()
+{
+ QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior");
+
+ QTest::newRow("StopAtBounds")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds);
+ QTest::newRow("DragOverBounds")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds);
+ QTest::newRow("OvershootBounds")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds);
+ QTest::newRow("DragAndOvershootBounds")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+}
+
+void tst_qquickflickable::overshoot_reentrant()
+{
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("overshoot_reentrant.qml"));
+ window->show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
+ QVERIFY(flickable);
+
+ // horizontal
+ flickable->setContentX(-10.0);
+ QCOMPARE(flickable->contentX(), -10.0);
+ QCOMPARE(flickable->horizontalOvershoot(), -10.0);
+
+ flickable->setProperty("contentPosAdjustment", -5.0);
+ flickable->setContentX(-20.0);
+ QCOMPARE(flickable->contentX(), -25.0);
+ QCOMPARE(flickable->horizontalOvershoot(), -25.0);
+
+ flickable->setContentX(210);
+ QCOMPARE(flickable->contentX(), 210.0);
+ QCOMPARE(flickable->horizontalOvershoot(), 10.0);
+
+ flickable->setProperty("contentPosAdjustment", 5.0);
+ flickable->setContentX(220.0);
+ QCOMPARE(flickable->contentX(), 225.0);
+ QCOMPARE(flickable->horizontalOvershoot(), 25.0);
+
+ // vertical
+ flickable->setContentY(-10.0);
+ QCOMPARE(flickable->contentY(), -10.0);
+ QCOMPARE(flickable->verticalOvershoot(), -10.0);
+
+ flickable->setProperty("contentPosAdjustment", -5.0);
+ flickable->setContentY(-20.0);
+ QCOMPARE(flickable->contentY(), -25.0);
+ QCOMPARE(flickable->verticalOvershoot(), -25.0);
+
+ flickable->setContentY(210);
+ QCOMPARE(flickable->contentY(), 210.0);
+ QCOMPARE(flickable->verticalOvershoot(), 10.0);
+
+ flickable->setProperty("contentPosAdjustment", 5.0);
+ flickable->setContentY(220.0);
+ QCOMPARE(flickable->contentY(), 225.0);
+ QCOMPARE(flickable->verticalOvershoot(), 25.0);
+}
+
QTEST_MAIN(tst_qquickflickable)
#include "tst_qquickflickable.moc"
diff --git a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp
index 650892d650..4da6da6043 100644
--- a/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp
+++ b/tests/auto/quick/qquickgraphicsinfo/tst_qquickgraphicsinfo.cpp
@@ -51,7 +51,7 @@ private slots:
void tst_QQuickGraphicsInfo::testProperties()
{
QQuickView view;
- view.setSource(QUrl::fromLocalFile("data/basic.qml"));
+ view.setSource(QUrl("data/basic.qml"));
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
index d345163db5..4699f947a1 100644
--- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp
+++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
@@ -145,9 +145,9 @@ void tst_qquickimage::imageSource_data()
QTest::newRow("remote") << "/colors.png" << 120.0 << 120.0 << true << false << true << "";
QTest::newRow("remote redirected") << "/oldcolors.png" << 120.0 << 120.0 << true << false << false << "";
if (QImageReader::supportedImageFormats().contains("svg"))
- QTest::newRow("remote svg") << "/heart.svg" << 550.0 << 500.0 << true << false << false << "";
+ QTest::newRow("remote svg") << "/heart.svg" << 595.0 << 841.0 << true << false << false << "";
if (QImageReader::supportedImageFormats().contains("svgz"))
- QTest::newRow("remote svgz") << "/heart.svgz" << 550.0 << 500.0 << true << false << false << "";
+ QTest::newRow("remote svgz") << "/heart.svgz" << 595.0 << 841.0 << true << false << false << "";
QTest::newRow("remote not found") << "/no-such-file.png" << 0.0 << 0.0 << true
<< false << true << "<Unknown File>:2:1: QML Image: Error transferring {{ServerBaseUrl}}/no-such-file.png - server replied: Not found";
@@ -309,10 +309,6 @@ void tst_qquickimage::mirror()
qreal devicePixelRatio = 1.0;
foreach (QQuickImage::FillMode fillMode, fillModes) {
-#if defined(Q_OS_BLACKBERRY)
- QWindow dummy; // On BlackBerry first window is always full screen,
- dummy.showFullScreen(); // so make test window a second window.
-#endif
QScopedPointer<QQuickView> window(new QQuickView);
window->setSource(testFileUrl("mirror.qml"));
@@ -402,12 +398,12 @@ void tst_qquickimage::svg()
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
QVERIFY(obj != 0);
- QCOMPARE(obj->width(), 300.0);
- QCOMPARE(obj->height(), 273.0);
+ QCOMPARE(obj->width(), 212.0);
+ QCOMPARE(obj->height(), 300.0);
obj->setSourceSize(QSize(200,200));
- QCOMPARE(obj->width(), 200.0);
- QCOMPARE(obj->height(), 182.0);
+ QCOMPARE(obj->width(), 141.0);
+ QCOMPARE(obj->height(), 200.0);
delete obj;
}
diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
index 44310008d6..5419778cfc 100644
--- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
+++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
@@ -44,10 +44,6 @@ public:
QImage runTest(const QString &fileName)
{
-#if defined(Q_OS_BLACKBERRY)
- QWindow dummy; // On BlackBerry first window is always full screen,
- dummy.showFullScreen(); // so make test window a second window.
-#endif
QQuickView view;
view.setSource(testFileUrl(fileName));
diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
index 2d4e227a9e..97860458fe 100644
--- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
+++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
@@ -802,6 +802,27 @@ Item {
layout.destroy() // Do not crash
}
+ Component {
+ id: rectangle_Component
+ Rectangle {
+ width: 100
+ height: 50
+ }
+ }
+
+ function test_destroyImplicitInvisibleLayout()
+ {
+ var root = rectangle_Component.createObject(container)
+ root.visible = false
+ var layout = layout_deleteLayout.createObject(root)
+ layout.visible = true
+ // at this point the layout is still invisible because root is invisible
+ layout.destroy()
+ // Do not crash when destructing the layout
+ waitForRendering(container) // should ideally call gc(), but does not work
+ root.destroy()
+ }
+
function test_sizeHintWithHiddenChildren(data) {
var layout = layout_sizeHint_Component.createObject(container)
var grid = layout.children[0]
diff --git a/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml b/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml
new file mode 100644
index 0000000000..8234ac6ef7
--- /dev/null
+++ b/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtTest 1.0
+import QtQuick.Layouts 1.3
+
+Item {
+ id: container
+ width: 200
+ height: 200
+ TestCase {
+ id: testCase
+ name: "Tests_StackLayout"
+ when: windowShown
+ width: 200
+ height: 200
+
+ Component {
+ id: layout_rearrange_Component
+
+ StackLayout {
+ width: 640
+ height: 480
+
+ property alias testRectangle: testRectangle
+
+ RowLayout {
+ spacing: 0
+
+ Rectangle {
+ Layout.preferredWidth: 100
+ Layout.preferredHeight: 100
+ }
+
+ Rectangle {
+ id: testRectangle
+ Layout.preferredWidth: 100
+ Layout.preferredHeight: 100
+ visible: false
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+
+ function test_rearrange()
+ {
+ var layout = layout_rearrange_Component.createObject(container)
+ compare(layout.testRectangle.x, 0)
+ layout.testRectangle.visible = true
+ tryCompare(layout.testRectangle, "x", 100)
+
+ layout.destroy()
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklayouts/qquicklayouts.pro b/tests/auto/quick/qquicklayouts/qquicklayouts.pro
index 9ed3e076be..5079d0a182 100644
--- a/tests/auto/quick/qquicklayouts/qquicklayouts.pro
+++ b/tests/auto/quick/qquicklayouts/qquicklayouts.pro
@@ -9,5 +9,6 @@ TESTDATA = data/*
OTHER_FILES += \
data/tst_rowlayout.qml \
- data/tst_gridlayout.qml
+ data/tst_gridlayout.qml \
+ data/tst_stacklayout.qml
diff --git a/tests/auto/quick/qquicklistview/data/flickBothDirections.qml b/tests/auto/quick/qquicklistview/data/flickBothDirections.qml
new file mode 100644
index 0000000000..5d80ce4110
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/flickBothDirections.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.9
+
+Rectangle {
+ width: 200
+ height: 200
+ ListView {
+ id: list
+ objectName: "list"
+ width: 100
+ height: 100
+ model: 20
+ anchors.centerIn: parent
+ orientation: initialOrientation
+ contentWidth: initialContentWidth
+ contentHeight: initialContentHeight
+ flickableDirection: initialFlickableDirection
+ delegate: Rectangle {
+ width: list.orientation == ListView.Vertical ? 120 : 10
+ height: list.orientation == ListView.Vertical ? 20 : 110
+ color: Qt.rgba(0, 0, index / 19, 1)
+ opacity: 0.8
+ }
+ Rectangle {
+ z: -1
+ width: 100
+ height: 100
+ border.width: 1
+ border.color: "red"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 4816d9c341..ff06c1e1a4 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -53,6 +53,7 @@ Q_DECLARE_METATYPE(Qt::LayoutDirection)
Q_DECLARE_METATYPE(QQuickItemView::VerticalLayoutDirection)
Q_DECLARE_METATYPE(QQuickItemView::PositionMode)
Q_DECLARE_METATYPE(QQuickListView::Orientation)
+Q_DECLARE_METATYPE(QQuickFlickable::FlickableDirection)
Q_DECLARE_METATYPE(Qt::Key)
using namespace QQuickViewTestUtil;
@@ -205,6 +206,8 @@ private slots:
void multipleDisplaced();
void flickBeyondBounds();
+ void flickBothDirections();
+ void flickBothDirections_data();
void destroyItemOnCreation();
void parentBinding();
@@ -7123,6 +7126,82 @@ void tst_QQuickListView::flickBeyondBounds()
}
}
+void tst_QQuickListView::flickBothDirections()
+{
+ QFETCH(bool, initValues);
+ QFETCH(QQuickListView::Orientation, orientation);
+ QFETCH(QQuickFlickable::FlickableDirection, flickableDirection);
+ QFETCH(qreal, contentWidth);
+ QFETCH(qreal, contentHeight);
+ QFETCH(QPointF, targetPos);
+
+ QQuickView *window = getView();
+ QQuickViewTestUtil::moveMouseAway(window);
+
+ QQmlContext *ctxt = window->rootContext();
+ ctxt->setContextProperty("initialOrientation", initValues ? orientation : QQuickListView::Vertical);
+ ctxt->setContextProperty("initialFlickableDirection", initValues ? flickableDirection : QQuickFlickable::VerticalFlick);
+ ctxt->setContextProperty("initialContentWidth", initValues ? contentWidth : -1);
+ ctxt->setContextProperty("initialContentHeight", initValues ? contentHeight : -1);
+
+ window->setSource(testFileUrl("flickBothDirections.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
+ QVERIFY(listview);
+
+ if (!initValues) {
+ listview->setOrientation(orientation);
+ listview->setFlickableDirection(flickableDirection);
+ if (contentWidth > 0)
+ listview->setContentWidth(contentWidth);
+ if (contentHeight > 0)
+ listview->setContentHeight(contentHeight);
+ }
+
+ flick(window, QPoint(100, 100), QPoint(25, 25), 50);
+ QVERIFY(listview->isMoving());
+ QTRY_VERIFY(!listview->isMoving());
+ QCOMPARE(listview->contentX(), targetPos.x());
+ QCOMPARE(listview->contentY(), targetPos.y());
+}
+
+void tst_QQuickListView::flickBothDirections_data()
+{
+ QTest::addColumn<bool>("initValues");
+ QTest::addColumn<QQuickListView::Orientation>("orientation");
+ QTest::addColumn<QQuickFlickable::FlickableDirection>("flickableDirection");
+ QTest::addColumn<qreal>("contentWidth");
+ QTest::addColumn<qreal>("contentHeight");
+ QTest::addColumn<QPointF>("targetPos");
+
+ // model: 20
+ // listview: 100x100
+ // vertical delegate: 120x20 -> contentHeight: 20x20=400
+ // horizontal delegate: 10x110 -> contentWidth: 20x10=200
+
+ QTest::newRow("init:vertical,-1") << true << QQuickListView::Vertical << QQuickFlickable::VerticalFlick << -1. << -1. << QPointF(0, 300);
+ QTest::newRow("init:vertical,120") << true << QQuickListView::Vertical << QQuickFlickable::VerticalFlick<< 120. << -1. << QPointF(0, 300);
+ QTest::newRow("init:vertical,auto,-1") << true << QQuickListView::Vertical << QQuickFlickable::AutoFlickDirection << -1. << -1. << QPointF(0, 300);
+ QTest::newRow("init:vertical,auto,120") << true << QQuickListView::Vertical << QQuickFlickable::AutoFlickDirection << 120. << -1. << QPointF(20, 300);
+
+ QTest::newRow("completed:vertical,-1") << false << QQuickListView::Vertical << QQuickFlickable::VerticalFlick << -1. << -1. << QPointF(0, 300);
+ QTest::newRow("completed:vertical,120") << false << QQuickListView::Vertical << QQuickFlickable::VerticalFlick << 120. << -1. << QPointF(0, 300);
+ QTest::newRow("completed:vertical,auto,-1") << false << QQuickListView::Vertical << QQuickListView::AutoFlickDirection << -1. << -1. << QPointF(0, 300);
+ QTest::newRow("completed:vertical,auto,120") << false << QQuickListView::Vertical << QQuickListView::AutoFlickDirection << 120. << -1. << QPointF(20, 300);
+
+ QTest::newRow("init:horizontal,-1") << true << QQuickListView::Horizontal << QQuickFlickable::HorizontalFlick << -1. << -1. << QPointF(100, 0);
+ QTest::newRow("init:horizontal,110") << true << QQuickListView::Horizontal << QQuickFlickable::HorizontalFlick <<-1. << 110. << QPointF(100, 0);
+ QTest::newRow("init:horizontal,auto,-1") << true << QQuickListView::Horizontal << QQuickListView::AutoFlickDirection << -1. << -1. << QPointF(100, 0);
+ QTest::newRow("init:horizontal,auto,110") << true << QQuickListView::Horizontal << QQuickListView::AutoFlickDirection << -1. << 110. << QPointF(100, 10);
+
+ QTest::newRow("completed:horizontal,-1") << false << QQuickListView::Horizontal << QQuickFlickable::HorizontalFlick << -1. << -1. << QPointF(100, 0);
+ QTest::newRow("completed:horizontal,110") << false << QQuickListView::Horizontal << QQuickFlickable::HorizontalFlick << -1. << 110. << QPointF(100, 0);
+ QTest::newRow("completed:horizontal,auto,-1") << false << QQuickListView::Horizontal << QQuickListView::AutoFlickDirection << -1. << -1. << QPointF(100, 0);
+ QTest::newRow("completed:horizontal,auto,110") << false << QQuickListView::Horizontal << QQuickListView::AutoFlickDirection << -1. << 110. << QPointF(100, 10);
+}
+
void tst_QQuickListView::destroyItemOnCreation()
{
QaimModel model;
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index 77af4796b6..3e7439f3e9 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -469,7 +469,7 @@ void tst_QQuickLoader::networkComponent()
// because in the synchronous case we're already done loading.
QTRY_COMPARE(component.status(), QQmlComponent::Ready);
- QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(item);
QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->children().at(1));
@@ -481,7 +481,6 @@ void tst_QQuickLoader::networkComponent()
QCOMPARE(loader->status(), QQuickLoader::Ready);
QCOMPARE(static_cast<QQuickItem*>(loader)->children().count(), 1);
- delete loader;
}
void tst_QQuickLoader::failNetworkRequest()
diff --git a/tests/auto/quick/qquickpathview/data/removePath.qml b/tests/auto/quick/qquickpathview/data/removePath.qml
new file mode 100644
index 0000000000..85029f3eaf
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/removePath.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+
+PathView {
+ width: 240
+ height: 200
+
+ path: myPath
+
+ delegate: Text { text: value }
+ model: 10
+
+ Path {
+ id: myPath
+ startX: 120; startY: 100
+ PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
+ PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 }
+ }
+
+ function removePath() {
+ path = null
+ }
+
+ function setPath() {
+ path = myPath
+ }
+}
diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
index ba3d182efc..b01d0c3cec 100644
--- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
+++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
@@ -141,6 +141,7 @@ private slots:
void addCustomAttribute();
void movementDirection_data();
void movementDirection();
+ void removePath();
};
class TestObject : public QObject
@@ -2504,6 +2505,19 @@ void tst_QQuickPathView::movementDirection()
verify_offsets(pathview, toidx, fromoffset, tooffset);
}
+void tst_QQuickPathView::removePath()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("removePath.qml"));
+ window->show();
+
+ QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject());
+ QVERIFY(pathview != 0);
+
+ QVERIFY(QMetaObject::invokeMethod(pathview, "removePath"));
+ QVERIFY(QMetaObject::invokeMethod(pathview, "setPath"));
+}
+
QTEST_MAIN(tst_QQuickPathView)
#include "tst_qquickpathview.moc"
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 2032f72e26..034ea4aec8 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -762,11 +762,6 @@ void tst_qquicktext::horizontalAlignment()
void tst_qquicktext::horizontalAlignment_RightToLeft()
{
-#if defined(Q_OS_BLACKBERRY)
- QQuickWindow dummy; // On BlackBerry first window is always full screen,
- dummy.showFullScreen(); // so make test window a second window.
-#endif
-
QScopedPointer<QQuickView> window(createView(testFile("horizontalAlignment_RightToLeft.qml")));
QQuickText *text = window->rootObject()->findChild<QQuickText*>("text");
QVERIFY(text != 0);
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index 1451f8e2fc..67921e1fd0 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -135,6 +135,7 @@ private slots:
void signal_accepted();
void signal_editingfinished();
+ void signal_textEdited();
void passwordCharacter();
void cursorDelegate_data();
@@ -2441,6 +2442,57 @@ void tst_qquicktextinput::signal_editingfinished()
QTRY_COMPARE(editingFinished2Spy.count(), 1);
}
+void tst_qquicktextinput::signal_textEdited()
+{
+ QQuickWindow window;
+ window.show();
+ window.requestActivate();
+ QTest::qWaitForWindowActive(&window);
+
+ QQuickTextInput *input = new QQuickTextInput(window.contentItem());
+ QVERIFY(input);
+
+ QSignalSpy textChangedSpy(input, SIGNAL(textChanged()));
+ QVERIFY(textChangedSpy.isValid());
+
+ QSignalSpy textEditedSpy(input, SIGNAL(textEdited()));
+ QVERIFY(textEditedSpy.isValid());
+
+ input->forceActiveFocus();
+ QTRY_VERIFY(input->hasActiveFocus());
+
+ int textChanges = 0;
+ int textEdits = 0;
+
+ QTest::keyClick(&window, Qt::Key_A);
+ QCOMPARE(textChangedSpy.count(), ++textChanges);
+ QCOMPARE(textEditedSpy.count(), ++textEdits);
+
+ QTest::keyClick(&window, Qt::Key_B);
+ QCOMPARE(textChangedSpy.count(), ++textChanges);
+ QCOMPARE(textEditedSpy.count(), ++textEdits);
+
+ QTest::keyClick(&window, Qt::Key_C);
+ QCOMPARE(textChangedSpy.count(), ++textChanges);
+ QCOMPARE(textEditedSpy.count(), ++textEdits);
+
+ QTest::keyClick(&window, Qt::Key_Space);
+ QCOMPARE(textChangedSpy.count(), ++textChanges);
+ QCOMPARE(textEditedSpy.count(), ++textEdits);
+
+ QTest::keyClick(&window, Qt::Key_Backspace);
+ QCOMPARE(textChangedSpy.count(), ++textChanges);
+ QCOMPARE(textEditedSpy.count(), ++textEdits);
+
+ input->clear();
+ QCOMPARE(textChangedSpy.count(), ++textChanges);
+ QCOMPARE(textEditedSpy.count(), textEdits);
+
+ input->setText("TextInput");
+ QCOMPARE(textChangedSpy.count(), ++textChanges);
+ QCOMPARE(textEditedSpy.count(), textEdits);
+}
+
/*
TextInput element should only handle left/right keys until the cursor reaches
the extent of the text, then they should ignore the keys.
diff --git a/tests/auto/quick/qquickwindow/data/grabContentItemToImage.qml b/tests/auto/quick/qquickwindow/data/grabContentItemToImage.qml
new file mode 100644
index 0000000000..9086e0cc84
--- /dev/null
+++ b/tests/auto/quick/qquickwindow/data/grabContentItemToImage.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+import QtQuick.Window 2.2 as Window
+
+Window.Window {
+ visible: true
+ width: 100
+ height: 100
+ property int success: 0
+
+ function grabContentItemToImage() {
+ contentItem.grabToImage(function (image) {
+ success = 1
+ })
+ }
+}
diff --git a/tests/auto/quick/qquickwindow/qquickwindow.pro b/tests/auto/quick/qquickwindow/qquickwindow.pro
index 05093ba8e0..b0a5f97a32 100644
--- a/tests/auto/quick/qquickwindow/qquickwindow.pro
+++ b/tests/auto/quick/qquickwindow/qquickwindow.pro
@@ -16,4 +16,5 @@ OTHER_FILES += \
data/AnimationsWhileHidden.qml \
data/Headless.qml \
data/showHideAnimate.qml \
- data/windoworder.qml
+ data/windoworder.qml \
+ data/grabContentItemToImage.qml
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 3e78230d2e..d3f43fcd4d 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -383,6 +383,8 @@ private slots:
void pointerEventTypeAndPointCount();
+ void grabContentItemToImage();
+
private:
QTouchDevice *touchDevice;
QTouchDevice *touchDeviceWithVelocity;
@@ -2604,6 +2606,23 @@ void tst_qquickwindow::pointerEventTypeAndPointCount()
QVERIFY(!pte.touchPointById(0));
}
+void tst_qquickwindow::grabContentItemToImage()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("grabContentItemToImage.qml"));
+
+ QObject *created = component.create();
+ QScopedPointer<QObject> cleanup(created);
+ QVERIFY(created);
+
+ QQuickWindow *window = qobject_cast<QQuickWindow *>(created);
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ QMetaObject::invokeMethod(window, "grabContentItemToImage");
+ QTRY_COMPARE(created->property("success").toInt(), 1);
+}
+
QTEST_MAIN(tst_qquickwindow)
#include "tst_qquickwindow.moc"
diff --git a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
index 642345a4bb..902325802c 100644
--- a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
+++ b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
@@ -2,7 +2,9 @@ CONFIG += testcase
TARGET = tst_qquickxmllistmodel
macx:CONFIG -= app_bundle
-SOURCES += tst_qquickxmllistmodel.cpp
+SOURCES += tst_qquickxmllistmodel.cpp \
+ ../../../../src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+HEADERS += ../../../../src/imports/xmllistmodel/qqmlxmllistmodel_p.h
include (../../shared/util.pri)
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index b5af61d723..4f4fac8fa5 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -194,8 +194,6 @@ private:
QQuickView *tst_TouchMouse::createView()
{
QQuickView *window = new QQuickView(0);
- window->setGeometry(0,0,240,320);
-
return window;
}
@@ -210,13 +208,11 @@ void tst_TouchMouse::initTestCase()
void tst_TouchMouse::simpleTouchEvent()
{
- QQuickView *window = createView();
-
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("singleitem.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
@@ -225,33 +221,33 @@ void tst_TouchMouse::simpleTouchEvent()
// Do not accept touch or mouse
QPoint p1;
p1 = QPoint(20, 20);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
// Get a touch and then mouse event offered
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
p1 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
// Not accepted, no updates
QCOMPARE(eventItem1->eventList.size(), 2);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 2);
eventItem1->eventList.clear();
// Accept touch
eventItem1->acceptTouch = true;
p1 = QPoint(20, 20);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 1);
p1 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 2);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 3);
eventItem1->eventList.clear();
@@ -263,8 +259,8 @@ void tst_TouchMouse::simpleTouchEvent()
eventItem1->acceptMouse = true;
eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
p1 = QPoint(20, 20);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
@@ -280,13 +276,13 @@ void tst_TouchMouse::simpleTouchEvent()
QCOMPARE(eventItem1->eventList.at(1).mousePosGlobal, globalPos);
p1 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 4);
QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchUpdate);
QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseMove);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 7);
QCOMPARE(eventItem1->eventList.at(4).type, QEvent::TouchEnd);
QCOMPARE(eventItem1->eventList.at(5).type, QEvent::MouseButtonRelease);
@@ -301,17 +297,17 @@ void tst_TouchMouse::simpleTouchEvent()
eventItem1->acceptMouse = false;
eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
p1 = QPoint(20, 20);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
p1 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 2);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 2);
eventItem1->eventList.clear();
@@ -322,32 +318,30 @@ void tst_TouchMouse::simpleTouchEvent()
eventItem1->acceptTouch = true;
eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
p1 = QPoint(20, 20);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 1);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
p1 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::TouchUpdate);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 3);
QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchEnd);
eventItem1->eventList.clear();
-
- delete window;
}
void tst_TouchMouse::testEventFilter()
{
// // install event filter on item and see that it can grab events
-// QQuickView *window = createView();
-
+// QScopedPointer<QQuickView> window(createView());
// window->setSource(testFileUrl("singleitem.qml"));
// window->show();
-// window->requestActivate();
+// QQuickViewTestUtil::centerOnScreen(window.data());
+// QVERIFY(QTest::qWaitForWindowActive(window.data()));
// QVERIFY(window->rootObject() != 0);
// EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
@@ -359,16 +353,15 @@ void tst_TouchMouse::testEventFilter()
// eventItem1->installEventFilter(filter);
// QPoint p1 = QPoint(20, 20);
-// QTest::touchEvent(window, device).press(0, p1, window);
+// QTest::touchEvent(window.data(), device).press(0, p1, window.data());
// // QEXPECT_FAIL("", "We do not implement event filters correctly", Abort);
// QCOMPARE(eventItem1->eventList.size(), 0);
// QCOMPARE(filter->eventList.size(), 1);
-// QTest::touchEvent(window, device).release(0, p1, window);
+// QTest::touchEvent(window.data(), device).release(0, p1, window.data());
// QCOMPARE(eventItem1->eventList.size(), 0);
// QCOMPARE(filter->eventList.size(), 2);
// delete filter;
-// delete window;
}
void tst_TouchMouse::mouse()
@@ -377,34 +370,29 @@ void tst_TouchMouse::mouse()
// - eventItem2
QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
- QQuickView *window = createView();
-
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("twoitems.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
QVERIFY(eventItem1);
EventItem *eventItem2 = window->rootObject()->findChild<EventItem*>("eventItem2");
QVERIFY(eventItem2);
- QVERIFY(QTest::qWaitForWindowExposed(window));
// bottom item likes mouse, top likes touch
eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
eventItem1->acceptMouse = true;
// item 2 doesn't accept anything, thus it sees a touch pass by
QPoint p1 = QPoint(30, 30);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
-
- delete window;
}
void tst_TouchMouse::touchOverMouse()
@@ -412,13 +400,11 @@ void tst_TouchMouse::touchOverMouse()
// eventItem1
// - eventItem2
- QQuickView *window = createView();
-
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("twoitems.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
@@ -430,27 +416,23 @@ void tst_TouchMouse::touchOverMouse()
eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
eventItem2->acceptTouch = true;
- QVERIFY(QTest::qWaitForWindowExposed(window));
-
QCOMPARE(eventItem1->eventList.size(), 0);
QPoint p1 = QPoint(20, 20);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 0);
QCOMPARE(eventItem2->eventList.size(), 1);
QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
p1 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem2->eventList.size(), 2);
QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchUpdate);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem2->eventList.size(), 3);
QCOMPARE(eventItem2->eventList.at(2).type, QEvent::TouchEnd);
eventItem2->eventList.clear();
-
- delete window;
}
void tst_TouchMouse::mouseOverTouch()
@@ -458,13 +440,11 @@ void tst_TouchMouse::mouseOverTouch()
// eventItem1
// - eventItem2
- QQuickView *window = createView();
-
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("twoitems.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
@@ -477,12 +457,10 @@ void tst_TouchMouse::mouseOverTouch()
eventItem2->setAcceptedMouseButtons(Qt::LeftButton);
eventItem2->acceptMouse = true;
- QVERIFY(QTest::qWaitForWindowExposed(window));
-
QPoint p1 = QPoint(20, 20);
QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 0);
QCOMPARE(eventItem2->eventList.size(), 2);
QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
@@ -490,13 +468,11 @@ void tst_TouchMouse::mouseOverTouch()
// p1 += QPoint(10, 0);
-// QTest::touchEvent(window, device).move(0, p1, window);
+// QTest::touchEvent(window.data(), device).move(0, p1, window.data());
// QCOMPARE(eventItem2->eventList.size(), 1);
-// QTest::touchEvent(window, device).release(0, p1, window);
+// QTest::touchEvent(window.data(), device).release(0, p1, window.data());
// QCOMPARE(eventItem2->eventList.size(), 1);
// eventItem2->eventList.clear();
-
- delete window;
}
void tst_TouchMouse::buttonOnFlickable()
@@ -505,13 +481,11 @@ void tst_TouchMouse::buttonOnFlickable()
// - eventItem1 y: 100, height 100
// - eventItem2 y: 300, height 100
- QQuickView *window = createView();
-
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("buttononflickable.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>("flickable");
@@ -536,13 +510,13 @@ void tst_TouchMouse::buttonOnFlickable()
// mouse button
QCOMPARE(eventItem1->eventList.size(), 0);
QPoint p1 = QPoint(20, 130);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QTRY_COMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 5);
QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchEnd);
QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseButtonRelease);
@@ -551,12 +525,12 @@ void tst_TouchMouse::buttonOnFlickable()
// touch button
p1 = QPoint(10, 310);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem2->eventList.size(), 1);
QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem2->eventList.size(), 2);
QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchEnd);
QCOMPARE(eventItem1->eventList.size(), 0);
@@ -567,11 +541,11 @@ void tst_TouchMouse::buttonOnFlickable()
// click above button, no events please
p1 = QPoint(10, 90);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 0);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 0);
eventItem1->eventList.clear();
@@ -581,13 +555,13 @@ void tst_TouchMouse::buttonOnFlickable()
// check that flickable moves - mouse button
QCOMPARE(eventItem1->eventList.size(), 0);
p1 = QPoint(10, 110);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
- QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window.data());
QVERIFY(windowPriv->touchMouseId != -1);
auto pointerEvent = QQuickPointerDevice::touchDevices().at(0)->pointerEvent();
QCOMPARE(pointerEvent->point(0)->grabber(), eventItem1);
@@ -596,13 +570,13 @@ void tst_TouchMouse::buttonOnFlickable()
p1 += QPoint(0, -10);
QPoint p2 = p1 + QPoint(0, -10);
QPoint p3 = p2 + QPoint(0, -10);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).move(0, p1, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).move(0, p2, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).move(0, p3, window);
- QQuickTouchUtils::flush(window);
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).move(0, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).move(0, p3, window.data());
+ QQuickTouchUtils::flush(window.data());
// we cannot really know when the events get grabbed away
QVERIFY(eventItem1->eventList.size() >= 4);
@@ -614,9 +588,8 @@ void tst_TouchMouse::buttonOnFlickable()
QCOMPARE(pointerEvent->point(0)->grabber(), flickable);
QVERIFY(flickable->isMovingVertically());
- QTest::touchEvent(window, device).release(0, p3, window);
- QQuickTouchUtils::flush(window);
- delete window;
+ QTest::touchEvent(window.data(), device).release(0, p3, window.data());
+ QQuickTouchUtils::flush(window.data());
}
void tst_TouchMouse::buttonOnDelayedPressFlickable_data()
@@ -642,13 +615,11 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
filteredEventList.clear();
- QQuickView *window = createView();
-
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("buttononflickable.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>("flickable");
@@ -673,13 +644,13 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
// wait to avoid getting a double click event
QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
- QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window.data());
QCOMPARE(windowPriv->touchMouseId, -1); // no grabber
// touch press
QPoint p1 = QPoint(10, 110);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
if (scrollBeforeDelayIsOver) {
// no events, the flickable got scrolled, the button sees nothing
@@ -694,13 +665,13 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
p1 += QPoint(0, -10);
QPoint p2 = p1 + QPoint(0, -10);
QPoint p3 = p2 + QPoint(0, -10);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).move(0, p1, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).move(0, p2, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).move(0, p3, window);
- QQuickTouchUtils::flush(window);
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).move(0, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).move(0, p3, window.data());
+ QQuickTouchUtils::flush(window.data());
QTRY_VERIFY(flickable->isMovingVertically());
if (scrollBeforeDelayIsOver) {
@@ -721,8 +692,8 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
auto pointerEvent = QQuickPointerDevice::touchDevices().at(0)->pointerEvent();
QCOMPARE(pointerEvent->point(0)->grabber(), flickable);
- QTest::touchEvent(window, device).release(0, p3, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p3, window.data());
+ QQuickTouchUtils::flush(window.data());
// We should not have received any synthesised mouse events from Qt gui,
// just the delayed press.
@@ -730,8 +701,6 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
QCOMPARE(filteredEventList.count(), 0);
else
QCOMPARE(filteredEventList.count(), 1);
-
- delete window;
}
void tst_TouchMouse::buttonOnTouch()
@@ -744,12 +713,11 @@ void tst_TouchMouse::buttonOnTouch()
// - eventItem1 y: 100, height 100
// - eventItem2 y: 300, height 100
- QQuickView *window = createView();
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("buttonontouch.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
@@ -779,10 +747,10 @@ void tst_TouchMouse::buttonOnTouch()
// Normal touch click
QPoint p1 = QPoint(10, 110);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(eventItem1->eventList.size(), 5);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
@@ -792,7 +760,7 @@ void tst_TouchMouse::buttonOnTouch()
eventItem1->eventList.clear();
// Normal mouse click
- QTest::mouseClick(window, Qt::LeftButton, 0, p1);
+ QTest::mouseClick(window.data(), Qt::LeftButton, 0, p1);
QCOMPARE(eventItem1->eventList.size(), 3);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonRelease);
@@ -804,35 +772,35 @@ void tst_TouchMouse::buttonOnTouch()
QPoint p2 = QPoint(60, 10);
// Start the events after each other
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).stationary(0).press(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).stationary(0).press(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(button1->scale(), 1.0);
// This event seems to be discarded, let's ignore it for now until someone digs into pincharea
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
// QCOMPARE(button1->scale(), 1.5);
qDebug() << "Button scale: " << button1->scale();
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
// QCOMPARE(button1->scale(), 2.0);
qDebug() << "Button scale: " << button1->scale();
- QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data()).release(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
// QVERIFY(eventItem1->eventList.isEmpty());
// QCOMPARE(button1->scale(), 2.0);
qDebug() << "Button scale: " << button1->scale();
@@ -845,8 +813,8 @@ void tst_TouchMouse::buttonOnTouch()
button1->setScale(1.0);
p1 = QPoint(40, 110);
p2 = QPoint(60, 110);
- QTest::touchEvent(window, device).press(0, p1, window).press(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data()).press(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(button1->scale(), 1.0);
QCOMPARE(eventItem1->eventList.count(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
@@ -855,40 +823,37 @@ void tst_TouchMouse::buttonOnTouch()
// This event seems to be discarded, let's ignore it for now until someone digs into pincharea
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
//QCOMPARE(button1->scale(), 1.5);
qDebug() << button1->scale();
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p1, window.data()).move(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
qDebug() << button1->scale();
//QCOMPARE(button1->scale(), 2.0);
- QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data()).release(1, p2, window.data());
+ QQuickTouchUtils::flush(window.data());
// QCOMPARE(eventItem1->eventList.size(), 99);
qDebug() << button1->scale();
//QCOMPARE(button1->scale(), 2.0);
-
- delete window;
}
void tst_TouchMouse::pinchOnFlickable()
{
- QQuickView *window = createView();
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("pinchonflickable.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
@@ -901,23 +866,23 @@ void tst_TouchMouse::pinchOnFlickable()
// flickable - single touch point
QCOMPARE(flickable->contentX(), 0.0);
QPoint p = QPoint(100, 100);
- QTest::touchEvent(window, device).press(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).release(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).release(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
QGuiApplication::processEvents();
QTest::qWait(10);
@@ -929,48 +894,47 @@ void tst_TouchMouse::pinchOnFlickable()
QPoint p1 = QPoint(40, 20);
QPoint p2 = QPoint(60, 20);
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
- QQuickTouchUtils::flush(window);
- pinchSequence.press(0, p1, window).commit();
- QQuickTouchUtils::flush(window);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window.data(), device);
+ QQuickTouchUtils::flush(window.data());
+ pinchSequence.press(0, p1, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object. Otherwise if we let it
// be destroyed and then start a new sequence, point 0 will default to being
// stationary at 0, 0, and PinchArea will filter out that touchpoint because
// it is outside its bounds.
- pinchSequence.stationary(0).press(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.stationary(0).press(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(rect->scale(), 1.0);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
QVERIFY(!flickable->isDragging());
- QQuickTouchUtils::flush(window);
- pinchSequence.release(0, p1, window).release(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ QQuickTouchUtils::flush(window.data());
+ pinchSequence.release(0, p1, window.data()).release(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QVERIFY(rect->scale() > 1.0);
}
void tst_TouchMouse::flickableOnPinch()
{
- QQuickView *window = createView();
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("flickableonpinch.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
@@ -983,23 +947,23 @@ void tst_TouchMouse::flickableOnPinch()
// flickable - single touch point
QCOMPARE(flickable->contentX(), 0.0);
QPoint p = QPoint(100, 100);
- QTest::touchEvent(window, device).press(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
QTest::qWait(1000);
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).release(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).release(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
QTest::qWait(1000);
@@ -1011,45 +975,47 @@ void tst_TouchMouse::flickableOnPinch()
// pinch
QPoint p1 = QPoint(40, 20);
QPoint p2 = QPoint(60, 20);
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
- pinchSequence.press(0, p1, window).commit();
- QQuickTouchUtils::flush(window);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window.data(), device);
+ pinchSequence.press(0, p1, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object. Otherwise if we let it
// be destroyed and then start a new sequence, point 0 will default to being
// stationary at 0, 0, and PinchArea will filter out that touchpoint because
// it is outside its bounds.
- pinchSequence.stationary(0).press(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.stationary(0).press(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(rect->scale(), 1.0);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
- pinchSequence.release(0, p1, window).release(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
+ pinchSequence.release(0, p1, window.data()).release(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QVERIFY(rect->scale() > 1.0);
}
void tst_TouchMouse::mouseOnFlickableOnPinch()
{
- QQuickView *window = createView();
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("mouseonflickableonpinch.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
+
QRect windowRect = QRect(window->position(), window->size());
QCursor::setPos(windowRect.center());
@@ -1063,20 +1029,20 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
// flickable - single touch point
QCOMPARE(flickable->contentX(), 0.0);
QPoint p = QPoint(100, 100);
- QTest::touchEvent(window, device).press(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
p -= QPoint(10, 0);
- QTest::touchEvent(window, device).move(0, p, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).release(0, p, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).move(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).release(0, p, window.data());
+ QQuickTouchUtils::flush(window.data());
//QVERIFY(flickable->isMovingHorizontally());
@@ -1087,81 +1053,81 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
// pinch
QPoint p1 = QPoint(40, 20);
QPoint p2 = QPoint(60, 20);
- QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
- pinchSequence.press(0, p1, window).commit();
- QQuickTouchUtils::flush(window);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window.data(), device);
+ pinchSequence.press(0, p1, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
// In order for the stationary point to remember its previous position,
// we have to reuse the same pinchSequence object. Otherwise if we let it
// be destroyed and then start a new sequence, point 0 will default to being
// stationary at 0, 0, and PinchArea will filter out that touchpoint because
// it is outside its bounds.
- pinchSequence.stationary(0).press(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.stationary(0).press(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10,10);
p2 += QPoint(10,10);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(rect->scale(), 1.0);
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(10, 0);
p2 += QPoint(10, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
- pinchSequence.release(0, p1, window).release(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
+ pinchSequence.release(0, p1, window.data()).release(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QVERIFY(rect->scale() > 1.0);
// PinchArea should steal the event after flicking started
rect->setScale(1.0);
flickable->setContentX(0.0);
p = QPoint(100, 100);
- pinchSequence.press(0, p, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.press(0, p, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(rect->position(), QPointF(200.0, 200.0));
p -= QPoint(10, 0);
- pinchSequence.move(0, p, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p -= QPoint(10, 0);
- pinchSequence.move(0, p, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QGuiApplication::processEvents();
p -= QPoint(10, 0);
- pinchSequence.move(0, p, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(window->mouseGrabberItem(), flickable);
// Add a second finger, this should lead to stealing
p1 = QPoint(40, 100);
p2 = QPoint(60, 100);
- pinchSequence.stationary(0).press(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.stationary(0).press(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(rect->scale(), 1.0);
p1 -= QPoint(5, 0);
p2 += QPoint(5, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(5, 0);
p2 += QPoint(5, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
p1 -= QPoint(5, 0);
p2 += QPoint(5, 0);
- pinchSequence.move(0, p1, window).move(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
- pinchSequence.release(0, p1, window).release(1, p2, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.move(0, p1, window.data()).move(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
+ pinchSequence.release(0, p1, window.data()).release(1, p2, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
QVERIFY(rect->scale() > 1.0);
- pinchSequence.release(0, p, window).commit();
- QQuickTouchUtils::flush(window);
+ pinchSequence.release(0, p, window.data()).commit();
+ QQuickTouchUtils::flush(window.data());
}
/*
@@ -1176,13 +1142,11 @@ void tst_TouchMouse::mouseOnFlickableOnPinch()
*/
void tst_TouchMouse::tapOnDismissiveTopMouseAreaClicksBottomOne()
{
- QQuickView *window = createView();
-
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("twoMouseAreas.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
QQuickMouseArea *bottomMouseArea =
@@ -1194,23 +1158,21 @@ void tst_TouchMouse::tapOnDismissiveTopMouseAreaClicksBottomOne()
// tap the front mouse area (see qml file)
QPoint p1(20, 20);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(bottomClickedSpy.count(), 1);
QCOMPARE(bottomDoubleClickedSpy.count(), 0);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
- QTest::touchEvent(window, device).release(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(bottomClickedSpy.count(), 1);
QCOMPARE(bottomDoubleClickedSpy.count(), 1);
-
- delete window;
}
/*
@@ -1220,13 +1182,11 @@ void tst_TouchMouse::tapOnDismissiveTopMouseAreaClicksBottomOne()
*/
void tst_TouchMouse::touchGrabCausesMouseUngrab()
{
- QQuickView *window = createView();
-
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("twosiblingitems.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QVERIFY(window->rootObject() != 0);
EventItem *leftItem = window->rootObject()->findChild<EventItem*>("leftItem");
@@ -1242,8 +1202,8 @@ void tst_TouchMouse::touchGrabCausesMouseUngrab()
leftItem->setAcceptedMouseButtons(Qt::LeftButton);
QPoint p1;
p1 = QPoint(leftItem->width() / 2, leftItem->height() / 2);
- QTest::touchEvent(window, device).press(0, p1, window);
- QQuickTouchUtils::flush(window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
QCOMPARE(leftItem->eventList.size(), 2);
QCOMPARE(leftItem->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(leftItem->eventList.at(1).type, QEvent::MouseButtonPress);
@@ -1262,16 +1222,17 @@ void tst_TouchMouse::touchGrabCausesMouseUngrab()
QCOMPARE(leftItem->eventList.size(), 1);
QCOMPARE(leftItem->eventList.at(0).type, QEvent::UngrabMouse);
QCOMPARE(window->mouseGrabberItem(), (QQuickItem*)0);
-
- delete window;
}
void tst_TouchMouse::touchPointDeliveryOrder()
{
// Touch points should be first delivered to the item under the primary finger
QScopedPointer<QQuickView> window(createView());
-
window->setSource(testFileUrl("touchpointdeliveryorder.qml"));
+ window->show();
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+
/*
The items are positioned from left to right:
| background |
@@ -1285,8 +1246,6 @@ void tst_TouchMouse::touchPointDeliveryOrder()
QPoint pLeftMiddle = QPoint(200, 100);
QPoint pRightMiddle = QPoint(350, 100);
- window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window.data()));
QVector<QQuickItem*> events;
EventItem *background = window->rootObject()->findChild<EventItem*>("background");
@@ -1371,16 +1330,12 @@ void tst_TouchMouse::hoverEnabled()
// device->setType(QTouchDevice::TouchScreen);
// QWindowSystemInterface::registerTouchDevice(device);
- // Ensure the cursor is away from the window
- QCursor::setPos(0, 0);
-
- QQuickView *window = createView();
+ QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("hoverMouseAreas.qml"));
- window->setPosition(10, 10);
-
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QQuickViewTestUtil::moveMouseAway(window.data());
window->show();
- window->requestActivate();
- QVERIFY(QTest::qWaitForWindowExposed(window));
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
QQuickItem *root = window->rootObject();
QVERIFY(root != 0);
@@ -1403,14 +1358,14 @@ void tst_TouchMouse::hoverEnabled()
QPoint p2(150, 250);
// ------------------------- Mouse move to mouseArea1
- QTest::mouseMove(window, p1);
+ QTest::mouseMove(window.data(), p1);
QVERIFY(enterSpy1.count() == 1);
QVERIFY(mouseArea1->hovered());
QVERIFY(!mouseArea2->hovered());
// ------------------------- Touch click on mouseArea1
- QTest::touchEvent(window, device).press(0, p1, window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
QCOMPARE(enterSpy1.count(), 1);
QCOMPARE(enterSpy2.count(), 0);
@@ -1418,7 +1373,7 @@ void tst_TouchMouse::hoverEnabled()
QVERIFY(mouseArea1->hovered());
QVERIFY(!mouseArea2->hovered());
- QTest::touchEvent(window, device).release(0, p1, window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
QVERIFY(clickSpy1.count() == 1);
QVERIFY(mouseArea1->hovered());
QVERIFY(!mouseArea2->hovered());
@@ -1427,7 +1382,7 @@ void tst_TouchMouse::hoverEnabled()
if (QGuiApplication::platformName().compare(QLatin1String("xcb"), Qt::CaseInsensitive) == 0)
QSKIP("hover can be momentarily inconsistent on X11, depending on timing of flushFrameSynchronousEvents with touch and mouse movements (QTBUG-55350)");
- QTest::touchEvent(window, device).press(0, p2, window);
+ QTest::touchEvent(window.data(), device).press(0, p2, window.data());
QVERIFY(mouseArea1->hovered());
QVERIFY(mouseArea2->hovered());
@@ -1435,7 +1390,7 @@ void tst_TouchMouse::hoverEnabled()
QCOMPARE(enterSpy1.count(), 1);
QCOMPARE(enterSpy2.count(), 1);
- QTest::touchEvent(window, device).release(0, p2, window);
+ QTest::touchEvent(window.data(), device).release(0, p2, window.data());
QVERIFY(clickSpy2.count() == 1);
QVERIFY(mouseArea1->hovered());
@@ -1444,7 +1399,7 @@ void tst_TouchMouse::hoverEnabled()
QCOMPARE(exitSpy2.count(), 1);
// ------------------------- Another touch click on mouseArea1
- QTest::touchEvent(window, device).press(0, p1, window);
+ QTest::touchEvent(window.data(), device).press(0, p1, window.data());
QCOMPARE(enterSpy1.count(), 1);
QCOMPARE(enterSpy2.count(), 1);
@@ -1452,7 +1407,7 @@ void tst_TouchMouse::hoverEnabled()
QVERIFY(mouseArea1->hovered());
QVERIFY(!mouseArea2->hovered());
- QTest::touchEvent(window, device).release(0, p1, window);
+ QTest::touchEvent(window.data(), device).release(0, p1, window.data());
QCOMPARE(clickSpy1.count(), 2);
QVERIFY(mouseArea1->hovered());
QVERIFY(!mouseArea1->pressed());
diff --git a/tests/benchmarks/qml/compilation/tst_compilation.cpp b/tests/benchmarks/qml/compilation/tst_compilation.cpp
index 61339c6f60..b28d69332c 100644
--- a/tests/benchmarks/qml/compilation/tst_compilation.cpp
+++ b/tests/benchmarks/qml/compilation/tst_compilation.cpp
@@ -51,6 +51,9 @@ private slots:
void jsparser_data();
void jsparser();
+ void bigimport_data();
+ void bigimport();
+
private:
QQmlEngine engine;
};
@@ -115,6 +118,74 @@ void tst_compilation::jsparser()
}
}
+void tst_compilation::bigimport_data()
+{
+ QTest::addColumn<int>("filesToCreate");
+ QTest::addColumn<bool>("writeQmldir");
+
+ QTest::newRow("10, qmldir")
+ << 10 << true;
+ QTest::newRow("100, qmldir")
+ << 100 << true;
+ QTest::newRow("1000, qmldir")
+ << 1000 << true;
+
+ QTest::newRow("10, noqmldir")
+ << 10 << false;
+ QTest::newRow("100, noqmldir")
+ << 100 << false;
+ QTest::newRow("1000, noqmldir")
+ << 1000 << false;
+}
+
+void tst_compilation::bigimport()
+{
+ QFETCH(int, filesToCreate);
+ QFETCH(bool, writeQmldir);
+ QTemporaryDir d;
+ //d.setAutoRemove(false); // for debugging
+
+ QString p;
+ {
+ for (int i = 0; i < filesToCreate; ++i) {
+ QFile f(d.path() + QDir::separator() + QString::fromLatin1("Type%1.qml").arg(i));
+ QVERIFY(f.open(QIODevice::WriteOnly));
+ f.write("import QtQuick 2.0\n");
+ f.write("import \".\"\n");
+ f.write("Item {}\n");
+ }
+
+ QFile qmldir(d.path() + QDir::separator() + "qmldir");
+ if (writeQmldir)
+ QVERIFY(qmldir.open(QIODevice::WriteOnly));
+ QFile main(d.path() + QDir::separator() + "main.qml");
+ QVERIFY(main.open(QIODevice::WriteOnly));
+ p = QFileInfo(main).absoluteFilePath();
+ //qDebug() << p; // for debugging
+
+ main.write("import QtQuick 2.0\n");
+ main.write("import \".\"\n");
+ main.write("\n");
+ main.write("Item {\n");
+
+ for (int i = 0; i < filesToCreate; ++i) {
+ main.write(qPrintable(QString::fromLatin1("Type%1 {}\n").arg(i)));
+ if (writeQmldir)
+ qmldir.write(qPrintable(QString::fromLatin1("Type%1 1.0 Type%1.qml\n").arg(i)));
+ }
+
+ main.write("}");
+ }
+
+ QBENCHMARK {
+ QQmlEngine e;
+ QQmlComponent c(&e, p);
+ QCOMPARE(c.status(), QQmlComponent::Ready);
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(o->children().count() == filesToCreate);
+ }
+}
+
QTEST_MAIN(tst_compilation)
#include "tst_compilation.moc"
diff --git a/tests/manual/text/SignalIndicator.qml b/tests/manual/text/SignalIndicator.qml
new file mode 100644
index 0000000000..3eaadde6d7
--- /dev/null
+++ b/tests/manual/text/SignalIndicator.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+
+Rectangle {
+ implicitWidth: text.implicitWidth * 1.2
+ implicitHeight: text.implicitHeight * 1.1
+ color: "lightgrey"
+ property color blipColor: "green"
+ property int blipDuration: 30 // ms
+ property alias label: text.text
+
+ function blip() {
+ blipAnim.start()
+ }
+
+ SequentialAnimation on color {
+ id: blipAnim
+ PropertyAction { value: blipColor }
+ PauseAnimation { duration: blipDuration }
+ PropertyAction { value: "lightgrey" }
+ }
+
+ Text {
+ id: text
+ anchors.centerIn: parent
+ }
+}
diff --git a/tests/manual/text/main.cpp b/tests/manual/text/main.cpp
new file mode 100644
index 0000000000..a4e1060cf5
--- /dev/null
+++ b/tests/manual/text/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+
+ return app.exec();
+}
diff --git a/tests/manual/text/main.qml b/tests/manual/text/main.qml
new file mode 100644
index 0000000000..d7e214ee38
--- /dev/null
+++ b/tests/manual/text/main.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Window 2.2
+import "qrc:/quick/shared/" as Examples
+
+Window {
+ width: 800
+ height: 600
+ visible: true
+ Examples.LauncherList {
+ id: ll
+ anchors.fill: parent
+ Component.onCompleted: {
+ addExample("TextInput", "TextInput properties and signals", Qt.resolvedUrl("textInputPropertiesAndSignals.qml"))
+ }
+ }
+}
diff --git a/tests/manual/text/qml.qrc b/tests/manual/text/qml.qrc
new file mode 100644
index 0000000000..555e37bd69
--- /dev/null
+++ b/tests/manual/text/qml.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>textInputPropertiesAndSignals.qml</file>
+ <file>SignalIndicator.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/text/text.pro b/tests/manual/text/text.pro
new file mode 100644
index 0000000000..3705d41df0
--- /dev/null
+++ b/tests/manual/text/text.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+
+QT += qml quick
+
+SOURCES += main.cpp
+
+RESOURCES += qml.qrc ../../../examples/quick/shared/quick_shared.qrc
diff --git a/tests/manual/text/textInputPropertiesAndSignals.qml b/tests/manual/text/textInputPropertiesAndSignals.qml
new file mode 100644
index 0000000000..a3fd602c16
--- /dev/null
+++ b/tests/manual/text/textInputPropertiesAndSignals.qml
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Layouts 1.1
+import "qrc:/quick/shared/" as Shared
+
+Item {
+ width: 600; height: 600
+ GridLayout {
+ columns: 3; rowSpacing: 6; columnSpacing: 6
+ anchors { left: parent.left; right: parent.right; top: parent.top; margins: 12 }
+
+ // ----------------------------------------------------
+ Text {
+ text: "try typing and input methods in the TextInput below:"
+ Layout.columnSpan: 3
+ }
+
+ // ----------------------------------------------------
+ Text {
+ text: "TextInput"
+ }
+
+ Rectangle {
+ Layout.fillWidth: true
+ implicitHeight: textInput.implicitHeight + 8
+ radius: 4; antialiasing: true
+ border.color: "black"; color: "transparent"
+
+ TextInput {
+ id: textInput
+ anchors.fill: parent; anchors.margins: 4
+
+ onTextEdited: textEditedInd.blip()
+ onTextChanged: textChangedInd.blip()
+ onPreeditTextChanged: preeditInd.blip()
+ onDisplayTextChanged: displayTextInd.blip()
+ }
+
+ }
+
+ SignalIndicator {
+ id: textEditedInd
+ label: "textEdited"
+ }
+
+ // ----------------------------------------------------
+ Text { text: "text" }
+
+ Text { text: textInput.text; Layout.fillWidth: true }
+
+ SignalIndicator {
+ id: textChangedInd
+ label: "textChanged"
+ }
+
+ // ----------------------------------------------------
+ Text { text: "preeditText" }
+
+ Text { text: textInput.preeditText; Layout.fillWidth: true }
+
+ SignalIndicator {
+ id: preeditInd
+ label: "preeditTextChanged"
+ }
+
+ // ----------------------------------------------------
+ Text { text: "displayText" }
+
+ Text { text: textInput.displayText; Layout.fillWidth: true }
+
+ SignalIndicator {
+ id: displayTextInd
+ label: "displayTextChanged"
+ }
+
+ // ----------------------------------------------------
+ Shared.TextField {
+ id: copyFrom
+ Layout.column: 1
+ Layout.row: 5
+ Layout.fillWidth: true
+ text: "copy this"
+ }
+
+ Shared.Button {
+ Layout.column: 2
+ Layout.row: 5
+ text: "setText"
+ onClicked: {
+ Qt.inputMethod.reset()
+ textInput.text = copyFrom.text
+ }
+ }
+ }
+}
diff --git a/tests/manual/touch/mpta-crosshairs.qml b/tests/manual/touch/mpta-crosshairs.qml
index 901b3e8bac..d1dbd0f188 100644
--- a/tests/manual/touch/mpta-crosshairs.qml
+++ b/tests/manual/touch/mpta-crosshairs.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the manual tests of the Qt Toolkit.
@@ -38,11 +38,13 @@
**
****************************************************************************/
-import QtQuick 2.4
+import QtQuick 2.9
import QtQuick.Window 2.2
Rectangle {
id: root
+ width: 480
+ height: 480
color: "black"
MultiPointTouchArea {
@@ -51,11 +53,11 @@ Rectangle {
touchPoints: [
TouchPoint { property color color: "red" },
TouchPoint { property color color: "orange" },
- TouchPoint { property color color: "yellow" },
+ TouchPoint { property color color: "lightsteelblue" },
TouchPoint { property color color: "green" },
TouchPoint { property color color: "blue" },
TouchPoint { property color color: "violet" },
- TouchPoint { property color color: "cyan" },
+ TouchPoint { property color color: "steelblue" },
TouchPoint { property color color: "magenta" },
TouchPoint { property color color: "goldenrod" },
TouchPoint { property color color: "darkgray" }
@@ -65,51 +67,81 @@ Rectangle {
model: 10
Item {
- anchors.fill: parent
+ id: crosshairs
property TouchPoint touchPoint
+ x: touchPoint.x - width / 2
+ y: touchPoint.y - height / 2
+ width: 300; height: 300
visible: touchPoint.pressed
+ rotation: touchPoint.rotation
Rectangle {
color: touchPoint.color
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: 2
- x: touchPoint.x - 1
+ anchors.centerIn: parent
+ width: 2; height: parent.height
+ antialiasing: true
}
Rectangle {
color: touchPoint.color
- anchors.left: parent.left
- anchors.right: parent.right
- height: 2
- y: touchPoint.y - 1
+ anchors.centerIn: parent
+ width: parent.width; height: 2
+ antialiasing: true
}
Rectangle {
color: touchPoint.color
- width: Math.max(2, 50 * touchPoint.pressure)
- height: width
+ implicitWidth: label.implicitWidth + 8
+ implicitHeight: label.implicitHeight + 16
radius: width / 2
- x: touchPoint.x - width / 2
- y: touchPoint.y - width / 2
+ anchors.centerIn: parent
+ antialiasing: true
Rectangle {
- y: -40
- anchors.horizontalCenter: parent.horizontalCenter
- color: "#c0c0c0"
- implicitWidth: label.implicitWidth
- implicitHeight: label.implicitHeight
- Text {
- id: label
- text: 'id: ' + touchPoint.pointId.toString(16) + '\npos: (' + touchPoint.x.toFixed(2) + ', ' + touchPoint.y.toFixed(2) + ')'
- }
+ color: "black"
+ opacity: 0.35
+ width: (parent.width - 8) * touchPoint.pressure
+ height: width
+ radius: width / 2
+ anchors.centerIn: parent
+ antialiasing: true
+ }
+ Rectangle {
+ color: "transparent"
+ border.color: "white"
+ border.width: 2
+ opacity: 0.75
+ visible: width > 0
+ width: touchPoint.ellipseDiameters.width
+ height: touchPoint.ellipseDiameters.height
+ radius: Math.min(width, height) / 2
+ anchors.centerIn: parent
+ antialiasing: true
+ }
+ Text {
+ id: label
+ anchors.centerIn: parent
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ property string uid: touchPoint.uniqueId === undefined || touchPoint.uniqueId.numericId === -1 ?
+ "" : "\nUID " + touchPoint.uniqueId.numericId
+ text: "x " + touchPoint.x.toFixed(1) +
+ "\ny " + touchPoint.y.toFixed(1) + uid +
+ "\nID " + touchPoint.pointId.toString(16) +
+ "\n∡" + touchPoint.rotation.toFixed(1) + "°"
}
}
Rectangle {
id: velocityVector
visible: width > 0
width: touchPoint.velocity.length()
- height: 1
- x: touchPoint.x
- y: touchPoint.y
- rotation: width > 0 ? Math.acos(touchPoint.velocity.x / width) : 0
+ height: 4
+ Behavior on width { SmoothedAnimation { duration: 200 } }
+ radius: height / 2
+ antialiasing: true
+ color: "gray"
+ x: crosshairs.width / 2
+ y: crosshairs.height / 2
+ rotation: width > 0 ? Math.atan2(touchPoint.velocity.y, touchPoint.velocity.x) * 180 / Math.PI - crosshairs.rotation : 0
+ Behavior on rotation { SmoothedAnimation { duration: 20 } }
transformOrigin: Item.BottomLeft
}
diff --git a/tests/manual/v4/tests.pro b/tests/manual/v4/tests.pro
index a86a6bf6af..ce4a34f7a0 100644
--- a/tests/manual/v4/tests.pro
+++ b/tests/manual/v4/tests.pro
@@ -1,7 +1,7 @@
TEMPLATE = aux
TESTSCRIPT=$$PWD/test262.py
-V4CMD = qmljs
+isEmpty(V4CMD): V4CMD = qmljs
checktarget.target = check
checktarget.commands = python $$TESTSCRIPT --command=$$V4CMD --parallel --with-test-expectations --update-expectations
diff --git a/tests/testapplications/textlayout/styledtext-layout.qml b/tests/testapplications/textlayout/styledtext-layout.qml
index 4ad0c7e279..80f62a6b8f 100644
--- a/tests/testapplications/textlayout/styledtext-layout.qml
+++ b/tests/testapplications/textlayout/styledtext-layout.qml
@@ -88,7 +88,7 @@ Rectangle {
drag.target: rect
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: mouse.button == Qt.RightButton ? myText.font.pixelSize -= 1 : myText.font.pixelSize += 1
- onPositionChanged: myText.doLayout()
+ onPositionChanged: myText.forceLayout()
}
}
}
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
index 5e8b872821..e8a506264c 100644
--- a/tools/qml/main.cpp
+++ b/tools/qml/main.cpp
@@ -46,7 +46,6 @@
#include <QDir>
#include <QFile>
#include <QFileInfo>
-#include <QRegularExpression>
#include <QStringList>
#include <QScopedPointer>
#include <QDebug>
@@ -568,29 +567,14 @@ int main(int argc, char *argv[])
loadDummyDataFiles(e, dummyDir);
for (const QString &path : qAsConst(files)) {
- //QUrl::fromUserInput doesn't treat no scheme as relative file paths
-#if QT_CONFIG(regularexpression)
- QRegularExpression urlRe("[[:word:]]+://.*");
- if (urlRe.match(path).hasMatch()) { //Treat as a URL
- QUrl url = QUrl::fromUserInput(path);
- if (verboseMode)
- printf("qml: loading %s\n",
- qPrintable(url.isLocalFile()
- ? QDir::toNativeSeparators(url.toLocalFile())
- : url.toString()));
+ QUrl url = QUrl::fromUserInput(path, QDir::currentPath());
+ if (verboseMode)
+ printf("qml: loading %s\n", qPrintable(url.toString()));
+ QByteArray strippedFile;
+ if (getFileSansBangLine(path, strippedFile))
+ e.loadData(strippedFile, e.baseUrl().resolved(url)); //QQmlComponent won't resolve it for us, it doesn't know it's a valid file if we loadData
+ else //Errors or no bang line
e.load(url);
- } else
-#endif
- { //Local file path
- if (verboseMode)
- printf("qml: loading %s\n", qPrintable(QDir::toNativeSeparators(path)));
-
- QByteArray strippedFile;
- if (getFileSansBangLine(path, strippedFile))
- e.loadData(strippedFile, e.baseUrl().resolved(QUrl::fromLocalFile(path))); //QQmlComponent won't resolve it for us, it doesn't know it's a valid file if we loadData
- else //Errors or no bang line
- e.load(path);
- }
}
if (lw->earlyExit)
diff --git a/tools/qmllint/main.cpp b/tools/qmllint/main.cpp
index 99a53110a8..791fb71685 100644
--- a/tools/qmllint/main.cpp
+++ b/tools/qmllint/main.cpp
@@ -29,7 +29,9 @@
#include <QDebug>
#include <QFile>
#include <QFileInfo>
+#if QT_CONFIG(commandlineparser)
#include <QCommandLineParser>
+#endif
#include <QCoreApplication>
#include <private/qv4value_p.h>
@@ -73,6 +75,7 @@ int main(int argv, char *argc[])
QCoreApplication app(argv, argc);
QCoreApplication::setApplicationName("qmllint");
QCoreApplication::setApplicationVersion("1.0");
+#if QT_CONFIG(commandlineparser)
QCommandLineParser parser;
parser.setApplicationDescription(QLatin1String("QML syntax verifier"));
parser.addHelpOption();
@@ -89,8 +92,16 @@ int main(int argv, char *argc[])
}
bool silent = parser.isSet(silentOption);
+#else
+ bool silent = false;
+#endif
bool success = true;
+#if QT_CONFIG(commandlineparser)
for (const QString &filename : positionalArguments)
+#else
+ const auto arguments = app.arguments();
+ for (const QString &filename : arguments)
+#endif
success &= lint_file(filename, silent);
return success ? 0 : -1;
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index 92a8465d9f..774be45aec 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -741,7 +741,7 @@ void sigSegvHandler(int) {
void printUsage(const QString &appName)
{
std::cerr << qPrintable(QString(
- "Usage: %1 [-v] [-noinstantiate] [-defaultplatform] [-[non]relocatable] [-dependencies <dependencies.json>] [-merge <file-to-merge.qmltypes>] [-noforceqtquick] module.uri version [module/import/path]\n"
+ "Usage: %1 [-v] [-noinstantiate] [-defaultplatform] [-[non]relocatable] [-dependencies <dependencies.json>] [-merge <file-to-merge.qmltypes>] [-output <output-file.qmltypes>] [-noforceqtquick] module.uri version [module/import/path]\n"
" %1 [-v] [-noinstantiate] -path path/to/qmldir/directory [version]\n"
" %1 [-v] -builtins\n"
"Example: %1 Qt.labs.folderlistmodel 2.0 /home/user/dev/qt-install/imports").arg(
@@ -998,6 +998,7 @@ int main(int argc, char *argv[])
return EXIT_INVALIDARGUMENTS;
}
+ QString outputFilename;
QString pluginImportUri;
QString pluginImportVersion;
bool relocatable = true;
@@ -1051,6 +1052,13 @@ int main(int argc, char *argv[])
} else if (arg == QLatin1String("--noforceqtquick")
|| arg == QLatin1String("-noforceqtquick")){
forceQtQuickDependency = false;
+ } else if (arg == QLatin1String("--output")
+ || arg == QLatin1String("-output")) {
+ if (++iArg == args.size()) {
+ std::cerr << "missing output file" << std::endl;
+ return EXIT_INVALIDARGUMENTS;
+ }
+ outputFilename = args.at(iArg);
} else if (arg == QLatin1String("--defaultplatform")
|| arg == QLatin1String("-defaultplatform")) {
continue;
@@ -1306,7 +1314,15 @@ int main(int argc, char *argv[])
qml.writeEndObject();
qml.writeEndDocument();
- std::cout << bytes.constData() << std::flush;
+ if (!outputFilename.isEmpty()) {
+ QFile file(outputFilename);
+ if (file.open(QIODevice::WriteOnly)) {
+ QTextStream stream(&file);
+ stream << bytes.constData();
+ }
+ } else {
+ std::cout << bytes.constData() << std::flush;
+ }
// workaround to avoid crashes on exit
QTimer timer;
diff --git a/tools/qmltime/qmltime.cpp b/tools/qmltime/qmltime.cpp
index 4c282dd8f4..b337ccac5c 100644
--- a/tools/qmltime/qmltime.cpp
+++ b/tools/qmltime/qmltime.cpp
@@ -222,7 +222,7 @@ int main(int argc, char ** argv)
QByteArray its(argv[ii]);
bool ok = false;
iterations = its.toUInt(&ok);
- if (!ok)
+ if (!ok || iterations == 0)
usage(argv[0]);
} else {
usage(argv[0]);