aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/quick/demos/samegame/content/+blackberry/settings.js56
-rw-r--r--examples/quick/demos/samegame/content/BlockEmitter.qml2
-rw-r--r--examples/quick/demos/samegame/content/PaintEmitter.qml2
-rw-r--r--examples/quick/demos/samegame/content/SamegameText.qml2
-rwxr-xr-xexamples/quick/demos/samegame/content/samegame.js2
-rw-r--r--examples/quick/demos/samegame/content/settings.js (renamed from examples/quick/demos/samegame/settings.js)0
-rw-r--r--examples/quick/demos/samegame/samegame.qml2
-rw-r--r--examples/quick/demos/samegame/samegame.qrc3
-rw-r--r--examples/quick/dialogs/systemdialogs/FileDialogs.qml11
-rw-r--r--examples/quick/dialogs/systemdialogs/FontDialogs.qml153
-rw-r--r--examples/quick/dialogs/systemdialogs/MessageDialogs.qml307
-rw-r--r--examples/quick/dialogs/systemdialogs/systemdialogs.pro4
-rw-r--r--examples/quick/dialogs/systemdialogs/systemdialogs.qml14
-rw-r--r--examples/quick/dialogs/systemdialogs/systemdialogs.qrc2
-rw-r--r--examples/quick/models/abstractitemmodel/doc/images/qml-abstractitemmodel-example.pngbin0 -> 4478 bytes
-rw-r--r--examples/quick/models/abstractitemmodel/doc/src/abstractitemmodel-example.qdoc47
-rw-r--r--examples/quick/models/objectlistmodel/doc/images/qml-objectlistmodel-example.pngbin0 -> 1618 bytes
-rw-r--r--examples/quick/models/objectlistmodel/doc/src/objectlistmodel-example.qdoc47
-rw-r--r--examples/quick/models/stringlistmodel/doc/images/qml-stringlistmodel-example.pngbin0 -> 1612 bytes
-rw-r--r--examples/quick/models/stringlistmodel/doc/src/stringlistmodel-example.qdoc47
-rw-r--r--examples/quick/shared/CheckBox.qml1
-rw-r--r--examples/quick/shared/TabSet.qml4
-rw-r--r--examples/quick/shared/TextField.qml80
-rw-r--r--examples/quick/shared/qmldir1
-rw-r--r--examples/quick/shared/quick_shared.qrc1
-rw-r--r--examples/quick/shared/shared.h4
-rw-r--r--examples/quick/shared/shared.qrc1
-rw-r--r--src/3rdparty/double-conversion/utils.h2
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerARM.cpp2
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerARMv7.h6
-rw-r--r--src/3rdparty/masm/masm-defs.pri13
-rw-r--r--src/imports/dialogs-private/dialogs-private.pro17
-rw-r--r--src/imports/dialogs-private/dialogsprivateplugin.cpp66
-rw-r--r--src/imports/dialogs-private/qmldir3
-rw-r--r--src/imports/dialogs-private/qquickfontlistmodel.cpp276
-rw-r--r--src/imports/dialogs-private/qquickfontlistmodel_p.h125
-rw-r--r--src/imports/dialogs-private/qquickwritingsystemlistmodel.cpp169
-rw-r--r--src/imports/dialogs-private/qquickwritingsystemlistmodel_p.h100
-rw-r--r--src/imports/dialogs/DefaultColorDialog.qml27
-rw-r--r--src/imports/dialogs/DefaultFontDialog.qml457
-rw-r--r--src/imports/dialogs/DefaultMessageDialog.qml310
-rw-r--r--src/imports/dialogs/WidgetFontDialog.qml44
-rw-r--r--src/imports/dialogs/WidgetMessageDialog.qml44
-rw-r--r--src/imports/dialogs/dialogs.pro28
-rw-r--r--src/imports/dialogs/images/checkmark.pngbin0 -> 809 bytes
-rw-r--r--src/imports/dialogs/images/critical.pngbin0 -> 253 bytes
-rw-r--r--src/imports/dialogs/images/information.pngbin0 -> 254 bytes
-rw-r--r--src/imports/dialogs/images/question.pngbin0 -> 257 bytes
-rw-r--r--src/imports/dialogs/images/warning.pngbin0 -> 224 bytes
-rw-r--r--src/imports/dialogs/plugin.cpp31
-rw-r--r--src/imports/dialogs/plugins.qmltypes43
-rw-r--r--src/imports/dialogs/qml/Button.qml2
-rw-r--r--src/imports/dialogs/qml/CheckBox.qml96
-rw-r--r--src/imports/dialogs/qml/EdgeFade.qml63
-rw-r--r--src/imports/dialogs/qml/qmldir2
-rw-r--r--src/imports/dialogs/qquickabstractcolordialog.cpp9
-rw-r--r--src/imports/dialogs/qquickabstractcolordialog_p.h21
-rw-r--r--src/imports/dialogs/qquickabstractdialog.cpp53
-rw-r--r--src/imports/dialogs/qquickabstractdialog_p.h14
-rw-r--r--src/imports/dialogs/qquickabstractfontdialog.cpp150
-rw-r--r--src/imports/dialogs/qquickabstractfontdialog_p.h113
-rw-r--r--src/imports/dialogs/qquickabstractmessagedialog.cpp142
-rw-r--r--src/imports/dialogs/qquickabstractmessagedialog_p.h164
-rw-r--r--src/imports/dialogs/qquickfiledialog_p.h2
-rw-r--r--src/imports/dialogs/qquickfontdialog.cpp120
-rw-r--r--src/imports/dialogs/qquickfontdialog_p.h80
-rw-r--r--src/imports/dialogs/qquickmessageattached_p.h69
-rw-r--r--src/imports/dialogs/qquickmessagedialog.cpp181
-rw-r--r--src/imports/dialogs/qquickmessagedialog_p.h86
-rw-r--r--src/imports/dialogs/qquickplatformcolordialog.cpp19
-rw-r--r--src/imports/dialogs/qquickplatformfontdialog.cpp251
-rw-r--r--src/imports/dialogs/qquickplatformfontdialog_p.h78
-rw-r--r--src/imports/dialogs/qquickplatformmessagedialog.cpp206
-rw-r--r--src/imports/dialogs/qquickplatformmessagedialog_p.h78
-rw-r--r--src/imports/imports.pro1
-rw-r--r--src/imports/localstorage/plugin.cpp106
-rw-r--r--src/imports/widgets/qquickqcolordialog.cpp2
-rw-r--r--src/imports/widgets/qquickqfiledialog_p.h2
-rw-r--r--src/imports/widgets/qquickqfontdialog.cpp178
-rw-r--r--src/imports/widgets/qquickqfontdialog_p.h78
-rw-r--r--src/imports/widgets/qquickqmessagebox.cpp215
-rw-r--r--src/imports/widgets/qquickqmessagebox_p.h (renamed from src/quick/scenegraph/qsgpathsimplifier_p.h)36
-rw-r--r--src/imports/widgets/widgets.pro10
-rw-r--r--src/imports/widgets/widgetsplugin.cpp6
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel.cpp2
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel_p.h6
-rw-r--r--src/particles/qquickage_p.h8
-rw-r--r--src/particles/qquickangledirection_p.h12
-rw-r--r--src/particles/qquickcustomaffector.cpp9
-rw-r--r--src/particles/qquickcustomaffector_p.h12
-rw-r--r--src/particles/qquickdirection_p.h4
-rw-r--r--src/particles/qquickellipseextruder_p.h6
-rw-r--r--src/particles/qquickfriction_p.h8
-rw-r--r--src/particles/qquickgravity_p.h10
-rw-r--r--src/particles/qquickgroupgoal_p.h6
-rw-r--r--src/particles/qquickimageparticle.cpp4
-rw-r--r--src/particles/qquickimageparticle_p.h6
-rw-r--r--src/particles/qquickitemparticle_p.h12
-rw-r--r--src/particles/qquicklineextruder_p.h6
-rw-r--r--src/particles/qquickmaskextruder_p.h6
-rw-r--r--src/particles/qquickparticleaffector_p.h18
-rw-r--r--src/particles/qquickparticleemitter.cpp5
-rw-r--r--src/particles/qquickparticleemitter_p.h28
-rw-r--r--src/particles/qquickparticleextruder_p.h4
-rw-r--r--src/particles/qquickparticlegroup_p.h6
-rw-r--r--src/particles/qquickparticlepainter_p.h8
-rw-r--r--src/particles/qquickparticlesystem_p.h6
-rw-r--r--src/particles/qquickpointattractor_p.h14
-rw-r--r--src/particles/qquickpointdirection_p.h12
-rw-r--r--src/particles/qquickrectangleextruder_p.h6
-rw-r--r--src/particles/qquickspritegoal_p.h8
-rw-r--r--src/particles/qquicktargetdirection_p.h18
-rw-r--r--src/particles/qquicktrailemitter.cpp7
-rw-r--r--src/particles/qquicktrailemitter_p.h16
-rw-r--r--src/particles/qquickturbulence_p.h8
-rw-r--r--src/particles/qquickv4particledata.cpp44
-rw-r--r--src/particles/qquickwander_p.h12
-rw-r--r--src/qml/compiler/qv4codegen.cpp3
-rw-r--r--src/qml/compiler/qv4compileddata.cpp6
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h67
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp690
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h233
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp100
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h10
-rw-r--r--src/qml/compiler/qv4isel_p.cpp38
-rw-r--r--src/qml/compiler/qv4isel_p.h10
-rw-r--r--src/qml/compiler/qv4jsir.cpp4
-rw-r--r--src/qml/compiler/qv4jsir_p.h4
-rw-r--r--src/qml/compiler/qv4regalloc.cpp189
-rw-r--r--src/qml/compiler/qv4ssa.cpp402
-rw-r--r--src/qml/compiler/qv4ssa_p.h46
-rw-r--r--src/qml/debugger/debugger.pri8
-rw-r--r--src/qml/debugger/qqmlinspectorservice_p.h2
-rw-r--r--src/qml/debugger/qv4debugservice.cpp325
-rw-r--r--src/qml/debugger/qv4debugservice_p.h (renamed from src/qml/debugger/qv8debugservice_p.h)50
-rw-r--r--src/qml/debugger/qv8debugservice.cpp303
-rw-r--r--src/qml/debugger/qv8profilerservice_p.h2
-rw-r--r--src/qml/doc/src/cppintegration/contextproperties.qdoc14
-rw-r--r--src/qml/doc/src/javascript/date.qdoc106
-rw-r--r--src/qml/doc/src/javascript/number.qdoc2
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc25
-rw-r--r--src/qml/jsapi/qjsengine.cpp21
-rw-r--r--src/qml/jsapi/qjsvalue.cpp92
-rw-r--r--src/qml/jsapi/qjsvalue_p.h2
-rw-r--r--src/qml/jsapi/qjsvalueiterator.cpp6
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp15
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h14
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp320
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h52
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp16
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h12
-rw-r--r--src/qml/jsruntime/qv4context.cpp155
-rw-r--r--src/qml/jsruntime/qv4context_p.h11
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp219
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h117
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp23
-rw-r--r--src/qml/jsruntime/qv4engine.cpp99
-rw-r--r--src/qml/jsruntime/qv4engine_p.h46
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp45
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h52
-rw-r--r--src/qml/jsruntime/qv4exception.cpp3
-rw-r--r--src/qml/jsruntime/qv4exception_p.h4
-rw-r--r--src/qml/jsruntime/qv4function.cpp2
-rw-r--r--src/qml/jsruntime/qv4function_p.h6
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp154
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h78
-rw-r--r--src/qml/jsruntime/qv4global_p.h6
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp87
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h28
-rw-r--r--src/qml/jsruntime/qv4include.cpp38
-rw-r--r--src/qml/jsruntime/qv4include_p.h8
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp128
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h10
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp305
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h42
-rw-r--r--src/qml/jsruntime/qv4managed.cpp11
-rw-r--r--src/qml/jsruntime/qv4managed_p.h75
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp126
-rw-r--r--src/qml/jsruntime/qv4mathobject_p.h36
-rw-r--r--src/qml/jsruntime/qv4mm.cpp5
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp44
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h20
-rw-r--r--src/qml/jsruntime/qv4object.cpp106
-rw-r--r--src/qml/jsruntime/qv4object_p.h42
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp20
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h4
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp196
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h62
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp216
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h24
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp8
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp49
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h16
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp814
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h510
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h274
-rw-r--r--src/qml/jsruntime/qv4script.cpp38
-rw-r--r--src/qml/jsruntime/qv4script_p.h8
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp63
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h10
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp85
-rw-r--r--src/qml/jsruntime/qv4serialize_p.h4
-rw-r--r--src/qml/jsruntime/qv4sparsearray.cpp10
-rw-r--r--src/qml/jsruntime/qv4string.cpp20
-rw-r--r--src/qml/jsruntime/qv4string_p.h11
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp160
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h48
-rw-r--r--src/qml/jsruntime/qv4value.cpp168
-rw-r--r--src/qml/jsruntime/qv4value_def_p.h208
-rw-r--r--src/qml/jsruntime/qv4value_p.h116
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp28
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h8
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp131
-rw-r--r--src/qml/jsruntime/qv4vme_moth_p.h4
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h2
-rw-r--r--src/qml/qml/qml.pri5
-rw-r--r--src/qml/qml/qqml.h3
-rw-r--r--src/qml/qml/qqmlabstracturlinterceptor.cpp5
-rw-r--r--src/qml/qml/qqmlabstracturlinterceptor.h (renamed from src/qml/qml/qqmlabstracturlinterceptor_p.h)3
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp7
-rw-r--r--src/qml/qml/qqmlapplicationengine_p.h1
-rw-r--r--src/qml/qml/qqmlbinding.cpp9
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp12
-rw-r--r--src/qml/qml/qqmlcompiler.cpp2
-rw-r--r--src/qml/qml/qqmlcomponent.cpp67
-rw-r--r--src/qml/qml/qqmlcontext.cpp2
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp60
-rw-r--r--src/qml/qml/qqmlcontextwrapper_p.h6
-rw-r--r--src/qml/qml/qqmlengine.cpp62
-rw-r--r--src/qml/qml/qqmlexpression.cpp5
-rw-r--r--src/qml/qml/qqmlexpression_p.h2
-rw-r--r--src/qml/qml/qqmlfileselector.cpp138
-rw-r--r--src/qml/qml/qqmlfileselector.h71
-rw-r--r--src/qml/qml/qqmlfileselector_p.h74
-rw-r--r--src/qml/qml/qqmlimport.cpp4
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp78
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h4
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp20
-rw-r--r--src/qml/qml/qqmllistwrapper_p.h8
-rw-r--r--src/qml/qml/qqmllocale.cpp258
-rw-r--r--src/qml/qml/qqmllocale_p.h24
-rw-r--r--src/qml/qml/qqmlmetatype.cpp58
-rw-r--r--src/qml/qml/qqmlmetatype_p.h4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp7
-rw-r--r--src/qml/qml/qqmlproperty.cpp2
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp5
-rw-r--r--src/qml/qml/qqmltypeloader.cpp10
-rw-r--r--src/qml/qml/qqmltypeloader_p.h2
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp27
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h6
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp32
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h8
-rw-r--r--src/qml/qml/qqmlvme.cpp8
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp48
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h8
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp387
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp271
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h106
-rw-r--r--src/qml/qml/v8/qv4domerrors_p.h6
-rw-r--r--src/qml/qml/v8/qv8engine.cpp209
-rw-r--r--src/qml/qml/v8/qv8engine_p.h15
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp76
-rw-r--r--src/qml/types/qqmldelegatemodel_p.h2
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h22
-rw-r--r--src/qml/types/qqmllistmodel.cpp85
-rw-r--r--src/qml/types/qqmlobjectmodel_p.h2
-rw-r--r--src/qml/types/qquickworkerscript.cpp33
-rw-r--r--src/qml/types/qquickworkerscript_p.h4
-rw-r--r--src/qml/util/qqmladaptormodel.cpp34
-rw-r--r--src/qmltest/quicktestresult.cpp6
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp11
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp688
-rw-r--r--src/quick/items/qquickaccessibleattached_p.h6
-rw-r--r--src/quick/items/qquickanimatedsprite_p.h32
-rw-r--r--src/quick/items/qquickclipnode_p.h3
-rw-r--r--src/quick/items/qquickdrag.cpp25
-rw-r--r--src/quick/items/qquickdrag_p.h9
-rw-r--r--src/quick/items/qquickflickable_p_p.h2
-rw-r--r--src/quick/items/qquickgridview_p.h2
-rw-r--r--src/quick/items/qquickitem.cpp7
-rw-r--r--src/quick/items/qquickitem_p.h6
-rw-r--r--src/quick/items/qquickitemview_p.h20
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h2
-rw-r--r--src/quick/items/qquicklistview_p.h2
-rw-r--r--src/quick/items/qquickloader.cpp2
-rw-r--r--src/quick/items/qquickmousearea.cpp12
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h2
-rw-r--r--src/quick/items/qquickpathview.cpp8
-rw-r--r--src/quick/items/qquickpathview_p.h4
-rw-r--r--src/quick/items/qquickpincharea_p.h28
-rw-r--r--src/quick/items/qquickscreen_p.h2
-rw-r--r--src/quick/items/qquicksprite_p.h30
-rw-r--r--src/quick/items/qquickspriteengine_p.h20
-rw-r--r--src/quick/items/qquickspritesequence_p.h10
-rw-r--r--src/quick/items/qquicktext_p_p.h2
-rw-r--r--src/quick/items/qquicktextedit.cpp9
-rw-r--r--src/quick/items/qquicktextinput.cpp4
-rw-r--r--src/quick/items/qquicktextutil_p.h2
-rw-r--r--src/quick/items/qquickwindow.cpp15
-rw-r--r--src/quick/items/qquickwindow_p.h4
-rw-r--r--src/quick/quick.pro4
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp14
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h4
-rw-r--r--src/quick/scenegraph/qsgpathsimplifier.cpp1673
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h2
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop_p.h2
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop_p.h2
-rw-r--r--src/quick/util/qquickapplication.cpp8
-rw-r--r--src/quick/util/qquickapplication_p.h5
-rw-r--r--src/quick/util/qquickglobal.cpp33
-rw-r--r--src/quick/util/qquickpath_p.h2
-rw-r--r--src/quick/util/qquicktimeline.cpp4
-rw-r--r--tests/auto/auto.pro10
-rw-r--r--tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro2
-rw-r--r--tests/auto/qml/debugger/debugger.pro8
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp5
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp7
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp3
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp5
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp4
-rw-r--r--tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp3
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.cpp16
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp54
-rw-r--r--tests/auto/qml/qml.pro3
-rw-r--r--tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp4
-rw-r--r--tests/auto/qml/qqmlecmascript/data/date.qml20
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp11
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp73
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp2
-rw-r--r--tests/auto/qml/qqmlenginecleanup/data/TestType.qml43
-rw-r--r--tests/auto/qml/qqmlenginecleanup/data/types.qml56
-rw-r--r--tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro10
-rw-r--r--tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp98
-rw-r--r--tests/auto/qml/qqmlfileselector/data/+basic/basicTest.qml5
-rw-r--r--tests/auto/qml/qqmlfileselector/data/basicTest.qml5
-rw-r--r--tests/auto/qml/qqmlfileselector/qqmlfileselector.pro13
-rw-r--r--tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp81
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp18
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp69
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro13
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/protectedModule/qmldir1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro3
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp21
-rw-r--r--tests/auto/qml/qv4debugger/tst_qv4debugger.cpp6
-rw-r--r--tests/auto/quick/nokeywords/nokeywords.pro10
-rw-r--r--tests/auto/quick/nokeywords/tst_nokeywords.cpp120
-rw-r--r--tests/auto/quick/qquickapplication/tst_qquickapplication.cpp66
-rw-r--r--tests/auto/quick/qquickflickable/data/nestedmousearea.qml26
-rw-r--r--tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp3
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp70
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp173
-rw-r--r--tests/auto/quick/qquicktextinput/data/maxLength.qml2
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp3
-rw-r--r--tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp12
-rw-r--r--tests/auto/quick/quick.pro1
-rw-r--r--tests/manual/qmltypememory/main.qml1
-rw-r--r--tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp3
-rw-r--r--tools/qml/Info.plist49
-rw-r--r--tools/qml/conf.h99
-rw-r--r--tools/qml/conf/configuration.qml47
-rw-r--r--tools/qml/conf/qtquick.qml55
-rw-r--r--tools/qml/main.cpp466
-rw-r--r--tools/qml/qml.icnsbin0 -> 196156 bytes
-rw-r--r--tools/qml/qml.pro14
-rw-r--r--tools/qml/qml.qrc6
-rw-r--r--tools/qmlplugindump/main.cpp240
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.cpp6
-rw-r--r--tools/qmlprofiler/qpacketprotocol.cpp1
-rw-r--r--tools/tools.pro1
-rw-r--r--tools/v4/main.cpp25
373 files changed, 13914 insertions, 7561 deletions
diff --git a/examples/quick/demos/samegame/content/+blackberry/settings.js b/examples/quick/demos/samegame/content/+blackberry/settings.js
new file mode 100644
index 0000000000..a86d2a9a1a
--- /dev/null
+++ b/examples/quick/demos/samegame/content/+blackberry/settings.js
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc and its Subsidiary(-ies) 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$
+**
+****************************************************************************/
+
+.pragma library
+
+//This should be switched over once a proper QML settings API exists
+
+var menuDelay = 500
+
+var headerHeight = 70
+var footerHeight = 100
+
+var fontPixelSize = 55
+
+var blockSize = 64
+
+var toolButtonHeight = 64
+
+var menuButtonSpacing = 15
diff --git a/examples/quick/demos/samegame/content/BlockEmitter.qml b/examples/quick/demos/samegame/content/BlockEmitter.qml
index ba6261c8e6..49ee38d376 100644
--- a/examples/quick/demos/samegame/content/BlockEmitter.qml
+++ b/examples/quick/demos/samegame/content/BlockEmitter.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtQuick.Particles 2.0
-import "../settings.js" as Settings
+import "settings.js" as Settings
Emitter {
property Item block: parent
diff --git a/examples/quick/demos/samegame/content/PaintEmitter.qml b/examples/quick/demos/samegame/content/PaintEmitter.qml
index fe758af181..85d148de92 100644
--- a/examples/quick/demos/samegame/content/PaintEmitter.qml
+++ b/examples/quick/demos/samegame/content/PaintEmitter.qml
@@ -40,7 +40,7 @@
import QtQuick 2.0
import QtQuick.Particles 2.0
-import "../settings.js" as Settings
+import "settings.js" as Settings
Emitter {
property Item block: parent
diff --git a/examples/quick/demos/samegame/content/SamegameText.qml b/examples/quick/demos/samegame/content/SamegameText.qml
index 28c85f9486..e3bee989fb 100644
--- a/examples/quick/demos/samegame/content/SamegameText.qml
+++ b/examples/quick/demos/samegame/content/SamegameText.qml
@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.0
-import "../settings.js" as Settings
+import "settings.js" as Settings
Text {
font.pixelSize: Settings.fontPixelSize;
diff --git a/examples/quick/demos/samegame/content/samegame.js b/examples/quick/demos/samegame/content/samegame.js
index 6bf402ed0a..5bb24d70db 100755
--- a/examples/quick/demos/samegame/content/samegame.js
+++ b/examples/quick/demos/samegame/content/samegame.js
@@ -41,7 +41,7 @@
/* This script file handles the game logic */
.pragma library
.import QtQuick.LocalStorage 2.0 as Sql
-.import "../settings.js" as Settings
+.import "settings.js" as Settings
var maxColumn = 10;
var maxRow = 13;
diff --git a/examples/quick/demos/samegame/settings.js b/examples/quick/demos/samegame/content/settings.js
index e09dee9af3..e09dee9af3 100644
--- a/examples/quick/demos/samegame/settings.js
+++ b/examples/quick/demos/samegame/content/settings.js
diff --git a/examples/quick/demos/samegame/samegame.qml b/examples/quick/demos/samegame/samegame.qml
index 8712141509..23cdf94acc 100644
--- a/examples/quick/demos/samegame/samegame.qml
+++ b/examples/quick/demos/samegame/samegame.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
import QtQuick.Particles 2.0
import "content/samegame.js" as Logic
-import "settings.js" as Settings
+import "content/settings.js" as Settings
import "content"
Rectangle {
diff --git a/examples/quick/demos/samegame/samegame.qrc b/examples/quick/demos/samegame/samegame.qrc
index 951b9d116c..40b7cb6478 100644
--- a/examples/quick/demos/samegame/samegame.qrc
+++ b/examples/quick/demos/samegame/samegame.qrc
@@ -1,7 +1,8 @@
<RCC>
<qresource prefix="/demos/samegame">
<file>samegame.qml</file>
- <file>settings.js</file>
+ <file>content/settings.js</file>
+ <file>content/+blackberry/settings.js</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/dialogs/systemdialogs/FileDialogs.qml b/examples/quick/dialogs/systemdialogs/FileDialogs.qml
index 508466da0c..dca47ae1fd 100644
--- a/examples/quick/dialogs/systemdialogs/FileDialogs.qml
+++ b/examples/quick/dialogs/systemdialogs/FileDialogs.qml
@@ -40,6 +40,7 @@
import QtQuick 2.0
import QtQuick.Dialogs 1.0
+import QtQuick.Window 2.0
import "../../shared"
Rectangle {
@@ -174,6 +175,16 @@ Rectangle {
// TODO: QTBUG-29814 This isn't portable, but we don't expose QDir::tempPath to QML yet.
onClicked: fileDialog.folder = "/tmp" // file:///tmp would also be OK
}
+ Button {
+ text: "set geometry"
+ anchors.verticalCenter: parent.verticalCenter
+ onClicked: {
+ fileDialog.width = Math.min(512, Screen.width * 0.9)
+ fileDialog.height = Math.min(340, Screen.height * 0.9)
+ fileDialog.x = (Screen.width - fileDialog.width) / 2
+ fileDialog.y = (Screen.height - fileDialog.height) / 2
+ }
+ }
}
}
}
diff --git a/examples/quick/dialogs/systemdialogs/FontDialogs.qml b/examples/quick/dialogs/systemdialogs/FontDialogs.qml
new file mode 100644
index 0000000000..7d4328994b
--- /dev/null
+++ b/examples/quick/dialogs/systemdialogs/FontDialogs.qml
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc and its Subsidiary(-ies) 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 QtQuick.Dialogs 1.1
+import "../../shared"
+
+Rectangle {
+ width: 320
+ height: 360
+ color: palette.window
+ SystemPalette { id: palette }
+ clip: true
+
+ FontDialog {
+ id: fontDialog
+ visible: fontDialogVisible.checked
+ modality: fontDialogModal.checked ? Qt.WindowModal : Qt.NonModal
+ scalableFonts: fontDialogScalableFonts.checked
+ nonScalableFonts: fontDialogNonScalableFonts.checked
+ monospacedFonts: fontDialogMonospacedFonts.checked
+ proportionalFonts: fontDialogProportionalFonts.checked
+ title: "Choose a font"
+ font: Qt.font({ family: "Arial", pointSize: 24, weight: Font.Normal })
+ onAccepted: { console.log("Accepted: " + font) }
+ onRejected: { console.log("Rejected") }
+ }
+
+ Column {
+ id: optionsColumn
+ anchors.fill: parent
+ anchors.margins: 12
+ spacing: 8
+ Text {
+ font.bold: true
+ text: "Font dialog properties:"
+ }
+ CheckBox {
+ id: fontDialogModal
+ text: "Modal"
+ checked: true
+ Binding on checked { value: fontDialog.modality != Qt.NonModal }
+ }
+ CheckBox {
+ id: fontDialogScalableFonts
+ text: "Scalable fonts"
+ Binding on checked { value: fontDialog.scalableFonts }
+ }
+ CheckBox {
+ id: fontDialogNonScalableFonts
+ text: "Non scalable fonts"
+ Binding on checked { value: fontDialog.nonScalableFonts }
+ }
+ CheckBox {
+ id: fontDialogMonospacedFonts
+ text: "Monospaced fonts"
+ Binding on checked { value: fontDialog.monospacedFonts }
+ }
+ CheckBox {
+ id: fontDialogProportionalFonts
+ text: "Proportional fonts"
+ Binding on checked { value: fontDialog.proportionalFonts }
+ }
+ CheckBox {
+ id: fontDialogVisible
+ text: "Visible"
+ Binding on checked { value: fontDialog.visible }
+ }
+ Text {
+ text: "Current font:"
+ }
+ Text {
+ id: fontLabel
+ color: palette.windowText
+ text: "<b>" + fontDialog.font.family + " - " + fontDialog.font.pointSize + "</b>"
+ MouseArea {
+ anchors.fill: parent
+ onClicked: fontDialog.open()
+ }
+ }
+ }
+
+ Rectangle {
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
+ height: buttonRow.height * 1.2
+ color: Qt.darker(palette.window, 1.1)
+ border.color: Qt.darker(palette.window, 1.3)
+ Row {
+ id: buttonRow
+ spacing: 6
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ anchors.leftMargin: 12
+ width: parent.width
+ Button {
+ text: "Open"
+ anchors.verticalCenter: parent.verticalCenter
+ onClicked: fontDialog.open()
+ }
+ Button {
+ text: "Close"
+ anchors.verticalCenter: parent.verticalCenter
+ onClicked: fontDialog.close()
+ }
+ Button {
+ text: "set to default"
+ anchors.verticalCenter: parent.verticalCenter
+ onClicked: fontDialog.font = Qt.font({ family: "Arial", pointSize: 24, weight: Font.Normal })
+ }
+ }
+ }
+}
diff --git a/examples/quick/dialogs/systemdialogs/MessageDialogs.qml b/examples/quick/dialogs/systemdialogs/MessageDialogs.qml
new file mode 100644
index 0000000000..e6fdf57e0d
--- /dev/null
+++ b/examples/quick/dialogs/systemdialogs/MessageDialogs.qml
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc and its Subsidiary(-ies) 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.1
+import QtQuick.Dialogs 1.1
+import QtQuick.Window 2.0
+import "../../shared"
+
+Rectangle {
+ width: 580
+ height: 400
+ color: palette.window
+ SystemPalette { id: palette }
+ clip: true
+
+ //! [messagedialog]
+ MessageDialog {
+ id: messageDialog
+ visible: messageDialogVisible.checked
+ modality: messageDialogModal.checked ? Qt.WindowModal : Qt.NonModal
+ title: windowTitleField.text
+ text: customizeText.checked ? textField.text : ""
+ informativeText: customizeInformativeText.checked ? informativeTextField.text : ""
+ detailedText: customizeDetailedText.checked ? detailedTextField.text : ""
+ onButtonClicked: console.log("clicked button " + clickedButton)
+ onAccepted: lastChosen.text = "Accepted " +
+ (clickedButton == Message.Ok ? "(OK)" : (clickedButton == Message.Retry ? "(Retry)" : "(Ignore)"))
+ onRejected: lastChosen.text = "Rejected " +
+ (clickedButton == Message.Close ? "(Close)" : (clickedButton == Message.Abort ? "(Abort)" : "(Cancel)"))
+ onHelp: lastChosen.text = "Yelped for help!"
+ onYes: lastChosen.text = (clickedButton == Message.Yes ? "Yeessss!!" : "Yes, now and always")
+ onNo: lastChosen.text = (clickedButton == Message.No ? "Oh No." : "No, no, a thousand times no!")
+ onApply: lastChosen.text = "Apply"
+ onReset: lastChosen.text = "Reset"
+ }
+ //! [messagedialog]
+
+ Column {
+ anchors.fill: parent
+ anchors.margins: 12
+ spacing: 8
+ Text {
+ color: palette.windowText
+ font.bold: true
+ text: "Message dialog properties:"
+ }
+ CheckBox {
+ id: messageDialogModal
+ text: "Modal"
+ checked: true
+ Binding on checked { value: messageDialog.modality != Qt.NonModal }
+ }
+ CheckBox {
+ id: customizeTitle
+ text: "Window Title"
+ checked: true
+ width: parent.width
+ TextField {
+ id: windowTitleField
+ anchors.right: parent.right
+ width: informativeTextField.width
+ text: "Alert"
+ }
+ }
+ Row {
+ spacing: 8
+ property bool updating: false
+ function updateIcon(icon, checked) {
+ if (updating) return
+ updating = true
+ messageDialog.icon = (checked ? icon : Message.NoIcon)
+ for (var i = 0; i < children.length; ++i)
+ if (children[i].icon !== icon)
+ children[i].checked = false
+ updating = false
+ }
+
+ CheckBox {
+ id: iconInformation
+ text: "Information"
+ property int icon: Message.Information
+ onCheckedChanged: parent.updateIcon(icon, checked)
+ }
+
+ CheckBox {
+ id: iconWarning
+ text: "Warning"
+ checked: true
+ property int icon: Message.Warning
+ onCheckedChanged: parent.updateIcon(icon, checked)
+ Component.onCompleted: parent.updateIcon(icon, true)
+ }
+
+ CheckBox {
+ id: iconCritical
+ text: "Critical"
+ property int icon: Message.Critical
+ onCheckedChanged: parent.updateIcon(icon, checked)
+ }
+
+ CheckBox {
+ id: iconQuestion
+ text: "Question"
+ property int icon: Message.Question
+ onCheckedChanged: parent.updateIcon(icon, checked)
+ }
+ }
+
+ CheckBox {
+ id: customizeText
+ text: "Primary Text"
+ checked: true
+ width: parent.width
+ TextField {
+ id: textField
+ anchors.right: parent.right
+ width: informativeTextField.width
+ text: "Attention Please"
+ }
+ }
+ CheckBox {
+ id: customizeInformativeText
+ text: "Informative Text"
+ checked: true
+ width: parent.width
+ TextField {
+ id: informativeTextField
+ anchors.right: parent.right
+ width: parent.width - parent.row.spacing - parent.row.width
+ text: "Be alert!"
+ }
+ }
+ Text {
+ text: "Buttons:"
+ }
+ Flow {
+ spacing: 8
+ width: parent.width
+ property bool updating: false
+ function updateButtons(button, checked) {
+ if (updating) return
+ updating = true
+ var buttons = 0
+ for (var i = 0; i < children.length; ++i)
+ if (children[i].checked)
+ buttons |= children[i].button
+ if (!buttons)
+ buttons = Message.Ok
+ messageDialog.standardButtons = buttons
+ updating = false
+ }
+
+ CheckBox {
+ text: "Help"
+ property int button: Message.Help
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "Abort"
+ property int button: Message.Abort
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "Close"
+ property int button: Message.Close
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "Cancel"
+ property int button: Message.Cancel
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "NoToAll"
+ property int button: Message.NoToAll
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "No"
+ property int button: Message.No
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "YesToAll"
+ property int button: Message.YesToAll
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "Yes"
+ property int button: Message.Yes
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "Ignore"
+ property int button: Message.Ignore
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "Retry"
+ property int button: Message.Retry
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+
+ CheckBox {
+ text: "OK"
+ checked: true
+ property int button: Message.Ok
+ onCheckedChanged: parent.updateButtons(button, checked)
+ }
+ }
+ CheckBox {
+ id: customizeDetailedText
+ text: "Detailed Text"
+ checked: true
+ width: parent.width
+ TextField {
+ id: detailedTextField
+ anchors.right: parent.right
+ width: informativeTextField.width
+ text: "The world needs more lerts."
+ }
+ }
+ CheckBox {
+ id: messageDialogVisible
+ text: "Visible"
+ Binding on checked { value: messageDialog.visible }
+ }
+ Text {
+ id: lastChosen
+ }
+ }
+
+ Rectangle {
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
+ height: buttonRow.height * 1.2
+ color: Qt.darker(palette.window, 1.1)
+ border.color: Qt.darker(palette.window, 1.3)
+ Row {
+ id: buttonRow
+ spacing: 6
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ anchors.leftMargin: 12
+ width: parent.width
+ Button {
+ text: "Open"
+ anchors.verticalCenter: parent.verticalCenter
+ onClicked: messageDialog.open()
+ }
+ Button {
+ text: "Close"
+ anchors.verticalCenter: parent.verticalCenter
+ onClicked: messageDialog.close()
+ }
+ }
+ }
+}
diff --git a/examples/quick/dialogs/systemdialogs/systemdialogs.pro b/examples/quick/dialogs/systemdialogs/systemdialogs.pro
index 4e520d1a5d..323ea2fac7 100644
--- a/examples/quick/dialogs/systemdialogs/systemdialogs.pro
+++ b/examples/quick/dialogs/systemdialogs/systemdialogs.pro
@@ -7,7 +7,9 @@ RESOURCES += systemdialogs.qrc ../../shared/shared.qrc
OTHER_FILES += \
systemdialogs.qml \
FileDialogs.qml \
- ColorDialogs.qml
+ ColorDialogs.qml \
+ FontDialogs.qml \
+ MessageDialogs.qml
target.path = $$[QT_INSTALL_EXAMPLES]/quick/dialogs/systemdialogs
INSTALLS += target
diff --git a/examples/quick/dialogs/systemdialogs/systemdialogs.qml b/examples/quick/dialogs/systemdialogs/systemdialogs.qml
index 6ef1f4b507..1600e88812 100644
--- a/examples/quick/dialogs/systemdialogs/systemdialogs.qml
+++ b/examples/quick/dialogs/systemdialogs/systemdialogs.qml
@@ -38,7 +38,7 @@
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.2
import "../../shared"
TabSet {
@@ -56,4 +56,16 @@ TabSet {
anchors.fill: parent
color: "#e3e3e3" // to match tab.png
}
+
+ FontDialogs {
+ property string title: "Font Dialog"
+ anchors.fill: parent
+ color: "#e3e3e3" // to match tab.png
+ }
+
+ MessageDialogs {
+ property string title: "Message Dialog"
+ anchors.fill: parent
+ color: "#e3e3e3" // to match tab.png
+ }
}
diff --git a/examples/quick/dialogs/systemdialogs/systemdialogs.qrc b/examples/quick/dialogs/systemdialogs/systemdialogs.qrc
index e9a46022b2..2193088cb9 100644
--- a/examples/quick/dialogs/systemdialogs/systemdialogs.qrc
+++ b/examples/quick/dialogs/systemdialogs/systemdialogs.qrc
@@ -3,5 +3,7 @@
<file>systemdialogs.qml</file>
<file>FileDialogs.qml</file>
<file>ColorDialogs.qml</file>
+ <file>FontDialogs.qml</file>
+ <file>MessageDialogs.qml</file>
</qresource>
</RCC>
diff --git a/examples/quick/models/abstractitemmodel/doc/images/qml-abstractitemmodel-example.png b/examples/quick/models/abstractitemmodel/doc/images/qml-abstractitemmodel-example.png
new file mode 100644
index 0000000000..1d7ff197ad
--- /dev/null
+++ b/examples/quick/models/abstractitemmodel/doc/images/qml-abstractitemmodel-example.png
Binary files differ
diff --git a/examples/quick/models/abstractitemmodel/doc/src/abstractitemmodel-example.qdoc b/examples/quick/models/abstractitemmodel/doc/src/abstractitemmodel-example.qdoc
new file mode 100644
index 0000000000..bcf1034226
--- /dev/null
+++ b/examples/quick/models/abstractitemmodel/doc/src/abstractitemmodel-example.qdoc
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the demonstration applications 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 Digia Plc and its Subsidiary(-ies) 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$
+**
+****************************************************************************/
+
+/*!
+ \example models/abstractitemmodel
+ \title Models and Views: AbstractItemModel Example
+ \brief Shows how to use a QAbstractItemModel subclass as a model in QML.
+
+ \image qml-abstractitemmodel-example.png
+*/ \ No newline at end of file
diff --git a/examples/quick/models/objectlistmodel/doc/images/qml-objectlistmodel-example.png b/examples/quick/models/objectlistmodel/doc/images/qml-objectlistmodel-example.png
new file mode 100644
index 0000000000..c0fc490c75
--- /dev/null
+++ b/examples/quick/models/objectlistmodel/doc/images/qml-objectlistmodel-example.png
Binary files differ
diff --git a/examples/quick/models/objectlistmodel/doc/src/objectlistmodel-example.qdoc b/examples/quick/models/objectlistmodel/doc/src/objectlistmodel-example.qdoc
new file mode 100644
index 0000000000..2d1046dc5e
--- /dev/null
+++ b/examples/quick/models/objectlistmodel/doc/src/objectlistmodel-example.qdoc
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the demonstration applications 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 Digia Plc and its Subsidiary(-ies) 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$
+**
+****************************************************************************/
+
+/*!
+ \example models/objectlistmodel
+ \title Models and Views: Object ListModel Example
+ \brief Shows how to use a QList<QObject*> as a model in QML.
+
+ \image qml-objectlistmodel-example.png
+*/
diff --git a/examples/quick/models/stringlistmodel/doc/images/qml-stringlistmodel-example.png b/examples/quick/models/stringlistmodel/doc/images/qml-stringlistmodel-example.png
new file mode 100644
index 0000000000..c8c888b620
--- /dev/null
+++ b/examples/quick/models/stringlistmodel/doc/images/qml-stringlistmodel-example.png
Binary files differ
diff --git a/examples/quick/models/stringlistmodel/doc/src/stringlistmodel-example.qdoc b/examples/quick/models/stringlistmodel/doc/src/stringlistmodel-example.qdoc
new file mode 100644
index 0000000000..3ee9058d57
--- /dev/null
+++ b/examples/quick/models/stringlistmodel/doc/src/stringlistmodel-example.qdoc
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the demonstration applications 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 Digia Plc and its Subsidiary(-ies) 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$
+**
+****************************************************************************/
+
+/*!
+ \example models/stringlistmodel
+ \title Models and Views: String ListModel Example
+ \brief Shows how to use a QStringList as a model in QML.
+
+ \image qml-stringlistmodel-example.png
+*/
diff --git a/examples/quick/shared/CheckBox.qml b/examples/quick/shared/CheckBox.qml
index a3a22b7723..16ad2adba8 100644
--- a/examples/quick/shared/CheckBox.qml
+++ b/examples/quick/shared/CheckBox.qml
@@ -49,6 +49,7 @@ Item {
property alias text: label.text
property bool checked
property alias pressed: mouseArea.pressed
+ property alias row: row
signal clicked
SystemPalette { id: palette }
diff --git a/examples/quick/shared/TabSet.qml b/examples/quick/shared/TabSet.qml
index 86050b6073..1fdf476424 100644
--- a/examples/quick/shared/TabSet.qml
+++ b/examples/quick/shared/TabSet.qml
@@ -56,8 +56,10 @@ Item {
Component.onCompleted: setZOrders()
function setZOrders() {
- for (var i = 0; i < stack.children.length; ++i)
+ for (var i = 0; i < stack.children.length; ++i) {
stack.children[i].z = (i == current ? 1 : 0)
+ stack.children[i].enabled = (i == current)
+ }
}
Row {
diff --git a/examples/quick/shared/TextField.qml b/examples/quick/shared/TextField.qml
new file mode 100644
index 0000000000..9a6427a105
--- /dev/null
+++ b/examples/quick/shared/TextField.qml
@@ -0,0 +1,80 @@
+/*****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs module 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 Digia Plc and its Subsidiary(-ies) 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.1
+
+Item {
+ id: root
+
+ property alias textInput: textInput
+ property alias text: textInput.text
+ signal accepted
+ signal downPressed
+ implicitWidth: textInput.implicitWidth + rect.radius * 2
+ implicitHeight: textInput.implicitHeight
+
+ function copyAll() {
+ textInput.selectAll()
+ textInput.copy()
+ }
+
+ SystemPalette { id: palette }
+ height: textInput.implicitHeight + 8
+ clip: true
+
+ Rectangle {
+ id: rect
+ anchors.fill: parent
+ radius: height / 4
+ color: palette.button
+ border.color: Qt.darker(palette.button, 1.5)
+ }
+
+ TextInput {
+ id: textInput
+ color: palette.text
+ anchors.fill: parent
+ anchors.leftMargin: rect.radius
+ anchors.rightMargin: rect.radius
+ verticalAlignment: Text.AlignVCenter
+ onAccepted: root.accepted()
+ Keys.onDownPressed: root.downPressed()
+ }
+}
diff --git a/examples/quick/shared/qmldir b/examples/quick/shared/qmldir
index 4f7c50540d..b539191fec 100644
--- a/examples/quick/shared/qmldir
+++ b/examples/quick/shared/qmldir
@@ -4,3 +4,4 @@ LauncherList 2.0 LauncherList.qml
SimpleLauncherDelegate 2.0 SimpleLauncherDelegate.qml
Slider 2.0 Slider.qml
TabSet 2.1 TabSet.qml
+TextField 2.1 TextField.qml
diff --git a/examples/quick/shared/quick_shared.qrc b/examples/quick/shared/quick_shared.qrc
index ee706712dd..015a1f99d5 100644
--- a/examples/quick/shared/quick_shared.qrc
+++ b/examples/quick/shared/quick_shared.qrc
@@ -4,6 +4,7 @@
<file>SimpleLauncherDelegate.qml</file>
<file>Button.qml</file>
<file>CheckBox.qml</file>
+ <file>TextField.qml</file>
<file>images/back.png</file>
<file>images/next.png</file>
</qresource>
diff --git a/examples/quick/shared/shared.h b/examples/quick/shared/shared.h
index 648b2944b7..5cf1333c02 100644
--- a/examples/quick/shared/shared.h
+++ b/examples/quick/shared/shared.h
@@ -40,7 +40,8 @@
#include <QDir>
#include <QGuiApplication>
#include <QQmlEngine>
-#include <QQuickView>
+#include <QQmlFileSelector>
+#include <QQuickView> //Not using QQmlApplicationEngine because many examples don't have a Window{}
#define DECLARATIVE_EXAMPLE_MAIN(NAME) int main(int argc, char* argv[]) \
{\
QGuiApplication app(argc,argv);\
@@ -49,6 +50,7 @@
app.setApplicationName(QFileInfo(app.applicationFilePath()).baseName());\
QQuickView view;\
view.connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit()));\
+ view.engine()->setUrlInterceptor(new QQmlFileSelector(&view));\
view.setSource(QUrl("qrc:///" #NAME ".qml")); \
view.setResizeMode(QQuickView::SizeRootObjectToView);\
if (QGuiApplication::platformName() == QLatin1String("qnx") || \
diff --git a/examples/quick/shared/shared.qrc b/examples/quick/shared/shared.qrc
index 6aaeca5211..7e0c66c34b 100644
--- a/examples/quick/shared/shared.qrc
+++ b/examples/quick/shared/shared.qrc
@@ -7,6 +7,7 @@
<file>images/slider_handle.png</file>
<file>CheckBox.qml</file>
<file>TabSet.qml</file>
+ <file>TextField.qml</file>
<file>images/back.png</file>
<file>images/next.png</file>
<file>images/qt-logo.png</file>
diff --git a/src/3rdparty/double-conversion/utils.h b/src/3rdparty/double-conversion/utils.h
index f5a8c984e4..044c0c25eb 100644
--- a/src/3rdparty/double-conversion/utils.h
+++ b/src/3rdparty/double-conversion/utils.h
@@ -71,6 +71,8 @@
#else
#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
#endif // _WIN32
+#elif defined(WINCE) || defined(_WIN32_WCE)
+#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
#else
#error Target architecture was not detected as supported by Double-Conversion.
#endif
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARM.cpp b/src/3rdparty/masm/assembler/MacroAssemblerARM.cpp
index d40b7c2aea..3ca9c7da80 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerARM.cpp
+++ b/src/3rdparty/masm/assembler/MacroAssemblerARM.cpp
@@ -36,7 +36,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <elf.h>
-#define HWCAP_VFP· (1 << 6)
+#define HWCAP_VFP (1 << 6)
#endif
namespace JSC {
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
index 81c1d7e08a..0c5a5fb3ce 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
+++ b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
@@ -941,6 +941,12 @@ public:
m_assembler.vdiv(dest, op1, op2);
}
+ void divDouble(Address src, FPRegisterID dest)
+ {
+ loadDouble(src, fpTempRegister);
+ divDouble(fpTempRegister, dest);
+ }
+
void subDouble(FPRegisterID src, FPRegisterID dest)
{
m_assembler.vsub(dest, dest, src);
diff --git a/src/3rdparty/masm/masm-defs.pri b/src/3rdparty/masm/masm-defs.pri
index d2925a2b8c..836ac0c796 100644
--- a/src/3rdparty/masm/masm-defs.pri
+++ b/src/3rdparty/masm/masm-defs.pri
@@ -1,9 +1,16 @@
-!wince*:!ios:!if(win*:isEqual(QT_ARCH, "x86_64")): DEFINES += V4_ENABLE_JIT ENABLE_YARR_JIT=1
-else: DEFINES += ENABLE_YARR_JIT=0
+
+
+wince*: CONFIG += disable_jit
+ios: CONFIG += disable_jit
+if(win*:isEqual(QT_ARCH, "x86_64")): CONFIG += disable_jit
+equals(ANDROID_TARGET_ARCH, armeabi): CONFIG += disable_jit
+
+disable_jit: DEFINES += ENABLE_YARR_JIT=0
+else: DEFINES += V4_ENABLE_JIT ENABLE_YARR_JIT=1
# On Qt/Android/ARM release builds are thumb and debug builds arm,
# but we'll force the JIT to always generate thumb2
-android:isEqual(QT_ARCH, "arm") {
+contains(DEFINES, V4_ENABLE_JIT):android:isEqual(QT_ARCH, "arm") {
DEFINES += WTF_CPU_ARM_THUMB2
}
diff --git a/src/imports/dialogs-private/dialogs-private.pro b/src/imports/dialogs-private/dialogs-private.pro
new file mode 100644
index 0000000000..8e35afa2bc
--- /dev/null
+++ b/src/imports/dialogs-private/dialogs-private.pro
@@ -0,0 +1,17 @@
+CXX_MODULE = qml
+TARGET = dialogsprivateplugin
+TARGETPATH = QtQuick/Dialogs/Private
+IMPORT_VERSION = 1.1
+
+SOURCES += \
+ qquickfontlistmodel.cpp \
+ qquickwritingsystemlistmodel.cpp \
+ dialogsprivateplugin.cpp
+
+HEADERS += \
+ qquickfontlistmodel_p.h \
+ qquickwritingsystemlistmodel_p.h
+
+QT += quick-private gui-private core-private qml-private
+
+load(qml_plugin)
diff --git a/src/imports/dialogs-private/dialogsprivateplugin.cpp b/src/imports/dialogs-private/dialogsprivateplugin.cpp
new file mode 100644
index 0000000000..f920df30f3
--- /dev/null
+++ b/src/imports/dialogs-private/dialogsprivateplugin.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include "qquickwritingsystemlistmodel_p.h"
+#include "qquickfontlistmodel_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtQuick2DialogsPrivatePlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Dialogs.Private"));
+
+ qmlRegisterType<QQuickWritingSystemListModel>(uri, 1, 1, "WritingSystemListModel");
+ qmlRegisterType<QQuickFontListModel>(uri, 1, 1, "FontListModel");
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "dialogsprivateplugin.moc"
diff --git a/src/imports/dialogs-private/qmldir b/src/imports/dialogs-private/qmldir
new file mode 100644
index 0000000000..e184715519
--- /dev/null
+++ b/src/imports/dialogs-private/qmldir
@@ -0,0 +1,3 @@
+module QtQuick.Dialogs.Private
+plugin dialogsprivateplugin
+typeinfo plugins.qmltypes
diff --git a/src/imports/dialogs-private/qquickfontlistmodel.cpp b/src/imports/dialogs-private/qquickfontlistmodel.cpp
new file mode 100644
index 0000000000..54ce700238
--- /dev/null
+++ b/src/imports/dialogs-private/qquickfontlistmodel.cpp
@@ -0,0 +1,276 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickfontlistmodel_p.h"
+#include <QtGui/qfontdatabase.h>
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qjsengine.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickFontListModelPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickFontListModel)
+
+public:
+ QQuickFontListModelPrivate(QQuickFontListModel *q)
+ : q_ptr(q), ws(QFontDatabase::Any)
+ , options(QSharedPointer<QFontDialogOptions>(new QFontDialogOptions()))
+ {}
+
+ QQuickFontListModel *q_ptr;
+ QFontDatabase db;
+ QFontDatabase::WritingSystem ws;
+ QSharedPointer<QFontDialogOptions> options;
+ QStringList families;
+ QHash<int, QByteArray> roleNames;
+ ~QQuickFontListModelPrivate() {}
+ void init();
+};
+
+
+void QQuickFontListModelPrivate::init()
+{
+ Q_Q(QQuickFontListModel);
+
+ families = db.families();
+
+ emit q->rowCountChanged();
+ emit q->writingSystemChanged();
+}
+
+QQuickFontListModel::QQuickFontListModel(QObject *parent)
+ : QAbstractListModel(parent), d_ptr(new QQuickFontListModelPrivate(this))
+{
+ Q_D(QQuickFontListModel);
+ d->roleNames[FontFamilyRole] = "family";
+ d->init();
+}
+
+QQuickFontListModel::~QQuickFontListModel()
+{
+}
+
+QVariant QQuickFontListModel::data(const QModelIndex &index, int role) const
+{
+ Q_D(const QQuickFontListModel);
+ QVariant rv;
+
+ if (index.row() >= d->families.size())
+ return rv;
+
+ switch (role)
+ {
+ case FontFamilyRole:
+ rv = d->families.at(index.row());
+ break;
+ default:
+ break;
+ }
+ return rv;
+}
+
+QHash<int, QByteArray> QQuickFontListModel::roleNames() const
+{
+ Q_D(const QQuickFontListModel);
+ return d->roleNames;
+}
+
+int QQuickFontListModel::rowCount(const QModelIndex &parent) const
+{
+ Q_D(const QQuickFontListModel);
+ Q_UNUSED(parent);
+ return d->families.size();
+}
+
+QModelIndex QQuickFontListModel::index(int row, int , const QModelIndex &) const
+{
+ return createIndex(row, 0);
+}
+
+QString QQuickFontListModel::writingSystem() const
+{
+ Q_D(const QQuickFontListModel);
+ return QFontDatabase::writingSystemName(d->ws);
+}
+
+void QQuickFontListModel::setWritingSystem(const QString &wSystem)
+{
+ Q_D(QQuickFontListModel);
+
+ if (wSystem == writingSystem())
+ return;
+
+ QList<QFontDatabase::WritingSystem> wss;
+ wss << QFontDatabase::Any;
+ wss << d->db.writingSystems();
+ QFontDatabase::WritingSystem ws;
+ foreach (ws, wss) {
+ if (wSystem == QFontDatabase::writingSystemName(ws)) {
+ d->ws = ws;
+ updateFamilies();
+ return;
+ }
+ }
+}
+
+void QQuickFontListModel::updateFamilies()
+{
+ Q_D(QQuickFontListModel);
+
+ beginResetModel();
+ const QFontDialogOptions::FontDialogOptions scalableMask = (QFontDialogOptions::FontDialogOptions)(QFontDialogOptions::ScalableFonts | QFontDialogOptions::NonScalableFonts);
+ const QFontDialogOptions::FontDialogOptions spacingMask = (QFontDialogOptions::FontDialogOptions)(QFontDialogOptions::ProportionalFonts | QFontDialogOptions::MonospacedFonts);
+ const QFontDialogOptions::FontDialogOptions options = d->options->options();
+
+ d->families.clear();
+ foreach (const QString &family, d->db.families(d->ws)) {
+ if ((options & scalableMask) && (options & scalableMask) != scalableMask) {
+ if (bool(options & QFontDialogOptions::ScalableFonts) != d->db.isSmoothlyScalable(family))
+ continue;
+ }
+ if ((options & spacingMask) && (options & spacingMask) != spacingMask) {
+ if (bool(options & QFontDialogOptions::MonospacedFonts) != d->db.isFixedPitch(family))
+ continue;
+ }
+ d->families << family;
+ }
+ endResetModel();
+}
+
+bool QQuickFontListModel::scalableFonts() const
+{
+ Q_D(const QQuickFontListModel);
+ return d->options->testOption(QFontDialogOptions::ScalableFonts);
+}
+
+bool QQuickFontListModel::nonScalableFonts() const
+{
+ Q_D(const QQuickFontListModel);
+ return d->options->testOption(QFontDialogOptions::NonScalableFonts);
+}
+
+bool QQuickFontListModel::monospacedFonts() const
+{
+ Q_D(const QQuickFontListModel);
+ return d->options->testOption(QFontDialogOptions::MonospacedFonts);
+}
+
+bool QQuickFontListModel::proportionalFonts() const
+{
+ Q_D(const QQuickFontListModel);
+ return d->options->testOption(QFontDialogOptions::ProportionalFonts);
+}
+
+QJSValue QQuickFontListModel::get(int idx) const
+{
+ Q_D(const QQuickFontListModel);
+
+ QQmlEngine *engine = qmlContext(this)->engine();
+
+ if (idx < 0 || idx >= count())
+ return engine->newObject();
+
+ QJSValue result = engine->newObject();
+ int count = d->roleNames.keys().count();
+ for (int i = 0; i < count; ++i)
+ result.setProperty(QString(d->roleNames[Qt::UserRole + i + 1]), data(index(idx, 0), Qt::UserRole + i + 1).toString());
+
+ return result;
+}
+
+QJSValue QQuickFontListModel::pointSizes()
+{
+ QQmlEngine *engine = qmlContext(this)->engine();
+
+ QList<int> pss = QFontDatabase::standardSizes();
+ int size = pss.size();
+
+ QJSValue result = engine->newArray(size);
+ for (int i = 0; i < size; ++i)
+ result.setProperty(i, pss.at(i));
+
+ return result;
+}
+
+void QQuickFontListModel::classBegin()
+{
+}
+
+void QQuickFontListModel::componentComplete()
+{
+}
+
+void QQuickFontListModel::setScalableFonts(bool arg)
+{
+ Q_D(QQuickFontListModel);
+ d->options->setOption(QFontDialogOptions::ScalableFonts, arg);
+ updateFamilies();
+ emit scalableFontsChanged();
+}
+
+void QQuickFontListModel::setNonScalableFonts(bool arg)
+{
+ Q_D(QQuickFontListModel);
+ d->options->setOption(QFontDialogOptions::NonScalableFonts, arg);
+ updateFamilies();
+ emit nonScalableFontsChanged();
+}
+
+void QQuickFontListModel::setMonospacedFonts(bool arg)
+{
+ Q_D(QQuickFontListModel);
+ d->options->setOption(QFontDialogOptions::MonospacedFonts, arg);
+ updateFamilies();
+ emit monospacedFontsChanged();
+}
+
+void QQuickFontListModel::setProportionalFonts(bool arg)
+{
+ Q_D(QQuickFontListModel);
+ d->options->setOption(QFontDialogOptions::ProportionalFonts, arg);
+ updateFamilies();
+ emit proportionalFontsChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs-private/qquickfontlistmodel_p.h b/src/imports/dialogs-private/qquickfontlistmodel_p.h
new file mode 100644
index 0000000000..4f86bc779b
--- /dev/null
+++ b/src/imports/dialogs-private/qquickfontlistmodel_p.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKFONTLISTMODEL_P_H
+#define QQUICKFONTLISTMODEL_P_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/QAbstractListModel>
+#include <QtGui/qpa/qplatformdialoghelper.h>
+#include <QtQml/qqmlparserstatus.h>
+#include <QtQml/qjsvalue.h>
+
+QT_BEGIN_NAMESPACE
+
+class QModelIndex;
+
+class QQuickFontListModelPrivate;
+
+class QQuickFontListModel : public QAbstractListModel, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(QString writingSystem READ writingSystem WRITE setWritingSystem NOTIFY writingSystemChanged)
+
+ Q_PROPERTY(bool scalableFonts READ scalableFonts WRITE setScalableFonts NOTIFY scalableFontsChanged)
+ Q_PROPERTY(bool nonScalableFonts READ nonScalableFonts WRITE setNonScalableFonts NOTIFY nonScalableFontsChanged)
+ Q_PROPERTY(bool monospacedFonts READ monospacedFonts WRITE setMonospacedFonts NOTIFY monospacedFontsChanged)
+ Q_PROPERTY(bool proportionalFonts READ proportionalFonts WRITE setProportionalFonts NOTIFY proportionalFontsChanged)
+
+ Q_PROPERTY(int count READ count NOTIFY rowCountChanged)
+
+public:
+ QQuickFontListModel(QObject *parent = 0);
+ ~QQuickFontListModel();
+
+ enum Roles {
+ FontFamilyRole = Qt::UserRole + 1
+ };
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual QHash<int, QByteArray> roleNames() const;
+
+ int count() const { return rowCount(QModelIndex()); }
+
+ QString writingSystem() const;
+ void setWritingSystem(const QString& writingSystem);
+
+ bool scalableFonts() const;
+ bool nonScalableFonts() const;
+ bool monospacedFonts() const;
+ bool proportionalFonts() const;
+
+ Q_INVOKABLE QJSValue get(int index) const;
+ Q_INVOKABLE QJSValue pointSizes();
+
+ virtual void classBegin();
+ virtual void componentComplete();
+
+public Q_SLOTS:
+ void setScalableFonts(bool arg);
+ void setNonScalableFonts(bool arg);
+ void setMonospacedFonts(bool arg);
+ void setProportionalFonts(bool arg);
+
+Q_SIGNALS:
+ void scalableFontsChanged();
+ void nonScalableFontsChanged();
+ void monospacedFontsChanged();
+ void proportionalFontsChanged();
+ void writingSystemChanged();
+ void rowCountChanged() const;
+
+protected:
+ void updateFamilies();
+
+private:
+ Q_DISABLE_COPY(QQuickFontListModel)
+ Q_DECLARE_PRIVATE(QQuickFontListModel)
+ QScopedPointer<QQuickFontListModelPrivate> d_ptr;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKFONTLISTMODEL_P_H
diff --git a/src/imports/dialogs-private/qquickwritingsystemlistmodel.cpp b/src/imports/dialogs-private/qquickwritingsystemlistmodel.cpp
new file mode 100644
index 0000000000..23bc43a566
--- /dev/null
+++ b/src/imports/dialogs-private/qquickwritingsystemlistmodel.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickwritingsystemlistmodel_p.h"
+#include <QtGui/qfontdatabase.h>
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qjsengine.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWritingSystemListModelPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickWritingSystemListModel)
+
+public:
+ QQuickWritingSystemListModelPrivate(QQuickWritingSystemListModel *q)
+ : q_ptr(q)
+ {}
+
+ QQuickWritingSystemListModel *q_ptr;
+ QList<QFontDatabase::WritingSystem> wss;
+ QHash<int, QByteArray> roleNames;
+ ~QQuickWritingSystemListModelPrivate() {}
+ void init();
+};
+
+
+void QQuickWritingSystemListModelPrivate::init()
+{
+ Q_Q(QQuickWritingSystemListModel);
+ wss << QFontDatabase::Any;
+ QFontDatabase db;
+ wss << db.writingSystems();
+
+ emit q->rowCountChanged();
+ emit q->writingSystemsChanged();
+}
+
+QQuickWritingSystemListModel::QQuickWritingSystemListModel(QObject *parent)
+ : QAbstractListModel(parent), d_ptr(new QQuickWritingSystemListModelPrivate(this))
+{
+ Q_D(QQuickWritingSystemListModel);
+ d->roleNames[WritingSystemNameRole] = "name";
+ d->roleNames[WritingSystemSampleRole] = "sample";
+ d->init();
+}
+
+QQuickWritingSystemListModel::~QQuickWritingSystemListModel()
+{
+}
+
+QVariant QQuickWritingSystemListModel::data(const QModelIndex &index, int role) const
+{
+ Q_D(const QQuickWritingSystemListModel);
+ QVariant rv;
+
+ if (index.row() >= d->wss.size())
+ return rv;
+
+ switch (role)
+ {
+ case WritingSystemNameRole:
+ rv = QFontDatabase::writingSystemName(d->wss.at(index.row()));
+ break;
+ case WritingSystemSampleRole:
+ rv = QFontDatabase::writingSystemSample(d->wss.at(index.row()));
+ break;
+ default:
+ break;
+ }
+ return rv;
+}
+
+QHash<int, QByteArray> QQuickWritingSystemListModel::roleNames() const
+{
+ Q_D(const QQuickWritingSystemListModel);
+ return d->roleNames;
+}
+
+int QQuickWritingSystemListModel::rowCount(const QModelIndex &parent) const
+{
+ Q_D(const QQuickWritingSystemListModel);
+ Q_UNUSED(parent);
+ return d->wss.size();
+}
+
+QModelIndex QQuickWritingSystemListModel::index(int row, int , const QModelIndex &) const
+{
+ return createIndex(row, 0);
+}
+
+QStringList QQuickWritingSystemListModel::writingSystems() const
+{
+ Q_D(const QQuickWritingSystemListModel);
+ QStringList result;
+ QFontDatabase::WritingSystem ws;
+ foreach (ws, d->wss)
+ result.append(QFontDatabase::writingSystemName(ws));
+
+ return result;
+}
+
+QJSValue QQuickWritingSystemListModel::get(int idx) const
+{
+ Q_D(const QQuickWritingSystemListModel);
+
+ QQmlEngine *engine = qmlContext(this)->engine();
+
+ if (idx < 0 || idx >= count())
+ return engine->newObject();
+
+ QJSValue result = engine->newObject();
+ int count = d->roleNames.keys().count();
+ for (int i = 0; i < count; ++i)
+ result.setProperty(QString(d->roleNames[Qt::UserRole + i + 1]), data(index(idx, 0), Qt::UserRole + i + 1).toString());
+
+ return result;
+
+}
+
+void QQuickWritingSystemListModel::classBegin()
+{
+}
+
+void QQuickWritingSystemListModel::componentComplete()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs-private/qquickwritingsystemlistmodel_p.h b/src/imports/dialogs-private/qquickwritingsystemlistmodel_p.h
new file mode 100644
index 0000000000..120dd8a6f2
--- /dev/null
+++ b/src/imports/dialogs-private/qquickwritingsystemlistmodel_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWRITINGSYSTEMLISTMODEL_P_H
+#define QQUICKWRITINGSYSTEMLISTMODEL_P_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/QAbstractListModel>
+#include <QtQml/qqmlparserstatus.h>
+#include <QtQml/qjsvalue.h>
+
+QT_BEGIN_NAMESPACE
+
+class QModelIndex;
+
+class QQuickWritingSystemListModelPrivate;
+
+class QQuickWritingSystemListModel : public QAbstractListModel, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(QStringList writingSystems READ writingSystems NOTIFY writingSystemsChanged)
+
+ Q_PROPERTY(int count READ count NOTIFY rowCountChanged)
+
+public:
+ QQuickWritingSystemListModel(QObject *parent = 0);
+ ~QQuickWritingSystemListModel();
+
+ enum Roles {
+ WritingSystemNameRole = Qt::UserRole + 1,
+ WritingSystemSampleRole = Qt::UserRole + 2
+ };
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual QHash<int, QByteArray> roleNames() const;
+
+ int count() const { return rowCount(QModelIndex()); }
+
+ QStringList writingSystems() const;
+
+ Q_INVOKABLE QJSValue get(int index) const;
+
+ virtual void classBegin();
+ virtual void componentComplete();
+
+Q_SIGNALS:
+ void writingSystemsChanged();
+ void rowCountChanged() const;
+
+private:
+ Q_DISABLE_COPY(QQuickWritingSystemListModel)
+ Q_DECLARE_PRIVATE(QQuickWritingSystemListModel)
+ QScopedPointer<QQuickWritingSystemListModelPrivate> d_ptr;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKWRITINGSYSTEMLISTMODEL_P_H
diff --git a/src/imports/dialogs/DefaultColorDialog.qml b/src/imports/dialogs/DefaultColorDialog.qml
index 44af99bf18..1d4c4a704b 100644
--- a/src/imports/dialogs/DefaultColorDialog.qml
+++ b/src/imports/dialogs/DefaultColorDialog.qml
@@ -48,15 +48,16 @@ AbstractColorDialog {
property bool _valueSet: true // guard to prevent binding loops
function _setControlsFromColor() {
_valueSet = false
- hueSlider.value = root.hue
- saturationSlider.value = root.saturation
- lightnessSlider.value = root.lightness
- alphaSlider.value = root.alpha
- crosshairs.x = root.lightness * paletteMap.width
- crosshairs.y = (1.0 - root.saturation) * paletteMap.height
+ hueSlider.value = root.currentHue
+ saturationSlider.value = root.currentSaturation
+ lightnessSlider.value = root.currentLightness
+ alphaSlider.value = root.currentAlpha
+ crosshairs.x = root.currentLightness * paletteMap.width
+ crosshairs.y = (1.0 - root.currentSaturation) * paletteMap.height
_valueSet = true
}
- onColorChanged: _setControlsFromColor()
+ onCurrentColorChanged: _setControlsFromColor()
+ onSelectionAccepted: root.color = root.currentColor
Rectangle {
id: content
@@ -204,7 +205,7 @@ AbstractColorDialog {
ColorSlider {
id: hueSlider
value: 0.5
- onValueChanged: if (_valueSet) root.color = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
+ onValueChanged: if (_valueSet) root.currentColor = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
text: qsTr("Hue")
trackDelegate: Rectangle {
rotation: -90
@@ -225,7 +226,7 @@ AbstractColorDialog {
id: saturationSlider
visible: !content.usePaletteMap
value: 0.5
- onValueChanged: if (_valueSet) root.color = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
+ onValueChanged: if (_valueSet) root.currentColor = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
text: qsTr("Saturation")
trackDelegate: Rectangle {
rotation: -90
@@ -241,7 +242,7 @@ AbstractColorDialog {
id: lightnessSlider
visible: !content.usePaletteMap
value: 0.5
- onValueChanged: if (_valueSet) root.color = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
+ onValueChanged: if (_valueSet) root.currentColor = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
text: qsTr("Luminosity")
trackDelegate: Rectangle {
rotation: -90
@@ -259,7 +260,7 @@ AbstractColorDialog {
minimum: 0.0
maximum: 1.0
value: 1.0
- onValueChanged: if (_valueSet) root.color = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
+ onValueChanged: if (_valueSet) root.currentColor = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
text: qsTr("Alpha")
visible: root.showAlphaChannel
trackDelegate: Item {
@@ -296,9 +297,9 @@ AbstractColorDialog {
spacing: content.spacing
TextField {
id: colorField
- text: root.color
+ text: root.currentColor.toString()
anchors.verticalCenter: parent.verticalCenter
- onAccepted: root.color = text
+ onAccepted: root.currentColor = text
Component.onCompleted: width = implicitWidth + 10
}
Image {
diff --git a/src/imports/dialogs/DefaultFontDialog.qml b/src/imports/dialogs/DefaultFontDialog.qml
new file mode 100644
index 0000000000..87bb812c42
--- /dev/null
+++ b/src/imports/dialogs/DefaultFontDialog.qml
@@ -0,0 +1,457 @@
+/*****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs module of 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 Digia Plc and its Subsidiary(-ies) 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.1
+import QtQuick.Window 2.1
+import QtQuick.Dialogs 1.1
+import QtQuick.Dialogs.Private 1.1
+import "qml"
+
+AbstractFontDialog {
+ id: root
+
+ property alias font: content.externalFont
+
+ Rectangle {
+ id: content
+ property int maxSize: Math.min(Screen.desktopAvailableWidth, Screen.desktopAvailableHeight)
+ implicitWidth: settings.implicitWidth + changeableWidth + outerSpacing * 2
+ implicitHeight: writingSystemLabel.implicitHeight + changeableHeight + buttonRow.height + outerSpacing * 2
+ color: palette.window
+ property real spacing: 8
+ property real outerSpacing: 12
+ property real listMargins: 4
+ property color borderColor: Qt.darker(palette.button, 1.5)
+
+ property font font: Qt.font({ family: "Helvetica", pointSize: 24, weight: Font.Normal })
+ property font externalFont
+ property string writingSystem
+ property string writingSystemSample
+ property var pointSizes
+
+ property real changeableWidth: 160
+ property real changeableHeight: 120
+
+ onFontChanged: externalFont = font
+
+ onExternalFontChanged: {
+ if (content.font != content.externalFont) {
+ font = externalFont
+ wsListView.reset()
+ fontListView.reset()
+ weightListView.reset()
+ }
+ }
+
+ SystemPalette { id: palette }
+
+ Grid {
+ id: settings
+ anchors {
+ top: parent.top
+ bottom: buttonRow.top
+ left: parent.left
+ margins: content.outerSpacing
+ }
+ columns: 5
+ spacing: content.spacing
+
+ Text { id: writingSystemLabel; text: qsTr("Writing System") }
+ Text { id: fontNameLabel; text: qsTr("Font") }
+ Text { id: weightLabel; text: qsTr("Weight") }
+ Text { id: sizeLabel; text: qsTr("Size") }
+ Text { id: optionsLabel; text: qsTr("Others") }
+ Rectangle {
+ radius: 3
+ color: palette.window
+ border.color: content.borderColor
+ implicitWidth: Math.max(writingSystemLabel.implicitWidth + content.listMargins * 2, 80)
+ implicitHeight: Math.max(content.changeableHeight, sampleRectangle.height)
+ clip: true
+ ListView {
+ id: wsListView
+ anchors.fill: parent
+ anchors.margins: content.listMargins
+ anchors.topMargin: 2
+ highlightMoveDuration: 0
+ function reset() {
+ if (wsModel.count > 0) {
+ content.writingSystem = wsModel.get(0).name;
+ fontModel.writingSystem = content.writingSystem;
+ content.writingSystemSample = wsModel.get(0).sample;
+ }
+ }
+
+ model: WritingSystemListModel {
+ id: wsModel
+ Component.onCompleted: wsListView.reset()
+ }
+ highlight: Rectangle {
+ color: palette.highlight
+ x: 2 - wsListView.anchors.margins
+ width: wsListView.parent.width - 4
+ }
+ delegate: Item {
+ width: parent.width
+ height: wsText.height
+ Text {
+ id: wsText
+ text: name
+ width: parent.width
+ elide: Text.ElideRight
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ wsListView.currentIndex = index;
+ content.writingSystem = wsModel.get(wsListView.currentIndex).name;
+ fontModel.writingSystem = content.writingSystem;
+ content.writingSystemSample = wsModel.get(wsListView.currentIndex).sample;
+ }
+ }
+ }
+ }
+ }
+ Rectangle {
+ radius: 3
+ color: palette.window
+ border.color: content.borderColor
+ implicitWidth: Math.max(fontNameLabel.implicitWidth + content.listMargins * 2, 100, (root.width - 400) / 3)
+ implicitHeight: Math.max(content.changeableHeight, sampleRectangle.height)
+ clip: true
+ ListView {
+ id: fontListView
+ anchors.fill: parent
+ anchors.margins: content.listMargins
+ anchors.topMargin: 2
+ highlightMoveDuration: 0
+ function reset() {
+ fontModel.findIndex()
+ content.pointSizes = fontModel.pointSizes()
+ fontModel.findPointSizesIndex()
+ }
+
+ model: FontListModel {
+ id: fontModel
+ scalableFonts: root.scalableFonts
+ nonScalableFonts: root.nonScalableFonts
+ monospacedFonts: root.monospacedFonts
+ proportionalFonts: root.proportionalFonts
+ Component.onCompleted: fontListView.reset()
+ onModelReset: { findIndex(); }
+ function findIndex() {
+ if (fontModel.count <= 0)
+ return
+
+ if (content.font.family == "") {
+ content.font.family = fontModel.get(0).family
+ fontListView.currentIndex = 0
+ } else {
+ var find = false
+ for (var i = 0; i < fontModel.count; ++i) {
+ if (content.font.family == fontModel.get(i).family) {
+ find = true
+ fontListView.currentIndex = i
+ break
+ }
+ }
+ if (find == false) {
+ content.font.family = fontModel.get(0).family
+ fontListView.currentIndex = 0
+ }
+ }
+ }
+ function findPointSizesIndex() {
+ if (content.pointSizes.length <= 0)
+ return
+
+ var find = false
+ for (var i = 0; i < content.pointSizes.length; ++i) {
+ if (content.font.pointSize == content.pointSizes[i]) {
+ find = true
+ pointSizesListView.currentIndex = i
+ break
+ }
+ }
+ if (find == false) {
+ content.font.pointSize = content.pointSizes[0]
+ pointSizesListView.currentIndex = 0
+ }
+ }
+ }
+ highlight: Rectangle {
+ color: palette.highlight
+ x: 2 - fontListView.anchors.margins
+ width: fontListView.parent.width - 4
+ }
+ delegate: Item {
+ width: parent.width
+ height: fontText.height
+ Text {
+ id: fontText
+ text: family
+ width: parent.width
+ elide: Text.ElideRight
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ fontListView.currentIndex = index
+ content.font.family = fontModel.get(fontListView.currentIndex).family
+ }
+ }
+ }
+ }
+ }
+ Rectangle {
+ radius: 3
+ color: palette.window
+ border.color: content.borderColor
+ implicitWidth: Math.max(weightLabel.implicitWidth + content.listMargins * 2, 80)
+ implicitHeight: Math.max(content.changeableHeight, sampleRectangle.height)
+ clip: true
+ ListView {
+ anchors.fill: parent
+ anchors.margins: content.listMargins
+ anchors.topMargin: 2
+ highlightMoveDuration: 0
+ id: weightListView
+ function reset() {
+ weightModel.findIndex()
+ }
+
+ model: ListModel {
+ id: weightModel
+ ListElement {
+ name: "Light"
+ weight: Font.Light
+ }
+ ListElement {
+ name: "Normal"
+ weight: Font.Normal
+ }
+ ListElement {
+ name: "DemiBold"
+ weight: Font.DemiBold
+ }
+ ListElement {
+ name: "Bold"
+ weight: Font.Bold
+ }
+ ListElement {
+ name: "Black"
+ weight: Font.Black
+ }
+ Component.onCompleted: weightListView.reset()
+ function findIndex() {
+ var find = false
+ for (var i = 0; i < weightModel.count; ++i) {
+ if (content.font.weight == weightModel.get(i).weight) {
+ find = true
+ weightListView.currentIndex = i
+ break
+ }
+ }
+ if (find == false) {
+ content.font.weight = weightModel.get(1).family
+ fontListView.currentIndex = 1
+ }
+ }
+ }
+ highlight: Rectangle {
+ color: palette.highlight
+ x: 2 - weightListView.anchors.margins
+ width: weightListView.parent.width - 4
+ }
+ delegate: Item {
+ width: parent.width
+ height: weightText.height
+ Text {
+ id: weightText
+ text: name
+ width: parent.width
+ elide: Text.ElideRight
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ weightListView.currentIndex = index
+ content.font.weight = weightModel.get(weightListView.currentIndex).weight
+ }
+ }
+ }
+ }
+ }
+ Rectangle {
+ radius: 3
+ color: palette.window
+ border.color: content.borderColor
+ implicitWidth: Math.max(sizeLabel.implicitWidth + content.listMargins * 2, 60)
+ implicitHeight: Math.max(content.changeableHeight, sampleRectangle.height)
+ clip: true
+ ListView {
+ anchors.fill: parent
+ anchors.margins: content.listMargins
+ anchors.topMargin: 2
+ highlightMoveDuration: 0
+ id: pointSizesListView
+ model: content.pointSizes
+ highlight: Rectangle {
+ color: palette.highlight
+ x: 2 - weightListView.anchors.margins
+ width: weightListView.parent.width - 4
+ }
+ delegate: Item {
+ width: parent.width
+ height: pointSizesText.height
+ Text {
+ id: pointSizesText
+ text: content.pointSizes[index]
+ width: parent.width
+ elide: Text.ElideRight
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ pointSizesListView.currentIndex = index
+ content.font.pointSize = content.pointSizes[pointSizesListView.currentIndex]
+ }
+ }
+ }
+ }
+ }
+ Column {
+ id: optionsColumn
+ anchors.margins: 2
+ spacing: 2
+ CheckBox {
+ id: italicCheckBox
+ text: qsTr("Italic")
+ checked: content.font.italic
+ onClicked: { content.font.italic = italicCheckBox.checked }
+ }
+ CheckBox {
+ id: underlineCheckBox
+ text: qsTr("Underline")
+ checked: content.font.underline
+ onClicked: { content.font.underline = underlineCheckBox.checked }
+ }
+ CheckBox {
+ id: overlineCheckBox
+ text: qsTr("Overline")
+ checked: content.font.overline
+ onClicked: { content.font.overline = overlineCheckBox.checked }
+ }
+ CheckBox {
+ id: strikeoutCheckBox
+ text: qsTr("Strikeout")
+ checked: content.font.strikeout
+ onClicked: { content.font.strikeout = strikeoutCheckBox.checked }
+ }
+ }
+ }
+
+ Rectangle {
+ id: fixsampleRectangle
+ color: palette.window
+ anchors {
+ top: parent.top
+ left: settings.right
+ right: parent.right
+ margins: content.outerSpacing
+ }
+ implicitWidth: fixsampleText.implicitWidth
+ implicitHeight: fixsampleText.implicitHeight
+ Text { id: fixsampleText; anchors.left: parent.left; text: qsTr("Sample") }
+ }
+ Rectangle {
+ id: sampleRectangle
+ clip: true
+ anchors {
+ top: fixsampleRectangle.bottom
+ bottom: buttonRow.top
+ left: fixsampleRectangle.left
+ right: parent.right
+ margins: content.outerSpacing
+ }
+ implicitWidth: content.changeableWidth
+ implicitHeight: content.changeableHeight
+ color: palette.window
+ border.color: content.borderColor
+ Text {
+ id: sample
+ anchors.centerIn: parent
+ font: content.font
+ text: content.writingSystemSample
+ }
+ }
+
+ Item {
+ id: buttonRow
+ height: buttonsOnly.height
+ width: parent.width
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: content.bottom
+ margins: content.outerSpacing
+ }
+ Row {
+ id: buttonsOnly
+ spacing: content.spacing
+ anchors.right: parent.right
+ Button {
+ id: cancelButton
+ text: qsTr("Cancel")
+ onClicked: root.reject()
+ }
+ Button {
+ id: okButton
+ text: qsTr("OK")
+ onClicked: {
+ root.font = content.font
+ root.accept()
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/imports/dialogs/DefaultMessageDialog.qml b/src/imports/dialogs/DefaultMessageDialog.qml
new file mode 100644
index 0000000000..5dbe727f68
--- /dev/null
+++ b/src/imports/dialogs/DefaultMessageDialog.qml
@@ -0,0 +1,310 @@
+/*****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs module 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 Digia Plc and its Subsidiary(-ies) 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.1
+import QtQuick.Window 2.1
+import QtQuick.Dialogs 1.1
+import "qml"
+
+AbstractMessageDialog {
+ id: root
+
+ Rectangle {
+ id: content
+ property real spacing: 8
+ property real outerSpacing: 12
+ property int maxSize: 0.9 * Math.min(Screen.desktopAvailableWidth, Screen.desktopAvailableHeight)
+ implicitHeight: contentColumn.implicitHeight + outerSpacing * 2
+ onImplicitHeightChanged: root.height = implicitHeight
+ implicitWidth: Math.min(maxSize, Math.max(
+ mainText.implicitWidth, buttons.implicitWidth) + outerSpacing * 2);
+ onImplicitWidthChanged: if (implicitWidth > root.width) root.width = implicitWidth
+ color: palette.window
+ focus: true
+ Keys.onEscapePressed: root.reject()
+ Keys.onEnterPressed: root.accept()
+ Keys.onReturnPressed: root.accept()
+ Keys.onPressed: if (event.modifiers === Qt.ControlModifier)
+ switch (event.key) {
+ case Qt.Key_A:
+ detailedText.selectAll();
+ break;
+ case Qt.Key_C:
+ detailedText.copy();
+ break;
+ }
+
+ Column {
+ id: contentColumn
+ spacing: content.spacing
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ margins: content.outerSpacing
+ }
+
+ SystemPalette { id: palette }
+
+ Item {
+ width: parent.width
+ height: Math.max(icon.height, mainText.height + informativeText.height + content.spacing)
+ Image {
+ id: icon
+ source: root.standardIconSource
+ }
+
+ Text {
+ id: mainText
+ anchors {
+ left: icon.right
+ leftMargin: content.spacing
+ right: parent.right
+ }
+ text: root.text
+ font.weight: Font.Bold
+ wrapMode: Text.WordWrap
+ }
+
+ Text {
+ id: informativeText
+ anchors {
+ left: icon.right
+ right: parent.right
+ top: mainText.bottom
+ leftMargin: content.spacing
+ topMargin: content.spacing
+ }
+ text: root.informativeText
+ wrapMode: Text.WordWrap
+ }
+ }
+
+
+ Row {
+ id: buttons
+ spacing: content.spacing
+ layoutDirection: Qt.RightToLeft
+ width: parent.width
+ Button {
+ id: okButton
+ text: "OK"
+ onClicked: root.click(Message.Ok)
+ visible: root.standardButtons & Message.Ok
+ }
+ Button {
+ id: openButton
+ text: "Open"
+ onClicked: root.click(Message.Open)
+ visible: root.standardButtons & Message.Open
+ }
+ Button {
+ id: saveButton
+ text: "Save"
+ onClicked: root.click(Message.Save)
+ visible: root.standardButtons & Message.Save
+ }
+ Button {
+ id: saveAllButton
+ text: "Save All"
+ onClicked: root.click(Message.SaveAll)
+ visible: root.standardButtons & Message.SaveAll
+ }
+ Button {
+ id: retryButton
+ text: "Retry"
+ onClicked: root.click(Message.Retry)
+ visible: root.standardButtons & Message.Retry
+ }
+ Button {
+ id: ignoreButton
+ text: "Ignore"
+ onClicked: root.click(Message.Ignore)
+ visible: root.standardButtons & Message.Ignore
+ }
+ Button {
+ id: applyButton
+ text: "Apply"
+ onClicked: root.click(Message.Apply)
+ visible: root.standardButtons & Message.Apply
+ }
+ Button {
+ id: yesButton
+ text: "Yes"
+ onClicked: root.click(Message.Yes)
+ visible: root.standardButtons & Message.Yes
+ }
+ Button {
+ id: yesAllButton
+ text: "Yes to All"
+ onClicked: root.click(Message.YesToAll)
+ visible: root.standardButtons & Message.YesToAll
+ }
+ Button {
+ id: noButton
+ text: "No"
+ onClicked: root.click(Message.No)
+ visible: root.standardButtons & Message.No
+ }
+ Button {
+ id: noAllButton
+ text: "No to All"
+ onClicked: root.click(Message.NoToAll)
+ visible: root.standardButtons & Message.NoToAll
+ }
+ Button {
+ id: discardButton
+ text: "Discard"
+ onClicked: root.click(Message.Discard)
+ visible: root.standardButtons & Message.Discard
+ }
+ Button {
+ id: resetButton
+ text: "Reset"
+ onClicked: root.click(Message.Reset)
+ visible: root.standardButtons & Message.Reset
+ }
+ Button {
+ id: restoreDefaultsButton
+ text: "Restore Defaults"
+ onClicked: root.click(Message.RestoreDefaults)
+ visible: root.standardButtons & Message.RestoreDefaults
+ }
+ Button {
+ id: cancelButton
+ text: "Cancel"
+ onClicked: root.click(Message.Cancel)
+ visible: root.standardButtons & Message.Cancel
+ }
+ Button {
+ id: abortButton
+ text: "Abort"
+ onClicked: root.click(Message.Abort)
+ visible: root.standardButtons & Message.Abort
+ }
+ Button {
+ id: closeButton
+ text: "Close"
+ onClicked: root.click(Message.Close)
+ visible: root.standardButtons & Message.Close
+ }
+ Button {
+ id: moreButton
+ text: "Show Details..."
+ onClicked: content.state = (content.state === "" ? "expanded" : "")
+ visible: root.detailedText.length > 0
+ }
+ Button {
+ id: helpButton
+ text: "Help"
+ onClicked: root.click(Message.Help)
+ visible: root.standardButtons & Message.Help
+ }
+ }
+ }
+
+ Item {
+ id: details
+ width: parent.width
+ implicitHeight: detailedText.implicitHeight + content.spacing
+ height: 0
+ clip: true
+
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: contentColumn.bottom
+ topMargin: content.spacing
+ leftMargin: content.outerSpacing
+ rightMargin: content.outerSpacing
+ }
+
+ Flickable {
+ id: flickable
+ contentHeight: detailedText.height
+ anchors.fill: parent
+ anchors.topMargin: content.spacing
+ anchors.bottomMargin: content.outerSpacing
+ TextEdit {
+ id: detailedText
+ text: root.detailedText
+ width: details.width
+ wrapMode: Text.WordWrap
+ readOnly: true
+ selectByMouse: true
+ }
+ }
+
+ Component {
+ id: edgeFade
+ EdgeFade {
+ fadeColor: palette.window
+ topThreshold: flickable.atYBeginning ? 0 : content.spacing * 3
+ bottomThreshold: flickable.atYEnd ? 0 : content.spacing * 3
+ }
+ }
+
+ Loader {
+ sourceComponent: flickable.height < flickable.contentHeight ? edgeFade : undefined
+ anchors.fill: parent
+ }
+
+ }
+
+ states: [
+ State {
+ name: "expanded"
+ PropertyChanges {
+ target: details
+ height: content.height - contentColumn.height - content.spacing - content.outerSpacing
+ }
+ PropertyChanges {
+ target: content
+ implicitHeight: contentColumn.implicitHeight + content.spacing * 2 +
+ detailedText.implicitHeight + content.outerSpacing * 2
+ }
+ PropertyChanges {
+ target: moreButton
+ text: "Hide Details"
+ }
+ }
+ ]
+ }
+}
diff --git a/src/imports/dialogs/WidgetFontDialog.qml b/src/imports/dialogs/WidgetFontDialog.qml
new file mode 100644
index 0000000000..69f98b28a2
--- /dev/null
+++ b/src/imports/dialogs/WidgetFontDialog.qml
@@ -0,0 +1,44 @@
+/*****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs module 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 Digia Plc and its Subsidiary(-ies) 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 QtQuick.PrivateWidgets 1.1
+
+QtFontDialog { }
diff --git a/src/imports/dialogs/WidgetMessageDialog.qml b/src/imports/dialogs/WidgetMessageDialog.qml
new file mode 100644
index 0000000000..8bc3eccfd7
--- /dev/null
+++ b/src/imports/dialogs/WidgetMessageDialog.qml
@@ -0,0 +1,44 @@
+/*****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs module 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 Digia Plc and its Subsidiary(-ies) 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.1
+import QtQuick.PrivateWidgets 1.1
+
+QtMessageDialog { }
diff --git a/src/imports/dialogs/dialogs.pro b/src/imports/dialogs/dialogs.pro
index e745d52e2b..8db3d9ab58 100644
--- a/src/imports/dialogs/dialogs.pro
+++ b/src/imports/dialogs/dialogs.pro
@@ -1,40 +1,64 @@
CXX_MODULE = qml
TARGET = dialogplugin
TARGETPATH = QtQuick/Dialogs
-IMPORT_VERSION = 1.0
+IMPORT_VERSION = 1.1
QMAKE_DOCS = $$PWD/doc/qtquickdialogs.qdocconf
SOURCES += \
+ qquickabstractmessagedialog.cpp \
+ qquickplatformmessagedialog.cpp \
+ qquickmessagedialog.cpp \
qquickabstractfiledialog.cpp \
qquickplatformfiledialog.cpp \
qquickfiledialog.cpp \
qquickabstractcolordialog.cpp \
qquickplatformcolordialog.cpp \
qquickcolordialog.cpp \
+ qquickabstractfontdialog.cpp \
+ qquickplatformfontdialog.cpp \
+ qquickfontdialog.cpp \
qquickabstractdialog.cpp \
plugin.cpp
HEADERS += \
+ qquickabstractmessagedialog_p.h \
+ qquickplatformmessagedialog_p.h \
+ qquickmessagedialog_p.h \
+ qquickmessageattached_p.h \
qquickabstractfiledialog_p.h \
qquickplatformfiledialog_p.h \
qquickfiledialog_p.h \
qquickabstractcolordialog_p.h \
qquickplatformcolordialog_p.h \
qquickcolordialog_p.h \
+ qquickabstractfontdialog_p.h \
+ qquickplatformfontdialog_p.h \
+ qquickfontdialog_p.h \
qquickabstractdialog_p.h
QML_FILES += \
+ DefaultMessageDialog.qml \
+ WidgetMessageDialog.qml \
DefaultFileDialog.qml \
WidgetFileDialog.qml \
DefaultColorDialog.qml \
WidgetColorDialog.qml \
+ DefaultFontDialog.qml \
+ WidgetFontDialog.qml \
qml/Button.qml \
+ qml/CheckBox.qml \
qml/ColorSlider.qml \
+ qml/EdgeFade.qml \
qml/DefaultWindowDecoration.qml \
qml/TextField.qml \
qml/qmldir \
+ images/critical.png \
+ images/information.png \
+ images/question.png \
+ images/warning.png \
images/checkers.png \
+ images/checkmark.png \
images/copy.png \
images/crosshairs.png \
images/slider_handle.png \
@@ -43,6 +67,6 @@ QML_FILES += \
images/folder.png \
images/up.png
-QT += quick-private gui-private core-private
+QT += quick-private gui gui-private core core-private qml
load(qml_plugin)
diff --git a/src/imports/dialogs/images/checkmark.png b/src/imports/dialogs/images/checkmark.png
new file mode 100644
index 0000000000..821aafccdd
--- /dev/null
+++ b/src/imports/dialogs/images/checkmark.png
Binary files differ
diff --git a/src/imports/dialogs/images/critical.png b/src/imports/dialogs/images/critical.png
new file mode 100644
index 0000000000..dc9c5aebf4
--- /dev/null
+++ b/src/imports/dialogs/images/critical.png
Binary files differ
diff --git a/src/imports/dialogs/images/information.png b/src/imports/dialogs/images/information.png
new file mode 100644
index 0000000000..0a2eb87d10
--- /dev/null
+++ b/src/imports/dialogs/images/information.png
Binary files differ
diff --git a/src/imports/dialogs/images/question.png b/src/imports/dialogs/images/question.png
new file mode 100644
index 0000000000..2dd92fd791
--- /dev/null
+++ b/src/imports/dialogs/images/question.png
Binary files differ
diff --git a/src/imports/dialogs/images/warning.png b/src/imports/dialogs/images/warning.png
new file mode 100644
index 0000000000..cba78f6bea
--- /dev/null
+++ b/src/imports/dialogs/images/warning.png
Binary files differ
diff --git a/src/imports/dialogs/plugin.cpp b/src/imports/dialogs/plugin.cpp
index 249152c48c..e62e4efa34 100644
--- a/src/imports/dialogs/plugin.cpp
+++ b/src/imports/dialogs/plugin.cpp
@@ -41,12 +41,19 @@
#include <QtQml/qqml.h>
#include <QtQml/qqmlextensionplugin.h>
+#include "qquickmessagedialog_p.h"
+#include "qquickabstractmessagedialog_p.h"
+#include "qquickmessageattached_p.h"
+#include "qquickplatformmessagedialog_p.h"
#include "qquickfiledialog_p.h"
#include "qquickabstractfiledialog_p.h"
#include "qquickplatformfiledialog_p.h"
#include "qquickcolordialog_p.h"
#include "qquickabstractcolordialog_p.h"
#include "qquickplatformcolordialog_p.h"
+#include "qquickfontdialog_p.h"
+#include "qquickabstractfontdialog_p.h"
+#include "qquickplatformfontdialog_p.h"
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
@@ -65,7 +72,7 @@ QT_BEGIN_NAMESPACE
To use the types in this module, import the module with the following line:
\code
- import QtQuick.Dialogs 1.0
+ import QtQuick.Dialogs 1.1
\endcode
*/
@@ -98,6 +105,15 @@ public:
// possible to instantiate it from Qt Quick.
// Otherwise fall back to a pure-QML implementation.
+ // MessageDialog
+ qmlRegisterUncreatableType<QQuickMessageAttached>(uri, 1, 1, "Message", QQuickMessageAttached::tr("Message can only be used via the attached property."));
+#ifndef PURE_QML_ONLY
+ if (QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::MessageDialog))
+ qmlRegisterType<QQuickPlatformMessageDialog>(uri, 1, 0, "MessageDialog");
+ else
+#endif
+ registerWidgetOrQmlImplementation<QQuickMessageDialog>(widgetsDir, qmlDir, "MessageDialog", uri, hasTopLevelWindows, 1, 1);
+
// FileDialog
#ifndef PURE_QML_ONLY
if (QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog))
@@ -113,6 +129,14 @@ public:
else
#endif
registerWidgetOrQmlImplementation<QQuickColorDialog>(widgetsDir, qmlDir, "ColorDialog", uri, hasTopLevelWindows, 1, 0);
+
+ // FontDialog
+#ifndef PURE_QML_ONLY
+ if (QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FontDialog))
+ qmlRegisterType<QQuickPlatformFontDialog>(uri, 1, 1, "FontDialog");
+ else
+#endif
+ registerWidgetOrQmlImplementation<QQuickFontDialog>(widgetsDir, qmlDir, "FontDialog", uri, hasTopLevelWindows, 1, 1);
}
protected:
@@ -122,7 +146,10 @@ protected:
//qDebug() << Q_FUNC_INFO << qmlDir << qmlName << uri;
bool needQml = true;
-#ifndef PURE_QML_ONLY
+#ifdef PURE_QML_ONLY
+ Q_UNUSED(widgetsDir)
+ Q_UNUSED(hasTopLevelWindows)
+#else
// If there is a qmldir and we have a QApplication instance (as opposed to a
// widget-free QGuiApplication), assume that the widget-based dialog will work.
if (hasTopLevelWindows && widgetsDir.exists("qmldir") &&
diff --git a/src/imports/dialogs/plugins.qmltypes b/src/imports/dialogs/plugins.qmltypes
index 4e7090b960..c52d355cad 100644
--- a/src/imports/dialogs/plugins.qmltypes
+++ b/src/imports/dialogs/plugins.qmltypes
@@ -11,6 +11,11 @@ Module {
prototype: "QQuickAbstractDialog"
Property { name: "showAlphaChannel"; type: "bool" }
Property { name: "color"; type: "QColor" }
+ Property { name: "currentColor"; type: "QColor" }
+ Property { name: "currentHue"; type: "double"; isReadonly: true }
+ Property { name: "currentSaturation"; type: "double"; isReadonly: true }
+ Property { name: "currentLightness"; type: "double"; isReadonly: true }
+ Property { name: "currentAlpha"; type: "double"; isReadonly: true }
Signal { name: "selectionAccepted" }
Method {
name: "setVisible"
@@ -29,6 +34,10 @@ Module {
Parameter { name: "arg"; type: "QColor" }
}
Method {
+ name: "setCurrentColor"
+ Parameter { name: "currentColor"; type: "QColor" }
+ }
+ Method {
name: "setShowAlphaChannel"
Parameter { name: "arg"; type: "bool" }
}
@@ -50,6 +59,22 @@ Module {
Signal { name: "rejected" }
Method { name: "open" }
Method { name: "close" }
+ Method {
+ name: "setX"
+ Parameter { name: "arg"; type: "int" }
+ }
+ Method {
+ name: "setY"
+ Parameter { name: "arg"; type: "int" }
+ }
+ Method {
+ name: "setWidth"
+ Parameter { name: "arg"; type: "int" }
+ }
+ Method {
+ name: "setHeight"
+ Parameter { name: "arg"; type: "int" }
+ }
}
Component {
name: "QQuickAbstractFileDialog"
@@ -99,25 +124,15 @@ Module {
}
}
Component {
- name: "QQuickColorDialog"
- defaultProperty: "implementation"
+ name: "QQuickPlatformColorDialog"
prototype: "QQuickAbstractColorDialog"
- exports: ["QtQuick.Dialogs/AbstractColorDialog 1.0"]
+ exports: ["QtQuick.Dialogs/ColorDialog 1.0"]
exportMetaObjectRevisions: [0]
- Property { name: "implementation"; type: "QObject"; isPointer: true }
}
Component {
- name: "QQuickFileDialog"
- defaultProperty: "implementation"
+ name: "QQuickPlatformFileDialog"
prototype: "QQuickAbstractFileDialog"
- exports: ["QtQuick.Dialogs/AbstractFileDialog 1.0"]
+ exports: ["QtQuick.Dialogs/FileDialog 1.0"]
exportMetaObjectRevisions: [0]
- Property { name: "implementation"; type: "QObject"; isPointer: true }
- Method { name: "clearSelection" }
- Method {
- name: "addSelection"
- type: "bool"
- Parameter { name: "path"; type: "QUrl" }
- }
}
}
diff --git a/src/imports/dialogs/qml/Button.qml b/src/imports/dialogs/qml/Button.qml
index 26cc23a5be..19ed073484 100644
--- a/src/imports/dialogs/qml/Button.qml
+++ b/src/imports/dialogs/qml/Button.qml
@@ -50,7 +50,7 @@ Item {
property alias containsMouse: mouseArea.containsMouse
property alias pressed: mouseArea.pressed
implicitHeight: Math.max(Screen.logicalPixelDensity * 7, buttonLabel.implicitHeight * 1.2)
- implicitWidth: Math.max(Screen.logicalPixelDensity * 11, buttonLabel.implicitWidth * 1.3)
+ implicitWidth: visible ? Math.max(Screen.logicalPixelDensity * 11, buttonLabel.implicitWidth * 1.3) : 0
height: implicitHeight
width: implicitWidth
diff --git a/src/imports/dialogs/qml/CheckBox.qml b/src/imports/dialogs/qml/CheckBox.qml
new file mode 100644
index 0000000000..32b0e6ff70
--- /dev/null
+++ b/src/imports/dialogs/qml/CheckBox.qml
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs module 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 Digia Plc and its Subsidiary(-ies) 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.1
+
+Item {
+ id: root
+ implicitHeight: frame.height
+ implicitWidth: row.implicitWidth
+ width: implicitWidth
+ height: implicitHeight
+ property alias text: label.text
+ property bool checked
+ property alias pressed: mouseArea.pressed
+ signal clicked
+
+ SystemPalette { id: palette }
+
+ Row {
+ id: row
+ anchors.verticalCenter: parent.verticalCenter
+ spacing: 6
+ Rectangle {
+ id: frame
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: mouseArea.pressed ? Qt.darker(palette.button, 1.3) : palette.button }
+ GradientStop { position: 1.0; color: Qt.darker(palette.button, 1.3) }
+ }
+ height: label.implicitHeight * 1.5
+ width: height
+ anchors.margins: 1
+ radius: 3
+ antialiasing: true
+ border.color: Qt.darker(palette.button, 1.5)
+ Image {
+ id: theX
+ source: "../images/checkmark.png"
+ anchors.fill: frame
+ anchors.margins: frame.width / 5
+ fillMode: Image.PreserveAspectFit
+ smooth: true
+ visible: checked
+ }
+ }
+ Text {
+ id: label
+ color: palette.text
+ anchors.verticalCenter: frame.verticalCenter
+ }
+ }
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: {
+ parent.checked = !parent.checked
+ parent.clicked()
+ }
+ }
+}
diff --git a/src/imports/dialogs/qml/EdgeFade.qml b/src/imports/dialogs/qml/EdgeFade.qml
new file mode 100644
index 0000000000..376aa151e6
--- /dev/null
+++ b/src/imports/dialogs/qml/EdgeFade.qml
@@ -0,0 +1,63 @@
+/*****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs module 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 Digia Plc and its Subsidiary(-ies) 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.1
+
+ShaderEffect {
+ property color fadeColor
+ property real topThreshold: 10
+ property real bottomThreshold: 10
+ property real _topRatio: topThreshold / height
+ property real _bottomRatio: bottomThreshold / height
+ z: 1
+ fragmentShader: "
+ varying lowp vec2 qt_TexCoord0;
+ uniform lowp vec4 fadeColor;
+ uniform highp float _topRatio;
+ uniform highp float _bottomRatio;
+
+ void main() {
+ highp float bottomEnd = 1. - _bottomRatio;
+ gl_FragColor = fadeColor *
+ (qt_TexCoord0.y < _topRatio ? 1. - qt_TexCoord0.y / _topRatio :
+ (qt_TexCoord0.y > bottomEnd ? (qt_TexCoord0.y - bottomEnd) / _bottomRatio : 0.));
+ }
+ "
+}
diff --git a/src/imports/dialogs/qml/qmldir b/src/imports/dialogs/qml/qmldir
index c475502cf1..9d273b1c4b 100644
--- a/src/imports/dialogs/qml/qmldir
+++ b/src/imports/dialogs/qml/qmldir
@@ -1,3 +1,5 @@
Button 1.0 Button.qml
+CheckBox 1.1 CheckBox.qml
ColorSlider 1.0 ColorSlider.qml
+EdgeFade 1.0 EdgeFade.qml
TextField 1.0 TextField.qml
diff --git a/src/imports/dialogs/qquickabstractcolordialog.cpp b/src/imports/dialogs/qquickabstractcolordialog.cpp
index d565352af6..abac997ca6 100644
--- a/src/imports/dialogs/qquickabstractcolordialog.cpp
+++ b/src/imports/dialogs/qquickabstractcolordialog.cpp
@@ -109,6 +109,15 @@ void QQuickAbstractColorDialog::setColor(QColor arg)
m_color = arg;
emit colorChanged();
}
+ setCurrentColor(arg);
+}
+
+void QQuickAbstractColorDialog::setCurrentColor(QColor currentColor)
+{
+ if (m_currentColor != currentColor) {
+ m_currentColor = currentColor;
+ emit currentColorChanged();
+ }
}
void QQuickAbstractColorDialog::setShowAlphaChannel(bool arg)
diff --git a/src/imports/dialogs/qquickabstractcolordialog_p.h b/src/imports/dialogs/qquickabstractcolordialog_p.h
index bd23e0d1a4..ad2c7ce1ed 100644
--- a/src/imports/dialogs/qquickabstractcolordialog_p.h
+++ b/src/imports/dialogs/qquickabstractcolordialog_p.h
@@ -66,10 +66,11 @@ class QQuickAbstractColorDialog : public QQuickAbstractDialog
Q_OBJECT
Q_PROPERTY(bool showAlphaChannel READ showAlphaChannel WRITE setShowAlphaChannel NOTIFY showAlphaChannelChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
- Q_PROPERTY(qreal hue READ hue NOTIFY colorChanged)
- Q_PROPERTY(qreal saturation READ saturation NOTIFY colorChanged)
- Q_PROPERTY(qreal lightness READ lightness NOTIFY colorChanged)
- Q_PROPERTY(qreal alpha READ alpha NOTIFY colorChanged)
+ Q_PROPERTY(QColor currentColor READ currentColor WRITE setCurrentColor NOTIFY currentColorChanged)
+ Q_PROPERTY(qreal currentHue READ currentHue NOTIFY currentColorChanged)
+ Q_PROPERTY(qreal currentSaturation READ currentSaturation NOTIFY currentColorChanged)
+ Q_PROPERTY(qreal currentLightness READ currentLightness NOTIFY currentColorChanged)
+ Q_PROPERTY(qreal currentAlpha READ currentAlpha NOTIFY currentColorChanged)
public:
QQuickAbstractColorDialog(QObject *parent = 0);
@@ -78,27 +79,31 @@ public:
virtual QString title() const;
bool showAlphaChannel() const;
QColor color() const { return m_color; }
- qreal hue() const { return m_color.hslHueF(); }
- qreal saturation() const { return m_color.hslSaturationF(); }
- qreal lightness() const { return m_color.lightnessF(); }
- qreal alpha() const { return m_color.alphaF(); }
+ QColor currentColor() const { return m_currentColor; }
+ qreal currentHue() const { return m_currentColor.hslHueF(); }
+ qreal currentSaturation() const { return m_currentColor.hslSaturationF(); }
+ qreal currentLightness() const { return m_currentColor.lightnessF(); }
+ qreal currentAlpha() const { return m_currentColor.alphaF(); }
public Q_SLOTS:
void setVisible(bool v);
void setModality(Qt::WindowModality m);
void setTitle(const QString &t);
void setColor(QColor arg);
+ void setCurrentColor(QColor currentColor);
void setShowAlphaChannel(bool arg);
Q_SIGNALS:
void showAlphaChannelChanged();
void colorChanged();
+ void currentColorChanged();
void selectionAccepted();
protected:
QPlatformColorDialogHelper *m_dlgHelper;
QSharedPointer<QColorDialogOptions> m_options;
QColor m_color;
+ QColor m_currentColor;
Q_DISABLE_COPY(QQuickAbstractColorDialog)
};
diff --git a/src/imports/dialogs/qquickabstractdialog.cpp b/src/imports/dialogs/qquickabstractdialog.cpp
index 560cbaf3e0..17f8d1aef2 100644
--- a/src/imports/dialogs/qquickabstractdialog.cpp
+++ b/src/imports/dialogs/qquickabstractdialog.cpp
@@ -63,6 +63,7 @@ QQuickAbstractDialog::QQuickAbstractDialog(QObject *parent)
, m_windowDecoration(0)
, m_hasNativeWindows(QGuiApplicationPrivate::platformIntegration()->
hasCapability(QPlatformIntegration::MultipleWindows))
+ , m_hasAspiredPosition(false)
{
}
@@ -124,8 +125,24 @@ void QQuickAbstractDialog::setVisible(bool v)
}
}
}
- if (m_dialogWindow)
+ if (m_dialogWindow) {
+ // "grow up" to the size and position expected to achieve
+ if (!m_sizeAspiration.isNull()) {
+ if (m_hasAspiredPosition)
+ m_dialogWindow->setGeometry(m_sizeAspiration);
+ else {
+ if (m_sizeAspiration.width() > 0)
+ m_dialogWindow->setWidth(m_sizeAspiration.width());
+ if (m_sizeAspiration.height() > 0)
+ m_dialogWindow->setHeight(m_sizeAspiration.height());
+ }
+ }
connect(m_dialogWindow, SIGNAL(visibleChanged(bool)), this, SLOT(visibleChanged(bool)));
+ connect(m_dialogWindow, SIGNAL(xChanged(int)), this, SLOT(setX(int)));
+ connect(m_dialogWindow, SIGNAL(yChanged(int)), this, SLOT(setY(int)));
+ connect(m_dialogWindow, SIGNAL(widthChanged(int)), this, SLOT(setWidth(int)));
+ connect(m_dialogWindow, SIGNAL(heightChanged(int)), this, SLOT(setHeight(int)));
+ }
}
if (m_windowDecoration) {
m_windowDecoration->setVisible(v);
@@ -230,66 +247,84 @@ int QQuickAbstractDialog::x() const
{
if (m_dialogWindow)
return m_dialogWindow->x();
- return -1;
+ return m_sizeAspiration.x();
}
int QQuickAbstractDialog::y() const
{
if (m_dialogWindow)
return m_dialogWindow->y();
- return -1;
+ return m_sizeAspiration.y();
}
int QQuickAbstractDialog::width() const
{
if (m_dialogWindow)
return m_dialogWindow->width();
- return -1;
+ return m_sizeAspiration.width();
}
int QQuickAbstractDialog::height() const
{
if (m_dialogWindow)
return m_dialogWindow->height();
- return -1;
+ return m_sizeAspiration.height();
}
void QQuickAbstractDialog::setX(int arg)
{
+ m_hasAspiredPosition = true;
+ m_sizeAspiration.setX(arg);
if (helper()) {
// TODO
} else if (m_dialogWindow) {
- m_dialogWindow->setX(arg);
+ if (sender() != m_dialogWindow)
+ m_dialogWindow->setX(arg);
+ } else if (m_contentItem) {
+ m_contentItem->setX(arg);
}
emit geometryChanged();
}
void QQuickAbstractDialog::setY(int arg)
{
+ m_hasAspiredPosition = true;
+ m_sizeAspiration.setY(arg);
if (helper()) {
// TODO
} else if (m_dialogWindow) {
- m_dialogWindow->setY(arg);
+ if (sender() != m_dialogWindow)
+ m_dialogWindow->setY(arg);
+ } else if (m_contentItem) {
+ m_contentItem->setY(arg);
}
emit geometryChanged();
}
void QQuickAbstractDialog::setWidth(int arg)
{
+ m_sizeAspiration.setWidth(arg);
if (helper()) {
// TODO
} else if (m_dialogWindow) {
- m_dialogWindow->setWidth(arg);
+ if (sender() != m_dialogWindow)
+ m_dialogWindow->setWidth(arg);
+ } else if (m_contentItem) {
+ m_contentItem->setWidth(arg);
}
emit geometryChanged();
}
void QQuickAbstractDialog::setHeight(int arg)
{
+ m_sizeAspiration.setHeight(arg);
if (helper()) {
// TODO
} else if (m_dialogWindow) {
- m_dialogWindow->setHeight(arg);
+ if (sender() != m_dialogWindow)
+ m_dialogWindow->setHeight(arg);
+ } else if (m_contentItem) {
+ m_contentItem->setHeight(arg);
}
emit geometryChanged();
}
diff --git a/src/imports/dialogs/qquickabstractdialog_p.h b/src/imports/dialogs/qquickabstractdialog_p.h
index 5e3d9b43f7..8ffa166c5b 100644
--- a/src/imports/dialogs/qquickabstractdialog_p.h
+++ b/src/imports/dialogs/qquickabstractdialog_p.h
@@ -91,14 +91,14 @@ public:
virtual void setTitle(const QString &t) = 0;
void setQmlImplementation(QObject* obj);
bool isWindow() const { return m_hasNativeWindows; }
- void setX(int arg);
- void setY(int arg);
- void setWidth(int arg);
- void setHeight(int arg);
public Q_SLOTS:
void open() { setVisible(true); }
void close() { setVisible(false); }
+ void setX(int arg);
+ void setY(int arg);
+ void setWidth(int arg);
+ void setHeight(int arg);
Q_SIGNALS:
void visibilityChanged();
@@ -110,8 +110,8 @@ Q_SIGNALS:
protected Q_SLOTS:
void decorationLoaded();
- void accept();
- void reject();
+ virtual void accept();
+ virtual void reject();
void visibleChanged(bool v);
void windowGeometryChanged();
@@ -130,6 +130,8 @@ protected: // variables for pure-QML implementations only
QQuickItem *m_contentItem;
QQuickItem *m_windowDecoration;
bool m_hasNativeWindows;
+ QRect m_sizeAspiration;
+ bool m_hasAspiredPosition;
static QQmlComponent *m_decorationComponent;
diff --git a/src/imports/dialogs/qquickabstractfontdialog.cpp b/src/imports/dialogs/qquickabstractfontdialog.cpp
new file mode 100644
index 0000000000..29dd15e8cc
--- /dev/null
+++ b/src/imports/dialogs/qquickabstractfontdialog.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickabstractfontdialog_p.h"
+#include "qquickitem.h"
+
+#include <private/qguiapplication_p.h>
+#include <QWindow>
+#include <QQuickWindow>
+
+QT_BEGIN_NAMESPACE
+
+QQuickAbstractFontDialog::QQuickAbstractFontDialog(QObject *parent)
+ : QQuickAbstractDialog(parent)
+ , m_dlgHelper(0)
+ , m_options(QSharedPointer<QFontDialogOptions>(new QFontDialogOptions()))
+{
+ // On the Mac, modality doesn't work unless you call exec(). But this is a reasonable default anyway.
+ m_modality = Qt::NonModal;
+ connect(this, SIGNAL(accepted()), this, SIGNAL(selectionAccepted()));
+}
+
+QQuickAbstractFontDialog::~QQuickAbstractFontDialog()
+{
+}
+
+void QQuickAbstractFontDialog::setVisible(bool v)
+{
+ if (helper() && v) {
+ m_dlgHelper->setOptions(m_options);
+ // Due to the fact that QFontDialogOptions doesn't have currentFont...
+ m_dlgHelper->setCurrentFont(m_font);
+ }
+ QQuickAbstractDialog::setVisible(v);
+}
+
+void QQuickAbstractFontDialog::setModality(Qt::WindowModality m)
+{
+#ifdef Q_OS_MAC
+ // On the Mac, modality doesn't work unless you call exec()
+ m_modality = Qt::NonModal;
+ emit modalityChanged();
+ return;
+#endif
+ QQuickAbstractDialog::setModality(m);
+}
+
+QString QQuickAbstractFontDialog::title() const
+{
+ return m_options->windowTitle();
+}
+
+bool QQuickAbstractFontDialog::scalableFonts() const
+{
+ return m_options->testOption(QFontDialogOptions::ScalableFonts);
+}
+
+bool QQuickAbstractFontDialog::nonScalableFonts() const
+{
+ return m_options->testOption(QFontDialogOptions::NonScalableFonts);
+}
+
+bool QQuickAbstractFontDialog::monospacedFonts() const
+{
+ return m_options->testOption(QFontDialogOptions::MonospacedFonts);
+}
+
+bool QQuickAbstractFontDialog::proportionalFonts() const
+{
+ return m_options->testOption(QFontDialogOptions::ProportionalFonts);
+}
+
+void QQuickAbstractFontDialog::setTitle(const QString &t)
+{
+ if (m_options->windowTitle() == t) return;
+ m_options->setWindowTitle(t);
+ emit titleChanged();
+}
+
+void QQuickAbstractFontDialog::setFont(const QFont &arg)
+{
+ if (m_font != arg) {
+ m_font = arg;
+ emit fontChanged();
+ }
+}
+
+void QQuickAbstractFontDialog::setScalableFonts(bool arg)
+{
+ m_options->setOption(QFontDialogOptions::ScalableFonts, arg);
+ emit scalableFontsChanged();
+}
+
+void QQuickAbstractFontDialog::setNonScalableFonts(bool arg)
+{
+ m_options->setOption(QFontDialogOptions::NonScalableFonts, arg);
+ emit nonScalableFontsChanged();
+}
+
+void QQuickAbstractFontDialog::setMonospacedFonts(bool arg)
+{
+ m_options->setOption(QFontDialogOptions::MonospacedFonts, arg);
+ emit monospacedFontsChanged();
+}
+
+void QQuickAbstractFontDialog::setProportionalFonts(bool arg)
+{
+ m_options->setOption(QFontDialogOptions::ProportionalFonts, arg);
+ emit proportionalFontsChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickabstractfontdialog_p.h b/src/imports/dialogs/qquickabstractfontdialog_p.h
new file mode 100644
index 0000000000..858a0d3eac
--- /dev/null
+++ b/src/imports/dialogs/qquickabstractfontdialog_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKABSTRACTFONTDIALOG_P_H
+#define QQUICKABSTRACTFONTDIALOG_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 <QtQml>
+#include <QQuickView>
+#include <QtGui/qpa/qplatformdialoghelper.h>
+#include <QtGui/qfont.h>
+#include <qpa/qplatformtheme.h>
+#include "qquickabstractdialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickAbstractFontDialog : public QQuickAbstractDialog
+{
+ Q_OBJECT
+ Q_PROPERTY(bool scalableFonts READ scalableFonts WRITE setScalableFonts NOTIFY scalableFontsChanged)
+ Q_PROPERTY(bool nonScalableFonts READ nonScalableFonts WRITE setNonScalableFonts NOTIFY nonScalableFontsChanged)
+ Q_PROPERTY(bool monospacedFonts READ monospacedFonts WRITE setMonospacedFonts NOTIFY monospacedFontsChanged)
+ Q_PROPERTY(bool proportionalFonts READ proportionalFonts WRITE setProportionalFonts NOTIFY proportionalFontsChanged)
+ Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
+
+public:
+ QQuickAbstractFontDialog(QObject *parent = 0);
+ virtual ~QQuickAbstractFontDialog();
+
+ virtual QString title() const;
+ bool scalableFonts() const;
+ bool nonScalableFonts() const;
+ bool monospacedFonts() const;
+ bool proportionalFonts() const;
+ QFont font() const { return m_font; }
+
+public Q_SLOTS:
+ void setVisible(bool v);
+ void setModality(Qt::WindowModality m);
+ void setTitle(const QString &t);
+ void setFont(const QFont &arg);
+ void setScalableFonts(bool arg);
+ void setNonScalableFonts(bool arg);
+ void setMonospacedFonts(bool arg);
+ void setProportionalFonts(bool arg);
+
+Q_SIGNALS:
+ void scalableFontsChanged();
+ void nonScalableFontsChanged();
+ void monospacedFontsChanged();
+ void proportionalFontsChanged();
+ void fontChanged();
+ void selectionAccepted();
+
+protected:
+ QPlatformFontDialogHelper *m_dlgHelper;
+ QSharedPointer<QFontDialogOptions> m_options;
+ QFont m_font;
+
+ Q_DISABLE_COPY(QQuickAbstractFontDialog)
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKABSTRACTFONTDIALOG_P_H
diff --git a/src/imports/dialogs/qquickabstractmessagedialog.cpp b/src/imports/dialogs/qquickabstractmessagedialog.cpp
new file mode 100644
index 0000000000..cfcf056e6c
--- /dev/null
+++ b/src/imports/dialogs/qquickabstractmessagedialog.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickabstractmessagedialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QQuickAbstractMessageDialog::QQuickAbstractMessageDialog(QObject *parent)
+ : QQuickAbstractDialog(parent)
+ , m_dlgHelper(0)
+ , m_options(QSharedPointer<QMessageDialogOptions>(new QMessageDialogOptions()))
+ , m_clickedButton(NoButton)
+{
+}
+
+QQuickAbstractMessageDialog::~QQuickAbstractMessageDialog()
+{
+}
+
+void QQuickAbstractMessageDialog::setVisible(bool v)
+{
+ if (helper() && v)
+ m_dlgHelper->setOptions(m_options);
+ if (v)
+ m_clickedButton = NoButton;
+ QQuickAbstractDialog::setVisible(v);
+}
+
+void QQuickAbstractMessageDialog::setTitle(const QString &arg)
+{
+ if (arg != m_options->windowTitle()) {
+ m_options->setWindowTitle(arg);
+ emit titleChanged();
+ }
+}
+
+void QQuickAbstractMessageDialog::setText(const QString &arg)
+{
+ if (arg != m_options->text()) {
+ m_options->setText(arg);
+ emit textChanged();
+ }
+}
+
+void QQuickAbstractMessageDialog::setInformativeText(const QString &arg)
+{
+ if (arg != m_options->informativeText()) {
+ m_options->setInformativeText(arg);
+ emit informativeTextChanged();
+ }
+}
+
+void QQuickAbstractMessageDialog::setDetailedText(const QString &arg)
+{
+ if (arg != m_options->detailedText()) {
+ m_options->setDetailedText(arg);
+ emit detailedTextChanged();
+ }
+}
+
+void QQuickAbstractMessageDialog::setIcon(QQuickAbstractMessageDialog::Icon icon)
+{
+ if (static_cast<int>(icon) != static_cast<int>(m_options->icon())) {
+ m_options->setIcon(static_cast<QMessageDialogOptions::Icon>(icon));
+ emit iconChanged();
+ }
+}
+
+QUrl QQuickAbstractMessageDialog::standardIconSource()
+{
+ switch (m_options->icon()) {
+ case QMessageDialogOptions::Information:
+ return QUrl("images/information.png");
+ break;
+ case QMessageDialogOptions::Warning:
+ return QUrl("images/warning.png");
+ break;
+ case QMessageDialogOptions::Critical:
+ return QUrl("images/critical.png");
+ break;
+ case QMessageDialogOptions::Question:
+ return QUrl("images/question.png");
+ break;
+ default:
+ return QUrl();
+ break;
+ }
+}
+
+void QQuickAbstractMessageDialog::setStandardButtons(StandardButtons buttons)
+{
+ if (buttons != m_options->standardButtons()) {
+ m_options->setStandardButtons(static_cast<QMessageDialogOptions::StandardButtons>(static_cast<int>(buttons)));
+ emit standardButtonsChanged();
+ }
+}
+
+void QQuickAbstractMessageDialog::click(QQuickAbstractMessageDialog::StandardButton button)
+{
+ m_clickedButton = button;
+ emit buttonClicked();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickabstractmessagedialog_p.h b/src/imports/dialogs/qquickabstractmessagedialog_p.h
new file mode 100644
index 0000000000..3f1b842a96
--- /dev/null
+++ b/src/imports/dialogs/qquickabstractmessagedialog_p.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKABSTRACTMESSAGEDIALOG_P_H
+#define QQUICKABSTRACTMESSAGEDIALOG_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 <QtQml>
+#include <QQuickView>
+#include <QtGui/qpa/qplatformdialoghelper.h>
+#include <qpa/qplatformtheme.h>
+#include "qquickabstractdialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickAbstractMessageDialog : public QQuickAbstractDialog
+{
+ Q_OBJECT
+
+ Q_ENUMS(Icon)
+ Q_ENUMS(StandardButton)
+ Q_FLAGS(StandardButtons)
+
+ Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+ Q_PROPERTY(QString informativeText READ informativeText WRITE setInformativeText NOTIFY informativeTextChanged)
+ Q_PROPERTY(QString detailedText READ detailedText WRITE setDetailedText NOTIFY detailedTextChanged)
+ Q_PROPERTY(Icon icon READ icon WRITE setIcon NOTIFY iconChanged)
+ Q_PROPERTY(QUrl standardIconSource READ standardIconSource NOTIFY iconChanged)
+ Q_PROPERTY(StandardButtons standardButtons READ standardButtons WRITE setStandardButtons NOTIFY standardButtonsChanged)
+ Q_PROPERTY(StandardButton clickedButton READ clickedButton NOTIFY buttonClicked)
+
+public:
+ QQuickAbstractMessageDialog(QObject *parent = 0);
+ virtual ~QQuickAbstractMessageDialog();
+
+ virtual QString title() const { return m_options->windowTitle(); }
+ QString text() const { return m_options->text(); }
+ QString informativeText() const { return m_options->informativeText(); }
+ QString detailedText() const { return m_options->detailedText(); }
+
+ enum Icon {
+ NoIcon = QMessageDialogOptions::NoIcon,
+ Information = QMessageDialogOptions::Information,
+ Warning = QMessageDialogOptions::Warning,
+ Critical = QMessageDialogOptions::Critical,
+ Question = QMessageDialogOptions::Question
+ };
+
+ Icon icon() const { return static_cast<Icon>(m_options->icon()); }
+
+ QUrl standardIconSource();
+
+ enum StandardButton {
+ NoButton = QMessageDialogOptions::NoButton,
+ Ok = QMessageDialogOptions::Ok,
+ Save = QMessageDialogOptions::Save,
+ SaveAll = QMessageDialogOptions::SaveAll,
+ Open = QMessageDialogOptions::Open,
+ Yes = QMessageDialogOptions::Yes,
+ YesToAll = QMessageDialogOptions::YesToAll,
+ No = QMessageDialogOptions::No,
+ NoToAll = QMessageDialogOptions::NoToAll,
+ Abort = QMessageDialogOptions::Abort,
+ Retry = QMessageDialogOptions::Retry,
+ Ignore = QMessageDialogOptions::Ignore,
+ Close = QMessageDialogOptions::Close,
+ Cancel = QMessageDialogOptions::Cancel,
+ Discard = QMessageDialogOptions::Discard,
+ Help = QMessageDialogOptions::Help,
+ Apply = QMessageDialogOptions::Apply,
+ Reset = QMessageDialogOptions::Reset,
+ RestoreDefaults = QMessageDialogOptions::RestoreDefaults
+ };
+ Q_DECLARE_FLAGS(StandardButtons, StandardButton)
+
+ StandardButtons standardButtons() const { return static_cast<StandardButtons>(static_cast<int>(m_options->standardButtons())); }
+
+ StandardButton clickedButton() const { return m_clickedButton; }
+
+public Q_SLOTS:
+ virtual void setVisible(bool v);
+ virtual void setTitle(const QString &arg);
+ void setText(const QString &arg);
+ void setInformativeText(const QString &arg);
+ void setDetailedText(const QString &arg);
+ void setIcon(Icon icon);
+ void setStandardButtons(StandardButtons buttons);
+ void click(StandardButton button);
+
+Q_SIGNALS:
+ void textChanged();
+ void informativeTextChanged();
+ void detailedTextChanged();
+ void iconChanged();
+ void standardButtonsChanged();
+ void buttonClicked();
+ void discard();
+ void help();
+ void yes();
+ void no();
+ void apply();
+ void reset();
+
+protected:
+ QPlatformMessageDialogHelper *m_dlgHelper;
+ QSharedPointer<QMessageDialogOptions> m_options;
+ StandardButton m_clickedButton;
+
+ Q_DISABLE_COPY(QQuickAbstractMessageDialog)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickAbstractMessageDialog::StandardButtons)
+
+QT_END_NAMESPACE
+
+#endif // QQUICKABSTRACTMESSAGEDIALOG_P_H
diff --git a/src/imports/dialogs/qquickfiledialog_p.h b/src/imports/dialogs/qquickfiledialog_p.h
index 0176bc3fe4..a4c7939fda 100644
--- a/src/imports/dialogs/qquickfiledialog_p.h
+++ b/src/imports/dialogs/qquickfiledialog_p.h
@@ -68,7 +68,7 @@ public:
~QQuickFileDialog();
virtual QList<QUrl> fileUrls();
-signals:
+Q_SIGNALS:
public Q_SLOTS:
void clearSelection();
diff --git a/src/imports/dialogs/qquickfontdialog.cpp b/src/imports/dialogs/qquickfontdialog.cpp
new file mode 100644
index 0000000000..2f3c6d83bb
--- /dev/null
+++ b/src/imports/dialogs/qquickfontdialog.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickfontdialog_p.h"
+#include <QQuickItem>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype AbstractFontDialog
+ \instantiates QQuickFontDialog
+ \inqmlmodule QtQuick.Dialogs 1
+ \ingroup qtquick-visual
+ \brief API wrapper for QML font dialog implementations
+ \since 5.2
+ \internal
+
+ AbstractFontDialog provides only the API for implementing a font dialog.
+ The implementation (e.g. a Window or preferably an Item, in case it is
+ shown on a device that doesn't support multiple windows) can be provided as
+ \l implementation, which is the default property (the only allowed child
+ element).
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::AbstractFontDialog::accepted
+
+ The \a accepted signal is emitted by \l accept().
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::AbstractFontDialog::rejected
+
+ The \a accepted signal is emitted by \l reject().
+*/
+
+/*!
+ \class QQuickFontDialog
+ \inmodule QtQuick.Dialogs
+ \internal
+
+ The QQuickFontDialog class is a concrete subclass of \l
+ QQuickAbstractFontDialog, but it is abstract from the QML perspective
+ because it needs to enclose a graphical implementation. It exists in order
+ to provide accessors and helper functions which the QML implementation will
+ need.
+
+ \since 5.2
+*/
+
+/*!
+ Constructs a font dialog wrapper with parent window \a parent.
+*/
+QQuickFontDialog::QQuickFontDialog(QObject *parent)
+ : QQuickAbstractFontDialog(parent)
+{
+}
+
+
+/*!
+ Destroys the font dialog wrapper.
+*/
+QQuickFontDialog::~QQuickFontDialog()
+{
+}
+
+/*!
+ \qmlproperty bool AbstractFontDialog::visible
+
+ This property holds whether the dialog is visible. By default this is false.
+*/
+
+/*!
+ \qmlproperty QObject AbstractFontDialog::implementation
+
+ The QML object which implements the actual font dialog. Should be either a
+ \l Window or an \l Item.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickfontdialog_p.h b/src/imports/dialogs/qquickfontdialog_p.h
new file mode 100644
index 0000000000..a8e2d82e6f
--- /dev/null
+++ b/src/imports/dialogs/qquickfontdialog_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKFONTDIALOG_P_H
+#define QQUICKFONTDIALOG_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 "qquickabstractfontdialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickFontDialog : public QQuickAbstractFontDialog
+{
+ Q_OBJECT
+ Q_PROPERTY(QObject* implementation READ qmlImplementation WRITE setQmlImplementation DESIGNABLE false)
+ Q_CLASSINFO("DefaultProperty", "implementation")
+
+public:
+ explicit QQuickFontDialog(QObject *parent = 0);
+ ~QQuickFontDialog();
+
+protected:
+ virtual QPlatformFontDialogHelper *helper() { return 0; }
+
+ Q_DISABLE_COPY(QQuickFontDialog)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickFontDialog *)
+
+#endif // QQUICKFONTDIALOG_P_H
diff --git a/src/imports/dialogs/qquickmessageattached_p.h b/src/imports/dialogs/qquickmessageattached_p.h
new file mode 100644
index 0000000000..c1cb94ae36
--- /dev/null
+++ b/src/imports/dialogs/qquickmessageattached_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKMESSAGEATTACHED_H
+#define QQUICKMESSAGEATTACHED_H
+
+#include <private/qtquickglobal_p.h>
+#include <QtGui/qpa/qplatformdialoghelper.h>
+#include "qquickabstractmessagedialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_DECL_EXPORT QQuickMessageAttached : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(QQuickAbstractMessageDialog::Icon)
+ Q_ENUMS(QQuickAbstractMessageDialog::StandardButton)
+
+public:
+ static QQuickMessageAttached *qmlAttachedProperties(QObject *obj) {
+ return new QQuickMessageAttached(obj); }
+
+ QQuickMessageAttached(QObject *parent = 0) : QObject(parent) { }
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickMessageAttached)
+QML_DECLARE_TYPEINFO(QQuickMessageAttached, QML_HAS_ATTACHED_PROPERTIES)
+
+#endif // QQUICKMESSAGEATTACHED_H
diff --git a/src/imports/dialogs/qquickmessagedialog.cpp b/src/imports/dialogs/qquickmessagedialog.cpp
new file mode 100644
index 0000000000..43b6ca09b4
--- /dev/null
+++ b/src/imports/dialogs/qquickmessagedialog.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickmessagedialog_p.h"
+#include <QQuickItem>
+#include <private/qguiapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype AbstractMessageDialog
+ \instantiates QQuickMessageDialog
+ \inqmlmodule QtQuick.Dialogs 1
+ \ingroup qtquick-visual
+ \brief API wrapper for QML message dialog implementations
+ \since 5.2
+ \internal
+
+ AbstractMessageDialog provides only the API for implementing a message dialog.
+ The implementation (e.g. a Window or preferably an Item, in case it is
+ shown on a device that doesn't support multiple windows) can be provided as
+ \l implementation, which is the default property (the only allowed child
+ element).
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::AbstractMessageDialog::accepted
+
+ This signal is emitted by \l accept().
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::AbstractMessageDialog::rejected
+
+ This signal is emitted by \l reject().
+*/
+
+/*!
+ \class QQuickMessageDialog
+ \inmodule QtQuick.Dialogs
+ \internal
+
+ The QQuickMessageDialog class is a concrete subclass of
+ \l QQuickAbstractMessageDialog, but it is abstract from the QML perspective
+ because it needs to enclose a graphical implementation. It exists in order
+ to provide accessors and helper functions which the QML implementation will
+ need.
+
+ \since 5.2
+*/
+
+/*!
+ Constructs a message dialog wrapper with parent window \a parent.
+*/
+QQuickMessageDialog::QQuickMessageDialog(QObject *parent)
+ : QQuickAbstractMessageDialog(parent)
+{
+ connect(this, SIGNAL(buttonClicked()), this, SLOT(clicked()));
+}
+
+
+/*!
+ Destroys the message dialog wrapper.
+*/
+QQuickMessageDialog::~QQuickMessageDialog()
+{
+}
+
+/*!
+ \qmlproperty bool AbstractMessageDialog::visible
+
+ This property holds whether the dialog is visible. By default this is false.
+*/
+
+/*!
+ \qmlproperty QObject AbstractMessageDialog::implementation
+
+ The QML object which implements the actual message dialog. Should be either a
+ \l Window or an \l Item.
+*/
+
+
+void QQuickMessageDialog::clicked() {
+ switch (m_clickedButton) {
+ // This mapping from buttons to roles is the same as
+ // documented for enum QMessageBox::StandardButton
+ case Ok:
+ case Open:
+ case Save:
+ case SaveAll:
+ case Retry:
+ case Ignore:
+ accept();
+ break;
+ case Cancel:
+ case Close:
+ case Abort:
+ reject();
+ break;
+ case Discard:
+ emit discard();
+ close();
+ break;
+ case Help:
+ emit help();
+ break;
+ case Yes:
+ case YesToAll:
+ emit yes();
+ close();
+ break;
+ case No:
+ case NoToAll:
+ emit no();
+ close();
+ break;
+ case Apply:
+ emit apply();
+ break;
+ case Reset:
+ case RestoreDefaults:
+ emit reset();
+ break;
+ default:
+ qWarning("StandardButton %d has no role", m_clickedButton);
+ }
+}
+
+void QQuickMessageDialog::accept() {
+ // enter key is treated like OK
+ if (m_clickedButton == NoButton)
+ m_clickedButton = Ok;
+ QQuickAbstractMessageDialog::accept();
+}
+
+void QQuickMessageDialog::reject() {
+ // escape key is treated like cancel
+ if (m_clickedButton == NoButton)
+ m_clickedButton = Cancel;
+ QQuickAbstractMessageDialog::reject();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickmessagedialog_p.h b/src/imports/dialogs/qquickmessagedialog_p.h
new file mode 100644
index 0000000000..b21d8cba42
--- /dev/null
+++ b/src/imports/dialogs/qquickmessagedialog_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKMESSAGEDIALOG_P_H
+#define QQUICKMESSAGEDIALOG_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 "qquickabstractmessagedialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickMessageDialog : public QQuickAbstractMessageDialog
+{
+ Q_OBJECT
+ Q_PROPERTY(QObject* implementation READ qmlImplementation WRITE setQmlImplementation DESIGNABLE false)
+ Q_CLASSINFO("DefaultProperty", "implementation") // AbstractMessageDialog in QML can have only one child
+
+public:
+ explicit QQuickMessageDialog(QObject *parent = 0);
+ ~QQuickMessageDialog();
+
+protected:
+ virtual QPlatformDialogHelper *helper() { return 0; }
+
+protected Q_SLOTS:
+ virtual void accept();
+ virtual void reject();
+ void clicked();
+
+private:
+ Q_DISABLE_COPY(QQuickMessageDialog)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickMessageDialog *)
+
+#endif // QQUICKMESSAGEDIALOG_P_H
diff --git a/src/imports/dialogs/qquickplatformcolordialog.cpp b/src/imports/dialogs/qquickplatformcolordialog.cpp
index 8dc6d09f2c..9de9b7a553 100644
--- a/src/imports/dialogs/qquickplatformcolordialog.cpp
+++ b/src/imports/dialogs/qquickplatformcolordialog.cpp
@@ -166,7 +166,7 @@ QPlatformColorDialogHelper *QQuickPlatformColorDialog::helper()
return m_dlgHelper;
connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
- connect(m_dlgHelper, SIGNAL(currentColorChanged(QColor)), this, SLOT(setColor(QColor)));
+ connect(m_dlgHelper, SIGNAL(currentColorChanged(QColor)), this, SLOT(setCurrentColor(QColor)));
connect(m_dlgHelper, SIGNAL(colorSelected(QColor)), this, SLOT(setColor(QColor)));
}
@@ -232,6 +232,23 @@ QPlatformColorDialogHelper *QQuickPlatformColorDialog::helper()
\qmlproperty color ColorDialog::color
The color which the user selected.
+
+ \note This color is not always the same as the color held by the
+ currentColor property since the user can choose different colors before
+ finally selecting the one to use.
+
+ \sa currentColor
+*/
+
+/*!
+ \qmlproperty color ColorDialog::currentColor
+
+ The color which the user has currently selected.
+
+ For the color that is set when the dialog is accepted, use the \l color
+ property.
+
+ \sa color
*/
QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickplatformfontdialog.cpp b/src/imports/dialogs/qquickplatformfontdialog.cpp
new file mode 100644
index 0000000000..8b2e0e0501
--- /dev/null
+++ b/src/imports/dialogs/qquickplatformfontdialog.cpp
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickplatformfontdialog_p.h"
+#include "qquickitem.h"
+
+#include <private/qguiapplication_p.h>
+#include <QWindow>
+#include <QQuickView>
+#include <QQuickWindow>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype FontDialog
+ \instantiates QQuickPlatformFontDialog
+ \inqmlmodule QtQuick.Dialogs 1
+ \ingroup qtquick-visual
+ \brief Dialog component for choosing a font.
+ \since 5.2
+
+ FontDialog allows the user to select a font. The dialog is initially
+ invisible. You need to set the properties as desired first, then set
+ \l visible to true or call \l open().
+
+ Here is a minimal example to open a font dialog and exit after the user
+ chooses a font:
+
+ \qml
+ import QtQuick 2.2
+ import QtQuick.Dialogs 1.1
+
+ FontDialog {
+ id: fontDialog
+ title: "Please choose a font"
+ font: Qt.font({ family: "Arial", pointSize: 24, weight: Font.Normal })
+ onAccepted: {
+ console.log("You chose: " + fontDialog.font)
+ Qt.quit()
+ }
+ onRejected: {
+ console.log("Canceled")
+ Qt.quit()
+ }
+ Component.onCompleted: visible = true
+ }
+ \endqml
+
+ A FontDialog window is automatically transient for its parent window. So
+ whether you declare the dialog inside an \l Item or inside a \l Window, the
+ dialog will appear centered over the window containing the item, or over
+ the Window that you declared.
+
+ The implementation of FontDialog will be a platform font dialog if
+ possible. If that isn't possible, then it will try to instantiate a
+ \l QFontDialog. If that also isn't possible, then it will fall back to a QML
+ implementation, DefaultFontDialog.qml. In that case you can customize the
+ appearance by editing this file. DefaultFontDialog.qml contains a Rectangle
+ to hold the dialog's contents, because certain embedded systems do not
+ support multiple top-level windows. When the dialog becomes visible, it
+ will automatically be wrapped in a Window if possible, or simply reparented
+ on top of the main window if there can only be one window.
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::FontDialog::accepted
+
+ The \a accepted signal is emitted when the user has finished using the
+ dialog. You can then inspect the \a font property to get the selection.
+
+ Example:
+
+ \qml
+ FontDialog {
+ onAccepted: { console.log("Selected font: " + font) }
+ }
+ \endqml
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::FontDialog::rejected
+
+ The \a rejected signal is emitted when the user has dismissed the dialog,
+ either by closing the dialog window or by pressing the Cancel button.
+*/
+
+/*!
+ \class QQuickPlatformFontDialog
+ \inmodule QtQuick.Dialogs
+ \internal
+
+ \brief The QQuickPlatformFontDialog class provides a font dialog
+
+ The dialog is implemented via the QQuickPlatformFontDialogHelper when possible;
+ otherwise it falls back to a QFontDialog or a QML implementation.
+
+ \since 5.2
+*/
+
+/*!
+ Constructs a file dialog with parent window \a parent.
+*/
+QQuickPlatformFontDialog::QQuickPlatformFontDialog(QObject *parent) :
+ QQuickAbstractFontDialog(parent)
+{
+}
+
+/*!
+ Destroys the file dialog.
+*/
+QQuickPlatformFontDialog::~QQuickPlatformFontDialog()
+{
+ if (m_dlgHelper)
+ m_dlgHelper->hide();
+ delete m_dlgHelper;
+}
+
+QPlatformFontDialogHelper *QQuickPlatformFontDialog::helper()
+{
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ if (parentItem)
+ m_parentWindow = parentItem->window();
+
+ if ( !m_dlgHelper && QGuiApplicationPrivate::platformTheme()->
+ usePlatformNativeDialog(QPlatformTheme::FontDialog) ) {
+ m_dlgHelper = static_cast<QPlatformFontDialogHelper *>(QGuiApplicationPrivate::platformTheme()
+ ->createPlatformDialogHelper(QPlatformTheme::FontDialog));
+ if (!m_dlgHelper)
+ return m_dlgHelper;
+ connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
+ connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
+ connect(m_dlgHelper, SIGNAL(currentFontChanged(const QFont&)), this, SLOT(setFont(const QFont&)));
+ connect(m_dlgHelper, SIGNAL(fontSelected(const QFont&)), this, SLOT(setFont(const QFont&)));
+ }
+
+ return m_dlgHelper;
+}
+
+/*!
+ \qmlproperty bool FontDialog::visible
+
+ This property holds whether the dialog is visible. By default this is
+ false.
+
+ \sa modality
+*/
+
+/*!
+ \qmlproperty Qt::WindowModality FontDialog::modality
+
+ Whether the dialog should be shown modal with respect to the window
+ containing the dialog's parent Item, modal with respect to the whole
+ application, or non-modal.
+
+ By default it is \l WindowModal.
+
+ Modality does not mean that there are any blocking calls to wait for the
+ dialog to be accepted or rejected; it's only that the user will be
+ prevented from interacting with the parent window and/or the application
+ windows at the same time. You probably need to write an onAccepted handler
+ to actually load or save the chosen file.
+*/
+
+/*!
+ \qmlmethod void FontDialog::open()
+
+ Shows the dialog to the user. It is equivalent to setting \l visible to
+ true.
+*/
+
+/*!
+ \qmlmethod void FontDialog::close()
+
+ Closes the dialog.
+*/
+
+/*!
+ \qmlproperty string FontDialog::title
+
+ The title of the dialog window.
+*/
+
+/*!
+ \qmlproperty bool FontDialog::scalableFonts
+
+ Whether the dialog will show scalable fonts or not.
+*/
+
+/*!
+ \qmlproperty bool FontDialog::nonScalableFonts
+
+ Whether the dialog will show non scalable fonts or not.
+*/
+
+/*!
+ \qmlproperty bool FontDialog::monospacedFonts
+
+ Whether the dialog will show monospaced fonts or not.
+*/
+
+/*!
+ \qmlproperty bool FontDialog::proportionalFonts
+
+ Whether the dialog will show proportional fonts or not.
+*/
+
+/*!
+ \qmlproperty font FontDialog::font
+
+ The font which the user selected.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickplatformfontdialog_p.h b/src/imports/dialogs/qquickplatformfontdialog_p.h
new file mode 100644
index 0000000000..743b24ad87
--- /dev/null
+++ b/src/imports/dialogs/qquickplatformfontdialog_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPLATFORMFONTDIALOG_P_H
+#define QQUICKPLATFORMFONTDIALOG_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 "qquickabstractfontdialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPlatformFontDialog : public QQuickAbstractFontDialog
+{
+ Q_OBJECT
+
+public:
+ QQuickPlatformFontDialog(QObject *parent = 0);
+ virtual ~QQuickPlatformFontDialog();
+
+protected:
+ QPlatformFontDialogHelper *helper();
+
+ Q_DISABLE_COPY(QQuickPlatformFontDialog)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPlatformFontDialog *)
+
+#endif // QQUICKPLATFORMFONTDIALOG_P_H
diff --git a/src/imports/dialogs/qquickplatformmessagedialog.cpp b/src/imports/dialogs/qquickplatformmessagedialog.cpp
new file mode 100644
index 0000000000..0e21212711
--- /dev/null
+++ b/src/imports/dialogs/qquickplatformmessagedialog.cpp
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickplatformmessagedialog_p.h"
+#include "qquickitem.h"
+
+#include <private/qguiapplication_p.h>
+#include <QWindow>
+#include <QQuickView>
+#include <QQuickWindow>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype MessageDialog
+ \instantiates QQuickPlatformMessageDialog
+ \inqmlmodule QtQuick.Dialogs 1
+ \ingroup dialogs
+ \brief Dialog component for displaying popup messages.
+ \since Qt 5.2
+
+ The most basic use case for a MessageDialog is a popup alert. It also
+ allows the user to respond in various ways depending on which buttons are
+ enabled. The dialog is initially invisible. You need to set the properties
+ as desired first, then set \l visible to true or call \l open().
+
+ Here is a minimal example to show an alert and exit after the user
+ responds:
+
+ \qml
+ import QtQuick 2.2
+ import QtQuick.Dialogs 1.1
+
+ MessageDialog {
+ id: messageDialog
+ title: "May I have your attention please"
+ text: "It's so cool that you are using Qt Quick."
+ onAccepted: {
+ console.log("And of course you could only agree.")
+ Qt.quit()
+ }
+ Component.onCompleted: visible = true
+ }
+ \endqml
+
+ A MessageDialog window is automatically transient for its parent window. So
+ whether you declare the dialog inside an \l Item or inside a \l Window, the
+ dialog will appear centered over the window containing the item, or over
+ the Window that you declared.
+
+ The implementation of MessageDialog will be a platform message dialog if
+ possible. If that isn't possible, then it will try to instantiate a
+ \l QMessageBox. If that also isn't possible, then it will fall back to a QML
+ implementation, DefaultMessageDialog.qml. In that case you can customize the
+ appearance by editing this file. DefaultMessageDialog.qml contains a Rectangle
+ to hold the dialog's contents, because certain embedded systems do not
+ support multiple top-level windows. When the dialog becomes visible, it
+ will automatically be wrapped in a Window if possible, or simply reparented
+ on top of the main window if there can only be one window.
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::MessageDialog::accepted
+
+ This handler is called when the user has pressed OK.
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::MessageDialog::rejected
+
+ This handler is called when the user has dismissed the dialog,
+ either by closing the dialog window or by pressing the Cancel button.
+*/
+
+/*!
+ \class QQuickPlatformMessageDialog
+ \inmodule QtQuick.Dialogs
+ \internal
+
+ \brief The QQuickPlatformMessageDialog class provides a message dialog
+
+ The dialog is implemented via the QPlatformMessageDialogHelper when possible;
+ otherwise it falls back to a QMessageBox or a QML implementation.
+
+ \since 5.2
+*/
+
+/*!
+ Constructs a file dialog with parent window \a parent.
+*/
+QQuickPlatformMessageDialog::QQuickPlatformMessageDialog(QObject *parent) :
+ QQuickAbstractMessageDialog(parent)
+{
+}
+
+/*!
+ Destroys the file dialog.
+*/
+QQuickPlatformMessageDialog::~QQuickPlatformMessageDialog()
+{
+ if (m_dlgHelper)
+ m_dlgHelper->hide();
+ delete m_dlgHelper;
+}
+
+QPlatformMessageDialogHelper *QQuickPlatformMessageDialog::helper()
+{
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ if (parentItem)
+ m_parentWindow = parentItem->window();
+
+ if ( !m_dlgHelper && QGuiApplicationPrivate::platformTheme()->
+ usePlatformNativeDialog(QPlatformTheme::MessageDialog) ) {
+ m_dlgHelper = static_cast<QPlatformMessageDialogHelper *>(QGuiApplicationPrivate::platformTheme()
+ ->createPlatformDialogHelper(QPlatformTheme::MessageDialog));
+ if (!m_dlgHelper)
+ return m_dlgHelper;
+ connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
+ connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
+ }
+
+ return m_dlgHelper;
+}
+
+/*!
+ \qmlproperty bool MessageDialog::visible
+
+ This property holds whether the dialog is visible. By default this is
+ false.
+
+ \sa modality
+*/
+
+/*!
+ \qmlproperty Qt::WindowModality MessageDialog::modality
+
+ Whether the dialog should be shown modal with respect to the window
+ containing the dialog's parent Item, modal with respect to the whole
+ application, or non-modal.
+
+ By default it is \c Qt.WindowModal.
+
+ Modality does not mean that there are any blocking calls to wait for the
+ dialog to be accepted or rejected; it's only that the user will be
+ prevented from interacting with the parent window and/or the application
+ windows at the same time.
+*/
+
+/*!
+ \qmlmethod void MessageDialog::open()
+
+ Shows the dialog to the user. It is equivalent to setting \l visible to
+ true.
+*/
+
+/*!
+ \qmlmethod void MessageDialog::close()
+
+ Closes the dialog.
+*/
+
+/*!
+ \qmlproperty string MessageDialog::title
+
+ The title of the dialog window.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickplatformmessagedialog_p.h b/src/imports/dialogs/qquickplatformmessagedialog_p.h
new file mode 100644
index 0000000000..61f055bb38
--- /dev/null
+++ b/src/imports/dialogs/qquickplatformmessagedialog_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPLATFORMMESSAGEDIALOG_P_H
+#define QQUICKPLATFORMMESSAGEDIALOG_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 "qquickabstractmessagedialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPlatformMessageDialog : public QQuickAbstractMessageDialog
+{
+ Q_OBJECT
+
+public:
+ QQuickPlatformMessageDialog(QObject *parent = 0);
+ virtual ~QQuickPlatformMessageDialog();
+
+protected:
+ QPlatformMessageDialogHelper *helper();
+
+ Q_DISABLE_COPY(QQuickPlatformMessageDialog)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPlatformMessageDialog *)
+
+#endif // QQUICKPLATFORMMESSAGEDIALOG_P_H
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index 5bc5d61eb7..3f15755211 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -11,6 +11,7 @@ qtHaveModule(quick) {
qtquick2 \
particles \
window \
+ dialogs-private \
dialogs \
testlib
}
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 405acd0f7c..246ddd96c5 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -65,14 +65,14 @@
using namespace QV4;
#define V4THROW_SQL(error, desc) { \
- Value v = Value::fromString(ctx, desc); \
- Object *ex = ctx->engine->newErrorObject(v); \
+ QV4::Scoped<String> v(scope, Value::fromString(ctx, desc)); \
+ QV4::Scoped<Object> ex(scope, ctx->engine->newErrorObject(v.asValue())); \
ex->put(ctx->engine->newIdentifier(QStringLiteral("code")), Value::fromInt32(error)); \
- ctx->throwError(Value::fromObject(ex)); \
+ ctx->throwError(ex); \
}
#define V4THROW_REFERENCE(string) { \
- Value v = Value::fromString(ctx, string); \
+ QV4::Scoped<String> v(scope, Value::fromString(ctx, string)); \
ctx->throwReferenceError(v); \
}
@@ -105,7 +105,7 @@ public:
~QQmlSqlDatabaseWrapper() {
}
- static Value getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void destroy(Managed *that) {
static_cast<QQmlSqlDatabaseWrapper *>(that)->~QQmlSqlDatabaseWrapper();
}
@@ -124,17 +124,21 @@ public:
DEFINE_MANAGED_VTABLE(QQmlSqlDatabaseWrapper);
-static Value qmlsqldatabase_version(SimpleCallContext *ctx)
+static ReturnedValue qmlsqldatabase_version(SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
+
QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
if (!r || r->type != QQmlSqlDatabaseWrapper::Database)
V4THROW_REFERENCE("Not a SQLDatabase object");
- return Value::fromString(ctx->engine->newString(r->version));
+ return Value::fromString(ctx->engine->newString(r->version)).asReturnedValue();
}
-static Value qmlsqldatabase_rows_length(SimpleCallContext *ctx)
+static ReturnedValue qmlsqldatabase_rows_length(SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
+
QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
if (!r || r->type != QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
@@ -148,19 +152,23 @@ static Value qmlsqldatabase_rows_length(SimpleCallContext *ctx)
s = 0;
}
}
- return Value::fromInt32(s);
+ return Encode(s);
}
-static Value qmlsqldatabase_rows_forwardOnly(SimpleCallContext *ctx)
+static ReturnedValue qmlsqldatabase_rows_forwardOnly(SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
+
QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
if (!r || r->type != QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
- return Value::fromBoolean(r->sqlQuery.isForwardOnly());
+ return Encode(r->sqlQuery.isForwardOnly());
}
-static Value qmlsqldatabase_rows_setForwardOnly(SimpleCallContext *ctx)
+static ReturnedValue qmlsqldatabase_rows_setForwardOnly(SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
+
QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
if (!r || r->type != QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
@@ -168,7 +176,7 @@ static Value qmlsqldatabase_rows_setForwardOnly(SimpleCallContext *ctx)
ctx->throwTypeError();
r->sqlQuery.setForwardOnly(ctx->arguments[0].toBoolean());
- return Value::undefinedValue();
+ return Encode::undefined();
}
QQmlSqlDatabaseData::~QQmlSqlDatabaseData()
@@ -191,7 +199,7 @@ static QString qmlsqldatabase_databaseFile(const QString& connectionName, QV8Eng
return qmlsqldatabase_databasesPath(engine) + QDir::separator() + connectionName;
}
-static Value qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, ExecutionEngine *v4, quint32 index, bool *hasProperty = 0)
+static ReturnedValue qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, ExecutionEngine *v4, quint32 index, bool *hasProperty = 0)
{
QV8Engine *v8 = v4->v8Engine;
@@ -204,20 +212,20 @@ static Value qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, ExecutionEngin
if (v.isNull()) {
row->put(v4->newIdentifier(record.fieldName(ii)), Value::nullValue());
} else {
- row->put(v4->newIdentifier(record.fieldName(ii)), v8->fromVariant(v));
+ row->put(v4->newIdentifier(record.fieldName(ii)), Value::fromReturnedValue(v8->fromVariant(v)));
}
}
if (hasProperty)
*hasProperty = true;
- return Value::fromObject(row);
+ return Value::fromObject(row).asReturnedValue();
} else {
if (hasProperty)
*hasProperty = false;
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
}
-Value QQmlSqlDatabaseWrapper::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue QQmlSqlDatabaseWrapper::getIndexed(Managed *m, uint index, bool *hasProperty)
{
QQmlSqlDatabaseWrapper *r = m->as<QQmlSqlDatabaseWrapper>();
if (!r || r->type != QQmlSqlDatabaseWrapper::Rows)
@@ -226,8 +234,9 @@ Value QQmlSqlDatabaseWrapper::getIndexed(Managed *m, uint index, bool *hasProper
return qmlsqldatabase_rows_index(r, m->engine(), index, hasProperty);
}
-static Value qmlsqldatabase_rows_item(SimpleCallContext *ctx)
+static ReturnedValue qmlsqldatabase_rows_item(SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
if (!r || r->type != QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
@@ -235,8 +244,9 @@ static Value qmlsqldatabase_rows_item(SimpleCallContext *ctx)
return qmlsqldatabase_rows_index(r, ctx->engine, ctx->argumentCount ? ctx->arguments[0].toUInt32() : 0);
}
-static Value qmlsqldatabase_executeSql(SimpleCallContext *ctx)
+static ReturnedValue qmlsqldatabase_executeSql(SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
if (!r || r->type != QQmlSqlDatabaseWrapper::Query)
V4THROW_REFERENCE("Not a SQLDatabase::Query object");
@@ -248,7 +258,7 @@ static Value qmlsqldatabase_executeSql(SimpleCallContext *ctx)
QSqlDatabase db = r->database;
- QString sql = ctx->argument(0).toQString();
+ QString sql = ctx->argument(0).toQStringNoThrow();
if (r->readonly && !sql.startsWith(QLatin1String("SELECT"),Qt::CaseInsensitive)) {
V4THROW_SQL(SQLEXCEPTION_SYNTAX_ERR, QQmlEngine::tr("Read-only Transaction"));
@@ -257,7 +267,7 @@ static Value qmlsqldatabase_executeSql(SimpleCallContext *ctx)
QSqlQuery query(db);
bool err = false;
- Value result = Value::undefinedValue();
+ ScopedValue result(scope, Value::undefinedValue());
if (query.prepare(sql)) {
if (ctx->argumentCount > 1) {
@@ -265,20 +275,21 @@ static Value qmlsqldatabase_executeSql(SimpleCallContext *ctx)
if (ArrayObject *array = values.asArrayObject()) {
quint32 size = array->arrayLength();
for (quint32 ii = 0; ii < size; ++ii)
- query.bindValue(ii, engine->toVariant(array->getIndexed(ii), -1));
+ query.bindValue(ii, engine->toVariant(QV4::Value::fromReturnedValue(array->getIndexed(ii)), -1));
} else if (Object *object = values.asObject()) {
ObjectIterator it(object, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly);
+ ScopedValue key(scope);
while (1) {
Value value;
- Value key = it.nextPropertyName(&value);
- if (key.isNull())
+ key = it.nextPropertyName(&value);
+ if (key->isNull())
break;
QVariant v = engine->toVariant(value, -1);
- if (key.isString()) {
- query.bindValue(key.stringValue()->toQString(), v);
+ if (key->isString()) {
+ query.bindValue(key->stringValue()->toQString(), v);
} else {
- assert(key.isInteger());
- query.bindValue(key.integerValue(), v);
+ assert(key->isInteger());
+ query.bindValue(key->integerValue(), v);
}
}
} else {
@@ -307,13 +318,15 @@ static Value qmlsqldatabase_executeSql(SimpleCallContext *ctx)
if (err)
V4THROW_SQL(SQLEXCEPTION_DATABASE_ERR,query.lastError().text());
- return result;
+ return result.asReturnedValue();
}
-static Value qmlsqldatabase_changeVersion(SimpleCallContext *ctx)
+static ReturnedValue qmlsqldatabase_changeVersion(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 2)
- return Value::undefinedValue();
+ return Encode::undefined();
+
+ Scope scope(ctx);
QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
if (!r || r->type != QQmlSqlDatabaseWrapper::Database)
@@ -322,8 +335,8 @@ static Value qmlsqldatabase_changeVersion(SimpleCallContext *ctx)
QV8Engine *engine = ctx->engine->v8Engine;
QSqlDatabase db = r->database;
- QString from_version = ctx->arguments[0].toQString();
- QString to_version = ctx->arguments[1].toQString();
+ QString from_version = ctx->arguments[0].toQStringNoThrow();
+ QString to_version = ctx->arguments[1].toQStringNoThrow();
Value callback = ctx->argument(2);
if (from_version != r->version)
@@ -341,7 +354,7 @@ static Value qmlsqldatabase_changeVersion(SimpleCallContext *ctx)
ok = false;
db.transaction();
- ScopedCallData callData(ctx->engine, 1);
+ ScopedCallData callData(scope, 1);
callData->thisObject = engine->global();
callData->args[0] = Value::fromObject(w);
try {
@@ -368,11 +381,12 @@ static Value qmlsqldatabase_changeVersion(SimpleCallContext *ctx)
#endif
}
- return Value::undefinedValue();
+ return Encode::undefined();
}
-static Value qmlsqldatabase_transaction_shared(SimpleCallContext *ctx, bool readOnly)
+static ReturnedValue qmlsqldatabase_transaction_shared(SimpleCallContext *ctx, bool readOnly)
{
+ QV4::Scope scope(ctx);
QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>();
if (!r || r->type != QQmlSqlDatabaseWrapper::Database)
V4THROW_REFERENCE("Not a SQLDatabase object");
@@ -395,7 +409,7 @@ static Value qmlsqldatabase_transaction_shared(SimpleCallContext *ctx, bool read
db.transaction();
if (callback) {
- ScopedCallData callData(ctx->engine, 1);
+ ScopedCallData callData(scope, 1);
callData->thisObject = engine->global();
callData->args[0] = Value::fromObject(w);
try {
@@ -412,15 +426,15 @@ static Value qmlsqldatabase_transaction_shared(SimpleCallContext *ctx, bool read
db.rollback();
}
- return Value::undefinedValue();
+ return Encode::undefined();
}
-static Value qmlsqldatabase_transaction(SimpleCallContext *ctx)
+static ReturnedValue qmlsqldatabase_transaction(SimpleCallContext *ctx)
{
return qmlsqldatabase_transaction_shared(ctx, false);
}
-static Value qmlsqldatabase_read_transaction(SimpleCallContext *ctx)
+static ReturnedValue qmlsqldatabase_read_transaction(SimpleCallContext *ctx)
{
return qmlsqldatabase_transaction_shared(ctx, true);
}
@@ -619,6 +633,7 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
#ifndef QT_NO_SETTINGS
QV8Engine *engine = args->engine();
ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
+ QV4::Scope scope(ctx);
if (engine->engine()->offlineStoragePath().isEmpty())
V4THROW_SQL(SQLEXCEPTION_DATABASE_ERR, QQmlEngine::tr("SQL: can't create database, offline storage is disabled."));
@@ -626,9 +641,9 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
QSqlDatabase database;
- QString dbname = (*args)[0].toQString();
- QString dbversion = (*args)[1].toQString();
- QString dbdescription = (*args)[2].toQString();
+ QString dbname = (*args)[0].toQStringNoThrow();
+ QString dbversion = (*args)[1].toQStringNoThrow();
+ QString dbdescription = (*args)[2].toQStringNoThrow();
int dbestimatedsize = (*args)[3].toInt32();
FunctionObject *dbcreationCallback = (*args)[4].asFunctionObject();
@@ -678,7 +693,8 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
db->version = version;
if (created && dbcreationCallback) {
- ScopedCallData callData(ctx->engine, 1);
+ Scope scope(ctx);
+ ScopedCallData callData(scope, 1);
callData->thisObject = engine->global();
callData->args[0] = Value::fromObject(db);
dbcreationCallback->call(callData);
diff --git a/src/imports/widgets/qquickqcolordialog.cpp b/src/imports/widgets/qquickqcolordialog.cpp
index d10eacee60..ee27d147e7 100644
--- a/src/imports/widgets/qquickqcolordialog.cpp
+++ b/src/imports/widgets/qquickqcolordialog.cpp
@@ -163,7 +163,7 @@ QPlatformColorDialogHelper *QQuickQColorDialog::helper()
if (!m_dlgHelper) {
m_dlgHelper = new QColorDialogHelper();
- connect(m_dlgHelper, SIGNAL(currentColorChanged(const QColor&)), this, SLOT(setColor(QColor)));
+ connect(m_dlgHelper, SIGNAL(currentColorChanged(const QColor&)), this, SLOT(setCurrentColor(QColor)));
connect(m_dlgHelper, SIGNAL(colorSelected(const QColor&)), this, SLOT(setColor(QColor)));
connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
diff --git a/src/imports/widgets/qquickqfiledialog_p.h b/src/imports/widgets/qquickqfiledialog_p.h
index 8bf7c73882..2bd364eba0 100644
--- a/src/imports/widgets/qquickqfiledialog_p.h
+++ b/src/imports/widgets/qquickqfiledialog_p.h
@@ -90,7 +90,7 @@ public:
bool show(Qt::WindowFlags f, Qt::WindowModality m, QWindow *parent) Q_DECL_OVERRIDE;
void hide() Q_DECL_OVERRIDE { m_dialog.hide(); }
-private slots:
+private Q_SLOTS:
void currentChanged(const QString& path);
void directoryEntered(const QString& path);
void fileSelected(const QString& path);
diff --git a/src/imports/widgets/qquickqfontdialog.cpp b/src/imports/widgets/qquickqfontdialog.cpp
new file mode 100644
index 0000000000..6d637e1ddb
--- /dev/null
+++ b/src/imports/widgets/qquickqfontdialog.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickqfontdialog_p.h"
+#include "qquickitem.h"
+
+#include <private/qguiapplication_p.h>
+#include <private/qqmlcontext_p.h>
+#include <QWindow>
+#include <QQuickWindow>
+#include <QFontDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QFontDialogHelper : public QPlatformFontDialogHelper
+{
+public:
+ QFontDialogHelper() :
+ QPlatformFontDialogHelper()
+ {
+ connect(&m_dialog, SIGNAL(currentFontChanged(const QFont &)), this, SIGNAL(currentFontChanged(const QFont &)));
+ connect(&m_dialog, SIGNAL(fontSelected(const QFont &)), this, SIGNAL(fontSelected(const QFont &)));
+ connect(&m_dialog, SIGNAL(accepted()), this, SIGNAL(accept()));
+ connect(&m_dialog, SIGNAL(rejected()), this, SIGNAL(reject()));
+ }
+
+ virtual void setCurrentFont(const QFont &font) { m_dialog.setCurrentFont(font); }
+ virtual QFont currentFont() const { return m_dialog.currentFont(); }
+
+ virtual void exec() { m_dialog.exec(); }
+
+ virtual bool show(Qt::WindowFlags f, Qt::WindowModality m, QWindow *parent) {
+ m_dialog.winId();
+ QWindow *window = m_dialog.windowHandle();
+ Q_ASSERT(window);
+ window->setTransientParent(parent);
+ window->setFlags(f);
+ m_dialog.windowHandle()->setTransientParent(parent);
+ m_dialog.windowHandle()->setFlags(f);
+ m_dialog.setWindowModality(m);
+ m_dialog.setWindowTitle(QPlatformFontDialogHelper::options()->windowTitle());
+ m_dialog.setOptions((QFontDialog::FontDialogOptions)((int)(QPlatformFontDialogHelper::options()->options())));
+ m_dialog.show();
+ return m_dialog.isVisible();
+ }
+
+ virtual void hide() { m_dialog.hide(); }
+
+private:
+ QFontDialog m_dialog;
+};
+
+/*!
+ \qmltype QtFontDialog
+ \instantiates QQuickQFontDialog
+ \inqmlmodule QtQuick.PrivateWidgets 1
+ \ingroup qtquick-visual
+ \brief Dialog component for choosing files from a local filesystem.
+ \since 5.2
+ \internal
+
+ QtFontDialog provides a means to instantiate and manage a QFontDialog.
+ It is not recommended to be used directly; it is an implementation
+ detail of \l FontDialog in the \l QtQuick.Dialogs module.
+
+ To use this type, you will need to import the module with the following line:
+ \code
+ import QtQuick.PrivateWidgets 1.1
+ \endcode
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::FontDialog::accepted
+
+ The \a accepted signal is emitted when the user has finished using the
+ dialog. You can then inspect the \a filePath or \a filePaths properties to
+ get the selection.
+
+ Example:
+
+ \qml
+ FontDialog {
+ onAccepted: { console.log("Selected file: " + filePath) }
+ }
+ \endqml
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::FontDialog::rejected
+
+ The \a rejected signal is emitted when the user has dismissed the dialog,
+ either by closing the dialog window or by pressing the Cancel button.
+*/
+
+/*!
+ \class QQuickQFontDialog
+ \inmodule QtQuick.PrivateWidgets
+ \internal
+
+ \brief The QQuickQFontDialog class is a wrapper for a QFontDialog.
+
+ \since 5.2
+*/
+
+/*!
+ Constructs a file dialog with parent window \a parent.
+*/
+QQuickQFontDialog::QQuickQFontDialog(QObject *parent)
+ : QQuickAbstractFontDialog(parent)
+{
+}
+
+/*!
+ Destroys the file dialog.
+*/
+QQuickQFontDialog::~QQuickQFontDialog()
+{
+ if (m_dlgHelper)
+ m_dlgHelper->hide();
+ delete m_dlgHelper;
+}
+
+QPlatformFontDialogHelper *QQuickQFontDialog::helper()
+{
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ if (parentItem)
+ m_parentWindow = parentItem->window();
+
+ if (!m_dlgHelper) {
+ m_dlgHelper = new QFontDialogHelper();
+ connect(m_dlgHelper, SIGNAL(currentFontChanged(const QFont &)), this, SLOT(setFont(const QFont &)));
+ connect(m_dlgHelper, SIGNAL(fontSelected(const QFont &)), this, SLOT(setFont(const QFont &)));
+ connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
+ connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
+ }
+
+ return m_dlgHelper;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/widgets/qquickqfontdialog_p.h b/src/imports/widgets/qquickqfontdialog_p.h
new file mode 100644
index 0000000000..6efd15995b
--- /dev/null
+++ b/src/imports/widgets/qquickqfontdialog_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick.Dialogs 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKQFONTDIALOG_P_H
+#define QQUICKQFONTDIALOG_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 "../dialogs/qquickabstractfontdialog_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickQFontDialog : public QQuickAbstractFontDialog
+{
+ Q_OBJECT
+
+public:
+ QQuickQFontDialog(QObject *parent = 0);
+ virtual ~QQuickQFontDialog();
+
+protected:
+ QPlatformFontDialogHelper *helper();
+
+ Q_DISABLE_COPY(QQuickQFontDialog)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickQFontDialog *)
+
+#endif // QQUICKQFONTDIALOG_P_H
diff --git a/src/imports/widgets/qquickqmessagebox.cpp b/src/imports/widgets/qquickqmessagebox.cpp
new file mode 100644
index 0000000000..2f7c748c7b
--- /dev/null
+++ b/src/imports/widgets/qquickqmessagebox.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickqmessagebox_p.h"
+#include "qquickitem.h"
+
+#include <private/qguiapplication_p.h>
+#include <private/qqmlcontext_p.h>
+#include <QWindow>
+#include <QQuickWindow>
+#include <QMessageBox>
+#include <QAbstractButton>
+
+QT_BEGIN_NAMESPACE
+
+class QMessageBoxHelper : public QPlatformMessageDialogHelper
+{
+public:
+ QMessageBoxHelper() {
+ connect(&m_dialog, SIGNAL(accepted()), this, SIGNAL(accept()));
+ connect(&m_dialog, SIGNAL(rejected()), this, SIGNAL(reject()));
+ }
+
+ virtual void exec() { m_dialog.exec(); }
+
+ virtual bool show(Qt::WindowFlags f, Qt::WindowModality m, QWindow *parent) {
+ m_dialog.winId();
+ QWindow *window = m_dialog.windowHandle();
+ Q_ASSERT(window);
+ window->setTransientParent(parent);
+ window->setFlags(f);
+ m_dialog.setWindowModality(m);
+ m_dialog.setWindowTitle(QPlatformMessageDialogHelper::options()->windowTitle());
+ m_dialog.setIcon(static_cast<QMessageBox::Icon>(QPlatformMessageDialogHelper::options()->icon()));
+ if (!QPlatformMessageDialogHelper::options()->text().isNull())
+ m_dialog.setText(QPlatformMessageDialogHelper::options()->text());
+ if (!QPlatformMessageDialogHelper::options()->informativeText().isNull())
+ m_dialog.setInformativeText(QPlatformMessageDialogHelper::options()->informativeText());
+ if (!QPlatformMessageDialogHelper::options()->detailedText().isNull())
+ m_dialog.setDetailedText(QPlatformMessageDialogHelper::options()->detailedText());
+ m_dialog.setStandardButtons(static_cast<QMessageBox::StandardButtons>(static_cast<int>(
+ QPlatformMessageDialogHelper::options()->standardButtons())));
+ m_dialog.show();
+ return m_dialog.isVisible();
+ }
+
+ virtual void hide() { m_dialog.hide(); }
+
+ QMessageBox m_dialog;
+};
+
+/*!
+ \qmltype QtMessageDialog
+ \instantiates QQuickQMessageBox
+ \inqmlmodule QtQuick.PrivateWidgets 1
+ \ingroup qtquick-visual
+ \brief Dialog component for choosing a color.
+ \since 5.2
+ \internal
+
+ QtMessageDialog provides a means to instantiate and manage a QMessageBox.
+ It is not recommended to be used directly; it is an implementation
+ detail of \l MessageDialog in the \l QtQuick.Dialogs module.
+
+ To use this type, you will need to import the module with the following line:
+ \code
+ import QtQuick.PrivateWidgets 1.1
+ \endcode
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::MessageDialog::accepted
+
+ The \a accepted signal is emitted when the user has pressed the OK button
+ on the dialog.
+
+ Example:
+
+ \qml
+ MessageDialog {
+ onAccepted: { console.log("accepted") }
+ }
+ \endqml
+*/
+
+/*!
+ \qmlsignal QtQuick::Dialogs::MessageDialog::rejected
+
+ The \a rejected signal is emitted when the user has dismissed the dialog,
+ either by closing the dialog window or by pressing the Cancel button.
+*/
+
+/*!
+ \class QQuickQMessageBox
+ \inmodule QtQuick.PrivateWidgets
+ \internal
+
+ \brief The QQuickQMessageBox class is a wrapper for a QMessageBox.
+
+ \since 5.2
+*/
+
+/*!
+ Constructs a message dialog with parent window \a parent.
+*/
+QQuickQMessageBox::QQuickQMessageBox(QObject *parent)
+ : QQuickAbstractMessageDialog(parent)
+{
+}
+
+/*!
+ Destroys the message dialog.
+*/
+QQuickQMessageBox::~QQuickQMessageBox()
+{
+ if (m_dlgHelper)
+ m_dlgHelper->hide();
+ delete m_dlgHelper;
+}
+
+void QQuickQMessageBox::finished(int button) {
+ click(static_cast<StandardButton>(button));
+}
+
+void QQuickQMessageBox::clicked(QAbstractButton* button) {
+ QMessageBox &mb = static_cast<QMessageBoxHelper*>(QQuickAbstractMessageDialog::m_dlgHelper)->m_dialog;
+ switch (mb.buttonRole(button)) {
+ case QMessageBox::AcceptRole:
+ emit accepted();
+ break;
+ case QMessageBox::RejectRole:
+ emit rejected();
+ break;
+ case QMessageBox::DestructiveRole:
+ emit discard();
+ break;
+ case QMessageBox::HelpRole:
+ emit help();
+ break;
+ case QMessageBox::YesRole:
+ emit yes();
+ break;
+ case QMessageBox::NoRole:
+ emit no();
+ break;
+ case QMessageBox::ApplyRole:
+ emit apply();
+ break;
+ case QMessageBox::ResetRole:
+ emit reset();
+ break;
+ default:
+ qWarning("unhandled QMessageBox button role %d", mb.buttonRole(button));
+ }
+ if (!mb.isVisible())
+ setVisible(false);
+}
+
+QPlatformDialogHelper *QQuickQMessageBox::helper()
+{
+ QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
+ if (parentItem)
+ m_parentWindow = parentItem->window();
+
+ if (!QQuickAbstractMessageDialog::m_dlgHelper) {
+ QMessageBoxHelper* helper = new QMessageBoxHelper();
+ QQuickAbstractMessageDialog::m_dlgHelper = helper;
+ connect(helper, SIGNAL(accept()), this, SLOT(accept()));
+ connect(helper, SIGNAL(reject()), this, SLOT(reject()));
+ connect(&helper->m_dialog, SIGNAL(finished(int)), this, SLOT(finished(int)));
+ connect(&helper->m_dialog, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(clicked(QAbstractButton*)));
+ }
+
+ return QQuickAbstractMessageDialog::m_dlgHelper;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgpathsimplifier_p.h b/src/imports/widgets/qquickqmessagebox_p.h
index 49eb4dd3e5..9c3c1f2dd6 100644
--- a/src/quick/scenegraph/qsgpathsimplifier_p.h
+++ b/src/imports/widgets/qquickqmessagebox_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QSGPATHSIMPLIFIER_P_H
-#define QSGPATHSIMPLIFIER_P_H
+#ifndef QQUICKQMESSAGEBOX_P_H
+#define QQUICKQMESSAGEBOX_P_H
//
// W A R N I N G
@@ -53,16 +53,34 @@
// We mean it.
//
-#include <QtGui/qpainterpath.h>
-#include <QtGui/private/qdatabuffer_p.h>
-#include <QtGui/private/qvectorpath_p.h>
+#include <QMessageBox>
+#include "../dialogs/qquickabstractmessagedialog_p.h"
QT_BEGIN_NAMESPACE
-// The returned vertices are in 8:8 fixed point format. The path is assumed to be in the range (-128, 128)x(-128, 128).
-void qSimplifyPath(const QVectorPath &path, QDataBuffer<QPoint> &vertices, QDataBuffer<quint32> &indices, const QTransform &matrix = QTransform());
-void qSimplifyPath(const QPainterPath &path, QDataBuffer<QPoint> &vertices, QDataBuffer<quint32> &indices, const QTransform &matrix = QTransform());
+class QAbstractButton;
+
+class QQuickQMessageBox : public QQuickAbstractMessageDialog
+{
+ Q_OBJECT
+
+public:
+ QQuickQMessageBox(QObject *parent = 0);
+ virtual ~QQuickQMessageBox();
+
+protected slots:
+ void clicked(QAbstractButton* button);
+ void finished(int button);
+
+protected:
+ virtual QPlatformDialogHelper *helper();
+
+protected:
+ Q_DISABLE_COPY(QQuickQMessageBox)
+};
QT_END_NAMESPACE
-#endif
+QML_DECLARE_TYPE(QQuickQMessageBox *)
+
+#endif // QQUICKQMESSAGEBOX_P_H
diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro
index 7e6a04161a..8c075945fd 100644
--- a/src/imports/widgets/widgets.pro
+++ b/src/imports/widgets/widgets.pro
@@ -1,21 +1,29 @@
CXX_MODULE = qml
TARGET = widgetsplugin
TARGETPATH = QtQuick/PrivateWidgets
-IMPORT_VERSION = 1.0
+IMPORT_VERSION = 1.1
SOURCES += \
+ qquickqmessagebox.cpp \
+ ../dialogs/qquickabstractmessagedialog.cpp \
qquickqfiledialog.cpp \
../dialogs/qquickabstractfiledialog.cpp \
qquickqcolordialog.cpp \
../dialogs/qquickabstractcolordialog.cpp \
+ qquickqfontdialog.cpp \
+ ../dialogs/qquickabstractfontdialog.cpp \
../dialogs/qquickabstractdialog.cpp \
widgetsplugin.cpp
HEADERS += \
+ qquickqmessagebox_p.h \
+ ../dialogs/qquickabstractmessagedialog_p.h \
qquickqfiledialog_p.h \
../dialogs/qquickabstractfiledialog_p.h \
qquickqcolordialog_p.h \
../dialogs/qquickabstractcolordialog_p.h \
+ qquickqfontdialog_p.h \
+ ../dialogs/qquickabstractfontdialog_p.h \
../dialogs/qquickabstractdialog_p.h
QT += quick-private gui-private core-private qml-private widgets
diff --git a/src/imports/widgets/widgetsplugin.cpp b/src/imports/widgets/widgetsplugin.cpp
index be9d59f346..05c3a5e86c 100644
--- a/src/imports/widgets/widgetsplugin.cpp
+++ b/src/imports/widgets/widgetsplugin.cpp
@@ -41,8 +41,10 @@
#include <QtQml/qqmlextensionplugin.h>
#include <QtQml/qqml.h>
+#include "qquickqmessagebox_p.h"
#include "qquickqfiledialog_p.h"
#include "qquickqcolordialog_p.h"
+#include "qquickqfontdialog_p.h"
QT_BEGIN_NAMESPACE
@@ -59,7 +61,7 @@ QT_BEGIN_NAMESPACE
and to provide fallback implementations in case they fail to load.
\code
- import QtQuick.PrivateWidgets 1.0
+ import QtQuick.PrivateWidgets 1.1
\endcode
\since 5.1
@@ -75,8 +77,10 @@ public:
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.PrivateWidgets"));
+ qmlRegisterType<QQuickQMessageBox>(uri, 1, 1, "QtMessageDialog");
qmlRegisterType<QQuickQFileDialog>(uri, 1, 0, "QtFileDialog");
qmlRegisterType<QQuickQColorDialog>(uri, 1, 0, "QtColorDialog");
+ qmlRegisterType<QQuickQFontDialog>(uri, 1, 1, "QtFontDialog");
}
};
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
index c12bfee924..9f6437625d 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
@@ -926,7 +926,7 @@ QQmlV4Handle QQuickXmlListModel::get(int index) const
Object *o = v4engine->newObject();
for (int ii = 0; ii < d->roleObjects.count(); ++ii) {
Property *p = o->insertMember(v4engine->newIdentifier(d->roleObjects[ii]->name()), PropertyAttributes());
- p->value = v8engine->fromVariant(d->data.value(ii).value(index));
+ p->value = Value::fromReturnedValue(v8engine->fromVariant(d->data.value(ii).value(index)));
}
return QQmlV4Handle(Value::fromObject(o));
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h b/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
index ca4b7cf811..cd75d16902 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
@@ -161,7 +161,7 @@ public:
if (name == m_name)
return;
m_name = name;
- emit nameChanged();
+ Q_EMIT nameChanged();
}
QString query() const { return m_query; }
@@ -174,7 +174,7 @@ public:
if (m_query == query)
return;
m_query = query;
- emit queryChanged();
+ Q_EMIT queryChanged();
}
bool isKey() const { return m_isKey; }
@@ -182,7 +182,7 @@ public:
if (m_isKey == b)
return;
m_isKey = b;
- emit isKeyChanged();
+ Q_EMIT isKeyChanged();
}
bool isValid() {
diff --git a/src/particles/qquickage_p.h b/src/particles/qquickage_p.h
index 0839517e95..4bca34ce0f 100644
--- a/src/particles/qquickage_p.h
+++ b/src/particles/qquickage_p.h
@@ -66,16 +66,16 @@ public:
protected:
virtual bool affectParticle(QQuickParticleData *d, qreal dt);
-signals:
+Q_SIGNALS:
void lifeLeftChanged(int arg);
void advancePositionChanged(bool arg);
-public slots:
+public Q_SLOTS:
void setLifeLeft(int arg)
{
if (m_lifeLeft != arg) {
m_lifeLeft = arg;
- emit lifeLeftChanged(arg);
+ Q_EMIT lifeLeftChanged(arg);
}
}
@@ -83,7 +83,7 @@ public slots:
{
if (m_advancePosition != arg) {
m_advancePosition = arg;
- emit advancePositionChanged(arg);
+ Q_EMIT advancePositionChanged(arg);
}
}
diff --git a/src/particles/qquickangledirection_p.h b/src/particles/qquickangledirection_p.h
index d89455a5e7..f3283552fa 100644
--- a/src/particles/qquickangledirection_p.h
+++ b/src/particles/qquickangledirection_p.h
@@ -74,7 +74,7 @@ public:
return m_magnitudeVariation;
}
-signals:
+Q_SIGNALS:
void angleChanged(qreal arg);
@@ -84,12 +84,12 @@ signals:
void magnitudeVariationChanged(qreal arg);
-public slots:
+public Q_SLOTS:
void setAngle(qreal arg)
{
if (m_angle != arg) {
m_angle = arg;
- emit angleChanged(arg);
+ Q_EMIT angleChanged(arg);
}
}
@@ -97,7 +97,7 @@ void setMagnitude(qreal arg)
{
if (m_magnitude != arg) {
m_magnitude = arg;
- emit magnitudeChanged(arg);
+ Q_EMIT magnitudeChanged(arg);
}
}
@@ -105,7 +105,7 @@ void setAngleVariation(qreal arg)
{
if (m_angleVariation != arg) {
m_angleVariation = arg;
- emit angleVariationChanged(arg);
+ Q_EMIT angleVariationChanged(arg);
}
}
@@ -113,7 +113,7 @@ void setMagnitudeVariation(qreal arg)
{
if (m_magnitudeVariation != arg) {
m_magnitudeVariation = arg;
- emit magnitudeVariationChanged(arg);
+ Q_EMIT magnitudeVariationChanged(arg);
}
}
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp
index 40d0df1a22..09f8967045 100644
--- a/src/particles/qquickcustomaffector.cpp
+++ b/src/particles/qquickcustomaffector.cpp
@@ -146,13 +146,14 @@ void QQuickCustomAffector::affectSystem(qreal dt)
QQmlEngine *qmlEngine = ::qmlEngine(this);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine->handle());
- QV4::ArrayObject *array = v4->newArrayObject(toAffect.size());
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::ArrayObject> array(scope, v4->newArrayObject(toAffect.size()));
for (int i=0; i<toAffect.size(); i++)
array->putIndexed(i, toAffect[i]->v4Value().toValue());
if (dt >= simulationCutoff || dt <= simulationDelta) {
affectProperties(toAffect, dt);
- emit affectParticles(QQmlV4Handle(QV4::Value::fromObject(array)), dt);
+ emit affectParticles(QQmlV4Handle(array.asValue()), dt);
} else {
int realTime = m_system->timeInt;
m_system->timeInt -= dt * 1000.0;
@@ -160,12 +161,12 @@ void QQuickCustomAffector::affectSystem(qreal dt)
m_system->timeInt += simulationDelta * 1000.0;
dt -= simulationDelta;
affectProperties(toAffect, simulationDelta);
- emit affectParticles(QQmlV4Handle(QV4::Value::fromObject(array)), simulationDelta);
+ emit affectParticles(QQmlV4Handle(array.asValue()), simulationDelta);
}
m_system->timeInt = realTime;
if (dt > 0.0) {
affectProperties(toAffect, dt);
- emit affectParticles(QQmlV4Handle(QV4::Value::fromObject(array)), dt);
+ emit affectParticles(QQmlV4Handle(array.asValue()), dt);
}
}
diff --git a/src/particles/qquickcustomaffector_p.h b/src/particles/qquickcustomaffector_p.h
index 1a12684c48..d7d0c60e85 100644
--- a/src/particles/qquickcustomaffector_p.h
+++ b/src/particles/qquickcustomaffector_p.h
@@ -98,7 +98,7 @@ public:
}
-signals:
+Q_SIGNALS:
void affectParticles(QQmlV4Handle particles, qreal dt);
void positionChanged(QQuickDirection * arg);
@@ -109,12 +109,12 @@ signals:
void relativeChanged(bool arg);
-public slots:
+public Q_SLOTS:
void setPosition(QQuickDirection * arg)
{
if (m_position != arg) {
m_position = arg;
- emit positionChanged(arg);
+ Q_EMIT positionChanged(arg);
}
}
@@ -122,7 +122,7 @@ public slots:
{
if (m_velocity != arg) {
m_velocity = arg;
- emit velocityChanged(arg);
+ Q_EMIT velocityChanged(arg);
}
}
@@ -130,7 +130,7 @@ public slots:
{
if (m_acceleration != arg) {
m_acceleration = arg;
- emit accelerationChanged(arg);
+ Q_EMIT accelerationChanged(arg);
}
}
@@ -138,7 +138,7 @@ public slots:
{
if (m_relative != arg) {
m_relative = arg;
- emit relativeChanged(arg);
+ Q_EMIT relativeChanged(arg);
}
}
diff --git a/src/particles/qquickdirection_p.h b/src/particles/qquickdirection_p.h
index 4ceae16b35..51e7679fda 100644
--- a/src/particles/qquickdirection_p.h
+++ b/src/particles/qquickdirection_p.h
@@ -54,9 +54,9 @@ public:
explicit QQuickDirection(QObject *parent = 0);
virtual const QPointF sample(const QPointF &from);
-signals:
+Q_SIGNALS:
-public slots:
+public Q_SLOTS:
protected:
};
diff --git a/src/particles/qquickellipseextruder_p.h b/src/particles/qquickellipseextruder_p.h
index a9425b6205..0625565c10 100644
--- a/src/particles/qquickellipseextruder_p.h
+++ b/src/particles/qquickellipseextruder_p.h
@@ -59,17 +59,17 @@ public:
return m_fill;
}
-signals:
+Q_SIGNALS:
void fillChanged(bool arg);
-public slots:
+public Q_SLOTS:
void setFill(bool arg)
{
if (m_fill != arg) {
m_fill = arg;
- emit fillChanged(arg);
+ Q_EMIT fillChanged(arg);
}
}
private:
diff --git a/src/particles/qquickfriction_p.h b/src/particles/qquickfriction_p.h
index 13ba715e88..9b3d95df90 100644
--- a/src/particles/qquickfriction_p.h
+++ b/src/particles/qquickfriction_p.h
@@ -66,18 +66,18 @@ public:
protected:
virtual bool affectParticle(QQuickParticleData *d, qreal dt);
-signals:
+Q_SIGNALS:
void factorChanged(qreal arg);
void thresholdChanged(qreal arg);
-public slots:
+public Q_SLOTS:
void setFactor(qreal arg)
{
if (m_factor != arg) {
m_factor = arg;
- emit factorChanged(arg);
+ Q_EMIT factorChanged(arg);
}
}
@@ -85,7 +85,7 @@ public slots:
{
if (m_threshold != arg) {
m_threshold = arg;
- emit thresholdChanged(arg);
+ Q_EMIT thresholdChanged(arg);
}
}
diff --git a/src/particles/qquickgravity_p.h b/src/particles/qquickgravity_p.h
index e6010b536e..d4c3ef4ac2 100644
--- a/src/particles/qquickgravity_p.h
+++ b/src/particles/qquickgravity_p.h
@@ -64,20 +64,20 @@ public:
}
protected:
virtual bool affectParticle(QQuickParticleData *d, qreal dt);
-signals:
+Q_SIGNALS:
void magnitudeChanged(qreal arg);
void angleChanged(qreal arg);
-public slots:
+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;
- emit magnitudeChanged(arg);
+ Q_EMIT magnitudeChanged(arg);
}
}
@@ -86,7 +86,7 @@ void setMagnitude(qreal arg)
if (m_magnitude != arg) {
m_magnitude = arg;
m_needRecalc = true;
- emit magnitudeChanged(arg);
+ Q_EMIT magnitudeChanged(arg);
}
}
@@ -95,7 +95,7 @@ void setAngle(qreal arg)
if (m_angle != arg) {
m_angle = arg;
m_needRecalc = true;
- emit angleChanged(arg);
+ Q_EMIT angleChanged(arg);
}
}
diff --git a/src/particles/qquickgroupgoal_p.h b/src/particles/qquickgroupgoal_p.h
index 6a31b882a3..5d385f2f36 100644
--- a/src/particles/qquickgroupgoal_p.h
+++ b/src/particles/qquickgroupgoal_p.h
@@ -68,13 +68,13 @@ public:
protected:
virtual bool affectParticle(QQuickParticleData *d, qreal dt);
-signals:
+Q_SIGNALS:
void goalStateChanged(QString arg);
void jumpChanged(bool arg);
-public slots:
+public Q_SLOTS:
void setGoalState(QString arg);
@@ -82,7 +82,7 @@ public slots:
{
if (m_jump != arg) {
m_jump = arg;
- emit jumpChanged(arg);
+ Q_EMIT jumpChanged(arg);
}
}
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index c3e13f162f..0902adaf5d 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -1113,8 +1113,8 @@ void QQuickImageParticle::setBypassOptimizations(bool arg)
m_bypassOptimizations = arg;
emit bypassOptimizationsChanged(arg);
}
- if (perfLevel < 9999)
- reset();
+ // Applies regardless of perfLevel
+ reset();
}
void QQuickImageParticle::setEntryEffect(EntryEffect arg)
diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h
index daa3d5cdbc..8f2bb715f8 100644
--- a/src/particles/qquickimageparticle_p.h
+++ b/src/particles/qquickimageparticle_p.h
@@ -263,7 +263,7 @@ public:
void resetRotation();
void resetDeformation();
-signals:
+Q_SIGNALS:
void imageChanged();
void colortableChanged();
@@ -305,7 +305,7 @@ signals:
void statusChanged(Status arg);
-public slots:
+public Q_SLOTS:
void reloadColor(const Color4ub &c, QQuickParticleData* d);
void setAlphaVariation(qreal arg);
@@ -348,7 +348,7 @@ protected:
void sceneGraphInvalidated();
-private slots:
+private Q_SLOTS:
void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty
void spriteAdvance(int spriteIndex);
diff --git a/src/particles/qquickitemparticle_p.h b/src/particles/qquickitemparticle_p.h
index e5c7239567..d9c8555ed0 100644
--- a/src/particles/qquickitemparticle_p.h
+++ b/src/particles/qquickitemparticle_p.h
@@ -69,24 +69,24 @@ public:
return m_delegate;
}
-signals:
+Q_SIGNALS:
void fadeChanged();
void delegateChanged(QQmlComponent* arg);
-public slots:
+public Q_SLOTS:
//TODO: Add a follow mode, where moving the delegate causes the logical particle to go with it?
void freeze(QQuickItem* item);
void unfreeze(QQuickItem* item);
void take(QQuickItem* item,bool prioritize=false);//take by modelparticle
void give(QQuickItem* item);//give from modelparticle
- void setFade(bool arg){if (arg == m_fade) return; m_fade = arg; emit fadeChanged();}
+ void setFade(bool arg){if (arg == m_fade) return; m_fade = arg; Q_EMIT fadeChanged();}
void setDelegate(QQmlComponent* arg)
{
if (m_delegate != arg) {
m_delegate = arg;
- emit delegateChanged(arg);
+ Q_EMIT delegateChanged(arg);
}
}
@@ -121,8 +121,8 @@ public:
: QObject(parent), m_mp(0)
{;}
QQuickItemParticle* particle() {return m_mp;}
- void detach(){emit detached();}
- void attach(){emit attached();}
+ void detach(){Q_EMIT detached();}
+ void attach(){Q_EMIT attached();}
private:
QQuickItemParticle* m_mp;
friend class QQuickItemParticle;
diff --git a/src/particles/qquicklineextruder_p.h b/src/particles/qquicklineextruder_p.h
index 503e315b24..bfbd5aed54 100644
--- a/src/particles/qquicklineextruder_p.h
+++ b/src/particles/qquicklineextruder_p.h
@@ -57,17 +57,17 @@ public:
return m_mirrored;
}
-signals:
+Q_SIGNALS:
void mirroredChanged(bool arg);
-public slots:
+public Q_SLOTS:
void setmirrored(bool arg)
{
if (m_mirrored != arg) {
m_mirrored = arg;
- emit mirroredChanged(arg);
+ Q_EMIT mirroredChanged(arg);
}
}
private:
diff --git a/src/particles/qquickmaskextruder_p.h b/src/particles/qquickmaskextruder_p.h
index 5c948cc7d7..020c8762f8 100644
--- a/src/particles/qquickmaskextruder_p.h
+++ b/src/particles/qquickmaskextruder_p.h
@@ -62,14 +62,14 @@ public:
return m_source;
}
-signals:
+Q_SIGNALS:
void sourceChanged(QUrl arg);
-public slots:
+public Q_SLOTS:
void setSource(QUrl arg);
-private slots:
+private Q_SLOTS:
void startMaskLoading();
void finishMaskLoading();
diff --git a/src/particles/qquickparticleaffector_p.h b/src/particles/qquickparticleaffector_p.h
index 2629ecc676..5ee8430472 100644
--- a/src/particles/qquickparticleaffector_p.h
+++ b/src/particles/qquickparticleaffector_p.h
@@ -92,7 +92,7 @@ public:
return m_whenCollidingWith;
}
-signals:
+Q_SIGNALS:
void systemChanged(QQuickParticleSystem* arg);
@@ -108,13 +108,13 @@ signals:
void whenCollidingWithChanged(QStringList arg);
-public slots:
+public Q_SLOTS:
void setSystem(QQuickParticleSystem* arg)
{
if (m_system != arg) {
m_system = arg;
m_system->registerParticleAffector(this);
- emit systemChanged(arg);
+ Q_EMIT systemChanged(arg);
}
}
@@ -123,7 +123,7 @@ void setGroups(QStringList arg)
if (m_groups != arg) {
m_groups = arg;
m_updateIntSet = true;
- emit groupsChanged(arg);
+ Q_EMIT groupsChanged(arg);
}
}
@@ -131,7 +131,7 @@ void setEnabled(bool arg)
{
if (m_enabled != arg) {
m_enabled = arg;
- emit enabledChanged(arg);
+ Q_EMIT enabledChanged(arg);
}
}
@@ -140,7 +140,7 @@ void setOnceOff(bool arg)
if (m_onceOff != arg) {
m_onceOff = arg;
m_needsReset = true;
- emit onceChanged(arg);
+ Q_EMIT onceChanged(arg);
}
}
@@ -148,7 +148,7 @@ void setShape(QQuickParticleExtruder* arg)
{
if (m_shape != arg) {
m_shape = arg;
- emit shapeChanged(arg);
+ Q_EMIT shapeChanged(arg);
}
}
@@ -156,10 +156,10 @@ void setWhenCollidingWith(QStringList arg)
{
if (m_whenCollidingWith != arg) {
m_whenCollidingWith = arg;
- emit whenCollidingWithChanged(arg);
+ Q_EMIT whenCollidingWithChanged(arg);
}
}
-public slots:
+public Q_SLOTS:
void updateOffsets();
protected:
diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp
index 6627291c55..404554c9b6 100644
--- a/src/particles/qquickparticleemitter.cpp
+++ b/src/particles/qquickparticleemitter.cpp
@@ -481,14 +481,15 @@ void QQuickParticleEmitter::emitWindow(int timeStamp)
if (isEmitConnected()) {
QQmlEngine *qmlEngine = ::qmlEngine(this);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine->handle());
+ QV4::Scope scope(v4);
//Done after emitParticle so that the Painter::load is done first, this allows you to customize its static variables
//We then don't need to request another reload, because the first reload isn't scheduled until we get back to the render thread
- QV4::ArrayObject *array = v4->newArrayObject(toEmit.size());
+ QV4::Scoped<QV4::ArrayObject> array(scope, v4->newArrayObject(toEmit.size()));
for (int i=0; i<toEmit.size(); i++)
array->putIndexed(i, toEmit[i]->v4Value().toValue());
- emitParticles(QQmlV4Handle(QV4::Value::fromObject(array)));//A chance for arbitrary JS changes
+ emitParticles(QQmlV4Handle(array.asValue()));//A chance for arbitrary JS changes
}
m_last_emission = pt;
diff --git a/src/particles/qquickparticleemitter_p.h b/src/particles/qquickparticleemitter_p.h
index 051e27816d..edca86d53d 100644
--- a/src/particles/qquickparticleemitter_p.h
+++ b/src/particles/qquickparticleemitter_p.h
@@ -118,7 +118,7 @@ public:
qreal velocityFromMovement() const { return m_velocity_from_movement; }
void setVelocityFromMovement(qreal s);
virtual void componentComplete();
-signals:
+Q_SIGNALS:
void emitParticles(QQmlV4Handle particles);
void particlesPerSecondChanged(qreal);
void particleDurationChanged(int);
@@ -149,7 +149,7 @@ signals:
void startTimeChanged(int arg);
-public slots:
+public Q_SLOTS:
void pulse(int milliseconds);
void burst(int num);
void burst(int num, qreal x, qreal y);
@@ -160,7 +160,7 @@ public slots:
{
if (m_particlesPerSecond != arg) {
m_particlesPerSecond = arg;
- emit particlesPerSecondChanged(arg);
+ Q_EMIT particlesPerSecondChanged(arg);
}
}
@@ -168,7 +168,7 @@ public slots:
{
if (m_particleDuration != arg) {
m_particleDuration = arg;
- emit particleDurationChanged(arg);
+ Q_EMIT particleDurationChanged(arg);
}
}
@@ -178,7 +178,7 @@ public slots:
m_system = arg;
if (m_system)
m_system->registerParticleEmitter(this);
- emit systemChanged(arg);
+ Q_EMIT systemChanged(arg);
}
}
@@ -186,7 +186,7 @@ public slots:
{
if (m_group != arg) {
m_group = arg;
- emit groupChanged(arg);
+ Q_EMIT groupChanged(arg);
}
}
@@ -194,14 +194,14 @@ public slots:
{
if (m_particleDurationVariation != arg) {
m_particleDurationVariation = arg;
- emit particleDurationVariationChanged(arg);
+ Q_EMIT particleDurationVariationChanged(arg);
}
}
void setExtruder(QQuickParticleExtruder* arg)
{
if (m_extruder != arg) {
m_extruder = arg;
- emit extruderChanged(arg);
+ Q_EMIT extruderChanged(arg);
}
}
@@ -209,7 +209,7 @@ public slots:
{
if (m_particleSize != arg) {
m_particleSize = arg;
- emit particleSizeChanged(arg);
+ Q_EMIT particleSizeChanged(arg);
}
}
@@ -217,7 +217,7 @@ public slots:
{
if (m_particleEndSize != arg) {
m_particleEndSize = arg;
- emit particleEndSizeChanged(arg);
+ Q_EMIT particleEndSizeChanged(arg);
}
}
@@ -225,7 +225,7 @@ public slots:
{
if (m_particleSizeVariation != arg) {
m_particleSizeVariation = arg;
- emit particleSizeVariationChanged(arg);
+ Q_EMIT particleSizeVariationChanged(arg);
}
}
@@ -233,7 +233,7 @@ public slots:
{
if (m_velocity != arg) {
m_velocity = arg;
- emit velocityChanged(arg);
+ Q_EMIT velocityChanged(arg);
}
}
@@ -241,7 +241,7 @@ public slots:
{
if (m_acceleration != arg) {
m_acceleration = arg;
- emit accelerationChanged(arg);
+ Q_EMIT accelerationChanged(arg);
}
}
@@ -251,7 +251,7 @@ public slots:
{
if (m_startTime != arg) {
m_startTime = arg;
- emit startTimeChanged(arg);
+ Q_EMIT startTimeChanged(arg);
}
}
diff --git a/src/particles/qquickparticleextruder_p.h b/src/particles/qquickparticleextruder_p.h
index 36edc9cf06..c6d717dabe 100644
--- a/src/particles/qquickparticleextruder_p.h
+++ b/src/particles/qquickparticleextruder_p.h
@@ -57,8 +57,8 @@ public:
virtual QPointF extrude(const QRectF &);
virtual bool contains(const QRectF &bounds, const QPointF &point);
-signals:
-public slots:
+Q_SIGNALS:
+public Q_SLOTS:
protected:
};
diff --git a/src/particles/qquickparticlegroup_p.h b/src/particles/qquickparticlegroup_p.h
index bbac8aab0d..f7bccf99ac 100644
--- a/src/particles/qquickparticlegroup_p.h
+++ b/src/particles/qquickparticlegroup_p.h
@@ -74,13 +74,13 @@ public:
return m_system;
}
-public slots:
+public Q_SLOTS:
void setMaximumAlive(int arg)
{
if (m_maximumAlive != arg) {
m_maximumAlive = arg;
- emit maximumAliveChanged(arg);
+ Q_EMIT maximumAliveChanged(arg);
}
}
@@ -88,7 +88,7 @@ public slots:
void delayRedirect(QObject* obj);
-signals:
+Q_SIGNALS:
void maximumAliveChanged(int arg);
diff --git a/src/particles/qquickparticlepainter_p.h b/src/particles/qquickparticlepainter_p.h
index 7801fddb6e..cedf4cab52 100644
--- a/src/particles/qquickparticlepainter_p.h
+++ b/src/particles/qquickparticlepainter_p.h
@@ -76,13 +76,13 @@ public:
void itemChange(ItemChange, const ItemChangeData &);
-signals:
+Q_SIGNALS:
void countChanged();
void systemChanged(QQuickParticleSystem* arg);
void groupsChanged(QStringList arg);
-public slots:
+public Q_SLOTS:
void setSystem(QQuickParticleSystem* arg);
void setGroups(QStringList arg)
@@ -90,13 +90,13 @@ public slots:
if (m_groups != arg) {
m_groups = arg;
//Note: The system watches this as it has to recalc things when groups change. It will request a reset if necessary
- emit groupsChanged(arg);
+ Q_EMIT groupsChanged(arg);
}
}
void calcSystemOffset(bool resetPending = false);
-private slots:
+private Q_SLOTS:
virtual void sceneGraphInvalidated() {}
protected:
diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h
index df57cd2cc7..cda505e4b4 100644
--- a/src/particles/qquickparticlesystem_p.h
+++ b/src/particles/qquickparticlesystem_p.h
@@ -254,14 +254,14 @@ public:
static const int maxLife = 600000;
-signals:
+Q_SIGNALS:
void systemInitialized();
void runningChanged(bool arg);
void pausedChanged(bool arg);
void emptyChanged(bool arg);
-public slots:
+public Q_SLOTS:
void start(){setRunning(true);}
void stop(){setRunning(false);}
void restart(){setRunning(false);setRunning(true);}
@@ -279,7 +279,7 @@ protected:
//This one only once per frame (effectively)
void componentComplete();
-private slots:
+private Q_SLOTS:
void emittersChanged();
void loadPainter(QObject* p);
void createEngine(); //Not invoked by sprite engine, unlike Sprite uses
diff --git a/src/particles/qquickpointattractor_p.h b/src/particles/qquickpointattractor_p.h
index 1332591daf..6747798364 100644
--- a/src/particles/qquickpointattractor_p.h
+++ b/src/particles/qquickpointattractor_p.h
@@ -98,7 +98,7 @@ public:
return m_proportionalToDistance;
}
-signals:
+Q_SIGNALS:
void strengthChanged(qreal arg);
@@ -110,12 +110,12 @@ signals:
void proportionalToDistanceChanged(Proportion arg);
-public slots:
+public Q_SLOTS:
void setStrength(qreal arg)
{
if (m_strength != arg) {
m_strength = arg;
- emit strengthChanged(arg);
+ Q_EMIT strengthChanged(arg);
}
}
@@ -123,7 +123,7 @@ void setPointX(qreal arg)
{
if (m_x != arg) {
m_x = arg;
- emit pointXChanged(arg);
+ Q_EMIT pointXChanged(arg);
}
}
@@ -131,14 +131,14 @@ void setPointY(qreal arg)
{
if (m_y != arg) {
m_y = arg;
- emit pointYChanged(arg);
+ Q_EMIT pointYChanged(arg);
}
}
void setAffectedParameter(AffectableParameters arg)
{
if (m_physics != arg) {
m_physics = arg;
- emit affectedParameterChanged(arg);
+ Q_EMIT affectedParameterChanged(arg);
}
}
@@ -146,7 +146,7 @@ void setProportionalToDistance(Proportion arg)
{
if (m_proportionalToDistance != arg) {
m_proportionalToDistance = arg;
- emit proportionalToDistanceChanged(arg);
+ Q_EMIT proportionalToDistanceChanged(arg);
}
}
diff --git a/src/particles/qquickpointdirection_p.h b/src/particles/qquickpointdirection_p.h
index eae385a3b7..e4c8624c9c 100644
--- a/src/particles/qquickpointdirection_p.h
+++ b/src/particles/qquickpointdirection_p.h
@@ -75,7 +75,7 @@ public:
return m_yVariation;
}
-signals:
+Q_SIGNALS:
void xChanged(qreal arg);
@@ -85,12 +85,12 @@ signals:
void yVariationChanged(qreal arg);
-public slots:
+public Q_SLOTS:
void setX(qreal arg)
{
if (m_x != arg) {
m_x = arg;
- emit xChanged(arg);
+ Q_EMIT xChanged(arg);
}
}
@@ -98,7 +98,7 @@ public slots:
{
if (m_y != arg) {
m_y = arg;
- emit yChanged(arg);
+ Q_EMIT yChanged(arg);
}
}
@@ -106,7 +106,7 @@ public slots:
{
if (m_xVariation != arg) {
m_xVariation = arg;
- emit xVariationChanged(arg);
+ Q_EMIT xVariationChanged(arg);
}
}
@@ -114,7 +114,7 @@ public slots:
{
if (m_yVariation != arg) {
m_yVariation = arg;
- emit yVariationChanged(arg);
+ Q_EMIT yVariationChanged(arg);
}
}
diff --git a/src/particles/qquickrectangleextruder_p.h b/src/particles/qquickrectangleextruder_p.h
index e0480687a0..f8ab2343c3 100644
--- a/src/particles/qquickrectangleextruder_p.h
+++ b/src/particles/qquickrectangleextruder_p.h
@@ -60,17 +60,17 @@ public:
return m_fill;
}
-signals:
+Q_SIGNALS:
void fillChanged(bool arg);
-public slots:
+public Q_SLOTS:
void setFill(bool arg)
{
if (m_fill != arg) {
m_fill = arg;
- emit fillChanged(arg);
+ Q_EMIT fillChanged(arg);
}
}
protected:
diff --git a/src/particles/qquickspritegoal_p.h b/src/particles/qquickspritegoal_p.h
index 4d5f192f0a..c5c7539b58 100644
--- a/src/particles/qquickspritegoal_p.h
+++ b/src/particles/qquickspritegoal_p.h
@@ -73,7 +73,7 @@ public:
protected:
virtual bool affectParticle(QQuickParticleData *d, qreal dt);
-signals:
+Q_SIGNALS:
void goalStateChanged(QString arg);
@@ -81,7 +81,7 @@ signals:
void systemStatesChanged(bool arg);
-public slots:
+public Q_SLOTS:
void setGoalState(QString arg);
@@ -89,7 +89,7 @@ void setJump(bool arg)
{
if (m_jump != arg) {
m_jump = arg;
- emit jumpChanged(arg);
+ Q_EMIT jumpChanged(arg);
}
}
@@ -99,7 +99,7 @@ void setSystemStates(bool 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.";
m_systemStates = arg;
- emit systemStatesChanged(arg);
+ Q_EMIT systemStatesChanged(arg);
}
}
diff --git a/src/particles/qquicktargetdirection_p.h b/src/particles/qquicktargetdirection_p.h
index 886a560271..50bfdbe8ec 100644
--- a/src/particles/qquicktargetdirection_p.h
+++ b/src/particles/qquicktargetdirection_p.h
@@ -99,7 +99,7 @@ public:
return m_targetItem;
}
-signals:
+Q_SIGNALS:
void targetXChanged(qreal arg);
@@ -115,12 +115,12 @@ signals:
void targetItemChanged(QQuickItem* arg);
-public slots:
+public Q_SLOTS:
void setTargetX(qreal arg)
{
if (m_targetX != arg) {
m_targetX = arg;
- emit targetXChanged(arg);
+ Q_EMIT targetXChanged(arg);
}
}
@@ -128,7 +128,7 @@ public slots:
{
if (m_targetY != arg) {
m_targetY = arg;
- emit targetYChanged(arg);
+ Q_EMIT targetYChanged(arg);
}
}
@@ -136,7 +136,7 @@ public slots:
{
if (m_targetVariation != arg) {
m_targetVariation = arg;
- emit targetVariationChanged(arg);
+ Q_EMIT targetVariationChanged(arg);
}
}
@@ -144,7 +144,7 @@ public slots:
{
if (m_magnitude != arg) {
m_magnitude = arg;
- emit magnitudeChanged(arg);
+ Q_EMIT magnitudeChanged(arg);
}
}
@@ -152,7 +152,7 @@ public slots:
{
if (m_proportionalMagnitude != arg) {
m_proportionalMagnitude = arg;
- emit proprotionalMagnitudeChanged(arg);
+ Q_EMIT proprotionalMagnitudeChanged(arg);
}
}
@@ -160,7 +160,7 @@ public slots:
{
if (m_magnitudeVariation != arg) {
m_magnitudeVariation = arg;
- emit magnitudeVariationChanged(arg);
+ Q_EMIT magnitudeVariationChanged(arg);
}
}
@@ -168,7 +168,7 @@ public slots:
{
if (m_targetItem != arg) {
m_targetItem = arg;
- emit targetItemChanged(arg);
+ Q_EMIT targetItemChanged(arg);
}
}
diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp
index 4f4a05d09a..84caebf5be 100644
--- a/src/particles/qquicktrailemitter.cpp
+++ b/src/particles/qquicktrailemitter.cpp
@@ -272,14 +272,15 @@ void QQuickTrailEmitter::emitWindow(int timeStamp)
QQmlEngine *qmlEngine = ::qmlEngine(this);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine->handle());
- QV4::ArrayObject *array = v4->newArrayObject(toEmit.size());
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::ArrayObject> array(scope, v4->newArrayObject(toEmit.size()));
for (int i=0; i<toEmit.size(); i++)
array->putIndexed(i, toEmit[i]->v4Value().toValue());
if (isEmitFollowConnected())
- emitFollowParticles(QQmlV4Handle(QV4::Value::fromObject(array)), d->v4Value());//A chance for many arbitrary JS changes
+ emitFollowParticles(QQmlV4Handle(array.asValue()), d->v4Value());//A chance for many arbitrary JS changes
else if (isEmitConnected())
- emitParticles(QQmlV4Handle(QV4::Value::fromObject(array)));//A chance for arbitrary JS changes
+ emitParticles(QQmlV4Handle(array.asValue()));//A chance for arbitrary JS changes
}
m_lastEmission[d->index] = pt;
}
diff --git a/src/particles/qquicktrailemitter_p.h b/src/particles/qquicktrailemitter_p.h
index 54041f1751..f3f6884417 100644
--- a/src/particles/qquicktrailemitter_p.h
+++ b/src/particles/qquicktrailemitter_p.h
@@ -90,7 +90,7 @@ public:
return m_emissionExtruder;
}
-signals:
+Q_SIGNALS:
void emitFollowParticles(QQmlV4Handle particles, QQmlV4Handle followed);
void particlesPerParticlePerSecondChanged(int arg);
@@ -103,20 +103,20 @@ signals:
void emissionShapeChanged(QQuickParticleExtruder* arg);
-public slots:
+public Q_SLOTS:
void setParticlesPerParticlePerSecond(int arg)
{
if (m_particlesPerParticlePerSecond != arg) {
m_particlesPerParticlePerSecond = arg;
- emit particlesPerParticlePerSecondChanged(arg);
+ Q_EMIT particlesPerParticlePerSecondChanged(arg);
}
}
void setEmitterXVariation(qreal arg)
{
if (m_emitterXVariation != arg) {
m_emitterXVariation = arg;
- emit emitterXVariationChanged(arg);
+ Q_EMIT emitterXVariationChanged(arg);
}
}
@@ -124,7 +124,7 @@ public slots:
{
if (m_emitterYVariation != arg) {
m_emitterYVariation = arg;
- emit emitterYVariationChanged(arg);
+ Q_EMIT emitterYVariationChanged(arg);
}
}
@@ -132,7 +132,7 @@ public slots:
{
if (m_follow != arg) {
m_follow = arg;
- emit followChanged(arg);
+ Q_EMIT followChanged(arg);
}
}
@@ -140,11 +140,11 @@ public slots:
{
if (m_emissionExtruder != arg) {
m_emissionExtruder = arg;
- emit emissionShapeChanged(arg);
+ Q_EMIT emissionShapeChanged(arg);
}
}
-private slots:
+private Q_SLOTS:
void recalcParticlesPerSecond();
private:
diff --git a/src/particles/qquickturbulence_p.h b/src/particles/qquickturbulence_p.h
index eea550ed15..b66d57fa49 100644
--- a/src/particles/qquickturbulence_p.h
+++ b/src/particles/qquickturbulence_p.h
@@ -67,19 +67,19 @@ class QQuickTurbulenceAffector : public QQuickParticleAffector
{
return m_noiseSource;
}
-signals:
+Q_SIGNALS:
void strengthChanged(qreal arg);
void noiseSourceChanged(QUrl arg);
-public slots:
+public Q_SLOTS:
void setStrength(qreal arg)
{
if (m_strength != arg) {
m_strength = arg;
- emit strengthChanged(arg);
+ Q_EMIT strengthChanged(arg);
}
}
@@ -87,7 +87,7 @@ public slots:
{
if (m_noiseSource != arg) {
m_noiseSource = arg;
- emit noiseSourceChanged(arg);
+ Q_EMIT noiseSourceChanged(arg);
initializeGrid();
}
}
diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp
index 2cb95b4a91..1a574600e0 100644
--- a/src/particles/qquickv4particledata.cpp
+++ b/src/particles/qquickv4particledata.cpp
@@ -298,7 +298,7 @@ public:
QV4::PersistentValue proto;
};
-static QV4::Value particleData_discard(QV4::SimpleCallContext *ctx)
+static QV4::ReturnedValue particleData_discard(QV4::SimpleCallContext *ctx)
{
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>();
@@ -306,101 +306,101 @@ static QV4::Value particleData_discard(QV4::SimpleCallContext *ctx)
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));
r->datum->lifeSpan = 0; //Don't kill(), because it could still be in the middle of being created
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-static QV4::Value particleData_lifeLeft(QV4::SimpleCallContext *ctx)
+static QV4::ReturnedValue particleData_lifeLeft(QV4::SimpleCallContext *ctx)
{
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>();
if (!r || !r->datum)
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));
- return QV4::Value::fromDouble(r->datum->lifeLeft());
+ return QV4::Encode(r->datum->lifeLeft());
}
-static QV4::Value particleData_curSize(QV4::SimpleCallContext *ctx)
+static QV4::ReturnedValue particleData_curSize(QV4::SimpleCallContext *ctx)
{
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>();
if (!r || !r->datum)
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));
- return QV4::Value::fromDouble(r->datum->curSize());
+ return QV4::Encode(r->datum->curSize());
}
-#define COLOR_GETTER_AND_SETTER(VAR, NAME) static QV4::Value particleData_get_ ## NAME (QV4::SimpleCallContext *ctx) \
+#define COLOR_GETTER_AND_SETTER(VAR, NAME) static QV4::ReturnedValue particleData_get_ ## NAME (QV4::SimpleCallContext *ctx) \
{ \
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
if (!r || !r->datum) \
ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \
\
- return QV4::Value::fromDouble((r->datum->color. VAR )/255.0);\
+ return QV4::Encode((r->datum->color. VAR )/255.0);\
}\
\
-static QV4::Value particleData_set_ ## NAME (QV4::SimpleCallContext *ctx)\
+static QV4::ReturnedValue particleData_set_ ## NAME (QV4::SimpleCallContext *ctx)\
{\
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
if (!r || !r->datum)\
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
r->datum->color. VAR = qMin(255, qMax(0, (int)floor(ctx->argument(0).toNumber() * 255.0)));\
- return QV4::Value::undefinedValue(); \
+ return QV4::Encode::undefined(); \
}
-#define SEMIBOOL_GETTER_AND_SETTER(VARIABLE) static QV4::Value particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \
+#define SEMIBOOL_GETTER_AND_SETTER(VARIABLE) static QV4::ReturnedValue particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \
{ \
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
if (!r || !r->datum) \
ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \
\
- return QV4::Value::fromBoolean(r->datum-> VARIABLE);\
+ return QV4::Encode(r->datum-> VARIABLE);\
}\
\
-static QV4::Value particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\
+static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\
{\
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
if (!r || !r->datum)\
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
r->datum-> VARIABLE = ctx->argument(0).toBoolean() ? 1.0 : 0.0;\
- return QV4::Value::undefinedValue(); \
+ return QV4::Encode::undefined(); \
}
-#define FLOAT_GETTER_AND_SETTER(VARIABLE) static QV4::Value particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \
+#define FLOAT_GETTER_AND_SETTER(VARIABLE) static QV4::ReturnedValue particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \
{ \
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
if (!r || !r->datum) \
ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \
\
- return QV4::Value::fromDouble(r->datum-> VARIABLE);\
+ return QV4::Encode(r->datum-> VARIABLE);\
}\
\
-static QV4::Value particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\
+static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\
{\
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
if (!r || !r->datum)\
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
r->datum-> VARIABLE = ctx->argument(0).toNumber();\
- return QV4::Value::undefinedValue(); \
+ return QV4::Encode::undefined(); \
}
-#define FAKE_FLOAT_GETTER_AND_SETTER(VARIABLE, GETTER, SETTER) static QV4::Value particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \
+#define FAKE_FLOAT_GETTER_AND_SETTER(VARIABLE, GETTER, SETTER) static QV4::ReturnedValue particleData_get_ ## VARIABLE (QV4::SimpleCallContext *ctx) \
{ \
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
if (!r || !r->datum) \
ctx->throwError(QStringLiteral("Not a valid ParticleData object")); \
\
- return QV4::Value::fromDouble(r->datum-> GETTER ());\
+ return QV4::Encode(r->datum-> GETTER ());\
}\
\
-static QV4::Value particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\
+static QV4::ReturnedValue particleData_set_ ## VARIABLE (QV4::SimpleCallContext *ctx)\
{\
QV4ParticleData *r = ctx->thisObject.as<QV4ParticleData>(); \
if (!r || !r->datum)\
ctx->throwError(QStringLiteral("Not a valid ParticleData object"));\
\
r->datum-> SETTER ( ctx->argument(0).toNumber() );\
- return QV4::Value::undefinedValue(); \
+ return QV4::Encode::undefined(); \
}
#define REGISTER_ACCESSOR(PROTO, ENGINE, VARIABLE, NAME) \
diff --git a/src/particles/qquickwander_p.h b/src/particles/qquickwander_p.h
index 0f09418ea2..efa68910d4 100644
--- a/src/particles/qquickwander_p.h
+++ b/src/particles/qquickwander_p.h
@@ -97,7 +97,7 @@ public:
protected:
virtual bool affectParticle(QQuickParticleData *d, qreal dt);
-signals:
+Q_SIGNALS:
void xVarianceChanged(qreal arg);
@@ -108,12 +108,12 @@ signals:
void affectedParameterChanged(AffectableParameters arg);
-public slots:
+public Q_SLOTS:
void setXVariance(qreal arg)
{
if (m_xVariance != arg) {
m_xVariance = arg;
- emit xVarianceChanged(arg);
+ Q_EMIT xVarianceChanged(arg);
}
}
@@ -121,7 +121,7 @@ void setYVariance(qreal arg)
{
if (m_yVariance != arg) {
m_yVariance = arg;
- emit yVarianceChanged(arg);
+ Q_EMIT yVarianceChanged(arg);
}
}
@@ -129,7 +129,7 @@ void setPace(qreal arg)
{
if (m_pace != arg) {
m_pace = arg;
- emit paceChanged(arg);
+ Q_EMIT paceChanged(arg);
}
}
@@ -138,7 +138,7 @@ void setAffectedParameter(AffectableParameters arg)
{
if (m_affectedParameter != arg) {
m_affectedParameter = arg;
- emit affectedParameterChanged(arg);
+ Q_EMIT affectedParameterChanged(arg);
}
}
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 52875ce41a..bd4b1f2c9d 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -61,9 +61,6 @@
#undef CONST
#endif
-#define QV4_NO_LIVENESS
-#undef SHOW_SSA
-
using namespace QQmlJS;
using namespace AST;
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index cdcc407e2a..bdc5c885c9 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -48,6 +48,8 @@
#include <private/qv4regexpobject_p.h>
#include <private/qv4unwindhelper_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -94,7 +96,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
flags |= QQmlJS::V4IR::RegExp::RegExp_IgnoreCase;
if (re->flags & CompiledData::RegExp::RegExp_Multiline)
flags |= QQmlJS::V4IR::RegExp::RegExp_Multiline;
- QV4::RegExpObject *obj = engine->newRegExpObject(data->stringAt(re->stringIndex), flags);
+ QV4::RegExpObject *obj = engine->newRegExpObject(data->stringAt(re->stringIndex), flags)->getPointer();
runtimeRegularExpressions[i] = QV4::Value::fromObject(obj);
}
@@ -138,7 +140,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
#if 0
runtimeFunctionsSortedByAddress.resize(runtimeFunctions.size());
memcpy(runtimeFunctionsSortedByAddress.data(), runtimeFunctions.data(), runtimeFunctions.size() * sizeof(QV4::Function*));
- qSort(runtimeFunctionsSortedByAddress.begin(), runtimeFunctionsSortedByAddress.end(), functionSortHelper);
+ std::sort(runtimeFunctionsSortedByAddress.begin(), runtimeFunctionsSortedByAddress.end(), functionSortHelper);
#endif
return runtimeFunctions[data->indexOfRootFunction];
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 68bc109eb4..af1ca0ae76 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE
F(LoadRegExp, loadRegExp) \
F(LoadClosure, loadClosure) \
F(MoveTemp, moveTemp) \
+ F(SwapTemps, swapTemps) \
F(LoadName, loadName) \
F(StoreName, storeName) \
F(LoadElement, loadElement) \
@@ -81,14 +82,6 @@ QT_BEGIN_NAMESPACE
F(CallBuiltinTypeofSubscript, callBuiltinTypeofSubscript) \
F(CallBuiltinTypeofName, callBuiltinTypeofName) \
F(CallBuiltinTypeofValue, callBuiltinTypeofValue) \
- F(CallBuiltinPostIncMember, callBuiltinPostIncMember) \
- F(CallBuiltinPostIncSubscript, callBuiltinPostIncSubscript) \
- F(CallBuiltinPostIncName, callBuiltinPostIncName) \
- F(CallBuiltinPostIncValue, callBuiltinPostIncValue) \
- F(CallBuiltinPostDecMember, callBuiltinPostDecMember) \
- F(CallBuiltinPostDecSubscript, callBuiltinPostDecSubscript) \
- F(CallBuiltinPostDecName, callBuiltinPostDecName) \
- F(CallBuiltinPostDecValue, callBuiltinPostDecValue) \
F(CallBuiltinDeclareVar, callBuiltinDeclareVar) \
F(CallBuiltinDefineGetterSetter, callBuiltinDefineGetterSetter) \
F(CallBuiltinDefineProperty, callBuiltinDefineProperty) \
@@ -236,6 +229,11 @@ union Instr
Param source;
Param result;
};
+ struct instr_swapTemps {
+ MOTH_INSTR_HEADER
+ Param left;
+ Param right;
+ };
struct instr_loadClosure {
MOTH_INSTR_HEADER
int value;
@@ -379,50 +377,6 @@ union Instr
Param value;
Param result;
};
- struct instr_callBuiltinPostIncMember {
- MOTH_INSTR_HEADER
- Param base;
- int member;
- Param result;
- };
- struct instr_callBuiltinPostIncSubscript {
- MOTH_INSTR_HEADER
- Param base;
- Param index;
- Param result;
- };
- struct instr_callBuiltinPostIncName {
- MOTH_INSTR_HEADER
- int name;
- Param result;
- };
- struct instr_callBuiltinPostIncValue {
- MOTH_INSTR_HEADER
- Param value;
- Param result;
- };
- struct instr_callBuiltinPostDecMember {
- MOTH_INSTR_HEADER
- Param base;
- int member;
- Param result;
- };
- struct instr_callBuiltinPostDecSubscript {
- MOTH_INSTR_HEADER
- Param base;
- Param index;
- Param result;
- };
- struct instr_callBuiltinPostDecName {
- MOTH_INSTR_HEADER
- int name;
- Param result;
- };
- struct instr_callBuiltinPostDecValue {
- MOTH_INSTR_HEADER
- Param value;
- Param result;
- };
struct instr_callBuiltinDeclareVar {
MOTH_INSTR_HEADER
int varName;
@@ -557,6 +511,7 @@ union Instr
instr_loadRuntimeString loadRuntimeString;
instr_loadRegExp loadRegExp;
instr_moveTemp moveTemp;
+ instr_swapTemps swapTemps;
instr_loadClosure loadClosure;
instr_loadName loadName;
instr_storeName storeName;
@@ -583,14 +538,6 @@ union Instr
instr_callBuiltinTypeofSubscript callBuiltinTypeofSubscript;
instr_callBuiltinTypeofName callBuiltinTypeofName;
instr_callBuiltinTypeofValue callBuiltinTypeofValue;
- instr_callBuiltinPostIncMember callBuiltinPostIncMember;
- instr_callBuiltinPostIncSubscript callBuiltinPostIncSubscript;
- instr_callBuiltinPostIncName callBuiltinPostIncName;
- instr_callBuiltinPostIncValue callBuiltinPostIncValue;
- instr_callBuiltinPostDecMember callBuiltinPostDecMember;
- instr_callBuiltinPostDecSubscript callBuiltinPostDecSubscript;
- instr_callBuiltinPostDecName callBuiltinPostDecName;
- instr_callBuiltinPostDecValue callBuiltinPostDecValue;
instr_callBuiltinDeclareVar callBuiltinDeclareVar;
instr_callBuiltinDefineGetterSetter callBuiltinDefineGetterSetter;
instr_callBuiltinDefineProperty callBuiltinDefineProperty;
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 19c7039e69..c7f2302e7f 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -79,8 +79,8 @@ void CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
const CompiledData::Function *compiledFunction = data->functionAt(i);
QV4::Function *runtimeFunction = new QV4::Function(engine, this, compiledFunction,
- (Value (*)(QV4::ExecutionContext *, const uchar *)) codeRefs[i].code().executableAddress(),
- codeRefs[i].size());
+ (ReturnedValue (*)(QV4::ExecutionContext *, const uchar *)) codeRefs[i].code().executableAddress(),
+ codeSizes[i]);
runtimeFunctions[i] = runtimeFunction;
}
@@ -167,6 +167,13 @@ protected:
virtual void visitTry(V4IR::Try *s) { s->exceptionVar->accept(this); }
virtual void visitPhi(V4IR::Phi *) { Q_UNREACHABLE(); }
};
+
+inline bool isPregOrConst(V4IR::Expr *e)
+{
+ if (V4IR::Temp *t = e->asTemp())
+ return t->kind == V4IR::Temp::PhysicalRegister;
+ return e->asConst() != 0;
+}
} // anonymous namespace
/* Platform/Calling convention/Architecture specific section */
@@ -283,7 +290,7 @@ Assembler::Pointer Assembler::loadTempAddress(RegisterID reg, V4IR::Temp *t)
return stackSlotPointer(t);
} break;
default:
- Q_UNIMPLEMENTED();
+ Q_UNREACHABLE();
}
return Pointer(reg, offset);
}
@@ -312,26 +319,33 @@ void Assembler::copyValue(Result result, Source source)
template <typename Result>
void Assembler::copyValue(Result result, V4IR::Expr* source)
{
-#ifdef VALUE_FITS_IN_REGISTER
- if (source->type == V4IR::DoubleType) {
+ if (source->type == V4IR::BoolType) {
+ RegisterID reg = toInt32Register(source, ScratchRegister);
+ storeBool(reg, result);
+ } else if (source->type == V4IR::SInt32Type) {
+ RegisterID reg = toInt32Register(source, ScratchRegister);
+ storeInt32(reg, result);
+ } else if (source->type == V4IR::UInt32Type) {
+ RegisterID reg = toUInt32Register(source, ScratchRegister);
+ storeUInt32(reg, result);
+ } else if (source->type == V4IR::DoubleType) {
storeDouble(toDoubleRegister(source), result);
- } else {
+ } else if (V4IR::Temp *temp = source->asTemp()) {
+#ifdef VALUE_FITS_IN_REGISTER
// Use ReturnValueRegister as "scratch" register because loadArgument
// and storeArgument are functions that may need a scratch register themselves.
loadArgumentInRegister(source, ReturnValueRegister, 0);
storeReturnValue(result);
- }
#else
- if (V4IR::Temp *temp = source->asTemp()) {
loadDouble(temp, FPGpr0);
storeDouble(FPGpr0, result);
+#endif
} else if (V4IR::Const *c = source->asConst()) {
QV4::Value v = convertToValue(c);
storeValue(v, result);
} else {
- assert(! "not implemented");
+ Q_UNREACHABLE();
}
-#endif
}
@@ -458,10 +472,10 @@ void Assembler::recordLineNumber(int lineNumber)
}
-JSC::MacroAssemblerCodeRef Assembler::link()
+JSC::MacroAssemblerCodeRef Assembler::link(int *codeSize)
{
-#if defined(Q_PROCESSOR_ARM) && !defined(Q_OS_IOS)
Label endOfCode = label();
+#if defined(Q_PROCESSOR_ARM) && !defined(Q_OS_IOS)
// Let the ARM exception table follow right after that
for (int i = 0, nops = UnwindHelper::unwindInfoSize() / 2; i < nops; ++i)
nop();
@@ -512,8 +526,9 @@ JSC::MacroAssemblerCodeRef Assembler::link()
}
_constTable.finalize(linkBuffer, _isel);
+ *codeSize = linkBuffer.offsetOf(endOfCode);
#if defined(Q_PROCESSOR_ARM) && !defined(Q_OS_IOS)
- UnwindHelper::writeARMUnwindInfo(linkBuffer.debugAddress(), linkBuffer.offsetOf(endOfCode));
+ UnwindHelper::writeARMUnwindInfo(linkBuffer.debugAddress(), *codeSize);
#endif
JSC::MacroAssemblerCodeRef codeRef;
@@ -576,6 +591,8 @@ InstructionSelection::InstructionSelection(QV4::ExecutableAllocator *execAllocat
, _as(0)
{
compilationUnit = new CompilationUnit;
+ compilationUnit->codeRefs.resize(module->functions.size());
+ compilationUnit->codeSizes.resize(module->functions.size());
}
InstructionSelection::~InstructionSelection()
@@ -583,8 +600,9 @@ InstructionSelection::~InstructionSelection()
delete _as;
}
-void InstructionSelection::run(V4IR::Function *function)
+void InstructionSelection::run(int functionIndex)
{
+ V4IR::Function *function = irModule->functions[functionIndex];
QVector<Lookup> lookups;
QSet<V4IR::BasicBlock*> reentryBlocks;
qSwap(_function, function);
@@ -592,8 +610,10 @@ void InstructionSelection::run(V4IR::Function *function)
V4IR::Optimizer opt(_function);
opt.run();
- if (opt.isInSSA()) {
+
#if CPU(X86_64) && (OS(MAC_OS_X) || OS(LINUX))
+ static const bool withRegisterAllocator = qgetenv("QV4_NO_REGALLOC").isEmpty();
+ if (opt.isInSSA() && withRegisterAllocator) {
static const QVector<int> intRegisters = QVector<int>()
<< JSC::X86Registers::edi
<< JSC::X86Registers::esi
@@ -611,12 +631,12 @@ void InstructionSelection::run(V4IR::Function *function)
<< JSC::X86Registers::xmm6
<< JSC::X86Registers::xmm7;
RegisterAllocator(intRegisters, fpRegisters).run(_function, opt);
-#else
- // No register allocator available for this platform, so:
- opt.convertOutOfSSA();
- ConvertTemps().toStackSlots(_function);
+ } else
#endif
- } else {
+ {
+ if (opt.isInSSA())
+ // No register allocator available for this platform, or env. var was set, so:
+ opt.convertOutOfSSA();
ConvertTemps().toStackSlots(_function);
}
V4IR::Optimizer::showMeTheCode(_function);
@@ -626,18 +646,10 @@ void InstructionSelection::run(V4IR::Function *function)
_as->enterStandardStackFrame();
- int contextPointer = 0;
-#if !defined(RETURN_VALUE_IN_REGISTER)
- // When the return VM value doesn't fit into a register, then
- // the caller provides a pointer for storage as first argument.
- // That shifts the index the context pointer argument by one.
- contextPointer++;
-#endif
-
#ifdef ARGUMENTS_IN_REGISTERS
- _as->move(_as->registerForArgument(contextPointer), Assembler::ContextRegister);
+ _as->move(_as->registerForArgument(0), Assembler::ContextRegister);
#else
- _as->loadPtr(addressForArgument(contextPointer), Assembler::ContextRegister);
+ _as->loadPtr(addressForArgument(0), Assembler::ContextRegister);
#endif
const int locals = _as->stackLayout().calculateJSStackFrameSize();
@@ -669,8 +681,8 @@ void InstructionSelection::run(V4IR::Function *function)
}
}
- JSC::MacroAssemblerCodeRef codeRef =_as->link();
- codeRefs[_function] = codeRef;
+ JSC::MacroAssemblerCodeRef codeRef =_as->link(&compilationUnit->codeSizes[functionIndex]);
+ compilationUnit->codeRefs[functionIndex] = codeRef;
qSwap(_function, function);
qSwap(_reentryBlocks, reentryBlocks);
@@ -690,10 +702,6 @@ void *InstructionSelection::addConstantTable(QVector<Value> *values)
QV4::CompiledData::CompilationUnit *InstructionSelection::backendCompileStep()
{
- compilationUnit->codeRefs.resize(irModule->functions.size());
- int i = 0;
- foreach (V4IR::Function *irFunction, irModule->functions)
- compilationUnit->codeRefs[i++] = codeRefs[irFunction];
return compilationUnit;
}
@@ -703,13 +711,13 @@ void InstructionSelection::callBuiltinInvalid(V4IR::Name *func, V4IR::ExprList *
if (useFastLookups && func->global) {
uint index = registerGlobalGetterLookup(*func->id);
- generateFunctionCall(Assembler::Void, __qmljs_call_global_lookup,
- Assembler::ContextRegister, Assembler::PointerToValue(result),
+ generateFunctionCall(result, __qmljs_call_global_lookup,
+ Assembler::ContextRegister,
Assembler::TrustedImm32(index),
baseAddressForCallData());
} else {
- generateFunctionCall(Assembler::Void, __qmljs_call_activation_property,
- Assembler::ContextRegister, Assembler::PointerToValue(result),
+ generateFunctionCall(result, __qmljs_call_activation_property,
+ Assembler::ContextRegister,
Assembler::PointerToString(*func->id),
baseAddressForCallData());
}
@@ -718,50 +726,47 @@ void InstructionSelection::callBuiltinInvalid(V4IR::Name *func, V4IR::ExprList *
void InstructionSelection::callBuiltinTypeofMember(V4IR::Expr *base, const QString &name,
V4IR::Temp *result)
{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_typeof_member, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::PointerToValue(base),
- Assembler::PointerToString(name));
+ generateFunctionCall(result, __qmljs_builtin_typeof_member, Assembler::ContextRegister,
+ Assembler::PointerToValue(base), Assembler::PointerToString(name));
}
void InstructionSelection::callBuiltinTypeofSubscript(V4IR::Expr *base, V4IR::Expr *index,
V4IR::Temp *result)
{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_typeof_element,
- Assembler::ContextRegister, Assembler::PointerToValue(result),
+ generateFunctionCall(result, __qmljs_builtin_typeof_element,
+ Assembler::ContextRegister,
Assembler::PointerToValue(base), Assembler::PointerToValue(index));
}
void InstructionSelection::callBuiltinTypeofName(const QString &name, V4IR::Temp *result)
{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_typeof_name, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::PointerToString(name));
+ generateFunctionCall(result, __qmljs_builtin_typeof_name, Assembler::ContextRegister,
+ Assembler::PointerToString(name));
}
void InstructionSelection::callBuiltinTypeofValue(V4IR::Expr *value, V4IR::Temp *result)
{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_typeof, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::PointerToValue(value));
+ generateFunctionCall(result, __qmljs_builtin_typeof, Assembler::ContextRegister,
+ Assembler::PointerToValue(value));
}
void InstructionSelection::callBuiltinDeleteMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result)
{
- generateFunctionCall(Assembler::Void, __qmljs_delete_member, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::Reference(base),
- Assembler::PointerToString(name));
+ generateFunctionCall(result, __qmljs_delete_member, Assembler::ContextRegister,
+ Assembler::Reference(base), Assembler::PointerToString(name));
}
void InstructionSelection::callBuiltinDeleteSubscript(V4IR::Temp *base, V4IR::Expr *index,
V4IR::Temp *result)
{
- generateFunctionCall(Assembler::Void, __qmljs_delete_subscript, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::Reference(base),
- Assembler::PointerToValue(index));
+ generateFunctionCall(result, __qmljs_delete_subscript, Assembler::ContextRegister,
+ Assembler::Reference(base), Assembler::PointerToValue(index));
}
void InstructionSelection::callBuiltinDeleteName(const QString &name, V4IR::Temp *result)
{
- generateFunctionCall(Assembler::Void, __qmljs_delete_name, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::PointerToString(name));
+ generateFunctionCall(result, __qmljs_delete_name, Assembler::ContextRegister,
+ Assembler::PointerToString(name));
}
void InstructionSelection::callBuiltinDeleteValue(V4IR::Temp *result)
@@ -769,57 +774,6 @@ void InstructionSelection::callBuiltinDeleteValue(V4IR::Temp *result)
_as->storeValue(Value::fromBoolean(false), result);
}
-void InstructionSelection::callBuiltinPostIncrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result)
-{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_post_increment_member,
- Assembler::ContextRegister, Assembler::PointerToValue(result),
- Assembler::PointerToValue(base), Assembler::PointerToString(name));
-}
-
-void InstructionSelection::callBuiltinPostIncrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result)
-{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_post_increment_element,
- Assembler::ContextRegister, Assembler::PointerToValue(result),
- Assembler::Reference(base), Assembler::PointerToValue(index));
-}
-
-void InstructionSelection::callBuiltinPostIncrementName(const QString &name, V4IR::Temp *result)
-{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_post_increment_name, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::PointerToString(name));
-}
-
-void InstructionSelection::callBuiltinPostIncrementValue(V4IR::Temp *value, V4IR::Temp *result)
-{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_post_increment,
- Assembler::PointerToValue(result), Assembler::PointerToValue(value));
-}
-
-void InstructionSelection::callBuiltinPostDecrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result)
-{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_post_decrement_member, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::Reference(base), Assembler::PointerToString(name));
-}
-
-void InstructionSelection::callBuiltinPostDecrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result)
-{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_post_decrement_element, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::Reference(base),
- Assembler::Reference(index));
-}
-
-void InstructionSelection::callBuiltinPostDecrementName(const QString &name, V4IR::Temp *result)
-{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_post_decrement_name, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::PointerToString(name));
-}
-
-void InstructionSelection::callBuiltinPostDecrementValue(V4IR::Temp *value, V4IR::Temp *result)
-{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_post_decrement,
- Assembler::PointerToValue(result), Assembler::PointerToValue(value));
-}
-
void InstructionSelection::callBuiltinThrow(V4IR::Expr *arg)
{
generateFunctionCall(Assembler::Void, __qmljs_throw, Assembler::ContextRegister,
@@ -828,9 +782,9 @@ void InstructionSelection::callBuiltinThrow(V4IR::Expr *arg)
typedef void *(*MiddleOfFunctionEntryPoint(ExecutionContext *, void *localsPtr));
static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunctionEntryPoint tryBody, MiddleOfFunctionEntryPoint catchBody,
- QV4::String *exceptionVarName, Value *exceptionVar)
+ QV4::String *exceptionVarName, ValueRef exceptionVar)
{
- *exceptionVar = Value::undefinedValue();
+ exceptionVar = Value::undefinedValue();
void *addressToContinueAt = 0;
Value *jsStackTop = context->engine->jsStackTop;
try {
@@ -838,16 +792,16 @@ static void *tryWrapper(ExecutionContext *context, void *localsPtr, MiddleOfFunc
} catch (Exception& ex) {
context->engine->jsStackTop = jsStackTop;
ex.accept(context);
- *exceptionVar = ex.value();
+ exceptionVar = ex.value();
try {
- QV4::ValueScope scope(context);
+ QV4::Scope scope(context);
QV4::ScopedValue exception(scope, ex.value());
ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(exceptionVarName, exception, context);
addressToContinueAt = catchBody(catchContext, localsPtr);
context = __qmljs_builtin_pop_scope(catchContext);
} catch (Exception& ex) {
context->engine->jsStackTop = jsStackTop;
- *exceptionVar = ex.value();
+ exceptionVar = ex.value();
ex.accept(context);
addressToContinueAt = catchBody(context, localsPtr);
}
@@ -885,7 +839,7 @@ void InstructionSelection::callBuiltinForeachIteratorObject(V4IR::Temp *arg, V4I
Q_ASSERT(arg);
Q_ASSERT(result);
- generateFunctionCall(Assembler::Void, __qmljs_foreach_iterator_object, Assembler::ContextRegister, Assembler::PointerToValue(result), Assembler::Reference(arg));
+ generateFunctionCall(result, __qmljs_foreach_iterator_object, Assembler::ContextRegister, Assembler::Reference(arg));
}
void InstructionSelection::callBuiltinForeachNextPropertyname(V4IR::Temp *arg, V4IR::Temp *result)
@@ -893,7 +847,7 @@ void InstructionSelection::callBuiltinForeachNextPropertyname(V4IR::Temp *arg, V
Q_ASSERT(arg);
Q_ASSERT(result);
- generateFunctionCall(Assembler::Void, __qmljs_foreach_next_property_name, Assembler::PointerToValue(result), Assembler::Reference(arg));
+ generateFunctionCall(result, __qmljs_foreach_next_property_name, Assembler::Reference(arg));
}
void InstructionSelection::callBuiltinPushWithScope(V4IR::Temp *arg)
@@ -930,7 +884,8 @@ void InstructionSelection::callBuiltinDefineProperty(V4IR::Temp *object, const Q
Q_ASSERT(value->asTemp() || value->asConst());
generateFunctionCall(Assembler::Void, __qmljs_builtin_define_property,
- Assembler::ContextRegister, Assembler::Reference(object), Assembler::PointerToString(name),
+ Assembler::ContextRegister, Assembler::Reference(object),
+ Assembler::PointerToString(name),
Assembler::PointerToValue(value));
}
@@ -939,9 +894,8 @@ void InstructionSelection::callBuiltinDefineArray(V4IR::Temp *result, V4IR::Expr
Q_ASSERT(result);
int length = prepareVariableArguments(args);
- generateFunctionCall(Assembler::Void, __qmljs_builtin_define_array, Assembler::ContextRegister,
- Assembler::PointerToValue(result), baseAddressForCallArguments(),
- Assembler::TrustedImm32(length));
+ generateFunctionCall(result, __qmljs_builtin_define_array, Assembler::ContextRegister,
+ baseAddressForCallArguments(), Assembler::TrustedImm32(length));
}
void InstructionSelection::callBuiltinDefineObjectLiteral(V4IR::Temp *result, V4IR::ExprList *args)
@@ -969,15 +923,13 @@ void InstructionSelection::callBuiltinDefineObjectLiteral(V4IR::Temp *result, V4
it = it->next;
}
- generateFunctionCall(Assembler::Void, __qmljs_builtin_define_object_literal, Assembler::ContextRegister,
- Assembler::PointerToValue(result), baseAddressForCallArguments(),
- Assembler::TrustedImm32(classId));
+ generateFunctionCall(result, __qmljs_builtin_define_object_literal, Assembler::ContextRegister,
+ baseAddressForCallArguments(), Assembler::TrustedImm32(classId));
}
void InstructionSelection::callBuiltinSetupArgumentObject(V4IR::Temp *result)
{
- generateFunctionCall(Assembler::Void, __qmljs_builtin_setup_arguments_object, Assembler::ContextRegister,
- Assembler::PointerToValue(result));
+ generateFunctionCall(result, __qmljs_builtin_setup_arguments_object, Assembler::ContextRegister);
}
void InstructionSelection::callValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result)
@@ -985,8 +937,8 @@ void InstructionSelection::callValue(V4IR::Temp *value, V4IR::ExprList *args, V4
Q_ASSERT(value);
int argc = prepareCallData(args, 0);
- generateFunctionCall(Assembler::Void, __qmljs_call_value, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::Reference(value),
+ generateFunctionCall(result, __qmljs_call_value, Assembler::ContextRegister,
+ Assembler::Reference(value),
baseAddressForCallData());
}
@@ -1018,7 +970,7 @@ void InstructionSelection::loadConst(V4IR::Const *sourceConst, V4IR::Temp *targe
_as->move(Assembler::TrustedImm32(convertToValue(sourceConst).int_32),
(Assembler::RegisterID) targetTemp->index);
} else {
- Q_UNIMPLEMENTED();
+ Q_UNREACHABLE();
}
} else {
_as->storeValue(convertToValue(sourceConst), targetTemp);
@@ -1027,27 +979,39 @@ void InstructionSelection::loadConst(V4IR::Const *sourceConst, V4IR::Temp *targe
void InstructionSelection::loadString(const QString &str, V4IR::Temp *targetTemp)
{
- generateFunctionCall(Assembler::Void, __qmljs_value_from_string, Assembler::PointerToValue(targetTemp), Assembler::PointerToString(str));
+ Pointer srcAddr = _as->loadStringAddress(Assembler::ReturnValueRegister, str);
+ _as->loadPtr(srcAddr, Assembler::ReturnValueRegister);
+ Pointer destAddr = _as->loadTempAddress(Assembler::ScratchRegister, targetTemp);
+#if QT_POINTER_SIZE == 8
+ _as->or64(Assembler::TrustedImm64(quint64(QV4::Value::Managed_Type) << QV4::Value::Tag_Shift),
+ Assembler::ReturnValueRegister);
+ _as->store64(Assembler::ReturnValueRegister, destAddr);
+#else
+ _as->store32(Assembler::ReturnValueRegister, destAddr);
+ destAddr.offset += 4;
+ _as->store32(Assembler::TrustedImm32(QV4::Value::Managed_Type), destAddr);
+#endif
}
void InstructionSelection::loadRegexp(V4IR::RegExp *sourceRegexp, V4IR::Temp *targetTemp)
{
int id = registerRegExp(sourceRegexp);
- generateFunctionCall(Assembler::Void, __qmljs_lookup_runtime_regexp, Assembler::ContextRegister, Assembler::PointerToValue(targetTemp), Assembler::TrustedImm32(id));
+ generateFunctionCall(targetTemp, __qmljs_lookup_runtime_regexp, Assembler::ContextRegister, Assembler::TrustedImm32(id));
}
void InstructionSelection::getActivationProperty(const V4IR::Name *name, V4IR::Temp *temp)
{
if (useFastLookups && name->global) {
uint index = registerGlobalGetterLookup(*name->id);
- generateLookupCall(index, offsetof(QV4::Lookup, globalGetter), Assembler::ContextRegister, Assembler::PointerToValue(temp));
+ generateLookupCall(temp, index, offsetof(QV4::Lookup, globalGetter), Assembler::ContextRegister, Assembler::Void);
return;
}
- generateFunctionCall(Assembler::Void, __qmljs_get_activation_property, Assembler::ContextRegister, Assembler::PointerToValue(temp), Assembler::PointerToString(*name->id));
+ generateFunctionCall(temp, __qmljs_get_activation_property, Assembler::ContextRegister, Assembler::PointerToString(*name->id));
}
void InstructionSelection::setActivationProperty(V4IR::Expr *source, const QString &targetName)
{
+ // ### should use a lookup call here
generateFunctionCall(Assembler::Void, __qmljs_set_activation_property,
Assembler::ContextRegister, Assembler::PointerToString(targetName), Assembler::PointerToValue(source));
}
@@ -1055,19 +1019,17 @@ void InstructionSelection::setActivationProperty(V4IR::Expr *source, const QStri
void InstructionSelection::initClosure(V4IR::Closure *closure, V4IR::Temp *target)
{
int id = irModule->functions.indexOf(closure->value);
- generateFunctionCall(Assembler::Void, __qmljs_init_closure, Assembler::ContextRegister, Assembler::PointerToValue(target), Assembler::TrustedImm32(id));
+ generateFunctionCall(target, __qmljs_init_closure, Assembler::ContextRegister, Assembler::TrustedImm32(id));
}
void InstructionSelection::getProperty(V4IR::Expr *base, const QString &name, V4IR::Temp *target)
{
if (useFastLookups) {
uint index = registerGetterLookup(name);
- generateLookupCall(index, offsetof(QV4::Lookup, getter), Assembler::PointerToValue(target),
- Assembler::PointerToValue(base));
+ generateLookupCall(target, index, offsetof(QV4::Lookup, getter), Assembler::PointerToValue(base), Assembler::Void);
} else {
- generateFunctionCall(Assembler::Void, __qmljs_get_property, Assembler::ContextRegister,
- Assembler::PointerToValue(target), Assembler::PointerToValue(base),
- Assembler::PointerToString(name));
+ generateFunctionCall(target, __qmljs_get_property, Assembler::ContextRegister,
+ Assembler::PointerToValue(base), Assembler::PointerToString(name));
}
}
@@ -1076,7 +1038,7 @@ void InstructionSelection::setProperty(V4IR::Expr *source, V4IR::Expr *targetBas
{
if (useFastLookups) {
uint index = registerSetterLookup(targetName);
- generateLookupCall(index, offsetof(QV4::Lookup, setter),
+ generateLookupCall(Assembler::Void, index, offsetof(QV4::Lookup, setter),
Assembler::PointerToValue(targetBase),
Assembler::PointerToValue(source));
} else {
@@ -1088,9 +1050,8 @@ void InstructionSelection::setProperty(V4IR::Expr *source, V4IR::Expr *targetBas
void InstructionSelection::getElement(V4IR::Expr *base, V4IR::Expr *index, V4IR::Temp *target)
{
- generateFunctionCall(Assembler::Void, __qmljs_get_element, Assembler::ContextRegister,
- Assembler::PointerToValue(target), Assembler::PointerToValue(base),
- Assembler::PointerToValue(index));
+ generateFunctionCall(target, __qmljs_get_element, Assembler::ContextRegister,
+ Assembler::PointerToValue(base), Assembler::PointerToValue(index));
}
void InstructionSelection::setElement(V4IR::Expr *source, V4IR::Expr *targetBase, V4IR::Expr *targetIndex)
@@ -1115,19 +1076,18 @@ void InstructionSelection::copyValue(V4IR::Temp *sourceTemp, V4IR::Temp *targetT
(Assembler::RegisterID) targetTemp->index);
return;
} else {
- Assembler::Pointer addr = _as->loadTempAddress(Assembler::ScratchRegister, targetTemp);
switch (sourceTemp->type) {
case V4IR::DoubleType:
- _as->storeDouble((Assembler::FPRegisterID) sourceTemp->index, addr);
+ _as->storeDouble((Assembler::FPRegisterID) sourceTemp->index, targetTemp);
break;
case V4IR::SInt32Type:
- _as->storeInt32((Assembler::RegisterID) sourceTemp->index, addr);
+ _as->storeInt32((Assembler::RegisterID) sourceTemp->index, targetTemp);
break;
case V4IR::UInt32Type:
- _as->storeUInt32((Assembler::RegisterID) sourceTemp->index, addr);
+ _as->storeUInt32((Assembler::RegisterID) sourceTemp->index, targetTemp);
break;
case V4IR::BoolType:
- _as->storeBool((Assembler::RegisterID) sourceTemp->index, addr);
+ _as->storeBool((Assembler::RegisterID) sourceTemp->index, targetTemp);
break;
default:
Q_ASSERT(!"Unreachable");
@@ -1164,10 +1124,10 @@ void InstructionSelection::copyValue(V4IR::Temp *sourceTemp, V4IR::Temp *targetT
void InstructionSelection::swapValues(V4IR::Temp *sourceTemp, V4IR::Temp *targetTemp)
{
- Q_ASSERT(sourceTemp->type == targetTemp->type);
-
if (sourceTemp->kind == V4IR::Temp::PhysicalRegister) {
if (targetTemp->kind == V4IR::Temp::PhysicalRegister) {
+ Q_ASSERT(sourceTemp->type == targetTemp->type);
+
if (sourceTemp->type == V4IR::DoubleType) {
_as->moveDouble((Assembler::FPRegisterID) targetTemp->index, Assembler::FPGpr0);
_as->moveDouble((Assembler::FPRegisterID) sourceTemp->index,
@@ -1181,11 +1141,14 @@ void InstructionSelection::swapValues(V4IR::Temp *sourceTemp, V4IR::Temp *target
}
} else if (sourceTemp->kind == V4IR::Temp::StackSlot) {
if (targetTemp->kind == V4IR::Temp::StackSlot) {
- Assembler::FPRegisterID tReg = _as->toDoubleRegister(targetTemp);
+ // Note: a swap for two stack-slots can involve different types.
#if CPU(X86_64)
+ _as->load64(_as->stackSlotPointer(targetTemp), Assembler::ReturnValueRegister);
_as->load64(_as->stackSlotPointer(sourceTemp), Assembler::ScratchRegister);
_as->store64(Assembler::ScratchRegister, _as->stackSlotPointer(targetTemp));
+ _as->store64(Assembler::ReturnValueRegister, _as->stackSlotPointer(sourceTemp));
#else
+ Assembler::FPRegisterID tReg = _as->toDoubleRegister(targetTemp);
Assembler::Pointer sAddr = _as->stackSlotPointer(sourceTemp);
Assembler::Pointer tAddr = _as->stackSlotPointer(targetTemp);
_as->load32(sAddr, Assembler::ScratchRegister);
@@ -1194,14 +1157,43 @@ void InstructionSelection::swapValues(V4IR::Temp *sourceTemp, V4IR::Temp *target
tAddr.offset += 4;
_as->load32(sAddr, Assembler::ScratchRegister);
_as->store32(Assembler::ScratchRegister, tAddr);
-#endif
_as->storeDouble(tReg, _as->stackSlotPointer(sourceTemp));
+#endif
return;
}
}
- // FIXME: TODO!
- Q_UNIMPLEMENTED();
+ V4IR::Temp *stackTemp = sourceTemp->kind == V4IR::Temp::StackSlot ? sourceTemp : targetTemp;
+ V4IR::Temp *registerTemp = sourceTemp->kind == V4IR::Temp::PhysicalRegister ? sourceTemp
+ : targetTemp;
+ Assembler::Pointer addr = _as->stackSlotPointer(stackTemp);
+ if (registerTemp->type == V4IR::DoubleType) {
+ _as->loadDouble(addr, Assembler::FPGpr0);
+ _as->storeDouble((Assembler::FPRegisterID) registerTemp->index, addr);
+ _as->moveDouble(Assembler::FPGpr0, (Assembler::FPRegisterID) registerTemp->index);
+ } else if (registerTemp->type == V4IR::UInt32Type) {
+ _as->toUInt32Register(addr, Assembler::ScratchRegister);
+ _as->storeUInt32((Assembler::RegisterID) registerTemp->index, addr);
+ _as->move(Assembler::ScratchRegister, (Assembler::RegisterID) registerTemp->index);
+ } else {
+ _as->load32(addr, Assembler::ScratchRegister);
+ _as->store32((Assembler::RegisterID) registerTemp->index, addr);
+ addr.offset += 4;
+ QV4::Value tag;
+ switch (registerTemp->type) {
+ case V4IR::BoolType:
+ tag = QV4::Value::fromBoolean(false);
+ break;
+ case V4IR::SInt32Type:
+ tag = QV4::Value::fromInt32(0);
+ break;
+ default:
+ tag = QV4::Value::undefinedValue();
+ Q_UNREACHABLE();
+ }
+ _as->store32(Assembler::TrustedImm32(tag.tag), addr);
+ _as->move(Assembler::ScratchRegister, (Assembler::RegisterID) registerTemp->index);
+ }
}
#define setOp(op, opName, operation) \
@@ -1225,32 +1217,131 @@ void InstructionSelection::unop(V4IR::AluOp oper, V4IR::Temp *sourceTemp, V4IR::
} // switch
if (op) {
- _as->generateFunctionCallImp(Assembler::Void, opName, op,
- Assembler::PointerToValue(targetTemp),
+ _as->generateFunctionCallImp(targetTemp, opName, op,
Assembler::PointerToValue(sourceTemp));
storeTarget(0, targetTemp);
}
}
+static inline Assembler::FPRegisterID getFreeFPReg(V4IR::Expr *shouldNotOverlap, int hint)
+{
+ if (V4IR::Temp *t = shouldNotOverlap->asTemp())
+ if (t->type == V4IR::DoubleType)
+ if (t->kind == V4IR::Temp::PhysicalRegister)
+ if (t->index == hint)
+ return Assembler::FPRegisterID(hint + 1);
+ return Assembler::FPRegisterID(hint);
+}
+
+Assembler::Jump InstructionSelection::genInlineBinop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource, V4IR::Temp *target)
+{
+ Assembler::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
+ // not transformed into SSA)
+ // - type inference found that either or both operands can be of non-number type, and the
+ // register allocator will have prepared for a call (meaning: all registers that do not
+ // hold operands are spilled to the stack, which makes them available here)
+ // Note: FPGPr0 can still not be used, because uint32->double conversion uses it as a scratch
+ // register.
+ switch (oper) {
+ case V4IR::OpAdd: {
+ Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 1);
+ Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 3);
+ Assembler::Jump leftIsNoDbl = genTryDoubleConversion(leftSource, lReg);
+ Assembler::Jump rightIsNoDbl = genTryDoubleConversion(rightSource, rReg);
+
+ _as->addDouble(rReg, lReg);
+ _as->storeDouble(lReg, target);
+ done = _as->jump();
+
+ if (leftIsNoDbl.isSet())
+ leftIsNoDbl.link(_as);
+ if (rightIsNoDbl.isSet())
+ rightIsNoDbl.link(_as);
+ } break;
+ case V4IR::OpMul: {
+ Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 1);
+ Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 3);
+ Assembler::Jump leftIsNoDbl = genTryDoubleConversion(leftSource, lReg);
+ Assembler::Jump rightIsNoDbl = genTryDoubleConversion(rightSource, rReg);
+
+ _as->mulDouble(rReg, lReg);
+ _as->storeDouble(lReg, target);
+ done = _as->jump();
+
+ if (leftIsNoDbl.isSet())
+ leftIsNoDbl.link(_as);
+ if (rightIsNoDbl.isSet())
+ rightIsNoDbl.link(_as);
+ } break;
+ case V4IR::OpSub: {
+ Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 1);
+ Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 3);
+ Assembler::Jump leftIsNoDbl = genTryDoubleConversion(leftSource, lReg);
+ Assembler::Jump rightIsNoDbl = genTryDoubleConversion(rightSource, rReg);
+
+ _as->subDouble(rReg, lReg);
+ _as->storeDouble(lReg, target);
+ done = _as->jump();
+
+ if (leftIsNoDbl.isSet())
+ leftIsNoDbl.link(_as);
+ if (rightIsNoDbl.isSet())
+ rightIsNoDbl.link(_as);
+ } break;
+ case V4IR::OpDiv: {
+ Assembler::FPRegisterID lReg = getFreeFPReg(rightSource, 1);
+ Assembler::FPRegisterID rReg = getFreeFPReg(leftSource, 3);
+ Assembler::Jump leftIsNoDbl = genTryDoubleConversion(leftSource, lReg);
+ Assembler::Jump rightIsNoDbl = genTryDoubleConversion(rightSource, rReg);
+
+ _as->divDouble(rReg, lReg);
+ _as->storeDouble(lReg, target);
+ done = _as->jump();
+
+ if (leftIsNoDbl.isSet())
+ leftIsNoDbl.link(_as);
+ if (rightIsNoDbl.isSet())
+ rightIsNoDbl.link(_as);
+ } break;
+ default:
+ break;
+ }
+
+ return done;
+}
+
void InstructionSelection::binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource, V4IR::Temp *target)
{
+ if (oper != V4IR:: OpMod
+ && leftSource->type == V4IR::DoubleType && rightSource->type == V4IR::DoubleType
+ && isPregOrConst(leftSource) && isPregOrConst(rightSource)) {
+ doubleBinop(oper, leftSource, rightSource, target);
+ return;
+ }
+
+ Assembler::Jump done = genInlineBinop(oper, leftSource, rightSource, target);
+
const Assembler::BinaryOperationInfo& info = Assembler::binaryOperation(oper);
if (info.fallbackImplementation) {
- _as->generateFunctionCallImp(Assembler::Void, info.name, info.fallbackImplementation,
- Assembler::PointerToValue(target),
+ _as->generateFunctionCallImp(target, info.name, info.fallbackImplementation,
Assembler::PointerToValue(leftSource),
Assembler::PointerToValue(rightSource));
storeTarget(0, target);
} else if (info.contextImplementation) {
- _as->generateFunctionCallImp(Assembler::Void, info.name, info.contextImplementation,
+ _as->generateFunctionCallImp(target, info.name, info.contextImplementation,
Assembler::ContextRegister,
- Assembler::PointerToValue(target),
Assembler::PointerToValue(leftSource),
Assembler::PointerToValue(rightSource));
storeTarget(1, target);
} else {
assert(!"unreachable");
}
+
+ if (done.isSet())
+ done.link(_as);
}
void InstructionSelection::inplaceNameOp(V4IR::AluOp oper, V4IR::Temp *rightSource, const QString &targetName)
@@ -1344,14 +1435,14 @@ void InstructionSelection::callProperty(V4IR::Expr *base, const QString &name, V
if (useFastLookups) {
uint index = registerGetterLookup(name);
- generateFunctionCall(Assembler::Void, __qmljs_call_property_lookup,
- Assembler::ContextRegister, Assembler::PointerToValue(result),
+ generateFunctionCall(result, __qmljs_call_property_lookup,
+ Assembler::ContextRegister,
Assembler::TrustedImm32(index),
baseAddressForCallData());
} else
{
- generateFunctionCall(Assembler::Void, __qmljs_call_property, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::PointerToString(name),
+ generateFunctionCall(result, __qmljs_call_property, Assembler::ContextRegister,
+ Assembler::PointerToString(name),
baseAddressForCallData());
}
}
@@ -1362,8 +1453,8 @@ void InstructionSelection::callSubscript(V4IR::Expr *base, V4IR::Expr *index, V4
assert(base != 0);
int argc = prepareCallData(args, base);
- generateFunctionCall(Assembler::Void, __qmljs_call_element, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::PointerToValue(index),
+ generateFunctionCall(result, __qmljs_call_element, Assembler::ContextRegister,
+ Assembler::PointerToValue(index),
baseAddressForCallData());
}
@@ -1422,22 +1513,30 @@ void InstructionSelection::convertTypeToDouble(V4IR::Temp *source, V4IR::Temp *t
// not an int, check if it's NOT a double:
isNoInt.link(_as);
+#if QT_POINTER_SIZE == 8
+ _as->and32(Assembler::TrustedImm32(Value::IsDouble_Mask), Assembler::ScratchRegister);
+ Assembler::Jump isDbl = _as->branch32(Assembler::NotEqual, Assembler::ScratchRegister,
+ Assembler::TrustedImm32(0));
+#else
_as->and32(Assembler::TrustedImm32(Value::NotDouble_Mask), Assembler::ScratchRegister);
Assembler::Jump isDbl = _as->branch32(Assembler::NotEqual, Assembler::ScratchRegister,
Assembler::TrustedImm32(Value::NotDouble_Mask));
+#endif
- generateFunctionCall(Assembler::Void, __qmljs_value_to_double,
- Assembler::PointerToValue(target),
- Assembler::PointerToValue(source));
- storeTarget(0, target);
+ generateFunctionCall(target, __qmljs_value_to_double, Assembler::PointerToValue(source));
Assembler::Jump noDoubleDone = _as->jump();
// it is a double:
isDbl.link(_as);
Assembler::Pointer addr2 = _as->loadTempAddress(Assembler::ScratchRegister, source);
if (target->kind == V4IR::Temp::StackSlot) {
+#if QT_POINTER_SIZE == 8
+ _as->load64(addr2, Assembler::ScratchRegister);
+ _as->store64(Assembler::ScratchRegister, _as->stackSlotPointer(target));
+#else
_as->loadDouble(addr2, Assembler::FPGpr0);
_as->storeDouble(Assembler::FPGpr0, _as->stackSlotPointer(target));
+#endif
} else {
_as->loadDouble(addr2, (Assembler::FPRegisterID) target->index);
}
@@ -1569,15 +1668,14 @@ void InstructionSelection::constructActivationProperty(V4IR::Name *func, V4IR::E
if (useFastLookups && func->global) {
uint index = registerGlobalGetterLookup(*func->id);
- generateFunctionCall(Assembler::Void, __qmljs_construct_global_lookup,
- Assembler::ContextRegister, Assembler::PointerToValue(result),
- Assembler::TrustedImm32(index),
- baseAddressForCallData());
+ generateFunctionCall(result, __qmljs_construct_global_lookup,
+ Assembler::ContextRegister,
+ Assembler::TrustedImm32(index), baseAddressForCallData());
return;
}
- generateFunctionCall(Assembler::Void, __qmljs_construct_activation_property,
- Assembler::ContextRegister, Assembler::PointerToValue(result),
+ generateFunctionCall(result, __qmljs_construct_activation_property,
+ Assembler::ContextRegister,
Assembler::PointerToString(*func->id),
baseAddressForCallData());
}
@@ -1586,8 +1684,8 @@ void InstructionSelection::constructActivationProperty(V4IR::Name *func, V4IR::E
void InstructionSelection::constructProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result)
{
int argc = prepareCallData(args, 0);
- generateFunctionCall(Assembler::Void, __qmljs_construct_property, Assembler::ContextRegister,
- Assembler::PointerToValue(result), Assembler::Reference(base), Assembler::PointerToString(name),
+ generateFunctionCall(result, __qmljs_construct_property, Assembler::ContextRegister,
+ Assembler::Reference(base), Assembler::PointerToString(name),
baseAddressForCallData());
}
@@ -1596,8 +1694,8 @@ void InstructionSelection::constructValue(V4IR::Temp *value, V4IR::ExprList *arg
assert(value != 0);
int argc = prepareCallData(args, 0);
- generateFunctionCall(Assembler::Void, __qmljs_construct_value,
- Assembler::ContextRegister, Assembler::PointerToValue(result),
+ generateFunctionCall(result, __qmljs_construct_value,
+ Assembler::ContextRegister,
Assembler::Reference(value),
baseAddressForCallData());
}
@@ -1650,6 +1748,10 @@ void InstructionSelection::visitCJump(V4IR::CJump *s)
_as->jumpToBlock(_block, s->iffalse);
return;
} else if (V4IR::Binop *b = s->cond->asBinop()) {
+ if (b->left->type == V4IR::DoubleType && b->right->type == V4IR::DoubleType
+ && visitCJumpDouble(b->op, b->left, b->right, s->iftrue, s->iffalse))
+ return;
+
CmpOp op = 0;
CmpOpContext opContext = 0;
const char *opName = 0;
@@ -1688,31 +1790,37 @@ void InstructionSelection::visitCJump(V4IR::CJump *s)
_as->jumpToBlock(_block, s->iffalse);
return;
}
- Q_UNIMPLEMENTED();
- assert(!"TODO");
+ Q_UNREACHABLE();
}
void InstructionSelection::visitRet(V4IR::Ret *s)
{
if (V4IR::Temp *t = s->expr->asTemp()) {
-#if defined(RETURN_VALUE_IN_REGISTER)
#if CPU(X86)
Address addr = _as->loadTempAddress(Assembler::ScratchRegister, t);
_as->load32(addr, JSC::X86Registers::eax);
addr.offset += 4;
_as->load32(addr, JSC::X86Registers::edx);
+#elif CPU(ARM)
+ Address addr = _as->loadTempAddress(Assembler::ScratchRegister, t);
+ _as->load32(addr, JSC::ARMRegisters::r0);
+ addr.offset += 4;
+ _as->load32(addr, JSC::ARMRegisters::r1);
#else
if (t->kind == V4IR::Temp::PhysicalRegister) {
if (t->type == V4IR::DoubleType) {
_as->moveDoubleTo64((Assembler::FPRegisterID) t->index,
Assembler::ReturnValueRegister);
+ } else if (t->type == V4IR::UInt32Type) {
+ Address tmp = addressForArgument(0);
+ _as->storeUInt32((Assembler::RegisterID) t->index, Pointer(tmp));
+ _as->load64(tmp, Assembler::ReturnValueRegister);
} else {
_as->zeroExtend32ToPtr((Assembler::RegisterID) t->index,
Assembler::ReturnValueRegister);
QV4::Value upper;
switch (t->type) {
case V4IR::SInt32Type:
- case V4IR::UInt32Type:
upper = QV4::Value::fromInt32(0);
break;
case V4IR::BoolType:
@@ -1720,7 +1828,7 @@ void InstructionSelection::visitRet(V4IR::Ret *s)
break;
default:
upper = QV4::Value::undefinedValue();
- Q_UNIMPLEMENTED();
+ Q_UNREACHABLE();
}
_as->or64(Assembler::TrustedImm64(((int64_t) upper.tag) << 32),
Assembler::ReturnValueRegister);
@@ -1729,25 +1837,18 @@ void InstructionSelection::visitRet(V4IR::Ret *s)
_as->copyValue(Assembler::ReturnValueRegister, t);
}
#endif
-#else
- _as->loadPtr(addressForArgument(0), Assembler::ReturnValueRegister);
- _as->copyValue(Address(Assembler::ReturnValueRegister, 0), t);
-#endif
} else if (V4IR::Const *c = s->expr->asConst()) {
QV4::Value retVal = convertToValue(c);
-#if defined(RETURN_VALUE_IN_REGISTER)
#if CPU(X86)
_as->move(Assembler::TrustedImm32(retVal.int_32), JSC::X86Registers::eax);
_as->move(Assembler::TrustedImm32(retVal.tag), JSC::X86Registers::edx);
+#elif CPU(ARM)
+ _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::ARMRegisters::r0);
+ _as->move(Assembler::TrustedImm32(retVal.tag), JSC::ARMRegisters::r1);
#else
_as->move(Assembler::TrustedImm64(retVal.val), Assembler::ReturnValueRegister);
#endif
-#else // !RETURN_VALUE_IN_REGISTER
- _as->loadPtr(addressForArgument(0), Assembler::ReturnValueRegister);
- _as->storeValue(retVal, Assembler::Address(Assembler::ReturnValueRegister));
-#endif
} else {
- Q_UNIMPLEMENTED();
Q_UNREACHABLE();
Q_UNUSED(s);
}
@@ -1758,14 +1859,6 @@ void InstructionSelection::visitRet(V4IR::Ret *s)
_as->storePtr(Assembler::LocalsRegister, Address(Assembler::ScratchRegister, offsetof(ExecutionEngine, jsStackTop)));
_as->leaveStandardStackFrame();
-#if !defined(ARGUMENTS_IN_REGISTERS) && !defined(RETURN_VALUE_IN_REGISTER)
- // Emulate ret(n) instruction
- // Pop off return address into scratch register ...
- _as->pop(Assembler::ScratchRegister);
- // ... and overwrite the invisible argument with
- // the return address.
- _as->poke(Assembler::ScratchRegister);
-#endif
_as->ret();
}
@@ -1794,7 +1887,7 @@ int InstructionSelection::prepareCallData(V4IR::ExprList* args, V4IR::Expr *this
}
Pointer p = _as->stackLayout().callDataAddress(offsetof(CallData, tag));
- _as->store32(Assembler::TrustedImm32(0), p);
+ _as->store32(Assembler::TrustedImm32(QV4::Value::Integer_Type), p);
p = _as->stackLayout().callDataAddress(offsetof(CallData, argc));
_as->store32(Assembler::TrustedImm32(argc), p);
p = _as->stackLayout().callDataAddress(offsetof(CallData, thisObject));
@@ -1855,3 +1948,196 @@ void Assembler::ConstantTable::finalize(JSC::LinkBuffer &linkBuffer, Instruction
foreach (DataLabelPtr label, _toPatch)
linkBuffer.patch(label, tablePtr);
}
+
+// Try to load the source expression into the destination FP register. This assumes that two
+// general purpose (integer) registers are available: the ScratchRegister and the
+// ReturnValueRegister. It returns a Jump if no conversion can be performed.
+Assembler::Jump InstructionSelection::genTryDoubleConversion(V4IR::Expr *src,
+ Assembler::FPRegisterID dest)
+{
+ switch (src->type) {
+ case V4IR::DoubleType:
+ _as->moveDouble(_as->toDoubleRegister(src, dest), dest);
+ return Assembler::Jump();
+ case V4IR::SInt32Type:
+ _as->convertInt32ToDouble(_as->toInt32Register(src, Assembler::ScratchRegister),
+ dest);
+ return Assembler::Jump();
+ case V4IR::UInt32Type:
+#if CPU(X86_64) || CPU(X86)
+ _as->convertUInt32ToDouble(_as->toUInt32Register(src, Assembler::ScratchRegister),
+ dest, Assembler::ReturnValueRegister);
+#else
+ Q_ASSERT(!"Not supported on this platform!");
+#endif
+ return Assembler::Jump();
+ case V4IR::BoolType:
+ // TODO?
+ return _as->jump();
+ default:
+ break;
+ }
+
+ V4IR::Temp *sourceTemp = src->asTemp();
+ Q_ASSERT(sourceTemp);
+
+ // It's not a number type, so it cannot be in a register.
+ Q_ASSERT(sourceTemp->kind != V4IR::Temp::PhysicalRegister || sourceTemp->type == V4IR::BoolType);
+
+ Assembler::Pointer tagAddr = _as->loadTempAddress(Assembler::ScratchRegister, sourceTemp);
+ tagAddr.offset += 4;
+ _as->load32(tagAddr, Assembler::ScratchRegister);
+
+ // check if it's an int32:
+ Assembler::Jump isNoInt = _as->branch32(Assembler::NotEqual, Assembler::ScratchRegister,
+ Assembler::TrustedImm32(Value::_Integer_Type));
+ _as->convertInt32ToDouble(_as->toInt32Register(src, Assembler::ScratchRegister), dest);
+ Assembler::Jump intDone = _as->jump();
+
+ // not an int, check if it's a double:
+ isNoInt.link(_as);
+#if QT_POINTER_SIZE == 8
+ _as->and32(Assembler::TrustedImm32(Value::IsDouble_Mask), Assembler::ScratchRegister);
+ Assembler::Jump isNoDbl = _as->branch32(Assembler::Equal, Assembler::ScratchRegister,
+ Assembler::TrustedImm32(0));
+#else
+ _as->and32(Assembler::TrustedImm32(Value::NotDouble_Mask), Assembler::ScratchRegister);
+ Assembler::Jump isNoDbl = _as->branch32(Assembler::Equal, Assembler::ScratchRegister,
+ Assembler::TrustedImm32(Value::NotDouble_Mask));
+#endif
+ _as->toDoubleRegister(src, dest);
+ intDone.link(_as);
+
+ return isNoDbl;
+}
+
+void InstructionSelection::doubleBinop(V4IR::AluOp oper, V4IR::Expr *leftSource,
+ V4IR::Expr *rightSource, V4IR::Temp *target)
+{
+ Q_ASSERT(leftSource->asConst() == 0 || rightSource->asConst() == 0);
+ Q_ASSERT(isPregOrConst(leftSource));
+ Q_ASSERT(isPregOrConst(rightSource));
+ Assembler::FPRegisterID targetReg;
+ if (target->kind == V4IR::Temp::PhysicalRegister)
+ targetReg = (Assembler::FPRegisterID) target->index;
+ else
+ targetReg = Assembler::FPGpr0;
+
+ switch (oper) {
+ case V4IR::OpAdd:
+ if (V4IR::Const *c = rightSource->asConst()) {
+ _as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
+ Assembler::ImplicitAddress addr =
+ _as->constantTable().loadValueAddress(c, Assembler::ScratchRegister);
+ _as->addDouble(Address(addr.base, addr.offset), targetReg);
+ break;
+ }
+
+ _as->addDouble(_as->toDoubleRegister(leftSource), _as->toDoubleRegister(rightSource),
+ targetReg);
+ break;
+ case V4IR::OpMul:
+ if (V4IR::Const *c = rightSource->asConst()) {
+ _as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
+ Assembler::ImplicitAddress addr =
+ _as->constantTable().loadValueAddress(c, Assembler::ScratchRegister);
+ _as->mulDouble(Address(addr.base, addr.offset), targetReg);
+ break;
+ }
+
+ _as->mulDouble(_as->toDoubleRegister(leftSource), _as->toDoubleRegister(rightSource),
+ targetReg);
+ break;
+ case V4IR::OpSub:
+#if CPU(X86) || CPU(X86_64)
+ if (V4IR::Temp *rightTemp = rightSource->asTemp()) {
+ if (rightTemp->kind == V4IR::Temp::PhysicalRegister && rightTemp->index == targetReg) {
+ _as->moveDouble(targetReg, Assembler::FPGpr0);
+ _as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
+ _as->subDouble(Assembler::FPGpr0, targetReg);
+ break;
+ }
+ }
+#endif
+ if (V4IR::Const *c = rightSource->asConst()) {
+ _as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
+ Assembler::ImplicitAddress addr =
+ _as->constantTable().loadValueAddress(c, Assembler::ScratchRegister);
+ _as->subDouble(Address(addr.base, addr.offset), targetReg);
+ break;
+ }
+
+ _as->subDouble(_as->toDoubleRegister(leftSource), _as->toDoubleRegister(rightSource),
+ targetReg);
+ break;
+ case V4IR::OpDiv:
+#if CPU(X86) || CPU(X86_64)
+ if (V4IR::Temp *rightTemp = rightSource->asTemp()) {
+ if (rightTemp->kind == V4IR::Temp::PhysicalRegister && rightTemp->index == targetReg) {
+ _as->moveDouble(targetReg, Assembler::FPGpr0);
+ _as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
+ _as->divDouble(Assembler::FPGpr0, targetReg);
+ break;
+ }
+ }
+#endif
+ if (V4IR::Const *c = rightSource->asConst()) {
+ _as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
+ Assembler::ImplicitAddress addr =
+ _as->constantTable().loadValueAddress(c, Assembler::ScratchRegister);
+ _as->divDouble(Address(addr.base, addr.offset), targetReg);
+ break;
+ }
+
+ _as->divDouble(_as->toDoubleRegister(leftSource), _as->toDoubleRegister(rightSource),
+ targetReg);
+ break;
+ default: {
+ Q_ASSERT(target->type == V4IR::BoolType);
+ Assembler::Jump trueCase = branchDouble(oper, leftSource, rightSource);
+ _as->storeBool(false, target);
+ Assembler::Jump done = _as->jump();
+ trueCase.link(_as);
+ _as->storeBool(true, target);
+ done.link(_as);
+ } return;
+ }
+
+ if (target->kind != V4IR::Temp::PhysicalRegister)
+ _as->storeDouble(Assembler::FPGpr0, target);
+}
+
+Assembler::Jump InstructionSelection::branchDouble(V4IR::AluOp op, V4IR::Expr *left,
+ V4IR::Expr *right)
+{
+ Q_ASSERT(isPregOrConst(left));
+ Q_ASSERT(isPregOrConst(right));
+ Q_ASSERT(left->asConst() == 0 || right->asConst() == 0);
+
+ Assembler::DoubleCondition cond;
+ switch (op) {
+ case V4IR::OpGt: cond = Assembler::DoubleGreaterThan; break;
+ case V4IR::OpLt: cond = Assembler::DoubleLessThan; break;
+ case V4IR::OpGe: cond = Assembler::DoubleGreaterThanOrEqual; break;
+ case V4IR::OpLe: cond = Assembler::DoubleLessThanOrEqual; break;
+ case V4IR::OpEqual:
+ case V4IR::OpStrictEqual: cond = Assembler::DoubleEqual; break;
+ case V4IR::OpNotEqual:
+ case V4IR::OpStrictNotEqual: cond = Assembler::DoubleNotEqualOrUnordered; break; // No, the inversion of DoubleEqual is NOT DoubleNotEqual.
+ default:
+ Q_UNREACHABLE();
+ }
+ return _as->branchDouble(cond, _as->toDoubleRegister(left), _as->toDoubleRegister(right));
+}
+
+bool InstructionSelection::visitCJumpDouble(V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right,
+ V4IR::BasicBlock *iftrue, V4IR::BasicBlock *iffalse)
+{
+ if (!isPregOrConst(left) || !isPregOrConst(right))
+ return false;
+
+ Assembler::Jump target = branchDouble(op, left, right);
+ _as->addPatch(iftrue, target);
+ _as->jumpToBlock(_block, iffalse);
+ return true;
+}
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index ec6780a6f3..3cf50d4541 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -73,6 +73,8 @@ struct CompilationUnit : public QV4::CompiledData::CompilationUnit
QVector<JSC::MacroAssemblerCodeRef> codeRefs;
QList<QVector<QV4::Value> > constantValues;
+ QVector<int> codeSizes; // corresponding to the endOfCode labels. MacroAssemblerCodeRef's size may
+ // be larger, as for example on ARM we append the exception handling table.
};
class Assembler : public JSC::MacroAssembler
@@ -86,13 +88,6 @@ public:
#undef VALUE_FITS_IN_REGISTER
#undef ARGUMENTS_IN_REGISTERS
-#if OS(WINDOWS)
- // Returned in EAX:EDX pair
-#define RETURN_VALUE_IN_REGISTER
-#else
-#undef RETURN_VALUE_IN_REGISTER
-#endif
-
#define HAVE_ALU_OPS_WITH_MEM_OPERAND 1
static const RegisterID StackFrameRegister = JSC::X86Registers::ebp;
@@ -123,7 +118,6 @@ public:
#define VALUE_FITS_IN_REGISTER
#define ARGUMENTS_IN_REGISTERS
-#define RETURN_VALUE_IN_REGISTER
#define HAVE_ALU_OPS_WITH_MEM_OPERAND 1
static const RegisterID StackFrameRegister = JSC::X86Registers::ebp;
@@ -177,7 +171,6 @@ public:
#undef VALUE_FITS_IN_REGISTER
#define ARGUMENTS_IN_REGISTERS
-#undef RETURN_VALUE_IN_REGISTER
#undef HAVE_ALU_OPS_WITH_MEM_OPERAND
static const RegisterID StackFrameRegister = JSC::ARMRegisters::r4;
@@ -249,21 +242,32 @@ public:
{}
};
- // Stack layout:
+ // V4 uses two stacks: one stack with QV4::Value items, which is checked by the garbage
+ // collector, and one stack used by the native C/C++/ABI code. This C++ stack is not scanned
+ // by the garbage collector, so if any JS object needs to be retained, it should be put on the
+ // JS stack.
+ //
+ // The "saved reg arg X" are on the C++ stack is used to store values in registers that need to
+ // be passed by reference to native functions. It is fine to use the C++ stack, because only
+ // non-object values can be stored in registers.
+ //
+ // Stack layout for the C++ stack:
// return address
- // old FP <- FP, LocalsRegister
+ // old FP <- FP
// callee saved reg n
// ...
// callee saved reg 0
- // function call argument n
+ // saved reg arg 0
+ // ...
+ // saved reg arg n <- SP
+ //
+ // Stack layout for the JS stack:
+ // function call argument n <- LocalsRegister
// ...
// function call argument 0
// local 0
// ...
// local n
- // saved const arg 0
- // ...
- // saved const arg n <- SP
class StackLayout
{
public:
@@ -271,21 +275,27 @@ public:
: calleeSavedRegCount(Assembler::calleeSavedRegisterCount + 1)
, maxOutgoingArgumentCount(function->maxNumberOfArguments)
, localCount(function->tempCount)
- , savedConstCount(maxArgCountForBuiltins)
+ , savedRegCount(maxArgCountForBuiltins)
{
#if 0 // debug code
qDebug("calleeSavedRegCount.....: %d",calleeSavedRegCount);
qDebug("maxOutgoingArgumentCount: %d",maxOutgoingArgumentCount);
qDebug("localCount..............: %d",localCount);
qDebug("savedConstCount.........: %d",savedConstCount);
- qDebug("argumentAddressForCall(0) = 0x%x / -0x%x", argumentAddressForCall(0).offset, -argumentAddressForCall(0).offset);
- if (localCount)qDebug("local(0) = 0x%x / -0x%x", stackSlotPointer(0).offset, -stackSlotPointer(0).offset);
- qDebug("savedReg(0) = 0x%x", savedRegPointer(0).offset);
- qDebug("savedReg(1) = 0x%x", savedRegPointer(1).offset);
- qDebug("savedReg(2) = 0x%x", savedRegPointer(2).offset);
- qDebug("savedReg(3) = 0x%x", savedRegPointer(3).offset);
- qDebug("savedReg(4) = 0x%x", savedRegPointer(4).offset);
- qDebug("savedReg(5) = 0x%x", savedRegPointer(5).offset);
+ for (int i = 0; i < maxOutgoingArgumentCount; ++i)
+ qDebug("argumentAddressForCall(%d) = 0x%x / -0x%x", i,
+ argumentAddressForCall(i).offset, -argumentAddressForCall(i).offset);
+ for (int i = 0; i < localCount; ++i)
+ qDebug("local(%d) = 0x%x / -0x%x", i, stackSlotPointer(i).offset,
+ -stackSlotPointer(i).offset);
+ qDebug("savedReg(0) = 0x%x / -0x%x", savedRegPointer(0).offset, -savedRegPointer(0).offset);
+ qDebug("savedReg(1) = 0x%x / -0x%x", savedRegPointer(1).offset, -savedRegPointer(1).offset);
+ qDebug("savedReg(2) = 0x%x / -0x%x", savedRegPointer(2).offset, -savedRegPointer(2).offset);
+ qDebug("savedReg(3) = 0x%x / -0x%x", savedRegPointer(3).offset, -savedRegPointer(3).offset);
+ qDebug("savedReg(4) = 0x%x / -0x%x", savedRegPointer(4).offset, -savedRegPointer(4).offset);
+ qDebug("savedReg(5) = 0x%x / -0x%x", savedRegPointer(5).offset, -savedRegPointer(5).offset);
+
+ qDebug("callDataAddress(0) = 0x%x", callDataAddress(0).offset);
#endif
}
@@ -295,7 +305,7 @@ public:
+ RegisterSize; // saved StackFrameRegister
// space for the callee saved registers
- int frameSize = RegisterSize * (calleeSavedRegisterCount + savedConstCount);
+ int frameSize = RegisterSize * (calleeSavedRegisterCount + savedRegCount);
frameSize = WTF::roundUpToMultipleOf(StackAlignment, frameSize + stackSpaceAllocatedOtherwise);
frameSize -= stackSpaceAllocatedOtherwise;
@@ -338,11 +348,10 @@ public:
Address savedRegPointer(int offset) const
{
Q_ASSERT(offset >= 0);
- Q_ASSERT(offset < savedConstCount);
+ Q_ASSERT(offset < savedRegCount);
- Address addr = argumentAddressForCall(0);
- addr.offset -= sizeof(QV4::Value) * (offset + localCount + 1);
- return addr;
+ const int off = offset * sizeof(QV4::Value);
+ return Address(Assembler::StackFrameRegister, - calleeSavedRegisterSpace() - off);
}
int calleeSavedRegisterSpace() const
@@ -362,7 +371,7 @@ public:
/// used by built-ins to save arguments (e.g. constants) to the stack when they need to be
/// passed by reference.
- int savedConstCount;
+ int savedRegCount;
};
class ConstantTable
@@ -596,6 +605,23 @@ public:
{
store64(ReturnValueRegister, dest);
}
+#elif defined(Q_PROCESSOR_X86)
+ void storeReturnValue(const Pointer &dest)
+ {
+ Pointer destination = dest;
+ store32(JSC::X86Registers::eax, destination);
+ destination.offset += 4;
+ store32(JSC::X86Registers::edx, destination);
+ }
+#elif defined(Q_PROCESSOR_ARM)
+ void storeReturnValue(const Pointer &dest)
+ {
+ Pointer destination = dest;
+ store32(JSC::ARMRegisters::r0, destination);
+ destination.offset += 4;
+ store32(JSC::ARMRegisters::r1, destination);
+ }
+#endif
void storeReturnValue(V4IR::Temp *temp)
{
@@ -604,7 +630,6 @@ public:
Pointer addr = loadTempAddress(ScratchRegister, temp);
storeReturnValue(addr);
}
-#endif
void storeReturnValue(VoidType)
{
@@ -692,25 +717,67 @@ public:
poke(TrustedImmPtr(name), StackSlot);
}
- using JSC::MacroAssembler::loadDouble;
void loadDouble(V4IR::Temp* temp, FPRegisterID dest)
{
+ if (temp->kind == V4IR::Temp::PhysicalRegister) {
+ moveDouble((FPRegisterID) temp->index, dest);
+ return;
+ }
Pointer ptr = loadTempAddress(ScratchRegister, temp);
loadDouble(ptr, dest);
}
- using JSC::MacroAssembler::storeDouble;
void storeDouble(FPRegisterID source, V4IR::Temp* temp)
{
+ if (temp->kind == V4IR::Temp::PhysicalRegister) {
+ moveDouble(source, (FPRegisterID) temp->index);
+ return;
+ }
+#if QT_POINTER_SIZE == 8
+ moveDoubleTo64(source, ReturnValueRegister);
+ move(TrustedImm64(QV4::Value::NaNEncodeMask), ScratchRegister);
+ xor64(ScratchRegister, ReturnValueRegister);
+ Pointer ptr = loadTempAddress(ScratchRegister, temp);
+ store64(ReturnValueRegister, ptr);
+#else
Pointer ptr = loadTempAddress(ScratchRegister, temp);
storeDouble(source, ptr);
+#endif
+ }
+#if QT_POINTER_SIZE == 8
+ // We need to (de)mangle the double
+ void loadDouble(Address addr, FPRegisterID dest)
+ {
+ load64(addr, ReturnValueRegister);
+ move(TrustedImm64(QV4::Value::NaNEncodeMask), ScratchRegister);
+ xor64(ScratchRegister, ReturnValueRegister);
+ move64ToDouble(ReturnValueRegister, dest);
}
+ void storeDouble(FPRegisterID source, Address addr)
+ {
+ moveDoubleTo64(source, ReturnValueRegister);
+ move(TrustedImm64(QV4::Value::NaNEncodeMask), ScratchRegister);
+ xor64(ScratchRegister, ReturnValueRegister);
+ store64(ReturnValueRegister, addr);
+ }
+#else
+ using JSC::MacroAssembler::loadDouble;
+ using JSC::MacroAssembler::storeDouble;
+#endif
+
template <typename Result, typename Source>
void copyValue(Result result, Source source);
template <typename Result>
void copyValue(Result result, V4IR::Expr* source);
+ void storeValue(QV4::Value value, RegisterID destination)
+ {
+ Q_UNUSED(value);
+ Q_UNUSED(destination);
+ Q_UNREACHABLE();
+ }
+
void storeValue(QV4::Value value, Address destination)
{
#ifdef VALUE_FITS_IN_REGISTER
@@ -1027,15 +1094,18 @@ public:
store32(TrustedImm32(QV4::Value::fromBoolean(0).tag), addr);
}
+ void storeBool(RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ }
+
void storeBool(RegisterID reg, V4IR::Temp *target)
{
if (target->kind == V4IR::Temp::PhysicalRegister) {
move(reg, (RegisterID) target->index);
- } else if (target->kind == V4IR::Temp::StackSlot) {
- Pointer addr = stackSlotPointer(target);
- storeBool(reg, addr);
} else {
- Q_UNIMPLEMENTED();
+ Pointer addr = loadTempAddress(ScratchRegister, target);
+ storeBool(reg, addr);
}
}
@@ -1049,6 +1119,11 @@ public:
}
}
+ void storeInt32(RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ }
+
void storeInt32(RegisterID reg, Pointer addr)
{
store32(reg, addr);
@@ -1066,26 +1141,48 @@ public:
}
}
+ void storeUInt32(RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ }
+
void storeUInt32(RegisterID reg, Pointer addr)
{
+ // The UInt32 representation in QV4::Value is really convoluted. See also toUInt32Register.
#if CPU(X86_64) | CPU(X86)
- Q_ASSERT(reg != ScratchRegister);
Jump intRange = branch32(GreaterThanOrEqual, reg, TrustedImm32(0));
- convertUInt32ToDouble(reg, FPGpr0, ScratchRegister);
+ convertUInt32ToDouble(reg, FPGpr0, ReturnValueRegister);
storeDouble(FPGpr0, addr);
Jump done = jump();
intRange.link(this);
storeInt32(reg, addr);
done.link(this);
#else
- Q_ASSERT(!"Not supported on this platform!");
+ Q_ASSERT(!"Not tested on this platform!");
#endif
}
+ void storeUInt32(RegisterID reg, V4IR::Temp *target)
+ {
+ if (target->kind == V4IR::Temp::PhysicalRegister) {
+ move(reg, (RegisterID) target->index);
+ } else {
+ Pointer addr = loadTempAddress(ScratchRegister, target);
+ storeUInt32(reg, addr);
+ }
+ }
+
FPRegisterID toDoubleRegister(V4IR::Expr *e, FPRegisterID target = FPGpr0)
{
if (V4IR::Const *c = e->asConst()) {
- loadDouble(constantTable().loadValueAddress(c, ScratchRegister), target);
+#if QT_POINTER_SIZE == 8
+ load64(constantTable().loadValueAddress(c, ScratchRegister), ReturnValueRegister);
+ move(TrustedImm64(QV4::Value::NaNEncodeMask), ScratchRegister);
+ xor64(ScratchRegister, ReturnValueRegister);
+ move64ToDouble(ReturnValueRegister, target);
+#else
+ JSC::MacroAssembler::loadDouble(constantTable().loadValueAddress(c, ScratchRegister), target);
+#endif
return target;
}
@@ -1094,8 +1191,7 @@ public:
if (t->kind == V4IR::Temp::PhysicalRegister)
return (FPRegisterID) t->index;
- Q_ASSERT(t->kind == V4IR::Temp::StackSlot);
- loadDouble(loadTempAddress(ScratchRegister, t), target);
+ loadDouble(t, target);
return target;
}
@@ -1137,11 +1233,30 @@ public:
RegisterID toUInt32Register(Pointer addr, RegisterID scratchReg)
{
+ // The UInt32 representation in QV4::Value is really convoluted. See also storeUInt32.
+ Pointer tagAddr = addr;
+ tagAddr.offset += 4;
+ load32(tagAddr, scratchReg);
+ Jump inIntRange = branch32(Equal, scratchReg, TrustedImm32(QV4::Value::_Integer_Type));
+
+ // it's not in signed int range, so load it as a double, and truncate it down
+ loadDouble(addr, FPGpr0);
+ static const QV4::Value magic = QV4::Value::fromDouble(double(INT_MAX) + 1);
+ ImplicitAddress magicAddr = constantTable().loadValueAddress(magic, scratchReg);
+ subDouble(Address(magicAddr.base, magicAddr.offset), FPGpr0);
+ Jump canNeverHappen = branchTruncateDoubleToUint32(FPGpr0, scratchReg);
+ canNeverHappen.link(this);
+ or32(TrustedImm32(1 << 31), scratchReg);
+ Jump done = jump();
+
+ inIntRange.link(this);
load32(addr, scratchReg);
+
+ done.link(this);
return scratchReg;
}
- JSC::MacroAssemblerCodeRef link();
+ JSC::MacroAssemblerCodeRef link(int *codeSize);
void recordLineNumber(int lineNumber);
@@ -1184,7 +1299,7 @@ public:
InstructionSelection(QV4::ExecutableAllocator *execAllocator, V4IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator);
~InstructionSelection();
- virtual void run(V4IR::Function *function);
+ virtual void run(int functionIndex);
void *addConstantTable(QVector<QV4::Value> *values);
protected:
@@ -1199,14 +1314,6 @@ protected:
virtual void callBuiltinDeleteSubscript(V4IR::Temp *base, V4IR::Expr *index, V4IR::Temp *result);
virtual void callBuiltinDeleteName(const QString &name, V4IR::Temp *result);
virtual void callBuiltinDeleteValue(V4IR::Temp *result);
- virtual void callBuiltinPostDecrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result);
- virtual void callBuiltinPostDecrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result);
- virtual void callBuiltinPostDecrementName(const QString &name, V4IR::Temp *result);
- virtual void callBuiltinPostDecrementValue(V4IR::Temp *value, V4IR::Temp *result);
- virtual void callBuiltinPostIncrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result);
- virtual void callBuiltinPostIncrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result);
- virtual void callBuiltinPostIncrementName(const QString &name, V4IR::Temp *result);
- virtual void callBuiltinPostIncrementValue(V4IR::Temp *value, V4IR::Temp *result);
virtual void callBuiltinThrow(V4IR::Expr *arg);
virtual void callBuiltinFinishTry();
virtual void callBuiltinForeachIteratorObject(V4IR::Temp *arg, V4IR::Temp *result);
@@ -1272,6 +1379,15 @@ protected:
virtual void visitRet(V4IR::Ret *);
virtual void visitTry(V4IR::Try *);
+ Assembler::Jump genTryDoubleConversion(V4IR::Expr *src, Assembler::FPRegisterID dest);
+ Assembler::Jump genInlineBinop(V4IR::AluOp oper, V4IR::Expr *leftSource,
+ V4IR::Expr *rightSource, V4IR::Temp *target);
+ void doubleBinop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource,
+ V4IR::Temp *target);
+ Assembler::Jump branchDouble(V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right);
+ bool visitCJumpDouble(V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right,
+ V4IR::BasicBlock *iftrue, V4IR::BasicBlock *iffalse);
+
private:
void convertTypeSlowPath(V4IR::Temp *source, V4IR::Temp *target);
void convertTypeToDouble(V4IR::Temp *source, V4IR::Temp *target);
@@ -1283,12 +1399,10 @@ private:
if (target->kind == V4IR::Temp::PhysicalRegister) {
_as->convertInt32ToDouble(_as->toInt32Register(source, Assembler::ScratchRegister),
(Assembler::FPRegisterID) target->index);
- } else if (target->kind == V4IR::Temp::StackSlot) {
+ } else {
_as->convertInt32ToDouble(_as->toInt32Register(source, Assembler::ScratchRegister),
Assembler::FPGpr0);
_as->storeDouble(Assembler::FPGpr0, _as->stackSlotPointer(target));
- } else {
- Q_UNIMPLEMENTED();
}
}
@@ -1339,8 +1453,8 @@ private:
int prepareVariableArguments(V4IR::ExprList* args);
int prepareCallData(V4IR::ExprList* args, V4IR::Expr *thisObject);
- template <typename Arg1, typename Arg2>
- void generateLookupCall(uint index, uint getterSetterOffset, Arg1 arg1, Arg2 arg2)
+ template <typename Retval, typename Arg1, typename Arg2>
+ void generateLookupCall(Retval retval, uint index, uint getterSetterOffset, Arg1 arg1, Arg2 arg2)
{
_as->loadPtr(Assembler::Address(Assembler::ContextRegister, offsetof(QV4::ExecutionContext, lookups)),
Assembler::ReturnValueRegister);
@@ -1350,7 +1464,7 @@ private:
Assembler::Address getterSetter = lookupAddr;
getterSetter.offset += getterSetterOffset;
- _as->generateFunctionCallImp(Assembler::Void, "lookup getter/setter", getterSetter, lookupAddr, arg1, arg2);
+ _as->generateFunctionCallImp(retval, "lookup getter/setter", getterSetter, lookupAddr, arg1, arg2);
}
template <typename Arg1>
@@ -1387,7 +1501,6 @@ private:
QSet<V4IR::BasicBlock*> _reentryBlocks;
CompilationUnit *compilationUnit;
- QHash<V4IR::Function*, JSC::MacroAssemblerCodeRef> codeRefs;
};
class Q_QML_EXPORT ISelFactory: public EvalISelFactory
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index 67433070f6..16ff43cd37 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -168,6 +168,8 @@ public:
private:
int allocateSlot(V4IR::Temp *t, V4IR::Stmt *currentStmt) {
+ Q_ASSERT(currentStmt->id > 0);
+
const V4IR::LifeTimeInterval &interval = _intervals[*t];
int idx = _hints.value(*t, -1);
if (idx != -1 && _activeSlots[idx] <= currentStmt->id) {
@@ -205,8 +207,9 @@ InstructionSelection::~InstructionSelection()
{
}
-void InstructionSelection::run(V4IR::Function *function)
+void InstructionSelection::run(int functionIndex)
{
+ V4IR::Function *function = irModule->functions[functionIndex];
V4IR::BasicBlock *block = 0, *nextBlock = 0;
QHash<V4IR::BasicBlock *, QVector<ptrdiff_t> > patches;
@@ -230,8 +233,10 @@ void InstructionSelection::run(V4IR::Function *function)
V4IR::Optimizer opt(_function);
opt.run();
StackSlotAllocator *stackSlotAllocator = 0;
- if (opt.isInSSA())
+ if (opt.isInSSA()) {
stackSlotAllocator = new StackSlotAllocator(opt.lifeRanges(), _function->tempCount);
+ opt.convertOutOfSSA();
+ }
qSwap(_stackSlotAllocator, stackSlotAllocator);
V4IR::Stmt *cs = 0;
qSwap(_currentStatement, cs);
@@ -257,21 +262,6 @@ void InstructionSelection::run(V4IR::Function *function)
if (s->location.isValid())
lineNumberMappings << _codeNext - _codeStart << s->location.startLine;
- if (opt.isInSSA() && s->asTerminator()) {
- foreach (const V4IR::Optimizer::SSADeconstructionMove &move,
- opt.ssaDeconstructionMoves(_block)) {
- if (V4IR::Const *c = move.source->asConst()) {
- loadConst(c, move.target);
- } else {
- Q_ASSERT(move.source->asTemp());
- if (move.needsConversion())
- convertType(move.source->asTemp(), move.target);
- else
- copyValue(move.source->asTemp(), move.target);
- }
- }
- }
-
s->accept(this);
}
}
@@ -496,10 +486,12 @@ void InstructionSelection::copyValue(V4IR::Temp *sourceTemp, V4IR::Temp *targetT
addInstruction(move);
}
-void InstructionSelection::swapValues(V4IR::Temp *, V4IR::Temp *)
+void InstructionSelection::swapValues(V4IR::Temp *sourceTemp, V4IR::Temp *targetTemp)
{
- // This is generated by the register allocator for the JIT, so it cannot end up here.
- Q_UNREACHABLE();
+ Instruction::SwapTemps swap;
+ swap.left = getParam(sourceTemp);
+ swap.right = getParam(targetTemp);
+ addInstruction(swap);
}
void InstructionSelection::unop(V4IR::AluOp oper, V4IR::Temp *sourceTemp, V4IR::Temp *targetTemp)
@@ -834,74 +826,6 @@ void InstructionSelection::callBuiltinDeleteValue(V4IR::Temp *result)
addInstruction(load);
}
-void InstructionSelection::callBuiltinPostDecrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result)
-{
- Instruction::CallBuiltinPostDecMember call;
- call.base = getParam(base);
- call.member = registerString(name);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinPostDecrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result)
-{
- Instruction::CallBuiltinPostDecSubscript call;
- call.base = getParam(base);
- call.index = getParam(index);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinPostDecrementName(const QString &name, V4IR::Temp *result)
-{
- Instruction::CallBuiltinPostDecName call;
- call.name = registerString(name);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinPostDecrementValue(V4IR::Temp *value, V4IR::Temp *result)
-{
- Instruction::CallBuiltinPostDecValue call;
- call.value = getParam(value);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinPostIncrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result)
-{
- Instruction::CallBuiltinPostIncMember call;
- call.base = getParam(base);
- call.member = registerString(name);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinPostIncrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result)
-{
- Instruction::CallBuiltinPostIncSubscript call;
- call.base = getParam(base);
- call.index = getParam(index);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinPostIncrementName(const QString &name, V4IR::Temp *result)
-{
- Instruction::CallBuiltinPostIncName call;
- call.name = registerString(name);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinPostIncrementValue(V4IR::Temp *value, V4IR::Temp *result)
-{
- Instruction::CallBuiltinPostIncValue call;
- call.value = getParam(value);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
void InstructionSelection::callBuiltinThrow(V4IR::Expr *arg)
{
Instruction::CallBuiltinThrow call;
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
index cf7d1f43e9..66cf62858e 100644
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ b/src/qml/compiler/qv4isel_moth_p.h
@@ -74,7 +74,7 @@ public:
InstructionSelection(QV4::ExecutableAllocator *execAllocator, V4IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator);
~InstructionSelection();
- virtual void run(V4IR::Function *function);
+ virtual void run(int functionIndex);
protected:
virtual QV4::CompiledData::CompilationUnit *backendCompileStep();
@@ -93,14 +93,6 @@ protected:
virtual void callBuiltinDeleteSubscript(V4IR::Temp *base, V4IR::Expr *index, V4IR::Temp *result);
virtual void callBuiltinDeleteName(const QString &name, V4IR::Temp *result);
virtual void callBuiltinDeleteValue(V4IR::Temp *result);
- virtual void callBuiltinPostDecrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result);
- virtual void callBuiltinPostDecrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result);
- virtual void callBuiltinPostDecrementName(const QString &name, V4IR::Temp *result);
- virtual void callBuiltinPostDecrementValue(V4IR::Temp *value, V4IR::Temp *result);
- virtual void callBuiltinPostIncrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result);
- virtual void callBuiltinPostIncrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result);
- virtual void callBuiltinPostIncrementName(const QString &name, V4IR::Temp *result);
- virtual void callBuiltinPostIncrementValue(V4IR::Temp *value, V4IR::Temp *result);
virtual void callBuiltinThrow(V4IR::Expr *arg);
virtual void callBuiltinFinishTry();
virtual void callBuiltinForeachIteratorObject(V4IR::Temp *arg, V4IR::Temp *result);
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp
index 5a1a6f5341..2f66628fea 100644
--- a/src/qml/compiler/qv4isel_p.cpp
+++ b/src/qml/compiler/qv4isel_p.cpp
@@ -83,8 +83,8 @@ QV4::CompiledData::CompilationUnit *EvalInstructionSelection::compile(bool gener
Function *rootFunction = irModule->rootFunction;
if (!rootFunction)
return 0;
- foreach (V4IR::Function *f, irModule->functions)
- run(f);
+ for (int i = 0; i < irModule->functions.size(); ++i)
+ run(i);
QV4::CompiledData::CompilationUnit *unit = backendCompileStep();
if (generateUnitData) {
@@ -289,40 +289,6 @@ void IRDecoder::callBuiltin(V4IR::Call *call, V4IR::Temp *result)
}
} break;
- case V4IR::Name::builtin_postincrement: {
- if (V4IR::Member *m = call->args->expr->asMember()) {
- callBuiltinPostIncrementMember(m->base->asTemp(), *m->name, result);
- return;
- } else if (V4IR::Subscript *ss = call->args->expr->asSubscript()) {
- callBuiltinPostIncrementSubscript(ss->base->asTemp(), ss->index->asTemp(), result);
- return;
- } else if (V4IR::Name *n = call->args->expr->asName()) {
- callBuiltinPostIncrementName(*n->id, result);
- return;
- } else if (V4IR::Temp *arg = call->args->expr->asTemp()){
- assert(arg != 0);
- callBuiltinPostIncrementValue(arg, result);
- return;
- }
- } break;
-
- case V4IR::Name::builtin_postdecrement: {
- if (V4IR::Member *m = call->args->expr->asMember()) {
- callBuiltinPostDecrementMember(m->base->asTemp(), *m->name, result);
- return;
- } else if (V4IR::Subscript *ss = call->args->expr->asSubscript()) {
- callBuiltinPostDecrementSubscript(ss->base->asTemp(), ss->index->asTemp(), result);
- return;
- } else if (V4IR::Name *n = call->args->expr->asName()) {
- callBuiltinPostDecrementName(*n->id, result);
- return;
- } else if (V4IR::Temp *arg = call->args->expr->asTemp()){
- assert(arg != 0);
- callBuiltinPostDecrementValue(arg, result);
- return;
- }
- } break;
-
case V4IR::Name::builtin_throw: {
V4IR::Expr *arg = call->args->expr;
assert(arg->asTemp() || arg->asConst());
diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h
index 8824b677af..4b82d154d9 100644
--- a/src/qml/compiler/qv4isel_p.h
+++ b/src/qml/compiler/qv4isel_p.h
@@ -78,7 +78,7 @@ public:
QV4::Compiler::JSUnitGenerator *jsUnitGenerator() const { return jsGenerator; }
protected:
- virtual void run(V4IR::Function *function) = 0;
+ virtual void run(int functionIndex) = 0;
virtual QV4::CompiledData::CompilationUnit *backendCompileStep() = 0;
bool useFastLookups;
@@ -118,14 +118,6 @@ public: // to implement by subclasses:
virtual void callBuiltinDeleteSubscript(V4IR::Temp *base, V4IR::Expr *index, V4IR::Temp *result) = 0;
virtual void callBuiltinDeleteName(const QString &name, V4IR::Temp *result) = 0;
virtual void callBuiltinDeleteValue(V4IR::Temp *result) = 0;
- virtual void callBuiltinPostDecrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result) = 0;
- virtual void callBuiltinPostDecrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result) = 0;
- virtual void callBuiltinPostDecrementName(const QString &name, V4IR::Temp *result) = 0;
- virtual void callBuiltinPostDecrementValue(V4IR::Temp *value, V4IR::Temp *result) = 0;
- virtual void callBuiltinPostIncrementMember(V4IR::Temp *base, const QString &name, V4IR::Temp *result) = 0;
- virtual void callBuiltinPostIncrementSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::Temp *result) = 0;
- virtual void callBuiltinPostIncrementName(const QString &name, V4IR::Temp *result) = 0;
- virtual void callBuiltinPostIncrementValue(V4IR::Temp *value, V4IR::Temp *result) = 0;
virtual void callBuiltinThrow(V4IR::Expr *arg) = 0;
virtual void callBuiltinFinishTry() = 0;
virtual void callBuiltinForeachIteratorObject(V4IR::Temp *arg, V4IR::Temp *result) = 0;
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
index 81aa727eda..6a274dac8d 100644
--- a/src/qml/compiler/qv4jsir.cpp
+++ b/src/qml/compiler/qv4jsir.cpp
@@ -398,10 +398,6 @@ static const char *builtin_to_string(Name::Builtin b)
return "builtin_typeof";
case Name::builtin_delete:
return "builtin_delete";
- case Name::builtin_postincrement:
- return "builtin_postincrement";
- case Name::builtin_postdecrement:
- return "builtin_postdecrement";
case Name::builtin_throw:
return "builtin_throw";
case Name::builtin_finish_try:
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 812a5eba94..5430d10710 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -311,8 +311,6 @@ struct Name: Expr {
builtin_invalid,
builtin_typeof,
builtin_delete,
- builtin_postincrement, // TODO: remove
- builtin_postdecrement, // TODO: remove
builtin_throw,
builtin_finish_try,
builtin_foreach_iterator_object,
@@ -380,7 +378,7 @@ struct Temp: Expr {
};
inline bool operator==(const Temp &t1, const Temp &t2) Q_DECL_NOTHROW
-{ return t1.index == t2.index && t1.scope == t2.scope && t1.kind == t2.kind; }
+{ return t1.index == t2.index && t1.scope == t2.scope && t1.kind == t2.kind && t1.type == t2.type; }
inline uint qHash(const Temp &t, uint seed = 0) Q_DECL_NOTHROW
{ return t.index ^ (t.kind | (t.scope << 3)) ^ seed; }
diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp
index 1c8bb66fc1..a6364a25d4 100644
--- a/src/qml/compiler/qv4regalloc.cpp
+++ b/src/qml/compiler/qv4regalloc.cpp
@@ -41,6 +41,8 @@
#include "qv4regalloc_p.h"
+#include <algorithm>
+
//#define DEBUG_REGALLOC
namespace {
@@ -101,6 +103,13 @@ public:
}
QList<Use> uses(const Temp &t) const { return _uses[t]; }
+ bool useMustHaveReg(const Temp &t, int position) {
+ foreach (const Use &use, uses(t))
+ if (use.pos == position)
+ return use.mustHaveRegister();
+ return false;
+ }
+
int def(const Temp &t) const {
Q_ASSERT(_defs[t].isValid());
return _defs[t].defStmt;
@@ -130,7 +139,7 @@ public:
qout << "RegAllocInfo:" << endl << "Defs/uses:" << endl;
QList<Temp> temps = _defs.keys();
- qSort(temps);
+ std::sort(temps.begin(), temps.end());
foreach (const Temp &t, temps) {
t.dump(qout);
qout << " def at " << _defs[t].defStmt << " ("
@@ -158,7 +167,7 @@ public:
QList<Temp> hinted = _hints.keys();
if (hinted.isEmpty())
qout << "\t(none)" << endl;
- qSort(hinted);
+ std::sort(hinted.begin(), hinted.end());
foreach (const Temp &t, hinted) {
qout << "\t";
t.dump(qout);
@@ -183,14 +192,6 @@ protected: // IRDecoder
virtual void callBuiltinDeleteSubscript(V4IR::Temp *, V4IR::Expr *, V4IR::Temp *) {}
virtual void callBuiltinDeleteName(const QString &, V4IR::Temp *) {}
virtual void callBuiltinDeleteValue(V4IR::Temp *) {}
- virtual void callBuiltinPostDecrementMember(V4IR::Temp *, const QString &, V4IR::Temp *) {}
- virtual void callBuiltinPostDecrementSubscript(V4IR::Temp *, V4IR::Temp *, V4IR::Temp *) {}
- virtual void callBuiltinPostDecrementName(const QString &, V4IR::Temp *) {}
- virtual void callBuiltinPostDecrementValue(V4IR::Temp *, V4IR::Temp *) {}
- virtual void callBuiltinPostIncrementMember(V4IR::Temp *, const QString &, V4IR::Temp *) {}
- virtual void callBuiltinPostIncrementSubscript(V4IR::Temp *, V4IR::Temp *, V4IR::Temp *) {}
- virtual void callBuiltinPostIncrementName(const QString &, V4IR::Temp *) {}
- virtual void callBuiltinPostIncrementValue(V4IR::Temp *, V4IR::Temp *) {}
virtual void callBuiltinThrow(V4IR::Expr *) {}
virtual void callBuiltinFinishTry() {}
virtual void callBuiltinForeachIteratorObject(V4IR::Temp *, V4IR::Temp *) {}
@@ -420,6 +421,13 @@ protected: // IRDecoder
{
bool needsCall = true;
+ if (leftSource->type == DoubleType && rightSource->type == DoubleType) {
+ if (oper == OpMul || oper == OpAdd || oper == OpDiv || oper == OpSub
+ || (oper >= OpGt && oper <= OpStrictNotEqual)) {
+ needsCall = false;
+ }
+ }
+
#if 0 // TODO: change masm to generate code
switch (leftSource->type) {
case DoubleType:
@@ -750,143 +758,6 @@ private:
}
}
- class MoveMapping
- {
- struct Move {
- Expr *from;
- Temp *to;
- bool needsSwap;
-
- Move(Expr *from, Temp *to)
- : from(from), to(to), needsSwap(false)
- {}
-
- bool operator==(const Move &other) const
- { return from == other.from && to == other.to; }
- };
-
- QList<Move> _moves;
-
- int isUsedAsSource(Expr *e) const
- {
- if (Temp *t = e->asTemp())
- for (int i = 0, ei = _moves.size(); i != ei; ++i)
- if (Temp *from = _moves[i].from->asTemp())
- if (*from == *t)
- return i;
-
- return -1;
- }
-
- public:
- void add(Expr *from, Temp *to) {
- if (Temp *t = from->asTemp())
- if (*t == *to)
- return;
-
- Move m(from, to);
- if (_moves.contains(m))
- return;
- _moves.append(m);
- }
-
- void order()
- {
- QList<Move> todo = _moves;
- QList<Move> output;
- output.reserve(_moves.size());
- QList<Move> delayed;
- delayed.reserve(_moves.size());
-
- while (!todo.isEmpty()) {
- const Move m = todo.first();
- todo.removeFirst();
- schedule(m, todo, delayed, output);
- }
-
- Q_ASSERT(todo.isEmpty());
- Q_ASSERT(delayed.isEmpty());
- qSwap(_moves, output);
-#if !defined(QT_NO_DEBUG)
- int swapCount = 0;
- foreach (const Move &m, _moves)
- if (m.needsSwap)
- ++swapCount;
- Q_ASSERT(output.size() == _moves.size() + swapCount);
-#endif
- }
-
-#ifdef DEBUG_REGALLOC
- void dump() const
- {
- QTextStream os(stdout, QIODevice::WriteOnly);
- os << "Move mapping has " << _moves.size() << " moves..." << endl;
- foreach (const Move &m, _moves) {
- os << "\t";
- m.to->dump(os);
- if (m.needsSwap)
- os << " <-> ";
- else
- os << " <-- ";
- m.from->dump(os);
- os << endl;
- }
- }
-#endif // DEBUG_REGALLOC
-
- void insertMoves(BasicBlock *predecessor, Function *function) const
- {
- int predecessorInsertionPoint = predecessor->statements.size() - 1;
- foreach (const Move &m, _moves) {
- V4IR::Move *move = function->New<V4IR::Move>();
- move->init(m.to, m.from, OpInvalid);
- move->swap = m.needsSwap;
- predecessor->statements.insert(predecessorInsertionPoint++, move);
- }
- }
-
- private:
- enum Action { NormalMove, NeedsSwap };
- Action schedule(const Move &m, QList<Move> &todo, QList<Move> &delayed, QList<Move> &output) const
- {
- int useIdx = isUsedAsSource(m.to);
- if (useIdx != -1) {
- const Move &dependency = _moves[useIdx];
- if (!output.contains(dependency)) {
- if (delayed.contains(dependency)) {
- // we have a cycle! Break it by using the scratch register
- delayed+=m;
-#ifdef DEBUG_REGALLOC
- QTextStream out(stderr, QIODevice::WriteOnly);
- out<<"we have a cycle! temps:" << endl;
- foreach (const Move &m, delayed) {
- out<<"\t";
- m.to->dump(out);
- out<<" <- ";
- m.from->dump(out);
- out<<endl;
- }
-#endif
- delayed.removeOne(m);
- return NeedsSwap;
- } else {
- delayed.append(m);
- todo.removeOne(dependency);
- Action action = schedule(dependency, todo, delayed, output);
- delayed.removeOne(m);
- Move mm(m);
- mm.needsSwap = action == NeedsSwap;
- output.append(mm);
- return action;
- }
- }
- }
-
- output.append(m);
- return NormalMove;
- }
- };
-
void resolveEdge(BasicBlock *predecessor, BasicBlock *successor)
{
#ifdef DEBUG_REGALLOC
@@ -909,6 +780,7 @@ private:
Q_ASSERT(successorStart > 0);
foreach (const LifeTimeInterval &it, _liveAtStart[successor]) {
+ bool lifeTimeHole = false;
if (it.end() < successorStart)
continue;
Expr *moveFrom = 0;
@@ -953,15 +825,18 @@ private:
predIt.temp().type);
} else {
int spillSlot = _assignedSpillSlots.value(predIt.temp(), -1);
- Q_ASSERT(spillSlot != -1);
- moveFrom = createTemp(Temp::StackSlot, spillSlot, predIt.temp().type);
+ if (spillSlot == -1)
+ lifeTimeHole = true;
+ else
+ moveFrom = createTemp(Temp::StackSlot, spillSlot, predIt.temp().type);
}
break;
}
}
}
if (!moveFrom) {
- Q_ASSERT(!_info->isPhiTarget(it.temp()) || it.isSplitFromInterval());
+ Q_ASSERT(!_info->isPhiTarget(it.temp()) || it.isSplitFromInterval() || lifeTimeHole);
+ Q_UNUSED(lifeTimeHole);
#if !defined(QT_NO_DEBUG)
if (_info->def(it.temp()) != successorStart && !it.isSplitFromInterval()) {
const int successorEnd = successor->statements.last()->id;
@@ -976,7 +851,8 @@ private:
Temp *moveTo;
if (it.reg() == LifeTimeInterval::Invalid || !it.covers(successorStart)) {
int spillSlot = _assignedSpillSlots.value(it.temp(), -1);
- Q_ASSERT(spillSlot != -1); // TODO: check isStructurallyValidLanguageTag
+ if (spillSlot == -1)
+ continue; // it has a life-time hole here.
moveTo = createTemp(Temp::StackSlot, spillSlot, it.temp().type);
} else {
moveTo = createTemp(Temp::PhysicalRegister, platformRegister(it), it.temp().type);
@@ -1116,7 +992,7 @@ void RegisterAllocator::run(Function *function, const Optimizer &opt)
QTextStream qout(stdout, QIODevice::WriteOnly);
qout << "Ranges:" << endl;
QList<LifeTimeInterval> handled = _unhandled;
- qSort(handled.begin(), handled.end(), LifeTimeInterval::lessThanForTemp);
+ std::sort(handled.begin(), handled.end(), LifeTimeInterval::lessThanForTemp);
foreach (const LifeTimeInterval &r, handled) {
r.dump(qout);
qout << endl;
@@ -1139,7 +1015,7 @@ void RegisterAllocator::run(Function *function, const Optimizer &opt)
dump();
#endif // DEBUG_REGALLOC
- qSort(_handled.begin(), _handled.end(), LifeTimeInterval::lessThan);
+ std::sort(_handled.begin(), _handled.end(), LifeTimeInterval::lessThan);
ResolutionPhase(_handled, function, _info.data(), _assignedSpillSlots, _normalRegisters, _fpRegisters).run();
function->tempCount = QSet<int>::fromList(_assignedSpillSlots.values()).size();
@@ -1188,7 +1064,7 @@ void RegisterAllocator::prepareRanges()
if (_fixedFPRegisterRanges[fpReg].isValid())
_active.append(_fixedFPRegisterRanges[fpReg]);
- qSort(_active.begin(), _active.end(), LifeTimeInterval::lessThan);
+ std::sort(_active.begin(), _active.end(), LifeTimeInterval::lessThan);
}
void RegisterAllocator::linearScan()
@@ -1419,6 +1295,7 @@ void RegisterAllocator::allocateBlockedReg(LifeTimeInterval &current, const int
QTextStream out(stderr, QIODevice::WriteOnly);
out << "*** splitting current for range ";current.dump(out);out<<endl;
#endif // DEBUG_REGALLOC
+ Q_ASSERT(!_info->useMustHaveReg(current.temp(), position));
split(current, position + 1, true);
_inactive.append(current);
} else {
@@ -1609,7 +1486,7 @@ void RegisterAllocator::dump() const
{
qout << "Ranges:" << endl;
QList<LifeTimeInterval> handled = _handled;
- qSort(handled.begin(), handled.end(), LifeTimeInterval::lessThanForTemp);
+ std::sort(handled.begin(), handled.end(), LifeTimeInterval::lessThanForTemp);
foreach (const LifeTimeInterval &r, handled) {
r.dump(qout);
qout << endl;
@@ -1621,7 +1498,7 @@ void RegisterAllocator::dump() const
QList<Temp> temps = _assignedSpillSlots.keys();
if (temps.isEmpty())
qout << "\t(none)" << endl;
- qSort(temps);
+ std::sort(temps.begin(), temps.end());
foreach (const Temp &t, temps) {
qout << "\t";
t.dump(qout);
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 528450b73e..5f62adb1b1 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -54,6 +54,7 @@
#include <cmath>
#include <iostream>
#include <cassert>
+#include <algorithm>
#ifdef CONST
#undef CONST
@@ -61,6 +62,7 @@
#define QV4_NO_LIVENESS
#undef SHOW_SSA
+#undef DEBUG_MOVEMAPPING
QT_USE_NAMESPACE
@@ -423,7 +425,7 @@ public:
VariableCollector(Function *function)
: variablesCanEscape(function->variablesCanEscape())
{
-#ifdef SHOW_SSA
+#if defined(SHOW_SSA)
qout << "Variables collected:" << endl;
#endif // SHOW_SSA
@@ -436,7 +438,7 @@ public:
}
}
-#ifdef SHOW_SSA
+#if defined(SHOW_SSA)
qout << "Non-locals:" << endl;
foreach (const Temp &nonLocal, nonLocals) {
qout << "\t";
@@ -499,7 +501,7 @@ protected:
if (Temp *t = s->target->asTemp()) {
if (isCollectable(t)) {
-#ifdef SHOW_SSA
+#if defined(SHOW_SSA)
qout << '\t';
t->dump(qout);
qout << " -> L" << currentBB->index << endl;
@@ -511,6 +513,8 @@ protected:
// For semi-pruned SSA:
killed.insert(*t);
}
+ } else {
+ s->target->accept(this);
}
}
@@ -1041,15 +1045,19 @@ public:
_worklist.removeFirst();
if (_defUses.useCount(v) == 0) {
-// qDebug()<<"-"<<v<<"has no uses...";
+#if defined(SHOW_SSA)
+ qout<<"- ";v.dump(qout);qout<<" has no uses..."<<endl;
+#endif
Stmt *s = _defUses.defStmt(v);
if (!s) {
_defUses.removeDef(v);
} else if (!hasSideEffect(s)) {
-#ifdef SHOW_SSA
- qout<<"-- defining stmt for";
+#if defined(SHOW_SSA)
+ qout<<"-- defining stmt for ";
v.dump(qout);
- qout<<"has no side effect"<<endl;
+ qout<<" has no side effect: ";
+ s->dump(qout);
+ qout<<endl;
#endif
QVector<Stmt *> &stmts = _defUses.defStmtBlock(v)->statements;
int idx = stmts.indexOf(s);
@@ -1063,11 +1071,6 @@ public:
}
}
}
-
-#ifdef SHOW_SSA
- qout<<"******************* After dead-code elimination:";
- _defUses.dump();
-#endif
}
private:
@@ -1204,9 +1207,76 @@ public:
}
}
}
+
+ PropagateTempTypes(_tempTypes).run(function);
}
private:
+ class PropagateTempTypes: public StmtVisitor, ExprVisitor
+ {
+ public:
+ PropagateTempTypes(const QHash<Temp, int> &tempTypes)
+ : _tempTypes(tempTypes)
+ {}
+
+ void run(Function *function)
+ {
+ foreach (BasicBlock *bb, function->basicBlocks)
+ foreach (Stmt *s, bb->statements)
+ s->accept(this);
+ }
+
+ protected:
+ virtual void visitConst(Const *e) {}
+ virtual void visitString(String *) {}
+ virtual void visitRegExp(RegExp *) {}
+ virtual void visitName(Name *) {}
+ virtual void visitTemp(Temp *e) { e->type = (Type) _tempTypes[*e]; }
+ virtual void visitClosure(Closure *) {}
+ virtual void visitConvert(Convert *e) { e->expr->accept(this); }
+ virtual void visitUnop(Unop *e) { e->expr->accept(this); }
+ virtual void visitBinop(Binop *e) { e->left->accept(this); e->right->accept(this); }
+
+ virtual void visitCall(Call *e) {
+ e->base->accept(this);
+ for (ExprList *it = e->args; it; it = it->next)
+ it->expr->accept(this);
+ }
+ virtual void visitNew(New *e) {
+ e->base->accept(this);
+ for (ExprList *it = e->args; it; it = it->next)
+ it->expr->accept(this);
+ }
+ virtual void visitSubscript(Subscript *e) {
+ e->base->accept(this);
+ e->index->accept(this);
+ }
+
+ virtual void visitMember(Member *e) {
+ e->base->accept(this);
+ }
+
+ virtual void visitExp(Exp *s) {s->expr->accept(this);}
+ virtual void visitMove(Move *s) {
+ s->source->accept(this);
+ s->target->accept(this);
+ }
+
+ virtual void visitJump(Jump *) {}
+ virtual void visitCJump(CJump *s) { s->cond->accept(this); }
+ virtual void visitRet(Ret *s) { s->expr->accept(this); }
+ virtual void visitTry(Try *s) { s->exceptionVar->accept(this); }
+ virtual void visitPhi(Phi *s) {
+ s->targetTemp->accept(this);
+ foreach (Expr *e, s->d->incoming)
+ e->accept(this);
+ }
+
+ private:
+ QHash<Temp, int> _tempTypes;
+ };
+
+private:
bool run(Stmt *s) {
TypingResult ty;
std::swap(_ty, ty);
@@ -1244,24 +1314,20 @@ private:
#if defined(SHOW_SSA)
qout<<"Setting type for "<< (t->scope?"scoped temp ":"temp ") <<t->index<< " to "<<typeName(Type(ty)) << " (" << ty << ")" << endl;
#endif
- if (isAlwaysAnObject(t)) {
- e->type = ObjectType;
- } else {
- e->type = (Type) ty;
-
- if (_tempTypes[*t] != ty) {
- _tempTypes[*t] = ty;
+ if (isAlwaysAnObject(t))
+ ty = ObjectType;
+ if (_tempTypes[*t] != ty) {
+ _tempTypes[*t] = ty;
#if defined(SHOW_SSA)
- foreach (Stmt *s, _defUses.uses(*t)) {
- qout << "Pushing back dependent stmt: ";
- s->dump(qout);
- qout << endl;
- }
+ foreach (Stmt *s, _defUses.uses(*t)) {
+ qout << "Pushing back dependent stmt: ";
+ s->dump(qout);
+ qout << endl;
+ }
#endif
- _worklist += QSet<Stmt *>::fromList(_defUses.uses(*t));
- }
+ _worklist += QSet<Stmt *>::fromList(_defUses.uses(*t));
}
} else {
e->type = (Type) ty;
@@ -1896,6 +1962,19 @@ inline Temp *isSameTempPhi(Phi *phi)
return 0;
}
+static Expr *clone(Expr *e, Function *function) {
+ if (Temp *t = e->asTemp()) {
+ return CloneExpr::cloneTemp(t, function);
+ } else if (Const *c = e->asConst()) {
+ return CloneExpr::cloneConst(c, function);
+ } else if (Name *n = e->asName()) {
+ return CloneExpr::cloneName(n, function);
+ } else {
+ Q_UNREACHABLE();
+ return e;
+ }
+}
+
class ExprReplacer: public StmtVisitor, public ExprVisitor
{
DefUsesCalculator &_defUses;
@@ -1969,22 +2048,9 @@ protected:
}
private:
- Expr *clone(Expr *e) const {
- if (Temp *t = e->asTemp()) {
- return CloneExpr::cloneTemp(t, _function);
- } else if (Const *c = e->asConst()) {
- return CloneExpr::cloneConst(c, _function);
- } else if (Name *n = e->asName()) {
- return CloneExpr::cloneName(n, _function);
- } else {
- Q_UNIMPLEMENTED();
- return e;
- }
- }
-
void check(Expr *&e) {
if (equals(e, _toReplace))
- e = clone(_replacement);
+ e = clone(_replacement, _function);
else
e->accept(this);
}
@@ -2209,7 +2275,6 @@ void optimizeSSA(Function *function, DefUsesCalculator &defUses)
*ref[s] = 0;
continue;
}
-
} else if (Move *m = s->asMove()) {
if (Temp *t = unescapableTemp(m->target, variablesCanEscape)) {
// constant propagation:
@@ -2217,13 +2282,13 @@ void optimizeSSA(Function *function, DefUsesCalculator &defUses)
if (c->type & NumberType || c->type == BoolType) {
// TODO: when propagating other constants, e.g. undefined, the other
// optimization passes have to be changed to cope with them.
-// qout<<"propagating constant from ";s->dump(qout);qout<<" info:"<<endl;
W += replaceUses(t, c);
defUses.removeDef(*t);
*ref[s] = 0;
}
continue;
}
+
#if defined(PROPAGATE_THIS)
if (Name *n = m->source->asName()) {
qout<<"propagating constant from ";s->dump(qout);qout<<" info:"<<endl;
@@ -2233,6 +2298,7 @@ void optimizeSSA(Function *function, DefUsesCalculator &defUses)
continue;
}
#endif
+
// copy propagation:
if (Temp *t2 = unescapableTemp(m->source, variablesCanEscape)) {
QVector<Stmt *> newT2Uses = replaceUses(t, t2);
@@ -2363,6 +2429,7 @@ void optimizeSSA(Function *function, DefUsesCalculator &defUses)
continue;
}
}
+
} else if (CJump *cjump = s->asCJump()) {
if (Const *c = cjump->cond->asConst()) {
// Note: this assumes that there are no critical edges! Meaning, we can safely purge
@@ -2512,7 +2579,7 @@ public:
range.setTemp(i.key());
_sortedRanges.append(range);
}
- qSort(_sortedRanges.begin(), _sortedRanges.end(), LifeTimeInterval::lessThan);
+ std::sort(_sortedRanges.begin(), _sortedRanges.end(), LifeTimeInterval::lessThan);
}
QList<LifeTimeInterval> ranges() const { return _sortedRanges; }
@@ -2529,7 +2596,7 @@ public:
foreach (BasicBlock *bb, _liveIn.keys()) {
qout << "L" << bb->index <<" live-in: ";
QList<Temp> live = QList<Temp>::fromSet(_liveIn.value(bb));
- qSort(live);
+ std::sort(live.begin(), live.end());
for (int i = 0; i < live.size(); ++i) {
if (i > 0) qout << ", ";
live[i].dump(qout);
@@ -2707,7 +2774,7 @@ void Optimizer::run()
// Number all basic blocks, so we have nice numbers in the dumps:
for (int i = 0; i < function->basicBlocks.size(); ++i)
function->basicBlocks[i]->index = i;
- showMeTheCode(function);
+// showMeTheCode(function);
cleanupBasicBlocks(function);
@@ -2719,6 +2786,7 @@ void Optimizer::run()
static bool doOpt = qgetenv("QV4_NO_OPT").isEmpty();
if (!function->hasTry && !function->hasWith && doSSA) {
+// qout << "SSA for " << *function->name << endl;
// qout << "Starting edge splitting..." << endl;
splitCriticalEdges(function);
// showMeTheCode(function);
@@ -2763,83 +2831,62 @@ void Optimizer::run()
checkCriticalEdges(function->basicBlocks);
#endif
-// qout << "Finished." << endl;
+// qout << "Finished SSA." << endl;
inSSA = true;
} else {
inSSA = false;
}
}
-namespace {
-void insertMove(Function *function, BasicBlock *basicBlock, Temp *target, Expr *source) {
- if (target->type != source->type) {
- if (source->asConst()) {
- const int idx = function->tempCount++;
+void Optimizer::convertOutOfSSA() {
+ if (!inSSA)
+ return;
- Temp *tmp = function->New<Temp>();
- tmp->init(Temp::VirtualRegister, idx, 0);
+ // There should be no critical edges at this point.
- Move *s = function->New<Move>();
- s->init(tmp, source, OpInvalid);
- basicBlock->statements.insert(basicBlock->statements.size() - 1, s);
+ foreach (BasicBlock *bb, function->basicBlocks) {
+ const int id = bb->statements.last()->id;
+ MoveMapping moves;
- tmp = function->New<Temp>();
- tmp->init(Temp::VirtualRegister, idx, 0);
- source = tmp;
+ foreach (BasicBlock *successor, bb->out) {
+ const int inIdx = successor->in.indexOf(bb);
+ Q_ASSERT(inIdx >= 0);
+ foreach (Stmt *s, successor->statements) {
+ if (Phi *phi = s->asPhi()) {
+ moves.add(clone(phi->d->incoming[inIdx], function),
+ clone(phi->targetTemp, function)->asTemp(), id);
+ } else {
+ break;
+ }
+ }
}
- source = basicBlock->CONVERT(source, target->type);
- }
- Move *s = function->New<Move>();
- s->init(target, source, OpInvalid);
- basicBlock->statements.insert(basicBlock->statements.size() - 1, s);
-}
-}
+ #if defined(DEBUG_MOVEMAPPING)
+ QTextStream os(stdout, QIODevice::WriteOnly);
+ os << "Move mapping for function ";
+ if (function->name)
+ os << *function->name;
+ else
+ os << (void *) function;
+ os << " on basic-block L" << bb->index << ":" << endl;
+ moves.dump();
+ #endif // DEBUG_MOVEMAPPING
-/*
- * Quick function to convert out of SSA, so we can put the stuff through the ISel phases. This
- * has to be replaced by a phase in the specific ISel back-ends and do register allocation at the
- * same time. That way the huge number of redundant moves generated by this function are eliminated.
- */
-void Optimizer::convertOutOfSSA() {
- // We assume that edge-splitting is already done.
- foreach (BasicBlock *bb, function->basicBlocks) {
- QVector<Stmt *> &stmts = bb->statements;
- while (!stmts.isEmpty()) {
- Stmt *s = stmts.first();
- if (Phi *phi = s->asPhi()) {
- stmts.removeFirst();
- for (int i = 0, ei = phi->d->incoming.size(); i != ei; ++i)
- insertMove(function, bb->in[i], phi->targetTemp, phi->d->incoming[i]);
- phi->destroyData();
- } else {
- break;
- }
- }
- }
-}
+ moves.order();
-QList<Optimizer::SSADeconstructionMove> Optimizer::ssaDeconstructionMoves(BasicBlock *basicBlock) const
-{
- QList<SSADeconstructionMove> moves;
+ moves.insertMoves(bb, function);
+ }
- foreach (BasicBlock *outEdge, basicBlock->out) {
- int inIdx = outEdge->in.indexOf(basicBlock);
- Q_ASSERT(inIdx >= 0);
- foreach (Stmt *s, outEdge->statements) {
- if (Phi *phi = s->asPhi()) {
- SSADeconstructionMove m;
- m.phi = phi;
- m.source = phi->d->incoming[inIdx];
- m.target = phi->targetTemp;
- moves.append(m);
+ foreach (BasicBlock *bb, function->basicBlocks) {
+ while (!bb->statements.isEmpty()) {
+ if (Phi *phi = bb->statements.first()->asPhi()) {
+ phi->destroyData();
+ bb->statements.removeFirst();
} else {
break;
}
}
}
-
- return moves;
}
QList<LifeTimeInterval> Optimizer::lifeRanges() const
@@ -2856,3 +2903,152 @@ void Optimizer::showMeTheCode(Function *function)
{
::showMeTheCode(function);
}
+
+static inline bool overlappingStorage(const Temp &t1, const Temp &t2)
+{
+ // This is the same as the operator==, but for one detail: memory locations are not sensitive
+ // to types, and neither are general-purpose registers.
+
+ if (t1.scope != t2.scope)
+ return false;
+ if (t1.index != t2.index)
+ return false; // different position, where-ever that may (physically) be.
+ if (t1.kind != t2.kind)
+ return false; // formal/local/(physical-)register/stack do never overlap
+ if (t1.kind != Temp::PhysicalRegister) // Other than registers, ...
+ return t1.kind == t2.kind; // ... everything else overlaps: any memory location can hold everything.
+
+ // So now the index is the same, and we know that both stored in a register. If both are
+ // floating-point registers, they are the same. Or, if both are non-floating-point registers,
+ // generally called general-purpose registers, they are also the same.
+ return (t1.type == DoubleType && t2.type == DoubleType)
+ || (t1.type != DoubleType && t2.type != DoubleType);
+}
+
+int MoveMapping::isUsedAsSource(Expr *e) const
+{
+ if (Temp *t = e->asTemp())
+ for (int i = 0, ei = _moves.size(); i != ei; ++i)
+ if (Temp *from = _moves[i].from->asTemp())
+ if (overlappingStorage(*from, *t))
+ return i;
+
+ return -1;
+}
+
+void MoveMapping::add(Expr *from, Temp *to, int id) {
+ if (Temp *t = from->asTemp()) {
+ if (overlappingStorage(*t, *to)) {
+ // assignments like fp1 = fp1 or var{&1} = double{&1} can safely be skipped.
+#if defined(DEBUG_MOVEMAPPING)
+ QTextStream os(stderr, QIODevice::WriteOnly);
+ os << "Skipping ";
+ to->dump(os);
+ os << " <- ";
+ from->dump(os);
+ os << endl;
+#endif // DEBUG_MOVEMAPPING
+ return;
+ }
+ }
+
+ Move m(from, to, id);
+ if (_moves.contains(m))
+ return;
+ _moves.append(m);
+}
+
+void MoveMapping::order()
+{
+ QList<Move> todo = _moves;
+ QList<Move> output, swaps;
+ output.reserve(_moves.size());
+ QList<Move> delayed;
+ delayed.reserve(_moves.size());
+
+ while (!todo.isEmpty()) {
+ const Move m = todo.first();
+ todo.removeFirst();
+ schedule(m, todo, delayed, output, swaps);
+ }
+
+ output += swaps;
+
+ Q_ASSERT(todo.isEmpty());
+ Q_ASSERT(delayed.isEmpty());
+ qSwap(_moves, output);
+}
+
+void MoveMapping::insertMoves(BasicBlock *predecessor, Function *function) const
+{
+ int predecessorInsertionPoint = predecessor->statements.size() - 1;
+ foreach (const Move &m, _moves) {
+ V4IR::Move *move = function->New<V4IR::Move>();
+ move->init(m.to, m.from, OpInvalid);
+ move->id = m.id;
+ move->swap = m.needsSwap;
+ predecessor->statements.insert(predecessorInsertionPoint++, move);
+ }
+}
+
+void MoveMapping::dump() const
+{
+#if defined(DEBUG_MOVEMAPPING)
+ QTextStream os(stdout, QIODevice::WriteOnly);
+ os << "Move mapping has " << _moves.size() << " moves..." << endl;
+ foreach (const Move &m, _moves) {
+ os << "\t";
+ m.to->dump(os);
+ if (m.needsSwap)
+ os << " <-> ";
+ else
+ os << " <-- ";
+ m.from->dump(os);
+ os << endl;
+ }
+#endif // DEBUG_MOVEMAPPING
+}
+
+MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QList<Move> &delayed,
+ QList<Move> &output, QList<Move> &swaps) const
+{
+ int useIdx = isUsedAsSource(m.to);
+ if (useIdx != -1) {
+ const Move &dependency = _moves[useIdx];
+ if (!output.contains(dependency)) {
+ if (delayed.contains(dependency)) {
+ // We have a cycle! Break it by swapping instead of assigning.
+#if defined(DEBUG_MOVEMAPPING)
+ delayed+=m;
+ QTextStream out(stderr, QIODevice::WriteOnly);
+ out<<"we have a cycle! temps:" << endl;
+ foreach (const Move &m, delayed) {
+ out<<"\t";
+ m.to->dump(out);
+ out<<" <- ";
+ m.from->dump(out);
+ out<<endl;
+ }
+ delayed.removeOne(m);
+#endif // DEBUG_MOVEMAPPING
+ return NeedsSwap;
+ } else {
+ delayed.append(m);
+ todo.removeOne(dependency);
+ Action action = schedule(dependency, todo, delayed, output, swaps);
+ delayed.removeOne(m);
+ Move mm(m);
+ if (action == NeedsSwap) {
+ mm.needsSwap = true;
+ swaps.append(mm);
+ } else {
+ output.append(mm);
+ }
+ return action;
+ }
+ }
+ }
+
+ output.append(m);
+ return NormalMove;
+}
diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h
index 2195cfd9bb..1fabc8e76f 100644
--- a/src/qml/compiler/qv4ssa_p.h
+++ b/src/qml/compiler/qv4ssa_p.h
@@ -118,17 +118,6 @@ public:
class Optimizer
{
public:
- struct SSADeconstructionMove
- {
- Stmt *phi;
- Expr *source;
- Temp *target;
-
- bool needsConversion() const
- { return target->type != source->type; }
- };
-
-public:
Optimizer(Function *function)
: function(function)
, inSSA(false)
@@ -142,8 +131,6 @@ public:
QHash<BasicBlock *, BasicBlock *> loopStartEndBlocks() const { return startEndLoops; }
- QList<SSADeconstructionMove> ssaDeconstructionMoves(BasicBlock *basicBlock) const;
-
QList<LifeTimeInterval> lifeRanges() const;
static void showMeTheCode(Function *function);
@@ -154,6 +141,39 @@ private:
QHash<BasicBlock *, BasicBlock *> startEndLoops;
};
+class MoveMapping
+{
+ struct Move {
+ Expr *from;
+ Temp *to;
+ int id;
+ bool needsSwap;
+
+ Move(Expr *from, Temp *to, int id)
+ : from(from), to(to), id(id), needsSwap(false)
+ {}
+
+ bool operator==(const Move &other) const
+ { return from == other.from && to == other.to; }
+ };
+
+ QList<Move> _moves;
+
+ int isUsedAsSource(Expr *e) const;
+
+public:
+ void add(Expr *from, Temp *to, int id = 0);
+ void order();
+ void insertMoves(BasicBlock *predecessor, Function *function) const;
+
+ void dump() const;
+
+private:
+ enum Action { NormalMove, NeedsSwap };
+ Action schedule(const Move &m, QList<Move> &todo, QList<Move> &delayed, QList<Move> &output,
+ QList<Move> &swaps) const;
+};
+
} // V4IR namespace
} // QQmlJS namespace
QT_END_NAMESPACE
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri
index f16e225cfd..c10f43c8c9 100644
--- a/src/qml/debugger/debugger.pri
+++ b/src/qml/debugger/debugger.pri
@@ -3,10 +3,10 @@ SOURCES += \
$$PWD/qqmlprofilerservice.cpp \
$$PWD/qqmldebugserver.cpp \
$$PWD/qqmlinspectorservice.cpp \
- $$PWD/qv8debugservice.cpp \
$$PWD/qv8profilerservice.cpp \
$$PWD/qqmlenginedebugservice.cpp \
- $$PWD/qdebugmessageservice.cpp
+ $$PWD/qdebugmessageservice.cpp \
+ $$PWD/qv4debugservice.cpp
HEADERS += \
$$PWD/qqmldebugservice_p.h \
@@ -17,8 +17,8 @@ HEADERS += \
$$PWD/qqmldebugstatesdelegate_p.h \
$$PWD/qqmlinspectorservice_p.h \
$$PWD/qqmlinspectorinterface_p.h \
- $$PWD/qv8debugservice_p.h \
$$PWD/qv8profilerservice_p.h \
$$PWD/qqmlenginedebugservice_p.h \
$$PWD/qqmldebug.h \
- $$PWD/qdebugmessageservice_p.h
+ $$PWD/qdebugmessageservice_p.h \
+ $$PWD/qv4debugservice_p.h
diff --git a/src/qml/debugger/qqmlinspectorservice_p.h b/src/qml/debugger/qqmlinspectorservice_p.h
index f8b2a39240..6496ba8ffd 100644
--- a/src/qml/debugger/qqmlinspectorservice_p.h
+++ b/src/qml/debugger/qqmlinspectorservice_p.h
@@ -80,7 +80,7 @@ protected:
virtual void stateChanged(State state);
virtual void messageReceived(const QByteArray &);
-private slots:
+private Q_SLOTS:
void processMessage(const QByteArray &message);
void updateState();
diff --git a/src/qml/debugger/qv4debugservice.cpp b/src/qml/debugger/qv4debugservice.cpp
new file mode 100644
index 0000000000..ac239f31be
--- /dev/null
+++ b/src/qml/debugger/qv4debugservice.cpp
@@ -0,0 +1,325 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4debugservice_p.h"
+#include "qqmldebugservice_p_p.h"
+#include "qqmlengine.h"
+#include "qv4debugging_p.h"
+#include "qv4engine_p.h"
+#include "qv4function_p.h"
+
+#include <private/qv8engine_p.h>
+
+const char *V4_CONNECT = "connect";
+const char *V4_BREAK_ON_SIGNAL = "breakonsignal";
+const char *V4_ADD_BREAKPOINT = "addBreakpoint";
+const char *V4_REMOVE_BREAKPOINT = "removeBreakpoint";
+const char *V4_PAUSE = "interrupt";
+const char *V4_ALL = "all";
+const char *V4_BREAK = "break";
+
+const char *V4_FILENAME = "filename";
+const char *V4_LINENUMBER = "linenumber";
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC(QV4DebugService, v4ServiceInstance)
+
+class QV4DebuggerAgent : public QV4::Debugging::DebuggerAgent
+{
+public slots:
+ virtual void debuggerPaused(QV4::Debugging::Debugger *debugger);
+};
+
+class QV4DebugServicePrivate : public QQmlDebugServicePrivate
+{
+ Q_DECLARE_PUBLIC(QV4DebugService)
+
+public:
+ QV4DebugServicePrivate() : version(1) {}
+
+ static QByteArray packMessage(const QByteArray &command, int querySequence, const QByteArray &message = QByteArray())
+ {
+ QByteArray reply;
+ QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
+ const QByteArray cmd("V4DEBUG");
+ rs << cmd << QByteArray::number(++sequence) << QByteArray::number(querySequence) << command << message;
+ return reply;
+ }
+
+ void processCommand(const QByteArray &command, const QByteArray &data);
+ void addBreakpoint(const QByteArray &data);
+ void removeBreakpoint(const QByteArray &data);
+
+ QMutex initializeMutex;
+ QWaitCondition initializeCondition;
+ QV4DebuggerAgent debuggerAgent;
+
+ QStringList breakOnSignals;
+ QMap<int, QV4::Debugging::Debugger *> debuggerMap;
+ static int debuggerIndex;
+ static int sequence;
+ const int version;
+};
+
+int QV4DebugServicePrivate::debuggerIndex = 0;
+int QV4DebugServicePrivate::sequence = 0;
+
+QV4DebugService::QV4DebugService(QObject *parent)
+ : QQmlDebugService(*(new QV4DebugServicePrivate()),
+ QStringLiteral("V4Debugger"), 1, parent)
+{
+ Q_D(QV4DebugService);
+
+ // don't execute stateChanged, messageReceived in parallel
+ QMutexLocker lock(&d->initializeMutex);
+
+ if (registerService() == Enabled && blockingMode()) {
+ // let's wait for first message ...
+ d->initializeCondition.wait(&d->initializeMutex);
+ }
+}
+
+QV4DebugService::~QV4DebugService()
+{
+}
+
+QV4DebugService *QV4DebugService::instance()
+{
+ return v4ServiceInstance();
+}
+
+void QV4DebugService::addEngine(const QQmlEngine *engine)
+{
+ Q_D(QV4DebugService);
+ if (engine) {
+ QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
+ if (ee) {
+ ee->enableDebugger();
+ QV4::Debugging::Debugger *debugger = ee->debugger;
+ d->debuggerMap.insert(d->debuggerIndex++, debugger);
+ d->debuggerAgent.addDebugger(debugger);
+ }
+ }
+}
+
+void QV4DebugService::removeEngine(const QQmlEngine *engine)
+{
+ Q_D(QV4DebugService);
+ if (engine){
+ const QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
+ if (ee) {
+ QV4::Debugging::Debugger *debugger = ee->debugger;
+ typedef QMap<int, QV4::Debugging::Debugger *>::const_iterator DebuggerMapIterator;
+ const DebuggerMapIterator end = d->debuggerMap.constEnd();
+ for (DebuggerMapIterator i = d->debuggerMap.constBegin(); i != end; ++i) {
+ if (i.value() == debugger) {
+ d->debuggerMap.remove(i.key());
+ break;
+ }
+ }
+ d->debuggerAgent.removeDebugger(debugger);
+ }
+ }
+}
+
+void QV4DebugService::signalEmitted(const QString &signal)
+{
+ //This function is only called by QQmlBoundSignal
+ //only if there is a slot connected to the signal. Hence, there
+ //is no need for additional check.
+ Q_D(QV4DebugService);
+
+ //Parse just the name and remove the class info
+ //Normalize to Lower case.
+ QString signalName = signal.left(signal.indexOf(QLatin1Char('('))).toLower();
+
+ foreach (const QString &signal, d->breakOnSignals) {
+ if (signal == signalName) {
+ // TODO: pause debugger
+ break;
+ }
+ }
+}
+
+void QV4DebugService::stateChanged(QQmlDebugService::State newState)
+{
+ Q_D(QV4DebugService);
+ QMutexLocker lock(&d->initializeMutex);
+
+ if (newState != Enabled) {
+ // wake up constructor in blocking mode
+ // (we might got disabled before first message arrived)
+ d->initializeCondition.wakeAll();
+ }
+}
+
+void QV4DebugService::messageReceived(const QByteArray &message)
+{
+ Q_D(QV4DebugService);
+ QMutexLocker lock(&d->initializeMutex);
+
+ QQmlDebugStream ms(message);
+ QByteArray header;
+ ms >> header;
+
+ if (header == "V4DEBUG") {
+ QByteArray sequenceValue;
+ QByteArray command;
+ QByteArray data;
+ ms >> sequenceValue >> command >> data;
+
+ QQmlDebugStream ds(data);
+
+ QByteArray versionValue;
+ QByteArray debuggerValue;
+ ds >> versionValue >> debuggerValue; // unused for now
+
+ int querySequence = sequenceValue.toInt();
+ if (command == V4_BREAK_ON_SIGNAL) {
+ QByteArray signal;
+ bool enabled;
+ ds >> signal >> enabled;
+ //Normalize to lower case.
+ QString signalName(QString::fromUtf8(signal).toLower());
+ if (enabled)
+ d->breakOnSignals.append(signalName);
+ else
+ d->breakOnSignals.removeOne(signalName);
+ } else if (command == V4_ADD_BREAKPOINT) {
+ QMetaObject::invokeMethod(this, "addBreakpoint", Qt::QueuedConnection,
+ Q_ARG(QByteArray, data), Q_ARG(int, querySequence));
+ } else if (command == V4_REMOVE_BREAKPOINT) {
+ QMetaObject::invokeMethod(this, "removeBreakpoint", Qt::QueuedConnection,
+ Q_ARG(QByteArray, data), Q_ARG(int, querySequence));
+ } else if (command == V4_PAUSE) {
+ int id = ds.atEnd() ? debuggerValue.toInt() : -1;
+ QMetaObject::invokeMethod(this, "pause", Qt::QueuedConnection, Q_ARG(int, id),
+ Q_ARG(int, querySequence));
+ } else if (command == V4_CONNECT) {
+ QByteArray response;
+ QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ rs << QByteArray::number(d->version) << QByteArray::number(1);
+ sendMessage(d->packMessage(command, sequenceValue.toInt(), response));
+
+ d->initializeCondition.wakeAll();
+ } else {
+ QByteArray response;
+ QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ rs << QByteArray::number(d->version) << QByteArray::number(0);
+ sendMessage(d->packMessage(command, sequenceValue.toInt(), response));
+ }
+ }
+}
+
+void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::Debugger *debugger)
+{
+ QByteArray data;
+ QQmlDebugStream message(&data, QIODevice::WriteOnly);
+
+ QV4::Debugging::Debugger::ExecutionState state = debugger->currentExecutionState();
+ message << V4_FILENAME << state.fileName.toLatin1();
+ message << V4_LINENUMBER << QByteArray().number(state.lineNumber);
+
+ QV4DebugService::instance()->sendMessage(QV4DebugServicePrivate::packMessage(V4_BREAK, -1, data));
+
+ qDebug() << Q_FUNC_INFO;
+}
+
+void QV4DebugService::pause(int debuggerId, int querySequence)
+{
+ Q_D(QV4DebugService);
+
+ debuggerId == -1 ? d->debuggerAgent.pauseAll()
+ : d->debuggerAgent.pause(d->debuggerMap.value(debuggerId));
+ QByteArray response;
+ QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ rs << QByteArray::number(d->version) << QByteArray::number(1);
+ sendMessage(d->packMessage(V4_PAUSE, querySequence, response));
+}
+
+void QV4DebugService::addBreakpoint(const QByteArray &data, int querySequence)
+{
+ Q_D(QV4DebugService);
+
+ QQmlDebugStream ds(data);
+ QString fileName;
+ int lineNumber = -1;
+ while (!ds.atEnd()) {
+ QByteArray key;
+ QByteArray value;
+ ds >> key >> value;
+ if (key == V4_FILENAME)
+ fileName = QString::fromLatin1(value);
+ else if (key == V4_LINENUMBER)
+ lineNumber = value.toInt();
+ }
+ d->debuggerAgent.addBreakPoint(fileName, lineNumber);
+ QByteArray response;
+ QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ rs << QByteArray::number(d->version) << QByteArray::number(1);
+ sendMessage(d->packMessage(V4_ADD_BREAKPOINT, querySequence, response));
+}
+
+void QV4DebugService::removeBreakpoint(const QByteArray &data, int querySequence)
+{
+ Q_D(QV4DebugService);
+
+ QQmlDebugStream ds(data);
+ QString fileName;
+ int lineNumber = -1;
+ while (!ds.atEnd()) {
+ QByteArray key;
+ QByteArray value;
+ ds >> key >> value;
+ if (key == V4_FILENAME)
+ fileName = QString::fromLatin1(value);
+ else if (key == V4_LINENUMBER)
+ lineNumber = value.toInt();
+ }
+ d->debuggerAgent.removeBreakPoint(fileName, lineNumber);
+ QByteArray response;
+ QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ rs << QByteArray::number(d->version) << QByteArray::number(1);
+ sendMessage(d->packMessage(V4_REMOVE_BREAKPOINT, querySequence, response));
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/debugger/qv8debugservice_p.h b/src/qml/debugger/qv4debugservice_p.h
index 75fd69290c..a89b009c7f 100644
--- a/src/qml/debugger/qv8debugservice_p.h
+++ b/src/qml/debugger/qv4debugservice_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QV8DEBUGSERVICE_P_H
-#define QV8DEBUGSERVICE_P_H
+#ifndef QV4DEBUGSERVICE_P_H
+#define QV4DEBUGSERVICE_P_H
//
// W A R N I N G
@@ -54,54 +54,40 @@
//
#include "qqmldebugservice_p.h"
-#ifdef Q_OS_WINCE
-# ifdef DebugBreak
-# undef DebugBreak
-# endif
-#endif
-#include <private/qv8debug_p.h>
QT_BEGIN_NAMESPACE
+namespace QV4 { class ExecutionEngine; }
+class QQmlEngine;
+class QV4DebugServicePrivate;
-class QV8Engine;
-class QV8DebugServicePrivate;
-
-class QV8DebugService : public QQmlDebugService
+class QV4DebugService : public QQmlDebugService
{
Q_OBJECT
public:
- QV8DebugService(QObject *parent = 0);
- ~QV8DebugService();
-
- static QV8DebugService *instance();
- static void addEngine(const QV8Engine *engine);
- static void removeEngine(const QV8Engine *engine);
+ explicit QV4DebugService(QObject *parent = 0);
+ ~QV4DebugService();
- void debugMessageHandler(const QString &message);
+ static QV4DebugService *instance();
+ void addEngine(const QQmlEngine *engine);
+ void removeEngine(const QQmlEngine *engine);
void signalEmitted(const QString &signal);
-public slots:
- void processDebugMessages();
-
-private slots:
- void scheduledDebugBreak(bool schedule);
- void sendDebugMessage(const QString &message);
- void init();
-
protected:
void stateChanged(State newState);
void messageReceived(const QByteArray &);
-private:
- void setEngine(const QV8Engine *engine);
+private slots:
+ void pause(int debuggerId, int querySequence);
+ void addBreakpoint(const QByteArray &data, int querySequence);
+ void removeBreakpoint(const QByteArray &data, int querySequence);
private:
- Q_DISABLE_COPY(QV8DebugService)
- Q_DECLARE_PRIVATE(QV8DebugService)
+ Q_DISABLE_COPY(QV4DebugService)
+ Q_DECLARE_PRIVATE(QV4DebugService)
};
QT_END_NAMESPACE
-#endif // QV8DEBUGSERVICE_P_H
+#endif // QV4DEBUGSERVICE_P_H
diff --git a/src/qml/debugger/qv8debugservice.cpp b/src/qml/debugger/qv8debugservice.cpp
deleted file mode 100644
index 2195dad089..0000000000
--- a/src/qml/debugger/qv8debugservice.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8debugservice_p.h"
-#include "qqmldebugservice_p_p.h"
-#include <private/qv8engine_p.h>
-
-#include <QtCore/QHash>
-#include <QtCore/QFileInfo>
-#include <QtCore/QMutex>
-#include <QtCore/QWaitCondition>
-
-//V8 DEBUG SERVICE PROTOCOL
-// <HEADER><COMMAND><DATA>
-// <HEADER> : "V8DEBUG"
-// <COMMAND> : ["connect", "disconnect", "interrupt",
-// "v8request", "v8message", "breakonsignal",
-// "breakaftercompile"]
-// <DATA> : connect, disconnect, interrupt: empty
-// v8request, v8message: <JSONrequest_string>
-// breakonsignal: <signalname_string><enabled_bool>
-// breakaftercompile: <enabled_bool>
-
-const char *V8_DEBUGGER_KEY_VERSION = "version";
-const char *V8_DEBUGGER_KEY_CONNECT = "connect";
-const char *V8_DEBUGGER_KEY_INTERRUPT = "interrupt";
-const char *V8_DEBUGGER_KEY_DISCONNECT = "disconnect";
-const char *V8_DEBUGGER_KEY_REQUEST = "v8request";
-const char *V8_DEBUGGER_KEY_V8MESSAGE = "v8message";
-const char *V8_DEBUGGER_KEY_BREAK_ON_SIGNAL = "breakonsignal";
-
-QT_BEGIN_NAMESPACE
-
-struct SignalHandlerData
-{
- QString functionName;
- bool enabled;
-};
-
-Q_GLOBAL_STATIC(QV8DebugService, v8ServiceInstance)
-
-// DebugMessageHandler will call back already when the QV8DebugService constructor is
-// running, we therefore need a plain pointer.
-static QV8DebugService *v8ServiceInstancePtr = 0;
-
-void DebugMessageDispatchHandler()
-{
- QMetaObject::invokeMethod(v8ServiceInstancePtr, "processDebugMessages", Qt::QueuedConnection);
-}
-
-/* ### FIXME: v4
-void DebugMessageHandler(const v8::Debug::Message& message)
-{
- v8::DebugEvent event = message.GetEvent();
-
- if (message.IsEvent()) {
- if (event == v8::AfterCompile || event == v8::BeforeCompile)
- return;
- } else if (event != v8::Break && event != v8::Exception &&
- event != v8::AfterCompile && event != v8::BeforeCompile) {
- return;
- }
-
- v8ServiceInstancePtr->debugMessageHandler(QJSConverter::toString(message.GetJSON()));
-}
-*/
-
-class QV8DebugServicePrivate : public QQmlDebugServicePrivate
-{
-public:
- QV8DebugServicePrivate()
- : engine(0)
- {
- }
-
- void initializeDebuggerThread();
-
- static QByteArray packMessage(const QString &type, const QString &message = QString());
-
- QMutex initializeMutex;
- QWaitCondition initializeCondition;
- QStringList breakOnSignals;
- const QV8Engine *engine;
-};
-
-QV8DebugService::QV8DebugService(QObject *parent)
- : QQmlDebugService(*(new QV8DebugServicePrivate()),
- QStringLiteral("V8Debugger"), 2, parent)
-{
- Q_D(QV8DebugService);
- v8ServiceInstancePtr = this;
- // don't execute stateChanged, messageReceived in parallel
- QMutexLocker lock(&d->initializeMutex);
-
- if (registerService() == Enabled) {
- init();
- if (blockingMode())
- d->initializeCondition.wait(&d->initializeMutex);
- }
-}
-
-QV8DebugService::~QV8DebugService()
-{
-}
-
-QV8DebugService *QV8DebugService::instance()
-{
- return v8ServiceInstance();
-}
-
-void QV8DebugService::addEngine(const QV8Engine *engine)
-{
- // just make sure that the service is properly registered
- v8ServiceInstance()->setEngine(engine);
-}
-
-void QV8DebugService::removeEngine(const QV8Engine *engine)
-{
- if (v8ServiceInstance()->d_func()->engine == engine)
- v8ServiceInstance()->setEngine(0);
-}
-
-void QV8DebugService::setEngine(const QV8Engine *engine)
-{
- Q_D(QV8DebugService);
-
- d->engine = engine;
-}
-
-void QV8DebugService::debugMessageHandler(const QString &message)
-{
- sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_V8MESSAGE), message));
-}
-
-void QV8DebugService::signalEmitted(const QString &signal)
-{
- //This function is only called by QQmlBoundSignal
- //only if there is a slot connected to the signal. Hence, there
- //is no need for additional check.
- Q_D(QV8DebugService);
-
- //Parse just the name and remove the class info
- //Normalize to Lower case.
- QString signalName = signal.left(signal.indexOf(QLatin1Char('('))).toLower();
-
- foreach (const QString &signal, d->breakOnSignals) {
- if (signal == signalName) {
- scheduledDebugBreak(true);
- break;
- }
- }
-}
-
-// executed in the gui thread
-void QV8DebugService::init()
-{
-#if 0 // ### FIXME: v4
- Q_D(QV8DebugService);
- if (!d->debugIsolate)
- d->debugIsolate = v8::Isolate::GetCurrent();
- v8::Debug::SetMessageHandler2(DebugMessageHandler);
- v8::Debug::SetDebugMessageDispatchHandler(DebugMessageDispatchHandler);
- QV4Compiler::enableV4(false);
-#endif
-}
-
-// executed in the gui thread
-void QV8DebugService::scheduledDebugBreak(bool schedule)
-{
-// ### FIXME: v4
-// if (schedule)
-// v8::Debug::DebugBreak();
-// else
-// v8::Debug::CancelDebugBreak();
-}
-
-// executed in the debugger thread
-void QV8DebugService::stateChanged(QQmlDebugService::State newState)
-{
- Q_D(QV8DebugService);
- QMutexLocker lock(&d->initializeMutex);
-
- if (newState == Enabled) {
- // execute in GUI thread, bock to make sure messageReceived isn't called
- // before it finished.
- QMetaObject::invokeMethod(this, "init", Qt::BlockingQueuedConnection);
- } else {
- // wake up constructor in blocking mode
- // (we might got disabled before first message arrived)
- d->initializeCondition.wakeAll();
- }
-}
-
-// executed in the debugger thread
-void QV8DebugService::messageReceived(const QByteArray &message)
-{
- Q_D(QV8DebugService);
- QMutexLocker lock(&d->initializeMutex);
-
- QQmlDebugStream ds(message);
- QByteArray header;
- ds >> header;
-
- if (header == "V8DEBUG") {
- QByteArray command;
- QByteArray data;
- ds >> command >> data;
-
- if (command == V8_DEBUGGER_KEY_CONNECT) {
- sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_CONNECT)));
- // wake up constructor in blocking mode
- d->initializeCondition.wakeAll();
- } else if (command == V8_DEBUGGER_KEY_INTERRUPT) {
- // break has to be executed in gui thread
- QMetaObject::invokeMethod(this, "scheduledDebugBreak", Qt::QueuedConnection, Q_ARG(bool, true));
- sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_INTERRUPT)));
-
- } else if (command == V8_DEBUGGER_KEY_DISCONNECT) {
- // cancel break has to be executed in gui thread
- QMetaObject::invokeMethod(this, "scheduledDebugBreak", Qt::QueuedConnection, Q_ARG(bool, false));
- sendDebugMessage(QString::fromUtf8(data));
-
- } else if (command == V8_DEBUGGER_KEY_REQUEST) {
- sendDebugMessage(QString::fromUtf8(data));
-
- } else if (command == V8_DEBUGGER_KEY_BREAK_ON_SIGNAL) {
- QQmlDebugStream rs(data);
- QByteArray signal;
- bool enabled;
- rs >> signal >> enabled;
- //Normalize to lower case.
- QString signalName(QString::fromUtf8(signal).toLower());
- if (enabled)
- d->breakOnSignals.append(signalName);
- else
- d->breakOnSignals.removeOne(signalName);
- sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_BREAK_ON_SIGNAL)));
- }
- }
-}
-
-void QV8DebugService::sendDebugMessage(const QString &message)
-{
-#if 0 // ### FIXME: v4
- Q_D(QV8DebugService);
- v8::Debug::SendCommand(message.utf16(), message.size(), 0, d->debugIsolate);
-#endif
-}
-
-void QV8DebugService::processDebugMessages()
-{
- Q_D(QV8DebugService);
-// ### FIXME: v4 v8::Debug::ProcessDebugMessages();
-}
-
-QByteArray QV8DebugServicePrivate::packMessage(const QString &type, const QString &message)
-{
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
- QByteArray cmd("V8DEBUG");
- rs << cmd << type.toUtf8() << message.toUtf8();
- return reply;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/debugger/qv8profilerservice_p.h b/src/qml/debugger/qv8profilerservice_p.h
index 10906442f5..60dc70f4db 100644
--- a/src/qml/debugger/qv8profilerservice_p.h
+++ b/src/qml/debugger/qv8profilerservice_p.h
@@ -94,7 +94,7 @@ public:
static QV8ProfilerService *instance();
static void initialize();
-public slots:
+public Q_SLOTS:
void startProfiling(const QString &title);
void stopProfiling(const QString &title);
void takeSnapshot();
diff --git a/src/qml/doc/src/cppintegration/contextproperties.qdoc b/src/qml/doc/src/cppintegration/contextproperties.qdoc
index 1c2bced738..e0d5091f2f 100644
--- a/src/qml/doc/src/cppintegration/contextproperties.qdoc
+++ b/src/qml/doc/src/cppintegration/contextproperties.qdoc
@@ -84,11 +84,15 @@ a \l Connections object:
\snippet qml/qtbinding/context-advanced/connections.qml 0
Context properties can be useful for using C++ based data models in a QML view. See the
-\l {quick/modelviews/stringlistmodel}{String ListModel},
-\l {quick/modelviews/objectlistmodel}{Object ListModel} and
-\l {quick/modelviews/abstractitemmodel}{AbstractItemModel} models for
-respective examples on using QStringListModel, QObjectList-based models and QAbstractItemModel
-in QML views.
+following examples:
+\list
+ \li \l {Models and Views: String ListModel Example}{String ListModel}
+ \li \l {Models and Views: Object ListModel Example}{Object ListModel}
+ \li \l {Models and Views: AbstractItemModel Example}{AbstractItemModel}
+\endlist
+
+demonstrating the use of QStringList, \l{QList<QObject*>}-based models and
+QAbstractItemModel in QML views.
Also see the QQmlContext documentation for more information.
diff --git a/src/qml/doc/src/javascript/date.qdoc b/src/qml/doc/src/javascript/date.qdoc
index 085d988377..89dc464adb 100644
--- a/src/qml/doc/src/javascript/date.qdoc
+++ b/src/qml/doc/src/javascript/date.qdoc
@@ -132,17 +132,18 @@
hour, if DST is currently in effect, while it was not for the time specified, or
vice versa.
- \sa {QtQuick2::Locale}{Locale}
+ \sa {QtQml2::Locale}{Locale}
*/
/*!
- \qmlmethod string Date::toLocaleString(locale,format)
+ \qmlmethod string Date::toLocaleString(locale, format)
Converts the Date to a string containing the date and time
suitable for the specified \a locale
in the specified \a format.
- If the format is not specified Locale.LongFormat will be used.
+ If \a format is not specified, \l {QtQml2::Locale}{Locale.LongFormat} will
+ be used.
If \a locale is not specified, the default locale will be used.
@@ -158,12 +159,13 @@
*/
/*!
- \qmlmethod string Date::toLocaleDateString(locale,format)
+ \qmlmethod string Date::toLocaleDateString(locale, format)
Converts the Date to a string containing the date suitable for the specified \a locale
in the specified \a format.
- If the format is not specified Locale.LongFormat will be used.
+ If \a format is not specified, \l {QtQml2::Locale}{Locale.LongFormat} will
+ be used.
If \a locale is not specified, the default locale will be used.
@@ -179,12 +181,13 @@
*/
/*!
- \qmlmethod string Date::toLocaleTimeString(locale,format)
+ \qmlmethod string Date::toLocaleTimeString(locale, format)
Converts the Date to a string containing the time suitable for the specified \a locale
in the specified \a format.
- If the format is not specified Locale.LongFormat will be used.
+ If \a format is not specified, \l {QtQml2::Locale}{Locale.LongFormat} will
+ be used.
If \a locale is not specified, the default locale will be used.
@@ -200,10 +203,97 @@
*/
/*!
+ \qmlmethod string Date::fromLocaleString(locale, dateTimeString, format)
+
+ Converts the datetime string \a dateTimeString to a \l {QtQml2::Date}{Date}
+ object using \a locale and \a format.
+
+ If \a format is not specified, \l {QtQml2::Locale}{Locale.LongFormat} will
+ be used.
+
+ If \a locale is not specified, the default locale will be used.
+
+ The following example shows a datetime being parsed from a datetime string
+ in a certain format using the default locale:
+ \code
+ import QtQml 2.0
+
+ QtObject {
+ property var locale: Qt.locale()
+ property string dateTimeString: "Tue 2013-09-17 10:56:06"
+
+ Component.onCompleted: {
+ print(Date.fromLocaleString(locale, dateTimeString, "ddd yyyy-MM-dd hh:mm:ss"));
+ }
+ }
+ \endcode
+*/
+
+/*!
+ \qmlmethod string Date::fromLocaleDateString(locale, dateString, format)
+
+ Converts the date string \a dateString to a \l {QtQml2::Date}{Date} object
+ using \a locale and \a format.
+
+ If \a format is not specified, \l {QtQml2::Locale}{Locale.LongFormat} will
+ be used.
+
+ If \a locale is not specified, the default locale will be used.
+
+ The following example shows the current date first being formatted as a date
+ string using the default locale and format, then parsed back again in the
+ same manner:
+ \code
+ import QtQml 2.0
+
+ QtObject {
+ property var locale: Qt.locale()
+ property date currentDate: new Date()
+ property string dateString
+
+ Component.onCompleted: {
+ dateString = currentDate.toLocaleDateString();
+ print(Date.fromLocaleDateString(dateString));
+ }
+ }
+ \endcode
+*/
+
+/*!
+ \qmlmethod string Date::fromLocaleTimeString(locale, timeString, format)
+
+ Converts the time string \a timeString to a \l {QtQml2::Date}{Date} object
+ using \a locale and \a format.
+
+ If \a format is not specified, \l {QtQml2::Locale}{Locale.LongFormat} will
+ be used.
+
+ If \a locale is not specified, the default locale will be used.
+
+ The following example shows the current time first being formatted as a time
+ string using the default locale and a short format, then parsed back again
+ in the same manner:
+ \code
+ import QtQuick 2.0
+
+ QtObject {
+ property var locale: Qt.locale()
+ property date currentTime: new Date()
+ property string timeString
+
+ Component.onCompleted: {
+ timeString = currentTime.toLocaleTimeString(locale, Locale.ShortFormat);
+ print(Date.fromLocaleTimeString(locale, timeString, Locale.ShortFormat));
+ }
+ }
+ \endcode
+*/
+
+/*!
\qmlmethod string Date::timeZoneUpdated()
Informs the JS engine that the system's timezone has been changed, which is necessary
- for the correct manipulation of date/time data.
+ for the correct manipulation of datetime data.
JS stores Date objects in UTC time; all access to and from Date components in local
time involves the application of the current offset from UTC. If the current offset
diff --git a/src/qml/doc/src/javascript/number.qdoc b/src/qml/doc/src/javascript/number.qdoc
index 20fe40c86f..fa56f71925 100644
--- a/src/qml/doc/src/javascript/number.qdoc
+++ b/src/qml/doc/src/javascript/number.qdoc
@@ -33,7 +33,7 @@
The QML Number object extends the JS Number object with
locale aware functions.
- \sa {QtQuick2::Locale}{Locale}
+ \sa {QtQml2::Locale}{Locale}
*/
/*!
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 386f9f49df..7d668a4a11 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -413,3 +413,28 @@
Returns non-zero if the registration was sucessful.
*/
+/*!
+ \fn int qmlProtectModule(const QString &uri, int versionMajor);
+ \relates QQmlEngine
+
+ This function protects a module from having types registered into it. This
+ can be used to prevent other plugins from injecting types into your module.
+ It can also be a performance improvement, as it allows the engine to skip
+ checking for the possibility of new types or plugins when this import is
+ reached.
+
+ The performance benefit is primarily seen when registering application
+ specific types from within the application instead of through a plugin.
+ Using qmlProtectModule allows the engine to skip checking for a plugin when
+ that uri is imported, which can be noticeable with slow file systems.
+
+ After this function is called, any attempt to register C++ types into this
+ uri, major version combination will lead to a runtime error. Call this after
+ you have registered all of your types with the engine.
+
+ #include <QtQml> to use this function.
+
+ Returns true if the module was found and locked, otherwise returns false.
+ The module must contain exported types in order to be found.
+*/
+
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index d3c2c75ca7..b66dd51648 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -260,18 +260,20 @@ void QJSEngine::collectGarbage()
*/
QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
{
+ QV4::Scope scope(d->m_v4Engine);
QV4::ExecutionContext *ctx = d->m_v4Engine->current;
+ QV4::ScopedValue result(scope);
try {
QV4::Script script(ctx, program, fileName, lineNumber);
script.strictMode = ctx->strictMode;
script.inheritContext = true;
script.parse();
- QV4::Value result = script.run();
- return new QJSValuePrivate(d->m_v4Engine, result);
+ result = script.run();
} catch (QV4::Exception& ex) {
ex.accept(ctx);
- return new QJSValuePrivate(d->m_v4Engine, ex.value());
+ result = ex.value();
}
+ return new QJSValuePrivate(d->m_v4Engine, result);
}
/*!
@@ -294,11 +296,12 @@ QJSValue QJSEngine::newObject()
*/
QJSValue QJSEngine::newArray(uint length)
{
- QV4::ArrayObject *array = d->m_v4Engine->newArrayObject();
+ QV4::Scope scope(d->m_v4Engine);
+ QV4::Scoped<QV4::ArrayObject> array(scope, d->m_v4Engine->newArrayObject());
if (length < 0x1000)
array->arrayReserve(length);
array->setArrayLengthUnchecked(length);
- return new QJSValuePrivate(array);
+ return new QJSValuePrivate(d->m_v4Engine, array.asValue());
}
/*!
@@ -325,8 +328,10 @@ QJSValue QJSEngine::newQObject(QObject *object)
{
Q_D(QJSEngine);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(d);
+ QV4::Scope scope(v4);
QQmlEngine::setObjectOwnership(object, QQmlEngine::JavaScriptOwnership);
- return new QJSValuePrivate(v4, QV4::QObjectWrapper::wrap(v4, object));
+ QV4::ScopedValue v(scope, QV4::QObjectWrapper::wrap(v4, object));
+ return new QJSValuePrivate(v4, v);
}
/*!
@@ -351,7 +356,7 @@ QJSValue QJSEngine::globalObject() const
QJSValue QJSEngine::create(int type, const void *ptr)
{
Q_D(QJSEngine);
- return new QJSValuePrivate(d->m_v4Engine, d->metaTypeToJS(type, ptr));
+ return new QJSValuePrivate(d->m_v4Engine, QV4::Value::fromReturnedValue(d->metaTypeToJS(type, ptr)));
}
/*!
@@ -363,7 +368,7 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
QJSValuePrivate *vp = QJSValuePrivate::get(value);
QV8Engine *engine = vp->engine ? vp->engine->v8Engine : 0;
if (engine) {
- return engine->metaTypeFromJS(vp->getValue(engine->m_v4Engine), type, ptr);
+ return engine->metaTypeFromJS(QV4::Value::fromReturnedValue(vp->getValue(engine->m_v4Engine)), type, ptr);
} else {
switch (type) {
case QMetaType::Bool:
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index f18814cedf..908e9a4519 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -57,13 +57,13 @@
#include <private/qv4exception_p.h>
#include <private/qv4scopedvalue_p.h>
-QV4::Value QJSValuePrivate::getValue(QV4::ExecutionEngine *e)
+QV4::ReturnedValue QJSValuePrivate::getValue(QV4::ExecutionEngine *e)
{
if (!this->engine)
this->engine = e;
else if (this->engine != e) {
qWarning("JSValue can't be reassigned to another engine.");
- return QV4::Value::emptyValue();
+ return QV4::Value::emptyValue().asReturnedValue();
}
if (value.asString() == &string) {
value = QV4::Value::fromString(engine->newString(string.toQString()));
@@ -74,7 +74,7 @@ QV4::Value QJSValuePrivate::getValue(QV4::ExecutionEngine *e)
if (next)
next->prev = &this->next;
}
- return value;
+ return value.asReturnedValue();
}
/*!
@@ -360,7 +360,7 @@ bool QJSValue::isVariant() const
*/
QString QJSValue::toString() const
{
- return d->value.toQString();
+ return d->value.toQStringNoThrow();
}
/*!
@@ -506,17 +506,18 @@ QJSValue QJSValue::call(const QJSValueList &args)
ExecutionEngine *engine = d->engine;
assert(engine);
- ScopedCallData callData(engine, args.length());
+ Scope scope(engine);
+ ScopedCallData callData(scope, args.length());
callData->thisObject = Value::fromObject(engine->globalObject);
for (int i = 0; i < args.size(); ++i) {
if (!args.at(i).d->checkEngine(engine)) {
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue();
}
- callData->args[i] = args.at(i).d->getValue(engine);
+ callData->args[i] = QV4::Value::fromReturnedValue(args.at(i).d->getValue(engine));
}
- Value result;
+ ScopedValue result(scope);
QV4::ExecutionContext *ctx = engine->current;
try {
result = f->call(callData);
@@ -556,23 +557,24 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
ExecutionEngine *engine = d->engine;
assert(engine);
+ Scope scope(engine);
if (!instance.d->checkEngine(engine)) {
qWarning("QJSValue::call() failed: cannot call function with thisObject created in a different engine");
return QJSValue();
}
- ScopedCallData callData(engine, args.size());
- callData->thisObject = instance.d->getValue(engine);
+ ScopedCallData callData(scope, args.size());
+ callData->thisObject = QV4::Value::fromReturnedValue(instance.d->getValue(engine));
for (int i = 0; i < args.size(); ++i) {
if (!args.at(i).d->checkEngine(engine)) {
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue();
}
- callData->args[i] = args.at(i).d->getValue(engine);
+ callData->args[i] = QV4::Value::fromReturnedValue(args.at(i).d->getValue(engine));
}
- Value result;
+ ScopedValue result(scope);
QV4::ExecutionContext *ctx = engine->current;
try {
result = f->call(callData);
@@ -611,16 +613,17 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
ExecutionEngine *engine = d->engine;
assert(engine);
- ScopedCallData callData(engine, args.size());
+ Scope scope(engine);
+ ScopedCallData callData(scope, args.size());
for (int i = 0; i < args.size(); ++i) {
if (!args.at(i).d->checkEngine(engine)) {
qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
return QJSValue();
}
- callData->args[i] = args.at(i).d->getValue(engine);
+ callData->args[i] = QV4::Value::fromReturnedValue(args.at(i).d->getValue(engine));
}
- Value result;
+ ScopedValue result(scope);
QV4::ExecutionContext *ctx = engine->current;
try {
result = f->construct(callData);
@@ -660,12 +663,17 @@ QJSEngine* QJSValue::engine() const
*/
QJSValue QJSValue::prototype() const
{
- Object *o = d->value.asObject();
+ QV4::ExecutionEngine *engine = d->engine;
+ if (!engine)
+ return QJSValue();
+ QV4::Scope scope(engine);
+ Scoped<Object> o(scope, d->value.asObject());
if (!o)
return QJSValue();
- if (!o->prototype())
+ Scoped<Object> p(scope, o->prototype());
+ if (!p)
return QJSValue(NullValue);
- return new QJSValuePrivate(o->internalClass->engine, Value::fromObject(o->prototype()));
+ return new QJSValuePrivate(o->internalClass->engine, p.asValue());
}
/*!
@@ -788,11 +796,15 @@ bool QJSValue::strictlyEquals(const QJSValue& other) const
*/
QJSValue QJSValue::property(const QString& name) const
{
+ ExecutionEngine *engine = d->engine;
+ if (!engine)
+ return QJSValue();
+ QV4::Scope scope(engine);
+
Object *o = d->value.asObject();
if (!o)
return QJSValue();
- ExecutionEngine *engine = d->engine;
String *s = engine->newString(name);
uint idx = s->asArrayIndex();
if (idx < UINT_MAX)
@@ -800,13 +812,14 @@ QJSValue QJSValue::property(const QString& name) const
s->makeIdentifier();
QV4::ExecutionContext *ctx = engine->current;
+ QV4::ScopedValue result(scope);
try {
- QV4::Value v = o->get(s);
- return new QJSValuePrivate(engine, v);
+ result = o->get(s);
} catch (QV4::Exception &e) {
e.accept(ctx);
- return new QJSValuePrivate(engine, e.value());
+ result = e.value();
}
+ return new QJSValuePrivate(engine, result);
}
/*!
@@ -823,19 +836,24 @@ QJSValue QJSValue::property(const QString& name) const
*/
QJSValue QJSValue::property(quint32 arrayIndex) const
{
+ ExecutionEngine *engine = d->engine;
+ if (!engine)
+ return QJSValue();
+
+ QV4::Scope scope(engine);
Object *o = d->value.asObject();
if (!o)
return QJSValue();
- ExecutionEngine *engine = d->engine;
QV4::ExecutionContext *ctx = engine->current;
+ QV4::ScopedValue result(scope);
try {
- QV4::Value v = arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex);
- return new QJSValuePrivate(engine, v);
+ result = arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex);
} catch (QV4::Exception &e) {
e.accept(ctx);
- return new QJSValuePrivate(engine, e.value());
+ result = e.value();
}
+ return new QJSValuePrivate(engine, result);
}
/*!
@@ -851,7 +869,12 @@ QJSValue QJSValue::property(quint32 arrayIndex) const
*/
void QJSValue::setProperty(const QString& name, const QJSValue& value)
{
- Object *o = d->value.asObject();
+ ExecutionEngine *engine = d->engine;
+ if (!engine)
+ return;
+ Scope scope(engine);
+
+ Scoped<Object> o(scope, d->value);
if (!o)
return;
@@ -860,7 +883,6 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
return;
}
- ExecutionEngine *engine = d->engine;
String *s = engine->newString(name);
uint idx = s->asArrayIndex();
if (idx < UINT_MAX) {
@@ -871,7 +893,8 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
QV4::ExecutionContext *ctx = engine->current;
s->makeIdentifier();
try {
- o->put(s, value.d->getValue(engine));
+ QV4::ScopedValue v(scope, value.d->getValue(engine));
+ o->put(s, v);
} catch (QV4::Exception &e) {
e.accept(ctx);
}
@@ -891,17 +914,22 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
*/
void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
{
- Object *o = d->value.asObject();
+ ExecutionEngine *engine = d->engine;
+ if (!engine)
+ return;
+ Scope scope(engine);
+
+ Scoped<Object> o(scope, d->value);
if (!o)
return;
- ExecutionEngine *engine = d->engine;
QV4::ExecutionContext *ctx = engine->current;
+ QV4::ScopedValue v(scope, value.d->getValue(engine));
try {
if (arrayIndex != UINT_MAX)
- o->putIndexed(arrayIndex, value.d->getValue(engine));
+ o->putIndexed(arrayIndex, v);
else
- o->put(engine->id_uintMax, value.d->getValue(engine));
+ o->put(engine->id_uintMax, v);
} catch (QV4::Exception &e) {
e.accept(ctx);
}
diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h
index 69046e84df..f99fed7c44 100644
--- a/src/qml/jsapi/qjsvalue_p.h
+++ b/src/qml/jsapi/qjsvalue_p.h
@@ -88,7 +88,7 @@ public:
value = QV4::Value::fromString(&string);
}
- QV4::Value getValue(QV4::ExecutionEngine *e);
+ QV4::ReturnedValue getValue(QV4::ExecutionEngine *e);
static QJSValuePrivate *get(const QJSValue &v) { return v.d; }
diff --git a/src/qml/jsapi/qjsvalueiterator.cpp b/src/qml/jsapi/qjsvalueiterator.cpp
index aa1ecd6e54..2b074c3cb2 100644
--- a/src/qml/jsapi/qjsvalueiterator.cpp
+++ b/src/qml/jsapi/qjsvalueiterator.cpp
@@ -152,7 +152,7 @@ bool QJSValueIterator::next()
QString QJSValueIterator::name() const
{
if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
- return false;
+ return QString();
if (d_ptr->currentName)
return d_ptr->currentName->toQString();
if (d_ptr->currentIndex < UINT_MAX)
@@ -174,9 +174,11 @@ QJSValue QJSValueIterator::value() const
QV4::Object *o = d_ptr->iterator.object;
QV4::ExecutionEngine *engine = o->internalClass->engine;
+ QV4::Scope scope(engine);
+
QV4::ExecutionContext *ctx = engine->current;
try {
- QV4::Value v;
+ QV4::ScopedValue v(scope);
if (d_ptr->currentName)
v = o->get(d_ptr->currentName);
else if (d_ptr->currentIndex != UINT_MAX)
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 5a53c0fc3e..6c028de372 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -44,10 +44,10 @@
using namespace QV4;
-static Value throwTypeError(SimpleCallContext *ctx)
+static ReturnedValue throwTypeError(SimpleCallContext *ctx)
{
ctx->throwTypeError();
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
DEFINE_MANAGED_VTABLE(ArgumentsObject);
@@ -106,6 +106,7 @@ void ArgumentsObject::destroy(Managed *that)
bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const Property &desc, PropertyAttributes attrs)
{
+ Scope scope(ctx);
uint pidx = propertyIndexFromArrayIndex(index);
Property *pd = arrayData + pidx;
Property map;
@@ -130,7 +131,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
if (isMapped && attrs.isData()) {
if (!attrs.isGeneric()) {
- ScopedCallData callData(ctx->engine, 1);
+ ScopedCallData callData(scope, 1);
callData->thisObject = Value::fromObject(this);
callData->args[0] = desc.value;
map.setter()->call(callData);
@@ -148,7 +149,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
DEFINE_MANAGED_VTABLE(ArgumentsGetterFunction);
-Value ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
+ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
{
ArgumentsGetterFunction *g = static_cast<ArgumentsGetterFunction *>(getter);
Object *that = callData->thisObject.asObject();
@@ -159,12 +160,12 @@ Value ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
getter->engine()->current->throwTypeError();
assert(g->index < o->context->argumentCount);
- return o->context->argument(g->index);
+ return o->context->argument(g->index).asReturnedValue();
}
DEFINE_MANAGED_VTABLE(ArgumentsSetterFunction);
-Value ArgumentsSetterFunction::call(Managed *setter, CallData *callData)
+ReturnedValue ArgumentsSetterFunction::call(Managed *setter, CallData *callData)
{
ArgumentsSetterFunction *s = static_cast<ArgumentsSetterFunction *>(setter);
Object *that = callData->thisObject.asObject();
@@ -176,7 +177,7 @@ Value ArgumentsSetterFunction::call(Managed *setter, CallData *callData)
assert(s->index < o->context->argumentCount);
o->context->arguments[s->index] = callData->argc ? callData->args[0] : Value::undefinedValue();
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
void ArgumentsObject::markObjects(Managed *that)
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 66ee22c953..7862a602bd 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -50,32 +50,29 @@ namespace QV4 {
struct ArgumentsGetterFunction: FunctionObject
{
+ Q_MANAGED
uint index;
ArgumentsGetterFunction(ExecutionContext *scope, uint index)
: FunctionObject(scope), index(index) { vtbl = &static_vtbl; }
- static Value call(Managed *that, CallData *d);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue call(Managed *that, CallData *d);
};
struct ArgumentsSetterFunction: FunctionObject
{
+ Q_MANAGED
uint index;
ArgumentsSetterFunction(ExecutionContext *scope, uint index)
: FunctionObject(scope), index(index) { vtbl = &static_vtbl; }
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct ArgumentsObject: Object {
+ Q_MANAGED
CallContext *context;
QVector<Value> mappedArguments;
ArgumentsObject(CallContext *context);
@@ -90,7 +87,6 @@ struct ArgumentsObject: Object {
static void markObjects(Managed *that);
protected:
- static const ManagedVTable static_vtbl;
static void destroy(Managed *);
};
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index e3b08f5941..1f09b97d5c 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -54,10 +54,11 @@ ArrayCtor::ArrayCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value ArrayCtor::construct(Managed *m, CallData *callData)
+ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData)
{
ExecutionEngine *v4 = m->engine();
- ArrayObject *a = v4->newArrayObject();
+ Scope scope(v4);
+ Scoped<ArrayObject> a(scope, v4->newArrayObject());
uint len;
if (callData->argc == 1 && callData->args[0].isNumber()) {
bool ok;
@@ -77,10 +78,10 @@ Value ArrayCtor::construct(Managed *m, CallData *callData)
}
a->setArrayLengthUnchecked(len);
- return Value::fromObject(a);
+ return a.asReturnedValue();
}
-Value ArrayCtor::call(Managed *that, CallData *callData)
+ReturnedValue ArrayCtor::call(Managed *that, CallData *callData)
{
return construct(that, callData);
}
@@ -123,36 +124,41 @@ uint ArrayPrototype::getLength(ExecutionContext *ctx, Object *o)
{
if (o->isArrayObject())
return o->arrayLength();
- return o->get(ctx->engine->id_length).toUInt32();
+ Scope scope(ctx);
+ ScopedValue v(scope, o->get(ctx->engine->id_length));
+ return v->toUInt32();
}
-Value ArrayPrototype::method_isArray(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_isArray(SimpleCallContext *ctx)
{
Value arg = ctx->argument(0);
bool isArray = arg.asArrayObject();
- return Value::fromBoolean(isArray);
+ return Value::fromBoolean(isArray).asReturnedValue();
}
-Value ArrayPrototype::method_toString(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_toString(SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QV4::Object *o = ctx->thisObject.toObject(ctx);
- FunctionObject *f = o->get(ctx->engine->newString("join")).asFunctionObject();
+ ScopedValue v(scope, o->get(ctx->engine->newString("join")));
+ FunctionObject *f = v->asFunctionObject();
if (f) {
- ScopedCallData d(ctx->engine, 0);
+ ScopedCallData d(scope, 0);
d->thisObject = ctx->thisObject;
return f->call(d);
}
return ObjectPrototype::method_toString(ctx);
}
-Value ArrayPrototype::method_toLocaleString(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_toLocaleString(SimpleCallContext *ctx)
{
return method_toString(ctx);
}
-Value ArrayPrototype::method_concat(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_concat(SimpleCallContext *ctx)
{
- ArrayObject *result = ctx->engine->newArrayObject();
+ Scope scope(ctx);
+ Scoped<ArrayObject> result(scope, ctx->engine->newArrayObject());
if (ArrayObject *instance = ctx->thisObject.asArrayObject()) {
result->copyArrayData(instance);
@@ -174,14 +180,15 @@ Value ArrayPrototype::method_concat(SimpleCallContext *ctx)
result->arrayConcat(elt);
else
- result->arraySet(getLength(ctx, result), arg);
+ result->arraySet(getLength(ctx, result.getPointer()), arg);
}
- return Value::fromObject(result);
+ return result.asReturnedValue();
}
-Value ArrayPrototype::method_join(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_join(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Value arg = ctx->argument(0);
QString r4;
@@ -190,75 +197,78 @@ Value ArrayPrototype::method_join(SimpleCallContext *ctx)
else
r4 = arg.toString(ctx)->toQString();
- Value self = ctx->thisObject;
- const Value length = self.property(ctx, ctx->engine->id_length);
- const quint32 r2 = Value::toUInt32(length.isUndefined() ? 0 : length.toNumber());
+ Scoped<Object> self(scope, ctx->thisObject);
+ ScopedValue length(scope, self->get(ctx->engine->id_length));
+ const quint32 r2 = Value::toUInt32(length->isUndefined() ? 0 : length->toNumber());
static QSet<Object *> visitedArrayElements;
- if (! r2 || visitedArrayElements.contains(self.objectValue()))
- return Value::fromString(ctx, QString());
+ if (! r2 || visitedArrayElements.contains(self.getPointer()))
+ return Value::fromString(ctx, QString()).asReturnedValue();
// avoid infinite recursion
- visitedArrayElements.insert(self.objectValue());
+ visitedArrayElements.insert(self.getPointer());
QString R;
// ### FIXME
- if (ArrayObject *a = self.asArrayObject()) {
+ if (ArrayObject *a = self->asArrayObject()) {
+ ScopedValue e(scope);
for (uint i = 0; i < a->arrayLength(); ++i) {
if (i)
R += r4;
- Value e = a->getIndexed(i);
- if (! (e.isUndefined() || e.isNull()))
- R += e.toString(ctx)->toQString();
+ e = a->getIndexed(i);
+ if (!e->isNullOrUndefined())
+ R += e->toString(ctx)->toQString();
}
} else {
//
// crazy!
//
- Value r6 = self.property(ctx, ctx->engine->newString(QStringLiteral("0")));
- if (!(r6.isUndefined() || r6.isNull()))
- R = r6.toString(ctx)->toQString();
+ ScopedValue r6(scope, self->get(ctx->engine->newString(QStringLiteral("0"))));
+ if (!r6->isNullOrUndefined())
+ R = r6->toString(ctx)->toQString();
+ ScopedValue r12(scope);
for (quint32 k = 1; k < r2; ++k) {
R += r4;
String *name = Value::fromDouble(k).toString(ctx);
- Value r12 = self.property(ctx, name);
+ r12 = self->get(name);
- if (! (r12.isUndefined() || r12.isNull()))
- R += r12.toString(ctx)->toQString();
+ if (!r12->isNullOrUndefined())
+ R += r12->toString(ctx)->toQString();
}
}
- visitedArrayElements.remove(self.objectValue());
- return Value::fromString(ctx, R);
+ visitedArrayElements.remove(self.getPointer());
+ return Value::fromString(ctx, R).asReturnedValue();
}
-Value ArrayPrototype::method_pop(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_pop(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
if (!len) {
if (!instance->isArrayObject())
instance->put(ctx->engine->id_length, Value::fromInt32(0));
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
- Value result = instance->getIndexed(len - 1);
+ ScopedValue result(scope, instance->getIndexed(len - 1));
instance->deleteIndexedProperty(len - 1);
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(len - 1);
else
instance->put(ctx->engine->id_length, Value::fromDouble(len - 1));
- return result;
+ return result.asReturnedValue();
}
-Value ArrayPrototype::method_push(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_push(SimpleCallContext *ctx)
{
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
@@ -275,7 +285,7 @@ Value ArrayPrototype::method_push(SimpleCallContext *ctx)
instance->put(ctx->engine->id_length, Value::fromDouble(newLen));
else
ctx->throwRangeError(Value::fromString(ctx, QStringLiteral("Array.prototype.push: Overflow")));
- return Value::fromDouble(newLen);
+ return Value::fromDouble(newLen).asReturnedValue();
}
if (!instance->protoHasArray() && instance->arrayDataLen <= len) {
@@ -306,22 +316,25 @@ Value ArrayPrototype::method_push(SimpleCallContext *ctx)
instance->put(ctx->engine->id_length, Value::fromDouble(len));
if (len < INT_MAX)
- return Value::fromInt32(len);
- return Value::fromDouble((double)len);
+ return Value::fromInt32(len).asReturnedValue();
+ return Value::fromDouble((double)len).asReturnedValue();
}
-Value ArrayPrototype::method_reverse(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_reverse(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint length = getLength(ctx, instance);
int lo = 0, hi = length - 1;
+ ScopedValue lval(scope);
+ ScopedValue hval(scope);
for (; lo < hi; ++lo, --hi) {
bool loExists, hiExists;
- Value lval = instance->getIndexed(lo, &loExists);
- Value hval = instance->getIndexed(hi, &hiExists);
+ lval = instance->getIndexed(lo, &loExists);
+ hval = instance->getIndexed(hi, &hiExists);
if (hiExists)
instance->putIndexed(lo, hval);
else
@@ -331,18 +344,19 @@ Value ArrayPrototype::method_reverse(SimpleCallContext *ctx)
else
instance->deleteIndexedProperty(hi);
}
- return Value::fromObject(instance);
+ return Value::fromObject(instance).asReturnedValue();
}
-Value ArrayPrototype::method_shift(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_shift(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
if (!len) {
if (!instance->isArrayObject())
instance->put(ctx->engine->id_length, Value::fromInt32(0));
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
Property *front = 0;
@@ -350,7 +364,7 @@ Value ArrayPrototype::method_shift(SimpleCallContext *ctx)
if (pidx < UINT_MAX && (!instance->arrayAttributes || !instance->arrayAttributes[0].isGeneric()))
front = instance->arrayData + pidx;
- Value result = front ? instance->getValue(front, instance->arrayAttributes ? instance->arrayAttributes[pidx] : Attr_Data) : Value::undefinedValue();
+ Value result = front ? Value::fromReturnedValue(instance->getValue(front, instance->arrayAttributes ? instance->arrayAttributes[pidx] : Attr_Data)) : Value::undefinedValue();
if (!instance->protoHasArray() && instance->arrayDataLen <= len) {
if (!instance->sparseArray) {
@@ -367,10 +381,11 @@ Value ArrayPrototype::method_shift(SimpleCallContext *ctx)
instance->freeArrayValue(idx);
}
} else {
+ ScopedValue v(scope);
// do it the slow way
for (uint k = 1; k < len; ++k) {
bool exists;
- Value v = instance->getIndexed(k, &exists);
+ v = instance->getIndexed(k, &exists);
if (exists)
instance->putIndexed(k - 1, v);
else
@@ -383,15 +398,16 @@ Value ArrayPrototype::method_shift(SimpleCallContext *ctx)
instance->setArrayLengthUnchecked(len - 1);
else
instance->put(ctx->engine->id_length, Value::fromDouble(len - 1));
- return result;
+ return result.asReturnedValue();
}
-Value ArrayPrototype::method_slice(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_slice(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *o = ctx->thisObject.toObject(ctx);
- ArrayObject *result = ctx->engine->newArrayObject();
- uint len = o->get(ctx->engine->id_length).toUInt32();
+ Scoped<ArrayObject> result(scope, ctx->engine->newArrayObject());
+ uint len = ArrayPrototype::getLength(ctx, o);
double s = ctx->argument(0).toInteger();
uint start;
if (s < 0)
@@ -411,19 +427,20 @@ Value ArrayPrototype::method_slice(SimpleCallContext *ctx)
end = (uint) e;
}
+ ScopedValue v(scope);
uint n = 0;
for (uint i = start; i < end; ++i) {
bool exists;
- Value v = o->getIndexed(i, &exists);
+ v = o->getIndexed(i, &exists);
if (exists) {
result->arraySet(n, v);
}
++n;
}
- return Value::fromObject(result);
+ return result.asReturnedValue();
}
-Value ArrayPrototype::method_sort(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_sort(SimpleCallContext *ctx)
{
Object *instance = ctx->thisObject.toObject(ctx);
@@ -431,15 +448,16 @@ Value ArrayPrototype::method_sort(SimpleCallContext *ctx)
Value comparefn = ctx->argument(0);
instance->arraySort(ctx, instance, comparefn, len);
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
-Value ArrayPrototype::method_splice(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
- ArrayObject *newArray = ctx->engine->newArrayObject();
+ Scoped<ArrayObject> newArray(scope, ctx->engine->newArrayObject());
double rs = ctx->argument(0).toInteger();
uint start;
@@ -453,7 +471,7 @@ Value ArrayPrototype::method_splice(SimpleCallContext *ctx)
newArray->arrayReserve(deleteCount);
Property *pd = newArray->arrayData;
for (uint i = 0; i < deleteCount; ++i) {
- pd->value = instance->getIndexed(start + i);
+ pd->value = Value::fromReturnedValue(instance->getIndexed(start + i));
++pd;
}
newArray->arrayDataLen = deleteCount;
@@ -461,10 +479,11 @@ Value ArrayPrototype::method_splice(SimpleCallContext *ctx)
uint itemCount = ctx->argumentCount < 2 ? 0 : ctx->argumentCount - 2;
+ ScopedValue v(scope);
if (itemCount < deleteCount) {
for (uint k = start; k < len - deleteCount; ++k) {
bool exists;
- Value v = instance->getIndexed(k + deleteCount, &exists);
+ v = instance->getIndexed(k + deleteCount, &exists);
if (exists)
instance->putIndexed(k + itemCount, v);
else
@@ -476,7 +495,7 @@ Value ArrayPrototype::method_splice(SimpleCallContext *ctx)
uint k = len - deleteCount;
while (k > start) {
bool exists;
- Value v = instance->getIndexed(k + deleteCount - 1, &exists);
+ v = instance->getIndexed(k + deleteCount - 1, &exists);
if (exists)
instance->putIndexed(k + itemCount - 1, v);
else
@@ -491,11 +510,12 @@ Value ArrayPrototype::method_splice(SimpleCallContext *ctx)
ctx->strictMode = true;
instance->put(ctx->engine->id_length, Value::fromDouble(len - deleteCount + itemCount));
- return Value::fromObject(newArray);
+ return newArray.asReturnedValue();
}
-Value ArrayPrototype::method_unshift(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_unshift(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
@@ -521,9 +541,10 @@ Value ArrayPrototype::method_unshift(SimpleCallContext *ctx)
}
}
} else {
+ ScopedValue v(scope);
for (uint k = len; k > 0; --k) {
bool exists;
- Value v = instance->getIndexed(k - 1, &exists);
+ v = instance->getIndexed(k - 1, &exists);
if (exists)
instance->putIndexed(k + ctx->argumentCount - 1, v);
else
@@ -540,18 +561,18 @@ Value ArrayPrototype::method_unshift(SimpleCallContext *ctx)
instance->put(ctx->engine->id_length, Value::fromDouble(newLen));
if (newLen < INT_MAX)
- return Value::fromInt32(newLen);
- return Value::fromDouble((double)newLen);
+ return Value::fromInt32(newLen).asReturnedValue();
+ return Value::fromDouble((double)newLen).asReturnedValue();
}
-Value ArrayPrototype::method_indexOf(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_indexOf(SimpleCallContext *ctx)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
if (!len)
- return Value::fromInt32(-1);
+ return Value::fromInt32(-1).asReturnedValue();
ScopedValue searchValue(scope);
uint fromIndex = 0;
@@ -564,7 +585,7 @@ Value ArrayPrototype::method_indexOf(SimpleCallContext *ctx)
if (ctx->argumentCount >= 2) {
double f = ctx->argument(1).toInteger();
if (f >= len)
- return Value::fromInt32(-1);
+ return Value::fromInt32(-1).asReturnedValue();
if (f < 0)
f = qMax(len + f, 0.);
fromIndex = (uint) f;
@@ -576,22 +597,22 @@ Value ArrayPrototype::method_indexOf(SimpleCallContext *ctx)
bool exists;
v = instance->getIndexed(k, &exists);
if (exists && __qmljs_strict_equal(v, searchValue))
- return Value::fromDouble(k);
+ return Value::fromDouble(k).asReturnedValue();
}
- return Value::fromInt32(-1);
+ return Value::fromInt32(-1).asReturnedValue();
}
return instance->arrayIndexOf(searchValue, fromIndex, len, ctx, instance);
}
-Value ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
if (!len)
- return Value::fromInt32(-1);
+ return Value::fromInt32(-1).asReturnedValue();
ScopedValue searchValue(scope);
uint fromIndex = len;
@@ -608,7 +629,7 @@ Value ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx)
else if (f < 0) {
f = len + f;
if (f < 0)
- return Value::fromInt32(-1);
+ return Value::fromInt32(-1).asReturnedValue();
}
fromIndex = (uint) f + 1;
}
@@ -619,13 +640,14 @@ Value ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx)
bool exists;
v = instance->getIndexed(k, &exists);
if (exists && __qmljs_strict_equal(v, searchValue))
- return Value::fromDouble(k);
+ return Value::fromDouble(k).asReturnedValue();
}
- return Value::fromInt32(-1);
+ return Value::fromInt32(-1).asReturnedValue();
}
-Value ArrayPrototype::method_every(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_every(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
@@ -636,26 +658,30 @@ Value ArrayPrototype::method_every(SimpleCallContext *ctx)
Value thisArg = ctx->argument(1);
+ ScopedCallData callData(scope, 3);
+ callData->args[2] = Value::fromObject(instance);
+ callData->thisObject = thisArg;
+ ScopedValue r(scope);
+ ScopedValue v(scope);
+
bool ok = true;
for (uint k = 0; ok && k < len; ++k) {
bool exists;
- Value v = instance->getIndexed(k, &exists);
+ v = instance->getIndexed(k, &exists);
if (!exists)
continue;
- ScopedCallData callData(ctx->engine, 3);
callData->args[0] = v;
callData->args[1] = Value::fromDouble(k);
- callData->args[2] = Value::fromObject(instance);
- callData->thisObject = thisArg;
- Value r = callback->call(callData);
- ok = r.toBoolean();
+ r = callback->call(callData);
+ ok = r->toBoolean();
}
- return Value::fromBoolean(ok);
+ return Value::fromBoolean(ok).asReturnedValue();
}
-Value ArrayPrototype::method_some(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_some(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
@@ -664,28 +690,29 @@ Value ArrayPrototype::method_some(SimpleCallContext *ctx)
if (!callback)
ctx->throwTypeError();
- Value thisArg = ctx->argument(1);
+ ScopedCallData callData(scope, 3);
+ callData->thisObject = ctx->argument(1);
+ callData->args[2] = Value::fromObject(instance);
+ ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
bool exists;
- Value v = instance->getIndexed(k, &exists);
+ v = instance->getIndexed(k, &exists);
if (!exists)
continue;
- ScopedCallData callData(ctx->engine, 3);
- callData->thisObject = thisArg;
callData->args[0] = v;
callData->args[1] = Value::fromDouble(k);
- callData->args[2] = Value::fromObject(instance);
- Value r = callback->call(callData);
+ Value r = Value::fromReturnedValue(callback->call(callData));
if (r.toBoolean())
- return Value::fromBoolean(true);
+ return Value::fromBoolean(true).asReturnedValue();
}
- return Value::fromBoolean(false);
+ return Value::fromBoolean(false).asReturnedValue();
}
-Value ArrayPrototype::method_forEach(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_forEach(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
@@ -694,26 +721,27 @@ Value ArrayPrototype::method_forEach(SimpleCallContext *ctx)
if (!callback)
ctx->throwTypeError();
- Value thisArg = ctx->argument(1);
+ ScopedCallData callData(scope, 3);
+ callData->thisObject = ctx->argument(1);
+ callData->args[2] = Value::fromObject(instance);
+ ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
bool exists;
- Value v = instance->getIndexed(k, &exists);
+ v = instance->getIndexed(k, &exists);
if (!exists)
continue;
- ScopedCallData callData(ctx->engine, 3);
- callData->thisObject = thisArg;
callData->args[0] = v;
callData->args[1] = Value::fromDouble(k);
- callData->args[2] = Value::fromObject(instance);
callback->call(callData);
}
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
-Value ArrayPrototype::method_map(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_map(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
@@ -724,29 +752,33 @@ Value ArrayPrototype::method_map(SimpleCallContext *ctx)
Value thisArg = ctx->argument(1);
- ArrayObject *a = ctx->engine->newArrayObject();
+ Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
a->arrayReserve(len);
a->setArrayLengthUnchecked(len);
+ ScopedValue mapped(scope);
+ ScopedCallData callData(scope, 3);
+ callData->thisObject = thisArg;
+ callData->args[2] = Value::fromObject(instance);
+
+ ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
bool exists;
- Value v = instance->getIndexed(k, &exists);
+ v = instance->getIndexed(k, &exists);
if (!exists)
continue;
- ScopedCallData callData(ctx->engine, 3);
- callData->thisObject = thisArg;
callData->args[0] = v;
callData->args[1] = Value::fromDouble(k);
- callData->args[2] = Value::fromObject(instance);
- Value mapped = callback->call(callData);
+ mapped = callback->call(callData);
a->arraySet(k, mapped);
}
- return Value::fromObject(a);
+ return a.asReturnedValue();
}
-Value ArrayPrototype::method_filter(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_filter(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
@@ -757,32 +789,37 @@ Value ArrayPrototype::method_filter(SimpleCallContext *ctx)
Value thisArg = ctx->argument(1);
- ArrayObject *a = ctx->engine->newArrayObject();
+ Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
a->arrayReserve(len);
+ ScopedValue selected(scope);
+ ScopedCallData callData(scope, 3);
+ callData->thisObject = thisArg;
+ callData->args[2] = Value::fromObject(instance);
+
+ ScopedValue v(scope);
+
uint to = 0;
for (uint k = 0; k < len; ++k) {
bool exists;
- Value v = instance->getIndexed(k, &exists);
+ v = instance->getIndexed(k, &exists);
if (!exists)
continue;
- ScopedCallData callData(ctx->engine, 3);
- callData->thisObject = thisArg;
callData->args[0] = v;
callData->args[1] = Value::fromDouble(k);
- callData->args[2] = Value::fromObject(instance);
- Value selected = callback->call(callData);
- if (selected.toBoolean()) {
+ selected = callback->call(callData);
+ if (selected->toBoolean()) {
a->arraySet(to, v);
++to;
}
}
- return Value::fromObject(a);
+ return a.asReturnedValue();
}
-Value ArrayPrototype::method_reduce(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_reduce(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
@@ -792,13 +829,15 @@ Value ArrayPrototype::method_reduce(SimpleCallContext *ctx)
ctx->throwTypeError();
uint k = 0;
- Value acc;
+ ScopedValue acc(scope);
+ ScopedValue v(scope);
+
if (ctx->argumentCount > 1) {
acc = ctx->argument(1);
} else {
bool kPresent = false;
while (k < len && !kPresent) {
- Value v = instance->getIndexed(k, &kPresent);
+ v = instance->getIndexed(k, &kPresent);
if (kPresent)
acc = v;
++k;
@@ -807,25 +846,28 @@ Value ArrayPrototype::method_reduce(SimpleCallContext *ctx)
ctx->throwTypeError();
}
+ ScopedCallData callData(scope, 4);
+ callData->thisObject = Value::undefinedValue();
+ callData->args[0] = acc;
+ callData->args[3] = Value::fromObject(instance);
+
while (k < len) {
bool kPresent;
- Value v = instance->getIndexed(k, &kPresent);
+ v = instance->getIndexed(k, &kPresent);
if (kPresent) {
- ScopedCallData callData(ctx->engine, 4);
- callData->thisObject = Value::undefinedValue();
callData->args[0] = acc;
callData->args[1] = v;
callData->args[2] = Value::fromDouble(k);
- callData->args[3] = Value::fromObject(instance);
acc = callback->call(callData);
}
++k;
}
- return acc;
+ return acc.asReturnedValue();
}
-Value ArrayPrototype::method_reduceRight(SimpleCallContext *ctx)
+ReturnedValue ArrayPrototype::method_reduceRight(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *instance = ctx->thisObject.toObject(ctx);
uint len = getLength(ctx, instance);
@@ -837,17 +879,18 @@ Value ArrayPrototype::method_reduceRight(SimpleCallContext *ctx)
if (len == 0) {
if (ctx->argumentCount == 1)
ctx->throwTypeError();
- return ctx->argument(1);
+ return ctx->argument(1).asReturnedValue();
}
uint k = len;
- Value acc;
+ ScopedValue acc(scope);
+ ScopedValue v(scope);
if (ctx->argumentCount > 1) {
acc = ctx->argument(1);
} else {
bool kPresent = false;
while (k > 0 && !kPresent) {
- Value v = instance->getIndexed(k - 1, &kPresent);
+ v = instance->getIndexed(k - 1, &kPresent);
if (kPresent)
acc = v;
--k;
@@ -856,20 +899,21 @@ Value ArrayPrototype::method_reduceRight(SimpleCallContext *ctx)
ctx->throwTypeError();
}
+ ScopedCallData callData(scope, 4);
+ callData->thisObject = Value::undefinedValue();
+ callData->args[3] = Value::fromObject(instance);
+
while (k > 0) {
bool kPresent;
- Value v = instance->getIndexed(k - 1, &kPresent);
+ v = instance->getIndexed(k - 1, &kPresent);
if (kPresent) {
- ScopedCallData callData(ctx->engine, 4);
- callData->thisObject = Value::undefinedValue();
callData->args[0] = acc;
callData->args[1] = v;
callData->args[2] = Value::fromDouble(k - 1);
- callData->args[3] = Value::fromObject(instance);
acc = callback->call(callData);
}
--k;
}
- return acc;
+ return acc.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index 354ddd0380..a38a87f1f3 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -51,13 +51,11 @@ namespace QV4 {
struct ArrayCtor: FunctionObject
{
+ Q_MANAGED
ArrayCtor(ExecutionContext *scope);
- static Value construct(Managed *m, CallData *callData);
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct ArrayPrototype: ArrayObject
@@ -68,28 +66,28 @@ struct ArrayPrototype: ArrayObject
static uint getLength(ExecutionContext *ctx, Object *o);
- static Value method_isArray(SimpleCallContext *ctx);
- static Value method_toString(SimpleCallContext *ctx);
- static Value method_toLocaleString(SimpleCallContext *ctx);
- static Value method_concat(SimpleCallContext *ctx);
- static Value method_join(SimpleCallContext *ctx);
- static Value method_pop(SimpleCallContext *ctx);
- static Value method_push(SimpleCallContext *ctx);
- static Value method_reverse(SimpleCallContext *ctx);
- static Value method_shift(SimpleCallContext *ctx);
- static Value method_slice(SimpleCallContext *ctx);
- static Value method_sort(SimpleCallContext *ctx);
- static Value method_splice(SimpleCallContext *ctx);
- static Value method_unshift(SimpleCallContext *ctx);
- static Value method_indexOf(SimpleCallContext *ctx);
- static Value method_lastIndexOf(SimpleCallContext *ctx);
- static Value method_every(SimpleCallContext *ctx);
- static Value method_some(SimpleCallContext *ctx);
- static Value method_forEach(SimpleCallContext *ctx);
- static Value method_map(SimpleCallContext *ctx);
- static Value method_filter(SimpleCallContext *ctx);
- static Value method_reduce(SimpleCallContext *ctx);
- static Value method_reduceRight(SimpleCallContext *ctx);
+ static ReturnedValue method_isArray(SimpleCallContext *ctx);
+ static ReturnedValue method_toString(SimpleCallContext *ctx);
+ static ReturnedValue method_toLocaleString(SimpleCallContext *ctx);
+ static ReturnedValue method_concat(SimpleCallContext *ctx);
+ static ReturnedValue method_join(SimpleCallContext *ctx);
+ static ReturnedValue method_pop(SimpleCallContext *ctx);
+ static ReturnedValue method_push(SimpleCallContext *ctx);
+ static ReturnedValue method_reverse(SimpleCallContext *ctx);
+ static ReturnedValue method_shift(SimpleCallContext *ctx);
+ static ReturnedValue method_slice(SimpleCallContext *ctx);
+ static ReturnedValue method_sort(SimpleCallContext *ctx);
+ static ReturnedValue method_splice(SimpleCallContext *ctx);
+ static ReturnedValue method_unshift(SimpleCallContext *ctx);
+ static ReturnedValue method_indexOf(SimpleCallContext *ctx);
+ static ReturnedValue method_lastIndexOf(SimpleCallContext *ctx);
+ static ReturnedValue method_every(SimpleCallContext *ctx);
+ static ReturnedValue method_some(SimpleCallContext *ctx);
+ static ReturnedValue method_forEach(SimpleCallContext *ctx);
+ static ReturnedValue method_map(SimpleCallContext *ctx);
+ static ReturnedValue method_filter(SimpleCallContext *ctx);
+ static ReturnedValue method_reduce(SimpleCallContext *ctx);
+ static ReturnedValue method_reduceRight(SimpleCallContext *ctx);
};
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index 6b77db3ca7..86ddebd6c3 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -51,16 +51,16 @@ BooleanCtor::BooleanCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value BooleanCtor::construct(Managed *m, CallData *callData)
+ReturnedValue BooleanCtor::construct(Managed *m, CallData *callData)
{
bool n = callData->argc ? callData->args[0].toBoolean() : false;
- return Value::fromObject(m->engine()->newBooleanObject(Value::fromBoolean(n)));
+ return Encode(m->engine()->newBooleanObject(Value::fromBoolean(n)));
}
-Value BooleanCtor::call(Managed *, CallData *callData)
+ReturnedValue BooleanCtor::call(Managed *, CallData *callData)
{
bool value = callData->argc ? callData->args[0].toBoolean() : 0;
- return Value::fromBoolean(value);
+ return Encode(value);
}
void BooleanPrototype::init(ExecutionContext *ctx, const Value &ctor)
@@ -72,7 +72,7 @@ void BooleanPrototype::init(ExecutionContext *ctx, const Value &ctor)
defineDefaultProperty(ctx, QStringLiteral("valueOf"), method_valueOf);
}
-Value BooleanPrototype::method_toString(SimpleCallContext *ctx)
+ReturnedValue BooleanPrototype::method_toString(SimpleCallContext *ctx)
{
bool result;
if (ctx->thisObject.isBoolean()) {
@@ -84,14 +84,14 @@ Value BooleanPrototype::method_toString(SimpleCallContext *ctx)
result = thisObject->value.booleanValue();
}
- return Value::fromString(ctx, QLatin1String(result ? "true" : "false"));
+ return Value::fromString(ctx, QLatin1String(result ? "true" : "false")).asReturnedValue();
}
-Value BooleanPrototype::method_valueOf(SimpleCallContext *ctx)
+ReturnedValue BooleanPrototype::method_valueOf(SimpleCallContext *ctx)
{
BooleanObject *thisObject = ctx->thisObject.asBooleanObject();
if (!thisObject)
ctx->throwTypeError();
- return thisObject->value;
+ return thisObject->value.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index 35ecf25b6f..ef74834a5c 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -51,13 +51,11 @@ namespace QV4 {
struct BooleanCtor: FunctionObject
{
+ Q_MANAGED
BooleanCtor(ExecutionContext *scope);
- static Value construct(Managed *, CallData *callData);
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct BooleanPrototype: BooleanObject
@@ -65,8 +63,8 @@ struct BooleanPrototype: BooleanObject
BooleanPrototype(InternalClass *ic): BooleanObject(ic) {}
void init(ExecutionContext *ctx, const Value &ctor);
- static Value method_toString(SimpleCallContext *ctx);
- static Value method_valueOf(SimpleCallContext *ctx);
+ static ReturnedValue method_toString(SimpleCallContext *ctx);
+ static ReturnedValue method_valueOf(SimpleCallContext *ctx);
};
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 1e42a186a0..56701457e4 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -363,6 +363,7 @@ void ExecutionContext::mark()
void ExecutionContext::setProperty(String *name, const Value& value)
{
+ Scope scope(this);
for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) {
if (ctx->type == Type_WithContext) {
Object *w = static_cast<WithContext *>(ctx)->withObject;
@@ -398,17 +399,21 @@ void ExecutionContext::setProperty(String *name, const Value& value)
}
}
}
- if (strictMode || name->isEqualTo(engine->id_this))
- throwReferenceError(Value::fromString(name));
+ if (strictMode || name->isEqualTo(engine->id_this)) {
+ Scoped<String> n(scope, name);
+ throwReferenceError(n);
+ }
engine->globalObject->put(name, value);
}
-Value ExecutionContext::getProperty(String *name)
+ReturnedValue ExecutionContext::getProperty(String *name)
{
+ Scope scope(this);
+ ScopedValue v(scope);
name->makeIdentifier();
if (name->isEqualTo(engine->id_this))
- return thisObject;
+ return thisObject.asReturnedValue();
bool hasWith = false;
bool hasCatchScope = false;
@@ -417,9 +422,9 @@ Value ExecutionContext::getProperty(String *name)
Object *w = static_cast<WithContext *>(ctx)->withObject;
hasWith = true;
bool hasProperty = false;
- Value v = w->get(name, &hasProperty);
+ v = w->get(name, &hasProperty);
if (hasProperty) {
- return v;
+ return v.asReturnedValue();
}
continue;
}
@@ -428,7 +433,7 @@ Value ExecutionContext::getProperty(String *name)
hasCatchScope = true;
CatchContext *c = static_cast<CatchContext *>(ctx);
if (c->exceptionVarName->isEqualTo(name))
- return c->exceptionValue;
+ return c->exceptionValue.asReturnedValue();
}
else if (ctx->type >= Type_CallContext) {
@@ -437,40 +442,43 @@ Value ExecutionContext::getProperty(String *name)
if (f->needsActivation || hasWith || hasCatchScope) {
for (unsigned int i = 0; i < f->varCount; ++i)
if (f->varList[i]->isEqualTo(name))
- return c->locals[i];
+ return c->locals[i].asReturnedValue();
for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
if (f->formalParameterList[i]->isEqualTo(name))
- return c->arguments[i];
+ return c->arguments[i].asReturnedValue();
}
if (c->activation) {
bool hasProperty = false;
- Value v = c->activation->get(name, &hasProperty);
+ v = c->activation->get(name, &hasProperty);
if (hasProperty)
- return v;
+ return v.asReturnedValue();
}
if (f->function && f->function->isNamedExpression()
&& name->isEqualTo(f->function->name))
- return Value::fromObject(c->function);
+ return Value::fromObject(c->function).asReturnedValue();
}
else if (ctx->type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(ctx);
bool hasProperty = false;
- Value v = g->global->get(name, &hasProperty);
+ v = g->global->get(name, &hasProperty);
if (hasProperty)
- return v;
+ return v.asReturnedValue();
}
}
- throwReferenceError(Value::fromString(name));
- return Value::undefinedValue();
+ Scoped<String> n(scope, name);
+ throwReferenceError(n);
+ return Value::undefinedValue().asReturnedValue();
}
-Value ExecutionContext::getPropertyNoThrow(String *name)
+ReturnedValue ExecutionContext::getPropertyNoThrow(String *name)
{
+ Scope scope(this);
+ ScopedValue v(scope);
name->makeIdentifier();
if (name->isEqualTo(engine->id_this))
- return thisObject;
+ return thisObject.asReturnedValue();
bool hasWith = false;
bool hasCatchScope = false;
@@ -479,9 +487,9 @@ Value ExecutionContext::getPropertyNoThrow(String *name)
Object *w = static_cast<WithContext *>(ctx)->withObject;
hasWith = true;
bool hasProperty = false;
- Value v = w->get(name, &hasProperty);
+ v = w->get(name, &hasProperty);
if (hasProperty) {
- return v;
+ return v.asReturnedValue();
}
continue;
}
@@ -490,7 +498,7 @@ Value ExecutionContext::getPropertyNoThrow(String *name)
hasCatchScope = true;
CatchContext *c = static_cast<CatchContext *>(ctx);
if (c->exceptionVarName->isEqualTo(name))
- return c->exceptionValue;
+ return c->exceptionValue.asReturnedValue();
}
else if (ctx->type >= Type_CallContext) {
@@ -499,40 +507,42 @@ Value ExecutionContext::getPropertyNoThrow(String *name)
if (f->needsActivation || hasWith || hasCatchScope) {
for (unsigned int i = 0; i < f->varCount; ++i)
if (f->varList[i]->isEqualTo(name))
- return c->locals[i];
+ return c->locals[i].asReturnedValue();
for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
if (f->formalParameterList[i]->isEqualTo(name))
- return c->arguments[i];
+ return c->arguments[i].asReturnedValue();
}
if (c->activation) {
bool hasProperty = false;
- Value v = c->activation->get(name, &hasProperty);
+ v = c->activation->get(name, &hasProperty);
if (hasProperty)
- return v;
+ return v.asReturnedValue();
}
if (f->function && f->function->isNamedExpression()
&& name->isEqualTo(f->function->name))
- return Value::fromObject(c->function);
+ return Value::fromObject(c->function).asReturnedValue();
}
else if (ctx->type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(ctx);
bool hasProperty = false;
- Value v = g->global->get(name, &hasProperty);
+ v = g->global->get(name, &hasProperty);
if (hasProperty)
- return v;
+ return v.asReturnedValue();
}
}
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
-Value ExecutionContext::getPropertyAndBase(String *name, Object **base)
+ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object **base)
{
+ Scope scope(this);
+ ScopedValue v(scope);
*base = 0;
name->makeIdentifier();
if (name->isEqualTo(engine->id_this))
- return thisObject;
+ return thisObject.asReturnedValue();
bool hasWith = false;
bool hasCatchScope = false;
@@ -541,10 +551,10 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base)
Object *w = static_cast<WithContext *>(ctx)->withObject;
hasWith = true;
bool hasProperty = false;
- Value v = w->get(name, &hasProperty);
+ v = w->get(name, &hasProperty);
if (hasProperty) {
*base = w;
- return v;
+ return v.asReturnedValue();
}
continue;
}
@@ -553,7 +563,7 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base)
hasCatchScope = true;
CatchContext *c = static_cast<CatchContext *>(ctx);
if (c->exceptionVarName->isEqualTo(name))
- return c->exceptionValue;
+ return c->exceptionValue.asReturnedValue();
}
else if (ctx->type >= Type_CallContext) {
@@ -562,102 +572,119 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base)
if (f->needsActivation || hasWith || hasCatchScope) {
for (unsigned int i = 0; i < f->varCount; ++i)
if (f->varList[i]->isEqualTo(name))
- return c->locals[i];
+ return c->locals[i].asReturnedValue();
for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
if (f->formalParameterList[i]->isEqualTo(name))
- return c->arguments[i];
+ return c->arguments[i].asReturnedValue();
}
if (c->activation) {
bool hasProperty = false;
- Value v = c->activation->get(name, &hasProperty);
+ v = c->activation->get(name, &hasProperty);
if (hasProperty) {
if (ctx->type == Type_QmlContext)
*base = c->activation;
- return v;
+ return v.asReturnedValue();
}
}
if (f->function && f->function->isNamedExpression()
&& name->isEqualTo(f->function->name))
- return Value::fromObject(c->function);
+ return Value::fromObject(c->function).asReturnedValue();
}
else if (ctx->type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(ctx);
bool hasProperty = false;
- Value v = g->global->get(name, &hasProperty);
+ v = g->global->get(name, &hasProperty);
if (hasProperty)
- return v;
+ return v.asReturnedValue();
}
}
- throwReferenceError(Value::fromString(name));
- return Value::undefinedValue();
+ Scoped<String> n(scope, name);
+ throwReferenceError(n);
+ return Value::undefinedValue().asReturnedValue();
}
-void ExecutionContext::throwError(const Value &value)
+void ExecutionContext::throwError(const ValueRef value)
{
- ValueScope scope(this);
- ScopedValue v(scope, value);
- __qmljs_throw(this, v);
+ __qmljs_throw(this, value);
}
void ExecutionContext::throwError(const QString &message)
{
- Value v = Value::fromString(this, message);
- throwError(Value::fromObject(engine->newErrorObject(v)));
+ Scope scope(this);
+ ScopedValue v(scope, Value::fromString(this, message));
+ v = engine->newErrorObject(v);
+ throwError(v);
}
void ExecutionContext::throwSyntaxError(const QString &message, const QString &fileName, int line, int column)
{
- Object *error = engine->newSyntaxErrorObject(message, fileName, line, column);
- throwError(Value::fromObject(error));
+ Scope scope(this);
+ Scoped<Object> error(scope, engine->newSyntaxErrorObject(message, fileName, line, column));
+ throwError(error);
}
void ExecutionContext::throwSyntaxError(const QString &message)
{
- Object *error = engine->newSyntaxErrorObject(message);
- throwError(Value::fromObject(error));
+ Scope scope(this);
+ Scoped<Object> error(scope, engine->newSyntaxErrorObject(message));
+ throwError(error);
}
void ExecutionContext::throwTypeError()
{
- throwError(Value::fromObject(engine->newTypeErrorObject(QStringLiteral("Type error"))));
+ Scope scope(this);
+ Scoped<Object> error(scope, engine->newTypeErrorObject(QStringLiteral("Type error")));
+ throwError(error);
}
void ExecutionContext::throwTypeError(const QString &message)
{
- throwError(Value::fromObject(engine->newTypeErrorObject(message)));
+ Scope scope(this);
+ Scoped<Object> error(scope, engine->newTypeErrorObject(message));
+ throwError(error);
}
void ExecutionContext::throwUnimplemented(const QString &message)
{
- Value v = Value::fromString(this, QStringLiteral("Unimplemented ") + message);
- throwError(Value::fromObject(engine->newErrorObject(v)));
+ Scope scope(this);
+ ScopedValue v(scope, Value::fromString(this, QStringLiteral("Unimplemented ") + message));
+ v = engine->newErrorObject(v);
+ throwError(v);
}
-void ExecutionContext::throwReferenceError(Value value)
+void ExecutionContext::throwReferenceError(const ValueRef value)
{
- String *s = value.toString(this);
+ Scope scope(this);
+ Scoped<String> s(scope, value->toString(this));
QString msg = s->toQString() + QStringLiteral(" is not defined");
- throwError(Value::fromObject(engine->newReferenceErrorObject(msg)));
+ Scoped<Object> error(scope, engine->newReferenceErrorObject(msg));
+ throwError(error);
}
void ExecutionContext::throwReferenceError(const QString &message, const QString &fileName, int line, int column)
{
+ Scope scope(this);
QString msg = message + QStringLiteral(" is not defined");
- throwError(Value::fromObject(engine->newReferenceErrorObject(msg, fileName, line, column)));
+ Scoped<Object> error(scope, engine->newReferenceErrorObject(msg, fileName, line, column));
+ throwError(error);
}
void ExecutionContext::throwRangeError(Value value)
{
- String *s = value.toString(this);
+ Scope scope(this);
+ Scoped<String> s(scope, value.toString(this));
QString msg = s->toQString() + QStringLiteral(" out of range");
- throwError(Value::fromObject(engine->newRangeErrorObject(msg)));
+ Scoped<Object> error(scope, engine->newRangeErrorObject(msg));
+ throwError(error);
}
void ExecutionContext::throwURIError(Value msg)
{
- throwError(Value::fromObject(engine->newURIErrorObject(msg)));
+ Scope scope(this);
+ Scoped<Object> error(scope, engine->newURIErrorObject(msg));
+ throwError(error);
}
void SimpleCallContext::initSimpleCallContext(ExecutionEngine *engine)
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index fe10e33c5e..0c3b189401 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -54,6 +54,7 @@ struct ExecutionEngine;
struct DeclarativeEnvironment;
struct Lookup;
struct Function;
+struct ValueRef;
namespace CompiledData {
struct CompilationUnit;
@@ -129,22 +130,22 @@ struct Q_QML_EXPORT ExecutionContext
void createMutableBinding(String *name, bool deletable);
- void Q_NORETURN throwError(const Value &value);
+ void Q_NORETURN throwError(const QV4::ValueRef value);
void Q_NORETURN throwError(const QString &message);
void Q_NORETURN throwSyntaxError(const QString &message);
void Q_NORETURN throwSyntaxError(const QString &message, const QString &fileName, int line, int column);
void Q_NORETURN throwTypeError();
void Q_NORETURN throwTypeError(const QString &message);
- void Q_NORETURN throwReferenceError(Value value);
+ void Q_NORETURN throwReferenceError(const ValueRef value);
void Q_NORETURN throwReferenceError(const QString &value, const QString &fileName, int line, int column);
void Q_NORETURN throwRangeError(Value value);
void Q_NORETURN throwURIError(Value msg);
void Q_NORETURN throwUnimplemented(const QString &message);
void setProperty(String *name, const Value &value);
- Value getProperty(String *name);
- Value getPropertyNoThrow(String *name);
- Value getPropertyAndBase(String *name, Object **base);
+ ReturnedValue getProperty(String *name);
+ ReturnedValue getPropertyNoThrow(String *name);
+ ReturnedValue getPropertyAndBase(String *name, Object **base);
bool deleteProperty(String *name);
inline Value argument(unsigned int index = 0);
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 1ef4aec246..76d712656a 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -634,11 +634,14 @@ static double getLocalTZA()
#endif
}
+DEFINE_MANAGED_VTABLE(DateObject);
+
DateObject::DateObject(ExecutionEngine *engine, const QDateTime &date)
: Object(engine->dateClass)
{
+ vtbl = &static_vtbl;
type = Type_DateObject;
- value = Value::fromDouble(date.toMSecsSinceEpoch());
+ value.setDouble(date.isValid() ? date.toMSecsSinceEpoch() : qSNaN());
}
QDateTime DateObject::toQDateTime() const
@@ -654,7 +657,7 @@ DateCtor::DateCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value DateCtor::construct(Managed *m, CallData *callData)
+ReturnedValue DateCtor::construct(Managed *m, CallData *callData)
{
double t = 0;
@@ -662,7 +665,7 @@ Value DateCtor::construct(Managed *m, CallData *callData)
t = currentTime();
else if (callData->argc == 1) {
- ValueScope scope(m->engine());
+ Scope scope(m->engine());
ScopedValue arg(scope, callData->args[0]);
if (DateObject *d = arg->asDateObject())
arg = d->value;
@@ -689,14 +692,13 @@ Value DateCtor::construct(Managed *m, CallData *callData)
t = TimeClip(UTC(t));
}
- Object *o = m->engine()->newDateObject(Value::fromDouble(t));
- return Value::fromObject(o);
+ return Encode(m->engine()->newDateObject(Value::fromDouble(t)));
}
-Value DateCtor::call(Managed *m, CallData *)
+ReturnedValue DateCtor::call(Managed *m, CallData *)
{
double t = currentTime();
- return Value::fromString(m->engine()->current, ToString(t));
+ return Value::fromString(m->engine()->current, ToString(t)).asReturnedValue();
}
void DatePrototype::init(ExecutionContext *ctx, const Value &ctor)
@@ -768,12 +770,12 @@ double DatePrototype::getThisDate(ExecutionContext *ctx)
}
}
-Value DatePrototype::method_parse(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_parse(SimpleCallContext *ctx)
{
- return Value::fromDouble(ParseString(ctx->argument(0).toString(ctx)->toQString()));
+ return Encode(ParseString(ctx->argument(0).toString(ctx)->toQString()));
}
-Value DatePrototype::method_UTC(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_UTC(SimpleCallContext *ctx)
{
const int numArgs = ctx->argumentCount;
if (numArgs >= 2) {
@@ -788,221 +790,221 @@ Value DatePrototype::method_UTC(SimpleCallContext *ctx)
year += 1900;
double t = MakeDate(MakeDay(year, month, day),
MakeTime(hours, mins, secs, ms));
- return Value::fromDouble(TimeClip(t));
+ return Encode(TimeClip(t));
}
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value DatePrototype::method_now(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_now(SimpleCallContext *ctx)
{
Q_UNUSED(ctx);
double t = currentTime();
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_toString(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_toString(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
- return Value::fromString(ctx, ToString(t));
+ return Value::fromString(ctx, ToString(t)).asReturnedValue();
}
-Value DatePrototype::method_toDateString(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_toDateString(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
- return Value::fromString(ctx, ToDateString(t));
+ return Value::fromString(ctx, ToDateString(t)).asReturnedValue();
}
-Value DatePrototype::method_toTimeString(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_toTimeString(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
- return Value::fromString(ctx, ToTimeString(t));
+ return Value::fromString(ctx, ToTimeString(t)).asReturnedValue();
}
-Value DatePrototype::method_toLocaleString(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_toLocaleString(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
- return Value::fromString(ctx, ToLocaleString(t));
+ return Value::fromString(ctx, ToLocaleString(t)).asReturnedValue();
}
-Value DatePrototype::method_toLocaleDateString(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_toLocaleDateString(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
- return Value::fromString(ctx, ToLocaleDateString(t));
+ return Value::fromString(ctx, ToLocaleDateString(t)).asReturnedValue();
}
-Value DatePrototype::method_toLocaleTimeString(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_toLocaleTimeString(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
- return Value::fromString(ctx, ToLocaleTimeString(t));
+ return Value::fromString(ctx, ToLocaleTimeString(t)).asReturnedValue();
}
-Value DatePrototype::method_valueOf(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_valueOf(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getTime(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getTime(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getYear(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getYear(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = YearFromTime(LocalTime(t)) - 1900;
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getFullYear(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getFullYear(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = YearFromTime(LocalTime(t));
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getUTCFullYear(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getUTCFullYear(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = YearFromTime(t);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getMonth(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getMonth(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = MonthFromTime(LocalTime(t));
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getUTCMonth(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getUTCMonth(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = MonthFromTime(t);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getDate(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getDate(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = DateFromTime(LocalTime(t));
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getUTCDate(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getUTCDate(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = DateFromTime(t);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getDay(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getDay(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = WeekDay(LocalTime(t));
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getUTCDay(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getUTCDay(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = WeekDay(t);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getHours(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getHours(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = HourFromTime(LocalTime(t));
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getUTCHours(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getUTCHours(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = HourFromTime(t);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getMinutes(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getMinutes(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = MinFromTime(LocalTime(t));
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getUTCMinutes(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getUTCMinutes(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = MinFromTime(t);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getSeconds(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getSeconds(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = SecFromTime(LocalTime(t));
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getUTCSeconds(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getUTCSeconds(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = SecFromTime(t);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getMilliseconds(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getMilliseconds(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = msFromTime(LocalTime(t));
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getUTCMilliseconds(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getUTCMilliseconds(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = msFromTime(t);
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_getTimezoneOffset(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_getTimezoneOffset(SimpleCallContext *ctx)
{
double t = getThisDate(ctx);
if (! std::isnan(t))
t = (t - LocalTime(t)) / msPerMinute;
- return Value::fromDouble(t);
+ return Encode(t);
}
-Value DatePrototype::method_setTime(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setTime(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
ctx->throwTypeError();
self->value.setDouble(TimeClip(ctx->argument(0).toNumber()));
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setMilliseconds(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setMilliseconds(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1011,10 +1013,10 @@ Value DatePrototype::method_setMilliseconds(SimpleCallContext *ctx)
double t = LocalTime(self->value.asDouble());
double ms = ctx->argument(0).toNumber();
self->value.setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setUTCMilliseconds(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setUTCMilliseconds(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1023,10 +1025,10 @@ Value DatePrototype::method_setUTCMilliseconds(SimpleCallContext *ctx)
double t = self->value.asDouble();
double ms = ctx->argument(0).toNumber();
self->value.setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setSeconds(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setSeconds(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1037,10 +1039,10 @@ Value DatePrototype::method_setSeconds(SimpleCallContext *ctx)
double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->argument(1).toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setUTCSeconds(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setUTCSeconds(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1051,10 +1053,10 @@ Value DatePrototype::method_setUTCSeconds(SimpleCallContext *ctx)
double ms = (ctx->argumentCount < 2) ? msFromTime(t) : ctx->argument(1).toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setMinutes(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setMinutes(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1066,10 +1068,10 @@ Value DatePrototype::method_setMinutes(SimpleCallContext *ctx)
double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->argument(2).toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setUTCMinutes(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setUTCMinutes(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1081,10 +1083,10 @@ Value DatePrototype::method_setUTCMinutes(SimpleCallContext *ctx)
double ms = (ctx->argumentCount < 3) ? msFromTime(t) : ctx->argument(2).toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setHours(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setHours(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1097,10 +1099,10 @@ Value DatePrototype::method_setHours(SimpleCallContext *ctx)
double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->argument(3).toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setUTCHours(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setUTCHours(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1113,10 +1115,10 @@ Value DatePrototype::method_setUTCHours(SimpleCallContext *ctx)
double ms = (ctx->argumentCount < 4) ? msFromTime(t) : ctx->argument(3).toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setDate(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setDate(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1126,10 +1128,10 @@ Value DatePrototype::method_setDate(SimpleCallContext *ctx)
double date = ctx->argument(0).toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setUTCDate(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setUTCDate(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1139,10 +1141,10 @@ Value DatePrototype::method_setUTCDate(SimpleCallContext *ctx)
double date = ctx->argument(0).toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setMonth(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setMonth(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1153,10 +1155,10 @@ Value DatePrototype::method_setMonth(SimpleCallContext *ctx)
double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->argument(1).toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setUTCMonth(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setUTCMonth(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1167,10 +1169,10 @@ Value DatePrototype::method_setUTCMonth(SimpleCallContext *ctx)
double date = (ctx->argumentCount < 2) ? DateFromTime(t) : ctx->argument(1).toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setYear(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setYear(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1193,10 +1195,10 @@ Value DatePrototype::method_setYear(SimpleCallContext *ctx)
r = TimeClip(r);
}
self->value.setDouble(r);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setUTCFullYear(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setUTCFullYear(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1208,10 +1210,10 @@ Value DatePrototype::method_setUTCFullYear(SimpleCallContext *ctx)
double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->argument(2).toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_setFullYear(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_setFullYear(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1225,17 +1227,17 @@ Value DatePrototype::method_setFullYear(SimpleCallContext *ctx)
double date = (ctx->argumentCount < 3) ? DateFromTime(t) : ctx->argument(2).toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
self->value.setDouble(t);
- return self->value;
+ return self->value.asReturnedValue();
}
-Value DatePrototype::method_toUTCString(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_toUTCString(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
ctx->throwTypeError();
double t = self->value.asDouble();
- return Value::fromString(ctx, ToUTCString(t));
+ return Value::fromString(ctx, ToUTCString(t)).asReturnedValue();
}
static void addZeroPrefixedInt(QString &str, int num, int nDigits)
@@ -1251,7 +1253,7 @@ static void addZeroPrefixedInt(QString &str, int num, int nDigits)
}
}
-Value DatePrototype::method_toISOString(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_toISOString(SimpleCallContext *ctx)
{
DateObject *self = ctx->thisObject.asDateObject();
if (!self)
@@ -1265,7 +1267,7 @@ Value DatePrototype::method_toISOString(SimpleCallContext *ctx)
int year = (int)YearFromTime(t);
if (year < 0 || year > 9999) {
if (qAbs(year) >= 1000000)
- return Value::fromString(ctx, QStringLiteral("Invalid Date"));
+ return Value::fromString(ctx, QStringLiteral("Invalid Date")).asReturnedValue();
result += year < 0 ? '-' : '+';
year = qAbs(year);
addZeroPrefixedInt(result, year, 6);
@@ -1286,24 +1288,25 @@ Value DatePrototype::method_toISOString(SimpleCallContext *ctx)
addZeroPrefixedInt(result, msFromTime(t), 3);
result += 'Z';
- return Value::fromString(ctx, result);
+ return Value::fromString(ctx, result).asReturnedValue();
}
-Value DatePrototype::method_toJSON(SimpleCallContext *ctx)
+ReturnedValue DatePrototype::method_toJSON(SimpleCallContext *ctx)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
ScopedValue O(scope, __qmljs_to_object(ctx, ValueRef(&ctx->thisObject)));
ScopedValue tv(scope, __qmljs_to_primitive(O, NUMBER_HINT));
if (tv->isNumber() && !std::isfinite(tv->toNumber()))
- return Value::nullValue();
+ return Encode::null();
- FunctionObject *toIso = O->objectValue()->get(ctx->engine->newString(QStringLiteral("toISOString"))).asFunctionObject();
+ ScopedValue v(scope, O->objectValue()->get(ctx->engine->newString(QStringLiteral("toISOString"))));
+ FunctionObject *toIso = v->asFunctionObject();
if (!toIso)
ctx->throwTypeError();
- ScopedCallData callData(ctx->engine, 0);
+ ScopedCallData callData(scope, 0);
callData->thisObject = ctx->thisObject;
return toIso->call(callData);
}
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 573326adc4..45a9420a41 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -52,25 +52,30 @@ class QDateTime;
namespace QV4 {
struct DateObject: Object {
+ Q_MANAGED
Value value;
- DateObject(ExecutionEngine *engine, const Value &value): Object(engine->dateClass), value(value) { type = Type_DateObject; }
+ DateObject(ExecutionEngine *engine, const Value &value): Object(engine->dateClass), value(value) {
+ vtbl = &static_vtbl;
+ type = Type_DateObject;
+ }
DateObject(ExecutionEngine *engine, const QDateTime &value);
QDateTime toQDateTime() const;
protected:
- DateObject(InternalClass *ic): Object(ic), value(Value::fromDouble(qSNaN())) { type = Type_DateObject; }
+ DateObject(InternalClass *ic): Object(ic), value(Value::fromDouble(qSNaN())) {
+ vtbl = &static_vtbl;
+ type = Type_DateObject;
+ }
};
struct DateCtor: FunctionObject
{
+ Q_MANAGED
DateCtor(ExecutionContext *scope);
- static Value construct(Managed *, CallData *callData);
- static Value call(Managed *that, CallData *);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *);
};
struct DatePrototype: DateObject
@@ -80,55 +85,55 @@ struct DatePrototype: DateObject
static double getThisDate(ExecutionContext *ctx);
- static Value method_parse(SimpleCallContext *ctx);
- static Value method_UTC(SimpleCallContext *ctx);
- static Value method_now(SimpleCallContext *ctx);
-
- static Value method_toString(SimpleCallContext *ctx);
- static Value method_toDateString(SimpleCallContext *ctx);
- static Value method_toTimeString(SimpleCallContext *ctx);
- static Value method_toLocaleString(SimpleCallContext *ctx);
- static Value method_toLocaleDateString(SimpleCallContext *ctx);
- static Value method_toLocaleTimeString(SimpleCallContext *ctx);
- static Value method_valueOf(SimpleCallContext *ctx);
- static Value method_getTime(SimpleCallContext *ctx);
- static Value method_getYear(SimpleCallContext *ctx);
- static Value method_getFullYear(SimpleCallContext *ctx);
- static Value method_getUTCFullYear(SimpleCallContext *ctx);
- static Value method_getMonth(SimpleCallContext *ctx);
- static Value method_getUTCMonth(SimpleCallContext *ctx);
- static Value method_getDate(SimpleCallContext *ctx);
- static Value method_getUTCDate(SimpleCallContext *ctx);
- static Value method_getDay(SimpleCallContext *ctx);
- static Value method_getUTCDay(SimpleCallContext *ctx);
- static Value method_getHours(SimpleCallContext *ctx);
- static Value method_getUTCHours(SimpleCallContext *ctx);
- static Value method_getMinutes(SimpleCallContext *ctx);
- static Value method_getUTCMinutes(SimpleCallContext *ctx);
- static Value method_getSeconds(SimpleCallContext *ctx);
- static Value method_getUTCSeconds(SimpleCallContext *ctx);
- static Value method_getMilliseconds(SimpleCallContext *ctx);
- static Value method_getUTCMilliseconds(SimpleCallContext *ctx);
- static Value method_getTimezoneOffset(SimpleCallContext *ctx);
- static Value method_setTime(SimpleCallContext *ctx);
- static Value method_setMilliseconds(SimpleCallContext *ctx);
- static Value method_setUTCMilliseconds(SimpleCallContext *ctx);
- static Value method_setSeconds(SimpleCallContext *ctx);
- static Value method_setUTCSeconds(SimpleCallContext *ctx);
- static Value method_setMinutes(SimpleCallContext *ctx);
- static Value method_setUTCMinutes(SimpleCallContext *ctx);
- static Value method_setHours(SimpleCallContext *ctx);
- static Value method_setUTCHours(SimpleCallContext *ctx);
- static Value method_setDate(SimpleCallContext *ctx);
- static Value method_setUTCDate(SimpleCallContext *ctx);
- static Value method_setMonth(SimpleCallContext *ctx);
- static Value method_setUTCMonth(SimpleCallContext *ctx);
- static Value method_setYear(SimpleCallContext *ctx);
- static Value method_setFullYear(SimpleCallContext *ctx);
- static Value method_setUTCFullYear(SimpleCallContext *ctx);
- static Value method_toUTCString(SimpleCallContext *ctx);
- static Value method_toISOString(SimpleCallContext *ctx);
- static Value method_toJSON(SimpleCallContext *ctx);
+ static ReturnedValue method_parse(SimpleCallContext *ctx);
+ static ReturnedValue method_UTC(SimpleCallContext *ctx);
+ static ReturnedValue method_now(SimpleCallContext *ctx);
+
+ static ReturnedValue method_toString(SimpleCallContext *ctx);
+ static ReturnedValue method_toDateString(SimpleCallContext *ctx);
+ static ReturnedValue method_toTimeString(SimpleCallContext *ctx);
+ static ReturnedValue method_toLocaleString(SimpleCallContext *ctx);
+ static ReturnedValue method_toLocaleDateString(SimpleCallContext *ctx);
+ static ReturnedValue method_toLocaleTimeString(SimpleCallContext *ctx);
+ static ReturnedValue method_valueOf(SimpleCallContext *ctx);
+ static ReturnedValue method_getTime(SimpleCallContext *ctx);
+ static ReturnedValue method_getYear(SimpleCallContext *ctx);
+ static ReturnedValue method_getFullYear(SimpleCallContext *ctx);
+ static ReturnedValue method_getUTCFullYear(SimpleCallContext *ctx);
+ static ReturnedValue method_getMonth(SimpleCallContext *ctx);
+ static ReturnedValue method_getUTCMonth(SimpleCallContext *ctx);
+ static ReturnedValue method_getDate(SimpleCallContext *ctx);
+ static ReturnedValue method_getUTCDate(SimpleCallContext *ctx);
+ static ReturnedValue method_getDay(SimpleCallContext *ctx);
+ static ReturnedValue method_getUTCDay(SimpleCallContext *ctx);
+ static ReturnedValue method_getHours(SimpleCallContext *ctx);
+ static ReturnedValue method_getUTCHours(SimpleCallContext *ctx);
+ static ReturnedValue method_getMinutes(SimpleCallContext *ctx);
+ static ReturnedValue method_getUTCMinutes(SimpleCallContext *ctx);
+ static ReturnedValue method_getSeconds(SimpleCallContext *ctx);
+ static ReturnedValue method_getUTCSeconds(SimpleCallContext *ctx);
+ static ReturnedValue method_getMilliseconds(SimpleCallContext *ctx);
+ static ReturnedValue method_getUTCMilliseconds(SimpleCallContext *ctx);
+ static ReturnedValue method_getTimezoneOffset(SimpleCallContext *ctx);
+ static ReturnedValue method_setTime(SimpleCallContext *ctx);
+ static ReturnedValue method_setMilliseconds(SimpleCallContext *ctx);
+ static ReturnedValue method_setUTCMilliseconds(SimpleCallContext *ctx);
+ static ReturnedValue method_setSeconds(SimpleCallContext *ctx);
+ static ReturnedValue method_setUTCSeconds(SimpleCallContext *ctx);
+ static ReturnedValue method_setMinutes(SimpleCallContext *ctx);
+ static ReturnedValue method_setUTCMinutes(SimpleCallContext *ctx);
+ static ReturnedValue method_setHours(SimpleCallContext *ctx);
+ static ReturnedValue method_setUTCHours(SimpleCallContext *ctx);
+ static ReturnedValue method_setDate(SimpleCallContext *ctx);
+ static ReturnedValue method_setUTCDate(SimpleCallContext *ctx);
+ static ReturnedValue method_setMonth(SimpleCallContext *ctx);
+ static ReturnedValue method_setUTCMonth(SimpleCallContext *ctx);
+ static ReturnedValue method_setYear(SimpleCallContext *ctx);
+ static ReturnedValue method_setFullYear(SimpleCallContext *ctx);
+ static ReturnedValue method_setUTCFullYear(SimpleCallContext *ctx);
+ static ReturnedValue method_toUTCString(SimpleCallContext *ctx);
+ static ReturnedValue method_toISOString(SimpleCallContext *ctx);
+ static ReturnedValue method_toJSON(SimpleCallContext *ctx);
static void timezoneUpdated();
};
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index 10f22a11b8..34b72e95fb 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -46,6 +46,8 @@
#include "qv4instr_moth_p.h"
#include <iostream>
+#include <algorithm>
+
using namespace QV4;
using namespace QV4::Debugging;
@@ -207,14 +209,16 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string
{
using namespace QV4;
using namespace std;
+
+ Scope scope(ctx);
+
cout << prefix << "tag: " << hex << v.tag << dec << endl << prefix << "\t-> ";
switch (v.type()) {
- case Value::Undefined_Type: cout << "Undefined" << endl; return;
- case Value::Null_Type: cout << "Null" << endl; return;
+ case Value::Undefined_Type: cout << "Undefined"; return;
+ case Value::Null_Type: cout << "Null"; return;
case Value::Boolean_Type: cout << "Boolean"; break;
case Value::Integer_Type: cout << "Integer"; break;
- case Value::Object_Type: cout << "Object"; break;
- case Value::String_Type: cout << "String"; break;
+ case Value::Managed_Type: cout << v.managed()->className().toUtf8().data(); break;
default: cout << "UNKNOWN" << endl; return;
}
cout << endl;
@@ -269,11 +273,12 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string
cout << prefix << "properties:" << endl;
ForEachIteratorObject it(ctx, o);
- for (Value name = it.nextPropertyName(); !name.isNull(); name = it.nextPropertyName()) {
- cout << prefix << "\t\"" << qPrintable(name.stringValue()->toQString()) << "\"" << endl;
+ QV4::ScopedValue name(scope);
+ for (name = it.nextPropertyName(); !name->isNull(); name = it.nextPropertyName()) {
+ cout << prefix << "\t\"" << qPrintable(name->stringValue()->toQString()) << "\"" << endl;
PropertyAttributes attrs;
- Property *d = o->__getOwnProperty__(name.stringValue(), &attrs);
- Value pval = o->getValue(d, attrs);
+ Property *d = o->__getOwnProperty__(name->stringValue(), &attrs);
+ Value pval = Value::fromReturnedValue(o->getValue(d, attrs));
cout << prefix << "\tvalue:" << endl;
realDumpValue(pval, ctx, prefix + "\t");
}
@@ -331,7 +336,7 @@ void Debugger::BreakPoints::add(const QString &fileName, int lineNumber)
QList<int> &lines = (*this)[fileName];
if (!lines.contains(lineNumber)) {
lines.append(lineNumber);
- qSort(lines);
+ std::sort(lines.begin(), lines.end());
}
}
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 638609de37..1a084905ae 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -338,9 +338,9 @@ ExecutionContext *ExecutionEngine::pushGlobalContext()
return current;
}
-FunctionObject *ExecutionEngine::newBuiltinFunction(ExecutionContext *scope, String *name, Value (*code)(SimpleCallContext *))
+FunctionObject *ExecutionEngine::newBuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *))
{
- BuiltinFunctionOld *f = new (memoryManager) BuiltinFunctionOld(scope, name, code);
+ BuiltinFunction *f = new (memoryManager) BuiltinFunction(scope, name, code);
return f;
}
@@ -375,25 +375,25 @@ String *ExecutionEngine::newIdentifier(const QString &text)
return identifierTable->insertString(text);
}
-Object *ExecutionEngine::newStringObject(const Value &value)
+Returned<Object> *ExecutionEngine::newStringObject(const Value &value)
{
StringObject *object = new (memoryManager) StringObject(this, value);
- return object;
+ return object->asReturned<Object>();
}
-Object *ExecutionEngine::newNumberObject(const Value &value)
+Returned<Object> *ExecutionEngine::newNumberObject(const Value &value)
{
NumberObject *object = new (memoryManager) NumberObject(this, value);
- return object;
+ return object->asReturned<Object>();
}
-Object *ExecutionEngine::newBooleanObject(const Value &value)
+Returned<Object> *ExecutionEngine::newBooleanObject(const Value &value)
{
Object *object = new (memoryManager) BooleanObject(this, value);
- return object;
+ return object->asReturned<Object>();
}
-ArrayObject *ExecutionEngine::newArrayObject(int count)
+Returned<ArrayObject> *ExecutionEngine::newArrayObject(int count)
{
ArrayObject *object = new (memoryManager) ArrayObject(this);
@@ -402,35 +402,35 @@ ArrayObject *ExecutionEngine::newArrayObject(int count)
object->arrayReserve(count);
object->setArrayLengthUnchecked(count);
}
- return object;
+ return object->asReturned<ArrayObject>();
}
-ArrayObject *ExecutionEngine::newArrayObject(const QStringList &list)
+Returned<ArrayObject> *ExecutionEngine::newArrayObject(const QStringList &list)
{
ArrayObject *object = new (memoryManager) ArrayObject(this, list);
- return object;
+ return object->asReturned<ArrayObject>();
}
-ArrayObject *ExecutionEngine::newArrayObject(InternalClass *ic)
+Returned<ArrayObject> *ExecutionEngine::newArrayObject(InternalClass *ic)
{
ArrayObject *object = new (memoryManager) ArrayObject(ic);
- return object;
+ return object->asReturned<ArrayObject>();
}
-DateObject *ExecutionEngine::newDateObject(const Value &value)
+Returned<DateObject> *ExecutionEngine::newDateObject(const Value &value)
{
DateObject *object = new (memoryManager) DateObject(this, value);
- return object;
+ return object->asReturned<DateObject>();
}
-DateObject *ExecutionEngine::newDateObject(const QDateTime &dt)
+Returned<DateObject> *ExecutionEngine::newDateObject(const QDateTime &dt)
{
DateObject *object = new (memoryManager) DateObject(this, dt);
- return object;
+ return object->asReturned<DateObject>();
}
-RegExpObject *ExecutionEngine::newRegExpObject(const QString &pattern, int flags)
+Returned<RegExpObject> *ExecutionEngine::newRegExpObject(const QString &pattern, int flags)
{
bool global = (flags & QQmlJS::V4IR::RegExp::RegExp_Global);
bool ignoreCase = false;
@@ -443,72 +443,81 @@ RegExpObject *ExecutionEngine::newRegExpObject(const QString &pattern, int flags
return newRegExpObject(RegExp::create(this, pattern, ignoreCase, multiline), global);
}
-RegExpObject *ExecutionEngine::newRegExpObject(RegExp* re, bool global)
+Returned<RegExpObject> *ExecutionEngine::newRegExpObject(RegExp* re, bool global)
{
RegExpObject *object = new (memoryManager) RegExpObject(this, re, global);
- return object;
+ return object->asReturned<RegExpObject>();
}
-RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re)
+Returned<RegExpObject> *ExecutionEngine::newRegExpObject(const QRegExp &re)
{
RegExpObject *object = new (memoryManager) RegExpObject(this, re);
- return object;
+ return object->asReturned<RegExpObject>();
}
-Object *ExecutionEngine::newErrorObject(const Value &value)
+Returned<Object> *ExecutionEngine::newErrorObject(const Value &value)
{
ErrorObject *object = new (memoryManager) ErrorObject(errorClass, value);
- return object;
+ return object->asReturned<Object>();
}
-Object *ExecutionEngine::newSyntaxErrorObject(const QString &message)
+Returned<Object> *ExecutionEngine::newSyntaxErrorObject(const QString &message)
{
- return new (memoryManager) SyntaxErrorObject(this, Value::fromString(this, message));
+ Object *error = new (memoryManager) SyntaxErrorObject(this, Value::fromString(this, message));
+ return error->asReturned<Object>();
}
-Object *ExecutionEngine::newSyntaxErrorObject(const QString &message, const QString &fileName, int line, int column)
+Returned<Object> *ExecutionEngine::newSyntaxErrorObject(const QString &message, const QString &fileName, int line, int column)
{
- return new (memoryManager) SyntaxErrorObject(this, message, fileName, line, column);
+ Object *error = new (memoryManager) SyntaxErrorObject(this, message, fileName, line, column);
+ return error->asReturned<Object>();
}
-Object *ExecutionEngine::newReferenceErrorObject(const QString &message)
+Returned<Object> *ExecutionEngine::newReferenceErrorObject(const QString &message)
{
- return new (memoryManager) ReferenceErrorObject(this, message);
+ Object *o = new (memoryManager) ReferenceErrorObject(this, message);
+ return o->asReturned<Object>();
}
-Object *ExecutionEngine::newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber)
+Returned<Object> *ExecutionEngine::newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber)
{
- return new (memoryManager) ReferenceErrorObject(this, message, fileName, lineNumber, columnNumber);
+ Object *o = new (memoryManager) ReferenceErrorObject(this, message, fileName, lineNumber, columnNumber);
+ return o->asReturned<Object>();
}
-Object *ExecutionEngine::newTypeErrorObject(const QString &message)
+Returned<Object> *ExecutionEngine::newTypeErrorObject(const QString &message)
{
- return new (memoryManager) TypeErrorObject(this, message);
+ Object *o = new (memoryManager) TypeErrorObject(this, message);
+ return o->asReturned<Object>();
}
-Object *ExecutionEngine::newRangeErrorObject(const QString &message)
+Returned<Object> *ExecutionEngine::newRangeErrorObject(const QString &message)
{
- return new (memoryManager) RangeErrorObject(this, message);
+ Object *o = new (memoryManager) RangeErrorObject(this, message);
+ return o->asReturned<Object>();
}
-Object *ExecutionEngine::newURIErrorObject(Value message)
+Returned<Object> *ExecutionEngine::newURIErrorObject(Value message)
{
- return new (memoryManager) URIErrorObject(this, message);
+ Object *o = new (memoryManager) URIErrorObject(this, message);
+ return o->asReturned<Object>();
}
-Object *ExecutionEngine::newVariantObject(const QVariant &v)
+Returned<Object> *ExecutionEngine::newVariantObject(const QVariant &v)
{
- return new (memoryManager) VariantObject(this, v);
+ Object *o = new (memoryManager) VariantObject(this, v);
+ return o->asReturned<Object>();
}
-Object *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, Object *o)
+Returned<Object> *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, Object *o)
{
- return new (memoryManager) ForEachIteratorObject(ctx, o);
+ Object *obj = new (memoryManager) ForEachIteratorObject(ctx, o);
+ return obj->asReturned<Object>();
}
-Object *ExecutionEngine::qmlContextObject() const
+Returned<Object> *ExecutionEngine::qmlContextObject() const
{
ExecutionContext *ctx = current;
@@ -525,7 +534,7 @@ Object *ExecutionEngine::qmlContextObject() const
if (ctx->type != ExecutionContext::Type_QmlContext)
return 0;
- return static_cast<CallContext *>(ctx)->activation;
+ return static_cast<CallContext *>(ctx)->activation->asReturned<Object>();
}
namespace {
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 1dbffa28aa..297f756033 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -261,7 +261,7 @@ struct Q_QML_EXPORT ExecutionEngine
void pushContext(SimpleCallContext *context);
ExecutionContext *popContext();
- FunctionObject *newBuiltinFunction(ExecutionContext *scope, String *name, Value (*code)(SimpleCallContext *));
+ FunctionObject *newBuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *));
BoundFunction *newBoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector<Value> &boundArgs);
Object *newObject();
@@ -270,35 +270,35 @@ struct Q_QML_EXPORT ExecutionEngine
String *newString(const QString &s);
String *newIdentifier(const QString &text);
- Object *newStringObject(const Value &value);
- Object *newNumberObject(const Value &value);
- Object *newBooleanObject(const Value &value);
+ Returned<Object> *newStringObject(const Value &value);
+ Returned<Object> *newNumberObject(const Value &value);
+ Returned<Object> *newBooleanObject(const Value &value);
- ArrayObject *newArrayObject(int count = 0);
- ArrayObject *newArrayObject(const QStringList &list);
- ArrayObject *newArrayObject(InternalClass *ic);
+ Returned<ArrayObject> *newArrayObject(int count = 0);
+ Returned<ArrayObject> *newArrayObject(const QStringList &list);
+ Returned<ArrayObject> *newArrayObject(InternalClass *ic);
- DateObject *newDateObject(const Value &value);
- DateObject *newDateObject(const QDateTime &dt);
+ Returned<DateObject> *newDateObject(const Value &value);
+ Returned<DateObject> *newDateObject(const QDateTime &dt);
- RegExpObject *newRegExpObject(const QString &pattern, int flags);
- RegExpObject *newRegExpObject(RegExp* re, bool global);
- RegExpObject *newRegExpObject(const QRegExp &re);
+ Returned<RegExpObject> *newRegExpObject(const QString &pattern, int flags);
+ Returned<RegExpObject> *newRegExpObject(RegExp* re, bool global);
+ Returned<RegExpObject> *newRegExpObject(const QRegExp &re);
- Object *newErrorObject(const Value &value);
- Object *newSyntaxErrorObject(const QString &message, const QString &fileName, int line, int column);
- Object *newSyntaxErrorObject(const QString &message);
- Object *newReferenceErrorObject(const QString &message);
- Object *newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber);
- Object *newTypeErrorObject(const QString &message);
- Object *newRangeErrorObject(const QString &message);
- Object *newURIErrorObject(Value message);
+ Returned<Object> *newErrorObject(const Value &value);
+ Returned<Object> *newSyntaxErrorObject(const QString &message, const QString &fileName, int line, int column);
+ Returned<Object> *newSyntaxErrorObject(const QString &message);
+ Returned<Object> *newReferenceErrorObject(const QString &message);
+ Returned<Object> *newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber, int columnNumber);
+ Returned<Object> *newTypeErrorObject(const QString &message);
+ Returned<Object> *newRangeErrorObject(const QString &message);
+ Returned<Object> *newURIErrorObject(Value message);
- Object *newVariantObject(const QVariant &v);
+ Returned<Object> *newVariantObject(const QVariant &v);
- Object *newForEachIteratorObject(ExecutionContext *ctx, Object *o);
+ Returned<Object> *newForEachIteratorObject(ExecutionContext *ctx, Object *o);
- Object *qmlContextObject() const;
+ Returned<Object> *qmlContextObject() const;
struct StackFrame {
QString source;
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 6174c9a7f5..987d5083fa 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -127,7 +127,7 @@ ErrorObject::ErrorObject(InternalClass *ic, const QString &message, const QStrin
defineDefaultProperty(ic->engine, QStringLiteral("message"), Value::fromString(ic->engine->newString(message)));
}
-Value ErrorObject::method_get_stack(SimpleCallContext *ctx)
+ReturnedValue ErrorObject::method_get_stack(SimpleCallContext *ctx)
{
ErrorObject *This = ctx->thisObject.asErrorObject();
if (!This)
@@ -148,7 +148,7 @@ Value ErrorObject::method_get_stack(SimpleCallContext *ctx)
}
This->stack = ctx->engine->newString(trace);
}
- return Value::fromString(This->stack);
+ return Value::fromString(This->stack).asReturnedValue();
}
void ErrorObject::markObjects(Managed *that)
@@ -240,12 +240,12 @@ ErrorCtor::ErrorCtor(ExecutionContext *scope, String *name)
vtbl = &static_vtbl;
}
-Value ErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue ErrorCtor::construct(Managed *m, CallData *callData)
{
- return Value::fromObject(m->engine()->newErrorObject(callData->argc ? callData->args[0] : Value::undefinedValue()));
+ return Encode(m->engine()->newErrorObject(callData->argc ? callData->args[0] : Value::undefinedValue()));
}
-Value ErrorCtor::call(Managed *that, CallData *callData)
+ReturnedValue ErrorCtor::call(Managed *that, CallData *callData)
{
return that->construct(callData);
}
@@ -256,9 +256,10 @@ EvalErrorCtor::EvalErrorCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value EvalErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData)
{
- return Value::fromObject(new (m->engine()->memoryManager) EvalErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue()));
+ return Value::fromObject(new (m->engine()->memoryManager) EvalErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue()))
+ .asReturnedValue();
}
RangeErrorCtor::RangeErrorCtor(ExecutionContext *scope)
@@ -267,9 +268,9 @@ RangeErrorCtor::RangeErrorCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value RangeErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData)
{
- return Value::fromObject(new (m->engine()->memoryManager) RangeErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue()));
+ return Value::fromObject(new (m->engine()->memoryManager) RangeErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue())).asReturnedValue();
}
ReferenceErrorCtor::ReferenceErrorCtor(ExecutionContext *scope)
@@ -278,9 +279,9 @@ ReferenceErrorCtor::ReferenceErrorCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value ReferenceErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData)
{
- return Value::fromObject(new (m->engine()->memoryManager) ReferenceErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue()));
+ return Value::fromObject(new (m->engine()->memoryManager) ReferenceErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue())).asReturnedValue();
}
SyntaxErrorCtor::SyntaxErrorCtor(ExecutionContext *scope)
@@ -289,9 +290,9 @@ SyntaxErrorCtor::SyntaxErrorCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value SyntaxErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData)
{
- return Value::fromObject(new (m->engine()->memoryManager) SyntaxErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue()));
+ return Value::fromObject(new (m->engine()->memoryManager) SyntaxErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue())).asReturnedValue();
}
TypeErrorCtor::TypeErrorCtor(ExecutionContext *scope)
@@ -300,9 +301,9 @@ TypeErrorCtor::TypeErrorCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value TypeErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData)
{
- return Value::fromObject(new (m->engine()->memoryManager) TypeErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue()));
+ return Value::fromObject(new (m->engine()->memoryManager) TypeErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue())).asReturnedValue();
}
URIErrorCtor::URIErrorCtor(ExecutionContext *scope)
@@ -311,9 +312,9 @@ URIErrorCtor::URIErrorCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value URIErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue URIErrorCtor::construct(Managed *m, CallData *callData)
{
- return Value::fromObject(new (m->engine()->memoryManager) URIErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue()));
+ return Value::fromObject(new (m->engine()->memoryManager) URIErrorObject(m->engine(), callData->argc ? callData->args[0] : Value::undefinedValue())).asReturnedValue();
}
void ErrorPrototype::init(ExecutionEngine *engine, const Value &ctor, Object *obj)
@@ -325,9 +326,9 @@ void ErrorPrototype::init(ExecutionEngine *engine, const Value &ctor, Object *ob
obj->defineDefaultProperty(engine, QStringLiteral("message"), Value::fromString(engine, QString()));
}
-Value ErrorPrototype::method_toString(SimpleCallContext *ctx)
+ReturnedValue ErrorPrototype::method_toString(SimpleCallContext *ctx)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
Object *o = ctx->thisObject.asObject();
if (!o)
@@ -338,12 +339,12 @@ Value ErrorPrototype::method_toString(SimpleCallContext *ctx)
if (name->isUndefined())
qname = QString::fromLatin1("Error");
else
- qname = __qmljs_to_string(name, ctx).stringValue()->toQString();
+ qname = name->toQString();
ScopedValue message(scope, o->get(ctx->engine->newString(QString::fromLatin1("message"))));
QString qmessage;
if (!message->isUndefined())
- qmessage = __qmljs_to_string(message, ctx).stringValue()->toQString();
+ qmessage = message->toQString();
QString str;
if (qname.isEmpty()) {
@@ -354,5 +355,5 @@ Value ErrorPrototype::method_toString(SimpleCallContext *ctx)
str = qname + QLatin1String(": ") + qmessage;
}
- return Value::fromString(ctx, str);
+ return Value::fromString(ctx, str).asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 1d82bb7ba2..73d9362a6d 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -72,7 +72,7 @@ struct ErrorObject: Object {
ExecutionEngine::StackTrace stackTrace;
String *stack;
- static Value method_get_stack(SimpleCallContext *ctx);
+ static ReturnedValue method_get_stack(SimpleCallContext *ctx);
static void markObjects(Managed *that);
static void destroy(Managed *that) { static_cast<ErrorObject *>(that)->~ErrorObject(); }
};
@@ -93,11 +93,9 @@ struct ReferenceErrorObject: ErrorObject {
};
struct SyntaxErrorObject: ErrorObject {
+ Q_MANAGED
SyntaxErrorObject(ExecutionEngine *engine, const Value &msg);
SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber);
-
-protected:
- static const ManagedVTable static_vtbl;
};
struct TypeErrorObject: ErrorObject {
@@ -111,74 +109,60 @@ struct URIErrorObject: ErrorObject {
struct ErrorCtor: FunctionObject
{
+ Q_MANAGED
ErrorCtor(ExecutionContext *scope);
ErrorCtor(ExecutionContext *scope, String *name);
- static Value construct(Managed *, CallData *callData);
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct EvalErrorCtor: ErrorCtor
{
+ Q_MANAGED
EvalErrorCtor(ExecutionContext *scope);
- static Value construct(Managed *m, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *m, CallData *callData);
};
struct RangeErrorCtor: ErrorCtor
{
+ Q_MANAGED
RangeErrorCtor(ExecutionContext *scope);
- static Value construct(Managed *m, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *m, CallData *callData);
};
struct ReferenceErrorCtor: ErrorCtor
{
+ Q_MANAGED
ReferenceErrorCtor(ExecutionContext *scope);
- static Value construct(Managed *m, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *m, CallData *callData);
};
struct SyntaxErrorCtor: ErrorCtor
{
+ Q_MANAGED
SyntaxErrorCtor(ExecutionContext *scope);
- static Value construct(Managed *m, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *m, CallData *callData);
};
struct TypeErrorCtor: ErrorCtor
{
+ Q_MANAGED
TypeErrorCtor(ExecutionContext *scope);
- static Value construct(Managed *m, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *m, CallData *callData);
};
struct URIErrorCtor: ErrorCtor
{
+ Q_MANAGED
URIErrorCtor(ExecutionContext *scope);
- static Value construct(Managed *m, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *m, CallData *callData);
};
@@ -189,7 +173,7 @@ struct ErrorPrototype: ErrorObject
void init(ExecutionEngine *engine, const Value &ctor) { init(engine, ctor, this); }
static void init(ExecutionEngine *engine, const Value &ctor, Object *obj);
- static Value method_toString(SimpleCallContext *ctx);
+ static ReturnedValue method_toString(SimpleCallContext *ctx);
};
struct EvalErrorPrototype: ErrorObject
diff --git a/src/qml/jsruntime/qv4exception.cpp b/src/qml/jsruntime/qv4exception.cpp
index 9f15c27ffc..725a046b71 100644
--- a/src/qml/jsruntime/qv4exception.cpp
+++ b/src/qml/jsruntime/qv4exception.cpp
@@ -87,7 +87,8 @@ void Exception::throwException(ExecutionContext *context, const Value &value)
}
Exception::Exception(ExecutionContext *throwingContext, const Value &exceptionValue)
- : exception(exceptionValue)
+ : e(throwingContext->engine)
+ , exception(exceptionValue)
{
this->throwingContext = throwingContext->engine->current;
accepted = false;
diff --git a/src/qml/jsruntime/qv4exception_p.h b/src/qml/jsruntime/qv4exception_p.h
index 8ba06f57f4..75246fa147 100644
--- a/src/qml/jsruntime/qv4exception_p.h
+++ b/src/qml/jsruntime/qv4exception_p.h
@@ -58,15 +58,17 @@ struct Q_QML_EXPORT Exception {
void partiallyUnwindContext(ExecutionContext *catchingContext);
- Value value() const { return exception; }
+ ReturnedValue value() const { return exception.value().asReturnedValue(); }
ExecutionEngine::StackTrace stackTrace() const { return m_stackTrace; }
+ ExecutionEngine *engine() const { return e; }
private:
void *operator new(size_t, void *p) { return p; }
explicit Exception(ExecutionContext *throwingContext, const Value &exceptionValue);
+ ExecutionEngine *e;
ExecutionContext *throwingContext;
bool accepted;
PersistentValue exception;
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 9907f3e2ba..a7ae365d21 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function,
- Value (*codePtr)(ExecutionContext *, const uchar *), quint32 _codeSize)
+ ReturnedValue (*codePtr)(ExecutionContext *, const uchar *), quint32 _codeSize)
: name(0)
, compiledFunction(function)
, compilationUnit(unit)
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 1fc40d7209..b93eded3f3 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -85,7 +85,7 @@ struct Function {
const CompiledData::Function *compiledFunction;
CompiledData::CompilationUnit *compilationUnit;
- inline Value code(ExecutionContext *ctx, const uchar *data) {
+ inline ReturnedValue code(ExecutionContext *ctx, const uchar *data) {
Value *stack = ctx->engine->jsStackTop;
try {
return codePtr(ctx, data);
@@ -95,7 +95,7 @@ struct Function {
}
}
- Value (*codePtr)(ExecutionContext *, const uchar *);
+ ReturnedValue (*codePtr)(ExecutionContext *, const uchar *);
const uchar *codeData;
quint32 codeSize;
@@ -103,7 +103,7 @@ struct Function {
QVector<String *> locals;
Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function,
- Value (*codePtr)(ExecutionContext *, const uchar *), quint32 _codeSize);
+ ReturnedValue (*codePtr)(ExecutionContext *, const uchar *), quint32 _codeSize);
~Function();
inline QString sourceFile() const { return compilationUnit->fileName(); }
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 252481b7f1..0cf235475e 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -63,6 +63,7 @@
#include <cassert>
#include <typeinfo>
#include <iostream>
+#include <algorithm>
#include "qv4alloca_p.h"
using namespace QV4;
@@ -121,9 +122,10 @@ FunctionObject::~FunctionObject()
function->compilationUnit->deref();
}
-Value FunctionObject::newInstance()
+ReturnedValue FunctionObject::newInstance()
{
- ScopedCallData callData(engine(), 0);
+ Scope scope(engine());
+ ScopedCallData callData(scope, 0);
return construct(callData);
}
@@ -136,7 +138,9 @@ bool FunctionObject::hasInstance(Managed *that, const Value &value)
return false;
ExecutionContext *ctx = f->engine()->current;
- Object *o = f->get(ctx->engine->id_prototype).asObject();
+ QV4::Scope scope(ctx);
+
+ Scoped<Object> o(scope, f->get(ctx->engine->id_prototype));
if (!o)
ctx->throwTypeError();
@@ -145,29 +149,30 @@ bool FunctionObject::hasInstance(Managed *that, const Value &value)
if (! v)
break;
- else if (o == v)
+ else if (o.getPointer() == v)
return true;
}
return false;
}
-Value FunctionObject::construct(Managed *that, CallData *)
+ReturnedValue FunctionObject::construct(Managed *that, CallData *)
{
FunctionObject *f = static_cast<FunctionObject *>(that);
ExecutionEngine *v4 = f->engine();
+ Scope scope(v4);
InternalClass *ic = v4->objectClass;
- Value proto = f->get(v4->id_prototype);
- if (proto.isObject())
- ic = v4->emptyClass->changePrototype(proto.objectValue());
+ Scoped<Object> proto(scope, f->get(v4->id_prototype));
+ if (!!proto)
+ ic = v4->emptyClass->changePrototype(proto.getPointer());
Object *obj = v4->newObject(ic);
- return Value::fromObject(obj);
+ return Value::fromObject(obj).asReturnedValue();
}
-Value FunctionObject::call(Managed *, CallData *)
+ReturnedValue FunctionObject::call(Managed *, CallData *)
{
- return Value::undefinedValue();
+ return Encode::undefined();
}
void FunctionObject::markObjects(Managed *that)
@@ -204,7 +209,7 @@ FunctionCtor::FunctionCtor(ExecutionContext *scope)
}
// 15.3.2
-Value FunctionCtor::construct(Managed *that, CallData *callData)
+ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
{
FunctionCtor *f = static_cast<FunctionCtor *>(that);
MemoryManager::GCBlocker gcBlocker(f->engine()->memoryManager);
@@ -249,11 +254,11 @@ Value FunctionCtor::construct(Managed *that, CallData *callData)
QV4::CompiledData::CompilationUnit *compilationUnit = isel->compile();
QV4::Function *vmf = compilationUnit->linkToEngine(v4);
- return Value::fromObject(FunctionObject::creatScriptFunction(v4->rootContext, vmf));
+ return Value::fromObject(FunctionObject::creatScriptFunction(v4->rootContext, vmf)).asReturnedValue();
}
// 15.3.1: This is equivalent to new Function(...)
-Value FunctionCtor::call(Managed *that, CallData *callData)
+ReturnedValue FunctionCtor::call(Managed *that, CallData *callData)
{
return construct(that, callData);
}
@@ -277,17 +282,18 @@ void FunctionPrototype::init(ExecutionContext *ctx, const Value &ctor)
}
-Value FunctionPrototype::method_toString(SimpleCallContext *ctx)
+ReturnedValue FunctionPrototype::method_toString(SimpleCallContext *ctx)
{
FunctionObject *fun = ctx->thisObject.asFunctionObject();
if (!fun)
ctx->throwTypeError();
- return Value::fromString(ctx, QStringLiteral("function() { [code] }"));
+ return Value::fromString(ctx, QStringLiteral("function() { [code] }")).asReturnedValue();
}
-Value FunctionPrototype::method_apply(SimpleCallContext *ctx)
+ReturnedValue FunctionPrototype::method_apply(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
FunctionObject *o = ctx->thisObject.asFunctionObject();
if (!o)
ctx->throwTypeError();
@@ -302,18 +308,18 @@ Value FunctionPrototype::method_apply(SimpleCallContext *ctx)
len = 0;
if (!arg.isNullOrUndefined()) {
ctx->throwTypeError();
- return Value::undefinedValue();
+ return Encode::undefined();
}
} else {
len = ArrayPrototype::getLength(ctx, arr);
}
- ScopedCallData callData(ctx->engine, len);
+ ScopedCallData callData(scope, len);
if (len) {
if (arr->protoHasArray() || arr->hasAccessorProperty) {
for (quint32 i = 0; i < len; ++i)
- callData->args[i] = arr->getIndexed(i);
+ callData->args[i] = Value::fromReturnedValue(arr->getIndexed(i));
} else {
int alen = qMin(len, arr->arrayDataLen);
for (quint32 i = 0; i < alen; ++i)
@@ -327,23 +333,25 @@ Value FunctionPrototype::method_apply(SimpleCallContext *ctx)
return o->call(callData);
}
-Value FunctionPrototype::method_call(SimpleCallContext *ctx)
+ReturnedValue FunctionPrototype::method_call(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Value thisArg = ctx->argument(0);
FunctionObject *o = ctx->thisObject.asFunctionObject();
if (!o)
ctx->throwTypeError();
- ScopedCallData callData(ctx->engine, ctx->argumentCount ? ctx->argumentCount - 1 : 0);
- if (ctx->argumentCount)
- qCopy(ctx->arguments + 1,
- ctx->arguments + ctx->argumentCount, callData->args);
+ ScopedCallData callData(scope, ctx->argumentCount ? ctx->argumentCount - 1 : 0);
+ if (ctx->argumentCount) {
+ std::copy(ctx->arguments + 1,
+ ctx->arguments + ctx->argumentCount, callData->args);
+ }
callData->thisObject = thisArg;
return o->call(callData);
}
-Value FunctionPrototype::method_bind(SimpleCallContext *ctx)
+ReturnedValue FunctionPrototype::method_bind(SimpleCallContext *ctx)
{
FunctionObject *target = ctx->thisObject.asFunctionObject();
if (!target)
@@ -356,14 +364,14 @@ Value FunctionPrototype::method_bind(SimpleCallContext *ctx)
BoundFunction *f = ctx->engine->newBoundFunction(ctx->engine->rootContext, target, boundThis, boundArgs);
- return Value::fromObject(f);
+ return Value::fromObject(f).asReturnedValue();
}
-static Value throwTypeError(SimpleCallContext *ctx)
+static ReturnedValue throwTypeError(SimpleCallContext *ctx)
{
ctx->throwTypeError();
- return Value::undefinedValue();
+ return 0;
}
DEFINE_MANAGED_VTABLE(ScriptFunction);
@@ -401,11 +409,11 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
}
}
-Value ScriptFunction::construct(Managed *that, CallData *callData)
+ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
{
ScriptFunction *f = static_cast<ScriptFunction *>(that);
- SAVE_JS_STACK(f->scope);
ExecutionEngine *v4 = f->engine();
+ Scope scope(v4);
InternalClass *ic = v4->objectClass;
Value proto = f->memberData[Index_Prototype].value;
@@ -417,27 +425,28 @@ Value ScriptFunction::construct(Managed *that, CallData *callData)
callData->thisObject = Value::fromObject(obj);
ExecutionContext *ctx = context->newCallContext(f, callData);
- Value result;
+ ScopedValue result(scope);
+ SAVE_JS_STACK(f->scope);
try {
result = f->function->code(ctx, f->function->codeData);
} catch (Exception &ex) {
ex.partiallyUnwindContext(context);
throw;
}
+ CHECK_JS_STACK(f->scope);
ctx->engine->popContext();
- CHECK_JS_STACK(f->scope);
- if (result.isObject())
- return result;
- return Value::fromObject(obj);
+ if (result->isObject())
+ return result.asReturnedValue();
+ return Value::fromObject(obj).asReturnedValue();
}
-Value ScriptFunction::call(Managed *that, CallData *callData)
+ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
{
ScriptFunction *f = static_cast<ScriptFunction *>(that);
- SAVE_JS_STACK(f->scope);
void *stackSpace;
ExecutionContext *context = f->engine()->current;
+ Scope scope(context);
CallContext *ctx = context->newCallContext(f, callData);
if (!f->strictMode && !callData->thisObject.isObject()) {
@@ -448,16 +457,17 @@ Value ScriptFunction::call(Managed *that, CallData *callData)
}
}
- Value result;
+ ScopedValue result(scope);
+ SAVE_JS_STACK(f->scope);
try {
result = f->function->code(ctx, f->function->codeData);
} catch (Exception &ex) {
ex.partiallyUnwindContext(context);
throw;
}
- ctx->engine->popContext();
CHECK_JS_STACK(f->scope);
- return result;
+ ctx->engine->popContext();
+ return result.asReturnedValue();
}
DEFINE_MANAGED_VTABLE(SimpleScriptFunction);
@@ -495,11 +505,11 @@ SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *fu
}
}
-Value SimpleScriptFunction::construct(Managed *that, CallData *callData)
+ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
{
SimpleScriptFunction *f = static_cast<SimpleScriptFunction *>(that);
- SAVE_JS_STACK(f->scope);
ExecutionEngine *v4 = f->engine();
+ Scope scope(v4);
InternalClass *ic = v4->objectClass;
Value proto = f->memberData[Index_Prototype].value;
@@ -512,27 +522,28 @@ Value SimpleScriptFunction::construct(Managed *that, CallData *callData)
callData->thisObject = Value::fromObject(obj);
ExecutionContext *ctx = context->newCallContext(stackSpace, f, callData);
- Value result;
+ ScopedValue result(scope);
+ SAVE_JS_STACK(f->scope);
try {
result = f->function->code(ctx, f->function->codeData);
} catch (Exception &ex) {
ex.partiallyUnwindContext(context);
throw;
}
+ CHECK_JS_STACK(f->scope);
ctx->engine->popContext();
- CHECK_JS_STACK(f->scope);
- if (result.isObject())
- return result;
- return Value::fromObject(obj);
+ if (result->isObject())
+ return result.asReturnedValue();
+ return Value::fromObject(obj).asReturnedValue();
}
-Value SimpleScriptFunction::call(Managed *that, CallData *callData)
+ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
{
SimpleScriptFunction *f = static_cast<SimpleScriptFunction *>(that);
- SAVE_JS_STACK(f->scope);
void *stackSpace = alloca(requiredMemoryForExecutionContectSimple(f));
ExecutionContext *context = f->engine()->current;
+ Scope scope(context);
ExecutionContext *ctx = context->newCallContext(stackSpace, f, callData);
if (!f->strictMode && !callData->thisObject.isObject()) {
@@ -543,24 +554,25 @@ Value SimpleScriptFunction::call(Managed *that, CallData *callData)
}
}
- Value result;
+ ScopedValue result(scope);
+ SAVE_JS_STACK(f->scope);
try {
result = f->function->code(ctx, f->function->codeData);
} catch (Exception &ex) {
ex.partiallyUnwindContext(context);
throw;
}
- ctx->engine->popContext();
CHECK_JS_STACK(f->scope);
- return result;
+ ctx->engine->popContext();
+ return result.asReturnedValue();
}
-DEFINE_MANAGED_VTABLE(BuiltinFunctionOld);
+DEFINE_MANAGED_VTABLE(BuiltinFunction);
-BuiltinFunctionOld::BuiltinFunctionOld(ExecutionContext *scope, String *name, Value (*code)(SimpleCallContext *))
+BuiltinFunction::BuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *))
: FunctionObject(scope, name)
, code(code)
{
@@ -568,16 +580,17 @@ BuiltinFunctionOld::BuiltinFunctionOld(ExecutionContext *scope, String *name, Va
isBuiltinFunction = true;
}
-Value BuiltinFunctionOld::construct(Managed *f, CallData *)
+ReturnedValue BuiltinFunction::construct(Managed *f, CallData *)
{
f->engine()->current->throwTypeError();
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value BuiltinFunctionOld::call(Managed *that, CallData *callData)
+ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData)
{
- BuiltinFunctionOld *f = static_cast<BuiltinFunctionOld *>(that);
+ BuiltinFunction *f = static_cast<BuiltinFunction *>(that);
ExecutionEngine *v4 = f->engine();
+ Scope scope(v4);
ExecutionContext *context = v4->current;
SimpleCallContext ctx;
@@ -589,7 +602,7 @@ Value BuiltinFunctionOld::call(Managed *that, CallData *callData)
ctx.argumentCount = callData->argc;
v4->pushContext(&ctx);
- Value result;
+ ScopedValue result(scope);
try {
result = f->code(&ctx);
} catch (Exception &ex) {
@@ -598,14 +611,15 @@ Value BuiltinFunctionOld::call(Managed *that, CallData *callData)
}
context->engine->popContext();
- return result;
+ return result.asReturnedValue();
}
-Value IndexedBuiltinFunction::call(Managed *that, CallData *callData)
+ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
{
IndexedBuiltinFunction *f = static_cast<IndexedBuiltinFunction *>(that);
ExecutionEngine *v4 = f->engine();
ExecutionContext *context = v4->current;
+ Scope scope(v4);
SimpleCallContext ctx;
ctx.initSimpleCallContext(f->scope->engine);
@@ -616,7 +630,7 @@ Value IndexedBuiltinFunction::call(Managed *that, CallData *callData)
ctx.argumentCount = callData->argc;
v4->pushContext(&ctx);
- Value result;
+ ScopedValue result(scope);
try {
result = f->code(&ctx, f->index);
} catch (Exception &ex) {
@@ -625,7 +639,7 @@ Value IndexedBuiltinFunction::call(Managed *that, CallData *callData)
}
context->engine->popContext();
- return result;
+ return result.asReturnedValue();
}
DEFINE_MANAGED_VTABLE(IndexedBuiltinFunction);
@@ -639,7 +653,7 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va
, boundArgs(boundArgs)
{
vtbl = &static_vtbl;
- int len = target->get(scope->engine->id_length).toUInt32();
+ int len = Value::fromReturnedValue(target->get(scope->engine->id_length)).toUInt32();
len -= boundArgs.size();
if (len < 0)
len = 0;
@@ -656,21 +670,23 @@ void BoundFunction::destroy(Managed *that)
static_cast<BoundFunction *>(that)->~BoundFunction();
}
-Value BoundFunction::call(Managed *that, CallData *dd)
+ReturnedValue BoundFunction::call(Managed *that, CallData *dd)
{
BoundFunction *f = static_cast<BoundFunction *>(that);
+ Scope scope(f->scope->engine);
- ScopedCallData callData(f->scope->engine, f->boundArgs.size() + dd->argc);
+ ScopedCallData callData(scope, f->boundArgs.size() + dd->argc);
callData->thisObject = f->boundThis;
memcpy(callData->args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
memcpy(callData->args + f->boundArgs.size(), dd->args, dd->argc*sizeof(Value));
return f->target->call(callData);
}
-Value BoundFunction::construct(Managed *that, CallData *dd)
+ReturnedValue BoundFunction::construct(Managed *that, CallData *dd)
{
BoundFunction *f = static_cast<BoundFunction *>(that);
- ScopedCallData callData(f->scope->engine, f->boundArgs.size() + dd->argc);
+ Scope scope(f->scope->engine);
+ ScopedCallData callData(scope, f->boundArgs.size() + dd->argc);
memcpy(callData->args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value));
memcpy(callData->args + f->boundArgs.size(), dd->args, dd->argc*sizeof(Value));
return f->target->construct(callData);
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index d694d28462..333b95ad74 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -93,6 +93,7 @@ struct InternalClass;
struct Lookup;
struct Q_QML_EXPORT FunctionObject: Object {
+ Q_MANAGED
// Used with Managed::subType
enum FunctionType {
RegularFunction = 0,
@@ -115,23 +116,26 @@ struct Q_QML_EXPORT FunctionObject: Object {
FunctionObject(ExecutionContext *scope, String *name = 0, bool createProto = false);
~FunctionObject();
- Value newInstance();
+ ReturnedValue newInstance();
- static Value construct(Managed *that, CallData *);
- static Value call(Managed *that, CallData *d);
- inline Value construct(CallData *callData) {
+ static ReturnedValue construct(Managed *that, CallData *);
+ static ReturnedValue call(Managed *that, CallData *d);
+ inline ReturnedValue construct(CallData *callData) {
return vtbl->construct(this, callData);
}
- inline Value call(CallData *callData) {
+ inline ReturnedValue call(CallData *callData) {
return vtbl->call(this, callData);
}
+ static FunctionObject *cast(const Value &v) {
+ return v.asFunctionObject();
+ }
+
static FunctionObject *creatScriptFunction(ExecutionContext *scope, Function *function);
protected:
FunctionObject(InternalClass *ic);
- static const ManagedVTable static_vtbl;
static void markObjects(Managed *that);
static bool hasInstance(Managed *that, const Value &value);
static void destroy(Managed *that)
@@ -140,13 +144,11 @@ protected:
struct FunctionCtor: FunctionObject
{
+ Q_MANAGED
FunctionCtor(ExecutionContext *scope);
- static Value construct(Managed *that, CallData *callData);
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *that, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct FunctionPrototype: FunctionObject
@@ -154,32 +156,30 @@ struct FunctionPrototype: FunctionObject
FunctionPrototype(InternalClass *ic);
void init(ExecutionContext *ctx, const Value &ctor);
- static Value method_toString(SimpleCallContext *ctx);
- static Value method_apply(SimpleCallContext *ctx);
- static Value method_call(SimpleCallContext *ctx);
- static Value method_bind(SimpleCallContext *ctx);
+ static ReturnedValue method_toString(SimpleCallContext *ctx);
+ static ReturnedValue method_apply(SimpleCallContext *ctx);
+ static ReturnedValue method_call(SimpleCallContext *ctx);
+ static ReturnedValue method_bind(SimpleCallContext *ctx);
};
-struct BuiltinFunctionOld: FunctionObject {
- Value (*code)(SimpleCallContext *);
-
- BuiltinFunctionOld(ExecutionContext *scope, String *name, Value (*code)(SimpleCallContext *));
+struct BuiltinFunction: FunctionObject {
+ Q_MANAGED
+ ReturnedValue (*code)(SimpleCallContext *);
- static Value construct(Managed *, CallData *);
- static Value call(Managed *that, CallData *callData);
+ BuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *));
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *, CallData *);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct IndexedBuiltinFunction: FunctionObject
{
Q_MANAGED
- Value (*code)(SimpleCallContext *ctx, uint index);
+ ReturnedValue (*code)(SimpleCallContext *ctx, uint index);
uint index;
- IndexedBuiltinFunction(ExecutionContext *scope, uint index, Value (*code)(SimpleCallContext *ctx, uint index))
+ IndexedBuiltinFunction(ExecutionContext *scope, uint index, ReturnedValue (*code)(SimpleCallContext *ctx, uint index))
: FunctionObject(scope, /*name*/0)
, code(code)
, index(index)
@@ -188,37 +188,34 @@ struct IndexedBuiltinFunction: FunctionObject
isBuiltinFunction = true;
}
- static Value construct(Managed *m, CallData *)
+ static ReturnedValue construct(Managed *m, CallData *)
{
m->engine()->current->throwTypeError();
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
- static Value call(Managed *that, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct ScriptFunction: FunctionObject {
+ Q_MANAGED
ScriptFunction(ExecutionContext *scope, Function *function);
- static Value construct(Managed *, CallData *callData);
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct SimpleScriptFunction: FunctionObject {
+ Q_MANAGED
SimpleScriptFunction(ExecutionContext *scope, Function *function);
- static Value construct(Managed *, CallData *callData);
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct BoundFunction: FunctionObject {
+ Q_MANAGED
FunctionObject *target;
Value boundThis;
QVector<Value> boundArgs;
@@ -227,10 +224,9 @@ struct BoundFunction: FunctionObject {
~BoundFunction() {}
- static Value construct(Managed *, CallData *d);
- static Value call(Managed *that, CallData *dd);
+ static ReturnedValue construct(Managed *, CallData *d);
+ static ReturnedValue call(Managed *that, CallData *dd);
- static const ManagedVTable static_vtbl;
static void destroy(Managed *);
static void markObjects(Managed *that);
static bool hasInstance(Managed *that, const Value &value);
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 4f70275c25..f610811ddf 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -98,6 +98,12 @@ struct Lookup;
struct ExecutionEngine;
struct QObjectWrapper;
+// ReturnedValue is used to return values from runtime methods
+// the type has to be a primitive type (no struct or union), so that the compiler
+// will return it in a register on all platforms.
+// It will be returned in rax on x64, [eax,edx] on x86 and [r0,r1] on arm
+typedef quint64 ReturnedValue;
+
namespace Global {
enum {
ReservedArgumentCount = 6
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 9764a7930f..e0cbee11ca 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -354,14 +354,15 @@ EvalFunction::EvalFunction(ExecutionContext *scope)
defineReadonlyProperty(scope->engine->id_length, Value::fromInt32(1));
}
-Value EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc, bool directCall)
+ReturnedValue EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc, bool directCall)
{
if (argc < 1)
- return Value::undefinedValue();
+ return Encode::undefined();
ExecutionContext *parentContext = engine()->current;
ExecutionEngine *engine = parentContext->engine;
ExecutionContext *ctx = parentContext;
+ Scope scope(ctx);
if (!directCall) {
// the context for eval should be the global scope, so we fake a root
@@ -370,7 +371,7 @@ Value EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc, bool d
}
if (!args[0].isString())
- return args[0];
+ return args[0].asReturnedValue();
const QString code = args[0].stringValue()->toQString();
bool inheritContext = !ctx->strictMode;
@@ -382,7 +383,7 @@ Value EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc, bool d
Function *function = script.function();
if (!function)
- return Value::undefinedValue();
+ return Encode::undefined();
strictMode = function->isStrict() || (ctx->strictMode);
@@ -391,7 +392,7 @@ Value EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc, bool d
if (strictMode) {
FunctionObject *e = FunctionObject::creatScriptFunction(ctx, function);
- ScopedCallData callData(ctx->engine, 0);
+ ScopedCallData callData(scope, 0);
callData->thisObject = ctx->thisObject;
return e->call(callData);
}
@@ -412,7 +413,7 @@ Value EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc, bool d
ctx->compiledFunction = function->compiledFunction;
ctx->runtimeStrings = function->compilationUnit->runtimeStrings;
- Value result = Value::undefinedValue();
+ ScopedValue result(scope);
try {
result = function->code(ctx, function->codeData);
} catch (Exception &ex) {
@@ -435,11 +436,11 @@ Value EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc, bool d
while (engine->current != parentContext)
engine->popContext();
- return result;
+ return result.asReturnedValue();
}
-Value EvalFunction::call(Managed *that, CallData *callData)
+ReturnedValue EvalFunction::call(Managed *that, CallData *callData)
{
// indirect call
// ### const_cast
@@ -464,7 +465,7 @@ static inline int toInt(const QChar &qc, int R)
}
// parseInt [15.1.2.2]
-Value GlobalFunctions::method_parseInt(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_parseInt(SimpleCallContext *context)
{
Value string = context->argument(0);
Value radix = context->argument(1);
@@ -486,7 +487,7 @@ Value GlobalFunctions::method_parseInt(SimpleCallContext *context)
bool stripPrefix = true; // 7
if (R) { // 8
if (R < 2 || R > 36)
- return Value::fromDouble(std::numeric_limits<double>::quiet_NaN()); // 8a
+ return Encode(std::numeric_limits<double>::quiet_NaN()); // 8a
if (R != 16)
stripPrefix = false; // 8b
} else { // 9
@@ -503,13 +504,13 @@ Value GlobalFunctions::method_parseInt(SimpleCallContext *context)
// 11: Z is progressively built below
// 13: this is handled by the toInt function
if (pos == end) // 12
- return Value::fromDouble(std::numeric_limits<double>::quiet_NaN());
+ return Encode(std::numeric_limits<double>::quiet_NaN());
bool overflow = false;
qint64 v_overflow;
unsigned overflow_digit_count = 0;
int d = toInt(*pos++, R);
if (d == -1)
- return Value::fromDouble(std::numeric_limits<double>::quiet_NaN());
+ return Encode(std::numeric_limits<double>::quiet_NaN());
qint64 v = d;
while (pos != end) {
d = toInt(*pos++, R);
@@ -536,14 +537,14 @@ Value GlobalFunctions::method_parseInt(SimpleCallContext *context)
if (overflow) {
double result = (double) v_overflow * pow(R, overflow_digit_count);
result += v;
- return Value::fromDouble(sign * result);
+ return Encode(sign * result);
} else {
- return Value::fromDouble(sign * (double) v); // 15
+ return Encode(sign * (double) v); // 15
}
}
// parseFloat [15.1.2.3]
-Value GlobalFunctions::method_parseFloat(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_parseFloat(SimpleCallContext *context)
{
Value string = context->argument(0);
@@ -554,47 +555,47 @@ Value GlobalFunctions::method_parseFloat(SimpleCallContext *context)
// 4:
if (trimmed.startsWith(QLatin1String("Infinity"))
|| trimmed.startsWith(QLatin1String("+Infinity")))
- return Value::fromDouble(Q_INFINITY);
+ return Encode(Q_INFINITY);
if (trimmed.startsWith("-Infinity"))
- return Value::fromDouble(-Q_INFINITY);
+ return 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 Value::fromDouble(std::numeric_limits<double>::quiet_NaN()); // 3
+ return Encode(std::numeric_limits<double>::quiet_NaN()); // 3
else
- return Value::fromDouble(d);
+ return Encode(d);
}
/// isNaN [15.1.2.4]
-Value GlobalFunctions::method_isNaN(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_isNaN(SimpleCallContext *context)
{
const Value &v = context->argument(0);
if (v.integerCompatible())
- return Value::fromBoolean(false);
+ return Encode(false);
double d = v.toNumber();
- return Value::fromBoolean(std::isnan(d));
+ return Encode((bool)std::isnan(d));
}
/// isFinite [15.1.2.5]
-Value GlobalFunctions::method_isFinite(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_isFinite(SimpleCallContext *context)
{
const Value &v = context->argument(0);
if (v.integerCompatible())
- return Value::fromBoolean(true);
+ return Encode(true);
double d = v.toNumber();
- return Value::fromBoolean(std::isfinite(d));
+ return Encode((bool)std::isfinite(d));
}
/// decodeURI [15.1.3.1]
-Value GlobalFunctions::method_decodeURI(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_decodeURI(SimpleCallContext *context)
{
if (context->argumentCount == 0)
- return Value::undefinedValue();
+ return Encode::undefined();
QString uriString = context->arguments[0].toString(context)->toQString();
bool ok;
@@ -602,14 +603,14 @@ Value GlobalFunctions::method_decodeURI(SimpleCallContext *context)
if (!ok)
context->throwURIError(Value::fromString(context, QStringLiteral("malformed URI sequence")));
- return Value::fromString(context, out);
+ return Value::fromString(context, out).asReturnedValue();
}
/// decodeURIComponent [15.1.3.2]
-Value GlobalFunctions::method_decodeURIComponent(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_decodeURIComponent(SimpleCallContext *context)
{
if (context->argumentCount == 0)
- return Value::undefinedValue();
+ return Encode::undefined();
QString uriString = context->arguments[0].toString(context)->toQString();
bool ok;
@@ -617,14 +618,14 @@ Value GlobalFunctions::method_decodeURIComponent(SimpleCallContext *context)
if (!ok)
context->throwURIError(Value::fromString(context, QStringLiteral("malformed URI sequence")));
- return Value::fromString(context, out);
+ return Value::fromString(context, out).asReturnedValue();
}
/// encodeURI [15.1.3.3]
-Value GlobalFunctions::method_encodeURI(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_encodeURI(SimpleCallContext *context)
{
if (context->argumentCount == 0)
- return Value::undefinedValue();
+ return Encode::undefined();
QString uriString = context->arguments[0].toString(context)->toQString();
bool ok;
@@ -632,14 +633,14 @@ Value GlobalFunctions::method_encodeURI(SimpleCallContext *context)
if (!ok)
context->throwURIError(Value::fromString(context, QStringLiteral("malformed URI sequence")));
- return Value::fromString(context, out);
+ return Value::fromString(context, out).asReturnedValue();
}
/// encodeURIComponent [15.1.3.4]
-Value GlobalFunctions::method_encodeURIComponent(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_encodeURIComponent(SimpleCallContext *context)
{
if (context->argumentCount == 0)
- return Value::undefinedValue();
+ return Encode::undefined();
QString uriString = context->arguments[0].toString(context)->toQString();
bool ok;
@@ -647,23 +648,23 @@ Value GlobalFunctions::method_encodeURIComponent(SimpleCallContext *context)
if (!ok)
context->throwURIError(Value::fromString(context, QStringLiteral("malformed URI sequence")));
- return Value::fromString(context, out);
+ return Value::fromString(context, out).asReturnedValue();
}
-Value GlobalFunctions::method_escape(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_escape(SimpleCallContext *context)
{
if (!context->argumentCount)
- return Value::fromString(context, QStringLiteral("undefined"));
+ return Value::fromString(context, QStringLiteral("undefined")).asReturnedValue();
QString str = context->argument(0).toString(context)->toQString();
- return Value::fromString(context, escape(str));
+ return Value::fromString(context, escape(str)).asReturnedValue();
}
-Value GlobalFunctions::method_unescape(SimpleCallContext *context)
+ReturnedValue GlobalFunctions::method_unescape(SimpleCallContext *context)
{
if (!context->argumentCount)
- return Value::fromString(context, QStringLiteral("undefined"));
+ return Value::fromString(context, QStringLiteral("undefined")).asReturnedValue();
QString str = context->argument(0).toString(context)->toQString();
- return Value::fromString(context, unescape(str));
+ return Value::fromString(context, unescape(str)).asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h
index b777bf8915..90b3395baa 100644
--- a/src/qml/jsruntime/qv4globalobject_p.h
+++ b/src/qml/jsruntime/qv4globalobject_p.h
@@ -50,29 +50,27 @@ namespace QV4 {
struct Q_QML_EXPORT EvalFunction : FunctionObject
{
+ Q_MANAGED
EvalFunction(ExecutionContext *scope);
- Value evalCall(Value thisObject, Value *args, int argc, bool directCall);
+ ReturnedValue evalCall(Value thisObject, Value *args, int argc, bool directCall);
using Managed::construct;
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct GlobalFunctions
{
- static Value method_parseInt(SimpleCallContext *context);
- static Value method_parseFloat(SimpleCallContext *context);
- static Value method_isNaN(SimpleCallContext *context);
- static Value method_isFinite(SimpleCallContext *context);
- static Value method_decodeURI(SimpleCallContext *context);
- static Value method_decodeURIComponent(SimpleCallContext *context);
- static Value method_encodeURI(SimpleCallContext *context);
- static Value method_encodeURIComponent(SimpleCallContext *context);
- static Value method_escape(SimpleCallContext *context);
- static Value method_unescape(SimpleCallContext *context);
+ static ReturnedValue method_parseInt(SimpleCallContext *context);
+ static ReturnedValue method_parseFloat(SimpleCallContext *context);
+ static ReturnedValue method_isNaN(SimpleCallContext *context);
+ static ReturnedValue method_isFinite(SimpleCallContext *context);
+ static ReturnedValue method_decodeURI(SimpleCallContext *context);
+ static ReturnedValue method_decodeURIComponent(SimpleCallContext *context);
+ static ReturnedValue method_encodeURI(SimpleCallContext *context);
+ static ReturnedValue method_encodeURIComponent(SimpleCallContext *context);
+ static ReturnedValue method_escape(SimpleCallContext *context);
+ static ReturnedValue method_unescape(SimpleCallContext *context);
};
}
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 647cc7d2cb..740bb406f3 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -82,7 +82,7 @@ QV4Include::~QV4Include()
delete m_reply; m_reply = 0;
}
-QV4::Value QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status)
+QV4::ReturnedValue QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status)
{
// XXX It seems inefficient to create this object from scratch each time.
@@ -94,7 +94,7 @@ QV4::Value QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status)
o->put(v4->newString("status"), QV4::Value::fromInt32(status));
- return QV4::Value::fromObject(o);
+ return QV4::Value::fromObject(o).asReturnedValue();
}
void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
@@ -104,8 +104,9 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
return;
QV4::ExecutionContext *ctx = f->engine()->current;
+ QV4::Scope scope(ctx);
try {
- QV4::ScopedCallData callData(ctx->engine, 1);
+ QV4::ScopedCallData callData(scope, 1);
callData->thisObject = QV4::Value::fromObject(f->engine()->globalObject);
callData->args[0] = status;
f->call(callData);
@@ -114,9 +115,9 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
}
}
-QV4::Value QV4Include::result()
+QV4::ReturnedValue QV4Include::result()
{
- return m_resultObject.value();
+ return m_resultObject.value().asReturnedValue();
}
#define INCLUDE_MAXIMUM_REDIRECT_RECURSION 15
@@ -148,7 +149,8 @@ void QV4Include::finished()
QV4::Script script(v4, m_qmlglobal.value().asObject(), code, m_url.toString());
QV4::ExecutionContext *ctx = v4->current;
- QV4::Object *o = m_resultObject.value().asObject();
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> o(scope, m_resultObject.value());
try {
script.parse();
script.run();
@@ -156,7 +158,8 @@ void QV4Include::finished()
} catch (QV4::Exception &e) {
e.accept(ctx);
o->put(v4->newString("status"), QV4::Value::fromInt32(Exception));
- o->put(v4->newString("exception"), e.value());
+ QV4::ScopedValue ex(scope, e.value());
+ o->put(v4->newString("exception"), ex);
}
} else {
m_resultObject.value().asObject()->put(v4->newString("status"), QV4::Value::fromInt32(NetworkError));
@@ -171,19 +174,20 @@ void QV4Include::finished()
/*
Documented in qv8engine.cpp
*/
-QV4::Value QV4Include::include(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QV4Include::method_include(QV4::SimpleCallContext *ctx)
{
if (!ctx->argumentCount)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
QV4::ExecutionEngine *v4 = ctx->engine;
+ QV4::Scope scope(v4);
QV8Engine *engine = v4->v8Engine;
QQmlContextData *context = QV4::QmlContextWrapper::callingContext(v4);
if (!context || !context->isJSContext)
V4THROW_ERROR("Qt.include(): Can only be called from JavaScript files");
- QUrl url(ctx->engine->resolvedUrl(ctx->arguments[0].toQString()));
+ QUrl url(ctx->engine->resolvedUrl(ctx->arguments[0].toQStringNoThrow()));
QV4::Value callbackFunction = QV4::Value::undefinedValue();
if (ctx->argumentCount >= 2 && ctx->arguments[1].asFunctionObject())
@@ -191,12 +195,12 @@ QV4::Value QV4Include::include(QV4::SimpleCallContext *ctx)
QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
- QV4::Value result = QV4::Value::undefinedValue();
+ QV4::ScopedValue result(scope);
+ QV4::Scoped<QV4::Object> qmlcontextobject(scope, v4->qmlContextObject());
if (localFile.isEmpty()) {
-
QV4Include *i = new QV4Include(url, engine, context,
- QV4::Value::fromObject(v4->qmlContextObject()),
+ qmlcontextobject.asValue(),
callbackFunction);
result = i->result();
@@ -209,8 +213,7 @@ QV4::Value QV4Include::include(QV4::SimpleCallContext *ctx)
QString code = QString::fromUtf8(data);
QQmlScript::Parser::extractPragmas(code);
- QV4::Object *qmlglobal = v4->qmlContextObject();
- QV4::Script script(v4, qmlglobal, code, url.toString());
+ QV4::Script script(v4, qmlcontextobject.getPointer(), code, url.toString());
QV4::ExecutionContext *ctx = v4->current;
try {
@@ -220,7 +223,8 @@ QV4::Value QV4Include::include(QV4::SimpleCallContext *ctx)
} catch (QV4::Exception &e) {
e.accept(ctx);
result = resultValue(v4, Exception);
- result.asObject()->put(v4->newString("exception"), e.value());
+ QV4::ScopedValue ex(scope, e.value());
+ result->asObject()->put(v4->newString("exception"), ex);
}
} else {
result = resultValue(v4, NetworkError);
@@ -229,7 +233,7 @@ QV4::Value QV4Include::include(QV4::SimpleCallContext *ctx)
callback(callbackFunction, result);
}
- return result;
+ return result.asReturnedValue();
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index d6bbcd1a60..6e299bce91 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -78,9 +78,9 @@ public:
Exception = 3
};
- static QV4::Value include(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_include(QV4::SimpleCallContext *ctx);
-private slots:
+private Q_SLOTS:
void finished();
private:
@@ -88,9 +88,9 @@ private:
const QV4::Value &qmlglobal, const QV4::Value &callback);
~QV4Include();
- QV4::Value result();
+ QV4::ReturnedValue result();
- static QV4::Value resultValue(QV4::ExecutionEngine *v4, Status status = Loading);
+ static QV4::ReturnedValue resultValue(QV4::ExecutionEngine *v4, Status status = Loading);
static void callback(const QV4::Value &callback, const QV4::Value &status);
QV4::ExecutionEngine *v4;
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index ef1f500580..2bb755b537 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -77,8 +77,8 @@ private:
inline bool eatSpace();
inline QChar nextToken();
- Value parseObject();
- Value parseArray();
+ ReturnedValue parseObject();
+ ReturnedValue parseArray();
bool parseMember(Object *o);
bool parseString(QString *string);
bool parseValue(Value *val);
@@ -224,42 +224,42 @@ Value JsonParser::parse(QJsonParseError *error)
end-object
*/
-Value JsonParser::parseObject()
+ReturnedValue JsonParser::parseObject()
{
if (++nestingLevel > nestingLimit) {
lastError = QJsonParseError::DeepNesting;
- return Value::undefinedValue();
+ return Encode::undefined();
}
BEGIN << "parseObject pos=" << json;
+ Scope scope(context);
- Object *o = context->engine->newObject();
- Value objectVal = Value::fromObject(o);
+ Scoped<Object> o(scope, context->engine->newObject());
QChar token = nextToken();
while (token == Quote) {
- if (!parseMember(o))
- return Value::undefinedValue();
+ if (!parseMember(o.getPointer()))
+ return Encode::undefined();
token = nextToken();
if (token != ValueSeparator)
break;
token = nextToken();
if (token == EndObject) {
lastError = QJsonParseError::MissingObject;
- return Value::undefinedValue();
+ return Encode::undefined();
}
}
DEBUG << "end token=" << token;
if (token != EndObject) {
lastError = QJsonParseError::UnterminatedObject;
- return Value::undefinedValue();
+ return Encode::undefined();
}
END;
--nestingLevel;
- return objectVal;
+ return o.asReturnedValue();
}
/*
@@ -291,19 +291,20 @@ bool JsonParser::parseMember(Object *o)
/*
array = begin-array [ value *( value-separator value ) ] end-array
*/
-Value JsonParser::parseArray()
+ReturnedValue JsonParser::parseArray()
{
+ Scope scope(context);
BEGIN << "parseArray";
- ArrayObject *array = context->engine->newArrayObject();
+ Scoped<ArrayObject> array(scope, context->engine->newArrayObject());
if (++nestingLevel > nestingLimit) {
lastError = QJsonParseError::DeepNesting;
- return Value::undefinedValue();
+ return Encode::undefined();
}
if (!eatSpace()) {
lastError = QJsonParseError::UnterminatedArray;
- return Value::undefinedValue();
+ return Encode::undefined();
}
if (*json == EndArray) {
nextToken();
@@ -312,7 +313,7 @@ Value JsonParser::parseArray()
while (1) {
Value val;
if (!parseValue(&val))
- return Value::undefinedValue();
+ return Encode::undefined();
array->arraySet(index, val);
QChar token = nextToken();
if (token == EndArray)
@@ -322,7 +323,7 @@ Value JsonParser::parseArray()
lastError = QJsonParseError::UnterminatedArray;
else
lastError = QJsonParseError::MissingValueSeparator;
- return Value::undefinedValue();
+ return Encode::undefined();
}
++index;
}
@@ -332,7 +333,7 @@ Value JsonParser::parseArray()
END;
--nestingLevel;
- return Value::fromObject(array);
+ return array.asReturnedValue();
}
/*
@@ -401,7 +402,7 @@ bool JsonParser::parseValue(Value *val)
return true;
}
case BeginArray: {
- *val = parseArray();
+ *val = Value::fromReturnedValue(parseArray());
if (val->isUndefined())
return false;
DEBUG << "value: array";
@@ -409,7 +410,7 @@ bool JsonParser::parseValue(Value *val)
return true;
}
case BeginObject: {
- *val = parseObject();
+ *val = Value::fromReturnedValue(parseObject());
if (val->isUndefined())
return false;
DEBUG << "value: object";
@@ -698,15 +699,16 @@ static QString quote(const QString &str)
QString Stringify::Str(const QString &key, Value value)
{
+ Scope scope(ctx);
QString result;
if (Object *o = value.asObject()) {
- FunctionObject *toJSON = o->get(ctx->engine->newString(QStringLiteral("toJSON"))).asFunctionObject();
- if (toJSON) {
- ScopedCallData callData(ctx->engine, 1);
+ Scoped<FunctionObject> toJSON(scope, o->get(ctx->engine->newString(QStringLiteral("toJSON"))));
+ if (!!toJSON) {
+ ScopedCallData callData(scope, 1);
callData->thisObject = value;
callData->args[0] = Value::fromString(ctx, key);
- value = toJSON->call(callData);
+ value = Value::fromReturnedValue(toJSON->call(callData));
}
}
@@ -714,11 +716,11 @@ QString Stringify::Str(const QString &key, Value value)
Object *holder = ctx->engine->newObject();
Value holderValue = Value::fromObject(holder);
holder->put(ctx, QString(), value);
- ScopedCallData callData(ctx->engine, 2);
+ ScopedCallData callData(scope, 2);
callData->args[0] = Value::fromString(ctx, key);
callData->args[1] = value;
callData->thisObject = holderValue;
- value = replacerFunction->call(callData);
+ value = Value::fromReturnedValue(replacerFunction->call(callData));
}
if (Object *o = value.asObject()) {
@@ -772,6 +774,8 @@ QString Stringify::JO(Object *o)
if (stack.contains(o))
ctx->throwTypeError();
+ Scope scope(o->engine());
+
QString result;
stack.push(o);
QString stepback = indent;
@@ -780,13 +784,14 @@ QString Stringify::JO(Object *o)
QStringList partial;
if (propertyList.isEmpty()) {
ObjectIterator it(o, ObjectIterator::EnumerableOnly);
+ ScopedValue name(scope);
while (1) {
Value v;
- Value name = it.nextPropertyNameAsString(&v);
- if (name.isNull())
+ name = it.nextPropertyNameAsString(&v);
+ if (name->isNull())
break;
- QString key = name.toQString();
+ QString key = name->toQStringNoThrow();
QString member = makeMember(key, v);
if (!member.isEmpty())
partial += member;
@@ -794,7 +799,7 @@ QString Stringify::JO(Object *o)
} else {
for (int i = 0; i < propertyList.size(); ++i) {
bool exists;
- Value v = o->get(propertyList.at(i), &exists);
+ ScopedValue v(scope, o->get(propertyList.at(i), &exists));
if (!exists)
continue;
QString member = makeMember(propertyList.at(i)->toQString(), v);
@@ -822,6 +827,8 @@ QString Stringify::JA(ArrayObject *a)
if (stack.contains(a))
ctx->throwTypeError();
+ Scope scope(a->engine());
+
QString result;
stack.push(a);
QString stepback = indent;
@@ -829,9 +836,10 @@ QString Stringify::JA(ArrayObject *a)
QStringList partial;
uint len = a->arrayLength();
+ ScopedValue v(scope);
for (uint i = 0; i < len; ++i) {
bool exists;
- Value v = a->getIndexed(i, &exists);
+ v = a->getIndexed(i, &exists);
if (!exists) {
partial += QStringLiteral("null");
continue;
@@ -868,7 +876,7 @@ JsonObject::JsonObject(ExecutionContext *context)
}
-Value JsonObject::method_parse(SimpleCallContext *ctx)
+ReturnedValue JsonObject::method_parse(SimpleCallContext *ctx)
{
QString jtext = ctx->argument(0).toString(ctx)->toQString();
@@ -881,12 +889,12 @@ Value JsonObject::method_parse(SimpleCallContext *ctx)
ctx->throwSyntaxError("JSON.parse: Parse error");
}
- return result;
+ return result.asReturnedValue();
}
-Value JsonObject::method_stringify(SimpleCallContext *ctx)
+ReturnedValue JsonObject::method_stringify(SimpleCallContext *ctx)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
Stringify stringify(ctx);
@@ -924,28 +932,28 @@ Value JsonObject::method_stringify(SimpleCallContext *ctx)
QString result = stringify.Str(QString(), ctx->argument(0));
if (result.isEmpty())
- return Value::undefinedValue();
- return Value::fromString(ctx, result);
+ return Encode::undefined();
+ return Value::fromString(ctx, result).asReturnedValue();
}
-QV4::Value JsonObject::fromJsonValue(ExecutionEngine *engine, const QJsonValue &value)
+ReturnedValue JsonObject::fromJsonValue(ExecutionEngine *engine, const QJsonValue &value)
{
if (value.isString())
- return Value::fromString(engine->current, value.toString());
+ return Value::fromString(engine->current, value.toString()).asReturnedValue();
else if (value.isDouble())
- return Value::fromDouble(value.toDouble());
+ return Encode(value.toDouble());
else if (value.isBool())
- return Value::fromBoolean(value.toBool());
+ return Encode(value.toBool());
else if (value.isArray())
return fromJsonArray(engine, value.toArray());
else if (value.isObject())
return fromJsonObject(engine, value.toObject());
else if (value.isNull())
- return Value::nullValue();
+ return Encode::null();
else
- return Value::undefinedValue();
+ return Encode::undefined();
}
QJsonValue JsonObject::toJsonValue(const QV4::Value &value,
@@ -967,12 +975,13 @@ QJsonValue JsonObject::toJsonValue(const QV4::Value &value,
return QJsonValue(QJsonValue::Undefined);
}
-QV4::Value JsonObject::fromJsonObject(ExecutionEngine *engine, const QJsonObject &object)
+QV4::ReturnedValue JsonObject::fromJsonObject(ExecutionEngine *engine, const QJsonObject &object)
{
- Object *o = engine->newObject();
+ Scope scope(engine);
+ Scoped<Object> o(scope, Value::fromObject(engine->newObject()));
for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it)
- o->put(engine->newString(it.key()), fromJsonValue(engine, it.value()));
- return Value::fromObject(o);
+ o->put(engine->newString(it.key()), Value::fromReturnedValue(fromJsonValue(engine, it.value())));
+ return o.asReturnedValue();
}
QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects)
@@ -981,6 +990,8 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects
if (!o || o->asFunctionObject())
return result;
+ Scope scope(o->engine());
+
if (visitedObjects.contains(o)) {
// Avoid recursion.
// For compatibility with QVariant{List,Map} conversion, we return an
@@ -991,13 +1002,14 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects
visitedObjects.insert(o);
ObjectIterator it(o, ObjectIterator::EnumerableOnly);
+ ScopedValue name(scope);
while (1) {
Value v;
- Value name = it.nextPropertyNameAsString(&v);
- if (name.isNull())
+ name = it.nextPropertyNameAsString(&v);
+ if (name->isNull())
break;
- QString key = name.toQString();
+ QString key = name->toQStringNoThrow();
if (!v.asFunctionObject())
result.insert(key, toJsonValue(v, visitedObjects));
}
@@ -1007,16 +1019,17 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects
return result;
}
-QV4::Value JsonObject::fromJsonArray(ExecutionEngine *engine, const QJsonArray &array)
+QV4::ReturnedValue JsonObject::fromJsonArray(ExecutionEngine *engine, const QJsonArray &array)
{
+ Scope scope(engine);
int size = array.size();
- ArrayObject *a = engine->newArrayObject();
+ Scoped<ArrayObject> a(scope, engine->newArrayObject());
a->arrayReserve(size);
a->arrayDataLen = size;
for (int i = 0; i < size; i++)
- a->arrayData[i].value = fromJsonValue(engine, array.at(i));
+ a->arrayData[i].value = Value::fromReturnedValue(fromJsonValue(engine, array.at(i)));
a->setArrayLengthUnchecked(size);
- return Value::fromObject(a);
+ return a.asReturnedValue();
}
QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects)
@@ -1025,6 +1038,8 @@ QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects)
if (!a)
return result;
+ Scope scope(a->engine());
+
if (visitedObjects.contains(a)) {
// Avoid recursion.
// For compatibility with QVariant{List,Map} conversion, we return an
@@ -1034,10 +1049,11 @@ QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects)
visitedObjects.insert(a);
+ ScopedValue v(scope);
quint32 length = a->arrayLength();
for (quint32 i = 0; i < length; ++i) {
- Value v = a->getIndexed(i);
- result.append(toJsonValue(v.asFunctionObject() ? QV4::Value::nullValue() : v, visitedObjects));
+ v = a->getIndexed(i);
+ result.append(toJsonValue(v->asFunctionObject() ? QV4::Value::nullValue() : v, visitedObjects));
}
visitedObjects.remove(a);
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index ccd99d5488..821cffcc7c 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -56,12 +56,12 @@ private:
public:
JsonObject(ExecutionContext *context);
- static Value method_parse(SimpleCallContext *ctx);
- static Value method_stringify(SimpleCallContext *ctx);
+ static ReturnedValue method_parse(SimpleCallContext *ctx);
+ static ReturnedValue method_stringify(SimpleCallContext *ctx);
- static QV4::Value fromJsonValue(ExecutionEngine *engine, const QJsonValue &value);
- static QV4::Value fromJsonObject(ExecutionEngine *engine, const QJsonObject &object);
- static QV4::Value fromJsonArray(ExecutionEngine *engine, const QJsonArray &array);
+ static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value);
+ static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object);
+ static ReturnedValue fromJsonArray(ExecutionEngine *engine, const QJsonArray &array);
static inline QJsonValue toJsonValue(const QV4::Value &value)
{ V4ObjectSet visitedObjects; return toJsonValue(value, visitedObjects); }
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 2cffa55642..da078729e4 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -87,12 +87,10 @@ Property *Lookup::lookup(Object *obj, PropertyAttributes *attrs)
}
-void Lookup::getterGeneric(QV4::Lookup *l, QV4::Value *result, const QV4::Value &object)
+ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const QV4::Value &object)
{
- if (Object *o = object.asObject()) {
- o->getLookup(l, result);
- return;
- }
+ if (Object *o = object.asObject())
+ return o->getLookup(l);
ExecutionEngine *engine = l->name->engine();
Object *proto;
@@ -103,13 +101,13 @@ void Lookup::getterGeneric(QV4::Lookup *l, QV4::Value *result, const QV4::Value
case Value::Boolean_Type:
proto = engine->booleanClass->prototype;
break;
- case Value::String_Type:
+ case Value::Managed_Type:
+ Q_ASSERT(object.isString());
proto = engine->stringClass->prototype;
if (l->name == engine->id_length) {
// special case, as the property is on the object itself
l->getter = stringLengthGetter;
- stringLengthGetter(l, result, object);
- return;
+ return stringLengthGetter(l, object);
}
break;
case Value::Integer_Type:
@@ -127,119 +125,94 @@ void Lookup::getterGeneric(QV4::Lookup *l, QV4::Value *result, const QV4::Value
l->getter = Lookup::primitiveGetter0;
else if (l->level == 1)
l->getter = Lookup::primitiveGetter1;
- if (result)
- *result = p->value;
- return;
+ return p->value.asReturnedValue();
} else {
if (l->level == 0)
l->getter = Lookup::primitiveGetterAccessor0;
else if (l->level == 1)
l->getter = Lookup::primitiveGetterAccessor1;
- if (result)
- *result = p->value;
- Value res = proto->getValue(object, p, attrs);
- if (result)
- *result = res;
- return;
+ return proto->getValue(object, p, attrs);
}
}
- if (result)
- *result = Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
-void Lookup::getter0(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::getter0(Lookup *l, const Value &object)
{
if (Object *o = object.asObject()) {
- if (l->classList[0] == o->internalClass) {
- if (result)
- *result = o->memberData[l->index].value;
- return;
- }
+ if (l->classList[0] == o->internalClass)
+ return o->memberData[l->index].value.asReturnedValue();
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::getter1(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::getter1(Lookup *l, const Value &object)
{
if (Object *o = object.asObject()) {
if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass) {
- if (result)
- *result = o->prototype()->memberData[l->index].value;
- return;
- }
+ l->classList[1] == o->prototype()->internalClass)
+ return o->prototype()->memberData[l->index].value.asReturnedValue();
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::getter2(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::getter2(Lookup *l, const Value &object)
{
if (Object *o = object.asObject()) {
if (l->classList[0] == o->internalClass) {
o = o->prototype();
if (l->classList[1] == o->internalClass) {
o = o->prototype();
- if (l->classList[2] == o->internalClass) {
- if (result)
- *result = o->memberData[l->index].value;
- return;
- }
+ if (l->classList[2] == o->internalClass)
+ return o->memberData[l->index].value.asReturnedValue();
}
}
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::getterAccessor0(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::getterAccessor0(Lookup *l, const Value &object)
{
if (Object *o = object.asObject()) {
if (l->classList[0] == o->internalClass) {
- Value res;
+ Scope scope(o->engine());
FunctionObject *getter = o->memberData[l->index].getter();
- if (!getter) {
- res = Value::undefinedValue();
- } else {
- ScopedCallData callData(o->engine(), 0);
- callData->thisObject = object;
- res = getter->call(callData);
- }
- if (result)
- *result = res;
- return;
+ if (!getter)
+ return Value::undefinedValue().asReturnedValue();
+
+ ScopedCallData callData(scope, 0);
+ callData->thisObject = object;
+ return getter->call(callData);
}
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::getterAccessor1(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::getterAccessor1(Lookup *l, const Value &object)
{
if (Object *o = object.asObject()) {
if (l->classList[0] == o->internalClass &&
l->classList[1] == o->prototype()->internalClass) {
- Value res;
+ Scope scope(o->engine());
FunctionObject *getter = o->prototype()->memberData[l->index].getter();
- if (!getter) {
- res = Value::undefinedValue();
- } else {
- ScopedCallData callData(o->engine(), 0);
- callData->thisObject = object;
- res = getter->call(callData);
- }
- if (result)
- *result = res;
- return;
+ if (!getter)
+ return Value::undefinedValue().asReturnedValue();
+
+ ScopedCallData callData(scope, 0);
+ callData->thisObject = object;
+ return getter->call(callData);
}
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::getterAccessor2(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::getterAccessor2(Lookup *l, const Value &object)
{
if (Object *o = object.asObject()) {
if (l->classList[0] == o->internalClass) {
@@ -247,116 +220,98 @@ void Lookup::getterAccessor2(Lookup *l, Value *result, const Value &object)
if (l->classList[1] == o->internalClass) {
o = o->prototype();
if (l->classList[2] == o->internalClass) {
- Value res;
+ Scope scope(o->engine());
FunctionObject *getter = o->memberData[l->index].getter();
- if (!getter) {
- res = Value::undefinedValue();
- } else {
- ScopedCallData callData(o->engine(), 0);
- callData->thisObject = object;
- res = getter->call(callData);
- }
- if (result)
- *result = res;
- return;
+ if (!getter)
+ return Value::undefinedValue().asReturnedValue();
+
+ ScopedCallData callData(scope, 0);
+ callData->thisObject = object;
+ return getter->call(callData);
}
}
}
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::primitiveGetter0(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::primitiveGetter0(Lookup *l, const Value &object)
{
if (object.type() == l->type) {
Object *o = l->proto;
- if (l->classList[0] == o->internalClass) {
- if (result)
- *result = o->memberData[l->index].value;
- return;
- }
+ if (l->classList[0] == o->internalClass)
+ return o->memberData[l->index].value.asReturnedValue();
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::primitiveGetter1(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::primitiveGetter1(Lookup *l, const Value &object)
{
if (object.type() == l->type) {
Object *o = l->proto;
if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass) {
- if (result)
- *result = o->prototype()->memberData[l->index].value;
- return;
- }
+ l->classList[1] == o->prototype()->internalClass)
+ return o->prototype()->memberData[l->index].value.asReturnedValue();
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::primitiveGetterAccessor0(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, const Value &object)
{
if (object.type() == l->type) {
Object *o = l->proto;
if (l->classList[0] == o->internalClass) {
+ Scope scope(o->engine());
Value res;
FunctionObject *getter = o->memberData[l->index].getter();
- if (!getter) {
- res = Value::undefinedValue();
- } else {
- ScopedCallData callData(o->engine(), 0);
- callData->thisObject = object;
- res = getter->call(callData);
- }
- if (result)
- *result = res;
- return;
+ if (!getter)
+ return Value::undefinedValue().asReturnedValue();
+
+ ScopedCallData callData(scope, 0);
+ callData->thisObject = object;
+ return getter->call(callData);
}
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::primitiveGetterAccessor1(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, const Value &object)
{
if (object.type() == l->type) {
Object *o = l->proto;
if (l->classList[0] == o->internalClass &&
l->classList[1] == o->prototype()->internalClass) {
+ Scope scope(o->engine());
Value res;
FunctionObject *getter = o->prototype()->memberData[l->index].getter();
- if (!getter) {
- res = Value::undefinedValue();
- } else {
- ScopedCallData callData(o->engine(), 0);
- callData->thisObject = object;
- res = getter->call(callData);
- }
- if (result)
- *result = res;
- return;
+ if (!getter)
+ return Value::undefinedValue().asReturnedValue();
+
+ ScopedCallData callData(scope, 0);
+ callData->thisObject = object;
+ return getter->call(callData);
}
}
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::stringLengthGetter(Lookup *l, Value *result, const Value &object)
+ReturnedValue Lookup::stringLengthGetter(Lookup *l, const Value &object)
{
- if (String *s = object.asString()) {
- if (result)
- *result = Value::fromUInt32(s->length());
- return;
- }
+ if (String *s = object.asString())
+ return Value::fromUInt32(s->length()).asReturnedValue();
+
l->getter = getterGeneric;
- getterGeneric(l, result, object);
+ return getterGeneric(l, object);
}
-void Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx, Value *result)
+ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->engine->globalObject;
PropertyAttributes attrs;
@@ -369,8 +324,7 @@ void Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx, Value *result
l->globalGetter = globalGetter1;
else if (l->level == 2)
l->globalGetter = globalGetter2;
- *result = p->value;
- return;
+ return p->value.asReturnedValue();
} else {
if (l->level == 0)
l->globalGetter = globalGetterAccessor0;
@@ -378,39 +332,36 @@ void Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx, Value *result
l->globalGetter = globalGetterAccessor1;
else if (l->level == 2)
l->globalGetter = globalGetterAccessor2;
- Value res = o->getValue(p, attrs);
- if (result)
- *result = res;
- return;
+ return o->getValue(p, attrs);
}
}
- ctx->throwReferenceError(Value::fromString(l->name));
+ Scope scope(ctx);
+ Scoped<String> n(scope, l->name);
+ ctx->throwReferenceError(n);
}
-void Lookup::globalGetter0(Lookup *l, ExecutionContext *ctx, Value *result)
+ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->engine->globalObject;
- if (l->classList[0] == o->internalClass) {
- *result = o->memberData[l->index].value;
- return;
- }
+ if (l->classList[0] == o->internalClass)
+ return o->memberData[l->index].value.asReturnedValue();
+
l->globalGetter = globalGetterGeneric;
- globalGetterGeneric(l, ctx, result);
+ return globalGetterGeneric(l, ctx);
}
-void Lookup::globalGetter1(Lookup *l, ExecutionContext *ctx, Value *result)
+ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->engine->globalObject;
if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass) {
- *result = o->prototype()->memberData[l->index].value;
- return;
- }
+ l->classList[1] == o->prototype()->internalClass)
+ return o->prototype()->memberData[l->index].value.asReturnedValue();
+
l->globalGetter = globalGetterGeneric;
- globalGetterGeneric(l, ctx, result);
+ return globalGetterGeneric(l, ctx);
}
-void Lookup::globalGetter2(Lookup *l, ExecutionContext *ctx, Value *result)
+ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->engine->globalObject;
if (l->classList[0] == o->internalClass) {
@@ -418,53 +369,50 @@ void Lookup::globalGetter2(Lookup *l, ExecutionContext *ctx, Value *result)
if (l->classList[1] == o->internalClass) {
o = o->prototype();
if (l->classList[2] == o->internalClass) {
- *result = o->prototype()->memberData[l->index].value;
- return;
+ return o->prototype()->memberData[l->index].value.asReturnedValue();
}
}
}
l->globalGetter = globalGetterGeneric;
- globalGetterGeneric(l, ctx, result);
+ return globalGetterGeneric(l, ctx);
}
-void Lookup::globalGetterAccessor0(Lookup *l, ExecutionContext *ctx, Value *result)
+ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->engine->globalObject;
if (l->classList[0] == o->internalClass) {
+ Scope scope(o->engine());
FunctionObject *getter = o->memberData[l->index].getter();
- if (!getter) {
- *result = Value::undefinedValue();
- } else {
- ScopedCallData callData(ctx->engine, 0);
- callData->thisObject = Value::undefinedValue();
- *result = getter->call(callData);
- }
- return;
+ if (!getter)
+ return Value::undefinedValue().asReturnedValue();
+
+ ScopedCallData callData(scope, 0);
+ callData->thisObject = Value::undefinedValue();
+ return getter->call(callData);
}
l->globalGetter = globalGetterGeneric;
- globalGetterGeneric(l, ctx, result);
+ return globalGetterGeneric(l, ctx);
}
-void Lookup::globalGetterAccessor1(Lookup *l, ExecutionContext *ctx, Value *result)
+ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->engine->globalObject;
if (l->classList[0] == o->internalClass &&
l->classList[1] == o->prototype()->internalClass) {
+ Scope scope(o->engine());
FunctionObject *getter = o->prototype()->memberData[l->index].getter();
- if (!getter) {
- *result = Value::undefinedValue();
- } else {
- ScopedCallData callData(ctx->engine, 0);
- callData->thisObject = Value::undefinedValue();
- *result = getter->call(callData);
- }
- return;
+ if (!getter)
+ return Value::undefinedValue().asReturnedValue();
+
+ ScopedCallData callData(scope, 0);
+ callData->thisObject = Value::undefinedValue();
+ return getter->call(callData);
}
l->globalGetter = globalGetterGeneric;
- globalGetterGeneric(l, ctx, result);
+ return globalGetterGeneric(l, ctx);
}
-void Lookup::globalGetterAccessor2(Lookup *l, ExecutionContext *ctx, Value *result)
+ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->engine->globalObject;
if (l->classList[0] == o->internalClass) {
@@ -472,27 +420,26 @@ void Lookup::globalGetterAccessor2(Lookup *l, ExecutionContext *ctx, Value *resu
if (l->classList[1] == o->internalClass) {
o = o->prototype();
if (l->classList[2] == o->internalClass) {
+ Scope scope(o->engine());
FunctionObject *getter = o->memberData[l->index].getter();
- if (!getter) {
- *result = Value::undefinedValue();
- } else {
- ScopedCallData callData(ctx->engine, 0);
- callData->thisObject = Value::undefinedValue();
- *result = getter->call(callData);
- }
- return;
+ if (!getter)
+ return Value::undefinedValue().asReturnedValue();
+
+ ScopedCallData callData(scope, 0);
+ callData->thisObject = Value::undefinedValue();
+ return getter->call(callData);
}
}
}
l->globalGetter = globalGetterGeneric;
- globalGetterGeneric(l, ctx, result);
+ return globalGetterGeneric(l, ctx);
}
void Lookup::setterGeneric(Lookup *l, const Value &object, const Value &value)
{
Object *o = object.asObject();
if (!o) {
- o = __qmljs_convert_to_object(l->name->engine()->current, ValueRef::fromRawValue(&object));
+ o = __qmljs_convert_to_object(l->name->engine()->current, ValueRef::fromRawValue(&object))->getPointer();
o->put(l->name, value);
return;
}
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index b37738dd92..b79e91028f 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -55,8 +55,8 @@ namespace QV4 {
struct Lookup {
enum { Size = 4 };
union {
- void (*getter)(Lookup *l, Value *result, const Value &object);
- void (*globalGetter)(Lookup *l, ExecutionContext *ctx, Value *result);
+ ReturnedValue (*getter)(Lookup *l, const Value &object);
+ ReturnedValue (*globalGetter)(Lookup *l, ExecutionContext *ctx);
void (*setter)(Lookup *l, const Value &object, const Value &v);
};
union {
@@ -72,27 +72,27 @@ struct Lookup {
uint index;
String *name;
- static void getterGeneric(Lookup *l, Value *result, const Value &object);
- static void getter0(Lookup *l, Value *result, const Value &object);
- static void getter1(Lookup *l, Value *result, const Value &object);
- static void getter2(Lookup *l, Value *result, const Value &object);
- static void getterAccessor0(Lookup *l, Value *result, const Value &object);
- static void getterAccessor1(Lookup *l, Value *result, const Value &object);
- static void getterAccessor2(Lookup *l, Value *result, const Value &object);
+ static ReturnedValue getterGeneric(Lookup *l, const Value &object);
+ static ReturnedValue getter0(Lookup *l, const Value &object);
+ static ReturnedValue getter1(Lookup *l, const Value &object);
+ static ReturnedValue getter2(Lookup *l, const Value &object);
+ static ReturnedValue getterAccessor0(Lookup *l, const Value &object);
+ static ReturnedValue getterAccessor1(Lookup *l, const Value &object);
+ static ReturnedValue getterAccessor2(Lookup *l, const Value &object);
- static void primitiveGetter0(Lookup *l, Value *result, const Value &object);
- static void primitiveGetter1(Lookup *l, Value *result, const Value &object);
- static void primitiveGetterAccessor0(Lookup *l, Value *result, const Value &object);
- static void primitiveGetterAccessor1(Lookup *l, Value *result, const Value &object);
- static void stringLengthGetter(Lookup *l, Value *result, const Value &object);
+ static ReturnedValue primitiveGetter0(Lookup *l, const Value &object);
+ static ReturnedValue primitiveGetter1(Lookup *l, const Value &object);
+ static ReturnedValue primitiveGetterAccessor0(Lookup *l, const Value &object);
+ static ReturnedValue primitiveGetterAccessor1(Lookup *l, const Value &object);
+ static ReturnedValue stringLengthGetter(Lookup *l, const Value &object);
- static void globalGetterGeneric(Lookup *l, ExecutionContext *ctx, Value *result);
- static void globalGetter0(Lookup *l, ExecutionContext *ctx, Value *result);
- static void globalGetter1(Lookup *l, ExecutionContext *ctx, Value *result);
- static void globalGetter2(Lookup *l, ExecutionContext *ctx, Value *result);
- static void globalGetterAccessor0(Lookup *l, ExecutionContext *ctx, Value *result);
- static void globalGetterAccessor1(Lookup *l, ExecutionContext *ctx, Value *result);
- static void globalGetterAccessor2(Lookup *l, ExecutionContext *ctx, Value *result);
+ static ReturnedValue globalGetterGeneric(Lookup *l, ExecutionContext *ctx);
+ static ReturnedValue globalGetter0(Lookup *l, ExecutionContext *ctx);
+ static ReturnedValue globalGetter1(Lookup *l, ExecutionContext *ctx);
+ static ReturnedValue globalGetter2(Lookup *l, ExecutionContext *ctx);
+ static ReturnedValue globalGetterAccessor0(Lookup *l, ExecutionContext *ctx);
+ static ReturnedValue globalGetterAccessor1(Lookup *l, ExecutionContext *ctx);
+ static ReturnedValue globalGetterAccessor2(Lookup *l, ExecutionContext *ctx);
static void setterGeneric(Lookup *l, const Value &object, const Value &value);
static void setter0(Lookup *l, const Value &object, const Value &value);
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index 62491ba7e5..4404f909b6 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -176,19 +176,20 @@ bool Managed::hasInstance(Managed *m, const Value &)
m->engine()->current->throwTypeError();
}
-Value Managed::construct(Managed *m, CallData *)
+ReturnedValue Managed::construct(Managed *m, CallData *)
{
m->engine()->current->throwTypeError();
}
-Value Managed::call(Managed *m, CallData *)
+ReturnedValue Managed::call(Managed *m, CallData *)
{
m->engine()->current->throwTypeError();
}
-void Managed::getLookup(Managed *m, Lookup *, Value *)
+ReturnedValue Managed::getLookup(Managed *m, Lookup *)
{
m->engine()->current->throwTypeError();
+ return 0;
}
void Managed::setLookup(Managed *m, Lookup *, const Value &)
@@ -201,12 +202,12 @@ bool Managed::isEqualTo(Managed *, Managed *)
return false;
}
-Value Managed::get(String *name, bool *hasProperty)
+ReturnedValue Managed::get(String *name, bool *hasProperty)
{
return vtbl->get(this, name, hasProperty);
}
-Value Managed::getIndexed(uint index, bool *hasProperty)
+ReturnedValue Managed::getIndexed(uint index, bool *hasProperty)
{
return vtbl->getIndexed(this, index, hasProperty);
}
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 50325478f5..f13f699748 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -61,10 +61,25 @@ inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; }
template <typename T1, typename T2>
inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
+template <typename T>
+struct Returned : private T
+{
+ static Returned<T> *create(T *t) { return static_cast<Returned<T> *>(t); }
+ T *getPointer() { return this; }
+ template<typename X>
+ static T *getPointer(Returned<X> *x) { return x->getPointer(); }
+ template<typename X>
+ Returned<X> *as() { return Returned<X>::create(Returned<X>::getPointer(this)); }
+ using T::asReturnedValue;
+};
+
#define Q_MANAGED \
public: \
Q_MANAGED_CHECK \
- static const QV4::ManagedVTable static_vtbl;
+ static const QV4::ManagedVTable static_vtbl; \
+ template <typename T> \
+ QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+
struct GCDeletable
{
@@ -91,21 +106,21 @@ struct CallData
struct ManagedVTable
{
- Value (*call)(Managed *, CallData *data);
- Value (*construct)(Managed *, CallData *data);
+ ReturnedValue (*call)(Managed *, CallData *data);
+ ReturnedValue (*construct)(Managed *, CallData *data);
void (*markObjects)(Managed *);
void (*destroy)(Managed *);
void (*collectDeletables)(Managed *, GCDeletable **deletable);
bool (*hasInstance)(Managed *, const Value &value);
- Value (*get)(Managed *, String *name, bool *hasProperty);
- Value (*getIndexed)(Managed *, uint index, bool *hasProperty);
+ ReturnedValue (*get)(Managed *, String *name, bool *hasProperty);
+ ReturnedValue (*getIndexed)(Managed *, uint index, bool *hasProperty);
void (*put)(Managed *, String *name, const Value &value);
void (*putIndexed)(Managed *, uint index, const Value &value);
PropertyAttributes (*query)(const Managed *, String *name);
PropertyAttributes (*queryIndexed)(const Managed *, uint index);
bool (*deleteProperty)(Managed *m, String *name);
bool (*deleteIndexedProperty)(Managed *m, uint index);
- void (*getLookup)(Managed *m, Lookup *l, Value *result);
+ ReturnedValue (*getLookup)(Managed *m, Lookup *l);
void (*setLookup)(Managed *m, Lookup *l, const Value &v);
bool (*isEqualTo)(Managed *m, Managed *other);
Property *(*advanceIterator)(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
@@ -162,6 +177,7 @@ const QV4::ManagedVTable classname::static_vtbl = \
struct Q_QML_EXPORT Managed
{
+ Q_MANAGED
private:
void *operator new(size_t);
Managed(const Managed &other);
@@ -210,6 +226,9 @@ public:
template <typename T>
T *as() {
+ // ### FIXME:
+ if (!this)
+ return 0;
#if !defined(QT_NO_QOBJECT_CHECK)
reinterpret_cast<T *>(this)->qt_check_for_QMANAGED_macro(*reinterpret_cast<T *>(this));
#endif
@@ -217,12 +236,23 @@ public:
}
template <typename T>
const T *as() const {
+ // ### FIXME:
+ if (!this)
+ return 0;
#if !defined(QT_NO_QOBJECT_CHECK)
reinterpret_cast<T *>(this)->qt_check_for_QMANAGED_macro(*reinterpret_cast<T *>(const_cast<Managed *>(this)));
#endif
return vtbl == &T::static_vtbl ? static_cast<const T *>(this) : 0;
}
+ template<typename T>
+ static T *cast(const Value &v) {
+ return v.as<T>();
+ }
+ static Managed *cast(const Value &v) {
+ return v.asManaged();
+ }
+
ArrayObject *asArrayObject() { return type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
FunctionObject *asFunctionObject() { return type == Type_FunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
BooleanObject *asBooleanObject() { return type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
@@ -252,10 +282,10 @@ public:
inline bool hasInstance(const Value &v) {
return vtbl->hasInstance(this, v);
}
- Value construct(CallData *d);
- Value call(CallData *d);
- Value get(String *name, bool *hasProperty = 0);
- Value getIndexed(uint index, bool *hasProperty = 0);
+ ReturnedValue construct(CallData *d);
+ ReturnedValue call(CallData *d);
+ ReturnedValue get(String *name, bool *hasProperty = 0);
+ ReturnedValue getIndexed(uint index, bool *hasProperty = 0);
void put(String *name, const Value &value)
{ vtbl->put(this, name, value); }
void putIndexed(uint index, const Value &value)
@@ -269,8 +299,8 @@ public:
{ return vtbl->deleteProperty(this, name); }
bool deleteIndexedProperty(uint index)
{ return vtbl->deleteIndexedProperty(this, index); }
- void getLookup(Lookup *l, Value *result)
- { vtbl->getLookup(this, l, result); }
+ ReturnedValue getLookup(Lookup *l)
+ { return vtbl->getLookup(this, l); }
void setLookup(Lookup *l, const Value &v)
{ vtbl->setLookup(this, l, v); }
@@ -281,9 +311,9 @@ public:
static void destroy(Managed *that) { that->_data = 0; }
static bool hasInstance(Managed *that, const Value &value);
- static Value construct(Managed *m, CallData *d);
- static Value call(Managed *m, CallData *);
- static void getLookup(Managed *m, Lookup *, Value *);
+ static ReturnedValue construct(Managed *m, CallData *d);
+ static ReturnedValue call(Managed *m, CallData *);
+ static ReturnedValue getLookup(Managed *m, Lookup *);
static void setLookup(Managed *m, Lookup *l, const Value &v);
static bool isEqualTo(Managed *m, Managed *other);
@@ -291,6 +321,8 @@ public:
return type;
}
+ ReturnedValue asReturnedValue() { return Value::fromManaged(this).asReturnedValue(); }
+
union {
uint _data;
struct {
@@ -311,9 +343,6 @@ public:
};
protected:
-
- static const ManagedVTable static_vtbl;
-
const ManagedVTable *vtbl;
public:
InternalClass *internalClass;
@@ -324,10 +353,12 @@ private:
friend struct ObjectIterator;
};
-// ### Not a good placement
-template<typename T>
-inline T *Value::as() const { Managed *m = isObject() ? managed() : 0; return m ? m->as<T>() : 0; }
-
+inline ReturnedValue Managed::construct(CallData *d) {
+ return vtbl->construct(this, d);
+}
+inline ReturnedValue Managed::call(CallData *d) {
+ return vtbl->call(this, d);
+}
}
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index 0e7b32d429..cf2d5afd3f 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -96,112 +96,112 @@ static double copySign(double x, double y)
return x;
}
-Value MathObject::method_abs(SimpleCallContext *context)
+ReturnedValue MathObject::method_abs(SimpleCallContext *context)
{
if (!context->argumentCount)
- return Value::fromDouble(qSNaN());
+ return Encode(qSNaN());
if (context->arguments[0].isInteger()) {
int i = context->arguments[0].integerValue();
- return Value::fromInt32(i < 0 ? - i : i);
+ return Encode(i < 0 ? - i : i);
}
double v = context->arguments[0].toNumber();
if (v == 0) // 0 | -0
- return Value::fromDouble(0);
+ return Encode(0);
- return Value::fromDouble(v < 0 ? -v : v);
+ return Encode(v < 0 ? -v : v);
}
-Value MathObject::method_acos(SimpleCallContext *context)
+ReturnedValue MathObject::method_acos(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : 2;
if (v > 1)
- return Value::fromDouble(qSNaN());
+ return Encode(qSNaN());
- return Value::fromDouble(::acos(v));
+ return Encode(::acos(v));
}
-Value MathObject::method_asin(SimpleCallContext *context)
+ReturnedValue MathObject::method_asin(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : 2;
if (v > 1)
- return Value::fromDouble(qSNaN());
+ return Encode(qSNaN());
else
- return Value::fromDouble(::asin(v));
+ return Encode(::asin(v));
}
-Value MathObject::method_atan(SimpleCallContext *context)
+ReturnedValue MathObject::method_atan(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
if (v == 0.0)
- return Value::fromDouble(v);
+ return Encode(v);
else
- return Value::fromDouble(::atan(v));
+ return Encode(::atan(v));
}
-Value MathObject::method_atan2(SimpleCallContext *context)
+ReturnedValue MathObject::method_atan2(SimpleCallContext *context)
{
double v1 = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
double v2 = context->argumentCount > 1 ? context->arguments[1].toNumber() : qSNaN();
if ((v1 < 0) && qIsFinite(v1) && qIsInf(v2) && (copySign(1.0, v2) == 1.0))
- return Value::fromDouble(copySign(0, -1.0));
+ return 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 Value::fromDouble(qt_PI);
+ return Encode(qt_PI);
} else if ((copySign(1.0, v1) == -1.0) && (copySign(1.0, v2) == -1.0)) {
- return Value::fromDouble(-qt_PI);
+ return Encode(-qt_PI);
}
}
- return Value::fromDouble(::atan2(v1, v2));
+ return Encode(::atan2(v1, v2));
}
-Value MathObject::method_ceil(SimpleCallContext *context)
+ReturnedValue MathObject::method_ceil(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
if (v < 0.0 && v > -1.0)
- return Value::fromDouble(copySign(0, -1.0));
+ return Encode(copySign(0, -1.0));
else
- return Value::fromDouble(::ceil(v));
+ return Encode(::ceil(v));
}
-Value MathObject::method_cos(SimpleCallContext *context)
+ReturnedValue MathObject::method_cos(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
- return Value::fromDouble(::cos(v));
+ return Encode(::cos(v));
}
-Value MathObject::method_exp(SimpleCallContext *context)
+ReturnedValue MathObject::method_exp(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
if (qIsInf(v)) {
if (copySign(1.0, v) == -1.0)
- return Value::fromDouble(0);
+ return Encode(0);
else
- return Value::fromDouble(qInf());
+ return Encode(qInf());
} else {
- return Value::fromDouble(::exp(v));
+ return Encode(::exp(v));
}
}
-Value MathObject::method_floor(SimpleCallContext *context)
+ReturnedValue MathObject::method_floor(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
- return Value::fromDouble(::floor(v));
+ return Encode(::floor(v));
}
-Value MathObject::method_log(SimpleCallContext *context)
+ReturnedValue MathObject::method_log(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
if (v < 0)
- return Value::fromDouble(qSNaN());
+ return Encode(qSNaN());
else
- return Value::fromDouble(::log(v));
+ return Encode(::log(v));
}
-Value MathObject::method_max(SimpleCallContext *context)
+ReturnedValue MathObject::method_max(SimpleCallContext *context)
{
double mx = -qInf();
for (unsigned i = 0; i < context->argumentCount; ++i) {
@@ -209,10 +209,10 @@ Value MathObject::method_max(SimpleCallContext *context)
if (x > mx || std::isnan(x))
mx = x;
}
- return Value::fromDouble(mx);
+ return Encode(mx);
}
-Value MathObject::method_min(SimpleCallContext *context)
+ReturnedValue MathObject::method_min(SimpleCallContext *context)
{
double mx = qInf();
for (unsigned i = 0; i < context->argumentCount; ++i) {
@@ -222,34 +222,34 @@ Value MathObject::method_min(SimpleCallContext *context)
mx = x;
}
}
- return Value::fromDouble(mx);
+ return Encode(mx);
}
-Value MathObject::method_pow(SimpleCallContext *context)
+ReturnedValue MathObject::method_pow(SimpleCallContext *context)
{
double x = context->argumentCount > 0 ? context->arguments[0].toNumber() : qSNaN();
double y = context->argumentCount > 1 ? context->arguments[1].toNumber() : qSNaN();
if (std::isnan(y))
- return Value::fromDouble(qSNaN());
+ return Encode(qSNaN());
if (y == 0) {
- return Value::fromDouble(1);
+ return Encode(1);
} else if (((x == 1) || (x == -1)) && std::isinf(y)) {
- return Value::fromDouble(qSNaN());
+ return Encode(qSNaN());
} else if (((x == 0) && copySign(1.0, x) == 1.0) && (y < 0)) {
- return Value::fromDouble(qInf());
+ return Encode(qInf());
} else if ((x == 0) && copySign(1.0, x) == -1.0) {
if (y < 0) {
if (::fmod(-y, 2.0) == 1.0)
- return Value::fromDouble(-qInf());
+ return Encode(-qInf());
else
- return Value::fromDouble(qInf());
+ return Encode(qInf());
} else if (y > 0) {
if (::fmod(y, 2.0) == 1.0)
- return Value::fromDouble(copySign(0, -1.0));
+ return Encode(copySign(0, -1.0));
else
- return Value::fromDouble(0);
+ return Encode(0);
}
}
@@ -257,54 +257,54 @@ Value MathObject::method_pow(SimpleCallContext *context)
else if (qIsInf(x) && copySign(1.0, x) == -1.0) {
if (y > 0) {
if (::fmod(y, 2.0) == 1.0)
- return Value::fromDouble(-qInf());
+ return Encode(-qInf());
else
- return Value::fromDouble(qInf());
+ return Encode(qInf());
} else if (y < 0) {
if (::fmod(-y, 2.0) == 1.0)
- return Value::fromDouble(copySign(0, -1.0));
+ return Encode(copySign(0, -1.0));
else
- return Value::fromDouble(0);
+ return Encode(0);
}
}
#endif
else {
- return Value::fromDouble(::pow(x, y));
+ return Encode(::pow(x, y));
}
// ###
- return Value::fromDouble(qSNaN());
+ return Encode(qSNaN());
}
-Value MathObject::method_random(SimpleCallContext *)
+ReturnedValue MathObject::method_random(SimpleCallContext *)
{
- return Value::fromDouble(qrand() / (double) RAND_MAX);
+ return Encode(qrand() / (double) RAND_MAX);
}
-Value MathObject::method_round(SimpleCallContext *context)
+ReturnedValue MathObject::method_round(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
v = copySign(::floor(v + 0.5), v);
- return Value::fromDouble(v);
+ return Encode(v);
}
-Value MathObject::method_sin(SimpleCallContext *context)
+ReturnedValue MathObject::method_sin(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
- return Value::fromDouble(::sin(v));
+ return Encode(::sin(v));
}
-Value MathObject::method_sqrt(SimpleCallContext *context)
+ReturnedValue MathObject::method_sqrt(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
- return Value::fromDouble(::sqrt(v));
+ return Encode(::sqrt(v));
}
-Value MathObject::method_tan(SimpleCallContext *context)
+ReturnedValue MathObject::method_tan(SimpleCallContext *context)
{
double v = context->argumentCount ? context->arguments[0].toNumber() : qSNaN();
if (v == 0.0)
- return Value::fromDouble(v);
+ return Encode(v);
else
- return Value::fromDouble(::tan(v));
+ return Encode(::tan(v));
}
diff --git a/src/qml/jsruntime/qv4mathobject_p.h b/src/qml/jsruntime/qv4mathobject_p.h
index 03c36bcc68..cdadc875f9 100644
--- a/src/qml/jsruntime/qv4mathobject_p.h
+++ b/src/qml/jsruntime/qv4mathobject_p.h
@@ -51,24 +51,24 @@ struct MathObject: Object
{
MathObject(ExecutionContext *ctx);
- static Value method_abs(SimpleCallContext *context);
- static Value method_acos(SimpleCallContext *context);
- static Value method_asin(SimpleCallContext *context);
- static Value method_atan(SimpleCallContext *context);
- static Value method_atan2(SimpleCallContext *context);
- static Value method_ceil(SimpleCallContext *context);
- static Value method_cos(SimpleCallContext *context);
- static Value method_exp(SimpleCallContext *context);
- static Value method_floor(SimpleCallContext *context);
- static Value method_log(SimpleCallContext *context);
- static Value method_max(SimpleCallContext *context);
- static Value method_min(SimpleCallContext *context);
- static Value method_pow(SimpleCallContext *context);
- static Value method_random(SimpleCallContext *context);
- static Value method_round(SimpleCallContext *context);
- static Value method_sin(SimpleCallContext *context);
- static Value method_sqrt(SimpleCallContext *context);
- static Value method_tan(SimpleCallContext *context);
+ static ReturnedValue method_abs(SimpleCallContext *context);
+ static ReturnedValue method_acos(SimpleCallContext *context);
+ static ReturnedValue method_asin(SimpleCallContext *context);
+ static ReturnedValue method_atan(SimpleCallContext *context);
+ static ReturnedValue method_atan2(SimpleCallContext *context);
+ static ReturnedValue method_ceil(SimpleCallContext *context);
+ static ReturnedValue method_cos(SimpleCallContext *context);
+ static ReturnedValue method_exp(SimpleCallContext *context);
+ static ReturnedValue method_floor(SimpleCallContext *context);
+ static ReturnedValue method_log(SimpleCallContext *context);
+ static ReturnedValue method_max(SimpleCallContext *context);
+ static ReturnedValue method_min(SimpleCallContext *context);
+ static ReturnedValue method_pow(SimpleCallContext *context);
+ static ReturnedValue method_random(SimpleCallContext *context);
+ static ReturnedValue method_round(SimpleCallContext *context);
+ static ReturnedValue method_sin(SimpleCallContext *context);
+ static ReturnedValue method_sqrt(SimpleCallContext *context);
+ static ReturnedValue method_tan(SimpleCallContext *context);
};
}
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index 874c349c42..2d53fa3fe5 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -55,6 +55,7 @@
#include <iostream>
#include <cstdlib>
+#include <algorithm>
#include "qv4alloca_p.h"
#ifdef V4_USE_VALGRIND
@@ -215,7 +216,7 @@ Managed *MemoryManager::alloc(std::size_t size)
allocation.memory = PageAllocation::allocate(allocSize, OSAllocator::JSGCHeapPages);
allocation.chunkSize = size;
m_d->heapChunks.append(allocation);
- qSort(m_d->heapChunks);
+ std::sort(m_d->heapChunks.begin(), m_d->heapChunks.end());
char *chunk = (char *)allocation.memory.base();
char *end = chunk + allocation.memory.size() - size;
memset(chunk, 0, allocation.memory.size());
@@ -581,7 +582,7 @@ void MemoryManager::collectFromStack() const
if (genericPtr < *heapChunkBoundaries || genericPtr > *(heapChunkBoundariesEnd - 1))
continue;
- int index = qLowerBound(heapChunkBoundaries, heapChunkBoundariesEnd, genericPtr) - heapChunkBoundaries;
+ int index = std::lower_bound(heapChunkBoundaries, heapChunkBoundariesEnd, genericPtr) - heapChunkBoundaries;
// An odd index means the pointer is _before_ the end of a heap chunk and therefore valid.
assert(index >= 0 && index < m_d->heapChunks.count() * 2);
if (index & 1) {
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index ffcbca2ce5..3702428553 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -56,16 +56,16 @@ NumberCtor::NumberCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value NumberCtor::construct(Managed *m, CallData *callData)
+ReturnedValue NumberCtor::construct(Managed *m, CallData *callData)
{
double dbl = callData->argc ? callData->args[0].toNumber() : 0.;
- return Value::fromObject(m->engine()->newNumberObject(Value::fromDouble(dbl)));
+ return Encode(m->engine()->newNumberObject(Value::fromDouble(dbl)));
}
-Value NumberCtor::call(Managed *, CallData *callData)
+ReturnedValue NumberCtor::call(Managed *, CallData *callData)
{
double dbl = callData->argc ? callData->args[0].toNumber() : 0.;
- return Value::fromDouble(dbl);
+ return Value::fromDouble(dbl).asReturnedValue();
}
void NumberPrototype::init(ExecutionContext *ctx, const Value &ctor)
@@ -106,7 +106,7 @@ inline Value thisNumberValue(ExecutionContext *ctx)
return n->value;
}
-Value NumberPrototype::method_toString(SimpleCallContext *ctx)
+ReturnedValue NumberPrototype::method_toString(SimpleCallContext *ctx)
{
double num = thisNumberValue(ctx).asDouble();
@@ -116,13 +116,13 @@ Value NumberPrototype::method_toString(SimpleCallContext *ctx)
if (radix < 2 || radix > 36) {
ctx->throwError(QString::fromLatin1("Number.prototype.toString: %0 is not a valid radix")
.arg(radix));
- return Value::undefinedValue();
+ return Encode::undefined();
}
if (std::isnan(num)) {
- return Value::fromString(ctx, QStringLiteral("NaN"));
+ return Value::fromString(ctx, QStringLiteral("NaN")).asReturnedValue();
} else if (qIsInf(num)) {
- return Value::fromString(ctx, QLatin1String(num < 0 ? "-Infinity" : "Infinity"));
+ return Value::fromString(ctx, QLatin1String(num < 0 ? "-Infinity" : "Infinity")).asReturnedValue();
}
if (radix != 10) {
@@ -152,28 +152,28 @@ Value NumberPrototype::method_toString(SimpleCallContext *ctx)
}
if (negative)
str.prepend(QLatin1Char('-'));
- return Value::fromString(ctx, str);
+ return Value::fromString(ctx, str).asReturnedValue();
}
}
String *str = Value::fromDouble(num).toString(ctx);
- return Value::fromString(str);
+ return Value::fromString(str).asReturnedValue();
}
-Value NumberPrototype::method_toLocaleString(SimpleCallContext *ctx)
+ReturnedValue NumberPrototype::method_toLocaleString(SimpleCallContext *ctx)
{
Value v = thisNumberValue(ctx);
String *str = v.toString(ctx);
- return Value::fromString(str);
+ return Value::fromString(str).asReturnedValue();
}
-Value NumberPrototype::method_valueOf(SimpleCallContext *ctx)
+ReturnedValue NumberPrototype::method_valueOf(SimpleCallContext *ctx)
{
- return thisNumberValue(ctx);
+ return thisNumberValue(ctx).asReturnedValue();
}
-Value NumberPrototype::method_toFixed(SimpleCallContext *ctx)
+ReturnedValue NumberPrototype::method_toFixed(SimpleCallContext *ctx)
{
double v = thisNumberValue(ctx).asDouble();
@@ -196,11 +196,11 @@ Value NumberPrototype::method_toFixed(SimpleCallContext *ctx)
else if (v < 1.e21)
str = QString::number(v, 'f', int (fdigits));
else
- return __qmljs_string_from_number(ctx, v);
- return Value::fromString(ctx, str);
+ return __qmljs_string_from_number(ctx, v)->asReturnedValue();
+ return Value::fromString(ctx, str).asReturnedValue();
}
-Value NumberPrototype::method_toExponential(SimpleCallContext *ctx)
+ReturnedValue NumberPrototype::method_toExponential(SimpleCallContext *ctx)
{
double d = thisNumberValue(ctx).asDouble();
@@ -220,12 +220,12 @@ Value NumberPrototype::method_toExponential(SimpleCallContext *ctx)
double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToExponential(d, fdigits, &builder);
QString result = QString::fromLatin1(builder.Finalize());
- return Value::fromString(ctx, result);
+ return Value::fromString(ctx, result).asReturnedValue();
}
-Value NumberPrototype::method_toPrecision(SimpleCallContext *ctx)
+ReturnedValue NumberPrototype::method_toPrecision(SimpleCallContext *ctx)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
ScopedValue v(scope, thisNumberValue(ctx));
@@ -244,5 +244,5 @@ Value NumberPrototype::method_toPrecision(SimpleCallContext *ctx)
double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToPrecision(v->asDouble(), precision, &builder);
QString result = QString::fromLatin1(builder.Finalize());
- return Value::fromString(ctx, result);
+ return Value::fromString(ctx, result).asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index a0c2a65e80..d2c4ce6569 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -51,13 +51,11 @@ namespace QV4 {
struct NumberCtor: FunctionObject
{
+ Q_MANAGED
NumberCtor(ExecutionContext *scope);
- static Value construct(Managed *that, CallData *callData);
- static Value call(Managed *, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *that, CallData *callData);
+ static ReturnedValue call(Managed *, CallData *callData);
};
struct NumberPrototype: NumberObject
@@ -65,12 +63,12 @@ struct NumberPrototype: NumberObject
NumberPrototype(InternalClass *ic): NumberObject(ic) {}
void init(ExecutionContext *ctx, const Value &ctor);
- static Value method_toString(SimpleCallContext *ctx);
- static Value method_toLocaleString(SimpleCallContext *ctx);
- static Value method_valueOf(SimpleCallContext *ctx);
- static Value method_toFixed(SimpleCallContext *ctx);
- static Value method_toExponential(SimpleCallContext *ctx);
- static Value method_toPrecision(SimpleCallContext *ctx);
+ static ReturnedValue method_toString(SimpleCallContext *ctx);
+ static ReturnedValue method_toLocaleString(SimpleCallContext *ctx);
+ static ReturnedValue method_valueOf(SimpleCallContext *ctx);
+ static ReturnedValue method_toFixed(SimpleCallContext *ctx);
+ static ReturnedValue method_toExponential(SimpleCallContext *ctx);
+ static ReturnedValue method_toPrecision(SimpleCallContext *ctx);
};
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 14584da46d..4f7e2966f1 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -127,15 +127,16 @@ void Object::put(ExecutionContext *ctx, const QString &name, const Value &value)
put(ctx->engine->newString(name), value);
}
-Value Object::getValue(const Value &thisObject, const Property *p, PropertyAttributes attrs)
+ReturnedValue Object::getValue(const Value &thisObject, const Property *p, PropertyAttributes attrs)
{
if (!attrs.isAccessor())
- return p->value;
+ return p->value.asReturnedValue();
FunctionObject *getter = p->getter();
if (!getter)
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
- ScopedCallData callData(getter->engine(), 0);
+ Scope scope(getter->engine());
+ ScopedCallData callData(scope, 0);
callData->thisObject = thisObject;
return getter->call(callData);
}
@@ -144,7 +145,8 @@ void Object::putValue(Property *pd, PropertyAttributes attrs, const Value &value
{
if (attrs.isAccessor()) {
if (pd->set) {
- ScopedCallData callData(pd->set->engine(), 1);
+ Scope scope(pd->set->engine());
+ ScopedCallData callData(scope, 1);
callData->args[0] = value;
callData->thisObject = Value::fromObject(this);
pd->set->call(callData);
@@ -167,22 +169,20 @@ void Object::putValue(Property *pd, PropertyAttributes attrs, const Value &value
void Object::inplaceBinOp(ExecutionContext *ctx, BinOp op, String *name, const ValueRef rhs)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
ScopedValue v(scope, get(name));
- ScopedValue result(scope);
- op(result, v, rhs);
+ ScopedValue result(scope, op(v, rhs));
put(name, result);
}
void Object::inplaceBinOp(ExecutionContext *ctx, BinOp op, const ValueRef index, const ValueRef rhs)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
uint idx = index->asArrayIndex();
if (idx < UINT_MAX) {
bool hasProperty = false;
ScopedValue v(scope, getIndexed(idx, &hasProperty));
- ScopedValue result(scope);
- op(result, v, rhs);
+ ScopedValue result(scope, op(v, rhs));
putIndexed(idx, result);
return;
}
@@ -193,22 +193,20 @@ void Object::inplaceBinOp(ExecutionContext *ctx, BinOp op, const ValueRef index,
void Object::inplaceBinOp(ExecutionContext *ctx, BinOpContext op, String *name, const ValueRef rhs)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
ScopedValue v(scope, get(name));
- ScopedValue result(scope);
- op(ctx, result, v, rhs);
+ ScopedValue result(scope, op(ctx, v, rhs));
put(name, result);
}
void Object::inplaceBinOp(ExecutionContext *ctx, BinOpContext op, const ValueRef index, const ValueRef rhs)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
uint idx = index->asArrayIndex();
if (idx < UINT_MAX) {
bool hasProperty = false;
ScopedValue v(scope, getIndexed(idx, &hasProperty));
- ScopedValue result(scope);
- op(ctx, result, v, rhs);
+ ScopedValue result(scope, op(ctx, v, rhs));
putIndexed(idx, result);
return;
}
@@ -233,7 +231,7 @@ void Object::defineDefaultProperty(ExecutionEngine *engine, const QString &name,
defineDefaultProperty(engine->newIdentifier(name), value);
}
-void Object::defineDefaultProperty(ExecutionContext *context, const QString &name, Value (*code)(SimpleCallContext *), int argumentCount)
+void Object::defineDefaultProperty(ExecutionContext *context, const QString &name, ReturnedValue (*code)(SimpleCallContext *), int argumentCount)
{
Q_UNUSED(argumentCount);
String *s = context->engine->newIdentifier(name);
@@ -242,7 +240,7 @@ void Object::defineDefaultProperty(ExecutionContext *context, const QString &nam
defineDefaultProperty(s, Value::fromObject(function));
}
-void Object::defineDefaultProperty(ExecutionEngine *engine, const QString &name, Value (*code)(SimpleCallContext *), int argumentCount)
+void Object::defineDefaultProperty(ExecutionEngine *engine, const QString &name, ReturnedValue (*code)(SimpleCallContext *), int argumentCount)
{
Q_UNUSED(argumentCount);
String *s = engine->newIdentifier(name);
@@ -252,13 +250,13 @@ void Object::defineDefaultProperty(ExecutionEngine *engine, const QString &name,
}
void Object::defineAccessorProperty(ExecutionEngine *engine, const QString &name,
- Value (*getter)(SimpleCallContext *), Value (*setter)(SimpleCallContext *))
+ ReturnedValue (*getter)(SimpleCallContext *), ReturnedValue (*setter)(SimpleCallContext *))
{
String *s = engine->newString(name);
defineAccessorProperty(s, getter, setter);
}
-void Object::defineAccessorProperty(String *name, Value (*getter)(SimpleCallContext *), Value (*setter)(SimpleCallContext *))
+void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(SimpleCallContext *), ReturnedValue (*setter)(SimpleCallContext *))
{
ExecutionEngine *v4 = engine();
Property *p = insertMember(name, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
@@ -451,12 +449,12 @@ bool Object::__hasProperty__(uint index) const
return false;
}
-Value Object::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue Object::get(Managed *m, String *name, bool *hasProperty)
{
return static_cast<Object *>(m)->internalGet(name, hasProperty);
}
-Value Object::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue Object::getIndexed(Managed *m, uint index, bool *hasProperty)
{
return static_cast<Object *>(m)->internalGetIndexed(index, hasProperty);
}
@@ -512,7 +510,7 @@ bool Object::deleteIndexedProperty(Managed *m, uint index)
return static_cast<Object *>(m)->internalDeleteIndexedProperty(index);
}
-void Object::getLookup(Managed *m, Lookup *l, Value *result)
+ReturnedValue Object::getLookup(Managed *m, Lookup *l)
{
Object *o = static_cast<Object *>(m);
PropertyAttributes attrs;
@@ -525,9 +523,7 @@ void Object::getLookup(Managed *m, Lookup *l, Value *result)
l->getter = Lookup::getter1;
else if (l->level == 2)
l->getter = Lookup::getter2;
- if (result)
- *result = p->value;
- return;
+ return p->value.asReturnedValue();
} else {
if (l->level == 0)
l->getter = Lookup::getterAccessor0;
@@ -535,16 +531,10 @@ void Object::getLookup(Managed *m, Lookup *l, Value *result)
l->getter = Lookup::getterAccessor1;
else if (l->level == 2)
l->getter = Lookup::getterAccessor2;
- if (result)
- *result = p->value;
- Value res = o->getValue(p, attrs);
- if (result)
- *result = res;
- return;
+ return o->getValue(p, attrs);
}
- } else if (result) {
- *result = Value::undefinedValue();
}
+ return Value::undefinedValue().asReturnedValue();
}
void Object::setLookup(Managed *m, Lookup *l, const Value &value)
@@ -656,7 +646,7 @@ Property *Object::advanceIterator(Managed *m, ObjectIterator *it, String **name,
}
// Section 8.12.3
-Value Object::internalGet(String *name, bool *hasProperty)
+ReturnedValue Object::internalGet(String *name, bool *hasProperty)
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -678,10 +668,10 @@ Value Object::internalGet(String *name, bool *hasProperty)
if (hasProperty)
*hasProperty = false;
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
-Value Object::internalGetIndexed(uint index, bool *hasProperty)
+ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty)
{
Property *pd = 0;
PropertyAttributes attrs = Attr_Data;
@@ -714,7 +704,7 @@ Value Object::internalGetIndexed(uint index, bool *hasProperty)
if (hasProperty)
*hasProperty = false;
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
@@ -778,7 +768,8 @@ void Object::internalPut(String *name, const Value &value)
if (pd && attrs.isAccessor()) {
assert(pd->setter() != 0);
- ScopedCallData callData(engine(), 1);
+ Scope scope(engine());
+ ScopedCallData callData(scope, 1);
callData->args[0] = value;
callData->thisObject = Value::fromObject(this);
pd->setter()->call(callData);
@@ -856,7 +847,8 @@ void Object::internalPutIndexed(uint index, const Value &value)
if (pd && attrs.isAccessor()) {
assert(pd->setter() != 0);
- ScopedCallData callData(engine(), 1);
+ Scope scope(engine());
+ ScopedCallData callData(scope, 1);
callData->args[0] = value;
callData->thisObject = Value::fromObject(this);
pd->setter()->call(callData);
@@ -1116,7 +1108,7 @@ void Object::copyArrayData(Object *other)
Q_ASSERT(len);
for (uint i = 0; i < len; ++i) {
- arraySet(i, other->getIndexed(i));
+ arraySet(i, Value::fromReturnedValue(other->getIndexed(i)));
}
} else {
arrayReserve(other->arrayDataLen);
@@ -1135,9 +1127,9 @@ void Object::copyArrayData(Object *other)
}
-Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionContext *ctx, Object *o)
+ReturnedValue Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionContext *ctx, Object *o)
{
- ValueScope scope(engine());
+ Scope scope(engine());
ScopedValue value(scope);
if (o->protoHasArray() || o->arrayAttributes) {
@@ -1146,13 +1138,13 @@ Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionCont
bool exists;
value = o->getIndexed(i, &exists);
if (exists && __qmljs_strict_equal(value, ValueRef(&v)))
- return Value::fromDouble(i);
+ return Encode(i);
}
} else if (sparseArray) {
for (SparseArrayNode *n = sparseArray->lowerBound(fromIndex); n != sparseArray->end() && n->key() < endIndex; n = n->nextNode()) {
value = o->getValue(arrayData + n->value, arrayAttributes ? arrayAttributes[n->value] : Attr_Data);
if (__qmljs_strict_equal(value, ValueRef(&v)))
- return Value::fromDouble(n->key());
+ return Encode(n->key());
}
} else {
if ((int) endIndex > arrayDataLen)
@@ -1164,12 +1156,12 @@ Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionCont
if (!arrayAttributes || !arrayAttributes[pd - arrayData].isGeneric()) {
value = o->getValue(pd, arrayAttributes ? arrayAttributes[pd - arrayData] : Attr_Data);
if (__qmljs_strict_equal(value, ValueRef(&v)))
- return Value::fromDouble(pd - arrayData);
+ return Encode((uint)(pd - arrayData));
}
++pd;
}
}
- return Value::fromInt32(-1);
+ return Encode(-1);
}
void Object::arrayConcat(const ArrayObject *other)
@@ -1204,7 +1196,7 @@ void Object::arrayConcat(const ArrayObject *other)
if (other->arrayAttributes) {
for (int i = 0; i < arrayDataLen; ++i) {
bool exists;
- arrayData[oldSize + i].value = const_cast<ArrayObject *>(other)->getIndexed(i, &exists);
+ arrayData[oldSize + i].value = Value::fromReturnedValue(const_cast<ArrayObject *>(other)->getIndexed(i, &exists));
if (arrayAttributes)
arrayAttributes[oldSize + i] = Attr_Data;
if (!exists) {
@@ -1244,11 +1236,11 @@ void Object::arraySort(ExecutionContext *context, Object *thisObject, const Valu
while (--len > i)
if (!arrayAttributes[len].isGeneric())
break;
- arrayData[i].value = getValue(arrayData + len, arrayAttributes[len]);
+ arrayData[i].value = Value::fromReturnedValue(getValue(arrayData + len, arrayAttributes[len]));
arrayAttributes[i] = Attr_Data;
arrayAttributes[len].clear();
} else if (arrayAttributes[i].isAccessor()) {
- arrayData[i].value = getValue(arrayData + i, arrayAttributes[i]);
+ arrayData[i].value = Value::fromReturnedValue(getValue(arrayData + i, arrayAttributes[i]));
arrayAttributes[i] = Attr_Data;
}
}
@@ -1380,7 +1372,7 @@ bool Object::setArrayLength(uint newLen) {
arrayAttributes[it->value].clear();
}
}
- pd.value.tag = Value::_Empty_Type;
+ pd.value.tag = Value::Empty_Type;
pd.value.int_32 = arrayFreeList;
arrayFreeList = it->value;
bool brk = (it == begin);
@@ -1432,6 +1424,8 @@ void Object::markArrayObjects() const
}
}
+DEFINE_MANAGED_VTABLE(ArrayObject);
+
ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
: Object(engine->arrayClass)
{
@@ -1460,10 +1454,14 @@ QStringList ArrayObject::toQStringList() const
QStringList result;
QV4::ExecutionEngine *engine = internalClass->engine;
+ Scope scope(engine);
+ ScopedValue v(scope);
uint32_t length = arrayLength();
- for (uint32_t i = 0; i < length; ++i)
- result.append(const_cast<ArrayObject *>(this)->getIndexed(i).toString(engine->current)->toQString());
+ for (uint32_t i = 0; i < length; ++i) {
+ v = const_cast<ArrayObject *>(this)->getIndexed(i);
+ result.append(v->toString(engine->current)->toQString());
+ }
return result;
}
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index c6329b9665..7cb3fe45c2 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -105,6 +105,7 @@ typedef Value (*PropertyEnumeratorFunction)(Object *object);
typedef PropertyAttributes (*PropertyQueryFunction)(const Object *object, String *name);
struct Q_QML_EXPORT Object: Managed {
+ Q_MANAGED
uint memberDataAlloc;
Property *memberData;
@@ -149,8 +150,8 @@ struct Q_QML_EXPORT Object: Managed {
//
void put(ExecutionContext *ctx, const QString &name, const Value &value);
- static Value getValue(const Value &thisObject, const Property *p, PropertyAttributes attrs);
- Value getValue(const Property *p, PropertyAttributes attrs) const {
+ static ReturnedValue getValue(const Value &thisObject, const Property *p, PropertyAttributes attrs);
+ ReturnedValue getValue(const Property *p, PropertyAttributes attrs) const {
return getValue(Value::fromObject(const_cast<Object *>(this)), p, attrs);
}
@@ -165,10 +166,10 @@ struct Q_QML_EXPORT Object: Managed {
void defineDefaultProperty(String *name, Value value);
void defineDefaultProperty(ExecutionContext *context, const QString &name, Value value);
void defineDefaultProperty(ExecutionEngine *engine, const QString &name, Value value);
- void defineDefaultProperty(ExecutionContext *context, const QString &name, Value (*code)(SimpleCallContext *), int count = 0);
- void defineDefaultProperty(ExecutionEngine *engine, const QString &name, Value (*code)(SimpleCallContext *), int count = 0);
- void defineAccessorProperty(ExecutionEngine *engine, const QString &name, Value (*getter)(SimpleCallContext *), Value (*setter)(SimpleCallContext *));
- void defineAccessorProperty(String *name, Value (*getter)(SimpleCallContext *), Value (*setter)(SimpleCallContext *));
+ void defineDefaultProperty(ExecutionContext *context, const QString &name, ReturnedValue (*code)(SimpleCallContext *), int count = 0);
+ void defineDefaultProperty(ExecutionEngine *engine, const QString &name, ReturnedValue (*code)(SimpleCallContext *), int count = 0);
+ void defineAccessorProperty(ExecutionEngine *engine, const QString &name, ReturnedValue (*getter)(SimpleCallContext *), ReturnedValue (*setter)(SimpleCallContext *));
+ void defineAccessorProperty(String *name, ReturnedValue (*getter)(SimpleCallContext *), ReturnedValue (*setter)(SimpleCallContext *));
/* Fixed: Writable: false, Enumerable: false, Configurable: false */
void defineReadonlyProperty(ExecutionEngine *engine, const QString &name, Value value);
void defineReadonlyProperty(String *name, Value value);
@@ -177,6 +178,10 @@ struct Q_QML_EXPORT Object: Managed {
inline ExecutionEngine *engine() const { return internalClass->engine; }
+ static Object *cast(const Value &v) {
+ return v.asObject();
+ }
+
// Array handling
uint allocArrayValue() {
@@ -197,7 +202,7 @@ struct Q_QML_EXPORT Object: Managed {
}
void freeArrayValue(int idx) {
Property &pd = arrayData[idx];
- pd.value.tag = Value::_Empty_Type;
+ pd.value.tag = Value::Empty_Type;
pd.value.int_32 = arrayFreeList;
arrayFreeList = idx;
if (arrayAttributes)
@@ -271,13 +276,14 @@ public:
void arrayConcat(const ArrayObject *other);
void arraySort(ExecutionContext *context, Object *thisObject, const Value &comparefn, uint arrayDataLen);
- Value arrayIndexOf(Value v, uint fromIndex, uint arrayDataLen, ExecutionContext *ctx, Object *o);
+ ReturnedValue arrayIndexOf(Value v, uint fromIndex, uint arrayDataLen, ExecutionContext *ctx, Object *o);
void arrayReserve(uint n);
void ensureArrayAttributes();
inline bool protoHasArray() {
- Object *p = this;
+ Scope scope(engine());
+ Scoped<Object> p(scope, this);
while ((p = p->prototype()))
if (p->arrayDataLen)
@@ -287,9 +293,9 @@ public:
}
void ensureMemberIndex(uint idx);
- inline Value get(String *name, bool *hasProperty = 0)
+ inline ReturnedValue get(String *name, bool *hasProperty = 0)
{ return vtbl->get(this, name, hasProperty); }
- inline Value getIndexed(uint idx, bool *hasProperty = 0)
+ inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0)
{ return vtbl->getIndexed(this, idx, hasProperty); }
inline void put(String *name, const Value &v)
{ vtbl->put(this, name, v); }
@@ -307,25 +313,24 @@ public:
using Managed::setLookup;
using Managed::advanceIterator;
protected:
- static const ManagedVTable static_vtbl;
static void destroy(Managed *that);
static void markObjects(Managed *that);
- static Value get(Managed *m, String *name, bool *hasProperty);
- static Value getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static void putIndexed(Managed *m, uint index, const Value &value);
static PropertyAttributes query(const Managed *m, String *name);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
static bool deleteProperty(Managed *m, String *name);
static bool deleteIndexedProperty(Managed *m, uint index);
- static void getLookup(Managed *m, Lookup *l, Value *result);
+ static ReturnedValue getLookup(Managed *m, Lookup *l);
static void setLookup(Managed *m, Lookup *l, const Value &v);
static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
private:
- Value internalGet(String *name, bool *hasProperty);
- Value internalGetIndexed(uint index, bool *hasProperty);
+ ReturnedValue internalGet(String *name, bool *hasProperty);
+ ReturnedValue internalGetIndexed(uint index, bool *hasProperty);
void internalPut(String *name, const Value &value);
void internalPutIndexed(uint index, const Value &value);
bool internalDeleteProperty(String *name);
@@ -344,7 +349,7 @@ struct ForEachIteratorObject: Object {
type = Type_ForeachIteratorObject;
}
- Value nextPropertyName() { return it.nextPropertyNameAsString(); }
+ ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }
protected:
static void markObjects(Managed *that);
@@ -365,6 +370,7 @@ protected:
};
struct ArrayObject: Object {
+ Q_MANAGED
enum {
LengthPropertyIndex = 0
};
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index 338398c0d8..f03c2d6b86 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -92,38 +92,38 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a
return 0;
}
-Value ObjectIterator::nextPropertyName(Value *value)
+ReturnedValue ObjectIterator::nextPropertyName(Value *value)
{
PropertyAttributes attrs;
uint index;
String *name;
Property *p = next(&name, &index, &attrs);
if (!p)
- return Value::nullValue();
+ return Encode::null();
if (value)
- *value = object->getValue(p, attrs);
+ *value = Value::fromReturnedValue(object->getValue(p, attrs));
if (name)
- return Value::fromString(name);
+ return Value::fromString(name).asReturnedValue();
assert(index < UINT_MAX);
- return Value::fromDouble(index);
+ return Encode(index);
}
-Value ObjectIterator::nextPropertyNameAsString(Value *value)
+ReturnedValue ObjectIterator::nextPropertyNameAsString(Value *value)
{
PropertyAttributes attrs;
uint index;
String *name;
Property *p = next(&name, &index, &attrs);
if (!p)
- return Value::nullValue();
+ return Encode::null();
if (value)
- *value = object->getValue(p, attrs);
+ *value = Value::fromReturnedValue(object->getValue(p, attrs));
if (name)
- return Value::fromString(name);
+ return Value::fromString(name).asReturnedValue();
assert(index < UINT_MAX);
- return Value::fromString(object->engine()->newString(QString::number(index)));
+ return Value::fromString(object->engine()->newString(QString::number(index))).asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index 95439397f5..d5464891f1 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -76,8 +76,8 @@ struct Q_QML_EXPORT ObjectIterator
ObjectIterator(Object *o, uint flags);
Property *next(String **name, uint *index, PropertyAttributes *attributes = 0);
- Value nextPropertyName(Value *value = 0);
- Value nextPropertyNameAsString(Value *value = 0);
+ ReturnedValue nextPropertyName(Value *value = 0);
+ ReturnedValue nextPropertyNameAsString(Value *value = 0);
};
}
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 2f8f6375f0..073d588e56 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -79,24 +79,25 @@ ObjectCtor::ObjectCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value ObjectCtor::construct(Managed *that, CallData *callData)
+ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData)
{
- ObjectCtor *ctor = static_cast<ObjectCtor *>(that);
ExecutionEngine *v4 = that->engine();
+ Scope scope(v4);
+ ObjectCtor *ctor = static_cast<ObjectCtor *>(that);
if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) {
Object *obj = v4->newObject();
- Value proto = ctor->get(v4->id_prototype);
- if (proto.isObject())
- obj->setPrototype(proto.objectValue());
- return Value::fromObject(obj);
+ Scoped<Object> proto(scope, ctor->get(v4->id_prototype));
+ if (!!proto)
+ obj->setPrototype(proto.getPointer());
+ return Value::fromObject(obj).asReturnedValue();
}
- return __qmljs_to_object(v4->current, ValueRef(&callData->args[0]));
+ return Value::fromReturnedValue(__qmljs_to_object(v4->current, ValueRef(&callData->args[0]))).asReturnedValue();
}
-Value ObjectCtor::call(Managed *m, CallData *callData)
+ReturnedValue ObjectCtor::call(Managed *m, CallData *callData)
{
if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull())
- return Value::fromObject(m->engine()->newObject());
+ return Value::fromObject(m->engine()->newObject()).asReturnedValue();
return __qmljs_to_object(m->engine()->current, ValueRef(&callData->args[0]));
}
@@ -134,17 +135,17 @@ void ObjectPrototype::init(ExecutionContext *ctx, const Value &ctor)
p->setSetter(v4->newBuiltinFunction(v4->rootContext, v4->id___proto__, method_set_proto));
}
-Value ObjectPrototype::method_getPrototypeOf(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_getPrototypeOf(SimpleCallContext *ctx)
{
Value o = ctx->argument(0);
if (! o.isObject())
ctx->throwTypeError();
Object *p = o.objectValue()->prototype();
- return p ? Value::fromObject(p) : Value::nullValue();
+ return p ? Value::fromObject(p).asReturnedValue() : Encode::null();
}
-Value ObjectPrototype::method_getOwnPropertyDescriptor(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(SimpleCallContext *ctx)
{
Value O = ctx->argument(0);
if (!O.isObject())
@@ -156,17 +157,17 @@ Value ObjectPrototype::method_getOwnPropertyDescriptor(SimpleCallContext *ctx)
return fromPropertyDescriptor(ctx, desc, attrs);
}
-Value ObjectPrototype::method_getOwnPropertyNames(SimpleCallContext *context)
+ReturnedValue ObjectPrototype::method_getOwnPropertyNames(SimpleCallContext *context)
{
Object *O = context->argumentCount ? context->arguments[0].asObject() : 0;
if (!O)
context->throwTypeError();
ArrayObject *array = getOwnPropertyNames(context->engine, context->arguments[0]);
- return Value::fromObject(array);
+ return Value::fromObject(array).asReturnedValue();
}
-Value ObjectPrototype::method_create(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_create(SimpleCallContext *ctx)
{
Value O = ctx->argument(0);
if (!O.isObject() && !O.isNull())
@@ -181,10 +182,10 @@ Value ObjectPrototype::method_create(SimpleCallContext *ctx)
method_defineProperties(ctx);
}
- return objValue;
+ return objValue.asReturnedValue();
}
-Value ObjectPrototype::method_defineProperty(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_defineProperty(SimpleCallContext *ctx)
{
Value O = ctx->argument(0);
if (!O.isObject())
@@ -200,10 +201,10 @@ Value ObjectPrototype::method_defineProperty(SimpleCallContext *ctx)
if (!O.objectValue()->__defineOwnProperty__(ctx, name, pd, attrs))
ctx->throwTypeError();
- return O;
+ return O.asReturnedValue();
}
-Value ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
{
Value O = ctx->argument(0);
if (!O.isObject())
@@ -221,7 +222,7 @@ Value ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
break;
Property n;
PropertyAttributes nattrs;
- toPropertyDescriptor(ctx, o->getValue(pd, attrs), &n, &nattrs);
+ toPropertyDescriptor(ctx, Value::fromReturnedValue(o->getValue(pd, attrs)), &n, &nattrs);
bool ok;
if (name)
ok = O.objectValue()->__defineOwnProperty__(ctx, name, n, nattrs);
@@ -231,10 +232,10 @@ Value ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
ctx->throwTypeError();
}
- return O;
+ return O.asReturnedValue();
}
-Value ObjectPrototype::method_seal(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_seal(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
@@ -250,10 +251,10 @@ Value ObjectPrototype::method_seal(SimpleCallContext *ctx)
o->arrayAttributes[i].setConfigurable(false);
}
- return ctx->argument(0);
+ return ctx->argument(0).asReturnedValue();
}
-Value ObjectPrototype::method_freeze(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_freeze(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
@@ -270,169 +271,171 @@ Value ObjectPrototype::method_freeze(SimpleCallContext *ctx)
if (o->arrayAttributes[i].isData())
o->arrayAttributes[i].setWritable(false);
}
- return ctx->argument(0);
+ return ctx->argument(0).asReturnedValue();
}
-Value ObjectPrototype::method_preventExtensions(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_preventExtensions(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
Object *o = ctx->argument(0).objectValue();
o->extensible = false;
- return ctx->argument(0);
+ return ctx->argument(0).asReturnedValue();
}
-Value ObjectPrototype::method_isSealed(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_isSealed(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
Object *o = ctx->argument(0).objectValue();
if (o->extensible)
- return Value::fromBoolean(false);
+ return Encode(false);
if (o->internalClass != o->internalClass->sealed())
- return Value::fromBoolean(false);
+ return Encode(false);
if (!o->arrayDataLen)
- return Value::fromBoolean(true);
+ return Encode(true);
if (!o->arrayAttributes)
- return Value::fromBoolean(false);
+ return Encode(false);
for (uint i = 0; i < o->arrayDataLen; ++i) {
if (!o->arrayAttributes[i].isGeneric())
if (o->arrayAttributes[i].isConfigurable())
- return Value::fromBoolean(false);
+ return Encode(false);
}
- return Value::fromBoolean(true);
+ return Encode(true);
}
-Value ObjectPrototype::method_isFrozen(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_isFrozen(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
Object *o = ctx->argument(0).objectValue();
if (o->extensible)
- return Value::fromBoolean(false);
+ return Encode(false);
if (o->internalClass != o->internalClass->frozen())
- return Value::fromBoolean(false);
+ return Encode(false);
if (!o->arrayDataLen)
- return Value::fromBoolean(true);
+ return Encode(true);
if (!o->arrayAttributes)
- return Value::fromBoolean(false);
+ return Encode(false);
for (uint i = 0; i < o->arrayDataLen; ++i) {
if (!o->arrayAttributes[i].isGeneric())
if (o->arrayAttributes[i].isConfigurable() || o->arrayAttributes[i].isWritable())
- return Value::fromBoolean(false);
+ return Encode(false);
}
- return Value::fromBoolean(true);
+ return Encode(true);
}
-Value ObjectPrototype::method_isExtensible(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_isExtensible(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
Object *o = ctx->argument(0).objectValue();
- return Value::fromBoolean(o->extensible);
+ return Encode((bool)o->extensible);
}
-Value ObjectPrototype::method_keys(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_keys(SimpleCallContext *ctx)
{
if (!ctx->argument(0).isObject())
ctx->throwTypeError();
+ Scope scope(ctx);
Object *o = ctx->argument(0).objectValue();
- ArrayObject *a = ctx->engine->newArrayObject();
+ Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
ObjectIterator it(o, ObjectIterator::EnumerableOnly);
+ ScopedValue name(scope);
while (1) {
- Value name = it.nextPropertyNameAsString();
- if (name.isNull())
+ name = it.nextPropertyNameAsString();
+ if (name->isNull())
break;
a->push_back(name);
}
- return Value::fromObject(a);
+ return a.asReturnedValue();
}
-Value ObjectPrototype::method_toString(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_toString(SimpleCallContext *ctx)
{
if (ctx->thisObject.isUndefined()) {
- return Value::fromString(ctx, QStringLiteral("[object Undefined]"));
+ return Value::fromString(ctx, QStringLiteral("[object Undefined]")).asReturnedValue();
} else if (ctx->thisObject.isNull()) {
- return Value::fromString(ctx, QStringLiteral("[object Null]"));
+ return Value::fromString(ctx, QStringLiteral("[object Null]")).asReturnedValue();
} else {
- Value obj = __qmljs_to_object(ctx, ValueRef(&ctx->thisObject));
+ Value obj = Value::fromReturnedValue(__qmljs_to_object(ctx, ValueRef(&ctx->thisObject)));
QString className = obj.objectValue()->className();
- return Value::fromString(ctx, QString::fromUtf8("[object %1]").arg(className));
+ return Value::fromString(ctx, QString::fromUtf8("[object %1]").arg(className)).asReturnedValue();
}
}
-Value ObjectPrototype::method_toLocaleString(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_toLocaleString(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
Object *o = ctx->thisObject.toObject(ctx);
- Value ts = o->get(ctx->engine->newString(QStringLiteral("toString")));
- FunctionObject *f = ts.asFunctionObject();
+ Scoped<FunctionObject> f(scope, o->get(ctx->engine->newString(QStringLiteral("toString"))));
if (!f)
ctx->throwTypeError();
- ScopedCallData callData(ctx->engine, 0);
+ ScopedCallData callData(scope, 0);
callData->thisObject = Value::fromObject(o);
return f->call(callData);
}
-Value ObjectPrototype::method_valueOf(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_valueOf(SimpleCallContext *ctx)
{
- return Value::fromObject(ctx->thisObject.toObject(ctx));
+ return Value::fromObject(ctx->thisObject.toObject(ctx)).asReturnedValue();
}
-Value ObjectPrototype::method_hasOwnProperty(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_hasOwnProperty(SimpleCallContext *ctx)
{
String *P = ctx->argument(0).toString(ctx);
Object *O = ctx->thisObject.toObject(ctx);
bool r = O->__getOwnProperty__(P) != 0;
if (!r)
r = !O->query(P).isEmpty();
- return Value::fromBoolean(r);
+ return Encode(r);
}
-Value ObjectPrototype::method_isPrototypeOf(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_isPrototypeOf(SimpleCallContext *ctx)
{
Value V = ctx->argument(0);
if (! V.isObject())
- return Value::fromBoolean(false);
+ return Encode(false);
Object *O = ctx->thisObject.toObject(ctx);
Object *proto = V.objectValue()->prototype();
while (proto) {
if (O == proto)
- return Value::fromBoolean(true);
+ return Encode(true);
proto = proto->prototype();
}
- return Value::fromBoolean(false);
+ return Encode(false);
}
-Value ObjectPrototype::method_propertyIsEnumerable(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_propertyIsEnumerable(SimpleCallContext *ctx)
{
String *p = ctx->argument(0).toString(ctx);
Object *o = ctx->thisObject.toObject(ctx);
PropertyAttributes attrs;
o->__getOwnProperty__(p, &attrs);
- return Value::fromBoolean(attrs.isEnumerable());
+ return Encode(attrs.isEnumerable());
}
-Value ObjectPrototype::method_defineGetter(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_defineGetter(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 2)
ctx->throwTypeError();
@@ -445,16 +448,16 @@ Value ObjectPrototype::method_defineGetter(SimpleCallContext *ctx)
Object *o = ctx->thisObject.asObject();
if (!o) {
if (!ctx->thisObject.isUndefined())
- return Value::undefinedValue();
+ return Encode::undefined();
o = ctx->engine->globalObject;
}
Property pd = Property::fromAccessor(f, 0);
o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value ObjectPrototype::method_defineSetter(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_defineSetter(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 2)
ctx->throwTypeError();
@@ -467,25 +470,25 @@ Value ObjectPrototype::method_defineSetter(SimpleCallContext *ctx)
Object *o = ctx->thisObject.asObject();
if (!o) {
if (!ctx->thisObject.isUndefined())
- return Value::undefinedValue();
+ return Encode::undefined();
o = ctx->engine->globalObject;
}
Property pd = Property::fromAccessor(0, f);
o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value ObjectPrototype::method_get_proto(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_get_proto(SimpleCallContext *ctx)
{
Object *o = ctx->thisObject.asObject();
if (!o)
ctx->throwTypeError();
- return Value::fromObject(o->prototype());
+ return Value::fromObject(o->prototype()).asReturnedValue();
}
-Value ObjectPrototype::method_set_proto(SimpleCallContext *ctx)
+ReturnedValue ObjectPrototype::method_set_proto(SimpleCallContext *ctx)
{
Object *o = ctx->thisObject.asObject();
if (!o)
@@ -505,7 +508,7 @@ Value ObjectPrototype::method_set_proto(SimpleCallContext *ctx)
}
if (!ok)
ctx->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
- return Value::undefinedValue();
+ return Encode::undefined();
}
void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Property *desc, PropertyAttributes *attrs)
@@ -513,6 +516,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
if (!v.isObject())
ctx->throwTypeError();
+ Scope scope(ctx);
Object *o = v.objectValue();
attrs->clear();
@@ -520,17 +524,17 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
desc->setSetter(0);
if (o->__hasProperty__(ctx->engine->id_enumerable))
- attrs->setEnumerable(o->get(ctx->engine->id_enumerable).toBoolean());
+ attrs->setEnumerable(Value::fromReturnedValue(o->get(ctx->engine->id_enumerable)).toBoolean());
if (o->__hasProperty__(ctx->engine->id_configurable))
- attrs->setConfigurable(o->get(ctx->engine->id_configurable).toBoolean());
+ attrs->setConfigurable(Value::fromReturnedValue(o->get(ctx->engine->id_configurable)).toBoolean());
if (o->__hasProperty__(ctx->engine->id_get)) {
- Value get = o->get(ctx->engine->id_get);
- FunctionObject *f = get.asFunctionObject();
+ ScopedValue get(scope, o->get(ctx->engine->id_get));
+ FunctionObject *f = get->asFunctionObject();
if (f) {
desc->setGetter(f);
- } else if (get.isUndefined()) {
+ } else if (get->isUndefined()) {
desc->setGetter((FunctionObject *)0x1);
} else {
ctx->throwTypeError();
@@ -539,11 +543,11 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
}
if (o->__hasProperty__(ctx->engine->id_set)) {
- Value set = o->get(ctx->engine->id_set);
- FunctionObject *f = set.asFunctionObject();
+ ScopedValue set(scope, o->get(ctx->engine->id_set));
+ FunctionObject *f = set->asFunctionObject();
if (f) {
desc->setSetter(f);
- } else if (set.isUndefined()) {
+ } else if (set->isUndefined()) {
desc->setSetter((FunctionObject *)0x1);
} else {
ctx->throwTypeError();
@@ -554,7 +558,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
if (o->__hasProperty__(ctx->engine->id_writable)) {
if (attrs->isAccessor())
ctx->throwTypeError();
- attrs->setWritable(o->get(ctx->engine->id_writable).toBoolean());
+ attrs->setWritable(Value::fromReturnedValue(o->get(ctx->engine->id_writable)).toBoolean());
// writable forces it to be a data descriptor
desc->value = Value::undefinedValue();
}
@@ -562,7 +566,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
if (o->__hasProperty__(ctx->engine->id_value)) {
if (attrs->isAccessor())
ctx->throwTypeError();
- desc->value = o->get(ctx->engine->id_value);
+ desc->value = Value::fromReturnedValue(o->get(ctx->engine->id_value));
attrs->setType(PropertyAttributes::Data);
}
@@ -571,10 +575,10 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
}
-Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Property *desc, PropertyAttributes attrs)
+ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Property *desc, PropertyAttributes attrs)
{
if (!desc)
- return Value::undefinedValue();
+ return Encode::undefined();
ExecutionEngine *engine = ctx->engine;
// Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name.
@@ -597,23 +601,25 @@ Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const Prope
pd.value = Value::fromBoolean(attrs.isConfigurable());
o->__defineOwnProperty__(ctx, engine->newString(QStringLiteral("configurable")), pd, Attr_Data);
- return Value::fromObject(o);
+ return Value::fromObject(o).asReturnedValue();
}
ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, const Value &o)
{
- ArrayObject *array = v4->newArrayObject();
+ Scope scope(v4);
+ Scoped<ArrayObject> array(scope, v4->newArrayObject());
Object *O = o.asObject();
if (!O)
- return array;
+ return array.getPointer();
ObjectIterator it(O, ObjectIterator::NoFlags);
+ ScopedValue name(scope);
while (1) {
- Value name = it.nextPropertyNameAsString();
- if (name.isNull())
+ name = it.nextPropertyNameAsString();
+ if (name->isNull())
break;
array->push_back(name);
}
- return array;
+ return array.getPointer();
}
diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h
index 33a115f203..311d53864f 100644
--- a/src/qml/jsruntime/qv4objectproto_p.h
+++ b/src/qml/jsruntime/qv4objectproto_p.h
@@ -51,13 +51,11 @@ namespace QV4 {
struct ObjectCtor: FunctionObject
{
+ Q_MANAGED
ObjectCtor(ExecutionContext *scope);
- static Value construct(Managed *that, CallData *callData);
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *that, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct ObjectPrototype: Object
@@ -66,35 +64,35 @@ struct ObjectPrototype: Object
void init(ExecutionContext *ctx, const Value &ctor);
- static Value method_getPrototypeOf(SimpleCallContext *ctx);
- static Value method_getOwnPropertyDescriptor(SimpleCallContext *ctx);
- static Value method_getOwnPropertyNames(SimpleCallContext *context);
- static Value method_create(SimpleCallContext *ctx);
- static Value method_defineProperty(SimpleCallContext *ctx);
- static Value method_defineProperties(SimpleCallContext *ctx);
- static Value method_seal(SimpleCallContext *ctx);
- static Value method_freeze(SimpleCallContext *ctx);
- static Value method_preventExtensions(SimpleCallContext *ctx);
- static Value method_isSealed(SimpleCallContext *ctx);
- static Value method_isFrozen(SimpleCallContext *ctx);
- static Value method_isExtensible(SimpleCallContext *ctx);
- static Value method_keys(SimpleCallContext *ctx);
-
- static Value method_toString(SimpleCallContext *ctx);
- static Value method_toLocaleString(SimpleCallContext *ctx);
- static Value method_valueOf(SimpleCallContext *ctx);
- static Value method_hasOwnProperty(SimpleCallContext *ctx);
- static Value method_isPrototypeOf(SimpleCallContext *ctx);
- static Value method_propertyIsEnumerable(SimpleCallContext *ctx);
-
- static Value method_defineGetter(SimpleCallContext *ctx);
- static Value method_defineSetter(SimpleCallContext *ctx);
-
- static Value method_get_proto(SimpleCallContext *ctx);
- static Value method_set_proto(SimpleCallContext *ctx);
+ static ReturnedValue method_getPrototypeOf(SimpleCallContext *ctx);
+ static ReturnedValue method_getOwnPropertyDescriptor(SimpleCallContext *ctx);
+ static ReturnedValue method_getOwnPropertyNames(SimpleCallContext *context);
+ static ReturnedValue method_create(SimpleCallContext *ctx);
+ static ReturnedValue method_defineProperty(SimpleCallContext *ctx);
+ static ReturnedValue method_defineProperties(SimpleCallContext *ctx);
+ static ReturnedValue method_seal(SimpleCallContext *ctx);
+ static ReturnedValue method_freeze(SimpleCallContext *ctx);
+ static ReturnedValue method_preventExtensions(SimpleCallContext *ctx);
+ static ReturnedValue method_isSealed(SimpleCallContext *ctx);
+ static ReturnedValue method_isFrozen(SimpleCallContext *ctx);
+ static ReturnedValue method_isExtensible(SimpleCallContext *ctx);
+ static ReturnedValue method_keys(SimpleCallContext *ctx);
+
+ static ReturnedValue method_toString(SimpleCallContext *ctx);
+ static ReturnedValue method_toLocaleString(SimpleCallContext *ctx);
+ static ReturnedValue method_valueOf(SimpleCallContext *ctx);
+ static ReturnedValue method_hasOwnProperty(SimpleCallContext *ctx);
+ static ReturnedValue method_isPrototypeOf(SimpleCallContext *ctx);
+ static ReturnedValue method_propertyIsEnumerable(SimpleCallContext *ctx);
+
+ static ReturnedValue method_defineGetter(SimpleCallContext *ctx);
+ static ReturnedValue method_defineSetter(SimpleCallContext *ctx);
+
+ static ReturnedValue method_get_proto(SimpleCallContext *ctx);
+ static ReturnedValue method_set_proto(SimpleCallContext *ctx);
static void toPropertyDescriptor(ExecutionContext *ctx, Value v, Property *desc, PropertyAttributes *attrs);
- static Value fromPropertyDescriptor(ExecutionContext *ctx, const Property *desc, PropertyAttributes attrs);
+ static ReturnedValue fromPropertyDescriptor(ExecutionContext *ctx, const Property *desc, PropertyAttributes attrs);
static ArrayObject *getOwnPropertyNames(ExecutionEngine *v4, const Value &o);
};
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 1e868ef3fe..d774014073 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -138,30 +138,16 @@ struct ReadAccessor {
}
};
-static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, int v)
-{ return QV4::Value::fromInt32(v); }
-static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, uint v)
-{ return QV4::Value::fromUInt32(v); }
-static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, bool v)
-{ return QV4::Value::fromBoolean(v); }
-static inline QV4::Value valueToHandle(QV4::ExecutionEngine *e, const QString &v)
-{ return QV4::Value::fromString(e, v); }
-static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, float v)
-{ return QV4::Value::fromDouble(v); }
-static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, double v)
-{ return QV4::Value::fromDouble(v); }
-static inline QV4::Value valueToHandle(QV4::ExecutionEngine *e, QObject *v)
-{ return QV4::QObjectWrapper::wrap(e, v); }
-
// Load value properties
template<void (*ReadFunction)(QObject *, const QQmlPropertyData &,
void *, QQmlNotifier **)>
-static QV4::Value LoadProperty(QV8Engine *engine, QObject *object,
+static QV4::ReturnedValue LoadProperty(QV8Engine *engine, QObject *object,
const QQmlPropertyData &property,
QQmlNotifier **notifier)
{
Q_ASSERT(!property.isFunction());
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope scope(v4);
if (property.isQObject()) {
QObject *rv = 0;
@@ -172,35 +158,35 @@ static QV4::Value LoadProperty(QV8Engine *engine, QObject *object,
} else if (property.propType == QMetaType::QReal) {
qreal v = 0;
ReadFunction(object, property, &v, notifier);
- return valueToHandle(v4, v);
+ return QV4::Encode(v);
} else if (property.propType == QMetaType::Int || property.isEnum()) {
int v = 0;
ReadFunction(object, property, &v, notifier);
- return valueToHandle(v4, v);
+ return QV4::Encode(v);
} else if (property.propType == QMetaType::Bool) {
bool v = false;
ReadFunction(object, property, &v, notifier);
- return valueToHandle(v4, v);
+ return QV4::Encode(v);
} else if (property.propType == QMetaType::QString) {
QString v;
ReadFunction(object, property, &v, notifier);
- return valueToHandle(v4, v);
+ return Value::fromString(v4, v).asReturnedValue();
} else if (property.propType == QMetaType::UInt) {
uint v = 0;
ReadFunction(object, property, &v, notifier);
- return valueToHandle(v4, v);
+ return QV4::Encode(v);
} else if (property.propType == QMetaType::Float) {
float v = 0;
ReadFunction(object, property, &v, notifier);
- return valueToHandle(v4, v);
+ return QV4::Encode(v);
} else if (property.propType == QMetaType::Double) {
double v = 0;
ReadFunction(object, property, &v, notifier);
- return valueToHandle(v4, v);
+ return QV4::Encode(v);
} else if (property.isV4Handle()) {
QQmlV4Handle handle;
ReadFunction(object, property, &handle, notifier);
- return handle.toValue();
+ return handle.toValue().asReturnedValue();
} else if (property.propType == qMetaTypeId<QJSValue>()) {
QJSValue v;
ReadFunction(object, property, &v, notifier);
@@ -225,16 +211,16 @@ static QV4::Value LoadProperty(QV8Engine *engine, QObject *object,
// see if it's a sequence type
bool succeeded = false;
- QV4::Value retn = QV4::SequencePrototype::newSequence(v4, property.propType, object, property.coreIndex, &succeeded);
+ QV4::ScopedValue retn(scope, QV4::SequencePrototype::newSequence(v4, property.propType, object, property.coreIndex, &succeeded));
if (succeeded)
- return retn;
+ return retn.asReturnedValue();
}
if (property.propType == QMetaType::UnknownType) {
QMetaProperty p = object->metaObject()->property(property.coreIndex);
qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property "
"'%s::%s'", p.typeName(), object->metaObject()->className(), p.name());
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
} else {
QVariant v(property.propType, (void *)0);
ReadFunction(object, property, v.data(), notifier);
@@ -271,20 +257,23 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlCont
return result;
}
-Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, bool includeImports)
+ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode,
+ bool *hasProperty, bool includeImports)
{
if (QQmlData::wasDeleted(m_object)) {
if (hasProperty)
*hasProperty = false;
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
+ QV4:Scope scope(ctx);
+
if (name->isEqualTo(m_destroy) || name->isEqualTo(m_toString)) {
int index = name->isEqualTo(m_destroy) ? QV4::QObjectMethod::DestroyMethod : QV4::QObjectMethod::ToStringMethod;
- QV4::Value method = QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, index);
+ QV4::ScopedValue method(scope, QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, index));
if (hasProperty)
*hasProperty = true;
- return method;
+ return method.asReturnedValue();
}
QQmlPropertyData local;
@@ -301,7 +290,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
if (r.isValid()) {
if (r.scriptIndex != -1) {
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
} else if (r.type) {
return QmlTypeWrapper::create(ctx->engine->v8Engine, m_object, r.type, QmlTypeWrapper::ExcludeEnums);
} else if (r.importNamespace) {
@@ -321,7 +310,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) {
if (hasProperty)
*hasProperty = false;
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
}
@@ -334,18 +323,20 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
Q_ASSERT(vmemo);
return vmemo->vmeMethod(result->coreIndex);
} else if (result->isV4Function()) {
- return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex, QV4::Value::fromObject(ctx->engine->qmlContextObject()));
+ QV4::Scoped<QV4::Object> qmlcontextobject(scope, ctx->engine->qmlContextObject());
+ return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex,
+ qmlcontextobject.asValue()).asReturnedValue();
} else if (result->isSignalHandler()) {
QV4::QmlSignalHandler *handler = new (ctx->engine->memoryManager) QV4::QmlSignalHandler(ctx->engine, m_object, result->coreIndex);
QV4::String *connect = ctx->engine->newIdentifier(QStringLiteral("connect"));
QV4::String *disconnect = ctx->engine->newIdentifier(QStringLiteral("disconnect"));
- handler->put(connect, ctx->engine->functionClass->prototype->get(connect));
- handler->put(disconnect, ctx->engine->functionClass->prototype->get(disconnect));
+ handler->put(connect, QV4::Value::fromReturnedValue(ctx->engine->functionClass->prototype->get(connect)));
+ handler->put(disconnect, QV4::Value::fromReturnedValue(ctx->engine->functionClass->prototype->get(disconnect)));
- return QV4::Value::fromObject(handler);
+ return QV4::Value::fromObject(handler).asReturnedValue();
} else {
- return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex);
+ return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex).asReturnedValue();
}
}
@@ -358,15 +349,16 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
if (ep && ep->propertyCapture && result->accessors->notifier)
nptr = &n;
- QV4::Value rv = LoadProperty<ReadAccessor::Accessor>(ctx->engine->v8Engine, m_object, *result, nptr);
+ QV4::ScopedValue rv(scope, LoadProperty<ReadAccessor::Accessor>(ctx->engine->v8Engine, m_object, *result, nptr));
if (result->accessors->notifier) {
- if (n) ep->captureProperty(n);
+ if (n)
+ ep->captureProperty(n);
} else {
ep->captureProperty(m_object, result->coreIndex, result->notifyIndex);
}
- return rv;
+ return rv.asReturnedValue();
}
if (ep && !result->isConstant())
@@ -383,25 +375,26 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml
}
}
-Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty)
+ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty)
{
+ QV4::Scope scope(ctx);
if (QQmlData::wasDeleted(object)) {
if (hasProperty)
*hasProperty = false;
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
if (!QQmlData::get(object, true)) {
if (hasProperty)
*hasProperty = false;
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
- QObjectWrapper *wrapper = wrap(ctx->engine, object).as<QV4::QObjectWrapper>();
+ QV4::Scoped<QObjectWrapper> wrapper(scope, wrap(ctx->engine, object));
if (!wrapper) {
if (hasProperty)
*hasProperty = false;
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
return wrapper->getQmlProperty(ctx, qmlContext, name, revisionMode, hasProperty);
}
@@ -507,7 +500,7 @@ bool QObjectWrapper::setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlC
} else if (result->propType == QMetaType::Double && value.isNumber()) {
PROPERTY_STORE(double, double(value.asDouble()));
} else if (result->propType == QMetaType::QString && value.isString()) {
- PROPERTY_STORE(QString, value.toQString());
+ PROPERTY_STORE(QString, value.toQStringNoThrow());
} else if (result->isVarProperty()) {
QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
Q_ASSERT(vmemo);
@@ -540,57 +533,59 @@ bool QObjectWrapper::setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlC
return true;
}
-Value QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object)
+ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object)
{
if (QQmlData::wasDeleted(object))
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
QQmlData *ddata = QQmlData::get(object, true);
if (!ddata)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
+
+ Scope scope(engine);
if (ddata->jsEngineId == engine->m_engineId && !ddata->jsWrapper.isEmpty()) {
// We own the JS object
- return ddata->jsWrapper.value();
+ return ddata->jsWrapper.value().asReturnedValue();
} else if (ddata->jsWrapper.isEmpty() &&
(ddata->jsEngineId == engine->m_engineId || // We own the QObject
ddata->jsEngineId == 0 || // No one owns the QObject
!ddata->hasTaintedV8Object)) { // Someone else has used the QObject, but it isn't tainted
- QV4::Value rv = create(engine, ddata, object);
+ QV4::ScopedValue rv(scope, create(engine, ddata, object));
ddata->jsWrapper = rv;
ddata->jsEngineId = engine->m_engineId;
- return rv;
+ return rv.asReturnedValue();
} else {
// If this object is tainted, we have to check to see if it is in our
// tainted object list
- Object *alternateWrapper = 0;
+ Scoped<Object> alternateWrapper(scope, (Object *)0);
if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV8Object)
- alternateWrapper = engine->m_multiplyWrappedQObjects->value(object);
+ alternateWrapper = Value::fromObject(engine->m_multiplyWrappedQObjects->value(object));
// If our tainted handle doesn't exist or has been collected, and there isn't
// a handle in the ddata, we can assume ownership of the ddata->v8object
if (ddata->jsWrapper.isEmpty() && !alternateWrapper) {
- QV4::Value result = create(engine, ddata, object);
+ QV4::ScopedValue result(scope, create(engine, ddata, object));
ddata->jsWrapper = result;
ddata->jsEngineId = engine->m_engineId;
- return result;
+ return result.asReturnedValue();
}
if (!alternateWrapper) {
- alternateWrapper = create(engine, ddata, object).asObject();
+ alternateWrapper = create(engine, ddata, object);
if (!engine->m_multiplyWrappedQObjects)
engine->m_multiplyWrappedQObjects = new MultiplyWrappedQObjectMap;
- engine->m_multiplyWrappedQObjects->insert(object, alternateWrapper);
+ engine->m_multiplyWrappedQObjects->insert(object, alternateWrapper.getPointer());
ddata->hasTaintedV8Object = true;
}
- return QV4::Value::fromObject(alternateWrapper);
+ return alternateWrapper.asReturnedValue();
}
}
-QV4::Value QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObject *object)
+ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObject *object)
{
QQmlEngine *qmlEngine = engine->v8Engine->engine();
if (!ddata->propertyCache && qmlEngine) {
@@ -598,10 +593,10 @@ QV4::Value QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObj
if (ddata->propertyCache) ddata->propertyCache->addref();
}
- return Value::fromObject(new (engine->memoryManager) QV4::QObjectWrapper(engine, object));
+ return Value::fromObject(new (engine->memoryManager) QV4::QObjectWrapper(engine, object)).asReturnedValue();
}
-QV4::Value QObjectWrapper::get(Managed *m, String *name, bool *hasProperty)
+QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProperty)
{
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
ExecutionEngine *v4 = m->engine();
@@ -655,7 +650,7 @@ Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String
++it->arrayIndex;
if (attributes)
*attributes = QV4::Attr_Data;
- it->tmpDynamicProperty.value = that->get(*name);
+ it->tmpDynamicProperty.value = QV4::Value::fromReturnedValue(that->get(*name));
return &it->tmpDynamicProperty;
}
const int methodCount = mo->methodCount();
@@ -664,7 +659,7 @@ Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String
++it->arrayIndex;
if (attributes)
*attributes = QV4::Attr_Data;
- it->tmpDynamicProperty.value = that->get(*name);
+ it->tmpDynamicProperty.value = QV4::Value::fromReturnedValue(that->get(*name));
return &it->tmpDynamicProperty;
}
return QV4::Object::advanceIterator(m, it, name, index, attributes);
@@ -701,14 +696,15 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
QV4::ExecutionEngine *v4 = f->internalClass->engine;
QV4::ExecutionContext *ctx = v4->current;
- QV4::ScopedCallData callData(v4, argCount);
+ Scope scope(v4);
+ QV4::ScopedCallData callData(scope, argCount);
callData->thisObject = This->thisObject.isEmpty() ? Value::fromObject(v4->globalObject) : This->thisObject.value();
for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1];
if (type == qMetaTypeId<QVariant>()) {
- callData->args[ii] = v4->v8Engine->fromVariant(*((QVariant *)metaArgs[ii + 1]));
+ callData->args[ii] = QV4::Value::fromReturnedValue(v4->v8Engine->fromVariant(*((QVariant *)metaArgs[ii + 1])));
} else {
- callData->args[ii] = v4->v8Engine->fromVariant(QVariant(type, metaArgs[ii + 1]));
+ callData->args[ii] = QV4::Value::fromReturnedValue(v4->v8Engine->fromVariant(QVariant(type, metaArgs[ii + 1])));
}
}
@@ -740,7 +736,7 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
return;
}
- QV4::ValueScope scope(v4);
+ QV4::Scope scope(v4);
QV4::ScopedValue function(scope, *reinterpret_cast<QV4::Value*>(metaArgs[1]));
QV4::ScopedValue thisObject(scope, *reinterpret_cast<QV4::Value*>(metaArgs[2]));
QObject *receiverToDisconnect = reinterpret_cast<QObject*>(metaArgs[3]);
@@ -779,7 +775,7 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
} // namespace QV4
-Value QObjectWrapper::method_connect(SimpleCallContext *ctx)
+ReturnedValue QObjectWrapper::method_connect(SimpleCallContext *ctx)
{
if (ctx->argumentCount == 0)
V4THROW_ERROR("Function.prototype.connect: no arguments given");
@@ -815,10 +811,10 @@ Value QObjectWrapper::method_connect(SimpleCallContext *ctx)
QObjectPrivate::connect(signalObject, signalIndex, slot, Qt::AutoConnection);
- return QV4::Value::undefinedValue();
+ return Encode::undefined();
}
-Value QObjectWrapper::method_disconnect(SimpleCallContext *ctx)
+ReturnedValue QObjectWrapper::method_disconnect(SimpleCallContext *ctx)
{
if (ctx->argumentCount == 0)
V4THROW_ERROR("Function.prototype.disconnect: no arguments given");
@@ -864,7 +860,7 @@ Value QObjectWrapper::method_disconnect(SimpleCallContext *ctx)
QObjectPrivate::disconnect(signalObject, signalIndex, reinterpret_cast<void**>(&a));
- return QV4::Value::undefinedValue();
+ return Encode::undefined();
}
static void markChildQObjectsRecursively(QObject *parent)
@@ -967,7 +963,7 @@ struct CallArgument {
inline void initAsType(int type);
inline void fromValue(int type, QV8Engine *, const QV4::Value&);
- inline QV4::Value toValue(QV8Engine *);
+ inline ReturnedValue toValue(QV8Engine *);
private:
CallArgument(const CallArgument &);
@@ -1021,7 +1017,7 @@ private:
};
}
-static QV4::Value CallMethod(QObject *object, int index, int returnType, int argCount,
+static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType, int argCount,
int *argTypes, QV8Engine *engine, CallArgs &callArgs)
{
if (argCount > 0) {
@@ -1068,7 +1064,7 @@ static QV4::Value CallMethod(QObject *object, int index, int returnType, int arg
void *args[] = { 0 };
QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args);
- return QV4::Value::undefinedValue();
+ return Encode::undefined();
}
}
@@ -1264,7 +1260,7 @@ static const QQmlPropertyData * RelatedMethod(QObject *object,
}
}
-static QV4::Value CallPrecise(QObject *object, const QQmlPropertyData &data,
+static QV4::ReturnedValue CallPrecise(QObject *object, const QQmlPropertyData &data,
QV8Engine *engine, CallArgs &callArgs)
{
QByteArray unknownTypeError;
@@ -1318,7 +1314,7 @@ Resolve the overloaded method to call. The algorithm works conceptually like th
If two or more overloads have the same match score, call the last one. The match
score is constructed by adding the matchScore() result for each of the parameters.
*/
-static QV4::Value CallOverloaded(QObject *object, const QQmlPropertyData &data,
+static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData &data,
QV8Engine *engine, CallArgs &callArgs)
{
int argumentCount = callArgs.Length();
@@ -1503,7 +1499,7 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, const QV4::Value &
if (value.isNull() || value.isUndefined())
qstringPtr = new (&allocData) QString();
else
- qstringPtr = new (&allocData) QString(value.toQString());
+ qstringPtr = new (&allocData) QString(value.toQStringNoThrow());
type = callType;
} else if (callType == QMetaType::QObjectStar) {
qobjectPtr = 0;
@@ -1516,10 +1512,14 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, const QV4::Value &
} else if (callType == qMetaTypeId<QList<QObject*> >()) {
qlistPtr = new (&allocData) QList<QObject *>();
if (QV4::ArrayObject *array = value.asArrayObject()) {
+ QV4::Scope scope(array->engine());
+ Scoped<QV4::QObjectWrapper> qobjectWrapper(scope);
+
uint32_t length = array->arrayLength();
for (uint32_t ii = 0; ii < length; ++ii) {
QObject *o = 0;
- if (QV4::QObjectWrapper *qobjectWrapper = array->getIndexed(ii).as<QV4::QObjectWrapper>())
+ qobjectWrapper = array->getIndexed(ii);
+ if (!!qobjectWrapper)
o = qobjectWrapper->object();
qlistPtr->append(o);
}
@@ -1576,23 +1576,25 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, const QV4::Value &
}
}
-QV4::Value CallArgument::toValue(QV8Engine *engine)
+QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope scope(v4);
+
if (type == qMetaTypeId<QJSValue>()) {
return QJSValuePrivate::get(*qjsValuePtr)->getValue(v4);
} else if (type == QMetaType::Int) {
- return QV4::Value::fromInt32(int(intValue));
+ return QV4::Encode(int(intValue));
} else if (type == QMetaType::UInt) {
- return QV4::Value::fromUInt32(intValue);
+ return QV4::Encode((uint)intValue);
} else if (type == QMetaType::Bool) {
- return QV4::Value::fromBoolean(boolValue);
+ return QV4::Encode(boolValue);
} else if (type == QMetaType::Double) {
- return QV4::Value::fromDouble(doubleValue);
+ return QV4::Encode(doubleValue);
} else if (type == QMetaType::Float) {
- return QV4::Value::fromDouble(floatValue);
+ return QV4::Encode(floatValue);
} else if (type == QMetaType::QString) {
- return engine->toString(*qstringPtr);
+ return engine->toString(*qstringPtr).asReturnedValue();
} else if (type == QMetaType::QObjectStar) {
QObject *object = qobjectPtr;
if (object)
@@ -1602,15 +1604,15 @@ QV4::Value CallArgument::toValue(QV8Engine *engine)
// XXX Can this be made more by using Array as a prototype and implementing
// directly against QList<QObject*>?
QList<QObject *> &list = *qlistPtr;
- QV4::ArrayObject *array = v4->newArrayObject();
+ QV4::Scoped<ArrayObject> array(scope, v4->newArrayObject());
array->arrayReserve(list.count());
array->arrayDataLen = list.count();
for (int ii = 0; ii < list.count(); ++ii)
- array->arrayData[ii].value = QV4::QObjectWrapper::wrap(v4, list.at(ii));
+ array->arrayData[ii].value = Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, list.at(ii)));
array->setArrayLengthUnchecked(list.count());
- return QV4::Value::fromObject(array);
+ return array.asReturnedValue();
} else if (type == qMetaTypeId<QQmlV4Handle>()) {
- return handlePtr->toValue();
+ return handlePtr->toValue().asReturnedValue();
} else if (type == QMetaType::QJsonArray) {
return QV4::JsonObject::fromJsonArray(v4, *jsonArrayPtr);
} else if (type == QMetaType::QJsonObject) {
@@ -1619,14 +1621,14 @@ QV4::Value CallArgument::toValue(QV8Engine *engine)
return QV4::JsonObject::fromJsonValue(v4, *jsonValuePtr);
} else if (type == -1 || type == qMetaTypeId<QVariant>()) {
QVariant value = *qvariantPtr;
- QV4::Value rv = engine->fromVariant(value);
- if (QV4::QObjectWrapper *qobjectWrapper = rv.as<QV4::QObjectWrapper>()) {
+ QV4::ScopedValue rv(scope, engine->fromVariant(value));
+ if (QV4::QObjectWrapper *qobjectWrapper = rv->as<QV4::QObjectWrapper>()) {
if (QObject *object = qobjectWrapper->object())
QQmlData::get(object, true)->setImplicitDestructible();
}
- return rv;
+ return rv.asReturnedValue();
} else {
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
}
@@ -1645,7 +1647,7 @@ QObjectMethod::QObjectMethod(ExecutionContext *scope, QObject *object, int index
subtype = WrappedQtMethod;
}
-QV4::Value QObjectMethod::method_toString(QV4::ExecutionContext *ctx)
+QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx)
{
QString result;
if (m_object) {
@@ -1666,13 +1668,13 @@ QV4::Value QObjectMethod::method_toString(QV4::ExecutionContext *ctx)
result = QLatin1String("null");
}
- return QV4::Value::fromString(ctx, result);
+ return QV4::Value::fromString(ctx, result).asReturnedValue();
}
-QV4::Value QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc)
+QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc)
{
if (!m_object)
- return QV4::Value::undefinedValue();
+ return Encode::undefined();
if (QQmlData::keepAliveDuringGarbageCollection(m_object))
ctx->throwError(QStringLiteral("Invalid attempt to destroy() an indestructible object"));
@@ -1685,16 +1687,16 @@ QV4::Value QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const Value
else
m_object->deleteLater();
- return QV4::Value::undefinedValue();
+ return Encode::undefined();
}
-Value QObjectMethod::call(Managed *m, CallData *callData)
+ReturnedValue QObjectMethod::call(Managed *m, CallData *callData)
{
QObjectMethod *This = static_cast<QObjectMethod*>(m);
return This->callInternal(callData);
}
-Value QObjectMethod::callInternal(CallData *callData)
+ReturnedValue QObjectMethod::callInternal(CallData *callData)
{
ExecutionContext *context = engine()->current;
if (m_index == DestroyMethod)
@@ -1704,11 +1706,11 @@ Value QObjectMethod::callInternal(CallData *callData)
QObject *object = m_object.data();
if (!object)
- return QV4::Value::undefinedValue();
+ return Encode::undefined();
QQmlData *ddata = QQmlData::get(object);
if (!ddata)
- return QV4::Value::undefinedValue();
+ return Encode::undefined();
QV8Engine *v8Engine = context->engine->v8Engine;
@@ -1718,7 +1720,7 @@ Value QObjectMethod::callInternal(CallData *callData)
if (ddata->propertyCache) {
QQmlPropertyData *d = ddata->propertyCache->method(m_index);
if (!d)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
method = *d;
}
}
@@ -1727,7 +1729,7 @@ Value QObjectMethod::callInternal(CallData *callData)
method.load(object->metaObject()->method(m_index));
if (method.coreIndex == -1)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
if (method.isV4Function()) {
@@ -1741,7 +1743,7 @@ Value QObjectMethod::callInternal(CallData *callData)
void *args[] = { 0, &funcptr };
QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, method.coreIndex, args);
- return rv;
+ return rv.asReturnedValue();
}
CallArgs callArgs(callData->argc, callData->args);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 3a48fee1ec..95986a4b0d 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -85,17 +85,17 @@ struct Q_QML_EXPORT QObjectWrapper : public QV4::Object
QObject *object() const { return m_object.data(); }
- Value getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false);
- static Value getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0);
+ ReturnedValue getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false);
+ static ReturnedValue getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0);
static bool setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value);
- static Value wrap(ExecutionEngine *engine, QObject *object);
+ static ReturnedValue wrap(ExecutionEngine *engine, QObject *object);
using Object::get;
private:
- static Value create(ExecutionEngine *engine, QQmlData *ddata, QObject *object);
+ static ReturnedValue create(ExecutionEngine *engine, QQmlData *ddata, QObject *object);
QObjectWrapper(ExecutionEngine *engine, QObject *object);
@@ -105,7 +105,7 @@ private:
String *m_destroy;
String *m_toString;
- static Value get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static PropertyAttributes query(const Managed *, String *name);
static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
@@ -116,8 +116,8 @@ private:
static_cast<QObjectWrapper *>(that)->~QObjectWrapper();
}
- static Value method_connect(SimpleCallContext *ctx);
- static Value method_disconnect(SimpleCallContext *ctx);
+ static ReturnedValue method_connect(SimpleCallContext *ctx);
+ static ReturnedValue method_disconnect(SimpleCallContext *ctx);
};
struct QObjectMethod : public QV4::FunctionObject
@@ -134,16 +134,16 @@ struct QObjectMethod : public QV4::FunctionObject
private:
QObjectMethod(QV4::ExecutionContext *scope, QObject *object, int index, const QV4::Value &qmlGlobal);
- QV4::Value method_toString(QV4::ExecutionContext *ctx);
- QV4::Value method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc);
+ QV4::ReturnedValue method_toString(QV4::ExecutionContext *ctx);
+ QV4::ReturnedValue method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc);
QPointer<QObject> m_object;
int m_index;
QV4::PersistentValue m_qmlGlobal;
- static Value call(Managed *, CallData *callData);
+ static ReturnedValue call(Managed *, CallData *callData);
- Value callInternal(CallData *callData);
+ ReturnedValue callInternal(CallData *callData);
static void destroy(Managed *that)
{
@@ -188,7 +188,7 @@ public:
Iterator erase(Iterator it);
void remove(QObject *key);
-private slots:
+private Q_SLOTS:
void removeDestroyedObject(QObject*);
};
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index ab01ce7650..5a9a8d9d1d 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -136,14 +136,14 @@ void RegExp::markObjects(Managed *that)
{
}
-Value RegExp::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue RegExp::get(Managed *, String *, bool *)
{
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
-Value RegExp::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue RegExp::getIndexed(Managed *m, uint index, bool *hasProperty)
{
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
void RegExp::put(Managed *m, String *name, const Value &value)
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index 6edbd4b2ad..f91faf5044 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -111,8 +111,8 @@ public:
protected:
static void destroy(Managed *that);
static void markObjects(Managed *that);
- static Value get(Managed *m, String *name, bool *hasProperty);
- static Value getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue get(Managed *, String *, bool *);
+ static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static void putIndexed(Managed *m, uint index, const Value &value);
static PropertyAttributes query(const Managed *m, String *name);
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 448d10180c..60a5026772 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -206,7 +206,8 @@ QString RegExpObject::toString() const
QString RegExpObject::source() const
{
- return const_cast<RegExpObject *>(this)->get(internalClass->engine->newIdentifier(QStringLiteral("source"))).stringValue()->toQString();
+ Value s = Value::fromReturnedValue(const_cast<RegExpObject *>(this)->get(internalClass->engine->newIdentifier(QStringLiteral("source"))));
+ return s.stringValue()->toQString();
}
uint RegExpObject::flags() const
@@ -229,10 +230,10 @@ RegExpCtor::RegExpCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value RegExpCtor::construct(Managed *m, CallData *callData)
+ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
{
ExecutionContext *ctx = m->engine()->current;
- ValueScope scope(ctx);
+ Scope scope(ctx);
ScopedValue r(scope, callData->argc > 0 ? callData->args[0] : Value::undefinedValue());
ScopedValue f(scope, callData->argc > 1 ? callData->args[1] : Value::undefinedValue());
@@ -240,8 +241,7 @@ Value RegExpCtor::construct(Managed *m, CallData *callData)
if (!f->isUndefined())
ctx->throwTypeError();
- RegExpObject *o = ctx->engine->newRegExpObject(re->value, re->global);
- return Value::fromObject(o);
+ return Encode(ctx->engine->newRegExpObject(re->value, re->global));
}
QString pattern;
@@ -271,15 +271,14 @@ Value RegExpCtor::construct(Managed *m, CallData *callData)
if (!re->isValid())
ctx->throwSyntaxError(0);
- RegExpObject *o = ctx->engine->newRegExpObject(re, global);
- return Value::fromObject(o);
+ return Encode(ctx->engine->newRegExpObject(re, global));
}
-Value RegExpCtor::call(Managed *that, CallData *callData)
+ReturnedValue RegExpCtor::call(Managed *that, CallData *callData)
{
if (callData->argc > 0 && callData->args[0].as<RegExpObject>()) {
if (callData->argc == 1 || callData->args[1].isUndefined())
- return callData->args[0];
+ return callData->args[0].asReturnedValue();
}
return construct(that, callData);
@@ -296,9 +295,9 @@ void RegExpPrototype::init(ExecutionContext *ctx, const Value &ctor)
defineDefaultProperty(ctx, QStringLiteral("compile"), method_compile, 2);
}
-Value RegExpPrototype::method_exec(SimpleCallContext *ctx)
+ReturnedValue RegExpPrototype::method_exec(SimpleCallContext *ctx)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
RegExpObject *r = ctx->thisObject.as<RegExpObject>();
if (!r)
@@ -311,18 +310,18 @@ Value RegExpPrototype::method_exec(SimpleCallContext *ctx)
int offset = r->global ? r->lastIndexProperty(ctx)->value.toInt32() : 0;
if (offset < 0 || offset > s.length()) {
r->lastIndexProperty(ctx)->value = Value::fromInt32(0);
- return Value::nullValue();
+ return Encode::null();
}
uint* matchOffsets = (uint*)alloca(r->value->captureCount() * 2 * sizeof(uint));
int result = r->value->match(s, offset, matchOffsets);
if (result == -1) {
r->lastIndexProperty(ctx)->value = Value::fromInt32(0);
- return Value::nullValue();
+ return Encode::null();
}
// fill in result data
- ArrayObject *array = ctx->engine->newArrayObject(ctx->engine->regExpExecArrayClass);
+ Scoped<ArrayObject> array(scope, ctx->engine->newArrayObject(ctx->engine->regExpExecArrayClass));
int len = r->value->captureCount();
array->arrayReserve(len);
for (int i = 0; i < len; ++i) {
@@ -339,37 +338,39 @@ Value RegExpPrototype::method_exec(SimpleCallContext *ctx)
if (r->global)
r->lastIndexProperty(ctx)->value = Value::fromInt32(matchOffsets[1]);
- return Value::fromObject(array);
+ return array.asReturnedValue();
}
-Value RegExpPrototype::method_test(SimpleCallContext *ctx)
+ReturnedValue RegExpPrototype::method_test(SimpleCallContext *ctx)
{
- Value r = method_exec(ctx);
- return Value::fromBoolean(!r.isNull());
+ Scope scope(ctx);
+ ScopedValue r(scope, method_exec(ctx));
+ return Encode(!r->isNull());
}
-Value RegExpPrototype::method_toString(SimpleCallContext *ctx)
+ReturnedValue RegExpPrototype::method_toString(SimpleCallContext *ctx)
{
RegExpObject *r = ctx->thisObject.as<RegExpObject>();
if (!r)
ctx->throwTypeError();
- return Value::fromString(ctx, r->toString());
+ return Value::fromString(ctx, r->toString()).asReturnedValue();
}
-Value RegExpPrototype::method_compile(SimpleCallContext *ctx)
+ReturnedValue RegExpPrototype::method_compile(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
RegExpObject *r = ctx->thisObject.as<RegExpObject>();
if (!r)
ctx->throwTypeError();
- ScopedCallData callData(ctx->engine, ctx->argumentCount);
+ ScopedCallData callData(scope, ctx->argumentCount);
memcpy(callData->args, ctx->arguments, ctx->argumentCount*sizeof(Value));
- RegExpObject *re = ctx->engine->regExpCtor.asFunctionObject()->construct(callData).as<RegExpObject>();
+ RegExpObject *re = Value::fromReturnedValue(ctx->engine->regExpCtor.asFunctionObject()->construct(callData)).as<RegExpObject>();
r->value = re->value;
r->global = re->global;
- return Value::undefinedValue();
+ return Encode::undefined();
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index a17802e2ff..765e98176c 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -103,13 +103,11 @@ protected:
struct RegExpCtor: FunctionObject
{
+ Q_MANAGED
RegExpCtor(ExecutionContext *scope);
- static Value construct(Managed *m, CallData *callData);
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct RegExpPrototype: RegExpObject
@@ -117,10 +115,10 @@ struct RegExpPrototype: RegExpObject
RegExpPrototype(InternalClass *ic): RegExpObject(ic) {}
void init(ExecutionContext *ctx, const Value &ctor);
- static Value method_exec(SimpleCallContext *ctx);
- static Value method_test(SimpleCallContext *ctx);
- static Value method_toString(SimpleCallContext *ctx);
- static Value method_compile(SimpleCallContext *ctx);
+ static ReturnedValue method_exec(SimpleCallContext *ctx);
+ static ReturnedValue method_test(SimpleCallContext *ctx);
+ static ReturnedValue method_toString(SimpleCallContext *ctx);
+ static ReturnedValue method_compile(SimpleCallContext *ctx);
};
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 733f353330..2bd201e2a1 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -67,6 +67,126 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+#ifdef QV4_COUNT_RUNTIME_FUNCTIONS
+struct RuntimeCounters::Data {
+ enum Type {
+ None = 0,
+ Undefined = 1,
+ Null = 2,
+ Boolean = 3,
+ Integer = 4,
+ Managed = 5,
+ Double = 7
+ };
+
+ static const char *pretty(Type t) {
+ switch (t) {
+ case None: return "";
+ case Undefined: return "Undefined";
+ case Null: return "Null";
+ case Boolean: return "Boolean";
+ case Integer: return "Integer";
+ case Managed: return "Managed";
+ case Double: return "Double";
+ default: return "Unknown";
+ }
+ }
+
+ static unsigned mangle(unsigned tag) {
+ switch (tag) {
+ case Value::Undefined_Type: return Undefined;
+ case Value::Null_Type: return Null;
+ case Value::Boolean_Type: return Boolean;
+ case Value::Integer_Type: return Integer;
+ case Value::Managed_Type: return Managed;
+ default: return Double;
+ }
+ }
+
+ static unsigned mangle(unsigned tag1, unsigned tag2) {
+ return (mangle(tag1) << 3) | mangle(tag2);
+ }
+
+ static void unmangle(unsigned signature, Type &tag1, Type &tag2) {
+ tag1 = Type((signature >> 3) & 7);
+ tag2 = Type(signature & 7);
+ }
+
+ typedef QVector<quint64> Counters;
+ QHash<const char *, Counters> counters;
+
+ inline void count(const char *func, unsigned tag) {
+ QVector<quint64> &cnt = counters[func];
+ if (cnt.isEmpty())
+ cnt.resize(64);
+ cnt[mangle(tag)] += 1;
+ }
+
+ inline void count(const char *func, unsigned tag1, unsigned tag2) {
+ QVector<quint64> &cnt = counters[func];
+ if (cnt.isEmpty())
+ cnt.resize(64);
+ cnt[mangle(tag1, tag2)] += 1;
+ }
+
+ struct Line {
+ const char *func;
+ Type tag1, tag2;
+ quint64 count;
+
+ static bool less(const Line &line1, const Line &line2) {
+ return line1.count > line2.count;
+ }
+ };
+
+ void dump() const {
+ QList<Line> lines;
+ foreach (const char *func, counters.keys()) {
+ const Counters &fCount = counters[func];
+ for (int i = 0, ei = fCount.size(); i != ei; ++i) {
+ quint64 count = fCount[i];
+ if (!count)
+ continue;
+ Line line;
+ line.func = func;
+ unmangle(i, line.tag1, line.tag2);
+ line.count = count;
+ lines.append(line);
+ }
+ }
+ qSort(lines.begin(), lines.end(), Line::less);
+ qDebug() << "Counters:";
+ foreach (const Line &line, lines)
+ qDebug("%10ld | %s | %s | %s", line.count, line.func, pretty(line.tag1), pretty(line.tag2));
+ }
+};
+
+RuntimeCounters *RuntimeCounters::instance = 0;
+static RuntimeCounters runtimeCountersInstance;
+RuntimeCounters::RuntimeCounters()
+ : d(new Data)
+{
+ if (!instance)
+ instance = this;
+}
+
+RuntimeCounters::~RuntimeCounters()
+{
+ d->dump();
+}
+
+void RuntimeCounters::count(const char *func, uint tag)
+{
+ d->count(func, tag);
+}
+
+void RuntimeCounters::count(const char *func, uint tag1, uint tag2)
+{
+ d->count(func, tag1, tag2);
+}
+
+#endif // QV4_COUNT_RUNTIME_FUNCTIONS
+
void __qmljs_numberToString(QString *result, double num, int radix)
{
Q_ASSERT(result);
@@ -120,47 +240,41 @@ void __qmljs_numberToString(QString *result, double num, int radix)
result->prepend(QLatin1Char('-'));
}
-void __qmljs_init_closure(ExecutionContext *ctx, ValueRef result, int functionId)
+ReturnedValue __qmljs_init_closure(ExecutionContext *ctx, int functionId)
{
QV4::Function *clos = ctx->compilationUnit->runtimeFunctions[functionId];
- assert(clos);
- *result = Value::fromObject(FunctionObject::creatScriptFunction(ctx, clos));
+ Q_ASSERT(clos);
+ FunctionObject *f = FunctionObject::creatScriptFunction(ctx, clos);
+ return f->asReturnedValue();
}
-void __qmljs_delete_subscript(ExecutionContext *ctx, ValueRef result, const ValueRef base, const ValueRef index)
+ReturnedValue __qmljs_delete_subscript(ExecutionContext *ctx, const ValueRef base, const ValueRef index)
{
if (Object *o = base->asObject()) {
uint n = index->asArrayIndex();
if (n < UINT_MAX) {
- Value res = Value::fromBoolean(o->deleteIndexedProperty(n));
- if (result)
- *result = res;
- return;
+ return Value::fromBoolean(o->deleteIndexedProperty(n)).asReturnedValue();
}
}
String *name = index->toString(ctx);
- __qmljs_delete_member(ctx, result, base, name);
+ return __qmljs_delete_member(ctx, base, name);
}
-void __qmljs_delete_member(ExecutionContext *ctx, ValueRef result, const ValueRef base, String *name)
+ReturnedValue __qmljs_delete_member(ExecutionContext *ctx, const ValueRef base, String *name)
{
Object *obj = base->toObject(ctx);
- Value res = Value::fromBoolean(obj->deleteProperty(name));
- if (result)
- *result = res;
+ return Value::fromBoolean(obj->deleteProperty(name)).asReturnedValue();
}
-void __qmljs_delete_name(ExecutionContext *ctx, ValueRef result, String *name)
+ReturnedValue __qmljs_delete_name(ExecutionContext *ctx, String *name)
{
- Value res = Value::fromBoolean(ctx->deleteProperty(name));
- if (result)
- *result = res;
+ return Value::fromBoolean(ctx->deleteProperty(name)).asReturnedValue();
}
-void __qmljs_add_helper(ExecutionContext *ctx, ValueRef result, const ValueRef left, const ValueRef right)
+QV4::ReturnedValue __qmljs_add_helper(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
ScopedValue pleft(scope, __qmljs_to_primitive(left, PREFERREDTYPE_HINT));
ScopedValue pright(scope, __qmljs_to_primitive(right, PREFERREDTYPE_HINT));
@@ -169,40 +283,37 @@ void __qmljs_add_helper(ExecutionContext *ctx, ValueRef result, const ValueRef l
pleft = __qmljs_to_string(pleft, ctx);
if (!pright->isString())
pright = __qmljs_to_string(pright, ctx);
- String *string = __qmljs_string_concat(ctx, pleft->stringValue(), pright->stringValue());
- *result = Value::fromString(string);
- return;
+ return __qmljs_string_concat(ctx, pleft->stringValue(), pright->stringValue())->asReturnedValue();
}
double x = __qmljs_to_number(pleft);
double y = __qmljs_to_number(pright);
- *result = Value::fromDouble(x + y);
+ return Value::fromDouble(x + y).asReturnedValue();
}
-void __qmljs_instanceof(ExecutionContext *ctx, ValueRef result, const ValueRef left, const ValueRef right)
+QV4::ReturnedValue __qmljs_instanceof(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
{
Object *o = right->asObject();
if (!o)
ctx->throwTypeError();
bool r = o->hasInstance(*left);
- *result = Value::fromBoolean(r);
+ return Value::fromBoolean(r).asReturnedValue();
}
-void __qmljs_in(ExecutionContext *ctx, ValueRef result, const ValueRef left, const ValueRef right)
+QV4::ReturnedValue __qmljs_in(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
{
if (!right->isObject())
ctx->throwTypeError();
String *s = left->toString(ctx);
bool r = right->objectValue()->__hasProperty__(s);
- *result = Value::fromBoolean(r);
+ return Value::fromBoolean(r).asReturnedValue();
}
static void inplaceBitOp(ExecutionContext *ctx, String *name, const ValueRef value, BinOp op)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
ScopedValue lhs(scope, ctx->getProperty(name));
- ScopedValue result(scope);
- op(result, lhs, value);
+ ScopedValue result(scope, op(lhs, value));
ctx->setProperty(name, result);
}
@@ -224,10 +335,9 @@ void __qmljs_inplace_bit_xor_name(ExecutionContext *ctx, String *name, const Val
void __qmljs_inplace_add_name(ExecutionContext *ctx, String *name, const ValueRef value)
{
- ValueScope scope(ctx);
+ Scope scope(ctx);
ScopedValue lhs(scope, ctx->getProperty(name));
- ScopedValue result(scope);
- __qmljs_add(ctx, result, lhs, value);
+ ScopedValue result(scope, __qmljs_add(ctx, lhs, value));
ctx->setProperty(name, result);
}
@@ -419,15 +529,15 @@ double __qmljs_string_to_number(const QString &string)
return d;
}
-Value __qmljs_string_from_number(ExecutionContext *ctx, double number)
+Returned<String> *__qmljs_string_from_number(ExecutionContext *ctx, double number)
{
QString qstr;
__qmljs_numberToString(&qstr, number, 10);
String *string = ctx->engine->newString(qstr);
- return Value::fromString(string);
+ return string->asReturned<String>();
}
-String *__qmljs_string_concat(ExecutionContext *ctx, String *first, String *second)
+Returned<String> *__qmljs_string_concat(ExecutionContext *ctx, String *first, String *second)
{
const QString &a = first->toQString();
const QString &b = second->toQString();
@@ -437,10 +547,10 @@ String *__qmljs_string_concat(ExecutionContext *ctx, String *first, String *seco
data += a.length();
memcpy(data, b.constData(), b.length()*sizeof(QChar));
- return ctx->engine->newString(newStr);
+ return ctx->engine->newString(newStr)->asReturned<String>();
}
-Value __qmljs_object_default_value(Object *object, int typeHint)
+ReturnedValue __qmljs_object_default_value(Object *object, int typeHint)
{
if (typeHint == PREFERREDTYPE_HINT) {
if (object->asDateObject())
@@ -457,27 +567,26 @@ Value __qmljs_object_default_value(Object *object, int typeHint)
qSwap(meth1, meth2);
ExecutionContext *ctx = engine->current;
+ Scope scope(ctx);
+ ScopedCallData callData(scope, 0);
+ callData->thisObject = Value::fromObject(object);
- Value conv = object->get(meth1);
- if (FunctionObject *o = conv.asFunctionObject()) {
- ScopedCallData callData(engine, 0);
- callData->thisObject = Value::fromObject(object);
- Value r = o->call(callData);
+ ScopedValue conv(scope, object->get(meth1));
+ if (FunctionObject *o = conv->asFunctionObject()) {
+ Value r = Value::fromReturnedValue(o->call(callData));
if (r.isPrimitive())
- return r;
+ return r.asReturnedValue();
}
conv = object->get(meth2);
- if (FunctionObject *o = conv.asFunctionObject()) {
- ScopedCallData callData(engine, 0);
- callData->thisObject = Value::fromObject(object);
- Value r = o->call(callData);
+ if (FunctionObject *o = conv->asFunctionObject()) {
+ Value r = Value::fromReturnedValue(o->call(callData));
if (r.isPrimitive())
- return r;
+ return r.asReturnedValue();
}
ctx->throwTypeError();
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
Bool __qmljs_to_boolean(const ValueRef value)
@@ -486,7 +595,7 @@ Bool __qmljs_to_boolean(const ValueRef value)
}
-Object *__qmljs_convert_to_object(ExecutionContext *ctx, const ValueRef value)
+Returned<Object> *__qmljs_convert_to_object(ExecutionContext *ctx, const ValueRef value)
{
assert(!value->isObject());
switch (value->type()) {
@@ -495,42 +604,40 @@ Object *__qmljs_convert_to_object(ExecutionContext *ctx, const ValueRef value)
ctx->throwTypeError();
case Value::Boolean_Type:
return ctx->engine->newBooleanObject(*value);
- case Value::String_Type:
+ case Value::Managed_Type:
+ Q_ASSERT(value->isString());
return ctx->engine->newStringObject(*value);
- break;
- case Value::Object_Type:
- Q_UNREACHABLE();
case Value::Integer_Type:
default: // double
return ctx->engine->newNumberObject(*value);
}
}
-String *__qmljs_convert_to_string(ExecutionContext *ctx, const ValueRef value)
+Returned<String> *__qmljs_convert_to_string(ExecutionContext *ctx, const ValueRef value)
{
switch (value->type()) {
case Value::Undefined_Type:
- return ctx->engine->id_undefined;
+ case Value::Empty_Type:
+ return ctx->engine->id_undefined->asReturned<String>();
case Value::Null_Type:
- return ctx->engine->id_null;
+ return ctx->engine->id_null->asReturned<String>();
case Value::Boolean_Type:
if (value->booleanValue())
- return ctx->engine->id_true;
- else
- return ctx->engine->id_false;
- case Value::String_Type:
- return value->stringValue();
- case Value::Object_Type: {
- Value prim = __qmljs_to_primitive(value, STRING_HINT);
- if (prim.isPrimitive())
- return __qmljs_convert_to_string(ctx, ValueRef(&prim));
+ return ctx->engine->id_true->asReturned<String>();
else
- ctx->throwTypeError();
- }
+ return ctx->engine->id_false->asReturned<String>();
+ case Value::Managed_Type:
+ if (value->isString())
+ return value->stringValue()->asReturned<String>();
+ {
+ Scope scope(ctx);
+ ScopedValue prim(scope, __qmljs_to_primitive(value, STRING_HINT));
+ return __qmljs_convert_to_string(ctx, prim);
+ }
case Value::Integer_Type:
- return __qmljs_string_from_number(ctx, value->int_32).stringValue();
+ return __qmljs_string_from_number(ctx, value->int_32);
default: // double
- return __qmljs_string_from_number(ctx, value->doubleValue()).stringValue();
+ return __qmljs_string_from_number(ctx, value->doubleValue());
} // switch
}
@@ -540,28 +647,25 @@ void __qmljs_set_property(ExecutionContext *ctx, const ValueRef object, String *
o->put(name, *value);
}
-void __qmljs_get_element(ExecutionContext *ctx, ValueRef result, const ValueRef object, const ValueRef index)
+ReturnedValue __qmljs_get_element(ExecutionContext *ctx, const ValueRef object, const ValueRef index)
{
+ Scope scope(ctx);
uint idx = index->asArrayIndex();
- Object *o = object->asObject();
+ Scoped<Object> o(scope, object);
if (!o) {
if (idx < UINT_MAX) {
if (String *str = object->asString()) {
if (idx >= (uint)str->toQString().length()) {
- if (result)
- *result = Value::undefinedValue();
- return;
+ return Value::undefinedValue().asReturnedValue();
}
const QString s = str->toQString().mid(idx, 1);
- if (result)
- *result = Value::fromString(ctx, s);
- return;
+ return Value::fromString(ctx, s).asReturnedValue();
}
}
if (object->isNullOrUndefined()) {
- QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index->toQString()).arg(object->toQString());
+ QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index->toQStringNoThrow()).arg(object->toQStringNoThrow());
ctx->throwTypeError(message);
}
@@ -572,26 +676,20 @@ void __qmljs_get_element(ExecutionContext *ctx, ValueRef result, const ValueRef
uint pidx = o->propertyIndexFromArrayIndex(idx);
if (pidx < UINT_MAX) {
if (!o->arrayAttributes || o->arrayAttributes[pidx].isData()) {
- if (result)
- *result = o->arrayData[pidx].value;
- return;
+ return o->arrayData[pidx].value.asReturnedValue();
}
}
- Value res = o->getIndexed(idx);
- if (result)
- *result = res;
- return;
+ return o->getIndexed(idx);
}
String *name = index->toString(ctx);
- Value res = o->get(name);
- if (result)
- *result = res;
+ return o->get(name);
}
void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const ValueRef index, const ValueRef value)
{
+ Scope scope(ctx);
Object *o = object->toObject(ctx);
uint idx = index->asArrayIndex();
@@ -618,7 +716,7 @@ void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const Val
return;
}
- ScopedCallData callData(ctx->engine, 1);
+ ScopedCallData callData(scope, 1);
callData->thisObject = Value::fromObject(o);
callData->args[0] = *value;
setter->call(callData);
@@ -633,23 +731,24 @@ void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const Val
o->put(name, *value);
}
-void __qmljs_foreach_iterator_object(ExecutionContext *ctx, ValueRef result, const ValueRef in)
+ReturnedValue __qmljs_foreach_iterator_object(ExecutionContext *ctx, const ValueRef in)
{
- Object *o = 0;
+ Scope scope(ctx);
+ Scoped<Object> o(scope, (Object *)0);
if (!in->isNullOrUndefined())
- o = in->toObject(ctx);
- Object *it = ctx->engine->newForEachIteratorObject(ctx, o);
- *result = Value::fromObject(it);
+ o = in;
+ Scoped<Object> it(scope, ctx->engine->newForEachIteratorObject(ctx, o.getPointer()));
+ return it.asReturnedValue();
}
-void __qmljs_foreach_next_property_name(ValueRef result, const ValueRef foreach_iterator)
+ReturnedValue __qmljs_foreach_next_property_name(const ValueRef foreach_iterator)
{
- assert(foreach_iterator->isObject());
+ Q_ASSERT(foreach_iterator->isObject());
ForEachIteratorObject *it = static_cast<ForEachIteratorObject *>(foreach_iterator->objectValue());
- assert(it->as<ForEachIteratorObject>());
+ Q_ASSERT(it->as<ForEachIteratorObject>());
- *result = it->nextPropertyName();
+ return it->nextPropertyName();
}
@@ -658,33 +757,31 @@ void __qmljs_set_activation_property(ExecutionContext *ctx, String *name, const
ctx->setProperty(name, *value);
}
-void __qmljs_get_property(ExecutionContext *ctx, ValueRef result, const ValueRef object, String *name)
+ReturnedValue __qmljs_get_property(ExecutionContext *ctx, const ValueRef object, String *name)
{
- Value res;
- Managed *m = object->asManaged();
- if (m) {
- res = m->get(name);
- } else {
- if (object->isNullOrUndefined()) {
- QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()).arg(object->toQString());
- ctx->throwTypeError(message);
- }
+ Scope scope(ctx);
+
+ Scoped<Object> o(scope, object);
+ if (o)
+ return o->get(name);
- m = __qmljs_convert_to_object(ctx, object);
- res = m->get(name);
+ if (object->isNullOrUndefined()) {
+ QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()).arg(object->toQStringNoThrow());
+ ctx->throwTypeError(message);
}
- if (result)
- *result = res;
+
+ o = __qmljs_convert_to_object(ctx, object);
+ return o->get(name);
}
-void __qmljs_get_activation_property(ExecutionContext *ctx, ValueRef result, String *name)
+ReturnedValue __qmljs_get_activation_property(ExecutionContext *ctx, String *name)
{
- *result = ctx->getProperty(name);
+ return ctx->getProperty(name);
}
uint __qmljs_equal_helper(const ValueRef x, const ValueRef y)
{
- Q_ASSERT(x->type() != y->type());
+ Q_ASSERT(x->type() != y->type() || (x->isManaged() && (x->isString() != y->isString())));
if (x->isNumber() && y->isNumber())
return x->asDouble() == y->asDouble();
@@ -705,11 +802,13 @@ uint __qmljs_equal_helper(const ValueRef x, const ValueRef y)
Value ny = Value::fromDouble((double) y->booleanValue());
return __qmljs_cmp_eq(x, ValueRef(&ny));
} else if ((x->isNumber() || x->isString()) && y->isObject()) {
- Value py = __qmljs_to_primitive(y, PREFERREDTYPE_HINT);
- return __qmljs_cmp_eq(x, ValueRef(&py));
+ Scope scope(y->objectValue()->engine());
+ ScopedValue py(scope, __qmljs_to_primitive(y, PREFERREDTYPE_HINT));
+ return __qmljs_cmp_eq(x, py);
} else if (x->isObject() && (y->isNumber() || y->isString())) {
- Value px = __qmljs_to_primitive(x, PREFERREDTYPE_HINT);
- return __qmljs_cmp_eq(ValueRef(&px), y);
+ Scope scope(x->objectValue()->engine());
+ ScopedValue px(scope, __qmljs_to_primitive(x, PREFERREDTYPE_HINT));
+ return __qmljs_cmp_eq(px, y);
}
return false;
@@ -721,7 +820,7 @@ Bool __qmljs_strict_equal(const ValueRef x, const ValueRef y)
if (x->rawValue() == y->rawValue())
// NaN != NaN
- return (x->tag & QV4::Value::NotDouble_Mask) != QV4::Value::NaN_Mask;
+ return !x->isNaN();
if (x->isNumber())
return y->isNumber() && x->asDouble() == y->asDouble();
@@ -730,181 +829,244 @@ Bool __qmljs_strict_equal(const ValueRef x, const ValueRef y)
return false;
}
+QV4::Bool __qmljs_cmp_gt(const QV4::ValueRef l, const QV4::ValueRef r)
+{
+ TRACE2(l, r);
+ if (QV4::Value::integerCompatible(*l, *r))
+ return l->integerValue() > r->integerValue();
+ if (QV4::Value::bothDouble(*l, *r))
+ return l->doubleValue() > r->doubleValue();
+ if (l->isString() && r->isString())
+ return r->stringValue()->compare(l->stringValue());
+
+ if (l->isObject() || r->isObject()) {
+ QV4::ExecutionEngine *e = (l->isObject() ? l->objectValue() : r->objectValue())->engine();
+ QV4::Scope scope(e);
+ QV4::ScopedValue pl(scope, __qmljs_to_primitive(l, QV4::NUMBER_HINT));
+ QV4::ScopedValue pr(scope, __qmljs_to_primitive(r, QV4::NUMBER_HINT));
+ return __qmljs_cmp_gt(pl, pr);
+ }
+
+ double dl = __qmljs_to_number(l);
+ double dr = __qmljs_to_number(r);
+ return dl > dr;
+}
+
+QV4::Bool __qmljs_cmp_lt(const QV4::ValueRef l, const QV4::ValueRef r)
+{
+ TRACE2(l, r);
+ if (QV4::Value::integerCompatible(*l, *r))
+ return l->integerValue() < r->integerValue();
+ if (QV4::Value::bothDouble(*l, *r))
+ return l->doubleValue() < r->doubleValue();
+ if (l->isString() && r->isString())
+ return l->stringValue()->compare(r->stringValue());
+
+ if (l->isObject() || r->isObject()) {
+ QV4::ExecutionEngine *e = (l->isObject() ? l->objectValue() : r->objectValue())->engine();
+ QV4::Scope scope(e);
+ QV4::ScopedValue pl(scope, __qmljs_to_primitive(l, QV4::NUMBER_HINT));
+ QV4::ScopedValue pr(scope, __qmljs_to_primitive(r, QV4::NUMBER_HINT));
+ return __qmljs_cmp_lt(pl, pr);
+ }
+
+ double dl = __qmljs_to_number(l);
+ double dr = __qmljs_to_number(r);
+ return dl < dr;
+}
+
+QV4::Bool __qmljs_cmp_ge(const QV4::ValueRef l, const QV4::ValueRef r)
+{
+ TRACE2(l, r);
+ if (QV4::Value::integerCompatible(*l, *r))
+ return l->integerValue() >= r->integerValue();
+ if (QV4::Value::bothDouble(*l, *r))
+ return l->doubleValue() >= r->doubleValue();
+ if (l->isString() && r->isString())
+ return !l->stringValue()->compare(r->stringValue());
+
+ if (l->isObject() || r->isObject()) {
+ QV4::ExecutionEngine *e = (l->isObject() ? l->objectValue() : r->objectValue())->engine();
+ QV4::Scope scope(e);
+ QV4::ScopedValue pl(scope, __qmljs_to_primitive(l, QV4::NUMBER_HINT));
+ QV4::ScopedValue pr(scope, __qmljs_to_primitive(r, QV4::NUMBER_HINT));
+ return __qmljs_cmp_ge(pl, pr);
+ }
+
+ double dl = __qmljs_to_number(l);
+ double dr = __qmljs_to_number(r);
+ return dl >= dr;
+}
+
+QV4::Bool __qmljs_cmp_le(const QV4::ValueRef l, const QV4::ValueRef r)
+{
+ TRACE2(l, r);
+ if (QV4::Value::integerCompatible(*l, *r))
+ return l->integerValue() <= r->integerValue();
+ if (QV4::Value::bothDouble(*l, *r))
+ return l->doubleValue() <= r->doubleValue();
+ if (l->isString() && r->isString())
+ return !r->stringValue()->compare(l->stringValue());
+
+ if (l->isObject() || r->isObject()) {
+ QV4::ExecutionEngine *e = (l->isObject() ? l->objectValue() : r->objectValue())->engine();
+ QV4::Scope scope(e);
+ QV4::ScopedValue pl(scope, __qmljs_to_primitive(l, QV4::NUMBER_HINT));
+ QV4::ScopedValue pr(scope, __qmljs_to_primitive(r, QV4::NUMBER_HINT));
+ return __qmljs_cmp_le(pl, pr);
+ }
+
+ double dl = __qmljs_to_number(l);
+ double dr = __qmljs_to_number(r);
+ return dl <= dr;
+}
+
-void __qmljs_call_global_lookup(ExecutionContext *context, ValueRef result, uint index, CallDataRef callData)
+ReturnedValue __qmljs_call_global_lookup(ExecutionContext *context, uint index, CallDataRef callData)
{
+ Scope scope(context);
Q_ASSERT(callData->thisObject.isUndefined());
Lookup *l = context->lookups + index;
- Value v;
- l->globalGetter(l, context, &v);
- FunctionObject *o = v.asFunctionObject();
+ Scoped<FunctionObject> o(scope, l->globalGetter(l, context));
if (!o)
context->throwTypeError();
- if (o == context->engine->evalFunction && l->name->isEqualTo(context->engine->id_eval)) {
- Value res = static_cast<EvalFunction *>(o)->evalCall(callData->thisObject, callData->args, callData->argc, true);
- if (result)
- *result = res;
- return;
- }
+ if (o.getPointer() == context->engine->evalFunction && l->name->isEqualTo(context->engine->id_eval))
+ return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData->thisObject, callData->args, callData->argc, true);
- Value res = o->call(callData);
- if (result)
- *result = res;
+ return o->call(callData);
}
-void __qmljs_call_activation_property(ExecutionContext *context, ValueRef result, String *name, CallDataRef callData)
+ReturnedValue __qmljs_call_activation_property(ExecutionContext *context, String *name, CallDataRef callData)
{
Q_ASSERT(callData->thisObject.isUndefined());
+ Scope scope(context);
Object *base;
- Value func = context->getPropertyAndBase(name, &base);
+ ScopedValue func(scope, context->getPropertyAndBase(name, &base));
if (base)
callData->thisObject = Value::fromObject(base);
- FunctionObject *o = func.asFunctionObject();
+ FunctionObject *o = func->asFunctionObject();
if (!o) {
QString objectAsString = QStringLiteral("[null]");
if (base)
- objectAsString = Value::fromObject(base).toQString();
+ objectAsString = Value::fromObject(base).toQStringNoThrow();
QString msg = QStringLiteral("Property '%1' of object %2 is not a function").arg(name->toQString()).arg(objectAsString);
context->throwTypeError(msg);
}
if (o == context->engine->evalFunction && name->isEqualTo(context->engine->id_eval)) {
- Value res = static_cast<EvalFunction *>(o)->evalCall(callData->thisObject, callData->args, callData->argc, true);
- if (result)
- *result = res;
- return;
+ return static_cast<EvalFunction *>(o)->evalCall(callData->thisObject, callData->args, callData->argc, true);
}
- Value res = o->call(callData);
- if (result)
- *result = res;
+ return o->call(callData);
}
-void __qmljs_call_property(ExecutionContext *context, ValueRef result, String *name, CallDataRef callData)
+ReturnedValue __qmljs_call_property(ExecutionContext *context, String *name, CallDataRef callData)
{
- Managed *baseObject = callData->thisObject.asManaged();
+ Scope scope(context);
+ Scoped<Object> baseObject(scope, callData->thisObject);
if (!baseObject) {
- if (callData->thisObject.isNullOrUndefined()) {
- QString message = QStringLiteral("Cannot call method '%1' of %2").arg(name->toQString()).arg(callData->thisObject.toQString());
+ if (callData->thisObject.isNullOrUndefined() || callData->thisObject.isEmpty()) {
+ QString message = QStringLiteral("Cannot call method '%1' of %2").arg(name->toQString()).arg(callData->thisObject.toQStringNoThrow());
context->throwTypeError(message);
}
baseObject = __qmljs_convert_to_object(context, ValueRef(&callData->thisObject));
- callData->thisObject = Value::fromObject(static_cast<Object *>(baseObject));
+ callData->thisObject = baseObject.asValue();
}
- FunctionObject *o = baseObject->get(name).asFunctionObject();
+ Scoped<FunctionObject> o(scope, baseObject->get(name));
if (!o) {
- QString error = QString("Property '%1' of object %2 is not a function").arg(name->toQString(), callData->thisObject.toQString());
+ QString error = QString("Property '%1' of object %2 is not a function").arg(name->toQString(), callData->thisObject.toQStringNoThrow());
context->throwTypeError(error);
}
- Value res = o->call(callData);
- if (result)
- *result = res;
+ return o->call(callData);
}
-void __qmljs_call_property_lookup(ExecutionContext *context, ValueRef result, uint index, CallDataRef callData)
+ReturnedValue __qmljs_call_property_lookup(ExecutionContext *context, uint index, CallDataRef callData)
{
- Value func;
+ Scope scope(context);
Lookup *l = context->lookups + index;
- l->getter(l, &func, callData->thisObject);
-
- Object *o = func.asObject();
+ Scoped<Object> o(scope, l->getter(l, callData->thisObject));
if (!o)
context->throwTypeError();
- Value res = o->call(callData);
- if (result)
- *result = res;
+ return o->call(callData);
}
-void __qmljs_call_element(ExecutionContext *context, ValueRef result, const ValueRef index, CallDataRef callData)
+ReturnedValue __qmljs_call_element(ExecutionContext *context, const ValueRef index, CallDataRef callData)
{
+ Scope scope(context);
Object *baseObject = callData->thisObject.toObject(context);
callData->thisObject = Value::fromObject(baseObject);
- Object *o = baseObject->get(index->toString(context)).asObject();
+ Scoped<Object> o(scope, baseObject->get(index->toString(context)));
if (!o)
context->throwTypeError();
- Value res = o->call(callData);
- if (result)
- *result = res;
+ return o->call(callData);
}
-void __qmljs_call_value(ExecutionContext *context, ValueRef result, const ValueRef func, CallDataRef callData)
+ReturnedValue __qmljs_call_value(ExecutionContext *context, const ValueRef func, CallDataRef callData)
{
Object *o = func->asObject();
if (!o)
context->throwTypeError();
- Value res = o->call(callData);
- if (result)
- *result = res;
+ return o->call(callData);
}
-void __qmljs_construct_global_lookup(ExecutionContext *context, ValueRef result, uint index, CallDataRef callData)
+ReturnedValue __qmljs_construct_global_lookup(ExecutionContext *context, uint index, CallDataRef callData)
{
+ Scope scope(context);
Q_ASSERT(callData->thisObject.isUndefined());
- Value func;
-
Lookup *l = context->lookups + index;
- l->globalGetter(l, context, &func);
-
- Object *f = func.asObject();
+ Scoped<Object> f(scope, l->globalGetter(l, context));
if (!f)
context->throwTypeError();
- Value res = f->construct(callData);
- if (result)
- *result = res;
+ return f->construct(callData);
}
-void __qmljs_construct_activation_property(ExecutionContext *context, ValueRef result, String *name, CallDataRef callData)
+ReturnedValue __qmljs_construct_activation_property(ExecutionContext *context, String *name, CallDataRef callData)
{
- Value func = context->getProperty(name);
- Object *f = func.asObject();
+ Scope scope(context);
+ ScopedValue func(scope, context->getProperty(name));
+ Object *f = func->asObject();
if (!f)
context->throwTypeError();
- Value res = f->construct(callData);
- if (result)
- *result = res;
+ return f->construct(callData);
}
-void __qmljs_construct_value(ExecutionContext *context, ValueRef result, const ValueRef func, CallDataRef callData)
+ReturnedValue __qmljs_construct_value(ExecutionContext *context, const ValueRef func, CallDataRef callData)
{
Object *f = func->asObject();
if (!f)
context->throwTypeError();
- Value res = f->construct(callData);
- if (result)
- *result = res;
+ return f->construct(callData);
}
-void __qmljs_construct_property(ExecutionContext *context, ValueRef result, const ValueRef base, String *name, CallDataRef callData)
+ReturnedValue __qmljs_construct_property(ExecutionContext *context, const ValueRef base, String *name, CallDataRef callData)
{
+ Scope scope(context);
Object *thisObject = base->toObject(context);
- Value func = thisObject->get(name);
- Object *f = func.asObject();
+ Scoped<Object> f(scope, thisObject->get(name));
if (!f)
context->throwTypeError();
- Value res = f->construct(callData);
- if (result)
- *result = res;
+ return f->construct(callData);
}
void __qmljs_throw(ExecutionContext *context, const ValueRef value)
@@ -912,10 +1074,8 @@ void __qmljs_throw(ExecutionContext *context, const ValueRef value)
Exception::throwException(context, *value);
}
-void __qmljs_builtin_typeof(ExecutionContext *ctx, ValueRef result, const ValueRef value)
+ReturnedValue __qmljs_builtin_typeof(ExecutionContext *ctx, const ValueRef value)
{
- if (!result)
- return;
String *res = 0;
switch (value->type()) {
case Value::Undefined_Type:
@@ -927,11 +1087,10 @@ void __qmljs_builtin_typeof(ExecutionContext *ctx, ValueRef result, const ValueR
case Value::Boolean_Type:
res = ctx->engine->id_boolean;
break;
- case Value::String_Type:
- res = ctx->engine->id_string;
- break;
- case Value::Object_Type:
- if (value->objectValue()->asFunctionObject())
+ case Value::Managed_Type:
+ if (value->isString())
+ res = ctx->engine->id_string;
+ else if (value->objectValue()->asFunctionObject())
res = ctx->engine->id_function;
else
res = ctx->engine->id_object; // ### implementation-defined
@@ -940,201 +1099,31 @@ void __qmljs_builtin_typeof(ExecutionContext *ctx, ValueRef result, const ValueR
res = ctx->engine->id_number;
break;
}
- *result = Value::fromString(res);
+ return Value::fromString(res).asReturnedValue();
}
-void __qmljs_builtin_typeof_name(ExecutionContext *context, ValueRef result, String *name)
+QV4::ReturnedValue __qmljs_builtin_typeof_name(ExecutionContext *context, String *name)
{
- ValueScope scope(context);
- ScopedValue res(scope);
+ Scope scope(context);
ScopedValue prop(scope, context->getPropertyNoThrow(name));
- __qmljs_builtin_typeof(context, res, prop);
- if (result)
- *result = res;
+ return __qmljs_builtin_typeof(context, prop);
}
-void __qmljs_builtin_typeof_member(ExecutionContext *context, ValueRef result, const ValueRef base,
- String *name)
+QV4::ReturnedValue __qmljs_builtin_typeof_member(ExecutionContext *context, const ValueRef base, String *name)
{
- ValueScope scope(context);
+ Scope scope(context);
Object *obj = base->toObject(context);
- ScopedValue res(scope);
ScopedValue prop(scope, obj->get(name));
- __qmljs_builtin_typeof(context, res, prop);
- if (result)
- *result = res;
+ return __qmljs_builtin_typeof(context, prop);
}
-void __qmljs_builtin_typeof_element(ExecutionContext *context, ValueRef result, const ValueRef base, const ValueRef index)
+QV4::ReturnedValue __qmljs_builtin_typeof_element(ExecutionContext *context, const ValueRef base, const ValueRef index)
{
- ValueScope scope(context);
+ Scope scope(context);
String *name = index->toString(context);
Object *obj = base->toObject(context);
- ScopedValue res(scope);
ScopedValue prop(scope, obj->get(name));
- __qmljs_builtin_typeof(context, res, prop);
- if (result)
- *result = res;
-}
-
-void __qmljs_builtin_post_increment(ValueRef result, ValueRef val)
-{
- if (val->isInteger() && val->integerValue() < INT_MAX) {
- if (result)
- *result = *val;
- val->int_32 += 1;
- return;
- }
-
- double d = val->toNumber();
- *val = Value::fromDouble(d + 1);
- if (result)
- *result = Value::fromDouble(d);
-}
-
-void __qmljs_builtin_post_increment_name(ExecutionContext *context, ValueRef result, String *name)
-{
- Value v = context->getProperty(name);
-
- if (v.isInteger() && v.integerValue() < INT_MAX) {
- if (result)
- *result = v;
- v.int_32 += 1;
- } else {
- double d = v.toNumber();
- if (result)
- *result = Value::fromDouble(d);
- v = Value::fromDouble(d + 1);
- }
-
- context->setProperty(name, v);
-}
-
-void __qmljs_builtin_post_increment_member(ExecutionContext *context, ValueRef result, const ValueRef base, String *name)
-{
- Object *o = base->toObject(context);
-
- Value v = o->get(name);
-
- if (v.isInteger() && v.integerValue() < INT_MAX) {
- if (result)
- *result = v;
- v.int_32 += 1;
- } else {
- double d = v.toNumber();
- if (result)
- *result = Value::fromDouble(d);
- v = Value::fromDouble(d + 1);
- }
-
- o->put(name, v);
-}
-
-void __qmljs_builtin_post_increment_element(ExecutionContext *context, ValueRef result, const ValueRef base, const ValueRef index)
-{
- Object *o = base->toObject(context);
-
- uint idx = index->asArrayIndex();
-
- if (idx == UINT_MAX) {
- String *s = index->toString(context);
- return __qmljs_builtin_post_increment_member(context, result, base, s);
- }
-
- Value v = o->getIndexed(idx);
-
- if (v.isInteger() && v.integerValue() < INT_MAX) {
- if (result)
- *result = v;
- v.int_32 += 1;
- } else {
- double d = v.toNumber();
- if (result)
- *result = Value::fromDouble(d);
- v = Value::fromDouble(d + 1);
- }
-
- o->putIndexed(idx, v);
-}
-
-void __qmljs_builtin_post_decrement(ValueRef result, ValueRef val)
-{
- if (val->isInteger() && val->integerValue() > INT_MIN) {
- if (result)
- *result = *val;
- val->int_32 -= 1;
- return;
- }
-
- double d = val->toNumber();
- *val = Value::fromDouble(d - 1);
- if (result)
- *result = Value::fromDouble(d);
-}
-
-void __qmljs_builtin_post_decrement_name(ExecutionContext *context, ValueRef result, String *name)
-{
- Value v = context->getProperty(name);
-
- if (v.isInteger() && v.integerValue() > INT_MIN) {
- if (result)
- *result = v;
- v.int_32 -= 1;
- } else {
- double d = v.toNumber();
- if (result)
- *result = Value::fromDouble(d);
- v = Value::fromDouble(d - 1);
- }
-
- context->setProperty(name, v);
-}
-
-void __qmljs_builtin_post_decrement_member(ExecutionContext *context, ValueRef result, const ValueRef base, String *name)
-{
- Object *o = base->toObject(context);
-
- Value v = o->get(name);
-
- if (v.isInteger() && v.integerValue() > INT_MIN) {
- if (result)
- *result = v;
- v.int_32 -= 1;
- } else {
- double d = v.toNumber();
- if (result)
- *result = Value::fromDouble(d);
- v = Value::fromDouble(d - 1);
- }
-
- o->put(name, v);
-}
-
-void __qmljs_builtin_post_decrement_element(ExecutionContext *context, ValueRef result, const ValueRef base, const ValueRef index)
-{
- Object *o = base->toObject(context);
-
- uint idx = index->asArrayIndex();
-
- if (idx == UINT_MAX) {
- String *s = index->toString(context);
- return __qmljs_builtin_post_decrement_member(context, result, base, s);
- }
-
- Value v = o->getIndexed(idx);
-
- if (v.isInteger() && v.integerValue() > INT_MIN) {
- if (result)
- *result = v;
- v.int_32 -= 1;
- } else {
- double d = v.toNumber();
- if (result)
- *result = Value::fromDouble(d);
- v = Value::fromDouble(d - 1);
- }
-
- o->putIndexed(idx, v);
+ return __qmljs_builtin_typeof(context, prop);
}
ExecutionContext *__qmljs_builtin_push_with_scope(const ValueRef o, ExecutionContext *ctx)
@@ -1168,9 +1157,10 @@ void __qmljs_builtin_define_property(ExecutionContext *ctx, const ValueRef objec
pd->value = val ? *val : Value::undefinedValue();
}
-void __qmljs_builtin_define_array(ExecutionContext *ctx, ValueRef array, Value *values, uint length)
+ReturnedValue __qmljs_builtin_define_array(ExecutionContext *ctx, Value *values, uint length)
{
- ArrayObject *a = ctx->engine->newArrayObject();
+ Scope scope(ctx);
+ Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
// ### FIXME: We need to allocate the array data to avoid crashes other places
// This should rather be done when required
@@ -1190,7 +1180,7 @@ void __qmljs_builtin_define_array(ExecutionContext *ctx, ValueRef array, Value *
}
a->setArrayLengthUnchecked(length);
}
- *array = Value::fromObject(a);
+ return a.asReturnedValue();
}
void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const ValueRef object, String *name, const ValueRef getter, const ValueRef setter)
@@ -1204,7 +1194,7 @@ void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const ValueRef
pd->setSetter(setter ? setter->asFunctionObject() : 0);
}
-void __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, ValueRef result, const QV4::Value *args, int classId)
+ReturnedValue __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, const QV4::Value *args, int classId)
{
QV4::InternalClass *klass = ctx->compilationUnit->runtimeClasses[classId];
Object *o = ctx->engine->newObject(klass);
@@ -1220,44 +1210,58 @@ void __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, ValueRef
}
}
- *result = Value::fromObject(o);
+ return Value::fromObject(o).asReturnedValue();
}
-void __qmljs_builtin_setup_arguments_object(ExecutionContext *ctx, ValueRef result)
+QV4::ReturnedValue __qmljs_builtin_setup_arguments_object(ExecutionContext *ctx)
{
assert(ctx->type >= ExecutionContext::Type_CallContext);
CallContext *c = static_cast<CallContext *>(ctx);
ArgumentsObject *args = new (c->engine->memoryManager) ArgumentsObject(c);
- *result = Value::fromObject(args);
+ return Value::fromObject(args).asReturnedValue();
}
-void __qmljs_increment(QV4::ValueRef result, const QV4::ValueRef value)
+QV4::ReturnedValue __qmljs_increment(const QV4::ValueRef value)
{
TRACE1(value);
if (value->isInteger())
- *result = Value::fromInt32(value->integerValue() + 1);
+ return Value::fromInt32(value->integerValue() + 1).asReturnedValue();
else {
double d = value->toNumber();
- *result = Value::fromDouble(d + 1);
+ return Value::fromDouble(d + 1).asReturnedValue();
}
}
-void __qmljs_decrement(QV4::ValueRef result, const QV4::ValueRef value)
+QV4::ReturnedValue __qmljs_decrement(const QV4::ValueRef value)
{
TRACE1(value);
if (value->isInteger())
- *result = Value::fromInt32(value->integerValue() - 1);
+ return Value::fromInt32(value->integerValue() - 1).asReturnedValue();
else {
double d = value->toNumber();
- *result = Value::fromDouble(d - 1);
+ return Value::fromDouble(d - 1).asReturnedValue();
}
}
-void __qmljs_value_to_double(double *result, const ValueRef value)
+QV4::ReturnedValue __qmljs_to_string(const QV4::ValueRef value, QV4::ExecutionContext *ctx)
+{
+ if (value->isString())
+ return value.asReturnedValue();
+ return __qmljs_convert_to_string(ctx, value)->asReturnedValue();
+}
+
+QV4::ReturnedValue __qmljs_to_object(QV4::ExecutionContext *ctx, const QV4::ValueRef value)
+{
+ if (value->isObject())
+ return value.asReturnedValue();
+ return Encode(__qmljs_convert_to_object(ctx, value));
+}
+
+ReturnedValue __qmljs_value_to_double(const ValueRef value)
{
- *result = value->toNumber();
+ return Encode(value->toNumber());
}
int __qmljs_value_to_int32(const ValueRef value)
@@ -1280,14 +1284,14 @@ unsigned __qmljs_double_to_uint32(const double &d)
return Value::toUInt32(d);
}
-void __qmljs_value_from_string(ValueRef result, String *string)
+ReturnedValue __qmljs_value_from_string(String *string)
{
- *result = Value::fromString(string);
+ return Value::fromString(string).asReturnedValue();
}
-void __qmljs_lookup_runtime_regexp(ExecutionContext *ctx, ValueRef result, int id)
+ReturnedValue __qmljs_lookup_runtime_regexp(ExecutionContext *ctx, int id)
{
- *result = ctx->compilationUnit->runtimeRegularExpressions[id];
+ return ctx->compilationUnit->runtimeRegularExpressions[id].asReturnedValue();
}
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index d1ca86fddd..8fbf7a6cb8 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -57,18 +57,36 @@
//#include <wtf/MathExtras.h>
-#ifdef DO_TRACE_INSTR
-# define TRACE1(x) fprintf(stderr, " %s\n", __FUNCTION__);
-# define TRACE2(x, y) fprintf(stderr, " %s\n", __FUNCTION__);
-#else
-# define TRACE1(x)
-# define TRACE2(x, y)
-#endif // TRACE1
-
QT_BEGIN_NAMESPACE
+#undef QV4_COUNT_RUNTIME_FUNCTIONS
+
namespace QV4 {
+#ifdef QV4_COUNT_RUNTIME_FUNCTIONS
+class RuntimeCounters
+{
+public:
+ RuntimeCounters();
+ ~RuntimeCounters();
+
+ static RuntimeCounters *instance;
+
+ void count(const char *func, uint tag);
+ void count(const char *func, uint tag1, uint tag2);
+
+private:
+ struct Data;
+ Data *d;
+};
+
+# define TRACE1(x) RuntimeCounters::instance->count(Q_FUNC_INFO, x.type());
+# define TRACE2(x, y) RuntimeCounters::instance->count(Q_FUNC_INFO, x.type(), y.type());
+#else
+# define TRACE1(x)
+# define TRACE2(x, y)
+#endif // QV4_COUNT_RUNTIME_FUNCTIONS
+
enum TypeHint {
PREFERREDTYPE_HINT,
NUMBER_HINT,
@@ -91,30 +109,20 @@ struct ExecutionEngine;
struct InternalClass;
// context
-void __qmljs_call_activation_property(QV4::ExecutionContext *, QV4::ValueRef result, QV4::String *name, CallDataRef callData);
-void __qmljs_call_property(QV4::ExecutionContext *context, QV4::ValueRef result, QV4::String *name, CallDataRef callData);
-void __qmljs_call_property_lookup(ExecutionContext *context, ValueRef result, uint index, CallDataRef callData);
-void __qmljs_call_element(ExecutionContext *context, ValueRef result, const ValueRef index, CallDataRef callData);
-void __qmljs_call_value(QV4::ExecutionContext *context, QV4::ValueRef result, const QV4::ValueRef func, CallDataRef callData);
-
-void __qmljs_construct_activation_property(QV4::ExecutionContext *, QV4::ValueRef result, QV4::String *name, CallDataRef callData);
-void __qmljs_construct_property(QV4::ExecutionContext *context, QV4::ValueRef result, const QV4::ValueRef base, QV4::String *name, CallDataRef callData);
-void __qmljs_construct_value(QV4::ExecutionContext *context, QV4::ValueRef result, const QV4::ValueRef func, CallDataRef callData);
-
-void __qmljs_builtin_typeof(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef val);
-void __qmljs_builtin_typeof_name(QV4::ExecutionContext *context, QV4::ValueRef result, QV4::String *name);
-void __qmljs_builtin_typeof_member(QV4::ExecutionContext* context, QV4::ValueRef result, const QV4::ValueRef base, QV4::String *name);
-void __qmljs_builtin_typeof_element(QV4::ExecutionContext* context, QV4::ValueRef result, const QV4::ValueRef base, const QV4::ValueRef index);
-
-void __qmljs_builtin_post_increment(QV4::ValueRef result, QV4::ValueRef val);
-void __qmljs_builtin_post_increment_name(QV4::ExecutionContext *context, QV4::ValueRef result, QV4::String *name);
-void __qmljs_builtin_post_increment_member(QV4::ExecutionContext *context, QV4::ValueRef result, const QV4::ValueRef base, QV4::String *name);
-void __qmljs_builtin_post_increment_element(QV4::ExecutionContext *context, QV4::ValueRef result, const QV4::ValueRef base, const QV4::ValueRef index);
-
-void __qmljs_builtin_post_decrement(QV4::ValueRef result, QV4::ValueRef val);
-void __qmljs_builtin_post_decrement_name(QV4::ExecutionContext *context, QV4::ValueRef result, QV4::String *name);
-void __qmljs_builtin_post_decrement_member(QV4::ExecutionContext *context, QV4::ValueRef result, const QV4::ValueRef base, QV4::String *name);
-void __qmljs_builtin_post_decrement_element(QV4::ExecutionContext *context, QV4::ValueRef result, const QV4::ValueRef base, const QV4::ValueRef index);
+QV4::ReturnedValue __qmljs_call_activation_property(QV4::ExecutionContext *, QV4::String *name, CallDataRef callData);
+QV4::ReturnedValue __qmljs_call_property(QV4::ExecutionContext *context, QV4::String *name, CallDataRef callData);
+QV4::ReturnedValue __qmljs_call_property_lookup(ExecutionContext *context, uint index, CallDataRef callData);
+QV4::ReturnedValue __qmljs_call_element(ExecutionContext *context, const ValueRef index, CallDataRef callData);
+QV4::ReturnedValue __qmljs_call_value(QV4::ExecutionContext *context, const QV4::ValueRef func, CallDataRef callData);
+
+QV4::ReturnedValue __qmljs_construct_activation_property(QV4::ExecutionContext *, QV4::String *name, CallDataRef callData);
+QV4::ReturnedValue __qmljs_construct_property(QV4::ExecutionContext *context, const QV4::ValueRef base, QV4::String *name, CallDataRef callData);
+QV4::ReturnedValue __qmljs_construct_value(QV4::ExecutionContext *context, const QV4::ValueRef func, CallDataRef callData);
+
+QV4::ReturnedValue __qmljs_builtin_typeof(QV4::ExecutionContext *ctx, const QV4::ValueRef val);
+QV4::ReturnedValue __qmljs_builtin_typeof_name(QV4::ExecutionContext *context, QV4::String *name);
+QV4::ReturnedValue __qmljs_builtin_typeof_member(QV4::ExecutionContext* context, const QV4::ValueRef base, QV4::String *name);
+QV4::ReturnedValue __qmljs_builtin_typeof_element(QV4::ExecutionContext* context, const QV4::ValueRef base, const QV4::ValueRef index);
void Q_NORETURN __qmljs_builtin_rethrow(QV4::ExecutionContext *context);
QV4::ExecutionContext *__qmljs_builtin_push_with_scope(const QV4::ValueRef o, QV4::ExecutionContext *ctx);
@@ -122,101 +130,101 @@ QV4::ExecutionContext *__qmljs_builtin_push_catch_scope(QV4::String *exceptionVa
QV4::ExecutionContext *__qmljs_builtin_pop_scope(QV4::ExecutionContext *ctx);
void __qmljs_builtin_declare_var(QV4::ExecutionContext *ctx, bool deletable, QV4::String *name);
void __qmljs_builtin_define_property(QV4::ExecutionContext *ctx, const QV4::ValueRef object, QV4::String *name, QV4::ValueRef val);
-void __qmljs_builtin_define_array(QV4::ExecutionContext *ctx, QV4::ValueRef array, QV4::Value *values, uint length);
+QV4::ReturnedValue __qmljs_builtin_define_array(QV4::ExecutionContext *ctx, QV4::Value *values, uint length);
void __qmljs_builtin_define_getter_setter(QV4::ExecutionContext *ctx, const QV4::ValueRef object, QV4::String *name, const QV4::ValueRef getter, const QV4::ValueRef setter);
-void __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::Value *args, int classId);
-void __qmljs_builtin_setup_arguments_object(ExecutionContext *ctx, QV4::ValueRef result);
+QV4::ReturnedValue __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, const QV4::Value *args, int classId);
+QV4::ReturnedValue __qmljs_builtin_setup_arguments_object(ExecutionContext *ctx);
-void __qmljs_value_from_string(QV4::ValueRef result, QV4::String *string);
-void __qmljs_lookup_runtime_regexp(QV4::ExecutionContext *ctx, QV4::ValueRef result, int id);
+QV4::ReturnedValue __qmljs_value_from_string(QV4::String *string);
+QV4::ReturnedValue __qmljs_lookup_runtime_regexp(QV4::ExecutionContext *ctx, int id);
// constructors
-void __qmljs_init_closure(QV4::ExecutionContext *ctx, QV4::ValueRef result, int functionId);
+QV4::ReturnedValue __qmljs_init_closure(QV4::ExecutionContext *ctx, int functionId);
// strings
Q_QML_EXPORT double __qmljs_string_to_number(const QString &s);
-QV4::Value __qmljs_string_from_number(QV4::ExecutionContext *ctx, double number);
-QV4::String *__qmljs_string_concat(QV4::ExecutionContext *ctx, QV4::String *first, QV4::String *second);
+Returned<String> *__qmljs_string_from_number(QV4::ExecutionContext *ctx, double number);
+Returned<String> *__qmljs_string_concat(QV4::ExecutionContext *ctx, QV4::String *first, QV4::String *second);
// objects
-Q_QML_EXPORT QV4::Value __qmljs_object_default_value(QV4::Object *object, int typeHint);
+Q_QML_EXPORT ReturnedValue __qmljs_object_default_value(QV4::Object *object, int typeHint);
void __qmljs_set_activation_property(QV4::ExecutionContext *ctx, QV4::String *name, const QV4::ValueRef value);
void __qmljs_set_property(QV4::ExecutionContext *ctx, const QV4::ValueRef object, QV4::String *name, const QV4::ValueRef value);
-void __qmljs_get_property(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef object, QV4::String *name);
-void __qmljs_get_activation_property(QV4::ExecutionContext *ctx, QV4::ValueRef result, QV4::String *name);
+QV4::ReturnedValue __qmljs_get_property(QV4::ExecutionContext *ctx, const QV4::ValueRef object, QV4::String *name);
+QV4::ReturnedValue __qmljs_get_activation_property(QV4::ExecutionContext *ctx, QV4::String *name);
-void __qmljs_call_global_lookup(QV4::ExecutionContext *context, QV4::ValueRef result, uint index, CallDataRef callData);
-void __qmljs_construct_global_lookup(QV4::ExecutionContext *context, QV4::ValueRef result, uint index, CallDataRef callData);
+ReturnedValue __qmljs_call_global_lookup(QV4::ExecutionContext *context, uint index, CallDataRef callData);
+QV4::ReturnedValue __qmljs_construct_global_lookup(QV4::ExecutionContext *context, uint index, CallDataRef callData);
-void __qmljs_get_element(QV4::ExecutionContext *ctx, QV4::ValueRef retval, const QV4::ValueRef object, const QV4::ValueRef index);
+QV4::ReturnedValue __qmljs_get_element(QV4::ExecutionContext *ctx, const QV4::ValueRef object, const QV4::ValueRef index);
void __qmljs_set_element(QV4::ExecutionContext *ctx, const QV4::ValueRef object, const QV4::ValueRef index, const QV4::ValueRef value);
// For each
-void __qmljs_foreach_iterator_object(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef in);
-void __qmljs_foreach_next_property_name(QV4::ValueRef result, const ValueRef foreach_iterator);
+QV4::ReturnedValue __qmljs_foreach_iterator_object(QV4::ExecutionContext *ctx, const QV4::ValueRef in);
+QV4::ReturnedValue __qmljs_foreach_next_property_name(const ValueRef foreach_iterator);
// type conversion and testing
-QV4::Value __qmljs_to_primitive(const ValueRef value, int typeHint);
+QV4::ReturnedValue __qmljs_to_primitive(const ValueRef value, int typeHint);
Q_QML_EXPORT QV4::Bool __qmljs_to_boolean(const QV4::ValueRef value);
double __qmljs_to_number(const QV4::ValueRef value);
-QV4::Value __qmljs_to_string(const ValueRef value, QV4::ExecutionContext *ctx);
-Q_QML_EXPORT QV4::String *__qmljs_convert_to_string(QV4::ExecutionContext *ctx, const ValueRef value);
+QV4::ReturnedValue __qmljs_to_string(const ValueRef value, QV4::ExecutionContext *ctx);
+Q_QML_EXPORT Returned<String> *__qmljs_convert_to_string(QV4::ExecutionContext *ctx, const ValueRef value);
void __qmljs_numberToString(QString *result, double num, int radix = 10);
-QV4::Value __qmljs_to_object(QV4::ExecutionContext *ctx, const ValueRef value);
-QV4::Object *__qmljs_convert_to_object(QV4::ExecutionContext *ctx, const ValueRef value);
+ReturnedValue __qmljs_to_object(QV4::ExecutionContext *ctx, const ValueRef value);
+Returned<Object> *__qmljs_convert_to_object(QV4::ExecutionContext *ctx, const ValueRef value);
QV4::Bool __qmljs_equal_helper(const ValueRef x, const ValueRef y);
Q_QML_EXPORT QV4::Bool __qmljs_strict_equal(const ValueRef x, const ValueRef y);
// unary operators
-typedef void (*UnaryOpName)(QV4::ValueRef, const QV4::ValueRef);
-void __qmljs_uplus(QV4::ValueRef result, const QV4::ValueRef value);
-void __qmljs_uminus(QV4::ValueRef result, const QV4::ValueRef value);
-void __qmljs_compl(QV4::ValueRef result, const QV4::ValueRef value);
-void __qmljs_not(QV4::ValueRef result, const QV4::ValueRef value);
-void __qmljs_increment(QV4::ValueRef result, const QV4::ValueRef value);
-void __qmljs_decrement(QV4::ValueRef result, const QV4::ValueRef value);
-
-Q_QML_EXPORT void __qmljs_value_to_double(double *result, const ValueRef value);
+typedef QV4::ReturnedValue (*UnaryOpName)(const QV4::ValueRef);
+QV4::ReturnedValue __qmljs_uplus(const QV4::ValueRef value);
+QV4::ReturnedValue __qmljs_uminus(const QV4::ValueRef value);
+QV4::ReturnedValue __qmljs_compl(const QV4::ValueRef value);
+QV4::ReturnedValue __qmljs_not(const QV4::ValueRef value);
+QV4::ReturnedValue __qmljs_increment(const QV4::ValueRef value);
+QV4::ReturnedValue __qmljs_decrement(const QV4::ValueRef value);
+
+Q_QML_EXPORT ReturnedValue __qmljs_value_to_double(const ValueRef value);
Q_QML_EXPORT int __qmljs_value_to_int32(const ValueRef value);
Q_QML_EXPORT int __qmljs_double_to_int32(const double &d);
Q_QML_EXPORT unsigned __qmljs_value_to_uint32(const ValueRef value);
Q_QML_EXPORT unsigned __qmljs_double_to_uint32(const double &d);
-void __qmljs_delete_subscript(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef base, const QV4::ValueRef index);
-void __qmljs_delete_member(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef base, QV4::String *name);
-void __qmljs_delete_name(QV4::ExecutionContext *ctx, QV4::ValueRef result, QV4::String *name);
+QV4::ReturnedValue __qmljs_delete_subscript(QV4::ExecutionContext *ctx, const QV4::ValueRef base, const QV4::ValueRef index);
+ReturnedValue __qmljs_delete_member(QV4::ExecutionContext *ctx, const QV4::ValueRef base, QV4::String *name);
+ReturnedValue __qmljs_delete_name(QV4::ExecutionContext *ctx, QV4::String *name);
void Q_NORETURN __qmljs_throw(QV4::ExecutionContext*, const QV4::ValueRef value);
// binary operators
-typedef void (*BinOp)(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-typedef void (*BinOpContext)(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-
-void __qmljs_instanceof(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_in(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_add(ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_bit_or(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_bit_xor(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_bit_and(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_sub(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_mul(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_div(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_mod(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_shl(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_shr(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_ushr(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_gt(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_lt(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_ge(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_le(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_eq(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_ne(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_se(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-void __qmljs_sne(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
-
-void __qmljs_add_helper(QV4::ExecutionContext *ctx, QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right);
+typedef QV4::ReturnedValue (*BinOp)(const QV4::ValueRef left, const QV4::ValueRef right);
+typedef QV4::ReturnedValue (*BinOpContext)(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right);
+
+QV4::ReturnedValue __qmljs_instanceof(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_in(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_add(ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_bit_or(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_bit_xor(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_bit_and(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_sub(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_mul(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_div(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_mod(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_shl(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_shr(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_ushr(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_gt(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_lt(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_ge(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_le(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_eq(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_ne(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_se(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::ReturnedValue __qmljs_sne(const QV4::ValueRef left, const QV4::ValueRef right);
+
+QV4::ReturnedValue __qmljs_add_helper(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right);
typedef void (*InplaceBinOpName)(QV4::ExecutionContext *ctx, QV4::String *name, const QV4::ValueRef value);
@@ -259,10 +267,10 @@ void __qmljs_inplace_shr_member(QV4::ExecutionContext *ctx, const QV4::ValueRef
void __qmljs_inplace_ushr_member(QV4::ExecutionContext *ctx, const QV4::ValueRef base, QV4::String *name, const QV4::ValueRef rhs);
typedef QV4::Bool (*CmpOp)(const QV4::ValueRef left, const QV4::ValueRef right);
-QV4::Bool __qmljs_cmp_gt(const QV4::ValueRef left, const QV4::ValueRef right);
-QV4::Bool __qmljs_cmp_lt(const QV4::ValueRef left, const QV4::ValueRef right);
-QV4::Bool __qmljs_cmp_ge(const QV4::ValueRef left, const QV4::ValueRef right);
-QV4::Bool __qmljs_cmp_le(const QV4::ValueRef left, const QV4::ValueRef right);
+QV4::Bool __qmljs_cmp_gt(const QV4::ValueRef l, const QV4::ValueRef r);
+QV4::Bool __qmljs_cmp_lt(const QV4::ValueRef l, const QV4::ValueRef r);
+QV4::Bool __qmljs_cmp_ge(const QV4::ValueRef l, const QV4::ValueRef r);
+QV4::Bool __qmljs_cmp_le(const QV4::ValueRef l, const QV4::ValueRef r);
QV4::Bool __qmljs_cmp_eq(const QV4::ValueRef left, const QV4::ValueRef right);
QV4::Bool __qmljs_cmp_ne(const QV4::ValueRef left, const QV4::ValueRef right);
QV4::Bool __qmljs_cmp_se(const QV4::ValueRef left, const QV4::ValueRef right);
@@ -273,11 +281,11 @@ QV4::Bool __qmljs_cmp_instanceof(QV4::ExecutionContext *ctx, const QV4::ValueRef
QV4::Bool __qmljs_cmp_in(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right);
// type conversion and testing
-inline QV4::Value __qmljs_to_primitive(const QV4::ValueRef value, int typeHint)
+inline ReturnedValue __qmljs_to_primitive(const QV4::ValueRef value, int typeHint)
{
QV4::Object *o = value->asObject();
if (!o)
- return *value;
+ return value.asReturnedValue();
return __qmljs_object_default_value(o, typeHint);
}
@@ -286,210 +294,174 @@ inline double __qmljs_to_number(const ValueRef value)
return value->toNumber();
}
-inline QV4::Value __qmljs_to_string(const QV4::ValueRef value, QV4::ExecutionContext *ctx)
-{
- if (value->isString())
- return *value;
- return QV4::Value::fromString(__qmljs_convert_to_string(ctx, value));
-}
-
-inline QV4::Value __qmljs_to_object(QV4::ExecutionContext *ctx, const QV4::ValueRef value)
-{
- if (value->isObject())
- return *value;
- return QV4::Value::fromObject(__qmljs_convert_to_object(ctx, value));
-}
-
-
-inline void __qmljs_uplus(QV4::ValueRef result, const QV4::ValueRef value)
+inline QV4::ReturnedValue __qmljs_uplus(const QV4::ValueRef value)
{
TRACE1(value);
- result = value;
- if (result->tryIntegerConversion())
- return;
+ if (value->integerCompatible())
+ return Encode(value->int_32);
- double n = __qmljs_to_number(value);
- *result = QV4::Value::fromDouble(n);
+ double n = value->toNumber();
+ return Encode(n);
}
-inline void __qmljs_uminus(QV4::ValueRef result, const QV4::ValueRef value)
+inline QV4::ReturnedValue __qmljs_uminus(const QV4::ValueRef value)
{
TRACE1(value);
// +0 != -0, so we need to convert to double when negating 0
if (value->isInteger() && value->integerValue())
- *result = QV4::Value::fromInt32(-value->integerValue());
+ return QV4::Value::fromInt32(-value->integerValue()).asReturnedValue();
else {
double n = __qmljs_to_number(value);
- *result = QV4::Value::fromDouble(-n);
+ return QV4::Value::fromDouble(-n).asReturnedValue();
}
}
-inline void __qmljs_compl(QV4::ValueRef result, const QV4::ValueRef value)
+inline QV4::ReturnedValue __qmljs_compl(const QV4::ValueRef value)
{
TRACE1(value);
int n;
- if (value->isConvertibleToInt())
+ if (value->integerCompatible())
n = value->int_32;
else
- n = QV4::Value::toInt32(__qmljs_to_number(value));
+ n = value->toInt32();
- *result = QV4::Value::fromInt32(~n);
+ return Encode((int)~n);
}
-inline void __qmljs_not(QV4::ValueRef result, const QV4::ValueRef value)
+inline QV4::ReturnedValue __qmljs_not(const QV4::ValueRef value)
{
TRACE1(value);
bool b = value->toBoolean();
- *result = QV4::Value::fromBoolean(!b);
+ return Encode(!b);
}
// binary operators
-inline void __qmljs_bit_or(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline ReturnedValue __qmljs_bit_or(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right)) {
- *result = QV4::Value::fromInt32(left->integerValue() | right->integerValue());
- return;
- }
+ if (QV4::Value::integerCompatible(*left, *right))
+ return QV4::Value::fromInt32(left->integerValue() | right->integerValue()).asReturnedValue();
- int lval = QV4::Value::toInt32(__qmljs_to_number(left));
- int rval = QV4::Value::toInt32(__qmljs_to_number(right));
- *result = QV4::Value::fromInt32(lval | rval);
+ int lval = left->toInt32();
+ int rval = right->toInt32();
+ return QV4::Value::fromInt32(lval | rval).asReturnedValue();
}
-inline void __qmljs_bit_xor(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline ReturnedValue __qmljs_bit_xor(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right)) {
- *result = QV4::Value::fromInt32(left->integerValue() ^ right->integerValue());
- return;
- }
+ if (QV4::Value::integerCompatible(*left, *right))
+ return QV4::Value::fromInt32(left->integerValue() ^ right->integerValue()).asReturnedValue();
- int lval = QV4::Value::toInt32(__qmljs_to_number(left));
- int rval = QV4::Value::toInt32(__qmljs_to_number(right));
- *result = QV4::Value::fromInt32(lval ^ rval);
+ int lval = left->toInt32();
+ int rval = right->toInt32();
+ return QV4::Value::fromInt32(lval ^ rval).asReturnedValue();
}
-inline void __qmljs_bit_and(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline ReturnedValue __qmljs_bit_and(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right)) {
- *result = QV4::Value::fromInt32(left->integerValue() & right->integerValue());
- return;
- }
+ if (QV4::Value::integerCompatible(*left, *right))
+ return QV4::Value::fromInt32(left->integerValue() & right->integerValue()).asReturnedValue();
- int lval = QV4::Value::toInt32(__qmljs_to_number(left));
- int rval = QV4::Value::toInt32(__qmljs_to_number(right));
- *result = QV4::Value::fromInt32(lval & rval);
+ int lval = left->toInt32();
+ int rval = right->toInt32();
+ return QV4::Value::fromInt32(lval & rval).asReturnedValue();
}
-inline void __qmljs_add(QV4::ExecutionContext *ctx, ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_add(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right)) {
- *result = add_int32(left->integerValue(), right->integerValue());
- return;
- }
+ if (QV4::Value::integerCompatible(*left, *right))
+ return add_int32(left->integerValue(), right->integerValue()).asReturnedValue();
- if (QV4::Value::bothDouble(*left, *right)) {
- *result = QV4::Value::fromDouble(left->doubleValue() + right->doubleValue());
- return;
- }
+ if (QV4::Value::bothDouble(*left, *right))
+ return QV4::Value::fromDouble(left->doubleValue() + right->doubleValue()).asReturnedValue();
- __qmljs_add_helper(ctx, result, left, right);
+ return __qmljs_add_helper(ctx, left, right);
}
-inline void __qmljs_sub(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_sub(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right)) {
- *result = sub_int32(left->integerValue(), right->integerValue());
- return;
- }
+ if (QV4::Value::integerCompatible(*left, *right))
+ return sub_int32(left->integerValue(), right->integerValue()).asReturnedValue();
double lval = __qmljs_to_number(left);
double rval = __qmljs_to_number(right);
- *result = QV4::Value::fromDouble(lval - rval);
+ return QV4::Value::fromDouble(lval - rval).asReturnedValue();
}
-inline void __qmljs_mul(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_mul(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right)) {
- *result = mul_int32(left->integerValue(), right->integerValue());
- return;
- }
+ if (QV4::Value::integerCompatible(*left, *right))
+ return mul_int32(left->integerValue(), right->integerValue()).asReturnedValue();
double lval = __qmljs_to_number(left);
double rval = __qmljs_to_number(right);
- *result = QV4::Value::fromDouble(lval * rval);
+ return QV4::Value::fromDouble(lval * rval).asReturnedValue();
}
-inline void __qmljs_div(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_div(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
double lval = __qmljs_to_number(left);
double rval = __qmljs_to_number(right);
- *result = QV4::Value::fromDouble(lval / rval);
+ return QV4::Value::fromDouble(lval / rval).asReturnedValue();
}
-inline void __qmljs_mod(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_mod(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
if (QV4::Value::integerCompatible(*left, *right) && right->integerValue() != 0) {
int intRes = left->integerValue() % right->integerValue();
- if (intRes != 0 || left->integerValue() >= 0) {
- *result = QV4::Value::fromInt32(intRes);
- return;
- }
+ if (intRes != 0 || left->integerValue() >= 0)
+ return QV4::Value::fromInt32(intRes).asReturnedValue();
}
double lval = __qmljs_to_number(left);
double rval = __qmljs_to_number(right);
- *result = QV4::Value::fromDouble(std::fmod(lval, rval));
+ return QV4::Value::fromDouble(std::fmod(lval, rval)).asReturnedValue();
}
-inline void __qmljs_shl(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_shl(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right)) {
- *result = QV4::Value::fromInt32(left->integerValue() << ((uint(right->integerValue()) & 0x1f)));
- return;
- }
+ if (QV4::Value::integerCompatible(*left, *right))
+ return QV4::Value::fromInt32(left->integerValue() << ((uint(right->integerValue()) & 0x1f))).asReturnedValue();
- int lval = QV4::Value::toInt32(__qmljs_to_number(left));
- unsigned rval = QV4::Value::toUInt32(__qmljs_to_number(right)) & 0x1f;
- *result = QV4::Value::fromInt32(lval << rval);
+ int lval = left->toInt32();
+ unsigned rval = right->toUInt32() & 0x1f;
+ return QV4::Value::fromInt32(lval << rval).asReturnedValue();
}
-inline void __qmljs_shr(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_shr(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right)) {
- *result = QV4::Value::fromInt32(left->integerValue() >> ((uint(right->integerValue()) & 0x1f)));
- return;
- }
+ if (QV4::Value::integerCompatible(*left, *right))
+ return QV4::Value::fromInt32(left->integerValue() >> ((uint(right->integerValue()) & 0x1f))).asReturnedValue();
- int lval = QV4::Value::toInt32(__qmljs_to_number(left));
- unsigned rval = QV4::Value::toUInt32(__qmljs_to_number(right)) & 0x1f;
- *result = QV4::Value::fromInt32(lval >> rval);
+ int lval = left->toInt32();
+ unsigned rval = right->toUInt32() & 0x1f;
+ return QV4::Value::fromInt32(lval >> rval).asReturnedValue();
}
-inline void __qmljs_ushr(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_ushr(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
@@ -497,168 +469,88 @@ inline void __qmljs_ushr(QV4::ValueRef result, const QV4::ValueRef left, const Q
if (QV4::Value::integerCompatible(*left, *right)) {
res = uint(left->integerValue()) >> (uint(right->integerValue()) & 0x1f);
} else {
- unsigned lval = QV4::Value::toUInt32(__qmljs_to_number(left));
- unsigned rval = QV4::Value::toUInt32(__qmljs_to_number(right)) & 0x1f;
+ unsigned lval = left->toUInt32();
+ unsigned rval = right->toUInt32() & 0x1f;
res = lval >> rval;
}
if (res > INT_MAX)
- *result = QV4::Value::fromDouble(res);
+ return QV4::Value::fromDouble(res).asReturnedValue();
else
- *result = QV4::Value::fromInt32(res);
+ return QV4::Value::fromInt32(res).asReturnedValue();
}
-inline void __qmljs_gt(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_gt(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_gt(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_gt(left, right)).asReturnedValue();
}
-inline void __qmljs_lt(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_lt(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_lt(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_lt(left, right)).asReturnedValue();
}
-inline void __qmljs_ge(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_ge(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_ge(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_ge(left, right)).asReturnedValue();
}
-inline void __qmljs_le(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_le(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_le(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_le(left, right)).asReturnedValue();
}
-inline void __qmljs_eq(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_eq(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(__qmljs_cmp_eq(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_eq(left, right)).asReturnedValue();
}
-inline void __qmljs_ne(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_ne(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- *result = QV4::Value::fromBoolean(!__qmljs_cmp_eq(left, right));
+ return QV4::Value::fromBoolean(!__qmljs_cmp_eq(left, right)).asReturnedValue();
}
-inline void __qmljs_se(QV4::ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_se(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
bool r = __qmljs_strict_equal(left, right);
- *result = QV4::Value::fromBoolean(r);
+ return QV4::Value::fromBoolean(r).asReturnedValue();
}
-inline void __qmljs_sne(ValueRef result, const QV4::ValueRef left, const QV4::ValueRef right)
+inline QV4::ReturnedValue __qmljs_sne(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
bool r = ! __qmljs_strict_equal(left, right);
- *result = QV4::Value::fromBoolean(r);
-}
-
-inline QV4::Bool __qmljs_cmp_gt(const QV4::ValueRef left, const QV4::ValueRef right)
-{
- TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right))
- return left->integerValue() > right->integerValue();
-
- // Safe, as l & r are primitive values
- QV4::Value l = __qmljs_to_primitive(left, QV4::NUMBER_HINT);
- QV4::Value r = __qmljs_to_primitive(right, QV4::NUMBER_HINT);
-
- if (QV4::Value::bothDouble(l, r)) {
- return l.doubleValue() > r.doubleValue();
- } else if (l.isString() && r.isString()) {
- return r.stringValue()->compare(l.stringValue());
- } else {
- double dl = __qmljs_to_number(ValueRef(&l));
- double dr = __qmljs_to_number(ValueRef(&r));
- return dl > dr;
- }
-}
-
-inline QV4::Bool __qmljs_cmp_lt(const QV4::ValueRef left, const QV4::ValueRef right)
-{
- TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right))
- return left->integerValue() < right->integerValue();
-
- QV4::Value l = __qmljs_to_primitive(left, QV4::NUMBER_HINT);
- QV4::Value r = __qmljs_to_primitive(right, QV4::NUMBER_HINT);
-
- if (QV4::Value::bothDouble(l, r)) {
- return l.doubleValue() < r.doubleValue();
- } else if (l.isString() && r.isString()) {
- return l.stringValue()->compare(r.stringValue());
- } else {
- double dl = __qmljs_to_number(ValueRef(&l));
- double dr = __qmljs_to_number(ValueRef(&r));
- return dl < dr;
- }
-}
-
-inline QV4::Bool __qmljs_cmp_ge(const QV4::ValueRef left, const QV4::ValueRef right)
-{
- TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right))
- return left->integerValue() >= right->integerValue();
-
- QV4::Value l = __qmljs_to_primitive(left, QV4::NUMBER_HINT);
- QV4::Value r = __qmljs_to_primitive(right, QV4::NUMBER_HINT);
-
- if (QV4::Value::bothDouble(l, r)) {
- return l.doubleValue() >= r.doubleValue();
- } else if (l.isString() && r.isString()) {
- return !l.stringValue()->compare(r.stringValue());
- } else {
- double dl = __qmljs_to_number(ValueRef(&l));
- double dr = __qmljs_to_number(ValueRef(&r));
- return dl >= dr;
- }
-}
-
-inline QV4::Bool __qmljs_cmp_le(const QV4::ValueRef left, const QV4::ValueRef right)
-{
- TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right))
- return left->integerValue() <= right->integerValue();
-
- QV4::Value l = __qmljs_to_primitive(left, QV4::NUMBER_HINT);
- QV4::Value r = __qmljs_to_primitive(right, QV4::NUMBER_HINT);
-
- if (QV4::Value::bothDouble(l, r)) {
- return l.doubleValue() <= r.doubleValue();
- } else if (l.isString() && r.isString()) {
- return !r.stringValue()->compare(l.stringValue());
- } else {
- double dl = __qmljs_to_number(ValueRef(&l));
- double dr = __qmljs_to_number(ValueRef(&r));
- return dl <= dr;
- }
+ return QV4::Value::fromBoolean(r).asReturnedValue();
}
inline QV4::Bool __qmljs_cmp_eq(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- if (left->val == right->val)
+ if (left->rawValue() == right->rawValue())
// NaN != NaN
- return (left->tag & QV4::Value::NotDouble_Mask) != QV4::Value::NaN_Mask;
+ return !left->isNaN();
if (left->type() == right->type()) {
- if (left->isManaged())
+ if (!left->isManaged())
+ return false;
+ if (left->isString() == right->isString())
return left->managed()->isEqualTo(right->managed());
- return false;
}
return __qmljs_equal_helper(left, right);
@@ -689,18 +581,18 @@ inline QV4::Bool __qmljs_cmp_instanceof(QV4::ExecutionContext *ctx, const QV4::V
{
TRACE2(left, right);
- QV4::Value v;
- __qmljs_instanceof(ctx, &v, left, right);
- return v.booleanValue();
+ Scope scope(ctx);
+ QV4::ScopedValue v(scope, __qmljs_instanceof(ctx, left, right));
+ return v->booleanValue();
}
inline uint __qmljs_cmp_in(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- QV4::Value v;
- __qmljs_in(ctx, &v, left, right);
- return v.booleanValue();
+ Scope scope(ctx);
+ QV4::ScopedValue v(scope, __qmljs_in(ctx, left, right));
+ return v->booleanValue();
}
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index a0e0d784a7..a800283cee 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -79,61 +79,73 @@ struct ScopedValueArray {
struct ScopedValue;
-struct ValueScope {
- ValueScope(ExecutionContext *ctx)
+struct Scope {
+ Scope(ExecutionContext *ctx)
: engine(ctx->engine)
+#ifndef QT_NO_DEBUG
+ , size(0)
+#endif
{
mark = ctx->engine->jsStackTop;
}
- ValueScope(ExecutionEngine *e)
+ Scope(ExecutionEngine *e)
: engine(e)
{
mark = e->jsStackTop;
}
- ~ValueScope() {
+ ~Scope() {
Q_ASSERT(engine->jsStackTop >= mark);
engine->jsStackTop = mark;
}
ExecutionEngine *engine;
Value *mark;
+#ifndef QT_NO_DEBUG
+ mutable int size;
+#endif
};
struct ScopedValue;
struct ValueRef;
-struct ReturnedValue
-{
- ReturnedValue(const Value &v)
- : v(v) {}
- // no destructor
-
-
-private:
- friend struct ValueRef;
- friend struct ScopedValue;
- QV4::Value v;
-};
-
struct ScopedValue
{
- ScopedValue(const ValueScope &scope)
+ ScopedValue(const Scope &scope)
{
ptr = scope.engine->jsStackTop++;
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
}
- ScopedValue(const ValueScope &scope, const Value &v)
+ ScopedValue(const Scope &scope, const Value &v)
{
ptr = scope.engine->jsStackTop++;
*ptr = v;
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
+
+ ScopedValue(const Scope &scope, const ReturnedValue &v)
+ {
+ ptr = scope.engine->jsStackTop++;
+ ptr->val = v;
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
}
- ScopedValue(const ValueScope &scope, const ReturnedValue &v)
+ template<typename T>
+ ScopedValue(const Scope &scope, Returned<T> *t)
{
ptr = scope.engine->jsStackTop++;
- *ptr = v.v;
+ *ptr = t->getPointer() ? Value::fromManaged(t->getPointer()) : Value::undefinedValue();
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
}
ScopedValue &operator=(const Value &v) {
@@ -142,7 +154,13 @@ struct ScopedValue
}
ScopedValue &operator=(const ReturnedValue &v) {
- *ptr = v.v;
+ ptr->val = v;
+ return *this;
+ }
+
+ template<typename T>
+ ScopedValue &operator=(Returned<T> *t) {
+ *ptr = t->getPointer() ? Value::fromManaged(t->getPointer()) : Value::undefinedValue();
return *this;
}
@@ -155,32 +173,149 @@ struct ScopedValue
return ptr;
}
+ const Value *operator->() const {
+ return ptr;
+ }
+
operator const Value &() const {
return *ptr;
}
+ ReturnedValue asReturnedValue() const { return ptr->val; }
+
Value *ptr;
};
-struct ScopedCallData {
- ScopedCallData(ExecutionEngine *e, int argc)
- : engine(e)
- // ### this check currently won't work because of exceptions
+template<typename T>
+struct Scoped
+{
+ inline void setPointer(Managed *p) {
+#if QT_POINTER_SIZE == 8
+ ptr->val = (quint64)p;
+#else
+ *ptr = p ? QV4::Value::fromManaged(p) : QV4::Value::undefinedValue();
+#endif
+ }
+
+ Scoped(const Scope &scope)
+ {
+ ptr = scope.engine->jsStackTop++;
#ifndef QT_NO_DEBUG
- , size(qMax(argc, (int)QV4::Global::ReservedArgumentCount) + offsetof(QV4::CallData, args)/sizeof(QV4::Value))
+ ++scope.size;
#endif
+ }
+
+ // ### GC FIX casting below to be safe
+ Scoped(const Scope &scope, const Value &v)
{
- ptr = reinterpret_cast<CallData *>(e->stackPush(qMax(argc, (int)QV4::Global::ReservedArgumentCount) + offsetof(QV4::CallData, args)/sizeof(QV4::Value)));
- ptr->tag = 0;
- ptr->argc = argc;
+ ptr = scope.engine->jsStackTop++;
+ setPointer(T::cast(v));
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
}
- ~ScopedCallData() {
+ Scoped(const Scope &scope, const ValueRef &v);
+
+ Scoped(const Scope &scope, T *t)
+ {
+ ptr = scope.engine->jsStackTop++;
+ setPointer(t);
#ifndef QT_NO_DEBUG
- engine->stackPop(size);
- Q_ASSERT((void *)engine->jsStackTop == (void *)ptr);
+ ++scope.size;
+#endif
+ }
+ template<typename X>
+ Scoped(const Scope &scope, Returned<X> *x)
+ {
+ ptr = scope.engine->jsStackTop++;
+ setPointer(Returned<T>::getPointer(x));
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
+
+ Scoped(const Scope &scope, const ReturnedValue &v)
+ {
+ ptr = scope.engine->jsStackTop++;
+ setPointer(T::cast(QV4::Value::fromReturnedValue(v)));
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+ }
+
+ Scoped<T> &operator=(const Value &v) {
+ setPointer(T::cast(v));
+ return *this;
+ }
+
+ Scoped<T> &operator=(const ValueRef &v);
+
+ Scoped<T> &operator=(const ReturnedValue &v) {
+ setPointer(T::cast(QV4::Value::fromReturnedValue(v)));
+ return *this;
+ }
+
+ Scoped<T> &operator=(const Scoped<T> &other) {
+ *ptr = *other.ptr;
+ return *this;
+ }
+
+ Scoped<T> &operator=(T *t) {
+ setPointer(t);
+ return *this;
+ }
+
+ template<typename X>
+ Scoped<T> &operator=(Returned<X> *x) {
+ setPointer(Returned<T>::getPointer(x));
+ return *this;
+ }
+
+
+ T *operator->() {
+ return static_cast<T *>(ptr->managed());
+ }
+
+ bool operator!() const {
+ return !ptr->managed();
+ }
+ operator bool() const {
+ return ptr->managed();
+ }
+
+ T *getPointer() {
+ return static_cast<T *>(ptr->managed());
+ }
+
+ Value asValue() const {
+#if QT_POINTER_SIZE == 8
+ return ptr->val ? *ptr : QV4::Value::undefinedValue();
+#else
+ return *ptr;
+#endif
+ }
+
+ ReturnedValue asReturnedValue() const {
+#if QT_POINTER_SIZE == 8
+ return ptr->val ? ptr->val : Value::undefinedValue().asReturnedValue();
#else
- engine->jsStackTop = reinterpret_cast<Value *>(ptr);
+ return ptr->val;
+#endif
+ }
+
+ Value *ptr;
+};
+
+struct ScopedCallData {
+ ScopedCallData(Scope &scope, int argc)
+ {
+ int size = qMax(argc, (int)QV4::Global::ReservedArgumentCount) + offsetof(QV4::CallData, args)/sizeof(QV4::Value);
+ ptr = reinterpret_cast<CallData *>(scope.engine->stackPush(size));
+ ptr->tag = QV4::Value::Integer_Type;
+ ptr->argc = argc;
+#ifndef QT_NO_DEBUG
+ scope.size += size;
#endif
}
@@ -192,17 +327,15 @@ struct ScopedCallData {
return ptr;
}
-
- ExecutionEngine *engine;
-#ifndef QT_NO_DEBUG
- int size;
-#endif
CallData *ptr;
};
struct ValueRef {
ValueRef(const ScopedValue &v)
: ptr(v.ptr) {}
+ template <typename T>
+ ValueRef(const Scoped<T> &v)
+ : ptr(v.ptr) {}
ValueRef(const PersistentValue &v)
: ptr(&v.d->value) {}
ValueRef(PersistentValuePrivate *p)
@@ -218,7 +351,7 @@ struct ValueRef {
ValueRef &operator=(const Value &v)
{ *ptr = v; return *this; }
ValueRef &operator=(const ReturnedValue &v) {
- *ptr = v.v;
+ ptr->val = v;
return *this;
}
@@ -242,12 +375,32 @@ struct ValueRef {
static const ValueRef fromRawValue(const Value *v) {
return ValueRef(const_cast<Value *>(v));
}
+
+ ReturnedValue asReturnedValue() const { return ptr->val; }
+
// ### get rid of this one!
ValueRef(Value *v) { ptr = v; }
private:
Value *ptr;
};
+template<typename T>
+inline Scoped<T>::Scoped(const Scope &scope, const ValueRef &v)
+{
+ ptr = scope.engine->jsStackTop++;
+ setPointer(T::cast(*v.operator ->()));
+#ifndef QT_NO_DEBUG
+ ++scope.size;
+#endif
+}
+
+template<typename T>
+inline Scoped<T> &Scoped<T>::operator=(const ValueRef &v)
+{
+ setPointer(T::cast(*v.operator ->()));
+ return *this;
+}
+
struct CallDataRef {
CallDataRef(const ScopedCallData &c)
@@ -280,6 +433,47 @@ private:
CallData *ptr;
};
+struct Encode : private Value {
+ static ReturnedValue undefined() {
+ return quint64(Undefined_Type) << Tag_Shift;
+ }
+ static ReturnedValue null() {
+ return quint64(_Null_Type) << Tag_Shift;
+ }
+
+ Encode(bool b) {
+ tag = _Boolean_Type;
+ int_32 = b;
+ }
+ Encode(double d) {
+ setDouble(d);
+ }
+ Encode(int i) {
+ tag = _Integer_Type;
+ int_32 = i;
+ }
+ Encode(uint i) {
+ if (i <= INT_MAX) {
+ tag = _Integer_Type;
+ int_32 = i;
+ } else {
+ setDouble(i);
+ }
+ }
+ Encode(ReturnedValue v) {
+ val = v;
+ }
+
+ template<typename T>
+ Encode(Returned<T> *t) {
+ val = t->getPointer()->asReturnedValue();
+ }
+
+ operator ReturnedValue() const {
+ return val;
+ }
+};
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 16bab966e9..ad83a52d8f 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -75,19 +75,19 @@ QmlBindingWrapper::QmlBindingWrapper(ExecutionContext *scope, Function *f, Objec
scope->engine->popContext();
}
-Value QmlBindingWrapper::call(Managed *that, CallData *)
+ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *)
{
ExecutionEngine *engine = that->engine();
+ Scope scope(engine);
QmlBindingWrapper *This = static_cast<QmlBindingWrapper *>(that);
CallContext *ctx = This->qmlContext;
std::fill(ctx->locals, ctx->locals + ctx->function->varCount, Value::undefinedValue());
engine->pushContext(ctx);
- Value result = This->function->code(ctx, This->function->codeData);
+ ScopedValue result(scope, This->function->code(ctx, This->function->codeData));
engine->popContext();
- return result;
-
+ return result.asReturnedValue();
}
void QmlBindingWrapper::markObjects(Managed *m)
@@ -141,6 +141,7 @@ void Script::parse()
parsed = true;
ExecutionEngine *v4 = scope->engine;
+ Scope valueScope(v4);
MemoryManager::GCBlocker gcBlocker(v4->memoryManager);
@@ -188,19 +189,22 @@ void Script::parse()
compilationUnitHolder = Value::fromObject(new (v4->memoryManager) CompilationUnitHolder(v4, compilationUnit));
}
- if (!vmFunction)
+ if (!vmFunction) {
// ### FIX file/line number
- v4->current->throwError(QV4::Value::fromObject(v4->newSyntaxErrorObject("Syntax error")));
+ Scoped<Object> error(valueScope, v4->newSyntaxErrorObject("Syntax error"));
+ v4->current->throwError(error);
+ }
}
-Value Script::run()
+ReturnedValue Script::run()
{
if (!parsed)
parse();
if (!vmFunction)
- return Value::undefinedValue();
+ return Encode::undefined();
QV4::ExecutionEngine *engine = scope->engine;
+ QV4::Scope valueScope(engine);
if (qml.isEmpty()) {
TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, vmFunction);
@@ -217,7 +221,7 @@ Value Script::run()
scope->compiledFunction = vmFunction->compiledFunction;
scope->runtimeStrings = vmFunction->compilationUnit->runtimeStrings;
- QV4::Value result;
+ QV4::ScopedValue result(valueScope);
try {
result = vmFunction->code(scope, vmFunction->codeData);
} catch (Exception &e) {
@@ -234,11 +238,11 @@ Value Script::run()
scope->compiledFunction = oldCompiledFunction;
scope->runtimeStrings = oldRuntimeStrings;
- return result;
+ return result.asReturnedValue();
} else {
FunctionObject *f = new (engine->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject());
- ScopedCallData callData(scope->engine, 0);
+ ScopedCallData callData(valueScope, 0);
callData->thisObject = Value::undefinedValue();
return f->call(callData);
}
@@ -251,25 +255,25 @@ Function *Script::function()
return vmFunction;
}
-Value Script::qmlBinding()
+ReturnedValue Script::qmlBinding()
{
if (!parsed)
parse();
QV4::ExecutionEngine *v4 = scope->engine;
- return Value::fromObject(new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject()));
+ return Value::fromObject(new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject())).asReturnedValue();
}
-QV4::Value Script::evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject)
+QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject)
{
+ QV4::Scope scope(engine);
QV4::Script qmlScript(engine, scopeObject, script, QString());
QV4::ExecutionContext *ctx = engine->current;
- QV4::Value result = QV4::Value::undefinedValue();
try {
qmlScript.parse();
- result = qmlScript.run();
+ return qmlScript.run();
} catch (QV4::Exception &e) {
e.accept(ctx);
}
- return result;
+ return Encode::undefined();
}
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index b00e076a2b..5a880fee88 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -56,7 +56,7 @@ struct QmlBindingWrapper : FunctionObject {
QmlBindingWrapper(ExecutionContext *scope, Function *f, Object *qml);
- static Value call(Managed *that, CallData *);
+ static ReturnedValue call(Managed *that, CallData *);
static void markObjects(Managed *m);
private:
@@ -88,13 +88,13 @@ struct Q_QML_EXPORT Script {
bool parseAsBinding;
void parse();
- Value run();
- Value qmlBinding();
+ ReturnedValue run();
+ ReturnedValue qmlBinding();
Function *function();
- static Value evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject);
+ static ReturnedValue evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject);
};
}
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 29ca34910c..72356204b5 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -48,6 +48,8 @@
#include <private/qqmlengine_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
using namespace QV4;
@@ -136,7 +138,7 @@ template <typename ElementType> ElementType convertValueToElement(const QV4::Val
template <> QString convertValueToElement(const QV4::Value &value)
{
- return value.toQString();
+ return value.toQStringNoThrow();
}
template <> int convertValueToElement(const QV4::Value &value)
@@ -146,7 +148,7 @@ template <> int convertValueToElement(const QV4::Value &value)
template <> QUrl convertValueToElement(const QV4::Value &value)
{
- return QUrl(value.toQString());
+ return QUrl(value.toQStringNoThrow());
}
template <> qreal convertValueToElement(const QV4::Value &value)
@@ -352,12 +354,13 @@ public:
bool operator()(typename Container::value_type lhs, typename Container::value_type rhs)
{
QV4::Managed *fun = this->m_compareFn.asManaged();
- ScopedCallData callData(fun->engine(), 2);
+ Scope scope(fun->engine());
+ ScopedCallData callData(scope, 2);
callData->args[0] = convertElementToValue(this->m_ctx->engine, lhs);
callData->args[1] = convertElementToValue(this->m_ctx->engine, rhs);
callData->thisObject = QV4::Value::fromObject(this->m_ctx->engine->globalObject);
- QV4::Value result = fun->call(callData);
- return result.toNumber() < 0;
+ QV4::ScopedValue result(scope, fun->call(callData));
+ return result->toNumber() < 0;
}
private:
@@ -376,17 +379,17 @@ public:
if (ctx->argumentCount == 1 && ctx->arguments[0].asFunctionObject()) {
QV4::Value compareFn = ctx->arguments[0];
CompareFunctor cf(ctx, compareFn);
- qSort(m_container.begin(), m_container.end(), cf);
+ std::sort(m_container.begin(), m_container.end(), cf);
} else {
DefaultCompareFunctor cf;
- qSort(m_container.begin(), m_container.end(), cf);
+ std::sort(m_container.begin(), m_container.end(), cf);
}
if (m_isReference)
storeReference();
}
- static QV4::Value method_get_length(QV4::SimpleCallContext *ctx)
+ static QV4::ReturnedValue method_get_length(QV4::SimpleCallContext *ctx)
{
QQmlSequence<Container> *This = ctx->thisObject.as<QQmlSequence<Container> >();
if (!This)
@@ -394,13 +397,13 @@ public:
if (This->m_isReference) {
if (!This->m_object)
- return QV4::Value::fromInt32(0);
+ return QV4::Encode(0);
This->loadReference();
}
- return QV4::Value::fromInt32(This->m_container.count());
+ return QV4::Encode(This->m_container.count());
}
- static QV4::Value method_set_length(QV4::SimpleCallContext* ctx)
+ static QV4::ReturnedValue method_set_length(QV4::SimpleCallContext* ctx)
{
QQmlSequence<Container> *This = ctx->thisObject.as<QQmlSequence<Container> >();
if (!This)
@@ -410,19 +413,19 @@ public:
/* Qt containers have int (rather than uint) allowable indexes. */
if (newLength > INT_MAX) {
generateWarning(ctx, QLatin1String("Index out of range during length set"));
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/* Read the sequence from the QObject property if we're a reference */
if (This->m_isReference) {
if (!This->m_object)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
This->loadReference();
}
/* Determine whether we need to modify the sequence */
qint32 newCount = static_cast<qint32>(newLength);
qint32 count = This->m_container.count();
if (newCount == count) {
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
} else if (newCount > count) {
/* according to ECMA262r3 we need to insert */
/* undefined values increasing length to newLength. */
@@ -444,7 +447,7 @@ public:
/* write back. already checked that object is non-null, so skip that check here. */
This->storeReference();
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
QVariant toVariant() const
@@ -455,7 +458,7 @@ public:
Container result;
quint32 length = array->arrayLength();
for (quint32 i = 0; i < length; ++i)
- result << convertValueToElement<typename Container::value_type>(array->getIndexed(i));
+ result << convertValueToElement<typename Container::value_type>(QV4::Value::fromReturnedValue(array->getIndexed(i)));
return QVariant::fromValue(result);
}
@@ -483,8 +486,8 @@ private:
int m_propertyIndex;
bool m_isReference;
- static QV4::Value getIndexed(QV4::Managed *that, uint index, bool *hasProperty)
- { return static_cast<QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty); }
+ static QV4::ReturnedValue getIndexed(QV4::Managed *that, uint index, bool *hasProperty)
+ { return static_cast<QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty).asReturnedValue(); }
static void putIndexed(Managed *that, uint index, const QV4::Value &value)
{ static_cast<QQmlSequence<Container> *>(that)->containerPutIndexed(index, value); }
static QV4::PropertyAttributes queryIndexed(const QV4::Managed *that, uint index)
@@ -535,14 +538,14 @@ void SequencePrototype::init(QV4::ExecutionEngine *engine)
defineDefaultProperty(engine, QStringLiteral("valueOf"), method_valueOf, 0);
}
-QV4::Value SequencePrototype::method_sort(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue SequencePrototype::method_sort(QV4::SimpleCallContext *ctx)
{
QV4::Object *o = ctx->thisObject.asObject();
if (!o || !o->isListType())
ctx->throwTypeError();
if (ctx->argumentCount >= 2)
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
#define CALL_SORT(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue) \
if (QQml##SequenceElementTypeName##List *s = o->as<QQml##SequenceElementTypeName##List>()) { \
@@ -552,7 +555,7 @@ QV4::Value SequencePrototype::method_sort(QV4::SimpleCallContext *ctx)
FOREACH_QML_SEQUENCE_TYPE(CALL_SORT)
#undef CALL_SORT
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
#define IS_SEQUENCE(unused1, unused2, SequenceType, unused3) \
@@ -568,36 +571,38 @@ bool SequencePrototype::isSequenceType(int sequenceTypeId)
#define NEW_REFERENCE_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
if (sequenceType == qMetaTypeId<SequenceType>()) { \
- QV4::Object *obj = new (engine->memoryManager) QQml##ElementTypeName##List(engine, object, propertyIndex); \
- return QV4::Value::fromObject(obj); \
+ QV4::Scoped<QV4::Object> obj(scope, QV4::Value::fromObject(new (engine->memoryManager) QQml##ElementTypeName##List(engine, object, propertyIndex))); \
+ return obj.asReturnedValue(); \
} else
-QV4::Value SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int sequenceType, QObject *object, int propertyIndex, bool *succeeded)
+ReturnedValue SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int sequenceType, QObject *object, int propertyIndex, bool *succeeded)
{
+ QV4::Scope scope(engine);
// This function is called when the property is a QObject Q_PROPERTY of
// the given sequence type. Internally we store a typed-sequence
// (as well as object ptr + property index for updated-read and write-back)
// and so access/mutate avoids variant conversion.
*succeeded = true;
- FOREACH_QML_SEQUENCE_TYPE(NEW_REFERENCE_SEQUENCE) { /* else */ *succeeded = false; return QV4::Value::undefinedValue(); }
+ FOREACH_QML_SEQUENCE_TYPE(NEW_REFERENCE_SEQUENCE) { /* else */ *succeeded = false; return QV4::Encode::undefined(); }
}
#undef NEW_REFERENCE_SEQUENCE
#define NEW_COPY_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
if (sequenceType == qMetaTypeId<SequenceType>()) { \
- QV4::Object *obj = new (engine->memoryManager) QQml##ElementTypeName##List(engine, v.value<SequenceType >()); \
- return QV4::Value::fromObject(obj); \
+ QV4::Scoped<QV4::Object> obj(scope, QV4::Value::fromObject(new (engine->memoryManager) QQml##ElementTypeName##List(engine, v.value<SequenceType >()))); \
+ return obj.asReturnedValue(); \
} else
-QV4::Value SequencePrototype::fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded)
+ReturnedValue SequencePrototype::fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded)
{
+ QV4::Scope scope(engine);
// This function is called when assigning a sequence value to a normal JS var
// in a JS block. Internally, we store a sequence of the specified type.
// Access and mutation is extremely fast since it will not need to modify any
// QObject property.
int sequenceType = v.userType();
*succeeded = true;
- FOREACH_QML_SEQUENCE_TYPE(NEW_COPY_SEQUENCE) { /* else */ *succeeded = false; return QV4::Value::undefinedValue(); }
+ FOREACH_QML_SEQUENCE_TYPE(NEW_COPY_SEQUENCE) { /* else */ *succeeded = false; return QV4::Encode::undefined(); }
}
#undef NEW_COPY_SEQUENCE
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index ceae4e6f97..f2d06d8918 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -69,16 +69,16 @@ struct SequencePrototype : public QV4::Object
void init(QV4::ExecutionEngine *engine);
- static QV4::Value method_valueOf(QV4::SimpleCallContext *ctx)
+ static ReturnedValue method_valueOf(QV4::SimpleCallContext *ctx)
{
- return QV4::Value::fromString(ctx->thisObject.toString(ctx));
+ return QV4::Value::fromString(ctx->thisObject.toString(ctx)).asReturnedValue();
}
- static QV4::Value method_sort(QV4::SimpleCallContext *ctx);
+ static ReturnedValue method_sort(QV4::SimpleCallContext *ctx);
static bool isSequenceType(int sequenceTypeId);
- static QV4::Value newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
- static QV4::Value fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded);
+ static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
+ static ReturnedValue fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded);
static int metaTypeForSequence(QV4::Object *object);
static QVariant toVariant(QV4::Object *object);
static QVariant toVariant(const QV4::Value &array, int typeHint, bool *succeeded);
diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp
index f7389dc6d7..41481ac1b8 100644
--- a/src/qml/jsruntime/qv4serialize.cpp
+++ b/src/qml/jsruntime/qv4serialize.cpp
@@ -150,6 +150,8 @@ static inline void *popPtr(const char *&data)
void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engine)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope scope(v4);
+
if (v.isEmpty()) {
} else if (v.isUndefined()) {
push(data, valueheader(WorkerUndefined));
@@ -187,7 +189,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi
reserve(data, sizeof(quint32) + length * sizeof(quint32));
push(data, valueheader(WorkerArray, length));
for (uint32_t ii = 0; ii < length; ++ii)
- serialize(data, array->getIndexed(ii), engine);
+ serialize(data, QV4::Value::fromReturnedValue(array->getIndexed(ii)), engine);
} else if (v.isInteger()) {
reserve(data, 2 * sizeof(quint32));
push(data, valueheader(WorkerInt32));
@@ -240,7 +242,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi
if (o->isListType()) {
// valid sequence. we generate a length (sequence length + 1 for the sequence type)
- uint32_t seqLength = o->get(v4->id_length).toUInt32();
+ uint32_t seqLength = ScopedValue(scope, o->get(v4->id_length))->toUInt32();
uint32_t length = seqLength + 1;
if (length > 0xFFFFFF) {
push(data, valueheader(WorkerUndefined));
@@ -250,7 +252,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi
push(data, valueheader(WorkerSequence, length));
serialize(data, QV4::Value::fromInt32(QV4::SequencePrototype::metaTypeForSequence(o)), engine); // sequence type
for (uint32_t ii = 0; ii < seqLength; ++ii)
- serialize(data, o->getIndexed(ii), engine); // sequence elements
+ serialize(data, QV4::Value::fromReturnedValue(o->getIndexed(ii)), engine); // sequence elements
return;
}
@@ -264,16 +266,15 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi
}
push(data, valueheader(WorkerObject, length));
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::ScopedValue val(scope);
+ QV4::ScopedValue s(scope);
for (quint32 ii = 0; ii < length; ++ii) {
- QV4::String *s = properties->getIndexed(ii).asString();
- serialize(data, QV4::Value::fromString(s), engine);
+ s = properties->getIndexed(ii);
+ serialize(data, s, engine);
- bool hasCaught = false;
QV4::ExecutionContext *ctx = v4->current;
- QV4::Value val = QV4::Value::undefinedValue();
try {
- val = o->get(s);
+ val = o->get(s->asString());
} catch (QV4::Exception &e) {
e.accept(ctx);
}
@@ -286,28 +287,29 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi
}
}
-QV4::Value Serialize::deserialize(const char *&data, QV8Engine *engine)
+ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine)
{
quint32 header = popUint32(data);
Type type = headertype(header);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ Scope scope(v4);
switch (type) {
case WorkerUndefined:
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
case WorkerNull:
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
case WorkerTrue:
- return QV4::Value::fromBoolean(true);
+ return QV4::Encode(true);
case WorkerFalse:
- return QV4::Value::fromBoolean(false);
+ return QV4::Encode(false);
case WorkerString:
{
quint32 size = headersize(header);
QString qstr((QChar *)data, size);
data += ALIGN(size * sizeof(uint16_t));
- return QV4::Value::fromString(v4->newString(qstr));
+ return QV4::Value::fromString(v4->newString(qstr)).asReturnedValue();
}
case WorkerFunction:
Q_ASSERT(!"Unreachable");
@@ -315,71 +317,80 @@ QV4::Value Serialize::deserialize(const char *&data, QV8Engine *engine)
case WorkerArray:
{
quint32 size = headersize(header);
- QV4::ArrayObject *a = v4->newArrayObject();
+ Scoped<ArrayObject> a(scope, v4->newArrayObject());
+ ScopedValue v(scope);
for (quint32 ii = 0; ii < size; ++ii) {
- a->putIndexed(ii, deserialize(data, engine));
+ v = deserialize(data, engine);
+ a->putIndexed(ii, v);
}
- return QV4::Value::fromObject(a);
+ return a.asReturnedValue();
}
case WorkerObject:
{
quint32 size = headersize(header);
QV4::Object *o = v4->newObject();
+ ScopedValue name(scope);
+ ScopedValue value(scope);
for (quint32 ii = 0; ii < size; ++ii) {
- QV4::Value name = deserialize(data, engine);
- QV4::Value value = deserialize(data, engine);
- o->put(name.asString(), value);
+ name = deserialize(data, engine);
+ value = deserialize(data, engine);
+ o->put(name->asString(), value);
}
- return QV4::Value::fromObject(o);
+ return QV4::Value::fromObject(o).asReturnedValue();
}
case WorkerInt32:
- return QV4::Value::fromInt32((qint32)popUint32(data));
+ return QV4::Encode((qint32)popUint32(data));
case WorkerUint32:
- return QV4::Value::fromUInt32(popUint32(data));
+ return QV4::Encode(popUint32(data));
case WorkerNumber:
- return QV4::Value::fromDouble(popDouble(data));
+ return QV4::Encode(popDouble(data));
case WorkerDate:
- return QV4::Value::fromObject(v4->newDateObject(QV4::Value::fromDouble(popDouble(data))));
+ return QV4::Encode(v4->newDateObject(QV4::Value::fromDouble(popDouble(data))));
case WorkerRegexp:
{
quint32 flags = headersize(header);
quint32 length = popUint32(data);
QString pattern = QString((QChar *)data, length - 1);
data += ALIGN(length * sizeof(uint16_t));
- return QV4::Value::fromObject(v4->newRegExpObject(pattern, flags));
+ return Encode(v4->newRegExpObject(pattern, flags));
}
case WorkerListModel:
{
void *ptr = popPtr(data);
QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr;
- QV4::Value rv = QV4::QObjectWrapper::wrap(v4, agent);
+ QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(v4, agent));
// ### Find a better solution then the ugly property
QQmlListModelWorkerAgent::VariantRef ref(agent);
QVariant var = qVariantFromValue(ref);
- rv.asObject()->defineReadonlyProperty(v4->newString("__qml:hidden:ref"), engine->fromVariant(var));
+ QV4::ScopedValue v(scope, engine->fromVariant((var)));
+ rv->asObject()->defineReadonlyProperty(v4->newString("__qml:hidden:ref"), v);
agent->release();
agent->setV8Engine(engine);
- return rv;
+ return rv.asReturnedValue();
}
case WorkerSequence:
{
+ ScopedValue value(scope);
bool succeeded = false;
quint32 length = headersize(header);
quint32 seqLength = length - 1;
- int sequenceType = deserialize(data, engine).integerValue();
- QV4::ArrayObject *array = v4->newArrayObject();
+ value = deserialize(data, engine);
+ int sequenceType = value->integerValue();
+ Scoped<ArrayObject> array(scope, v4->newArrayObject());
array->arrayReserve(seqLength);
array->arrayDataLen = seqLength;
- for (quint32 ii = 0; ii < seqLength; ++ii)
- array->arrayData[ii].value = deserialize(data, engine);
+ for (quint32 ii = 0; ii < seqLength; ++ii) {
+ value = deserialize(data, engine);
+ array->arrayData[ii].value = value;
+ }
array->setArrayLengthUnchecked(seqLength);
- QVariant seqVariant = QV4::SequencePrototype::toVariant(QV4::Value::fromObject(array), sequenceType, &succeeded);
+ QVariant seqVariant = QV4::SequencePrototype::toVariant(array.asValue(), sequenceType, &succeeded);
return QV4::SequencePrototype::fromVariant(v4, seqVariant, &succeeded);
}
}
Q_ASSERT(!"Unreachable");
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
QByteArray Serialize::serialize(const QV4::Value &value, QV8Engine *engine)
@@ -389,7 +400,7 @@ QByteArray Serialize::serialize(const QV4::Value &value, QV8Engine *engine)
return rv;
}
-QV4::Value Serialize::deserialize(const QByteArray &data, QV8Engine *engine)
+ReturnedValue Serialize::deserialize(const QByteArray &data, QV8Engine *engine)
{
const char *stream = data.constData();
return deserialize(stream, engine);
diff --git a/src/qml/jsruntime/qv4serialize_p.h b/src/qml/jsruntime/qv4serialize_p.h
index 5a04c9d25f..caedb962b1 100644
--- a/src/qml/jsruntime/qv4serialize_p.h
+++ b/src/qml/jsruntime/qv4serialize_p.h
@@ -66,11 +66,11 @@ class Serialize {
public:
static QByteArray serialize(const Value &, QV8Engine *);
- static Value deserialize(const QByteArray &, QV8Engine *);
+ static ReturnedValue deserialize(const QByteArray &, QV8Engine *);
private:
static void serialize(QByteArray &, const Value &, QV8Engine *);
- static Value deserialize(const char *&, QV8Engine *);
+ static ReturnedValue deserialize(const char *&, QV8Engine *);
};
}
diff --git a/src/qml/jsruntime/qv4sparsearray.cpp b/src/qml/jsruntime/qv4sparsearray.cpp
index f21855ebc9..faa2f310ed 100644
--- a/src/qml/jsruntime/qv4sparsearray.cpp
+++ b/src/qml/jsruntime/qv4sparsearray.cpp
@@ -61,13 +61,15 @@ bool ArrayElementLessThan::operator()(const Property &p1, const Property &p2) co
if (p2.value.isUndefined())
return true;
if (Object *o = m_comparefn.asObject()) {
- ScopedCallData callData(o->engine(), 2);
+ Scope scope(o->engine());
+ ScopedValue result(scope);
+ ScopedCallData callData(scope, 2);
callData->thisObject = Value::undefinedValue();
callData->args[0] = p1.value;
callData->args[1] = p2.value;
- Value result = Value::undefinedValue();
- __qmljs_call_value(m_context, &result, QV4::ValueRef::fromRawValue(&m_comparefn), callData);
- return result.toNumber() <= 0;
+ result = __qmljs_call_value(m_context, QV4::ValueRef::fromRawValue(&m_comparefn), callData);
+
+ return result->toNumber() <= 0;
}
return p1.value.toString(m_context)->toQString() < p2.value.toString(m_context)->toQString();
}
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 11d3100180..bd1f14b680 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -129,42 +129,42 @@ void String::destroy(Managed *that)
static_cast<String*>(that)->~String();
}
-Value String::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue String::get(Managed *m, String *name, bool *hasProperty)
{
String *that = static_cast<String *>(m);
ExecutionEngine *v4 = m->engine();
if (name == v4->id_length) {
if (hasProperty)
*hasProperty = true;
- return Value::fromInt32(that->_text.length());
+ return Value::fromInt32(that->_text.length()).asReturnedValue();
}
PropertyAttributes attrs;
Property *pd = v4->stringClass->prototype->__getPropertyDescriptor__(name, &attrs);
if (!pd || attrs.isGeneric()) {
if (hasProperty)
*hasProperty = false;
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
if (hasProperty)
*hasProperty = true;
return v4->stringClass->prototype->getValue(Value::fromString(that), pd, attrs);
}
-Value String::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue String::getIndexed(Managed *m, uint index, bool *hasProperty)
{
String *that = static_cast<String *>(m);
ExecutionEngine *engine = that->engine();
if (index < that->_text.length()) {
if (hasProperty)
*hasProperty = true;
- return Value::fromString(engine->newString(that->toQString().mid(index, 1)));
+ return Value::fromString(engine->newString(that->toQString().mid(index, 1))).asReturnedValue();
}
PropertyAttributes attrs;
Property *pd = engine->stringClass->prototype->__getPropertyDescriptor__(index, &attrs);
if (!pd || attrs.isGeneric()) {
if (hasProperty)
*hasProperty = false;
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
if (hasProperty)
*hasProperty = true;
@@ -173,15 +173,17 @@ Value String::getIndexed(Managed *m, uint index, bool *hasProperty)
void String::put(Managed *m, String *name, const Value &value)
{
+ Scope scope(m->engine());
String *that = static_cast<String *>(m);
- Object *o = that->engine()->newStringObject(Value::fromString(that));
+ Scoped<Object> o(scope, that->engine()->newStringObject(Value::fromString(that)));
o->put(name, value);
}
void String::putIndexed(Managed *m, uint index, const Value &value)
{
+ Scope scope(m->engine());
String *that = static_cast<String *>(m);
- Object *o = m->engine()->newStringObject(Value::fromString(that));
+ Scoped<Object> o(scope, that->engine()->newStringObject(Value::fromString(that)));
o->putIndexed(index, value);
}
@@ -213,6 +215,8 @@ bool String::isEqualTo(Managed *t, Managed *o)
{
if (t == o)
return true;
+
+ Q_ASSERT(t->type == Type_String && o->type == Type_String);
String *that = static_cast<String *>(t);
String *other = static_cast<String *>(o);
if (that->hashValue() != other->hashValue())
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 31e5c2a5f7..7dd912a41f 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -52,6 +52,7 @@ struct ExecutionEngine;
struct Identifier;
struct Q_QML_EXPORT String : public Managed {
+ Q_MANAGED
enum StringType {
StringType_Unknown,
StringType_Regular,
@@ -119,6 +120,10 @@ struct Q_QML_EXPORT String : public Managed {
return _text.length();
}
+ static String *cast(const Value &v) {
+ return v.asString();
+ }
+
QString _text;
mutable Identifier *identifier;
mutable uint stringHash;
@@ -126,8 +131,8 @@ struct Q_QML_EXPORT String : public Managed {
protected:
static void destroy(Managed *);
- static Value get(Managed *m, String *name, bool *hasProperty);
- static Value getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static void putIndexed(Managed *m, uint index, const Value &value);
static PropertyAttributes query(const Managed *m, String *name);
@@ -135,8 +140,6 @@ protected:
static bool deleteProperty(Managed *, String *);
static bool deleteIndexedProperty(Managed *m, uint index);
static bool isEqualTo(Managed *that, Managed *o);
-
- static const ManagedVTable static_vtbl;
};
}
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 0a9cb32e6f..811c5b26b9 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -160,24 +160,24 @@ StringCtor::StringCtor(ExecutionContext *scope)
vtbl = &static_vtbl;
}
-Value StringCtor::construct(Managed *m, CallData *callData)
+ReturnedValue StringCtor::construct(Managed *m, CallData *callData)
{
Value value;
if (callData->argc)
value = Value::fromString(callData->args[0].toString(m->engine()->current));
else
value = Value::fromString(m->engine()->current, QString());
- return Value::fromObject(m->engine()->newStringObject(value));
+ return Encode(m->engine()->newStringObject(value));
}
-Value StringCtor::call(Managed *m, CallData *callData)
+ReturnedValue StringCtor::call(Managed *m, CallData *callData)
{
Value value;
if (callData->argc)
value = Value::fromString(callData->args[0].toString(m->engine()->current));
else
value = Value::fromString(m->engine()->current, QString());
- return value;
+ return value.asReturnedValue();
}
void StringPrototype::init(ExecutionEngine *engine, const Value &ctor)
@@ -237,18 +237,18 @@ static QString getThisString(ExecutionContext *context, Value thisObject)
return str->toQString();
}
-Value StringPrototype::method_toString(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_toString(SimpleCallContext *context)
{
if (context->thisObject.isString())
- return context->thisObject;
+ return context->thisObject.asReturnedValue();
StringObject *o = context->thisObject.asStringObject();
if (!o)
context->throwTypeError();
- return o->value;
+ return o->value.asReturnedValue();
}
-Value StringPrototype::method_charAt(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_charAt(SimpleCallContext *context)
{
const QString str = getThisString(context, context->thisObject);
@@ -260,10 +260,10 @@ Value StringPrototype::method_charAt(SimpleCallContext *context)
if (pos >= 0 && pos < str.length())
result += str.at(pos);
- return Value::fromString(context, result);
+ return Value::fromString(context, result).asReturnedValue();
}
-Value StringPrototype::method_charCodeAt(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_charCodeAt(SimpleCallContext *context)
{
const QString str = getThisString(context, context->thisObject);
@@ -273,14 +273,14 @@ Value StringPrototype::method_charCodeAt(SimpleCallContext *context)
if (pos >= 0 && pos < str.length())
- return Value::fromInt32(str.at(pos).unicode());
+ return Encode(str.at(pos).unicode());
- return Value::fromDouble(qSNaN());
+ return Encode(qSNaN());
}
-Value StringPrototype::method_concat(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_concat(SimpleCallContext *context)
{
- ValueScope scope(context);
+ Scope scope(context);
QString value = getThisString(context, context->thisObject);
@@ -291,10 +291,10 @@ Value StringPrototype::method_concat(SimpleCallContext *context)
value += v->stringValue()->toQString();
}
- return Value::fromString(context, value);
+ return Value::fromString(context, value).asReturnedValue();
}
-Value StringPrototype::method_indexOf(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_indexOf(SimpleCallContext *context)
{
QString value = getThisString(context, context->thisObject);
@@ -310,20 +310,18 @@ Value StringPrototype::method_indexOf(SimpleCallContext *context)
if (! value.isEmpty())
index = value.indexOf(searchString, qMin(qMax(pos, 0), value.length()));
- return Value::fromDouble(index);
+ return Encode(index);
}
-Value StringPrototype::method_lastIndexOf(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_lastIndexOf(SimpleCallContext *context)
{
- ValueScope scope(context);
+ Scope scope(context);
const QString value = getThisString(context, context->thisObject);
QString searchString;
- if (context->argumentCount) {
- Value v = __qmljs_to_string(ValueRef(&context->arguments[0]), context);
- searchString = v.stringValue()->toQString();
- }
+ if (context->argumentCount)
+ searchString = context->arguments[0].toQString();
ScopedValue posArg(scope, context->argumentCount > 1 ? context->arguments[1] : Value::undefinedValue());
double position = __qmljs_to_number(posArg);
@@ -336,31 +334,32 @@ Value StringPrototype::method_lastIndexOf(SimpleCallContext *context)
if (!searchString.isEmpty() && pos == value.length())
--pos;
if (searchString.isNull() && pos == 0)
- return Value::fromDouble(-1);
+ return Encode(-1);
int index = value.lastIndexOf(searchString, pos);
- return Value::fromDouble(index);
+ return Encode(index);
}
-Value StringPrototype::method_localeCompare(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_localeCompare(SimpleCallContext *context)
{
const QString value = getThisString(context, context->thisObject);
const QString that = (context->argumentCount ? context->arguments[0] : Value::undefinedValue()).toString(context)->toQString();
- return Value::fromDouble(QString::localeAwareCompare(value, that));
+ return Encode(QString::localeAwareCompare(value, that));
}
-Value StringPrototype::method_match(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_match(SimpleCallContext *context)
{
if (context->thisObject.isUndefined() || context->thisObject.isNull())
context->throwTypeError();
+ Scope scope(context);
String *s = context->thisObject.toString(context);
Value regexp = context->argumentCount ? context->arguments[0] : Value::undefinedValue();
RegExpObject *rx = regexp.as<RegExpObject>();
if (!rx) {
- ScopedCallData callData(context->engine, 1);
+ ScopedCallData callData(scope, 1);
callData->args[0] = regexp;
- rx = context->engine->regExpCtor.asFunctionObject()->construct(callData).as<RegExpObject>();
+ rx = Value::fromReturnedValue(context->engine->regExpCtor.asFunctionObject()->construct(callData)).as<RegExpObject>();
}
if (!rx)
@@ -370,9 +369,9 @@ Value StringPrototype::method_match(SimpleCallContext *context)
bool global = rx->global;
// ### use the standard builtin function, not the one that might be redefined in the proto
- FunctionObject *exec = context->engine->regExpClass->prototype->get(context->engine->newString(QStringLiteral("exec")), 0).asFunctionObject();
+ Scoped<FunctionObject> exec(scope, context->engine->regExpClass->prototype->get(context->engine->newString(QStringLiteral("exec")), 0));
- ScopedCallData callData(context->engine, 1);
+ ScopedCallData callData(scope, 1);
callData->thisObject = Value::fromObject(rx);
callData->args[0] = Value::fromString(s);
if (!global)
@@ -380,30 +379,34 @@ Value StringPrototype::method_match(SimpleCallContext *context)
String *lastIndex = context->engine->newString(QStringLiteral("lastIndex"));
rx->put(lastIndex, Value::fromInt32(0));
- ArrayObject *a = context->engine->newArrayObject();
+ Scoped<ArrayObject> a(scope, context->engine->newArrayObject());
double previousLastIndex = 0;
uint n = 0;
+ ScopedValue result(scope);
+ ScopedValue matchStr(scope);
+ ScopedValue index(scope);
while (1) {
- Value result = exec->call(callData);
- if (result.isNull())
+ result = exec->call(callData);
+ if (result->isNull())
break;
- assert(result.isObject());
- double thisIndex = rx->get(lastIndex, 0).toInteger();
+ assert(result->isObject());
+ index = rx->get(lastIndex, 0);
+ double thisIndex = index->toInteger();
if (previousLastIndex == thisIndex) {
previousLastIndex = thisIndex + 1;
rx->put(lastIndex, Value::fromDouble(previousLastIndex));
} else {
previousLastIndex = thisIndex;
}
- Value matchStr = result.objectValue()->getIndexed(0);
+ matchStr = result->objectValue()->getIndexed(0);
a->arraySet(n, matchStr);
++n;
}
if (!n)
- return Value::nullValue();
+ return Encode::null();
- return Value::fromObject(a);
+ return a.asReturnedValue();
}
@@ -452,8 +455,9 @@ static void appendReplacementString(QString *result, const QString &input, const
}
}
-Value StringPrototype::method_replace(SimpleCallContext *ctx)
+ReturnedValue StringPrototype::method_replace(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
QString string;
if (StringObject *thisString = ctx->thisObject.asStringObject())
string = thisString->value.stringValue()->toQString();
@@ -509,9 +513,10 @@ Value StringPrototype::method_replace(SimpleCallContext *ctx)
QString result;
Value replaceValue = ctx->argument(1);
+ ScopedValue replacement(scope);
if (FunctionObject* searchCallback = replaceValue.asFunctionObject()) {
result.reserve(string.length() + 10*numStringMatches);
- ScopedCallData callData(ctx->engine, numCaptures + 2);
+ ScopedCallData callData(scope, numCaptures + 2);
callData->thisObject = Value::undefinedValue();
int lastEnd = 0;
for (int i = 0; i < numStringMatches; ++i) {
@@ -530,9 +535,9 @@ Value StringPrototype::method_replace(SimpleCallContext *ctx)
callData->args[numCaptures] = Value::fromUInt32(matchStart);
callData->args[numCaptures + 1] = Value::fromString(ctx, string);
- Value replacement = searchCallback->call(callData);
+ replacement = searchCallback->call(callData);
result += string.midRef(lastEnd, matchStart - lastEnd);
- result += replacement.toString(ctx)->toQString();
+ result += replacement->toString(ctx)->toQString();
lastEnd = matchEnd;
}
result += string.midRef(lastEnd);
@@ -558,33 +563,34 @@ Value StringPrototype::method_replace(SimpleCallContext *ctx)
if (matchOffsets != _matchOffsets)
free(matchOffsets);
- return Value::fromString(ctx, result);
+ return Value::fromString(ctx, result).asReturnedValue();
}
-Value StringPrototype::method_search(SimpleCallContext *ctx)
+ReturnedValue StringPrototype::method_search(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
QString string;
if (StringObject *thisString = ctx->thisObject.asStringObject())
string = thisString->value.stringValue()->toQString();
else
string = ctx->thisObject.toString(ctx)->toQString();
- Value regExpValue = ctx->argument(0);
- RegExpObject *regExp = regExpValue.as<RegExpObject>();
+ ScopedValue regExpValue(scope, ctx->argument(0));
+ RegExpObject *regExp = regExpValue->as<RegExpObject>();
if (!regExp) {
- ScopedCallData callData(ctx->engine, 1);
+ ScopedCallData callData(scope, 1);
callData->args[0] = regExpValue;
regExpValue = ctx->engine->regExpCtor.asFunctionObject()->construct(callData);
- regExp = regExpValue.as<RegExpObject>();
+ regExp = regExpValue->as<RegExpObject>();
}
uint* matchOffsets = (uint*)alloca(regExp->value->captureCount() * 2 * sizeof(uint));
uint result = regExp->value->match(string, /*offset*/0, matchOffsets);
if (result == JSC::Yarr::offsetNoMatch)
- return Value::fromInt32(-1);
- return Value::fromUInt32(result);
+ return Encode(-1);
+ return Encode(result);
}
-Value StringPrototype::method_slice(SimpleCallContext *ctx)
+ReturnedValue StringPrototype::method_slice(SimpleCallContext *ctx)
{
const QString text = getThisString(ctx);
const double length = text.length();
@@ -607,11 +613,12 @@ Value StringPrototype::method_slice(SimpleCallContext *ctx)
const int intEnd = int(end);
int count = qMax(0, intEnd - intStart);
- return Value::fromString(ctx, text.mid(intStart, count));
+ return Value::fromString(ctx, text.mid(intStart, count)).asReturnedValue();
}
-Value StringPrototype::method_split(SimpleCallContext *ctx)
+ReturnedValue StringPrototype::method_split(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
QString text;
if (StringObject *thisObject = ctx->thisObject.asStringObject())
text = thisObject->value.stringValue()->toQString();
@@ -621,21 +628,20 @@ Value StringPrototype::method_split(SimpleCallContext *ctx)
Value separatorValue = ctx->argumentCount > 0 ? ctx->argument(0) : Value::undefinedValue();
Value limitValue = ctx->argumentCount > 1 ? ctx->argument(1) : Value::undefinedValue();
- ArrayObject* array = ctx->engine->newArrayObject();
- Value result = Value::fromObject(array);
+ Scoped<ArrayObject> array(scope, ctx->engine->newArrayObject());
if (separatorValue.isUndefined()) {
if (limitValue.isUndefined()) {
array->push_back(Value::fromString(ctx, text));
- return result;
+ return array.asReturnedValue();
}
- return Value::fromString(ctx, text.left(limitValue.toInteger()));
+ return Value::fromString(ctx, text.left(limitValue.toInteger())).asReturnedValue();
}
uint limit = limitValue.isUndefined() ? UINT_MAX : limitValue.toUInt32();
if (limit == 0)
- return result;
+ return array.asReturnedValue();
if (RegExpObject* re = separatorValue.as<RegExpObject>()) {
if (re->value->pattern().isEmpty()) {
@@ -673,7 +679,7 @@ Value StringPrototype::method_split(SimpleCallContext *ctx)
if (separator.isEmpty()) {
for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
array->push_back(Value::fromString(ctx, text.mid(i, 1)));
- return result;
+ return array.asReturnedValue();
}
int start = 0;
@@ -687,10 +693,10 @@ Value StringPrototype::method_split(SimpleCallContext *ctx)
if (array->arrayLength() < limit && start != -1)
array->push_back(Value::fromString(ctx, text.mid(start)));
}
- return result;
+ return array.asReturnedValue();
}
-Value StringPrototype::method_substr(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_substr(SimpleCallContext *context)
{
const QString value = getThisString(context, context->thisObject);
@@ -710,10 +716,10 @@ Value StringPrototype::method_substr(SimpleCallContext *context)
qint32 x = Value::toInt32(start);
qint32 y = Value::toInt32(length);
- return Value::fromString(context, value.mid(x, y));
+ return Value::fromString(context, value.mid(x, y)).asReturnedValue();
}
-Value StringPrototype::method_substring(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_substring(SimpleCallContext *context)
{
QString value = getThisString(context, context->thisObject);
int length = value.length();
@@ -748,32 +754,32 @@ Value StringPrototype::method_substring(SimpleCallContext *context)
qint32 x = (int)start;
qint32 y = (int)(end - start);
- return Value::fromString(context, value.mid(x, y));
+ return Value::fromString(context, value.mid(x, y)).asReturnedValue();
}
-Value StringPrototype::method_toLowerCase(SimpleCallContext *ctx)
+ReturnedValue StringPrototype::method_toLowerCase(SimpleCallContext *ctx)
{
QString value = getThisString(ctx);
- return Value::fromString(ctx, value.toLower());
+ return Value::fromString(ctx, value.toLower()).asReturnedValue();
}
-Value StringPrototype::method_toLocaleLowerCase(SimpleCallContext *ctx)
+ReturnedValue StringPrototype::method_toLocaleLowerCase(SimpleCallContext *ctx)
{
return method_toLowerCase(ctx);
}
-Value StringPrototype::method_toUpperCase(SimpleCallContext *ctx)
+ReturnedValue StringPrototype::method_toUpperCase(SimpleCallContext *ctx)
{
QString value = getThisString(ctx);
- return Value::fromString(ctx, value.toUpper());
+ return Value::fromString(ctx, value.toUpper()).asReturnedValue();
}
-Value StringPrototype::method_toLocaleUpperCase(SimpleCallContext *ctx)
+ReturnedValue StringPrototype::method_toLocaleUpperCase(SimpleCallContext *ctx)
{
return method_toUpperCase(ctx);
}
-Value StringPrototype::method_fromCharCode(SimpleCallContext *context)
+ReturnedValue StringPrototype::method_fromCharCode(SimpleCallContext *context)
{
QString str(context->argumentCount, Qt::Uninitialized);
QChar *ch = str.data();
@@ -781,15 +787,15 @@ Value StringPrototype::method_fromCharCode(SimpleCallContext *context)
*ch = QChar(context->arguments[i].toUInt16());
++ch;
}
- return Value::fromString(context, str);
+ return Value::fromString(context, str).asReturnedValue();
}
-Value StringPrototype::method_trim(SimpleCallContext *ctx)
+ReturnedValue StringPrototype::method_trim(SimpleCallContext *ctx)
{
if (ctx->thisObject.isNull() || ctx->thisObject.isUndefined())
ctx->throwTypeError();
- QString s = __qmljs_to_string(ValueRef(&ctx->thisObject), ctx).stringValue()->toQString();
+ QString s = ctx->thisObject.toQString();
const QChar *chars = s.constData();
int start, end;
for (start = 0; start < s.length(); ++start) {
@@ -801,5 +807,5 @@ Value StringPrototype::method_trim(SimpleCallContext *ctx)
break;
}
- return Value::fromString(ctx, QString(chars + start, end - start + 1));
+ return Value::fromString(ctx, QString(chars + start, end - start + 1)).asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index f9cf89e9d9..0932379843 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -68,13 +68,11 @@ protected:
struct StringCtor: FunctionObject
{
+ Q_MANAGED
StringCtor(ExecutionContext *scope);
- static Value construct(Managed *m, CallData *callData);
- static Value call(Managed *that, CallData *callData);
-
-protected:
- static const ManagedVTable static_vtbl;
+ static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
};
struct StringPrototype: StringObject
@@ -82,26 +80,26 @@ struct StringPrototype: StringObject
StringPrototype(InternalClass *ic): StringObject(ic) {}
void init(ExecutionEngine *engine, const Value &ctor);
- static Value method_toString(SimpleCallContext *context);
- static Value method_charAt(SimpleCallContext *context);
- static Value method_charCodeAt(SimpleCallContext *context);
- static Value method_concat(SimpleCallContext *context);
- static Value method_indexOf(SimpleCallContext *context);
- static Value method_lastIndexOf(SimpleCallContext *context);
- static Value method_localeCompare(SimpleCallContext *context);
- static Value method_match(SimpleCallContext *context);
- static Value method_replace(SimpleCallContext *ctx);
- static Value method_search(SimpleCallContext *ctx);
- static Value method_slice(SimpleCallContext *ctx);
- static Value method_split(SimpleCallContext *ctx);
- static Value method_substr(SimpleCallContext *context);
- static Value method_substring(SimpleCallContext *context);
- static Value method_toLowerCase(SimpleCallContext *ctx);
- static Value method_toLocaleLowerCase(SimpleCallContext *ctx);
- static Value method_toUpperCase(SimpleCallContext *ctx);
- static Value method_toLocaleUpperCase(SimpleCallContext *ctx);
- static Value method_fromCharCode(SimpleCallContext *context);
- static Value method_trim(SimpleCallContext *ctx);
+ static ReturnedValue method_toString(SimpleCallContext *context);
+ static ReturnedValue method_charAt(SimpleCallContext *context);
+ static ReturnedValue method_charCodeAt(SimpleCallContext *context);
+ static ReturnedValue method_concat(SimpleCallContext *context);
+ static ReturnedValue method_indexOf(SimpleCallContext *context);
+ static ReturnedValue method_lastIndexOf(SimpleCallContext *context);
+ static ReturnedValue method_localeCompare(SimpleCallContext *context);
+ static ReturnedValue method_match(SimpleCallContext *context);
+ static ReturnedValue method_replace(SimpleCallContext *ctx);
+ static ReturnedValue method_search(SimpleCallContext *ctx);
+ static ReturnedValue method_slice(SimpleCallContext *ctx);
+ static ReturnedValue method_split(SimpleCallContext *ctx);
+ static ReturnedValue method_substr(SimpleCallContext *context);
+ static ReturnedValue method_substring(SimpleCallContext *context);
+ static ReturnedValue method_toLowerCase(SimpleCallContext *ctx);
+ static ReturnedValue method_toLocaleLowerCase(SimpleCallContext *ctx);
+ static ReturnedValue method_toUpperCase(SimpleCallContext *ctx);
+ static ReturnedValue method_toLocaleUpperCase(SimpleCallContext *ctx);
+ static ReturnedValue method_fromCharCode(SimpleCallContext *context);
+ static ReturnedValue method_trim(SimpleCallContext *ctx);
};
}
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index 718b87d2c9..f97aa66669 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -48,44 +48,9 @@
using namespace QV4;
-int Value::toInt32() const
-{
- if (isConvertibleToInt())
- return int_32;
- double d;
- if (isDouble())
- d = dbl;
- else
- d = toNumber();
-
- const double D32 = 4294967296.0;
- const double D31 = D32 / 2.0;
-
- if ((d >= -D31 && d < D31))
- return static_cast<int>(d);
-
- return Value::toInt32(d);
-}
-
-unsigned int Value::toUInt32() const
-{
- if (isConvertibleToInt())
- return (unsigned) int_32;
- double d;
- if (isDouble())
- d = dbl;
- else
- d = toNumber();
-
- const double D32 = 4294967296.0;
- if (d >= 0 && d < D32)
- return static_cast<uint>(d);
- return toUInt32(d);
-}
-
int Value::toUInt16() const
{
- if (isConvertibleToInt())
+ if (integerCompatible())
return (ushort)(uint)integerValue();
double number = toNumber();
@@ -111,41 +76,39 @@ int Value::toUInt16() const
double Value::toInteger() const
{
- if (isConvertibleToInt())
+ if (integerCompatible())
return int_32;
return Value::toInteger(toNumber());
}
-double Value::toNumber() const
+double Value::toNumberImpl() const
{
- QV4::Value v = *this;
-
- redo:
- switch (v.type()) {
+ switch (type()) {
case QV4::Value::Undefined_Type:
return std::numeric_limits<double>::quiet_NaN();
+ case QV4::Value::Managed_Type:
+ if (isString())
+ return __qmljs_string_to_number(stringValue()->toQString());
+ {
+ ExecutionContext *ctx = objectValue()->internalClass->engine->current;
+ Scope scope(ctx);
+ ScopedValue prim(scope, __qmljs_to_primitive(ValueRef::fromRawValue(this), NUMBER_HINT));
+ return prim->toNumber();
+ }
case QV4::Value::Null_Type:
- return 0;
case QV4::Value::Boolean_Type:
- return (v.booleanValue() ? 1. : 0.);
case QV4::Value::Integer_Type:
- return v.int_32;
- case QV4::Value::String_Type:
- return __qmljs_string_to_number(v.toQString());
- case QV4::Value::Object_Type: {
- v = __qmljs_to_primitive(ValueRef::fromRawValue(this), QV4::NUMBER_HINT);
- goto redo;
- }
default: // double
- return v.doubleValue();
+ Q_UNREACHABLE();
}
}
-QString Value::toQString() const
+QString Value::toQStringNoThrow() const
{
switch (type()) {
case Value::Undefined_Type:
+ case Value::Empty_Type:
return QStringLiteral("undefined");
case Value::Null_Type:
return QStringLiteral("null");
@@ -154,28 +117,64 @@ QString Value::toQString() const
return QStringLiteral("true");
else
return QStringLiteral("false");
- case Value::String_Type:
- return stringValue()->toQString();
- case Value::Object_Type: {
- ExecutionContext *ctx = objectValue()->internalClass->engine->current;
- ValueScope scope(ctx);
- try {
- ScopedValue prim(scope, __qmljs_to_primitive(ValueRef::fromRawValue(this), STRING_HINT));
- if (prim->isPrimitive())
- return prim->toQString();
- } catch (Exception &e) {
- e.accept(ctx);
+ case Value::Managed_Type:
+ if (isString())
+ return stringValue()->toQString();
+ {
+ ExecutionContext *ctx = objectValue()->internalClass->engine->current;
+ Scope scope(ctx);
try {
- ScopedValue ex(scope, e.value());
- ScopedValue prim(scope, __qmljs_to_primitive(ex, STRING_HINT));
+ ScopedValue prim(scope, __qmljs_to_primitive(ValueRef::fromRawValue(this), STRING_HINT));
if (prim->isPrimitive())
- return prim->toQString();
- } catch(Exception &e) {
+ return prim->toQStringNoThrow();
+ } catch (Exception &e) {
e.accept(ctx);
+ try {
+ ScopedValue ex(scope, e.value());
+ ScopedValue prim(scope, __qmljs_to_primitive(ex, STRING_HINT));
+ if (prim->isPrimitive())
+ return prim->toQStringNoThrow();
+ } catch(Exception &e) {
+ e.accept(ctx);
+ }
}
+ return QString();
}
- return QString();
+ case Value::Integer_Type: {
+ QString str;
+ __qmljs_numberToString(&str, (double)int_32, 10);
+ return str;
+ }
+ default: { // double
+ QString str;
+ __qmljs_numberToString(&str, doubleValue(), 10);
+ return str;
}
+ } // switch
+}
+
+QString Value::toQString() const
+{
+ switch (type()) {
+ case Value::Undefined_Type:
+ case Value::Empty_Type:
+ return QStringLiteral("undefined");
+ case Value::Null_Type:
+ return QStringLiteral("null");
+ case Value::Boolean_Type:
+ if (booleanValue())
+ return QStringLiteral("true");
+ else
+ return QStringLiteral("false");
+ case Value::Managed_Type:
+ if (isString())
+ return stringValue()->toQString();
+ {
+ ExecutionContext *ctx = objectValue()->internalClass->engine->current;
+ Scope scope(ctx);
+ ScopedValue prim(scope, __qmljs_to_primitive(ValueRef::fromRawValue(this), STRING_HINT));
+ return prim->toQString();
+ }
case Value::Integer_Type: {
QString str;
__qmljs_numberToString(&str, (double)int_32, 10);
@@ -194,10 +193,10 @@ bool Value::sameValue(Value other) const {
return true;
if (isString() && other.isString())
return stringValue()->isEqualTo(other.stringValue());
- if (isInteger())
- return int_32 ? (double(int_32) == other.dbl) : (other.val == 0);
- if (other.isInteger())
- return other.int_32 ? (dbl == double(other.int_32)) : (val == 0);
+ if (isInteger() && other.isDouble())
+ return int_32 ? (double(int_32) == other.doubleValue()) : (other.val == 0);
+ if (isDouble() && other.isInteger())
+ return other.int_32 ? (doubleValue() == double(other.int_32)) : (val == 0);
return false;
}
@@ -273,25 +272,24 @@ String *Value::toString(ExecutionContext *ctx) const
{
if (isString())
return stringValue();
- return __qmljs_convert_to_string(ctx, ValueRef::fromRawValue(this));
+ return __qmljs_convert_to_string(ctx, ValueRef::fromRawValue(this))->getPointer();
}
Object *Value::toObject(ExecutionContext *ctx) const
{
if (isObject())
return objectValue();
- return __qmljs_convert_to_object(ctx, ValueRef::fromRawValue(this));
+ return __qmljs_convert_to_object(ctx, ValueRef::fromRawValue(this))->getPointer();
}
-Value Value::property(ExecutionContext *ctx, String *name) const
+PersistentValue::PersistentValue(const Value &val)
+ : d(new PersistentValuePrivate(val))
{
- return isObject() ? objectValue()->get(name) : undefinedValue();
}
-
-PersistentValue::PersistentValue(const Value &val)
- : d(new PersistentValuePrivate(val))
+PersistentValue::PersistentValue(ReturnedValue val)
+ : d(new PersistentValuePrivate(Value::fromReturnedValue(val)))
{
}
@@ -328,6 +326,16 @@ PersistentValue &PersistentValue::operator =(const Value &other)
return *this;
}
+PersistentValue &PersistentValue::operator =(const ReturnedValue &other)
+{
+ if (!d) {
+ d = new PersistentValuePrivate(Value::fromReturnedValue(other));
+ return *this;
+ }
+ d = d->detach(Value::fromReturnedValue(other));
+ return *this;
+}
+
PersistentValue::~PersistentValue()
{
if (d)
diff --git a/src/qml/jsruntime/qv4value_def_p.h b/src/qml/jsruntime/qv4value_def_p.h
index 7d037f3d49..76f694c0e9 100644
--- a/src/qml/jsruntime/qv4value_def_p.h
+++ b/src/qml/jsruntime/qv4value_def_p.h
@@ -52,9 +52,38 @@ typedef uint Bool;
struct Q_QML_EXPORT Value
{
+ /*
+ We use two different ways of encoding JS values. One for 32bit and one for 64bit systems.
+
+ In both cases, we 8 bytes for a value and different variant of NaN boxing. A Double NaN (actually -qNaN)
+ is indicated by a number that has the top 13 bits set. THe other values are usually set to 0 by the
+ processor, and are thus free for us to store other data. We keep pointers in there for managed objects,
+ and encode the other types using the free space given to use by the unused bits for NaN values. This also
+ works for pointers on 64 bit systems, as they all currently only have 48 bits of addressable memory.
+
+ On 32bit, we store doubles as doubles. All other values, have the high 32bits set to a value that
+ will make the number a NaN. The Masks below are used for encoding the other types.
+
+ On 64 bit, we xor Doubles with (0xffff8000 << 32). Thas has the effect that no doubles will get encoded
+ with the 13 highest bits all 0. We are now using special values for bits 14-17 to encode our values. These
+ can be used, as the highest valid pointer on a 64 bit system is 2^48-1.
+
+ If they are all 0, we have a pointer to a Managed object. If bit 14 is set we have an integer.
+ This makes testing for pointers and numbers very fast (we have a number if any of the highest 14 bits is set).
+
+ Bit 15-17 is then used to encode other immediates.
+ */
+
+
union {
quint64 val;
+#if QT_POINTER_SIZE == 8
+ Managed *m;
+ Object *o;
+ String *s;
+#else
double dbl;
+#endif
struct {
#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
uint tag;
@@ -74,12 +103,12 @@ struct Q_QML_EXPORT Value
};
};
+#if QT_POINTER_SIZE == 4
enum Masks {
NaN_Mask = 0x7ff80000,
NotDouble_Mask = 0x7ffc0000,
Type_Mask = 0xffff8000,
Immediate_Mask = NotDouble_Mask | 0x00008000,
- IsManaged_Mask = Type_Mask & ~0x10000,
IsNullOrUndefined_Mask = Immediate_Mask | 0x20000,
Tag_Shift = 32
};
@@ -88,9 +117,8 @@ struct Q_QML_EXPORT Value
Null_Type = Immediate_Mask | 0x10000,
Boolean_Type = Immediate_Mask | 0x20000,
Integer_Type = Immediate_Mask | 0x30000,
- Object_Type = NotDouble_Mask | 0x00000,
- String_Type = NotDouble_Mask | 0x10000,
- Deleted_Type = NotDouble_Mask | 0x30000
+ Managed_Type = NotDouble_Mask | 0x00000,
+ Empty_Type = NotDouble_Mask | 0x30000
};
enum ImmediateFlags {
@@ -98,45 +126,119 @@ struct Q_QML_EXPORT Value
};
enum ValueTypeInternal {
- _Undefined_Type = Undefined_Type,
- _Empty_Type = Deleted_Type,
_Null_Type = Null_Type | ConvertibleToInt,
_Boolean_Type = Boolean_Type | ConvertibleToInt,
_Integer_Type = Integer_Type | ConvertibleToInt,
- _Object_Type = Object_Type,
- _String_Type = String_Type
};
+#else
+ static const quint64 NaNEncodeMask = 0xffff800000000000ll;
+ static const quint64 IsInt32Mask = 0x0002000000000000ll;
+ static const quint64 IsDoubleMask = 0xfffc000000000000ll;
+ static const quint64 IsNumberMask = IsInt32Mask|IsDoubleMask;
+ static const quint64 IsNullOrUndefinedMask = 0x0000800000000000ll;
+ static const quint64 IsNullOrBooleanMask = 0x0001000000000000ll;
+ static const quint64 IsConvertibleToIntMask = IsInt32Mask|IsNullOrBooleanMask;
+
+ enum Masks {
+ NaN_Mask = 0x7ff80000,
+ Type_Mask = 0xffff8000,
+ IsDouble_Mask = 0xfffc0000,
+ Immediate_Mask = 0x00018000,
+ IsNullOrUndefined_Mask = 0x00008000,
+ IsNullOrBoolean_Mask = 0x00010000,
+ Tag_Shift = 32
+ };
+ enum ValueType {
+ Undefined_Type = IsNullOrUndefined_Mask,
+ Null_Type = IsNullOrUndefined_Mask|IsNullOrBoolean_Mask,
+ Boolean_Type = IsNullOrBoolean_Mask,
+ Integer_Type = 0x20000|IsNullOrBoolean_Mask,
+ Managed_Type = 0,
+ Empty_Type = Undefined_Type | 0x4000
+ };
+ enum {
+ IsDouble_Shift = 64-14,
+ IsNumber_Shift = 64-15,
+ IsConvertibleToInt_Shift = 64-16,
+ IsManaged_Shift = 64-17
+ };
+
+
+ enum ValueTypeInternal {
+ _Null_Type = Null_Type,
+ _Boolean_Type = Boolean_Type,
+ _Integer_Type = Integer_Type
+ };
+#endif
inline unsigned type() const {
return tag & Type_Mask;
}
// used internally in property
- inline bool isEmpty() const { return tag == _Empty_Type; }
+ inline bool isEmpty() const { return tag == Empty_Type; }
- inline bool isUndefined() const { return tag == _Undefined_Type; }
+ inline bool isUndefined() const { return tag == Undefined_Type; }
inline bool isNull() const { return tag == _Null_Type; }
inline bool isBoolean() const { return tag == _Boolean_Type; }
inline bool isInteger() const { return tag == _Integer_Type; }
- inline bool isDouble() const { return (tag & NotDouble_Mask) != NotDouble_Mask; }
- inline bool isNumber() const { return tag == _Integer_Type || (tag & NotDouble_Mask) != NotDouble_Mask; }
#if QT_POINTER_SIZE == 8
- inline bool isString() const { return (tag & Type_Mask) == String_Type; }
- inline bool isObject() const { return (tag & Type_Mask) == Object_Type; }
+ inline bool isDouble() const { return (val >> IsDouble_Shift); }
+ inline bool isNumber() const { return (val >> IsNumber_Shift); }
+ inline bool isManaged() const { return !(val >> IsManaged_Shift); }
+ inline bool isNullOrUndefined() const { return ((val >> IsManaged_Shift) & ~2) == 1; }
+ inline bool integerCompatible() const { return ((val >> IsConvertibleToInt_Shift) & ~2) == 1; }
+ static inline bool integerCompatible(Value a, Value b) {
+ return a.integerCompatible() && b.integerCompatible();
+ }
+ static inline bool bothDouble(Value a, Value b) {
+ return a.isDouble() && b.isDouble();
+ }
+ double doubleValue() const {
+ Q_ASSERT(isDouble());
+ union {
+ quint64 i;
+ double d;
+ } v;
+ v.i = val ^ NaNEncodeMask;
+ return v.d;
+ }
+ void setDouble(double d) {
+ union {
+ quint64 i;
+ double d;
+ } v;
+ v.d = d;
+ val = v.i ^ NaNEncodeMask;
+ Q_ASSERT(isDouble());
+ }
+ bool isNaN() const { return (tag & 0x7fff8000) == 0x00078000; }
#else
- inline bool isString() const { return tag == String_Type; }
- inline bool isObject() const { return tag == Object_Type; }
-#endif
- inline bool isManaged() const { return (tag & IsManaged_Mask) == Object_Type; }
+ inline bool isDouble() const { return (tag & NotDouble_Mask) != NotDouble_Mask; }
+ inline bool isNumber() const { return tag == _Integer_Type || (tag & NotDouble_Mask) != NotDouble_Mask; }
+ inline bool isManaged() const { return tag == Managed_Type; }
inline bool isNullOrUndefined() const { return (tag & IsNullOrUndefined_Mask) == Undefined_Type; }
- inline bool isConvertibleToInt() const { return (tag & ConvertibleToInt) == ConvertibleToInt; }
+ inline bool integerCompatible() const { return (tag & ConvertibleToInt) == ConvertibleToInt; }
+ static inline bool integerCompatible(Value a, Value b) {
+ return ((a.tag & b.tag) & ConvertibleToInt) == ConvertibleToInt;
+ }
+ static inline bool bothDouble(Value a, Value b) {
+ return ((a.tag | b.tag) & NotDouble_Mask) != NotDouble_Mask;
+ }
+ double doubleValue() const { return dbl; }
+ void setDouble(double d) { dbl = d; }
+ bool isNaN() const { return (tag & QV4::Value::NotDouble_Mask) == QV4::Value::NaN_Mask; }
+#endif
+ inline bool isString() const;
+ inline bool isObject() const;
inline bool isInt32() {
if (tag == _Integer_Type)
return true;
if (isDouble()) {
- int i = (int)dbl;
- if (i == dbl) {
+ double d = doubleValue();
+ int i = (int)d;
+ if (i == d) {
int_32 = i;
tag = _Integer_Type;
return true;
@@ -144,36 +246,19 @@ struct Q_QML_EXPORT Value
}
return false;
}
-
- bool booleanValue() const {
- return int_32;
- }
- double doubleValue() const {
- return dbl;
- }
- void setDouble(double d) {
- dbl = d;
- }
double asDouble() const {
if (tag == _Integer_Type)
return int_32;
- return dbl;
+ return doubleValue();
+ }
+
+ bool booleanValue() const {
+ return int_32;
}
int integerValue() const {
return int_32;
}
-#if QT_POINTER_SIZE == 8
- String *stringValue() const {
- return (String *)(val & ~(quint64(Type_Mask) << Tag_Shift));
- }
- Object *objectValue() const {
- return (Object *)(val & ~(quint64(Type_Mask) << Tag_Shift));
- }
- Managed *managed() const {
- return (Managed *)(val & ~(quint64(Type_Mask) << Tag_Shift));
- }
-#else
String *stringValue() const {
return s;
}
@@ -183,7 +268,6 @@ struct Q_QML_EXPORT Value
Managed *managed() const {
return m;
}
-#endif
quint64 rawValue() const {
return val;
@@ -198,6 +282,7 @@ struct Q_QML_EXPORT Value
static Value fromUInt32(uint i);
static Value fromString(String *s);
static Value fromObject(Object *o);
+ static Value fromManaged(Managed *o);
#ifndef QMLJS_LLVM_RUNTIME
static Value fromString(ExecutionContext *ctx, const QString &fromString);
@@ -215,37 +300,15 @@ struct Q_QML_EXPORT Value
bool toBoolean() const;
double toInteger() const;
double toNumber() const;
+ double toNumberImpl() const;
+ QString toQStringNoThrow() const;
QString toQString() const;
String *toString(ExecutionContext *ctx) const;
Object *toObject(ExecutionContext *ctx) const;
- inline bool isPrimitive() const { return !isObject(); }
-#if QT_POINTER_SIZE == 8
- inline bool integerCompatible() const {
- const quint64 mask = quint64(ConvertibleToInt) << 32;
- return (val & mask) == mask;
- }
- static inline bool integerCompatible(Value a, Value b) {
- const quint64 mask = quint64(ConvertibleToInt) << 32;
- return ((a.val & b.val) & mask) == mask;
- }
- static inline bool bothDouble(Value a, Value b) {
- const quint64 mask = quint64(NotDouble_Mask) << 32;
- return ((a.val | b.val) & mask) != mask;
- }
-#else
- inline bool integerCompatible() const {
- return (tag & ConvertibleToInt) == ConvertibleToInt;
- }
- static inline bool integerCompatible(Value a, Value b) {
- return ((a.tag & b.tag) & ConvertibleToInt) == ConvertibleToInt;
- }
- static inline bool bothDouble(Value a, Value b) {
- return ((a.tag | b.tag) & NotDouble_Mask) != NotDouble_Mask;
- }
-#endif
+ inline bool isPrimitive() const;
inline bool tryIntegerConversion() {
- bool b = isConvertibleToInt();
+ bool b = integerCompatible();
if (b)
tag = _Integer_Type;
return b;
@@ -267,10 +330,11 @@ struct Q_QML_EXPORT Value
uint asArrayIndex() const;
uint asArrayLength(bool *ok) const;
- Value property(ExecutionContext *ctx, String *name) const;
-
inline ExecutionEngine *engine() const;
+ ReturnedValue asReturnedValue() const { return val; }
+ static Value fromReturnedValue(ReturnedValue val) { Value v; v.val = val; return v; }
+
// Section 9.12
bool sameValue(Value other) const;
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 8d6f26ea57..de00a2264c 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -59,7 +59,23 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-QV4::Object *__qmljs_convert_to_object(QV4::ExecutionContext *ctx, const QV4::Value &value);
+inline bool Value::isString() const
+{
+ if (!isManaged())
+ return false;
+ return managed() && managed()->type == Managed::Type_String;
+}
+inline bool Value::isObject() const
+{
+ if (!isManaged())
+ return false;
+ return managed() && managed()->type != Managed::Type_String;
+}
+
+inline bool Value::isPrimitive() const
+{
+ return !isObject();
+}
inline Managed *Value::asManaged() const
{
@@ -83,9 +99,9 @@ inline Value Value::undefinedValue()
{
Value v;
#if QT_POINTER_SIZE == 8
- v.val = quint64(_Undefined_Type) << Tag_Shift;
+ v.val = quint64(Undefined_Type) << Tag_Shift;
#else
- v.tag = _Undefined_Type;
+ v.tag = Undefined_Type;
v.int_32 = 0;
#endif
return v;
@@ -106,7 +122,7 @@ inline Value Value::nullValue()
inline Value Value::emptyValue()
{
Value v;
- v.tag = Value::_Empty_Type;
+ v.tag = Value::Empty_Type;
v.uint_32 = 0;
return v;
}
@@ -123,7 +139,7 @@ inline Value Value::fromBoolean(Bool b)
inline Value Value::fromDouble(double d)
{
Value v;
- v.dbl = d;
+ v.setDouble(d);
return v;
}
@@ -142,7 +158,7 @@ inline Value Value::fromUInt32(uint i)
v.tag = _Integer_Type;
v.int_32 = (int)i;
} else {
- v.dbl = i;
+ v.setDouble(i);
}
return v;
}
@@ -151,10 +167,9 @@ inline Value Value::fromString(String *s)
{
Value v;
#if QT_POINTER_SIZE == 8
- v.val = (quint64)s;
- v.val |= quint64(_String_Type) << Tag_Shift;
+ v.s = s;
#else
- v.tag = _String_Type;
+ v.tag = Managed_Type;
v.s = s;
#endif
return v;
@@ -164,15 +179,62 @@ inline Value Value::fromObject(Object *o)
{
Value v;
#if QT_POINTER_SIZE == 8
- v.val = (quint64)o;
- v.val |= quint64(_Object_Type) << Tag_Shift;
+ v.o = o;
#else
- v.tag = _Object_Type;
+ v.tag = Managed_Type;
v.o = o;
#endif
return v;
}
+inline Value Value::fromManaged(Managed *m)
+{
+ if (!m)
+ return QV4::Value::undefinedValue();
+ Value v;
+#if QT_POINTER_SIZE == 8
+ v.m = m;
+#else
+ v.tag = Managed_Type;
+ v.m = m;
+#endif
+ return v;
+}
+
+inline double Value::toNumber() const
+{
+ if (integerCompatible())
+ return int_32;
+ if (isDouble())
+ return doubleValue();
+ return toNumberImpl();
+}
+
+inline int Value::toInt32() const
+{
+ if (integerCompatible())
+ return int_32;
+ double d;
+ if (isDouble())
+ d = doubleValue();
+ else
+ d = toNumberImpl();
+
+ const double D32 = 4294967296.0;
+ const double D31 = D32 / 2.0;
+
+ if ((d >= -D31 && d < D31))
+ return static_cast<int>(d);
+
+ return Value::toInt32(d);
+}
+
+inline unsigned int Value::toUInt32() const
+{
+ return (unsigned int)toInt32();
+}
+
+
inline bool Value::toBoolean() const
{
switch (type()) {
@@ -182,9 +244,9 @@ inline bool Value::toBoolean() const
case Value::Boolean_Type:
case Value::Integer_Type:
return (bool)int_32;
- case Value::String_Type:
- return stringValue()->toQString().length() > 0;
- case Value::Object_Type:
+ case Value::Managed_Type:
+ if (isString())
+ return stringValue()->toQString().length() > 0;
return true;
default: // double
return doubleValue() && !std::isnan(doubleValue());
@@ -197,8 +259,9 @@ inline uint Value::asArrayIndex() const
return (uint)int_32;
if (!isDouble())
return UINT_MAX;
- uint idx = (uint)dbl;
- if (idx != dbl)
+ double d = doubleValue();
+ uint idx = (uint)d;
+ if (idx != d)
return UINT_MAX;
return idx;
}
@@ -206,11 +269,12 @@ inline uint Value::asArrayIndex() const
inline uint Value::asArrayLength(bool *ok) const
{
*ok = true;
- if (isConvertibleToInt() && int_32 >= 0)
+ if (integerCompatible() && int_32 >= 0)
return (uint)int_32;
if (isDouble()) {
- uint idx = (uint)dbl;
- if ((double)idx != dbl) {
+ double d = doubleValue();
+ uint idx = (uint)d;
+ if (idx != d) {
*ok = false;
return UINT_MAX;
}
@@ -275,13 +339,8 @@ inline ErrorObject *Value::asErrorObject() const
return isObject() ? managed()->asErrorObject() : 0;
}
-// ###
-inline Value Managed::construct(CallData *d) {
- return vtbl->construct(this, d);
-}
-inline Value Managed::call(CallData *d) {
- return vtbl->call(this, d);
-}
+template<typename T>
+inline T *Value::as() const { Managed *m = isObject() ? managed() : 0; return m ? m->as<T>() : 0; }
struct Q_QML_PRIVATE_EXPORT PersistentValuePrivate
{
@@ -311,10 +370,13 @@ class Q_QML_EXPORT PersistentValue
{
public:
PersistentValue() : d(0) {}
+
PersistentValue(const Value &val);
+ PersistentValue(ReturnedValue val);
PersistentValue(const PersistentValue &other);
PersistentValue &operator=(const PersistentValue &other);
PersistentValue &operator=(const Value &other);
+ PersistentValue &operator =(const ReturnedValue &other);
~PersistentValue();
Value value() const {
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index 574f612f74..ed3342aa58 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -152,15 +152,15 @@ void VariantPrototype::init(ExecutionEngine *engine)
defineDefaultProperty(engine, QStringLiteral("toString"), method_toString, 0);
}
-QV4::Value VariantPrototype::method_preserve(SimpleCallContext *ctx)
+QV4::ReturnedValue VariantPrototype::method_preserve(SimpleCallContext *ctx)
{
VariantObject *o = ctx->thisObject.as<QV4::VariantObject>();
if (o && o->isScarce())
o->node.remove();
- return Value::undefinedValue();
+ return Encode::undefined();
}
-QV4::Value VariantPrototype::method_destroy(SimpleCallContext *ctx)
+QV4::ReturnedValue VariantPrototype::method_destroy(SimpleCallContext *ctx)
{
VariantObject *o = ctx->thisObject.as<QV4::VariantObject>();
if (o) {
@@ -168,42 +168,42 @@ QV4::Value VariantPrototype::method_destroy(SimpleCallContext *ctx)
o->node.remove();
o->data = QVariant();
}
- return QV4::Value::undefinedValue();
+ return Encode::undefined();
}
-QV4::Value VariantPrototype::method_toString(SimpleCallContext *ctx)
+QV4::ReturnedValue VariantPrototype::method_toString(SimpleCallContext *ctx)
{
VariantObject *o = ctx->thisObject.as<QV4::VariantObject>();
if (!o)
- return Value::undefinedValue();
+ return Encode::undefined();
QString result = o->data.toString();
if (result.isEmpty() && !o->data.canConvert(QVariant::String))
result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(o->data.typeName()));
- return Value::fromString(ctx->engine->newString(result));
+ return Value::fromString(ctx->engine->newString(result)).asReturnedValue();
}
-QV4::Value VariantPrototype::method_valueOf(SimpleCallContext *ctx)
+QV4::ReturnedValue VariantPrototype::method_valueOf(SimpleCallContext *ctx)
{
VariantObject *o = ctx->thisObject.as<QV4::VariantObject>();
if (o) {
QVariant v = o->data;
switch (v.type()) {
case QVariant::Invalid:
- return Value::undefinedValue();
+ return Encode::undefined();
case QVariant::String:
- return Value::fromString(ctx->engine->newString(v.toString()));
+ return Value::fromString(ctx->engine->newString(v.toString())).asReturnedValue();
case QVariant::Int:
- return Value::fromInt32(v.toInt());
+ return Encode(v.toInt());
case QVariant::Double:
case QVariant::UInt:
- return Value::fromDouble(v.toDouble());
+ return Encode(v.toDouble());
case QVariant::Bool:
- return Value::fromBoolean(v.toBool());
+ return Encode(v.toBool());
default:
break;
}
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index eadf0ac4cf..60a48374b0 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -89,10 +89,10 @@ public:
void init(ExecutionEngine *engine);
- static Value method_preserve(SimpleCallContext *ctx);
- static Value method_destroy(SimpleCallContext *ctx);
- static Value method_toString(SimpleCallContext *ctx);
- static Value method_valueOf(SimpleCallContext *ctx);
+ static ReturnedValue method_preserve(SimpleCallContext *ctx);
+ static ReturnedValue method_destroy(SimpleCallContext *ctx);
+ static ReturnedValue method_toString(SimpleCallContext *ctx);
+ static ReturnedValue method_valueOf(SimpleCallContext *ctx);
};
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 92b0c75e8c..c342470015 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -217,9 +217,10 @@ static inline QV4::Value *getValueRef(QV4::ExecutionContext *context,
# define VALUE(param) *getValueRef(context, stack, param, stackSize)
# define VALUEPTR(param) getValueRef(context, stack, param, stackSize)
#endif
+#define STOREVALUE(param, value) VALUE(param) = QV4::Value::fromReturnedValue((value))
-QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
- QV4::Value *stack, unsigned stackSize
+QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *&code,
+ QV4::Value *stack, unsigned stackSize
#ifdef MOTH_THREADED_INTERPRETER
, void ***storeJumpTable
#endif
@@ -237,7 +238,7 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
};
#undef MOTH_INSTR_ADDR
*storeJumpTable = jumpTable;
- return QV4::Value::undefinedValue();
+ return QV4::Value::undefinedValue().asReturnedValue();
}
#endif
@@ -257,6 +258,10 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
VALUE(instr.result) = VALUE(instr.source);
MOTH_END_INSTR(MoveTemp)
+ MOTH_BEGIN_INSTR(SwapTemps)
+ qSwap(VALUE(instr.left), VALUE(instr.right));
+ MOTH_END_INSTR(MoveTemp)
+
MOTH_BEGIN_INSTR(LoadValue)
// TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData());
VALUE(instr.result) = VALUE(instr.value);
@@ -273,21 +278,21 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
MOTH_END_INSTR(LoadRegExp)
MOTH_BEGIN_INSTR(LoadClosure)
- __qmljs_init_closure(context, VALUEPTR(instr.result), instr.value);
+ STOREVALUE(instr.result, __qmljs_init_closure(context, instr.value));
MOTH_END_INSTR(LoadClosure)
MOTH_BEGIN_INSTR(LoadName)
- TRACE(inline, "property name = %s", instr.name->toQString().toUtf8().constData());
- __qmljs_get_activation_property(context, VALUEPTR(instr.result), runtimeStrings[instr.name]);
+ TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
+ STOREVALUE(instr.result, __qmljs_get_activation_property(context, runtimeStrings[instr.name]));
MOTH_END_INSTR(LoadName)
MOTH_BEGIN_INSTR(StoreName)
- TRACE(inline, "property name = %s", instr.name->toQString().toUtf8().constData());
+ TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
__qmljs_set_activation_property(context, runtimeStrings[instr.name], VALUEPTR(instr.source));
MOTH_END_INSTR(StoreName)
MOTH_BEGIN_INSTR(LoadElement)
- __qmljs_get_element(context, VALUEPTR(instr.result), VALUEPTR(instr.base), VALUEPTR(instr.index));
+ STOREVALUE(instr.result, __qmljs_get_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index)));
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(StoreElement)
@@ -295,7 +300,7 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
MOTH_END_INSTR(StoreElement)
MOTH_BEGIN_INSTR(LoadProperty)
- __qmljs_get_property(context, VALUEPTR(instr.result), VALUEPTR(instr.base), runtimeStrings[instr.name]);
+ STOREVALUE(instr.result, __qmljs_get_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name]));
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(StoreProperty)
@@ -310,7 +315,7 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
MOTH_END_INSTR(Push)
MOTH_BEGIN_INSTR(CallValue)
-#ifdef DO_TRACE_INSTR
+#if 0 //def DO_TRACE_INSTR
if (Debugging::Debugger *debugger = context->engine->debugger) {
if (QV4::FunctionObject *o = (VALUE(instr.dest)).asFunctionObject()) {
if (Debugging::FunctionDebugInfo *info = debugger->debugInfo(o)) {
@@ -322,39 +327,39 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
#endif // DO_TRACE_INSTR
Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = 0;
+ callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- __qmljs_call_value(context, VALUEPTR(instr.result), VALUEPTR(instr.dest), callData);
+ STOREVALUE(instr.result, __qmljs_call_value(context, VALUEPTR(instr.dest), callData));
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallProperty)
- TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(instr.name->toQString()), instr.args, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
+ TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = 0;
+ callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- __qmljs_call_property(context, QV4::ValueRef::fromRawValue(VALUEPTR(instr.result)), runtimeStrings[instr.name], callData);
+ STOREVALUE(instr.result, __qmljs_call_property(context, runtimeStrings[instr.name], callData));
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallElement)
Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = 0;
+ callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- __qmljs_call_element(context, VALUEPTR(instr.result), VALUEPTR(instr.index), callData);
+ STOREVALUE(instr.result, __qmljs_call_element(context, VALUEPTR(instr.index), callData));
MOTH_END_INSTR(CallElement)
MOTH_BEGIN_INSTR(CallActivationProperty)
TRACE(args, "starting at %d, length %d", instr.args, instr.argc);
Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = 0;
+ callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- __qmljs_call_activation_property(context, VALUEPTR(instr.result), runtimeStrings[instr.name], callData);
+ STOREVALUE(instr.result, __qmljs_call_activation_property(context, runtimeStrings[instr.name], callData));
MOTH_END_INSTR(CallActivationProperty)
MOTH_BEGIN_INSTR(CallBuiltinThrow)
@@ -370,7 +375,7 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
context->interpreterInstructionPointer = &code;
} catch (QV4::Exception &ex) {
ex.accept(context);
- VALUE(instr.exceptionVar) = ex.value();
+ STOREVALUE(instr.exceptionVar, ex.value());
try {
QV4::ExecutionContext *catchContext = __qmljs_builtin_push_catch_scope(runtimeStrings[instr.exceptionVarName], VALUEPTR(instr.exceptionVar), context);
const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset;
@@ -380,7 +385,7 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
context = __qmljs_builtin_pop_scope(catchContext);
} catch (QV4::Exception &ex) {
ex.accept(context);
- VALUE(instr.exceptionVar) = ex.value();
+ STOREVALUE(instr.exceptionVar, ex.value());
const uchar *catchCode = ((uchar *)&instr.catchOffset) + instr.catchOffset;
run(context, catchCode, stack, stackSize);
code = catchCode;
@@ -390,7 +395,7 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
MOTH_END_INSTR(EnterTry)
MOTH_BEGIN_INSTR(CallBuiltinFinishTry)
- return QV4::Value();
+ return QV4::ReturnedValue(0);
MOTH_END_INSTR(CallBuiltinFinishTry)
MOTH_BEGIN_INSTR(CallBuiltinPushScope)
@@ -402,71 +407,39 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
MOTH_END_INSTR(CallBuiltinPopScope)
MOTH_BEGIN_INSTR(CallBuiltinForeachIteratorObject)
- __qmljs_foreach_iterator_object(context, VALUEPTR(instr.result), VALUEPTR(instr.arg));
+ STOREVALUE(instr.result, __qmljs_foreach_iterator_object(context, VALUEPTR(instr.arg)));
MOTH_END_INSTR(CallBuiltinForeachIteratorObject)
MOTH_BEGIN_INSTR(CallBuiltinForeachNextPropertyName)
- __qmljs_foreach_next_property_name(VALUEPTR(instr.result), VALUEPTR(instr.arg));
+ STOREVALUE(instr.result, __qmljs_foreach_next_property_name(VALUEPTR(instr.arg)));
MOTH_END_INSTR(CallBuiltinForeachNextPropertyName)
MOTH_BEGIN_INSTR(CallBuiltinDeleteMember)
- __qmljs_delete_member(context, VALUEPTR(instr.result), VALUEPTR(instr.base), runtimeStrings[instr.member]);
+ STOREVALUE(instr.result, __qmljs_delete_member(context, VALUEPTR(instr.base), runtimeStrings[instr.member]));
MOTH_END_INSTR(CallBuiltinDeleteMember)
MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript)
- __qmljs_delete_subscript(context, VALUEPTR(instr.result), VALUEPTR(instr.base), VALUEPTR(instr.index));
+ STOREVALUE(instr.result, __qmljs_delete_subscript(context, VALUEPTR(instr.base), VALUEPTR(instr.index)));
MOTH_END_INSTR(CallBuiltinDeleteSubscript)
MOTH_BEGIN_INSTR(CallBuiltinDeleteName)
- __qmljs_delete_name(context, VALUEPTR(instr.result), runtimeStrings[instr.name]);
+ STOREVALUE(instr.result, __qmljs_delete_name(context, runtimeStrings[instr.name]));
MOTH_END_INSTR(CallBuiltinDeleteName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofMember)
- __qmljs_builtin_typeof_member(context, VALUEPTR(instr.result), VALUEPTR(instr.base), runtimeStrings[instr.member]);
+ STOREVALUE(instr.result, __qmljs_builtin_typeof_member(context, VALUEPTR(instr.base), runtimeStrings[instr.member]));
MOTH_END_INSTR(CallBuiltinTypeofMember)
MOTH_BEGIN_INSTR(CallBuiltinTypeofSubscript)
- __qmljs_builtin_typeof_element(context, VALUEPTR(instr.result), VALUEPTR(instr.base), VALUEPTR(instr.index));
+ STOREVALUE(instr.result, __qmljs_builtin_typeof_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index)));
MOTH_END_INSTR(CallBuiltinTypeofSubscript)
MOTH_BEGIN_INSTR(CallBuiltinTypeofName)
- __qmljs_builtin_typeof_name(context, VALUEPTR(instr.result), runtimeStrings[instr.name]);
+ STOREVALUE(instr.result, __qmljs_builtin_typeof_name(context, runtimeStrings[instr.name]));
MOTH_END_INSTR(CallBuiltinTypeofName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofValue)
- __qmljs_builtin_typeof(context, VALUEPTR(instr.result), VALUEPTR(instr.value));
- MOTH_END_INSTR(CallBuiltinTypeofValue)
-
- MOTH_BEGIN_INSTR(CallBuiltinPostIncMember)
- __qmljs_builtin_post_increment_member(context, VALUEPTR(instr.result), VALUEPTR(instr.base), runtimeStrings[instr.member]);
- MOTH_END_INSTR(CallBuiltinTypeofMember)
-
- MOTH_BEGIN_INSTR(CallBuiltinPostIncSubscript)
- __qmljs_builtin_post_increment_element(context, VALUEPTR(instr.result), VALUEPTR(instr.base), VALUEPTR(instr.index));
- MOTH_END_INSTR(CallBuiltinTypeofSubscript)
-
- MOTH_BEGIN_INSTR(CallBuiltinPostIncName)
- __qmljs_builtin_post_increment_name(context, VALUEPTR(instr.result), runtimeStrings[instr.name]);
- MOTH_END_INSTR(CallBuiltinTypeofName)
-
- MOTH_BEGIN_INSTR(CallBuiltinPostIncValue)
- __qmljs_builtin_post_increment(VALUEPTR(instr.result), VALUEPTR(instr.value));
- MOTH_END_INSTR(CallBuiltinTypeofValue)
-
- MOTH_BEGIN_INSTR(CallBuiltinPostDecMember)
- __qmljs_builtin_post_decrement_member(context, VALUEPTR(instr.result), VALUEPTR(instr.base), runtimeStrings[instr.member]);
- MOTH_END_INSTR(CallBuiltinTypeofMember)
-
- MOTH_BEGIN_INSTR(CallBuiltinPostDecSubscript)
- __qmljs_builtin_post_decrement_element(context, VALUEPTR(instr.result), VALUEPTR(instr.base), VALUEPTR(instr.index));
- MOTH_END_INSTR(CallBuiltinTypeofSubscript)
-
- MOTH_BEGIN_INSTR(CallBuiltinPostDecName)
- __qmljs_builtin_post_decrement_name(context, VALUEPTR(instr.result), runtimeStrings[instr.name]);
- MOTH_END_INSTR(CallBuiltinTypeofName)
-
- MOTH_BEGIN_INSTR(CallBuiltinPostDecValue)
- __qmljs_builtin_post_decrement(VALUEPTR(instr.result), VALUEPTR(instr.value));
+ STOREVALUE(instr.result, __qmljs_builtin_typeof(context, VALUEPTR(instr.value)));
MOTH_END_INSTR(CallBuiltinTypeofValue)
MOTH_BEGIN_INSTR(CallBuiltinDeclareVar)
@@ -484,44 +457,44 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
MOTH_BEGIN_INSTR(CallBuiltinDefineArray)
Q_ASSERT(instr.args + instr.argc <= stackSize);
QV4::Value *args = stack + instr.args;
- __qmljs_builtin_define_array(context, VALUEPTR(instr.result), args, instr.argc);
+ STOREVALUE(instr.result, __qmljs_builtin_define_array(context, args, instr.argc));
MOTH_END_INSTR(CallBuiltinDefineArray)
MOTH_BEGIN_INSTR(CallBuiltinDefineObjectLiteral)
QV4::Value *args = stack + instr.args;
- __qmljs_builtin_define_object_literal(context, VALUEPTR(instr.result), args, instr.internalClassId);
+ STOREVALUE(instr.result, __qmljs_builtin_define_object_literal(context, args, instr.internalClassId));
MOTH_END_INSTR(CallBuiltinDefineObjectLiteral)
MOTH_BEGIN_INSTR(CallBuiltinSetupArgumentsObject)
- __qmljs_builtin_setup_arguments_object(context, VALUEPTR(instr.result));
+ STOREVALUE(instr.result, __qmljs_builtin_setup_arguments_object(context));
MOTH_END_INSTR(CallBuiltinSetupArgumentsObject)
MOTH_BEGIN_INSTR(CreateValue)
Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = 0;
+ callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- __qmljs_construct_value(context, VALUEPTR(instr.result), VALUEPTR(instr.func), callData);
+ STOREVALUE(instr.result, __qmljs_construct_value(context, VALUEPTR(instr.func), callData));
MOTH_END_INSTR(CreateValue)
MOTH_BEGIN_INSTR(CreateProperty)
Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = 0;
+ callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- __qmljs_construct_property(context, VALUEPTR(instr.result), VALUEPTR(instr.base), runtimeStrings[instr.name], callData);
+ STOREVALUE(instr.result, __qmljs_construct_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name], callData));
MOTH_END_INSTR(CreateProperty)
MOTH_BEGIN_INSTR(CreateActivationProperty)
- TRACE(inline, "property name = %s, args = %d, argc = %d", instr.name->toQString().toUtf8().constData(), instr.args, instr.argc);
+ TRACE(inline, "property name = %s, args = %d, argc = %d", runtimeStrings[instr.name]->toQString().toUtf8().constData(), instr.args, instr.argc);
Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = 0;
+ callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- __qmljs_construct_activation_property(context, VALUEPTR(instr.result), runtimeStrings[instr.name], callData);
+ STOREVALUE(instr.result, __qmljs_construct_activation_property(context, runtimeStrings[instr.name], callData));
MOTH_END_INSTR(CreateActivationProperty)
MOTH_BEGIN_INSTR(Jump)
@@ -536,15 +509,15 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
MOTH_END_INSTR(CJump)
MOTH_BEGIN_INSTR(Unop)
- instr.alu(QV4::ValueRef::fromRawValue(VALUEPTR(instr.result)), QV4::ValueRef::fromRawValue(VALUEPTR(instr.source)));
+ STOREVALUE(instr.result, instr.alu(VALUEPTR(instr.source)));
MOTH_END_INSTR(Unop)
MOTH_BEGIN_INSTR(Binop)
- instr.alu(VALUEPTR(instr.result), VALUEPTR(instr.lhs), VALUEPTR(instr.rhs));
+ STOREVALUE(instr.result, instr.alu(VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(Binop)
MOTH_BEGIN_INSTR(BinopContext)
- instr.alu(context, VALUEPTR(instr.result), VALUEPTR(instr.lhs), VALUEPTR(instr.rhs));
+ STOREVALUE(instr.result, instr.alu(context, VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(BinopContext)
MOTH_BEGIN_INSTR(AddNumberParams)
@@ -578,7 +551,7 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
context->engine->stackPop(stackSize);
QV4::Value &result = VALUE(instr.result);
// TRACE(Ret, "returning value %s", result.toString(context)->toQString().toUtf8().constData());
- return result;
+ return result.asReturnedValue();
MOTH_END_INSTR(Ret)
MOTH_BEGIN_INSTR(LoadThis)
@@ -600,7 +573,7 @@ QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
MOTH_END_INSTR(InplaceMemberOp)
MOTH_BEGIN_INSTR(InplaceNameOp)
- TRACE(name, "%s", instr.name->toQString().toUtf8().constData());
+ TRACE(name, "%s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
instr.alu(context, runtimeStrings[instr.name], VALUEPTR(instr.source));
MOTH_END_INSTR(InplaceNameOp)
@@ -628,7 +601,7 @@ void **VME::instructionJumpTable()
}
#endif
-QV4::Value VME::exec(QV4::ExecutionContext *ctxt, const uchar *code)
+QV4::ReturnedValue VME::exec(QV4::ExecutionContext *ctxt, const uchar *code)
{
VME vme;
return vme.run(ctxt, code);
diff --git a/src/qml/jsruntime/qv4vme_moth_p.h b/src/qml/jsruntime/qv4vme_moth_p.h
index aedf865033..04c7f933ab 100644
--- a/src/qml/jsruntime/qv4vme_moth_p.h
+++ b/src/qml/jsruntime/qv4vme_moth_p.h
@@ -53,14 +53,14 @@ namespace Moth {
class VME
{
public:
- static QV4::Value exec(QV4::ExecutionContext *, const uchar *);
+ static QV4::ReturnedValue exec(QV4::ExecutionContext *, const uchar *);
#ifdef MOTH_THREADED_INTERPRETER
static void **instructionJumpTable();
#endif
private:
- QV4::Value run(QV4::ExecutionContext *, const uchar *&code,
+ QV4::ReturnedValue run(QV4::ExecutionContext *, const uchar *&code,
QV4::Value *stack = 0, unsigned stackSize = 0
#ifdef MOTH_THREADED_INTERPRETER
, void ***storeJumpTable = 0
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index 9b7215f0ae..e39e695c99 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -233,7 +233,7 @@ public:
inline quint16 *utf16Data() const { return (quint16 *)strData->data(); }
inline bool equals(const QV4::Value &string) const {
- QString s = string.toQString();
+ QString s = string.toQStringNoThrow();
if (isQString()) {
QStringDataPtr dd;
dd.ptr = strData;
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index 77b0334c7e..3bba6f8e83 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -55,6 +55,7 @@ SOURCES += \
$$PWD/qqmlcontextwrapper.cpp \
$$PWD/qqmlvaluetypewrapper.cpp \
$$PWD/qqmltypewrapper.cpp \
+ $$PWD/qqmlfileselector.cpp \
$$PWD/qqmlobjectcreator.cpp
HEADERS += \
@@ -125,13 +126,15 @@ HEADERS += \
$$PWD/qqmlplatform_p.h \
$$PWD/qqmlbinding_p.h \
$$PWD/qqmlextensionplugin_p.h \
- $$PWD/qqmlabstracturlinterceptor_p.h \
+ $$PWD/qqmlabstracturlinterceptor.h \
$$PWD/qqmlapplicationengine_p.h \
$$PWD/qqmlapplicationengine.h \
$$PWD/qqmllistwrapper_p.h \
$$PWD/qqmlcontextwrapper_p.h \
$$PWD/qqmlvaluetypewrapper_p.h \
$$PWD/qqmltypewrapper_p.h \
+ $$PWD/qqmlfileselector_p.h \
+ $$PWD/qqmlfileselector.h \
$$PWD/qqmlobjectcreator_p.h
include(ftw/ftw.pri)
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index ee69985edb..6082fcda08 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -441,6 +441,9 @@ using namespace QtQml;
#pragma clang diagnostic pop
#endif
+//The C++ version of protected namespaces in qmldir
+Q_QML_EXPORT bool qmlProtectModule(const char* uri, int majVersion);
+
template<typename T>
QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
{
diff --git a/src/qml/qml/qqmlabstracturlinterceptor.cpp b/src/qml/qml/qqmlabstracturlinterceptor.cpp
index a68d5f7489..127dad86ce 100644
--- a/src/qml/qml/qqmlabstracturlinterceptor.cpp
+++ b/src/qml/qml/qqmlabstracturlinterceptor.cpp
@@ -44,8 +44,6 @@
\inmodule QtQml
\brief allows you to control QML file loading.
- \note This class is in an extended validation period and still subject to change. It should be treated as private API for 5.1
-
QQmlAbstractUrlInterceptor is an interface which can be used to alter URLs
before they are used by the QML engine. This is primarily useful for altering
file urls into other file urls, such as selecting different graphical assets
@@ -88,4 +86,7 @@
A pure virtual function where you can intercept the url. The returned value is taken as the
new value for the url. The type of url being intercepted is given by the type variable.
+
+ Your implementation of this function must be thread-safe, as it can be called from multiple threads
+ at the same time.
*/
diff --git a/src/qml/qml/qqmlabstracturlinterceptor_p.h b/src/qml/qml/qqmlabstracturlinterceptor.h
index 186d59e301..4740b67adf 100644
--- a/src/qml/qml/qqmlabstracturlinterceptor_p.h
+++ b/src/qml/qml/qqmlabstracturlinterceptor.h
@@ -38,11 +38,12 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-//Private API for 5.1 (at least)
+
#ifndef QQMLABSTRACTURLINTERCEPTOR_H
#define QQMLABSTRACTURLINTERCEPTOR_H
#include <QtCore/qurl.h>
+#include <qtqmlglobal.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 85aeaf5786..3f13f8a140 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -44,6 +44,7 @@
#include <QQmlComponent>
#include "qqmlapplicationengine.h"
#include "qqmlapplicationengine_p.h"
+#include "qqmlfileselector.h"
QT_BEGIN_NAMESPACE
@@ -76,6 +77,7 @@ void QQmlApplicationEnginePrivate::init()
QCoreApplication::installTranslator(qtTranslator);
translators << qtTranslator;
#endif
+ q->setUrlInterceptor(new QQmlFileSelector(q));
QCoreApplication::instance()->setProperty("__qml_using_qqmlapplicationengine", QVariant(true));
}
@@ -172,13 +174,12 @@ void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o)
\li Connecting Qt.quit() to QCoreApplication::quit()
\li Automatically loads translation files from an i18n directory adjacent to the main QML file.
\li Automatically sets an incubuation controller if the scene contains a QQuickWindow.
+ \li Automatically sets a \c QQmlFileSelector as the url interceptor, applying file selectors to all
+ QML files and assets.
\endlist
The engine behavior can be further tweaked by using the inherited methods from QQmlEngine.
- \note In the future QQmlApplicationEngine may automatically apply file selectors.
- To ensure forwards compatibility, do not use folder names containing a '+' character in your QML file
- structure.
*/
/*!
diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h
index cc38c62c02..75d7cf768f 100644
--- a/src/qml/qml/qqmlapplicationengine_p.h
+++ b/src/qml/qml/qqmlapplicationengine_p.h
@@ -63,6 +63,7 @@
QT_BEGIN_NAMESPACE
class QTranslator;
+class QFileSelector;
class Q_QML_PRIVATE_EXPORT QQmlApplicationEnginePrivate : public QQmlEnginePrivate
{
Q_DECLARE_PUBLIC(QQmlApplicationEngine)
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index eff17ddd9a..a5e281dc56 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -244,12 +244,13 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
} else {
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
+ QV4::Scope scope(ep->v4engine());
+
ep->referenceScarceResources();
bool isUndefined = false;
- QV4::Value result =
- QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined);
+ QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined));
trace.event("writing binding result");
@@ -285,12 +286,12 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
QVariant QQmlBinding::evaluate()
{
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
+ QV4::Scope scope(ep->v4engine());
ep->referenceScarceResources();
bool isUndefined = false;
- QV4::Value result =
- QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined);
+ QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined));
ep->dereferenceScarceResources();
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 08344c4c60..3242ab9831 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -51,7 +51,7 @@
#include "qqmlcontext.h"
#include "qqmlglobal_p.h"
#include <private/qqmlprofilerservice_p.h>
-#include <private/qv8debugservice_p.h>
+#include <private/qv4debugservice_p.h>
#include "qqmlinfo.h"
#include <private/qv4value_p.h>
@@ -115,7 +115,7 @@ QString QQmlBoundSignalExpression::expression() const
{
if (m_expressionFunctionValid) {
Q_ASSERT (context() && engine());
- return m_v8function.value().toQString();
+ return m_v8function.value().toQStringNoThrow();
} else {
return m_expression;
}
@@ -194,7 +194,7 @@ 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 == QMetaType::QVariant) {
- args[ii] = engine->fromVariant(*((QVariant *)a[ii + 1]));
+ args[ii] = QV4::Value::fromReturnedValue(engine->fromVariant(*((QVariant *)a[ii + 1])));
} else if (type == QMetaType::Int) {
//### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise
args[ii] = QV4::Value::fromInt32(*reinterpret_cast<const int*>(a[ii + 1]));
@@ -204,9 +204,9 @@ void QQmlBoundSignalExpression::evaluate(void **a)
if (!*reinterpret_cast<void* const *>(a[ii + 1]))
args[ii] = QV4::Value::nullValue();
else
- args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1]));
+ args[ii] = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1])));
} else {
- args[ii] = engine->fromVariant(QVariant(type, a[ii + 1]));
+ args[ii] = QV4::Value::fromReturnedValue(engine->fromVariant(QVariant(type, a[ii + 1])));
}
}
@@ -330,7 +330,7 @@ void QQmlBoundSignal_callback(QQmlNotifierEndpoint *e, void **a)
return;
if (QQmlDebugService::isDebuggingEnabled())
- QV8DebugService::instance()->signalEmitted(QString::fromLatin1(QMetaObjectPrivate::signal(s->m_expression->target()->metaObject(), s->m_index).methodSignature()));
+ QV4DebugService::instance()->signalEmitted(QString::fromLatin1(QMetaObjectPrivate::signal(s->m_expression->target()->metaObject(), s->m_index).methodSignature()));
QQmlHandlingSignalProfiler prof(s->m_expression);
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 6bc9128730..8a0e015827 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -61,7 +61,7 @@
#include "qqmlscriptstring.h"
#include "qqmlglobal_p.h"
#include "qqmlbinding_p.h"
-#include "qqmlabstracturlinterceptor_p.h"
+#include "qqmlabstracturlinterceptor.h"
#include <QDebug>
#include <QPointF>
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 1becbe8f68..955c940a9d 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1114,11 +1114,11 @@ class QmlIncubatorObject : public QV4::Object, public QQmlIncubator
public:
QmlIncubatorObject(QV8Engine *engine, IncubationMode = Asynchronous);
- static QV4::Value method_get_statusChanged(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_statusChanged(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_status(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_object(QV4::SimpleCallContext *ctx);
- static QV4::Value method_forceCompletion(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_statusChanged(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_statusChanged(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_status(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_object(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_forceCompletion(QV4::SimpleCallContext *ctx);
static void destroy(Managed *that);
static void markObjects(Managed *that);
@@ -1228,6 +1228,7 @@ void QQmlComponent::createObject(QQmlV4Function *args)
QV8Engine *v8engine = args->engine();
QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine);
+ QV4::Scope scope(v4engine);
QQmlContext *ctxt = creationContext();
if (!ctxt) ctxt = d->engine->rootContext();
@@ -1241,17 +1242,17 @@ void QQmlComponent::createObject(QQmlV4Function *args)
QQmlComponent_setQmlParent(rv, parent);
- QV4::Value object = QV4::QObjectWrapper::wrap(v4engine, rv);
- Q_ASSERT(object.asObject());
+ QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, rv));
+ Q_ASSERT(object->isObject());
if (!valuemap.isEmpty()) {
QQmlComponentExtension *e = componentExtension(v8engine);
- QV4::Value f = QV4::Script::evaluate(v4engine, QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal().asObject());
- QV4::ScopedCallData callData(v4engine, 2);
+ QV4::Scoped<QV4::FunctionObject> f(scope, QV4::Script::evaluate(v4engine, QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal().asObject()));
+ QV4::ScopedCallData callData(scope, 2);
callData->thisObject = QV4::Value::fromObject(v4engine->globalObject);
callData->args[0] = object;
callData->args[1] = valuemap;
- f.asFunctionObject()->call(callData);
+ f->call(callData);
}
d->completeCreate();
@@ -1387,18 +1388,20 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
QV8Engine *v8engine = ep->v8engine();
QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine);
+ QV4::Scope scope(v4engine);
- QV4::Value object = QV4::QObjectWrapper::wrap(v4engine, toCreate);
- Q_ASSERT(object.asObject());
+ QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, toCreate));
+ Q_ASSERT(object->asObject());
if (!valuemap.isEmpty()) {
QQmlComponentExtension *e = componentExtension(v8engine);
- QV4::Value f = QV4::Script::evaluate(QV8Engine::getV4(v8engine), QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject());
- QV4::ScopedCallData callData(v4engine, 2);
+ QV4::Scoped<QV4::FunctionObject> f(scope, QV4::Script::evaluate(QV8Engine::getV4(v8engine),
+ QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()));
+ QV4::ScopedCallData callData(scope, 2);
callData->thisObject = QV4::Value::fromObject(v4engine->globalObject);
callData->args[0] = object;
callData->args[1] = valuemap;
- f.asFunctionObject()->call(callData);
+ f->call(callData);
}
}
@@ -1424,7 +1427,7 @@ QQmlComponentExtension::QQmlComponentExtension(QV8Engine *engine)
incubationProto = QV4::Value::fromObject(proto);
}
-QV4::Value QmlIncubatorObject::method_get_object(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QmlIncubatorObject::method_get_object(QV4::SimpleCallContext *ctx)
{
QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>();
if (!o)
@@ -1433,7 +1436,7 @@ QV4::Value QmlIncubatorObject::method_get_object(QV4::SimpleCallContext *ctx)
return QV4::QObjectWrapper::wrap(ctx->engine, o->object());
}
-QV4::Value QmlIncubatorObject::method_forceCompletion(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QmlIncubatorObject::method_forceCompletion(QV4::SimpleCallContext *ctx)
{
QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>();
if (!o)
@@ -1441,35 +1444,35 @@ QV4::Value QmlIncubatorObject::method_forceCompletion(QV4::SimpleCallContext *ct
o->forceCompletion();
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value QmlIncubatorObject::method_get_status(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QmlIncubatorObject::method_get_status(QV4::SimpleCallContext *ctx)
{
QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>();
if (!o)
ctx->throwTypeError();
- return QV4::Value::fromUInt32(o->status());
+ return QV4::Encode(o->status());
}
-QV4::Value QmlIncubatorObject::method_get_statusChanged(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QmlIncubatorObject::method_get_statusChanged(QV4::SimpleCallContext *ctx)
{
QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>();
if (!o)
ctx->throwTypeError();
- return o->m_statusChanged;
+ return o->m_statusChanged.asReturnedValue();
}
-QV4::Value QmlIncubatorObject::method_set_statusChanged(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QmlIncubatorObject::method_set_statusChanged(QV4::SimpleCallContext *ctx)
{
QmlIncubatorObject *o = ctx->thisObject.as<QmlIncubatorObject>();
if (!o || ctx->argumentCount < 1)
ctx->throwTypeError();
o->m_statusChanged = ctx->arguments[0];
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
QQmlComponentExtension::~QQmlComponentExtension()
@@ -1481,6 +1484,10 @@ QmlIncubatorObject::QmlIncubatorObject(QV8Engine *engine, IncubationMode m)
{
v8 = engine;
vtbl = &static_vtbl;
+
+ valuemap = QV4::Value::undefinedValue();
+ qmlGlobal = QV4::Value::undefinedValue();
+ m_statusChanged = QV4::Value::undefinedValue();
}
void QmlIncubatorObject::setInitialState(QObject *o)
@@ -1491,13 +1498,14 @@ void QmlIncubatorObject::setInitialState(QObject *o)
QQmlComponentExtension *e = componentExtension(v8);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8);
+ QV4::Scope scope(v4);
- QV4::Value f = QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject());
- QV4::ScopedCallData callData(v4, 2);
+ QV4::Scoped<QV4::FunctionObject> f(scope, QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()));
+ QV4::ScopedCallData callData(scope, 2);
callData->thisObject = QV4::Value::fromObject(v4->globalObject);
- callData->args[0] = QV4::QObjectWrapper::wrap(v4, o);
+ callData->args[0] = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, o));
callData->args[1] = valuemap;
- f.asFunctionObject()->call(callData);
+ f->call(callData);
}
}
@@ -1529,8 +1537,9 @@ void QmlIncubatorObject::statusChanged(Status s)
if (QV4::FunctionObject *f = callback.asFunctionObject()) {
QV4::ExecutionContext *ctx = f->engine()->current;
+ QV4::Scope scope(ctx);
try {
- QV4::ScopedCallData callData(ctx->engine, 1);
+ QV4::ScopedCallData callData(scope, 1);
callData->thisObject = QV4::Value::fromObject(this);
callData->args[0] = QV4::Value::fromUInt32(s);
f->call(callData);
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 7731935b75..78e6650d02 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -48,7 +48,7 @@
#include "qqmlengine_p.h"
#include "qqmlengine.h"
#include "qqmlinfo.h"
-#include "qqmlabstracturlinterceptor_p.h"
+#include "qqmlabstracturlinterceptor.h"
#include <qjsengine.h>
#include <QtCore/qvarlengtharray.h>
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index bd0b211403..de317a2dcb 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -73,15 +73,15 @@ QmlContextWrapper::~QmlContextWrapper()
context->destroy();
}
-QV4::Value QmlContextWrapper::qmlScope(QV8Engine *v8, QQmlContextData *ctxt, QObject *scope)
+ReturnedValue QmlContextWrapper::qmlScope(QV8Engine *v8, QQmlContextData *ctxt, QObject *scope)
{
ExecutionEngine *v4 = QV8Engine::getV4(v8);
QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, ctxt, scope);
- return Value::fromObject(w);
+ return Value::fromObject(w).asReturnedValue();
}
-QV4::Value QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url)
+ReturnedValue QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url)
{
ExecutionEngine *v4 = QV8Engine::getV4(v8);
@@ -92,27 +92,27 @@ QV4::Value QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url)
QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, context, 0);
w->isNullWrapper = true;
- return Value::fromObject(w);
+ return Value::fromObject(w).asReturnedValue();
}
QQmlContextData *QmlContextWrapper::callingContext(ExecutionEngine *v4)
{
- QV4::Object *qmlglobal = v4->qmlContextObject();
- if (!qmlglobal)
- return 0;
+ Scope scope(v4);
+ QV4::Scoped<QmlContextWrapper> c(scope, v4->qmlContextObject()->getPointer()->as<QmlContextWrapper>());
- QmlContextWrapper *c = qmlglobal->as<QmlContextWrapper>();
- return c ? c->getContext() : 0;
+ return !!c ? c->getContext() : 0;
}
QQmlContextData *QmlContextWrapper::getContext(const Value &value)
{
- Object *o = value.asObject();
- QmlContextWrapper *c = o ? o->as<QmlContextWrapper>() : 0;
- if (!c)
+ QV4::ExecutionEngine *v4 = value.engine();
+ if (!v4)
return 0;
- return c ? c->getContext():0;
+ Scope scope(v4);
+ QV4::Scoped<QmlContextWrapper> c(scope, value.as<QmlContextWrapper>());
+
+ return !!c ? c->getContext():0;
}
void QmlContextWrapper::takeContextOwnership(const Value &qmlglobal)
@@ -124,21 +124,22 @@ void QmlContextWrapper::takeContextOwnership(const Value &qmlglobal)
}
-Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty)
{
- QmlContextWrapper *resource = m->as<QmlContextWrapper>();
QV4::ExecutionEngine *v4 = m->engine();
+ QV4::Scope scope(v4);
+ QmlContextWrapper *resource = m->as<QmlContextWrapper>();
if (!resource)
v4->current->throwTypeError();
// In V8 the JS global object would come _before_ the QML global object,
// so simulate that here.
bool hasProp;
- QV4::Value result = v4->globalObject->get(name, &hasProp);
+ QV4::ScopedValue result(scope, v4->globalObject->get(name, &hasProp));
if (hasProp) {
if (hasProperty)
*hasProperty = hasProp;
- return result;
+ return result.asReturnedValue();
}
if (resource->isNullWrapper)
@@ -151,7 +152,7 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty)
if (hasProp) {
if (hasProperty)
*hasProperty = hasProp;
- return result;
+ return result.asReturnedValue();
}
// Its possible we could delay the calculation of the "actual" context (in the case
@@ -162,7 +163,7 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty)
if (!context) {
if (hasProperty)
*hasProperty = true;
- return result;
+ return result.asReturnedValue();
}
// Search type (attached property/enum/imported scripts) names
@@ -187,9 +188,9 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty)
if (r.scriptIndex != -1) {
int index = r.scriptIndex;
if (index < context->importedScripts.count())
- return context->importedScripts.at(index).value();
+ return context->importedScripts.at(index).value().asReturnedValue();
else
- return QV4::Value::undefinedValue();
+ return QV4::Value::undefinedValue().asReturnedValue();
} else if (r.type) {
return QmlTypeWrapper::create(engine, scopeObject, r.type);
} else if (r.importNamespace) {
@@ -241,11 +242,12 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty)
// Search scope object
if (scopeObject) {
bool hasProp = false;
- QV4::Value result = QV4::QObjectWrapper::getQmlProperty(v4->current, context, scopeObject, name, QV4::QObjectWrapper::CheckRevision, &hasProp);
+ QV4::ScopedValue result(scope, QV4::QObjectWrapper::getQmlProperty(v4->current, context, scopeObject,
+ name, QV4::QObjectWrapper::CheckRevision, &hasProp));
if (hasProp) {
if (hasProperty)
*hasProperty = true;
- return result;
+ return result.asReturnedValue();
}
}
scopeObject = 0;
@@ -254,11 +256,11 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty)
// Search context object
if (context->contextObject) {
bool hasProp = false;
- QV4::Value result = QV4::QObjectWrapper::getQmlProperty(v4->current, context, context->contextObject, name, QV4::QObjectWrapper::CheckRevision, &hasProp);
+ result = QV4::QObjectWrapper::getQmlProperty(v4->current, context, context->contextObject, name, QV4::QObjectWrapper::CheckRevision, &hasProp);
if (hasProp) {
if (hasProperty)
*hasProperty = true;
- return result;
+ return result.asReturnedValue();
}
}
@@ -267,13 +269,14 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty)
expressionContext->unresolvedNames = true;
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
{
- QmlContextWrapper *wrapper = m->as<QmlContextWrapper>();
ExecutionEngine *v4 = m->engine();
+ QV4::Scope scope(v4);
+ QV4::Scoped<QmlContextWrapper> wrapper(scope, m->as<QmlContextWrapper>());
if (!wrapper)
v4->current->throwTypeError();
@@ -281,7 +284,8 @@ void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
if (wrapper && wrapper->readOnly) {
QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
QLatin1Char('"');
- v4->current->throwError(Value::fromString(v4->current->engine->newString(error)));
+ Scoped<String> e(scope, v4->current->engine->newString(error));
+ v4->current->throwError(e);
}
Object::put(m, name, value);
diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h
index 0f44952567..c5f7f251c1 100644
--- a/src/qml/qml/qqmlcontextwrapper_p.h
+++ b/src/qml/qml/qqmlcontextwrapper_p.h
@@ -70,8 +70,8 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
QmlContextWrapper(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext = false);
~QmlContextWrapper();
- static QV4::Value qmlScope(QV8Engine *e, QQmlContextData *ctxt, QObject *scope);
- static QV4::Value urlScope(QV8Engine *e, const QUrl &);
+ static ReturnedValue qmlScope(QV8Engine *e, QQmlContextData *ctxt, QObject *scope);
+ static ReturnedValue urlScope(QV8Engine *e, const QUrl &);
static QQmlContextData *callingContext(ExecutionEngine *v4);
static void takeContextOwnership(const QV4::Value &qmlglobal);
@@ -82,7 +82,7 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
void setReadOnly(bool b) { readOnly = b; }
- static Value get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static void destroy(Managed *that);
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 971836f783..a2c190d0e6 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -63,10 +63,10 @@
#include "qqmltypenamecache_p.h"
#include "qqmlnotifier_p.h"
#include <private/qqmlprofilerservice_p.h>
-#include <private/qv8debugservice_p.h>
+#include <private/qv4debugservice_p.h>
#include <private/qdebugmessageservice_p.h>
#include "qqmlincubator.h"
-#include "qqmlabstracturlinterceptor_p.h"
+#include "qqmlabstracturlinterceptor.h"
#include <private/qv8profilerservice_p.h>
#include <private/qqmlboundsignal_p.h>
@@ -411,14 +411,50 @@ The following functions are also on the Qt object.
\row
\li \c application.active
\li
- This read-only property indicates whether the application is the top-most and focused
- application, and the user is able to interact with the application. The property
- is false when the application is in the background, the device keylock or screen
- saver is active, the screen backlight is turned off, or the global system dialog
- is being displayed on top of the application. It can be used for stopping and
- pausing animations, timers and active processing of data in order to save device
- battery power and free device memory and processor load when the application is not
- active.
+ Deprecated, use Qt.application.state == Qt.ApplicationActive instead.
+
+ \row
+ \li \c application.state
+ \li
+ This read-only property indicates the current state of the application.
+
+ Possible values are:
+
+ \list
+ \li Qt.ApplicationActive - The application is the top-most and focused application, and the
+ user is able to interact with the application.
+ \li Qt.ApplicationInactive - The application is visible or partially visible, but not selected
+ to be in front, the user cannot interact with the application.
+ On desktop platforms, this typically means that the user activated
+ another application. On mobile platforms, it is more common to
+ enter this state when the OS is interrupting the user with for
+ example incoming calls, SMS-messages or dialogs. This is usually a
+ transient state during which the application is paused. The user
+ may return focus to your application, but most of the time it will
+ be the first indication that the application is going to be suspended.
+ While in this state, consider pausing or stopping any activity that
+ should not continue when the user cannot interact with your
+ application, such as a video, a game, animations, or sensors.
+ You should also avoid performing CPU-intensive tasks which might
+ slow down the application in front.
+ \li Qt.ApplicationSuspended - The application is suspended and not visible to the user. On
+ mobile platforms, the application typically enters this state when
+ the user returns to the home screen or switches to another
+ application. While in this state, the application should ensure
+ that the user perceives it as always alive and does not lose his
+ progress, saving any persistent data. The application should cease
+ all activities and be prepared for code execution to stop. While
+ suspended, the application can be killed at any time without
+ further warnings (for example when low memory forces the OS to purge
+ suspended applications).
+ \li Qt.ApplicationHidden - The application is hidden and runs in the background. This is the
+ normal state for applications that need to do background processing,
+ like playing music, while the user interacts with other applications.
+ The application should free up all graphical resources when entering
+ this state. A Qt Quick application should not usually handle this state
+ at the QML level. Instead, you should unload the entire UI and reload
+ the QML files whenever the application becomes active again.
+ \endlist
\row
\li \c application.layoutDirection
@@ -469,6 +505,7 @@ The following functions are also on the Qt object.
Note that when using QML without a QGuiApplication, the following properties will be undefined:
\list
\li application.active
+ \li application.state
\li application.layoutDirection
\endlist
*/
@@ -738,6 +775,7 @@ void QQmlEnginePrivate::init()
if (baseModulesUninitialized) {
qmlRegisterType<QQmlComponent>("QML", 1, 0, "Component"); // required for the Compiler.
registerBaseTypes("QtQml", 2, 0); // import which provides language building blocks.
+ qmlRegisterUncreatableType<QQmlLocale>("QtQml", 2, 2, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
QQmlData::init();
baseModulesUninitialized = false;
@@ -759,7 +797,7 @@ void QQmlEnginePrivate::init()
QQmlEngineDebugService::isDebuggingEnabled()) {
isDebugging = true;
QQmlEngineDebugService::instance()->addEngine(q);
- QV8DebugService::addEngine(v8engine());
+ QV4DebugService::instance()->addEngine(q);
QV8ProfilerService::initialize();
QQmlProfilerService::initialize();
QDebugMessageService::instance();
@@ -848,7 +886,7 @@ QQmlEngine::~QQmlEngine()
Q_D(QQmlEngine);
if (d->isDebugging) {
QQmlEngineDebugService::instance()->remEngine(this);
- QV8DebugService::removeEngine(handle());
+ QV4DebugService::instance()->removeEngine(this);
}
// Emit onDestruction signals for the root context before
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index ddebf02c6c..76214c17a4 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -260,7 +260,7 @@ void QQmlExpression::setExpression(const QString &expression)
}
// Must be called with a valid handle scope
-QV4::Value QQmlExpressionPrivate::v4value(bool *isUndefined)
+QV4::ReturnedValue QQmlExpressionPrivate::v4value(bool *isUndefined)
{
if (!expressionFunctionValid) {
function = qmlBinding(context(), scopeObject(), expression, url, line, &qmlscope);
@@ -285,7 +285,8 @@ QVariant QQmlExpressionPrivate::value(bool *isUndefined)
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
{
- QV4::Value result = v4value(isUndefined);
+ QV4::Scope scope(QV8Engine::getV4(ep->v8engine()));
+ QV4::ScopedValue result(scope, v4value(isUndefined));
rv = ep->v8engine()->toVariant(result, -1);
}
diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h
index 9cc5a326f8..e84d193837 100644
--- a/src/qml/qml/qqmlexpression_p.h
+++ b/src/qml/qml/qqmlexpression_p.h
@@ -81,7 +81,7 @@ public:
QVariant value(bool *isUndefined = 0);
- QV4::Value v4value(bool *isUndefined = 0);
+ QV4::ReturnedValue v4value(bool *isUndefined = 0);
static inline QQmlExpressionPrivate *get(QQmlExpression *expr);
static inline QQmlExpression *get(QQmlExpressionPrivate *expr);
diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp
new file mode 100644
index 0000000000..5810e269eb
--- /dev/null
+++ b/src/qml/qml/qqmlfileselector.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFileSelector>
+#include "qqmlfileselector.h"
+#include "qqmlfileselector_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQmlFileSelector
+ \since 5.2
+ \inmodule QtQml
+ \brief A convenience class for applying a QFileSelector to QML file loading
+
+ QQmlFileSelector is a QQmlAbstractUrlInterceptor which will automatically apply a QFileSelector to
+ qml file and asset paths.
+
+ It is used as follows:
+
+ \code
+ QQmlEngine engine;
+ QQmlFileSelector selector;
+ engine.setUrlInterceptor(&selector);
+ \endcode
+
+ Then you can swap out files like so:
+ \code
+ main.qml
+ Component.qml
+ asset.png
+ +unix/Component.qml
+ +mac/asset.png
+ \endcode
+
+ In this example, main.qml will normally use Component.qml for the Component type. However on a
+ unix platform, the unix selector will be present and the +unix/Component.qml version will be
+ used instead. Note that this acts like swapping out Component.qml with +unix/Component.qml, so
+ when using Component.qml you should not need to alter any paths based on which version was
+ selected.
+
+ For example, to pass the "asset.png" file path around you would refer to it just as "asset.png" in
+ all of main.qml, Component.qml, and +linux/Component.qml. It will be replaced with +mac/asset.png
+ on Mac platforms in all cases.
+
+ For a list of available selectors, see \c QFileSelector.
+
+ Your platform may also provide additional selectors for you to use. As specified by QFileSelector,
+ directories used for selection must start with a '+' character, so you will not accidentally
+ trigger this feature unless you have directories with such names inside your project.
+ */
+
+/*!
+ Creates a new QQmlFileSelector, which includes its own QFileSelector.
+*/
+
+QQmlFileSelector::QQmlFileSelector(QObject* parent)
+ : QObject(*(new QQmlFileSelectorPrivate), parent)
+{
+}
+
+QQmlFileSelectorPrivate::QQmlFileSelectorPrivate()
+{
+ Q_Q(QQmlFileSelector);
+ ownSelector = true;
+ selector = new QFileSelector(q);
+}
+
+/*!
+ Sets a different QFileSelector instance for use by the QQmlFileSelector. QQmlFileSelector does not
+ take ownership of the new QFileSelector. To reset QQmlFileSelector to use its internal
+ QFileSelector instance, call setSelector(0).
+*/
+
+void QQmlFileSelector::setSelector(QFileSelector *selector)
+{
+ Q_D(QQmlFileSelector);
+ if (selector) {
+ if (d->ownSelector) {
+ delete d->selector;
+ d->ownSelector = false;
+ }
+ d->selector = selector;
+ } else {
+ if (!d->ownSelector) {
+ d->ownSelector = true;
+ d->selector = new QFileSelector(this);
+ } // Do nothing if already using internal selector
+ }
+}
+
+QUrl QQmlFileSelector::intercept(const QUrl &path, DataType type)
+{
+ Q_D(QQmlFileSelector);
+ if ( type == QQmlAbstractUrlInterceptor::QmldirFile ) //Don't intercept qmldir files, to prevent double interception
+ return path;
+ return d->selector->select(path);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlfileselector.h b/src/qml/qml/qqmlfileselector.h
new file mode 100644
index 0000000000..0152ce292a
--- /dev/null
+++ b/src/qml/qml/qqmlfileselector.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLFILESELECTOR_H
+#define QQMLFILESELECTOR_H
+
+#include <QtCore/QObject>
+#include <QtCore/QUrl>
+#include <QtQml/QQmlAbstractUrlInterceptor>
+#include <qtqmlglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QFileSelector;
+class QQmlFileSelectorPrivate;
+class Q_QML_EXPORT QQmlFileSelector : public QObject, public QQmlAbstractUrlInterceptor
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QQmlFileSelector)
+public:
+ QQmlFileSelector(QObject* parent=0);
+ void setSelector(QFileSelector *selector);
+
+protected:
+ virtual QUrl intercept(const QUrl &path, DataType type);
+
+private:
+ Q_DISABLE_COPY(QQmlFileSelector)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/qml/qqmlfileselector_p.h b/src/qml/qml/qqmlfileselector_p.h
new file mode 100644
index 0000000000..60d6072c8c
--- /dev/null
+++ b/src/qml/qml/qqmlfileselector_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLFILESELECTOR_P_H
+#define QQMLFILESELECTOR_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 "qqmlfileselector.h"
+#include <private/qobject_p.h>
+#include <private/qtqmlglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QFileSelector;
+class Q_QML_PRIVATE_EXPORT QQmlFileSelectorPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlFileSelector)
+public:
+ QQmlFileSelectorPrivate();
+ QFileSelector* selector;
+ bool ownSelector;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 85c6a4246a..e970ffec59 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -56,6 +56,8 @@
#include <private/qqmlengine_p.h>
#include <private/qfieldlist_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE)
@@ -835,7 +837,7 @@ QString QQmlImportsPrivate::resolvedUri(const QString &dir_arg, QQmlImportDataba
dir.chop(1);
QStringList paths = database->fileImportPath;
- qSort(paths.begin(), paths.end(), I::greaterThan); // Ensure subdirs preceed their parents.
+ std::sort(paths.begin(), paths.end(), I::greaterThan); // Ensure subdirs preceed their parents.
QString stableRelativePath = dir;
foreach(const QString &path, paths) {
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 2974bbcfbe..d16d421ed2 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -86,7 +86,7 @@ void QQmlDelayedError::setErrorObject(QObject *object)
void QQmlDelayedError::setError(const QV4::Exception &e)
{
- m_error.setDescription(e.value().toQString());
+ m_error.setDescription(QV4::Value::fromReturnedValue(e.value()).toQStringNoThrow());
QV4::ExecutionEngine::StackTrace trace = e.stackTrace();
if (!trace.isEmpty()) {
QV4::ExecutionEngine::StackFrame frame = trace.first();
@@ -122,15 +122,13 @@ void QQmlJavaScriptExpression::resetNotifyOnValueChanged()
clearGuards();
}
-QV4::Value
-QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
+QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
const QV4::Value &function, bool *isUndefined)
{
return evaluate(context, function, 0, 0, isUndefined);
}
-QV4::Value
-QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
+QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
const QV4::Value &function,
int argc, QV4::Value *args,
bool *isUndefined)
@@ -140,7 +138,7 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
if (function.isEmpty() || function.isUndefined()) {
if (isUndefined)
*isUndefined = true;
- return QV4::Value::emptyValue();
+ return QV4::Value::emptyValue().asReturnedValue();
}
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine);
@@ -162,36 +160,38 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
// incase we have been deleted.
DeleteWatcher watcher(this);
- QV4::Value result = QV4::Value::undefinedValue();
QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::Scope scope(v4);
+ QV4::ScopedValue result(scope, QV4::Value::undefinedValue());
QV4::ExecutionContext *ctx = v4->current;
try {
- QV4::Value This = ep->v8engine()->global();
+ QV4::ScopedCallData callData(scope, argc);
+ callData->thisObject = ep->v8engine()->global();
if (scopeObject() && requiresThisObject()) {
- QV4::Value value = QV4::QObjectWrapper::wrap(ctx->engine, scopeObject());
- if (value.isObject())
- This = value;
+ QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(ctx->engine, scopeObject()));
+ if (value->isObject())
+ callData->thisObject = value;
}
- QV4::ScopedCallData callData(v4, argc);
- callData->thisObject = This;
memcpy(callData->args, args, argc*sizeof(QV4::Value));
result = function.asFunctionObject()->call(callData);
if (isUndefined)
- *isUndefined = result.isUndefined();
+ *isUndefined = result->isUndefined();
if (!watcher.wasDeleted() && hasDelayedError())
delayedError()->clearError();
} catch (QV4::Exception &e) {
e.accept(ctx);
+ QV4::ScopedValue ex(scope, e.value());
if (isUndefined)
*isUndefined = true;
if (!watcher.wasDeleted()) {
- if (!e.value().isEmpty()) {
+ if (!ex->isEmpty()) {
delayedError()->setError(e);
} else {
- if (hasDelayedError()) delayedError()->clearError();
+ if (hasDelayedError())
+ delayedError()->clearError();
}
}
}
@@ -208,7 +208,7 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
ep->propertyCapture = lastPropertyCapture;
- return result;
+ return result.asReturnedValue();
}
void QQmlJavaScriptExpression::GuardCapture::captureProperty(QQmlNotifier *n)
@@ -302,6 +302,7 @@ QQmlDelayedError *QQmlJavaScriptExpression::delayedError()
void QQmlJavaScriptExpression::exceptionToError(const QV4::Exception &e, QQmlError &error)
{
+ QV4::Scope scope(e.engine());
QV4::ExecutionEngine::StackTrace trace = e.stackTrace();
if (!trace.isEmpty()) {
QV4::ExecutionEngine::StackFrame frame = trace.first();
@@ -309,15 +310,18 @@ void QQmlJavaScriptExpression::exceptionToError(const QV4::Exception &e, QQmlErr
error.setLine(frame.line);
error.setColumn(frame.column);
}
- QV4::ErrorObject *errorObj = e.value().asErrorObject();
- if (errorObj && errorObj->asSyntaxError())
- error.setDescription(errorObj->get(errorObj->engine()->newString("message")).toQString());
- else
- error.setDescription(e.value().toQString());
+ QV4::Scoped<QV4::ErrorObject> errorObj(scope, e.value());
+ if (!!errorObj && errorObj->asSyntaxError()) {
+ QV4::ScopedValue v(scope, errorObj->get(errorObj->engine()->newString("message")));
+ error.setDescription(v->toQStringNoThrow());
+ } else {
+ QV4::ScopedValue v(scope, e.value());
+ error.setDescription(v->toQStringNoThrow());
+ }
}
QV4::PersistentValue
-QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
+QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scopeObject,
const QString &code, const QString &filename, quint16 line,
QV4::PersistentValue *qmlscope)
{
@@ -326,10 +330,11 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
QV4::ExecutionContext *ctx = v4->current;
+ QV4::Scope scope(v4);
- QV4::Value scopeObject = QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, scope);
- QV4::Script script(v4, scopeObject.asObject(), code, filename, line);
- QV4::Value result;
+ QV4::Scoped<QV4::Object> qmlScopeObject(scope, QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, scopeObject));
+ QV4::Script script(v4, qmlScopeObject.getPointer(), code, filename, line);
+ QV4::ScopedValue result(scope);
try {
script.parse();
result = script.run();
@@ -343,16 +348,16 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setLine(line);
if (error.url().isEmpty())
error.setUrl(QUrl::fromLocalFile(filename));
- error.setObject(scope);
+ error.setObject(scopeObject);
ep->warning(error);
return QV4::PersistentValue();
}
if (qmlscope)
- *qmlscope = scopeObject;
- return result;
+ *qmlscope = qmlScopeObject.asValue();
+ return result.asReturnedValue();
}
-QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, QObject *scope,
+QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, QObject *qmlScope,
const QString &code, const QString &filename, quint16 line,
QV4::PersistentValue *qmlscope)
{
@@ -361,10 +366,11 @@ QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt,
QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
QV4::ExecutionContext *ctx = v4->current;
+ QV4::Scope scope(v4);
- QV4::Value scopeObject = QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, scope);
- QV4::Script script(v4, scopeObject.asObject(), code, filename, line);
- QV4::Value result;
+ QV4::ScopedValue qmlScopeObject(scope, QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, qmlScope));
+ QV4::Script script(v4, qmlScopeObject->asObject(), code, filename, line);
+ QV4::ScopedValue result(scope);
try {
script.parse();
result = script.qmlBinding();
@@ -378,13 +384,13 @@ QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt,
error.setLine(line);
if (error.url().isEmpty())
error.setUrl(QUrl::fromLocalFile(filename));
- error.setObject(scope);
+ error.setObject(qmlScope);
ep->warning(error);
return QV4::PersistentValue();
}
if (qmlscope)
- *qmlscope = scopeObject;
- return result;
+ *qmlscope = qmlScopeObject;
+ return result.asReturnedValue();
}
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index ef36a2f91a..f08b3af6cf 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -110,9 +110,9 @@ public:
QQmlJavaScriptExpression(VTable *vtable);
- QV4::Value evaluate(QQmlContextData *, const QV4::Value &function,
+ QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function,
bool *isUndefined);
- QV4::Value evaluate(QQmlContextData *, const QV4::Value &function,
+ QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function,
int argc, QV4::Value *args,
bool *isUndefined);
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index 1c1386d5b7..23aca851a6 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -63,10 +63,10 @@ QmlListWrapper::~QmlListWrapper()
{
}
-Value QmlListWrapper::create(QV8Engine *v8, QObject *object, int propId, int propType)
+ReturnedValue QmlListWrapper::create(QV8Engine *v8, QObject *object, int propId, int propType)
{
if (!object || propId == -1)
- return Value::nullValue();
+ return Encode::null();
ExecutionEngine *v4 = QV8Engine::getV4(v8);
@@ -75,10 +75,10 @@ Value QmlListWrapper::create(QV8Engine *v8, QObject *object, int propId, int pro
r->propertyType = propType;
void *args[] = { &r->property, 0 };
QMetaObject::metacall(object, QMetaObject::ReadProperty, propId, args);
- return Value::fromObject(r);
+ return Value::fromObject(r).asReturnedValue();
}
-Value QmlListWrapper::create(QV8Engine *v8, const QQmlListProperty<QObject> &prop, int propType)
+ReturnedValue QmlListWrapper::create(QV8Engine *v8, const QQmlListProperty<QObject> &prop, int propType)
{
ExecutionEngine *v4 = QV8Engine::getV4(v8);
@@ -86,7 +86,7 @@ Value QmlListWrapper::create(QV8Engine *v8, const QQmlListProperty<QObject> &pro
r->object = prop.object;
r->property = prop;
r->propertyType = propType;
- return Value::fromObject(r);
+ return Value::fromObject(r).asReturnedValue();
}
QVariant QmlListWrapper::toVariant() const
@@ -98,7 +98,7 @@ QVariant QmlListWrapper::toVariant() const
}
-Value QmlListWrapper::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue QmlListWrapper::get(Managed *m, String *name, bool *hasProperty)
{
QV4::ExecutionEngine *v4 = m->engine();
QmlListWrapper *w = m->as<QmlListWrapper>();
@@ -107,7 +107,7 @@ Value QmlListWrapper::get(Managed *m, String *name, bool *hasProperty)
if (name == v4->id_length && !w->object.isNull()) {
quint32 count = w->property.count ? w->property.count(&w->property) : 0;
- return Value::fromUInt32(count);
+ return Value::fromUInt32(count).asReturnedValue();
}
uint idx = name->asArrayIndex();
@@ -117,7 +117,7 @@ Value QmlListWrapper::get(Managed *m, String *name, bool *hasProperty)
return Object::get(m, name, hasProperty);
}
-Value QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProperty)
{
QV4::ExecutionEngine *e = m->engine();
QmlListWrapper *w = m->as<QmlListWrapper>();
@@ -128,7 +128,7 @@ Value QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProperty)
if (index < count && w->property.at)
return QV4::QObjectWrapper::wrap(e, w->property.at(&w->property, index));
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
void QmlListWrapper::put(Managed *m, String *name, const Value &value)
@@ -156,7 +156,7 @@ Property *QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, String
*attrs = QV4::Attr_Data;
*index = it->arrayIndex;
++it->arrayIndex;
- it->tmpDynamicProperty.value = QV4::QObjectWrapper::wrap(w->engine(), w->property.at(&w->property, *index));
+ it->tmpDynamicProperty.value = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(w->engine(), w->property.at(&w->property, *index)));
return &it->tmpDynamicProperty;
}
return QV4::Object::advanceIterator(m, it, name, index, attrs);
diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h
index c87b9b22d5..0de028a35b 100644
--- a/src/qml/qml/qqmllistwrapper_p.h
+++ b/src/qml/qml/qqmllistwrapper_p.h
@@ -76,13 +76,13 @@ protected:
public:
- static Value create(QV8Engine *v8, QObject *object, int propId, int propType);
- static Value create(QV8Engine *v8, const QQmlListProperty<QObject> &prop, int propType);
+ static ReturnedValue create(QV8Engine *v8, QObject *object, int propId, int propType);
+ static ReturnedValue create(QV8Engine *v8, const QQmlListProperty<QObject> &prop, int propType);
QVariant toVariant() const;
- static Value get(Managed *m, String *name, bool *hasProperty);
- static Value getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
static void destroy(Managed *that);
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 7f68ccc324..405411e65c 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -74,33 +74,33 @@ public:
return thisObject->locale;
}
- static QV4::Value method_currencySymbol(QV4::SimpleCallContext *ctx);
- static QV4::Value method_dateTimeFormat(QV4::SimpleCallContext *ctx);
- static QV4::Value method_timeFormat(QV4::SimpleCallContext *ctx);
- static QV4::Value method_dateFormat(QV4::SimpleCallContext *ctx);
- static QV4::Value method_monthName(QV4::SimpleCallContext *ctx);
- static QV4::Value method_standaloneMonthName(QV4::SimpleCallContext *ctx);
- static QV4::Value method_dayName(QV4::SimpleCallContext *ctx);
- static QV4::Value method_standaloneDayName(QV4::SimpleCallContext *ctx);
-
- static QV4::Value method_get_firstDayOfWeek(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_measurementSystem(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_textDirection(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_weekDays(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_uiLanguages(QV4::SimpleCallContext *ctx);
-
- static QV4::Value method_get_name(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_nativeLanguageName(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_nativeCountryName(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_decimalPoint(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_groupSeparator(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_percent(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_zeroDigit(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_negativeSign(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_positiveSign(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_exponential(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_amText(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_pmText(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_currencySymbol(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_dateTimeFormat(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_timeFormat(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_dateFormat(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_monthName(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_standaloneMonthName(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_dayName(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_standaloneDayName(QV4::SimpleCallContext *ctx);
+
+ static QV4::ReturnedValue method_get_firstDayOfWeek(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_measurementSystem(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_textDirection(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_weekDays(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_uiLanguages(QV4::SimpleCallContext *ctx);
+
+ static QV4::ReturnedValue method_get_name(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_nativeLanguageName(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_nativeCountryName(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_decimalPoint(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_groupSeparator(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_percent(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_zeroDigit(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_negativeSign(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_positiveSign(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_exponential(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_amText(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_pmText(QV4::SimpleCallContext *ctx);
private:
static void destroy(Managed *that)
@@ -126,16 +126,16 @@ static bool isLocaleObject(const QV4::Value &val)
void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine)
{
- engine->dateClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleString"), toLocaleString);
- engine->dateClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleTimeString"), toLocaleTimeString);
- engine->dateClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleDateString"), toLocaleDateString);
- engine->dateCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("fromLocaleString"), fromLocaleString);
- engine->dateCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("fromLocaleTimeString"), fromLocaleTimeString);
- engine->dateCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("fromLocaleDateString"), fromLocaleDateString);
- engine->dateCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("timeZoneUpdated"), timeZoneUpdated);
+ engine->dateClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleString"), method_toLocaleString);
+ engine->dateClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleTimeString"), method_toLocaleTimeString);
+ engine->dateClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleDateString"), method_toLocaleDateString);
+ engine->dateCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("fromLocaleString"), method_fromLocaleString);
+ engine->dateCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("fromLocaleTimeString"), method_fromLocaleTimeString);
+ engine->dateCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("fromLocaleDateString"), method_fromLocaleDateString);
+ engine->dateCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("timeZoneUpdated"), method_timeZoneUpdated);
}
-QV4::Value QQmlDateExtension::toLocaleString(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDateExtension::method_toLocaleString(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount > 2)
return QV4::DatePrototype::method_toLocaleString(ctx);
@@ -149,7 +149,7 @@ QV4::Value QQmlDateExtension::toLocaleString(QV4::SimpleCallContext *ctx)
if (ctx->argumentCount == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return QV4::Value::fromString(ctx, locale.toString(dt));
+ return QV4::Value::fromString(ctx, locale.toString(dt)).asReturnedValue();
}
if (!isLocaleObject(ctx->arguments[0]))
@@ -174,10 +174,10 @@ QV4::Value QQmlDateExtension::toLocaleString(QV4::SimpleCallContext *ctx)
formattedDt = r->locale.toString(dt, enumFormat);
}
- return QV4::Value::fromString(ctx, formattedDt);
+ return QV4::Value::fromString(ctx, formattedDt).asReturnedValue();
}
-QV4::Value QQmlDateExtension::toLocaleTimeString(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDateExtension::method_toLocaleTimeString(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount > 2)
return QV4::DatePrototype::method_toLocaleTimeString(ctx);
@@ -192,7 +192,7 @@ QV4::Value QQmlDateExtension::toLocaleTimeString(QV4::SimpleCallContext *ctx)
if (ctx->argumentCount == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return QV4::Value::fromString(ctx, locale.toString(time));
+ return QV4::Value::fromString(ctx, locale.toString(time)).asReturnedValue();
}
if (!isLocaleObject(ctx->arguments[0]))
@@ -217,10 +217,10 @@ QV4::Value QQmlDateExtension::toLocaleTimeString(QV4::SimpleCallContext *ctx)
formattedTime = r->locale.toString(time, enumFormat);
}
- return QV4::Value::fromString(ctx, formattedTime);
+ return QV4::Value::fromString(ctx, formattedTime).asReturnedValue();
}
-QV4::Value QQmlDateExtension::toLocaleDateString(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDateExtension::method_toLocaleDateString(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount > 2)
return QV4::DatePrototype::method_toLocaleDateString(ctx);
@@ -235,7 +235,7 @@ QV4::Value QQmlDateExtension::toLocaleDateString(QV4::SimpleCallContext *ctx)
if (ctx->argumentCount == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return QV4::Value::fromString(ctx, locale.toString(date));
+ return QV4::Value::fromString(ctx, locale.toString(date)).asReturnedValue();
}
if (!isLocaleObject(ctx->arguments[0]))
@@ -260,17 +260,17 @@ QV4::Value QQmlDateExtension::toLocaleDateString(QV4::SimpleCallContext *ctx)
formattedDate = r->locale.toString(date, enumFormat);
}
- return QV4::Value::fromString(ctx, formattedDate);
+ return QV4::Value::fromString(ctx, formattedDate).asReturnedValue();
}
-QV4::Value QQmlDateExtension::fromLocaleString(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDateExtension::method_fromLocaleString(QV4::SimpleCallContext *ctx)
{
QV4::ExecutionEngine * const engine = ctx->engine;
if (ctx->argumentCount == 1 && ctx->arguments[0].isString()) {
QLocale locale;
QString dateString = ctx->arguments[0].stringValue()->toQString();
QDateTime dt = locale.toDateTime(dateString);
- return QV4::Value::fromObject(engine->newDateObject(dt));
+ return QV4::Encode(engine->newDateObject(dt));
}
if (ctx->argumentCount < 1 || ctx->argumentCount > 3 || !isLocaleObject(ctx->arguments[0]))
@@ -280,7 +280,7 @@ QV4::Value QQmlDateExtension::fromLocaleString(QV4::SimpleCallContext *ctx)
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDateTime dt;
- QString dateString = ctx->arguments[1].toQString();
+ QString dateString = ctx->arguments[1].toQStringNoThrow();
if (ctx->argumentCount == 3) {
if (ctx->arguments[2].isString()) {
QString format = ctx->arguments[2].stringValue()->toQString();
@@ -296,10 +296,10 @@ QV4::Value QQmlDateExtension::fromLocaleString(QV4::SimpleCallContext *ctx)
dt = r->locale.toDateTime(dateString, enumFormat);
}
- return QV4::Value::fromObject(engine->newDateObject(dt));
+ return QV4::Encode(engine->newDateObject(dt));
}
-QV4::Value QQmlDateExtension::fromLocaleTimeString(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::SimpleCallContext *ctx)
{
QV4::ExecutionEngine * const engine = ctx->engine;
@@ -309,7 +309,7 @@ QV4::Value QQmlDateExtension::fromLocaleTimeString(QV4::SimpleCallContext *ctx)
QTime time = locale.toTime(timeString);
QDateTime dt = QDateTime::currentDateTime();
dt.setTime(time);
- return QV4::Value::fromObject(engine->newDateObject(dt));
+ return QV4::Encode(engine->newDateObject(dt));
}
if (ctx->argumentCount < 1 || ctx->argumentCount > 3 || !isLocaleObject(ctx->arguments[0]))
@@ -319,7 +319,7 @@ QV4::Value QQmlDateExtension::fromLocaleTimeString(QV4::SimpleCallContext *ctx)
QLocale::FormatType enumFormat = QLocale::LongFormat;
QTime tm;
- QString dateString = ctx->arguments[1].toQString();
+ QString dateString = ctx->arguments[1].toQStringNoThrow();
if (ctx->argumentCount == 3) {
if (ctx->arguments[2].isString()) {
QString format = ctx->arguments[2].stringValue()->toQString();
@@ -338,10 +338,10 @@ QV4::Value QQmlDateExtension::fromLocaleTimeString(QV4::SimpleCallContext *ctx)
QDateTime dt = QDateTime::currentDateTime();
dt.setTime(tm);
- return QV4::Value::fromObject(engine->newDateObject(dt));
+ return QV4::Encode(engine->newDateObject(dt));
}
-QV4::Value QQmlDateExtension::fromLocaleDateString(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDateExtension::method_fromLocaleDateString(QV4::SimpleCallContext *ctx)
{
QV4::ExecutionEngine * const engine = ctx->engine;
@@ -349,7 +349,7 @@ QV4::Value QQmlDateExtension::fromLocaleDateString(QV4::SimpleCallContext *ctx)
QLocale locale;
QString dateString = ctx->arguments[0].stringValue()->toQString();
QDate date = locale.toDate(dateString);
- return QV4::Value::fromObject(engine->newDateObject(QDateTime(date)));
+ return QV4::Encode(engine->newDateObject(QDateTime(date)));
}
if (ctx->argumentCount < 1 || ctx->argumentCount > 3 || !isLocaleObject(ctx->arguments[0]))
@@ -359,7 +359,7 @@ QV4::Value QQmlDateExtension::fromLocaleDateString(QV4::SimpleCallContext *ctx)
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDate dt;
- QString dateString = ctx->arguments[1].toQString();
+ QString dateString = ctx->arguments[1].toQStringNoThrow();
if (ctx->argumentCount == 3) {
if (ctx->arguments[2].isString()) {
QString format = ctx->arguments[2].stringValue()->toQString();
@@ -375,17 +375,17 @@ QV4::Value QQmlDateExtension::fromLocaleDateString(QV4::SimpleCallContext *ctx)
dt = r->locale.toDate(dateString, enumFormat);
}
- return QV4::Value::fromObject(engine->newDateObject(QDateTime(dt)));
+ return QV4::Encode(engine->newDateObject(QDateTime(dt)));
}
-QV4::Value QQmlDateExtension::timeZoneUpdated(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDateExtension::method_timeZoneUpdated(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 0)
V4THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments");
QV4::DatePrototype::timezoneUpdated();
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
//-----------------
@@ -393,12 +393,12 @@ QV4::Value QQmlDateExtension::timeZoneUpdated(QV4::SimpleCallContext *ctx)
void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine)
{
- engine->numberClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleString"), toLocaleString);
- engine->numberClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleCurrencyString"), toLocaleCurrencyString);
- engine->numberCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("fromLocaleString"), fromLocaleString);
+ engine->numberClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleString"), method_toLocaleString);
+ engine->numberClass->prototype->defineDefaultProperty(engine, QStringLiteral("toLocaleCurrencyString"), method_toLocaleCurrencyString);
+ engine->numberCtor.objectValue()->defineDefaultProperty(engine, QStringLiteral("fromLocaleString"), method_fromLocaleString);
}
-QV4::Value QQmlNumberExtension::toLocaleString(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount > 3)
V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
@@ -408,7 +408,7 @@ QV4::Value QQmlNumberExtension::toLocaleString(QV4::SimpleCallContext *ctx)
if (ctx->argumentCount == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return QV4::Value::fromString(ctx, locale.toString(number));
+ return QV4::Value::fromString(ctx, locale.toString(number)).asReturnedValue();
}
if (!isLocaleObject(ctx->arguments[0]))
@@ -431,10 +431,10 @@ QV4::Value QQmlNumberExtension::toLocaleString(QV4::SimpleCallContext *ctx)
prec = ctx->arguments[2].toInt32();
}
- return QV4::Value::fromString(ctx, r->locale.toString(number, (char)format, prec));
+ return QV4::Value::fromString(ctx, r->locale.toString(number, (char)format, prec)).asReturnedValue();
}
-QV4::Value QQmlNumberExtension::toLocaleCurrencyString(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount > 2)
V4THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
@@ -444,7 +444,7 @@ QV4::Value QQmlNumberExtension::toLocaleCurrencyString(QV4::SimpleCallContext *c
if (ctx->argumentCount == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return QV4::Value::fromString(ctx, locale.toString(number));
+ return QV4::Value::fromString(ctx, locale.toString(number)).asReturnedValue();
}
if (!isLocaleObject(ctx->arguments[0]))
@@ -456,13 +456,13 @@ QV4::Value QQmlNumberExtension::toLocaleCurrencyString(QV4::SimpleCallContext *c
if (ctx->argumentCount > 1) {
if (!ctx->arguments[1].isString())
V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- symbol = ctx->arguments[1].toQString();
+ symbol = ctx->arguments[1].toQStringNoThrow();
}
- return QV4::Value::fromString(ctx, r->locale.toCurrencyString(number, symbol));
+ return QV4::Value::fromString(ctx, r->locale.toCurrencyString(number, symbol)).asReturnedValue();
}
-QV4::Value QQmlNumberExtension::fromLocaleString(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount < 1 || ctx->argumentCount > 2)
V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
@@ -482,7 +482,7 @@ QV4::Value QQmlNumberExtension::fromLocaleString(QV4::SimpleCallContext *ctx)
QV4::String *ns = ctx->arguments[numberIdx].toString(ctx);
if (ns->isEmpty())
- return QV4::Value::fromDouble(Q_QNAN);
+ return QV4::Encode(Q_QNAN);
bool ok = false;
double val = locale.toDouble(ns->toQString(), &ok);
@@ -490,39 +490,40 @@ QV4::Value QQmlNumberExtension::fromLocaleString(QV4::SimpleCallContext *ctx)
if (!ok)
V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format")
- return QV4::Value::fromDouble(val);
+ return QV4::Encode(val);
}
//--------------
// Locale object
-QV4::Value QQmlLocaleData::method_get_firstDayOfWeek(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(QV4::SimpleCallContext *ctx)
{
QLocale locale = getThisLocale(ctx);
int fdow = int(locale.firstDayOfWeek());
if (fdow == 7)
fdow = 0; // Qt::Sunday = 7, but Sunday is 0 in JS Date
- return QV4::Value::fromInt32(fdow);
+ return QV4::Encode(fdow);
}
-QV4::Value QQmlLocaleData::method_get_measurementSystem(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlLocaleData::method_get_measurementSystem(QV4::SimpleCallContext *ctx)
{
QLocale locale = getThisLocale(ctx);
- return QV4::Value::fromInt32(locale.measurementSystem());
+ return QV4::Encode(locale.measurementSystem());
}
-QV4::Value QQmlLocaleData::method_get_textDirection(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlLocaleData::method_get_textDirection(QV4::SimpleCallContext *ctx)
{
QLocale locale = getThisLocale(ctx);
- return QV4::Value::fromInt32(locale.textDirection());
+ return QV4::Encode(locale.textDirection());
}
-QV4::Value QQmlLocaleData::method_get_weekDays(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QLocale locale = getThisLocale(ctx);
QList<Qt::DayOfWeek> days = locale.weekdays();
- QV4::ArrayObject *result = ctx->engine->newArrayObject();
+ QV4::Scoped<QV4::ArrayObject> result(scope, ctx->engine->newArrayObject());
result->arrayReserve(days.size());
result->arrayDataLen = days.size();
for (int i = 0; i < days.size(); ++i) {
@@ -533,24 +534,25 @@ QV4::Value QQmlLocaleData::method_get_weekDays(QV4::SimpleCallContext *ctx)
}
result->setArrayLengthUnchecked(days.size());
- return QV4::Value::fromObject(result);
+ return result.asReturnedValue();
}
-QV4::Value QQmlLocaleData::method_get_uiLanguages(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlLocaleData::method_get_uiLanguages(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QLocale locale = getThisLocale(ctx);
QStringList langs = locale.uiLanguages();
- QV4::ArrayObject *result = ctx->engine->newArrayObject();
+ QV4::Scoped<QV4::ArrayObject> result(scope, ctx->engine->newArrayObject());
result->arrayReserve(langs.size());
result->arrayDataLen = langs.size();
for (int i = 0; i < langs.size(); ++i)
result->arrayData[i].value = QV4::Value::fromString(ctx, langs.at(i));
result->setArrayLengthUnchecked(langs.size());
- return QV4::Value::fromObject(result);
+ return result.asReturnedValue();
}
-QV4::Value QQmlLocaleData::method_currencySymbol(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlLocaleData::method_currencySymbol(QV4::SimpleCallContext *ctx)
{
QLocale locale = getThisLocale(ctx);
if (ctx->argumentCount > 1)
@@ -562,11 +564,11 @@ QV4::Value QQmlLocaleData::method_currencySymbol(QV4::SimpleCallContext *ctx)
format = QLocale::CurrencySymbolFormat(intFormat);
}
- return QV4::Value::fromString(ctx, locale.currencySymbol(format));
+ return QV4::Value::fromString(ctx, locale.currencySymbol(format)).asReturnedValue();
}
#define LOCALE_FORMAT(FUNC) \
-QV4::Value QQmlLocaleData::method_ ##FUNC (QV4::SimpleCallContext *ctx) { \
+QV4::ReturnedValue QQmlLocaleData::method_ ##FUNC (QV4::SimpleCallContext *ctx) { \
QLocale locale = getThisLocale(ctx); \
if (ctx->argumentCount > 1) \
V4THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
@@ -575,7 +577,7 @@ QV4::Value QQmlLocaleData::method_ ##FUNC (QV4::SimpleCallContext *ctx) { \
quint32 intFormat = ctx->arguments[0].toUInt32(); \
format = QLocale::FormatType(intFormat); \
} \
- return QV4::Value::fromString(ctx, locale. FUNC (format)); \
+ return QV4::Value::fromString(ctx, locale. FUNC (format)).asReturnedValue(); \
}
LOCALE_FORMAT(dateTimeFormat)
@@ -584,7 +586,7 @@ LOCALE_FORMAT(dateFormat)
// +1 added to idx because JS is 0-based, whereas QLocale months begin at 1.
#define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \
-QV4::Value QQmlLocaleData::method_ ## VARIABLE (QV4::SimpleCallContext *ctx) {\
+QV4::ReturnedValue QQmlLocaleData::method_ ## VARIABLE (QV4::SimpleCallContext *ctx) {\
QLocale locale = getThisLocale(ctx); \
if (ctx->argumentCount < 1 || ctx->argumentCount > 2) \
V4THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
@@ -604,12 +606,12 @@ QV4::Value QQmlLocaleData::method_ ## VARIABLE (QV4::SimpleCallContext *ctx) {\
} else { \
name = locale. VARIABLE(idx, enumFormat); \
} \
- return QV4::Value::fromString(ctx, name); \
+ return QV4::Value::fromString(ctx, name).asReturnedValue(); \
}
// 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date
#define LOCALE_FORMATTED_DAYNAME(VARIABLE) \
-QV4::Value QQmlLocaleData::method_ ## VARIABLE (QV4::SimpleCallContext *ctx) {\
+QV4::ReturnedValue QQmlLocaleData::method_ ## VARIABLE (QV4::SimpleCallContext *ctx) {\
QLocale locale = getThisLocale(ctx); \
if (ctx->argumentCount < 1 || ctx->argumentCount > 2) \
V4THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
@@ -630,7 +632,7 @@ QV4::Value QQmlLocaleData::method_ ## VARIABLE (QV4::SimpleCallContext *ctx) {\
} else { \
name = locale. VARIABLE(idx, enumFormat); \
} \
- return QV4::Value::fromString(ctx, name); \
+ return QV4::Value::fromString(ctx, name).asReturnedValue(); \
}
LOCALE_FORMATTED_MONTHNAME(monthName)
@@ -638,10 +640,10 @@ LOCALE_FORMATTED_MONTHNAME(standaloneMonthName)
LOCALE_FORMATTED_DAYNAME(dayName)
LOCALE_FORMATTED_DAYNAME(standaloneDayName)
-#define LOCALE_STRING_PROPERTY(VARIABLE) QV4::Value QQmlLocaleData::method_get_ ## VARIABLE (QV4::SimpleCallContext* ctx) \
+#define LOCALE_STRING_PROPERTY(VARIABLE) QV4::ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (QV4::SimpleCallContext* ctx) \
{ \
QLocale locale = getThisLocale(ctx); \
- return QV4::Value::fromString(ctx, locale. VARIABLE());\
+ return QV4::Value::fromString(ctx, locale. VARIABLE()).asReturnedValue();\
}
LOCALE_STRING_PROPERTY(name)
@@ -796,7 +798,7 @@ V8_DEFINE_EXTENSION(QV8LocaleDataDeletable, localeV8Data);
This product includes software developed by the University of
California, Berkeley and its contributors.
- \sa {QtQuick2::Date}{Date}, {QtQuick2::Number}{Number}
+ \sa Date, Number
*/
QQmlLocale::QQmlLocale()
@@ -807,7 +809,7 @@ QQmlLocale::~QQmlLocale()
{
}
-QV4::Value QQmlLocale::locale(QV8Engine *v8engine, const QString &locale)
+QV4::ReturnedValue QQmlLocale::locale(QV8Engine *v8engine, const QString &locale)
{
QV8LocaleDataDeletable *d = localeV8Data(v8engine);
QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine);
@@ -815,15 +817,15 @@ QV4::Value QQmlLocale::locale(QV8Engine *v8engine, const QString &locale)
if (!locale.isEmpty())
wrapper->locale = QLocale(locale);
wrapper->setPrototype(d->prototype.value().asObject());
- return QV4::Value::fromObject(wrapper);
+ return QV4::Value::fromObject(wrapper).asReturnedValue();
}
void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine)
{
- engine->stringClass->prototype->defineDefaultProperty(engine, QStringLiteral("localeCompare"), localeCompare);
+ engine->stringClass->prototype->defineDefaultProperty(engine, QStringLiteral("localeCompare"), method_localeCompare);
}
-QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlLocale::method_localeCompare(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1 || (!ctx->arguments[0].isString() && !ctx->arguments[0].asStringObject()))
return QV4::StringPrototype::method_localeCompare(ctx);
@@ -831,14 +833,14 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
if (!ctx->thisObject.isString() && !ctx->thisObject.asStringObject())
return QV4::StringPrototype::method_localeCompare(ctx);
- QString thisString = ctx->thisObject.toQString();
- QString thatString = ctx->arguments[0].toQString();
+ QString thisString = ctx->thisObject.toQStringNoThrow();
+ QString thatString = ctx->arguments[0].toQStringNoThrow();
- return QV4::Value::fromInt32(QString::localeAwareCompare(thisString, thatString));
+ return QV4::Encode(QString::localeAwareCompare(thisString, thatString));
}
/*!
- \qmlproperty string QtQuick2::Locale::name
+ \qmlproperty string QtQml2::Locale::name
Holds the language and country of this locale as a
string of the form "language_country", where
@@ -847,77 +849,77 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlproperty string QtQuick2::Locale::decimalPoint
+ \qmlproperty string QtQml2::Locale::decimalPoint
Holds the decimal point character of this locale.
*/
/*!
- \qmlproperty string QtQuick2::Locale::groupSeparator
+ \qmlproperty string QtQml2::Locale::groupSeparator
Holds the group separator character of this locale.
*/
/*!
- \qmlproperty string QtQuick2::Locale::percent
+ \qmlproperty string QtQml2::Locale::percent
Holds the percent character of this locale.
*/
/*!
- \qmlproperty string QtQuick2::Locale::zeroDigit
+ \qmlproperty string QtQml2::Locale::zeroDigit
Holds Returns the zero digit character of this locale.
*/
/*!
- \qmlproperty string QtQuick2::Locale::negativeSign
+ \qmlproperty string QtQml2::Locale::negativeSign
Holds the negative sign character of this locale.
*/
/*!
- \qmlproperty string QtQuick2::Locale::positiveSign
+ \qmlproperty string QtQml2::Locale::positiveSign
Holds the positive sign character of this locale.
*/
/*!
- \qmlproperty string QtQuick2::Locale::exponential
+ \qmlproperty string QtQml2::Locale::exponential
Holds the exponential character of this locale.
*/
/*!
- \qmlmethod string QtQuick2::Locale::dateTimeFormat(type)
+ \qmlmethod string QtQml2::Locale::dateTimeFormat(type)
Returns the date time format used for the current locale.
\a type specifies the FormatType to return.
- \sa {QtQuick2::Date}{Date}
+ \sa Date
*/
/*!
- \qmlmethod string QtQuick2::Locale::dateFormat(type)
+ \qmlmethod string QtQml2::Locale::dateFormat(type)
Returns the date format used for the current locale.
\a type specifies the FormatType to return.
- \sa {QtQuick2::Date}{Date}
+ \sa Date
*/
/*!
- \qmlmethod string QtQuick2::Locale::timeFormat(type)
+ \qmlmethod string QtQml2::Locale::timeFormat(type)
Returns the time format used for the current locale.
\a type specifies the FormatType to return.
- \sa {QtQuick2::Date}{Date}
+ \sa Date
*/
/*!
- \qmlmethod string QtQuick2::Locale::monthName(month, type)
+ \qmlmethod string QtQml2::Locale::monthName(month, type)
Returns the localized name of \a month (0-11), in the optional
\l FormatType specified by \a type.
@@ -929,7 +931,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlmethod string QtQuick2::Locale::standaloneMonthName(month, type)
+ \qmlmethod string QtQml2::Locale::standaloneMonthName(month, type)
Returns the localized name of \a month (0-11) that is used as a
standalone text, in the optional \l FormatType specified by \a type.
@@ -944,7 +946,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlmethod string QtQuick2::Locale::dayName(day, type)
+ \qmlmethod string QtQml2::Locale::dayName(day, type)
Returns the localized name of the \a day (where 0 represents
Sunday, 1 represents Monday and so on), in the optional
@@ -954,7 +956,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlmethod string QtQuick2::Locale::standaloneDayName(day, type)
+ \qmlmethod string QtQml2::Locale::standaloneDayName(day, type)
Returns the localized name of the \a day (where 0 represents
Sunday, 1 represents Monday and so on) that is used as a
@@ -967,7 +969,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlproperty enumeration QtQuick2::Locale::firstDayOfWeek
+ \qmlproperty enumeration QtQml2::Locale::firstDayOfWeek
Holds the first day of the week according to the current locale.
@@ -986,7 +988,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlproperty Array<int> QtQuick2::Locale::weekDays
+ \qmlproperty Array<int> QtQml2::Locale::weekDays
Holds an array of days that are considered week days according to the current locale,
where Sunday is 0 and Saturday is 6.
@@ -995,7 +997,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlproperty Array<string> QtQuick2::Locale::uiLanguages
+ \qmlproperty Array<string> QtQml2::Locale::uiLanguages
Returns an ordered list of locale names for translation purposes in
preference order.
@@ -1007,7 +1009,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlproperty enumeration QtQuick2::Locale::textDirection
+ \qmlproperty enumeration QtQml2::Locale::textDirection
Holds the text direction of the language:
\list
@@ -1017,19 +1019,19 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlproperty string QtQuick2::Locale::amText
+ \qmlproperty string QtQml2::Locale::amText
The localized name of the "AM" suffix for times specified using the conventions of the 12-hour clock.
*/
/*!
- \qmlproperty string QtQuick2::Locale::pmText
+ \qmlproperty string QtQml2::Locale::pmText
The localized name of the "PM" suffix for times specified using the conventions of the 12-hour clock.
*/
/*!
- \qmlmethod string QtQuick2::Locale::currencySymbol(format)
+ \qmlmethod string QtQml2::Locale::currencySymbol(format)
Returns the currency symbol for the specified \a format:
\list
@@ -1041,7 +1043,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlproperty string QtQuick2::Locale::nativeLanguageName
+ \qmlproperty string QtQml2::Locale::nativeLanguageName
Holds a native name of the language for the locale. For example
"Schwiizertüütsch" for Swiss-German locale.
@@ -1050,7 +1052,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlproperty string QtQuick2::Locale::nativeCountryName
+ \qmlproperty string QtQml2::Locale::nativeCountryName
Holds a native name of the country for the locale. For example
"España" for Spanish/Spain locale.
@@ -1059,7 +1061,7 @@ QV4::Value QQmlLocale::localeCompare(QV4::SimpleCallContext *ctx)
*/
/*!
- \qmlproperty enumeration QtQuick2::Locale::measurementSystem
+ \qmlproperty enumeration QtQml2::Locale::measurementSystem
This property defines which units are used for measurement.
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 3bc8b6096e..8075bd462f 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -58,13 +58,13 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static QV4::Value toLocaleString(QV4::SimpleCallContext *ctx);
- static QV4::Value toLocaleTimeString(QV4::SimpleCallContext *ctx);
- static QV4::Value toLocaleDateString(QV4::SimpleCallContext *ctx);
- static QV4::Value fromLocaleString(QV4::SimpleCallContext *ctx);
- static QV4::Value fromLocaleTimeString(QV4::SimpleCallContext *ctx);
- static QV4::Value fromLocaleDateString(QV4::SimpleCallContext *ctx);
- static QV4::Value timeZoneUpdated(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_toLocaleString(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_toLocaleTimeString(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_toLocaleDateString(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_fromLocaleString(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_fromLocaleTimeString(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_fromLocaleDateString(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_timeZoneUpdated(QV4::SimpleCallContext *ctx);
};
@@ -74,9 +74,9 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static QV4::Value toLocaleString(QV4::SimpleCallContext *ctx);
- static QV4::Value fromLocaleString(QV4::SimpleCallContext *ctx);
- static QV4::Value toLocaleCurrencyString(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_toLocaleString(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_fromLocaleString(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_toLocaleCurrencyString(QV4::SimpleCallContext *ctx);
};
@@ -118,14 +118,14 @@ public:
Saturday = Qt::Saturday
};
- static QV4::Value locale(QV8Engine *v8engine, const QString &lang);
+ static QV4::ReturnedValue locale(QV8Engine *v8engine, const QString &lang);
static void registerStringLocaleCompare(QV4::ExecutionEngine *engine);
private:
QQmlLocale();
- static QV4::Value localeCompare(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_localeCompare(QV4::SimpleCallContext *ctx);
};
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index f3b4d6b1e5..f9583e7a59 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -112,12 +112,15 @@ class QQmlTypeModulePrivate
{
public:
QQmlTypeModulePrivate()
- : minMinorVersion(INT_MAX), maxMinorVersion(0) {}
+ : minMinorVersion(INT_MAX), maxMinorVersion(0), locked(false) {}
+
+ static QQmlTypeModulePrivate* get(QQmlTypeModule* q) { return q->d; }
QQmlMetaTypeData::VersionedUri uri;
int minMinorVersion;
int maxMinorVersion;
+ bool locked;
void add(QQmlType *);
@@ -1126,7 +1129,7 @@ QString registrationTypeString(QQmlType::RegistrationType typeType)
}
// NOTE: caller must hold a QWriteLocker on "data"
-bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, const char *uri, const QString &typeName)
+bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, const char *uri, const QString &typeName, int majorVersion = -1)
{
if (!typeName.isEmpty()) {
int typeNameLen = typeName.length();
@@ -1158,6 +1161,18 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace));
return false;
}
+ } else if (majorVersion >= 0) {
+ QQmlMetaTypeData::VersionedUri versionedUri;
+ versionedUri.uri = nameSpace;
+ versionedUri.majorVersion = majorVersion;
+ if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)){
+ if (QQmlTypeModulePrivate::get(qqtm)->locked){
+ QString failure(QCoreApplication::translate("qmlRegisterType",
+ "Cannot install %1 '%2' into protected module '%3' version '%4'"));
+ data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace).arg(majorVersion));
+ return false;
+ }
+ }
}
}
@@ -1206,7 +1221,7 @@ int registerType(const QQmlPrivate::RegisterType &type)
QWriteLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString elementName = QString::fromUtf8(type.elementName);
- if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName))
+ if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName, type.versionMajor))
return -1;
int index = data->types.count();
@@ -1226,7 +1241,7 @@ int registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
QWriteLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString typeName = QString::fromUtf8(type.typeName);
- if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName))
+ if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName, type.versionMajor))
return -1;
int index = data->types.count();
@@ -1248,7 +1263,7 @@ int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type)
bool fileImport = false;
if (*(type.uri) == '\0')
fileImport = true;
- if (!checkRegistration(QQmlType::CompositeType, data, fileImport?0:type.uri, typeName))
+ if (!checkRegistration(QQmlType::CompositeType, data, fileImport?0:type.uri, typeName, type.versionMajor))
return -1;
int index = data->types.count();
@@ -1284,6 +1299,23 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
return -1;
}
+//From qqml.h
+bool qmlProtectModule(const char *uri, int majVersion)
+{
+ QWriteLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+
+ QQmlMetaTypeData::VersionedUri versionedUri;
+ versionedUri.uri = QString::fromUtf8(uri);
+ versionedUri.majorVersion = majVersion;
+
+ if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0)) {
+ QQmlTypeModulePrivate::get(qqtm)->locked = true;
+ return true;
+ }
+ return false;
+}
+
bool QQmlMetaType::namespaceContainsRegistrations(const QString &uri)
{
QQmlMetaTypeData *data = metaTypeData();
@@ -1342,6 +1374,22 @@ bool QQmlMetaType::isAnyModule(const QString &uri)
}
/*
+ Returns true if a module \a uri of this version is installed and locked;
+*/
+bool QQmlMetaType::isLockedModule(const QString &uri, int majVersion)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+
+ QQmlMetaTypeData::VersionedUri versionedUri;
+ versionedUri.uri = uri;
+ versionedUri.majorVersion = majVersion;
+ if (QQmlTypeModule* qqtm = data->uriToModule.value(versionedUri, 0))
+ return QQmlTypeModulePrivate::get(qqtm)->locked;
+ return false;
+}
+
+/*
Returns true if any type or API has been registered for the given \a module with at least
versionMajor.versionMinor, or if types have been registered for \a module with at most
versionMajor.versionMinor.
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index e44eade902..f747049f11 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -113,6 +113,7 @@ public:
static StringConverter customStringConverter(int);
static bool isAnyModule(const QString &uri);
+ static bool isLockedModule(const QString &uri, int majorVersion);
static bool isModule(const QString &module, int versionMajor, int versionMinor);
static QQmlTypeModule *typeModule(const QString &uri, int majorVersion);
@@ -227,7 +228,7 @@ private:
CompositeType = 3
};
friend QString registrationTypeString(RegistrationType);
- friend bool checkRegistration(RegistrationType, QQmlMetaTypeData *, const char *, const QString &);
+ friend bool checkRegistration(RegistrationType, QQmlMetaTypeData *, const char *, const QString &, int);
friend int registerType(const QQmlPrivate::RegisterType &);
friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
friend int registerInterface(const QQmlPrivate::RegisterInterface &);
@@ -262,6 +263,7 @@ private:
friend void addTypeToData(QQmlType* type, QQmlMetaTypeData *data);
friend struct QQmlMetaTypeData;
friend Q_QML_EXPORT void qmlClearTypeRegistrations();
+ friend class QQmlTypeModulePrivate;
QQmlTypeModule();
~QQmlTypeModule();
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index cca4bb7dac..7ef84fe1c8 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -578,10 +578,11 @@ QObject *QmlObjectCreator::create(int index, QObject *parent)
_ddata->propertyCache->addref();
}
- QV4::Value scopeObject = QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _qobject);
+ QV4::Scope scope(QV8Engine::getV4(engine));
+ QV4::ScopedValue scopeObject(scope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _qobject));
- QVector<QQmlAbstractBinding*> dynamicBindings = setupBindings(scopeObject.asObject());
- setupFunctions(scopeObject.asObject());
+ QVector<QQmlAbstractBinding*> dynamicBindings = setupBindings(scopeObject->asObject());
+ setupFunctions(scopeObject->asObject());
// ### do this later when requested
for (int i = 0; i < dynamicBindings.count(); ++i) {
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index cf1b5ffd18..f821687f63 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1497,7 +1497,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
break;
case QMetaType::QString:
if (result.isString())
- QUICK_STORE(QString, result.toQString())
+ QUICK_STORE(QString, result.toQStringNoThrow())
break;
default:
break;
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index a1385e06fc..e498ca5dee 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -56,6 +56,7 @@
#include <ctype.h> // for toupper
#include <limits.h>
+#include <algorithm>
#ifdef Q_CC_MSVC
// nonstandard extension used : zero-sized array in struct/union.
@@ -1507,8 +1508,8 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder)
Q_ASSERT(properties.count() == propertyIndexCache.count());
Q_ASSERT(methods.count() == methodIndexCache.count());
- qSort(properties.begin(), properties.end(), Sort::lt);
- qSort(methods.begin(), methods.end(), Sort::lt);
+ std::sort(properties.begin(), properties.end(), Sort::lt);
+ std::sort(methods.begin(), methods.end(), Sort::lt);
for (int ii = 0; ii < properties.count(); ++ii) {
QQmlPropertyData *data = properties.at(ii).second;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index e1f96442b1..810347fd03 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "qqmltypeloader_p.h"
-#include "qqmlabstracturlinterceptor_p.h"
+#include "qqmlabstracturlinterceptor.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
@@ -1252,7 +1252,13 @@ bool QQmlTypeLoader::Blob::addImport(const QQmlScript::Import &import, QList<QQm
QString qmldirFilePath;
QString qmldirUrl;
- if (m_imports.locateQmldir(importDatabase, import.uri, import.majorVersion, import.minorVersion,
+ if (QQmlMetaType::isLockedModule(import.uri, import.majorVersion)) {
+ //Locked modules are checked first, to save on filesystem checks
+ if (!m_imports.addLibraryImport(importDatabase, import.uri, import.qualifier, import.majorVersion,
+ import.minorVersion, QString(), QString(), false, errors))
+ return false;
+
+ } else if (m_imports.locateQmldir(importDatabase, import.uri, import.majorVersion, import.minorVersion,
&qmldirFilePath, &qmldirUrl)) {
// This is a local library import
if (!m_imports.addLibraryImport(importDatabase, import.uri, import.qualifier, import.majorVersion,
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index c77c5b1a8d..f86c037f93 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -59,6 +59,7 @@
#include <QtQml/qqmlerror.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlfile.h>
+#include <QtQml/qqmlabstracturlinterceptor.h>
#include <private/qhashedstring_p.h>
#include <private/qqmlscript_p.h>
@@ -67,7 +68,6 @@
#include <private/qqmldirparser_p.h>
#include <private/qqmlbundle_p.h>
#include <private/qflagpointer_p.h>
-#include <private/qqmlabstracturlinterceptor_p.h>
#include <private/qqmlcodegenerator_p.h>
#include <private/qv4value_p.h>
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 33b8fb8e7a..09ef732e2d 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -87,19 +87,19 @@ QVariant QmlTypeWrapper::toVariant() const
// Returns a type wrapper for type t on o. This allows access of enums, and attached properties.
-Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlType *t, TypeNameMode mode)
+ReturnedValue QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlType *t, TypeNameMode mode)
{
Q_ASSERT(t);
ExecutionEngine *v4 = QV8Engine::getV4(v8);
QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8);
w->mode = mode; w->object = o; w->type = t;
- return Value::fromObject(w);
+ return Value::fromObject(w).asReturnedValue();
}
// Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a
// namespace.
-Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, const void *importNamespace, TypeNameMode mode)
+ReturnedValue QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, const void *importNamespace, TypeNameMode mode)
{
Q_ASSERT(t);
Q_ASSERT(importNamespace);
@@ -108,17 +108,20 @@ Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, co
QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8);
w->mode = mode; w->object = o; w->typeNamespace = t; w->importNamespace = importNamespace;
t->addref();
- return Value::fromObject(w);
+ return Value::fromObject(w).asReturnedValue();
}
-Value QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
{
- QmlTypeWrapper *w = m->as<QmlTypeWrapper>();
QV4::ExecutionEngine *v4 = m->engine();
+ QV4::Scope scope(v4);
+
+ QmlTypeWrapper *w = m->as<QmlTypeWrapper>();
if (!w)
v4->current->throwTypeError();
+
if (hasProperty)
*hasProperty = true;
@@ -149,7 +152,7 @@ Value QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
bool ok;
int value = e.keyToValue(enumName.constData(), &ok);
if (ok)
- return QV4::Value::fromInt32(value);
+ return QV4::Value::fromInt32(value).asReturnedValue();
}
}
}
@@ -159,8 +162,8 @@ Value QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
} else if (!siinfo->scriptApi(e).isUndefined()) {
QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine);
// NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable.
- QV4::Object *o = QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine).asObject();
- if (o)
+ QV4::Scoped<Object> o(scope, QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine));
+ if (!!o)
return o->get(name);
}
@@ -172,7 +175,7 @@ Value QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
bool ok = false;
int value = type->enumValue(name, &ok);
if (ok)
- return QV4::Value::fromInt32(value);
+ return QV4::Value::fromInt32(value).asReturnedValue();
// Fall through to base implementation
@@ -200,12 +203,12 @@ Value QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
} else if (r.scriptIndex != -1) {
int index = r.scriptIndex;
if (index < context->importedScripts.count())
- return context->importedScripts.at(index).value();
+ return context->importedScripts.at(index).value().asReturnedValue();
} else if (r.importNamespace) {
return create(w->v8, object, context->imports, r.importNamespace);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index 944621b1d6..acf6845736 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -78,11 +78,11 @@ public:
QVariant toVariant() const;
- static QV4::Value create(QV8Engine *, QObject *, QQmlType *, TypeNameMode = IncludeEnums);
- static QV4::Value create(QV8Engine *, QObject *, QQmlTypeNameCache *, const void *, TypeNameMode = IncludeEnums);
+ static ReturnedValue create(QV8Engine *, QObject *, QQmlType *, TypeNameMode = IncludeEnums);
+ static ReturnedValue create(QV8Engine *, QObject *, QQmlTypeNameCache *, const void *, TypeNameMode = IncludeEnums);
- static Value get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static PropertyAttributes query(const Managed *, String *name);
static void destroy(Managed *that);
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index f494fba11f..f89ce15a57 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -139,7 +139,7 @@ void QmlValueTypeWrapper::initProto(ExecutionEngine *v4)
v4->qmlExtensions()->valueTypeWrapperPrototype = o;
}
-Value QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type)
+ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type)
{
ExecutionEngine *v4 = QV8Engine::getV4(v8);
initProto(v4);
@@ -147,10 +147,10 @@ Value QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property,
QmlValueTypeReference *r = new (v4->memoryManager) QmlValueTypeReference(v8);
r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->type = type; r->object = object; r->property = property;
- return Value::fromObject(r);
+ return Value::fromObject(r).asReturnedValue();
}
-Value QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValueType *type)
+ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValueType *type)
{
ExecutionEngine *v4 = QV8Engine::getV4(v8);
initProto(v4);
@@ -158,7 +158,7 @@ Value QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValu
QmlValueTypeCopy *r = new (v4->memoryManager) QmlValueTypeCopy(v8);
r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->type = type; r->value = value;
- return Value::fromObject(r);
+ return Value::fromObject(r).asReturnedValue();
}
QVariant QmlValueTypeWrapper::toVariant() const
@@ -239,7 +239,7 @@ bool QmlValueTypeWrapper::isEqual(const QVariant& value)
}
}
-Value QmlValueTypeWrapper::method_toString(SimpleCallContext *ctx)
+ReturnedValue QmlValueTypeWrapper::method_toString(SimpleCallContext *ctx)
{
Object *o = ctx->thisObject.asObject();
if (!o)
@@ -251,19 +251,19 @@ Value QmlValueTypeWrapper::method_toString(SimpleCallContext *ctx)
if (w->objectType == QmlValueTypeWrapper::Reference) {
QmlValueTypeReference *reference = static_cast<QmlValueTypeReference *>(w);
if (reference->object && readReferenceValue(reference)) {
- return w->v8->toString(w->type->toString());
+ return w->v8->toString(w->type->toString()).asReturnedValue();
} else {
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
} else {
Q_ASSERT(w->objectType == QmlValueTypeWrapper::Copy);
QmlValueTypeCopy *copy = static_cast<QmlValueTypeCopy *>(w);
w->type->setValue(copy->value);
- return w->v8->toString(w->type->toString());
+ return w->v8->toString(w->type->toString()).asReturnedValue();
}
}
-Value QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
{
QmlValueTypeWrapper *r = m->as<QmlValueTypeWrapper>();
QV4::ExecutionEngine *v4 = m->engine();
@@ -275,7 +275,7 @@ Value QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
QmlValueTypeReference *reference = static_cast<QmlValueTypeReference *>(r);
if (!reference->object || !readReferenceValue(reference))
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
} else {
Q_ASSERT(r->objectType == QmlValueTypeWrapper::Copy);
@@ -309,7 +309,7 @@ Value QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
cpptype v; \
void *args[] = { &v, 0 }; \
r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \
- return constructor(v); \
+ return constructor(v).asReturnedValue(); \
}
// These four types are the most common used by the value type wrappers
@@ -327,14 +327,15 @@ Value QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
void QmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
{
- QmlValueTypeWrapper *r = m->as<QmlValueTypeWrapper>();
ExecutionEngine *v4 = m->engine();
+ Scope scope(v4);
+ Scoped<QmlValueTypeWrapper> r(scope, m->as<QmlValueTypeWrapper>());
if (!r)
v4->current->throwTypeError();
QByteArray propName = name->toQString().toUtf8();
if (r->objectType == QmlValueTypeWrapper::Reference) {
- QmlValueTypeReference *reference = static_cast<QmlValueTypeReference *>(r);
+ QmlValueTypeReference *reference = static_cast<QmlValueTypeReference *>(r.getPointer());
QMetaProperty writebackProperty = reference->object->metaObject()->property(reference->property);
if (!reference->object || !writebackProperty.isWritable() || !readReferenceValue(reference))
@@ -353,7 +354,8 @@ void QmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
if (!f->bindingKeyFlag) {
// assigning a JS function to a non-var-property is not allowed.
QString error = QLatin1String("Cannot assign JavaScript function to value-type property");
- v4->current->throwError(r->v8->toString(error));
+ Scoped<String> e(scope, r->v8->toString(error));
+ v4->current->throwError(e);
}
QQmlContextData *context = r->v8->callingContext();
@@ -400,7 +402,7 @@ void QmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
} else {
Q_ASSERT(r->objectType == QmlValueTypeWrapper::Copy);
- QmlValueTypeCopy *copy = static_cast<QmlValueTypeCopy *>(r);
+ QmlValueTypeCopy *copy = static_cast<QmlValueTypeCopy *>(r.getPointer());
int index = r->type->metaObject()->indexOfProperty(propName.constData());
if (index == -1)
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index f5088a5954..355000bb39 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -76,20 +76,20 @@ protected:
public:
- static Value create(QV8Engine *v8, QObject *, int, QQmlValueType *);
- static Value create(QV8Engine *v8, const QVariant &, QQmlValueType *);
+ static ReturnedValue create(QV8Engine *v8, QObject *, int, QQmlValueType *);
+ static ReturnedValue create(QV8Engine *v8, const QVariant &, QQmlValueType *);
QVariant toVariant() const;
bool isEqual(const QVariant& value);
- static Value get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static void destroy(Managed *that);
static bool isEqualTo(Managed *m, Managed *other);
static PropertyAttributes query(const Managed *, String *name);
- static QV4::Value method_toString(SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_toString(SimpleCallContext *ctx);
QV8Engine *v8;
ObjectType objectType;
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index e32193e6f6..1a6577d7ad 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -372,7 +372,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
// Store a created object in a property. These all pop from the objects stack.
QML_STORE_VALUE(StoreObject, QObject *, objects.pop());
QML_STORE_VALUE(StoreVariantObject, QVariant, QVariant::fromValue(objects.pop()));
- QML_STORE_VAR(StoreVarObject, QV4::QObjectWrapper::wrap(ep->v4engine(), objects.pop()));
+ QML_STORE_VAR(StoreVarObject, QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(ep->v4engine(), objects.pop())));
// Store a literal value in a corresponding property
QML_STORE_VALUE(StoreFloat, float, instr.value);
@@ -420,7 +420,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
// Store a literal value in a var property.
// We deliberately do not use string converters here
- QML_STORE_VAR(StoreVar, ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value)));
+ QML_STORE_VAR(StoreVar, QV4::Value::fromReturnedValue(ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value))));
QML_STORE_VAR(StoreVarInteger, QV4::Value::fromInt32(instr.value));
QML_STORE_VAR(StoreVarDouble, QV4::Value::fromDouble(instr.value));
QML_STORE_VAR(StoreVarBool, QV4::Value::fromBoolean(instr.value));
@@ -1113,6 +1113,8 @@ QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *s
Q_ASSERT(parentCtxt && parentCtxt->engine);
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine);
QV8Engine *v8engine = ep->v8engine();
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(parentCtxt->engine);
+ QV4::Scope scope(v4);
if (script->hasError()) {
ep->warning(script->error());
@@ -1178,7 +1180,7 @@ QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *s
return QV4::PersistentValue();
}
- QV4::Value qmlglobal = QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0);
+ QV4::ScopedValue qmlglobal(scope, QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0));
QV4::QmlContextWrapper::takeContextOwnership(qmlglobal);
QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->current;
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 0079b9580f..6739143979 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -911,8 +911,10 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(ctxt->engine);
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
+ QV4::Scope scope(ep->v4engine());
- QV4::FunctionObject *function = method(id).asFunctionObject();
+
+ QV4::Scoped<QV4::FunctionObject> function(scope, method(id));
if (!function) {
// The function was not compiled. There are some exceptional cases which the
// expression rewriter does not rewrite properly (e.g., \r-terminated lines
@@ -927,13 +929,13 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
QQmlVMEMetaData::MethodData *data = metaData->methodData() + id;
- QV4::ScopedCallData callData(function->engine(), data->parameterCount);
+ QV4::ScopedCallData callData(scope, data->parameterCount);
callData->thisObject = ep->v8engine()->global();
for (int ii = 0; ii < data->parameterCount; ++ii)
- callData->args[ii] = ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1]);
+ callData->args[ii] = QV4::Value::fromReturnedValue(ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1]));
- QV4::Value result = QV4::Value::undefinedValue();
+ QV4::ScopedValue result(scope);
QV4::ExecutionContext *ctx = function->engine()->current;
try {
result = function->call(callData);
@@ -960,11 +962,11 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
return object->qt_metacall(c, _id, a);
}
-QV4::Value QQmlVMEMetaObject::method(int index)
+QV4::ReturnedValue QQmlVMEMetaObject::method(int index)
{
if (!ctxt || !ctxt->isValid()) {
qWarning("QQmlVMEMetaObject: Internal error - attempted to evaluate a function in an invalid context");
- return QV4::Value::emptyValue();
+ return QV4::Value::emptyValue().asReturnedValue();
}
if (!v8methods)
@@ -983,16 +985,16 @@ QV4::Value QQmlVMEMetaObject::method(int index)
ctxt->urlString, data->lineNumber);
}
- return v8methods[index];
+ return v8methods[index].value().asReturnedValue();
}
-QV4::Value QQmlVMEMetaObject::readVarProperty(int id)
+QV4::ReturnedValue QQmlVMEMetaObject::readVarProperty(int id)
{
Q_ASSERT(id >= firstVarPropertyIndex);
if (ensureVarPropertiesAllocated())
return varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex);
- return QV4::Value::emptyValue();
+ return QV4::Value::emptyValue().asReturnedValue();
}
QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id)
@@ -1000,7 +1002,7 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id)
if (id >= firstVarPropertyIndex) {
if (ensureVarPropertiesAllocated())
return QQmlEnginePrivate::get(ctxt->engine)->v8engine()->toVariant(
- varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex), -1);
+ QV4::Value::fromReturnedValue(varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex)), -1);
return QVariant();
} else {
if (data[id].dataType() == QMetaType::QObjectStar) {
@@ -1017,11 +1019,12 @@ void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
if (!ensureVarPropertiesAllocated())
return;
+ QV4::Scope scope(varProperties.engine());
// Importantly, if the current value is a scarce resource, we need to ensure that it
// gets automatically released by the engine if no other references to it exist.
- QV4::Value oldv = varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex);
- if (QV4::VariantObject *v = oldv.as<QV4::VariantObject>())
- v->removeVmePropertyReference();
+ QV4::Scoped<QV4::VariantObject> oldv(scope, varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex));
+ if (!!oldv)
+ oldv->removeVmePropertyReference();
QObject *valueObject = 0;
QQmlVMEVariantQObjectPtr *guard = getQObjectGuardForProperty(id);
@@ -1058,16 +1061,18 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
if (!ensureVarPropertiesAllocated())
return;
+ QV4::Scope scope(varProperties.engine());
+
// Importantly, if the current value is a scarce resource, we need to ensure that it
// gets automatically released by the engine if no other references to it exist.
- QV4::Value oldv = varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex);
- if (QV4::VariantObject *v = oldv.as<QV4::VariantObject>())
- v->removeVmePropertyReference();
+ QV4::Scoped<QV4::VariantObject> oldv(scope, varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex));
+ if (!!oldv)
+ oldv->removeVmePropertyReference();
// And, if the new value is a scarce resource, we need to ensure that it does not get
// automatically released by the engine until no other references to it exist.
- QV4::Value newv = QQmlEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value);
- if (QV4::VariantObject *v = newv.as<QV4::VariantObject>())
+ QV4::ScopedValue newv(scope, QQmlEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value));
+ if (QV4::VariantObject *v = newv->as<QV4::VariantObject>())
v->addVmePropertyReference();
// Write the value and emit change signal as appropriate.
@@ -1146,7 +1151,7 @@ quint16 QQmlVMEMetaObject::vmeMethodLineNumber(int index)
return data->lineNumber;
}
-QV4::Value QQmlVMEMetaObject::vmeMethod(int index)
+QV4::ReturnedValue QQmlVMEMetaObject::vmeMethod(int index)
{
if (index < methodOffset()) {
Q_ASSERT(parentVMEMetaObject());
@@ -1174,7 +1179,7 @@ void QQmlVMEMetaObject::setVmeMethod(int index, QV4::PersistentValue function)
v8methods[methodIndex] = function;
}
-QV4::Value QQmlVMEMetaObject::vmeProperty(int index)
+QV4::ReturnedValue QQmlVMEMetaObject::vmeProperty(int index)
{
if (index < propOffset()) {
Q_ASSERT(parentVMEMetaObject());
@@ -1240,7 +1245,8 @@ void QQmlVMEMetaObject::allocateVarPropertiesArray()
QQmlEngine *qml = qmlEngine(object);
assert(qml);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(qml->handle());
- varProperties = QV4::Value::fromObject(v4->newArrayObject(metaData->varPropertyCount));
+ QV4::Scope scope(v4);
+ varProperties = QV4::ScopedValue(scope, v4->newArrayObject(metaData->varPropertyCount));
varPropertiesInitialized = true;
}
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index 9824e0d54b..35592c4906 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -164,10 +164,10 @@ public:
bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const;
void registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor);
- QV4::Value vmeMethod(int index);
+ QV4::ReturnedValue vmeMethod(int index);
quint16 vmeMethodLineNumber(int index);
void setVmeMethod(int index, QV4::PersistentValue function);
- QV4::Value vmeProperty(int index);
+ QV4::ReturnedValue vmeProperty(int index);
void setVMEProperty(int index, const QV4::Value &v);
void connectAliasSignal(int index, bool indexInSignalRange);
@@ -217,9 +217,9 @@ public:
QQmlPropertyValueInterceptor *interceptors;
QV4::PersistentValue *v8methods;
- QV4::Value method(int);
+ QV4::ReturnedValue method(int);
- QV4::Value readVarProperty(int);
+ QV4::ReturnedValue readVarProperty(int);
void writeVarProperty(int, const QV4::Value &);
QVariant readPropertyAsVariant(int);
void writeProperty(int, const QVariant &);
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index ddc7a4894b..dc98bd176e 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -70,8 +70,10 @@ using namespace QV4;
#ifndef QT_NO_XMLSTREAMREADER
-#define V4THROW_REFERENCE(string) \
- ctx->throwError(Value::fromObject(ctx->engine->newReferenceErrorObject(QStringLiteral(string))))
+#define V4THROW_REFERENCE(string) { \
+ Scoped<Object> error(scope, ctx->engine->newReferenceErrorObject(QStringLiteral(string))); \
+ ctx->throwError(error); \
+ }
QT_BEGIN_NAMESPACE
@@ -100,9 +102,11 @@ static inline QQmlXMLHttpRequestData *xhrdata(QV8Engine *engine)
static Value constructMeObject(const Value &thisObj, QV8Engine *e)
{
ExecutionEngine *v4 = QV8Engine::getV4(e);
+ Scope scope(v4);
Object *meObj = v4->newObject();
meObj->put(v4->newString(QStringLiteral("ThisObject")), thisObj);
- meObj->put(v4->newString(QStringLiteral("ActivationObject")), QmlContextWrapper::qmlScope(e, e->callingContext(), 0));
+ ScopedValue v(scope, QmlContextWrapper::qmlScope(e, e->callingContext(), 0));
+ meObj->put(v4->newString(QStringLiteral("ActivationObject")), v);
return Value::fromObject(meObj);
}
@@ -204,8 +208,8 @@ public:
static void destroy(Managed *that) {
that->as<NamedNodeMap>()->~NamedNodeMap();
}
- static Value get(Managed *m, String *name, bool *hasProperty);
- static Value getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
QList<NodeImpl *> list; // Only used in NamedNodeMap
NodeImpl *d;
@@ -235,8 +239,8 @@ public:
static void destroy(Managed *that) {
that->as<NodeList>()->~NodeList();
}
- static Value get(Managed *m, String *name, bool *hasProperty);
- static Value getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
// C++ API
static Value create(QV8Engine *, NodeImpl *);
@@ -270,17 +274,17 @@ public:
static void initClass(ExecutionEngine *engine);
// JS API
- static Value method_get_nodeName(SimpleCallContext *ctx);
- static Value method_get_nodeValue(SimpleCallContext *ctx);
- static Value method_get_nodeType(SimpleCallContext *ctx);
-
- static Value method_get_parentNode(SimpleCallContext *ctx);
- static Value method_get_childNodes(SimpleCallContext *ctx);
- static Value method_get_firstChild(SimpleCallContext *ctx);
- static Value method_get_lastChild(SimpleCallContext *ctx);
- static Value method_get_previousSibling(SimpleCallContext *ctx);
- static Value method_get_nextSibling(SimpleCallContext *ctx);
- static Value method_get_attributes(SimpleCallContext *ctx);
+ static ReturnedValue method_get_nodeName(SimpleCallContext *ctx);
+ static ReturnedValue method_get_nodeValue(SimpleCallContext *ctx);
+ static ReturnedValue method_get_nodeType(SimpleCallContext *ctx);
+
+ static ReturnedValue method_get_parentNode(SimpleCallContext *ctx);
+ static ReturnedValue method_get_childNodes(SimpleCallContext *ctx);
+ static ReturnedValue method_get_firstChild(SimpleCallContext *ctx);
+ static ReturnedValue method_get_lastChild(SimpleCallContext *ctx);
+ static ReturnedValue method_get_previousSibling(SimpleCallContext *ctx);
+ static ReturnedValue method_get_nextSibling(SimpleCallContext *ctx);
+ static ReturnedValue method_get_attributes(SimpleCallContext *ctx);
//static Value ownerDocument(SimpleCallContext *ctx);
//static Value namespaceURI(SimpleCallContext *ctx);
@@ -343,10 +347,10 @@ class Attr : public Node
{
public:
// JS API
- static Value name(SimpleCallContext *ctx);
+ static ReturnedValue method_name(SimpleCallContext *ctx);
// static Value specified(SimpleCallContext *);
- static Value value(SimpleCallContext *ctx);
- static Value ownerElement(SimpleCallContext *ctx);
+ static ReturnedValue method_value(SimpleCallContext *ctx);
+ static ReturnedValue method_ownerElement(SimpleCallContext *ctx);
// static Value schemaTypeInfo(SimpleCallContext *);
// static Value isId(SimpleCallContext *c);
@@ -358,7 +362,7 @@ class CharacterData : public Node
{
public:
// JS API
- static Value length(SimpleCallContext *ctx);
+ static ReturnedValue method_length(SimpleCallContext *ctx);
// C++ API
static Value prototype(ExecutionEngine *v4);
@@ -368,8 +372,8 @@ class Text : public CharacterData
{
public:
// JS API
- static Value isElementContentWhitespace(SimpleCallContext *ctx);
- static Value wholeText(SimpleCallContext *ctx);
+ static ReturnedValue method_isElementContentWhitespace(SimpleCallContext *ctx);
+ static ReturnedValue method_wholeText(SimpleCallContext *ctx);
// C++ API
static Value prototype(ExecutionEngine *);
@@ -386,14 +390,14 @@ class Document : public Node
{
public:
// JS API
- static Value xmlVersion(SimpleCallContext *ctx);
- static Value xmlEncoding(SimpleCallContext *ctx);
- static Value xmlStandalone(SimpleCallContext *ctx);
- static Value documentElement(SimpleCallContext *ctx);
+ static ReturnedValue method_xmlVersion(SimpleCallContext *ctx);
+ static ReturnedValue method_xmlEncoding(SimpleCallContext *ctx);
+ static ReturnedValue method_xmlStandalone(SimpleCallContext *ctx);
+ static ReturnedValue method_documentElement(SimpleCallContext *ctx);
// C++ API
static Value prototype(ExecutionEngine *);
- static Value load(QV8Engine *engine, const QByteArray &data);
+ static ReturnedValue load(QV8Engine *engine, const QByteArray &data);
};
}
@@ -408,7 +412,7 @@ void NodeImpl::release()
document->release();
}
-Value NodePrototype::method_get_nodeName(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_nodeName(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
@@ -429,10 +433,10 @@ Value NodePrototype::method_get_nodeName(SimpleCallContext *ctx)
name = r->d->name;
break;
}
- return Value::fromString(ctx->engine->newString(name));
+ return Value::fromString(ctx->engine->newString(name)).asReturnedValue();
}
-Value NodePrototype::method_get_nodeValue(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_nodeValue(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
@@ -445,21 +449,21 @@ Value NodePrototype::method_get_nodeValue(SimpleCallContext *ctx)
r->d->type == NodeImpl::Entity ||
r->d->type == NodeImpl::EntityReference ||
r->d->type == NodeImpl::Notation)
- return Value::nullValue();
+ return Encode::null();
- return Value::fromString(ctx->engine->newString(r->d->data));
+ return Value::fromString(ctx->engine->newString(r->d->data)).asReturnedValue();
}
-Value NodePrototype::method_get_nodeType(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_nodeType(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
ctx->throwTypeError();
- return Value::fromInt32(r->d->type);
+ return Encode(r->d->type);
}
-Value NodePrototype::method_get_parentNode(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_parentNode(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
@@ -467,11 +471,13 @@ Value NodePrototype::method_get_parentNode(SimpleCallContext *ctx)
QV8Engine *engine = ctx->engine->v8Engine;
- if (r->d->parent) return Node::create(engine, r->d->parent);
- else return Value::nullValue();
+ if (r->d->parent)
+ return Node::create(engine, r->d->parent).asReturnedValue();
+ else
+ return Encode::null();
}
-Value NodePrototype::method_get_childNodes(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_childNodes(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
@@ -479,10 +485,10 @@ Value NodePrototype::method_get_childNodes(SimpleCallContext *ctx)
QV8Engine *engine = ctx->engine->v8Engine;
- return NodeList::create(engine, r->d);
+ return NodeList::create(engine, r->d).asReturnedValue();
}
-Value NodePrototype::method_get_firstChild(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_firstChild(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
@@ -490,11 +496,13 @@ Value NodePrototype::method_get_firstChild(SimpleCallContext *ctx)
QV8Engine *engine = ctx->engine->v8Engine;
- if (r->d->children.isEmpty()) return Value::nullValue();
- else return Node::create(engine, r->d->children.first());
+ if (r->d->children.isEmpty())
+ return Encode::null();
+ else
+ return Node::create(engine, r->d->children.first()).asReturnedValue();
}
-Value NodePrototype::method_get_lastChild(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_lastChild(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
@@ -502,11 +510,13 @@ Value NodePrototype::method_get_lastChild(SimpleCallContext *ctx)
QV8Engine *engine = ctx->engine->v8Engine;
- if (r->d->children.isEmpty()) return Value::nullValue();
- else return Node::create(engine, r->d->children.last());
+ if (r->d->children.isEmpty())
+ return Encode::null();
+ else
+ return Node::create(engine, r->d->children.last()).asReturnedValue();
}
-Value NodePrototype::method_get_previousSibling(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_previousSibling(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
@@ -514,19 +524,22 @@ Value NodePrototype::method_get_previousSibling(SimpleCallContext *ctx)
QV8Engine *engine = ctx->engine->v8Engine;
- if (!r->d->parent) return Value::nullValue();
+ if (!r->d->parent)
+ return Encode::null();
for (int ii = 0; ii < r->d->parent->children.count(); ++ii) {
if (r->d->parent->children.at(ii) == r->d) {
- if (ii == 0) return Value::nullValue();
- else return Node::create(engine, r->d->parent->children.at(ii - 1));
+ if (ii == 0)
+ return Encode::null();
+ else
+ return Node::create(engine, r->d->parent->children.at(ii - 1)).asReturnedValue();
}
}
- return Value::nullValue();
+ return Encode::null();
}
-Value NodePrototype::method_get_nextSibling(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_nextSibling(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
@@ -534,19 +547,22 @@ Value NodePrototype::method_get_nextSibling(SimpleCallContext *ctx)
QV8Engine *engine = ctx->engine->v8Engine;
- if (!r->d->parent) return Value::nullValue();
+ if (!r->d->parent)
+ return Encode::null();
for (int ii = 0; ii < r->d->parent->children.count(); ++ii) {
if (r->d->parent->children.at(ii) == r->d) {
- if ((ii + 1) == r->d->parent->children.count()) return Value::nullValue();
- else return Node::create(engine, r->d->parent->children.at(ii + 1));
+ if ((ii + 1) == r->d->parent->children.count())
+ return Encode::null();
+ else
+ return Node::create(engine, r->d->parent->children.at(ii + 1)).asReturnedValue();
}
}
- return Value::nullValue();
+ return Encode::null();
}
-Value NodePrototype::method_get_attributes(SimpleCallContext *ctx)
+ReturnedValue NodePrototype::method_get_attributes(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
if (!r)
@@ -555,9 +571,9 @@ Value NodePrototype::method_get_attributes(SimpleCallContext *ctx)
QV8Engine *engine = ctx->engine->v8Engine;
if (r->d->type != NodeImpl::Element)
- return Value::nullValue();
+ return Encode::null();
else
- return NamedNodeMap::create(engine, r->d, r->d->attributes);
+ return NamedNodeMap::create(engine, r->d, r->d->attributes).asReturnedValue();
}
Value NodePrototype::getProto(ExecutionEngine *v4)
@@ -624,49 +640,53 @@ Value Attr::prototype(ExecutionEngine *engine)
if (d->attrPrototype.isEmpty()) {
Object *p = engine->newObject();
p->setPrototype(NodePrototype::getProto(engine).asObject());
- p->defineAccessorProperty(engine, QStringLiteral("name"), name, 0);
- p->defineAccessorProperty(engine, QStringLiteral("value"), value, 0);
- p->defineAccessorProperty(engine, QStringLiteral("ownerElement"), ownerElement, 0);
+ p->defineAccessorProperty(engine, QStringLiteral("name"), method_name, 0);
+ p->defineAccessorProperty(engine, QStringLiteral("value"), method_value, 0);
+ p->defineAccessorProperty(engine, QStringLiteral("ownerElement"), method_ownerElement, 0);
d->attrPrototype = Value::fromObject(p);
engine->v8Engine->freezeObject(d->attrPrototype.value());
}
return d->attrPrototype.value();
}
-Value Attr::name(SimpleCallContext *ctx)
+ReturnedValue Attr::method_name(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r) return Value::undefinedValue();
+ if (!r)
+ return Encode::undefined();
QV8Engine *engine = ctx->engine->v8Engine;
- return engine->toString(r->d->name);
+ return engine->toString(r->d->name).asReturnedValue();
}
-Value Attr::value(SimpleCallContext *ctx)
+ReturnedValue Attr::method_value(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r) return Value::undefinedValue();
+ if (!r)
+ return Encode::undefined();
QV8Engine *engine = ctx->engine->v8Engine;
- return engine->toString(r->d->data);
+ return engine->toString(r->d->data).asReturnedValue();
}
-Value Attr::ownerElement(SimpleCallContext *ctx)
+ReturnedValue Attr::method_ownerElement(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r) return Value::undefinedValue();
+ if (!r)
+ return Encode::undefined();
QV8Engine *engine = ctx->engine->v8Engine;
- return Node::create(engine, r->d->parent);
+ return Node::create(engine, r->d->parent).asReturnedValue();
}
-Value CharacterData::length(SimpleCallContext *ctx)
+ReturnedValue CharacterData::method_length(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r) return Value::undefinedValue();
+ if (!r)
+ return Encode::undefined();
QV8Engine *engine = ctx->engine->v8Engine;
Q_UNUSED(engine)
- return Value::fromInt32(r->d->data.length());
+ return Encode(r->d->data.length());
}
Value CharacterData::prototype(ExecutionEngine *v4)
@@ -676,28 +696,29 @@ Value CharacterData::prototype(ExecutionEngine *v4)
Object *p = v4->newObject();
p->setPrototype(NodePrototype::getProto(v4).asObject());
p->defineAccessorProperty(v4, QStringLiteral("data"), NodePrototype::method_get_nodeValue, 0);
- p->defineAccessorProperty(v4, QStringLiteral("length"), length, 0);
+ p->defineAccessorProperty(v4, QStringLiteral("length"), method_length, 0);
d->characterDataPrototype = Value::fromObject(p);
v4->v8Engine->freezeObject(d->characterDataPrototype);
}
return d->characterDataPrototype.value();
}
-Value Text::isElementContentWhitespace(SimpleCallContext *ctx)
+ReturnedValue Text::method_isElementContentWhitespace(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r) return Value::undefinedValue();
+ if (!r) return Encode::undefined();
- return Value::fromBoolean(r->d->data.trimmed().isEmpty());
+ return Encode(r->d->data.trimmed().isEmpty());
}
-Value Text::wholeText(SimpleCallContext *ctx)
+ReturnedValue Text::method_wholeText(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r) return Value::undefinedValue();
+ if (!r)
+ return Encode::undefined();
QV8Engine *engine = ctx->engine->v8Engine;
- return engine->toString(r->d->data);
+ return engine->toString(r->d->data).asReturnedValue();
}
Value Text::prototype(ExecutionEngine *v4)
@@ -706,8 +727,8 @@ Value Text::prototype(ExecutionEngine *v4)
if (d->textPrototype.isEmpty()) {
Object *p = v4->newObject();
p->setPrototype(CharacterData::prototype(v4).asObject());
- p->defineAccessorProperty(v4, QStringLiteral("isElementContentWhitespace"), isElementContentWhitespace, 0);
- p->defineAccessorProperty(v4, QStringLiteral("wholeText"), wholeText, 0);
+ p->defineAccessorProperty(v4, QStringLiteral("isElementContentWhitespace"), method_isElementContentWhitespace, 0);
+ p->defineAccessorProperty(v4, QStringLiteral("wholeText"), method_wholeText, 0);
d->textPrototype = Value::fromObject(p);
v4->v8Engine->freezeObject(d->textPrototype);
}
@@ -733,17 +754,17 @@ Value Document::prototype(ExecutionEngine *v4)
if (d->documentPrototype.isEmpty()) {
Object *p = v4->newObject();
p->setPrototype(NodePrototype::getProto(v4).asObject());
- p->defineAccessorProperty(v4, QStringLiteral("xmlVersion"), xmlVersion, 0);
- p->defineAccessorProperty(v4, QStringLiteral("xmlEncoding"), xmlEncoding, 0);
- p->defineAccessorProperty(v4, QStringLiteral("xmlStandalone"), xmlStandalone, 0);
- p->defineAccessorProperty(v4, QStringLiteral("documentElement"), documentElement, 0);
+ p->defineAccessorProperty(v4, QStringLiteral("xmlVersion"), method_xmlVersion, 0);
+ p->defineAccessorProperty(v4, QStringLiteral("xmlEncoding"), method_xmlEncoding, 0);
+ p->defineAccessorProperty(v4, QStringLiteral("xmlStandalone"), method_xmlStandalone, 0);
+ p->defineAccessorProperty(v4, QStringLiteral("documentElement"), method_documentElement, 0);
d->documentPrototype = Value::fromObject(p);
v4->v8Engine->freezeObject(d->documentPrototype);
}
return d->documentPrototype.value();
}
-Value Document::load(QV8Engine *engine, const QByteArray &data)
+ReturnedValue Document::load(QV8Engine *engine, const QByteArray &data)
{
Q_ASSERT(engine);
ExecutionEngine *v4 = QV8Engine::getV4(engine);
@@ -823,12 +844,12 @@ Value Document::load(QV8Engine *engine, const QByteArray &data)
if (!document || reader.hasError()) {
if (document)
document->release();
- return Value::nullValue();
+ return Encode::null();
}
Object *instance = new (v4->memoryManager) Node(v4, document);
instance->setPrototype(Document::prototype(v4).asObject());
- return Value::fromObject(instance);
+ return Value::fromObject(instance).asReturnedValue();
}
Node::Node(const Node &o)
@@ -843,7 +864,7 @@ bool Node::isNull() const
return d == 0;
}
-Value NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty)
{
QV4::ExecutionEngine *v4 = m->engine();
NamedNodeMap *r = m->as<NamedNodeMap>();
@@ -855,14 +876,14 @@ Value NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty)
if ((int)index < r->list.count()) {
if (hasProperty)
*hasProperty = true;
- return Node::create(engine, r->list.at(index));
+ return Node::create(engine, r->list.at(index)).asReturnedValue();
}
if (hasProperty)
*hasProperty = false;
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value NamedNodeMap::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue NamedNodeMap::get(Managed *m, String *name, bool *hasProperty)
{
NamedNodeMap *r = m->as<NamedNodeMap>();
QV4::ExecutionEngine *v4 = m->engine();
@@ -871,7 +892,7 @@ Value NamedNodeMap::get(Managed *m, String *name, bool *hasProperty)
name->makeIdentifier();
if (name->isEqualTo(v4->id_length))
- return Value::fromInt32(r->list.count());
+ return Value::fromInt32(r->list.count()).asReturnedValue();
QV8Engine *engine = v4->v8Engine;
@@ -880,13 +901,13 @@ Value NamedNodeMap::get(Managed *m, String *name, bool *hasProperty)
if (r->list.at(ii)->name == str) {
if (hasProperty)
*hasProperty = true;
- return Node::create(engine, r->list.at(ii));
+ return Node::create(engine, r->list.at(ii)).asReturnedValue();
}
}
if (hasProperty)
*hasProperty = false;
- return Value::undefinedValue();
+ return Encode::undefined();
}
Value NamedNodeMap::create(QV8Engine *engine, NodeImpl *data, const QList<NodeImpl *> &list)
@@ -897,7 +918,7 @@ Value NamedNodeMap::create(QV8Engine *engine, NodeImpl *data, const QList<NodeIm
return Value::fromObject(instance);
}
-Value NodeList::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue NodeList::getIndexed(Managed *m, uint index, bool *hasProperty)
{
QV4::ExecutionEngine *v4 = m->engine();
NodeList *r = m->as<NodeList>();
@@ -909,14 +930,14 @@ Value NodeList::getIndexed(Managed *m, uint index, bool *hasProperty)
if ((int)index < r->d->children.count()) {
if (hasProperty)
*hasProperty = true;
- return Node::create(engine, r->d->children.at(index));
+ return Node::create(engine, r->d->children.at(index)).asReturnedValue();
}
if (hasProperty)
*hasProperty = false;
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value NodeList::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue NodeList::get(Managed *m, String *name, bool *hasProperty)
{
QV4::ExecutionEngine *v4 = m->engine();
NodeList *r = m->as<NodeList>();
@@ -926,7 +947,7 @@ Value NodeList::get(Managed *m, String *name, bool *hasProperty)
name->makeIdentifier();
if (name->isEqualTo(v4->id_length))
- return Value::fromInt32(r->d->children.count());
+ return Value::fromInt32(r->d->children.count()).asReturnedValue();
return Object::get(m, name, hasProperty);
}
@@ -938,40 +959,44 @@ Value NodeList::create(QV8Engine *engine, NodeImpl *data)
return Value::fromObject(instance);
}
-Value Document::documentElement(SimpleCallContext *ctx)
+ReturnedValue Document::method_documentElement(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r || r->d->type != NodeImpl::Document) return Value::undefinedValue();
+ if (!r || r->d->type != NodeImpl::Document)
+ return Encode::undefined();
QV8Engine *engine = ctx->engine->v8Engine;
- return Node::create(engine, static_cast<DocumentImpl *>(r->d)->root);
+ return Node::create(engine, static_cast<DocumentImpl *>(r->d)->root).asReturnedValue();
}
-Value Document::xmlStandalone(SimpleCallContext *ctx)
+ReturnedValue Document::method_xmlStandalone(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r || r->d->type != NodeImpl::Document) return Value::undefinedValue();
+ if (!r || r->d->type != NodeImpl::Document)
+ return Encode::undefined();
QV8Engine *engine = ctx->engine->v8Engine;
Q_UNUSED(engine)
- return Value::fromBoolean(static_cast<DocumentImpl *>(r->d)->isStandalone);
+ return Encode(static_cast<DocumentImpl *>(r->d)->isStandalone);
}
-Value Document::xmlVersion(SimpleCallContext *ctx)
+ReturnedValue Document::method_xmlVersion(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r || r->d->type != NodeImpl::Document) return Value::undefinedValue();
+ if (!r || r->d->type != NodeImpl::Document)
+ return Encode::undefined();
QV8Engine *engine = ctx->engine->v8Engine;
- return engine->toString(static_cast<DocumentImpl *>(r->d)->version);
+ return engine->toString(static_cast<DocumentImpl *>(r->d)->version).asReturnedValue();
}
-Value Document::xmlEncoding(SimpleCallContext *ctx)
+ReturnedValue Document::method_xmlEncoding(SimpleCallContext *ctx)
{
Node *r = ctx->thisObject.as<Node>();
- if (!r || r->d->type != NodeImpl::Document) return Value::undefinedValue();
+ if (!r || r->d->type != NodeImpl::Document)
+ return Encode::undefined();
QV8Engine *engine = ctx->engine->v8Engine;
- return engine->toString(static_cast<DocumentImpl *>(r->d)->encoding);
+ return engine->toString(static_cast<DocumentImpl *>(r->d)->encoding).asReturnedValue();
}
class QQmlXMLHttpRequest : public QObject
@@ -1461,29 +1486,30 @@ const QByteArray &QQmlXMLHttpRequest::rawResponseBody() const
void QQmlXMLHttpRequest::dispatchCallback(const Value &me)
{
ExecutionContext *ctx = v4->current;
+ QV4::Scope scope(v4);
try {
Object *o = me.asObject();
if (!o)
ctx->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ThisObject"));
- Object *thisObj = o->get(v4->newString(QStringLiteral("ThisObject"))).asObject();
+ Scoped<Object> thisObj(scope, o->get(v4->newString(QStringLiteral("ThisObject"))));
if (!thisObj)
ctx->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ThisObject"));
- FunctionObject *callback = thisObj->get(v4->newString(QStringLiteral("onreadystatechange"))).asFunctionObject();
+ Scoped<FunctionObject> callback(scope, thisObj->get(v4->newString(QStringLiteral("onreadystatechange"))));
if (!callback) {
// not an error, but no onreadystatechange function to call.
return;
}
- Value activationObject = o->get(v4->newString(QStringLiteral("ActivationObject")));
- if (!activationObject.asObject())
+ Scoped<Object> activationObject(scope, o->get(v4->newString(QStringLiteral("ActivationObject"))));
+ if (!activationObject)
v4->current->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ActivationObject"));
- QQmlContextData *callingContext = QmlContextWrapper::getContext(activationObject);
+ QQmlContextData *callingContext = QmlContextWrapper::getContext(activationObject.asValue());
if (callingContext) {
- QV4::ScopedCallData callData(v4, 0);
- callData->thisObject = activationObject;
+ QV4::ScopedCallData callData(scope, 0);
+ callData->thisObject = activationObject.asValue();
callback->call(callData);
}
@@ -1564,7 +1590,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
if (c->proto)
c->proto->mark();
}
- static Value construct(Managed *that, QV4::CallData *)
+ static ReturnedValue construct(Managed *that, QV4::CallData *)
{
QQmlXMLHttpRequestCtor *ctor = that->as<QQmlXMLHttpRequestCtor>();
if (!ctor)
@@ -1574,27 +1600,27 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(engine, engine->networkAccessManager());
QQmlXMLHttpRequestWrapper *w = new (that->engine()->memoryManager) QQmlXMLHttpRequestWrapper(that->engine(), r);
w->setPrototype(ctor->proto);
- return Value::fromObject(w);
+ return Value::fromObject(w).asReturnedValue();
}
- static Value call(Managed *, QV4::CallData *) {
- return Value::undefinedValue();
+ static ReturnedValue call(Managed *, QV4::CallData *) {
+ return Value::undefinedValue().asReturnedValue();
}
void setupProto();
- static Value method_open(SimpleCallContext *ctx);
- static Value method_setRequestHeader(SimpleCallContext *ctx);
- static Value method_send(SimpleCallContext *ctx);
- static Value method_abort(SimpleCallContext *ctx);
- static Value method_getResponseHeader(SimpleCallContext *ctx);
- static Value method_getAllResponseHeaders(SimpleCallContext *ctx);
+ static ReturnedValue method_open(SimpleCallContext *ctx);
+ static ReturnedValue method_setRequestHeader(SimpleCallContext *ctx);
+ static ReturnedValue method_send(SimpleCallContext *ctx);
+ static ReturnedValue method_abort(SimpleCallContext *ctx);
+ static ReturnedValue method_getResponseHeader(SimpleCallContext *ctx);
+ static ReturnedValue method_getAllResponseHeaders(SimpleCallContext *ctx);
- static Value method_get_readyState(SimpleCallContext *ctx);
- static Value method_get_status(SimpleCallContext *ctx);
- static Value method_get_statusText(SimpleCallContext *ctx);
- static Value method_get_responseText(SimpleCallContext *ctx);
- static Value method_get_responseXML(SimpleCallContext *ctx);
+ static ReturnedValue method_get_readyState(SimpleCallContext *ctx);
+ static ReturnedValue method_get_status(SimpleCallContext *ctx);
+ static ReturnedValue method_get_statusText(SimpleCallContext *ctx);
+ static ReturnedValue method_get_responseText(SimpleCallContext *ctx);
+ static ReturnedValue method_get_responseXML(SimpleCallContext *ctx);
Object *proto;
@@ -1632,8 +1658,9 @@ void QQmlXMLHttpRequestCtor::setupProto()
// XMLHttpRequest methods
-Value QQmlXMLHttpRequestCtor::method_open(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_open(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1645,7 +1672,7 @@ Value QQmlXMLHttpRequestCtor::method_open(SimpleCallContext *ctx)
QV8Engine *engine = ctx->engine->v8Engine;
// Argument 0 - Method
- QString method = ctx->arguments[0].toQString().toUpper();
+ QString method = ctx->arguments[0].toQStringNoThrow().toUpper();
if (method != QLatin1String("GET") &&
method != QLatin1String("PUT") &&
method != QLatin1String("HEAD") &&
@@ -1654,7 +1681,7 @@ Value QQmlXMLHttpRequestCtor::method_open(SimpleCallContext *ctx)
V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type");
// Argument 1 - URL
- QUrl url = QUrl(ctx->arguments[1].toQString());
+ QUrl url = QUrl(ctx->arguments[1].toQStringNoThrow());
if (url.isRelative())
url = engine->callingContext()->resolvedUrl(url);
@@ -1666,9 +1693,9 @@ Value QQmlXMLHttpRequestCtor::method_open(SimpleCallContext *ctx)
// Argument 3/4 - user/pass (optional)
QString username, password;
if (ctx->argumentCount > 3)
- username = ctx->arguments[3].toQString();
+ username = ctx->arguments[3].toQStringNoThrow();
if (ctx->argumentCount > 4)
- password = ctx->arguments[4].toQString();
+ password = ctx->arguments[4].toQStringNoThrow();
// Clear the fragment (if any)
url.setFragment(QString());
@@ -1677,11 +1704,13 @@ Value QQmlXMLHttpRequestCtor::method_open(SimpleCallContext *ctx)
if (!username.isNull()) url.setUserName(username);
if (!password.isNull()) url.setPassword(password);
- return r->open(constructMeObject(ctx->thisObject, engine), method, url);
+ return r->open(constructMeObject(ctx->thisObject, engine), method, url).asReturnedValue();
}
-Value QQmlXMLHttpRequestCtor::method_setRequestHeader(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1693,8 +1722,8 @@ Value QQmlXMLHttpRequestCtor::method_setRequestHeader(SimpleCallContext *ctx)
if (r->readyState() != QQmlXMLHttpRequest::Opened || r->sendFlag())
V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- QString name = ctx->arguments[0].toQString();
- QString value = ctx->arguments[1].toQString();
+ QString name = ctx->arguments[0].toQStringNoThrow();
+ QString value = ctx->arguments[1].toQStringNoThrow();
// ### Check that name and value are well formed
@@ -1719,15 +1748,17 @@ Value QQmlXMLHttpRequestCtor::method_setRequestHeader(SimpleCallContext *ctx)
nameUpper == QLatin1String("VIA") ||
nameUpper.startsWith(QLatin1String("PROXY-")) ||
nameUpper.startsWith(QLatin1String("SEC-")))
- return Value::undefinedValue();
+ return Encode::undefined();
r->addHeader(name, value);
- return Value::undefinedValue();
+ return Encode::undefined();
}
-Value QQmlXMLHttpRequestCtor::method_send(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_send(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1741,23 +1772,27 @@ Value QQmlXMLHttpRequestCtor::method_send(SimpleCallContext *ctx)
QByteArray data;
if (ctx->argumentCount > 0)
- data = ctx->arguments[0].toQString().toUtf8();
+ data = ctx->arguments[0].toQStringNoThrow().toUtf8();
- return r->send(constructMeObject(ctx->thisObject, engine), data);
+ return r->send(constructMeObject(ctx->thisObject, engine), data).asReturnedValue();
}
-Value QQmlXMLHttpRequestCtor::method_abort(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_abort(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->request;
- return r->abort(constructMeObject(ctx->thisObject, ctx->engine->v8Engine));
+ return r->abort(constructMeObject(ctx->thisObject, ctx->engine->v8Engine)).asReturnedValue();
}
-Value QQmlXMLHttpRequestCtor::method_getResponseHeader(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1773,11 +1808,13 @@ Value QQmlXMLHttpRequestCtor::method_getResponseHeader(SimpleCallContext *ctx)
r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- return engine->toString(r->header(ctx->arguments[0].toQString()));
+ return engine->toString(r->header(ctx->arguments[0].toQStringNoThrow())).asReturnedValue();
}
-Value QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1793,22 +1830,26 @@ Value QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(SimpleCallContext *ct
r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- return engine->toString(r->headers());
+ return engine->toString(r->headers()).asReturnedValue();
}
// XMLHttpRequest properties
-Value QQmlXMLHttpRequestCtor::method_get_readyState(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->request;
- return Value::fromUInt32(r->readyState());
+ return Encode(r->readyState());
}
-Value QQmlXMLHttpRequestCtor::method_get_status(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1819,13 +1860,15 @@ Value QQmlXMLHttpRequestCtor::method_get_status(SimpleCallContext *ctx)
V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
if (r->errorFlag())
- return Value::fromInt32(0);
+ return Encode(0);
else
- return Value::fromInt32(r->replyStatus());
+ return Encode(r->replyStatus());
}
-Value QQmlXMLHttpRequestCtor::method_get_statusText(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1838,13 +1881,15 @@ Value QQmlXMLHttpRequestCtor::method_get_statusText(SimpleCallContext *ctx)
V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
if (r->errorFlag())
- return engine->toString(QString());
+ return engine->toString(QString()).asReturnedValue();
else
- return engine->toString(r->replyStatusText());
+ return engine->toString(r->replyStatusText()).asReturnedValue();
}
-Value QQmlXMLHttpRequestCtor::method_get_responseText(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1854,13 +1899,15 @@ Value QQmlXMLHttpRequestCtor::method_get_responseText(SimpleCallContext *ctx)
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)
- return engine->toString(QString());
+ return engine->toString(QString()).asReturnedValue();
else
- return engine->toString(r->responseBody());
+ return engine->toString(r->responseBody()).asReturnedValue();
}
-Value QQmlXMLHttpRequestCtor::method_get_responseXML(SimpleCallContext *ctx)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
+
QQmlXMLHttpRequestWrapper *w = ctx->thisObject.as<QQmlXMLHttpRequestWrapper>();
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
@@ -1869,7 +1916,7 @@ Value QQmlXMLHttpRequestCtor::method_get_responseXML(SimpleCallContext *ctx)
if (!r->receivedXml() ||
(r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)) {
- return Value::nullValue();
+ return Encode::null();
} else {
return Document::load(ctx->engine->v8Engine, r->rawResponseBody());
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 2321e27bc6..6389ad2715 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -103,7 +103,7 @@ QV4::QtObject::QtObject(ExecutionEngine *v4, QQmlEngine *qmlEngine)
put(v4->newString("Asynchronous"), QV4::Value::fromInt32(0));
put(v4->newString("Synchronous"), QV4::Value::fromInt32(1));
- defineDefaultProperty(v4, QStringLiteral("include"), QV4Include::include);
+ defineDefaultProperty(v4, QStringLiteral("include"), QV4Include::method_include);
defineDefaultProperty(v4, QStringLiteral("isQtObject"), method_isQtObject);
defineDefaultProperty(v4, QStringLiteral("rgba"), method_rgba);
defineDefaultProperty(v4, QStringLiteral("hsla"), method_hsla);
@@ -168,12 +168,12 @@ QV4::QtObject::QtObject(ExecutionEngine *v4, QQmlEngine *qmlEngine)
\qmlmethod bool Qt::isQtObject(object)
Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
*/
-Value QtObject::method_isQtObject(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_isQtObject(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount == 0)
- return QV4::Value::fromBoolean(false);
+ return QV4::Encode(false);
- return QV4::Value::fromBoolean(ctx->arguments[0].as<QV4::QObjectWrapper>() != 0);
+ return QV4::Encode(ctx->arguments[0].as<QV4::QObjectWrapper>() != 0);
}
/*!
@@ -182,7 +182,7 @@ Value QtObject::method_isQtObject(QV4::SimpleCallContext *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.
*/
-Value QtObject::method_rgba(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_rgba(QV4::SimpleCallContext *ctx)
{
int argCount = ctx->argumentCount;
if (argCount < 3 || argCount > 4)
@@ -211,7 +211,7 @@ Value QtObject::method_rgba(QV4::SimpleCallContext *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.
*/
-Value QtObject::method_hsla(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_hsla(QV4::SimpleCallContext *ctx)
{
int argCount = ctx->argumentCount;
if (argCount < 3 || argCount > 4)
@@ -242,7 +242,7 @@ 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.
*/
-Value QtObject::method_colorEqual(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_colorEqual(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 2)
V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
@@ -272,7 +272,7 @@ Value QtObject::method_colorEqual(QV4::SimpleCallContext *ctx)
}
bool equal = (lhs == rhs);
- return QV4::Value::fromBoolean(equal);
+ return QV4::Encode(equal);
}
/*!
@@ -282,7 +282,7 @@ 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.
*/
-Value QtObject::method_rect(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_rect(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 4)
V4THROW_ERROR("Qt.rect(): Invalid arguments");
@@ -299,7 +299,7 @@ Value QtObject::method_rect(QV4::SimpleCallContext *ctx)
\qmlmethod point Qt::point(int x, int y)
Returns a Point with the specified \c x and \c y coordinates.
*/
-Value QtObject::method_point(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_point(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 2)
V4THROW_ERROR("Qt.point(): Invalid arguments");
@@ -314,7 +314,7 @@ Value QtObject::method_point(QV4::SimpleCallContext *ctx)
\qmlmethod Qt::size(int width, int height)
Returns a Size with the specified \c width and \c height.
*/
-Value QtObject::method_size(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_size(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 2)
V4THROW_ERROR("Qt.size(): Invalid arguments");
@@ -333,7 +333,7 @@ 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.
*/
-Value QtObject::method_font(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_font(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1 || !ctx->arguments[0].isObject())
V4THROW_ERROR("Qt.font(): Invalid arguments");
@@ -352,7 +352,7 @@ Value QtObject::method_font(QV4::SimpleCallContext *ctx)
\qmlmethod Qt::vector2d(real x, real y)
Returns a Vector2D with the specified \c x and \c y.
*/
-Value QtObject::method_vector2d(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_vector2d(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 2)
V4THROW_ERROR("Qt.vector2d(): Invalid arguments");
@@ -370,7 +370,7 @@ Value QtObject::method_vector2d(QV4::SimpleCallContext *ctx)
\qmlmethod Qt::vector3d(real x, real y, real z)
Returns a Vector3D with the specified \c x, \c y and \c z.
*/
-Value QtObject::method_vector3d(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_vector3d(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 3)
V4THROW_ERROR("Qt.vector3d(): Invalid arguments");
@@ -389,7 +389,7 @@ Value QtObject::method_vector3d(QV4::SimpleCallContext *ctx)
\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.
*/
-Value QtObject::method_vector4d(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_vector4d(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 4)
V4THROW_ERROR("Qt.vector4d(): Invalid arguments");
@@ -409,7 +409,7 @@ Value QtObject::method_vector4d(QV4::SimpleCallContext *ctx)
\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.
*/
-Value QtObject::method_quaternion(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_quaternion(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 4)
V4THROW_ERROR("Qt.quaternion(): Invalid arguments");
@@ -432,7 +432,7 @@ Alternatively, the function may be called with a single argument
where that argument is a JavaScript array which contains the sixteen
matrix values.
*/
-Value QtObject::method_matrix4x4(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_matrix4x4(QV4::SimpleCallContext *ctx)
{
QV8Engine *v8engine = ctx->engine->v8Engine;
@@ -483,7 +483,7 @@ 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).
*/
-Value QtObject::method_lighter(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_lighter(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1 && ctx->argumentCount != 2)
V4THROW_ERROR("Qt.lighter(): Invalid arguments");
@@ -494,10 +494,10 @@ Value QtObject::method_lighter(QV4::SimpleCallContext *ctx)
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
} else if (v.userType() != QVariant::Color) {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
qreal factor = 1.5;
@@ -522,7 +522,7 @@ 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).
*/
-Value QtObject::method_darker(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_darker(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1 && ctx->argumentCount != 2)
V4THROW_ERROR("Qt.darker(): Invalid arguments");
@@ -533,10 +533,10 @@ Value QtObject::method_darker(QV4::SimpleCallContext *ctx)
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
} else if (v.userType() != QVariant::Color) {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
qreal factor = 2.0;
@@ -570,7 +570,7 @@ Value QtObject::method_darker(QV4::SimpleCallContext *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.
*/
-Value QtObject::method_tint(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_tint(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 2)
V4THROW_ERROR("Qt.tint(): Invalid arguments");
@@ -583,10 +583,10 @@ Value QtObject::method_tint(QV4::SimpleCallContext *ctx)
bool ok = false;
v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
if (!ok) {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
} else if (v1.userType() != QVariant::Color) {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
// tint color
@@ -595,10 +595,10 @@ Value QtObject::method_tint(QV4::SimpleCallContext *ctx)
bool ok = false;
v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
if (!ok) {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
} else if (v2.userType() != QVariant::Color) {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
return v8engine->fromVariant(QQml_colorProvider()->tint(v1, v2));
@@ -620,7 +620,7 @@ If \a format is not specified, \a date is formatted using
\sa Locale
*/
-Value QtObject::method_formatDate(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_formatDate(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount < 1 || ctx->argumentCount > 2)
V4THROW_ERROR("Qt.formatDate(): Invalid arguments");
@@ -663,7 +663,7 @@ If \a format is not specified, \a time is formatted using
\sa Locale
*/
-Value QtObject::method_formatTime(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_formatTime(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount < 1 || ctx->argumentCount > 2)
V4THROW_ERROR("Qt.formatTime(): Invalid arguments");
@@ -787,7 +787,7 @@ with the \a format values below to produce the following results:
\sa Locale
*/
-Value QtObject::method_formatDateTime(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_formatDateTime(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount < 1 || ctx->argumentCount > 2)
V4THROW_ERROR("Qt.formatDateTime(): Invalid arguments");
@@ -819,14 +819,14 @@ Value QtObject::method_formatDateTime(QV4::SimpleCallContext *ctx)
\qmlmethod bool Qt::openUrlExternally(url target)
Attempts to open the specified \c target url in an external application, based on the user's desktop preferences. Returns true if it succeeds, and false otherwise.
*/
-Value QtObject::method_openUrlExternally(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_openUrlExternally(QV4::SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1)
- return QV4::Value::fromBoolean(false);
+ return QV4::Encode(false);
QV8Engine *v8engine = ctx->engine->v8Engine;
- QUrl url(method_resolvedUrl(ctx).toQString());
+ QUrl url(Value::fromReturnedValue(method_resolvedUrl(ctx)).toQStringNoThrow());
return v8engine->fromVariant(QQml_guiProvider()->openUrlExternally(url));
}
@@ -834,7 +834,7 @@ Value QtObject::method_openUrlExternally(QV4::SimpleCallContext *ctx)
\qmlmethod url Qt::resolvedUrl(url url)
Returns \a url resolved relative to the URL of the caller.
*/
-Value QtObject::method_resolvedUrl(QV4::SimpleCallContext *ctx)
+ReturnedValue QtObject::method_resolvedUrl(QV4::SimpleCallContext *ctx)
{
QV8Engine *v8engine = ctx->engine->v8Engine;
@@ -845,19 +845,19 @@ Value QtObject::method_resolvedUrl(QV4::SimpleCallContext *ctx)
if (p) {
QQmlContextData *ctxt = v8engine->callingContext();
if (ctxt)
- return Value::fromString(ctx, ctxt->resolvedUrl(url).toString());
+ return Value::fromString(ctx, ctxt->resolvedUrl(url).toString()).asReturnedValue();
else
- return Value::fromString(ctx, url.toString());
+ return Value::fromString(ctx, url.toString()).asReturnedValue();
}
- return Value::fromString(ctx, e->baseUrl().resolved(url).toString());
+ return Value::fromString(ctx, e->baseUrl().resolved(url).toString()).asReturnedValue();
}
/*!
\qmlmethod list<string> Qt::fontFamilies()
Returns a list of the font families available to the application.
*/
-Value QtObject::method_fontFamilies(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_fontFamilies(SimpleCallContext *ctx)
{
if (ctx->argumentCount != 0)
V4THROW_ERROR("Qt.fontFamilies(): Invalid arguments");
@@ -870,42 +870,42 @@ Value QtObject::method_fontFamilies(SimpleCallContext *ctx)
\qmlmethod string Qt::md5(data)
Returns a hex string of the md5 hash of \c data.
*/
-Value QtObject::method_md5(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_md5(SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1)
V4THROW_ERROR("Qt.md5(): Invalid arguments");
- QByteArray data = ctx->arguments[0].toQString().toUtf8();
+ QByteArray data = ctx->arguments[0].toQStringNoThrow().toUtf8();
QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
- return Value::fromString(ctx, QLatin1String(result.toHex()));
+ return Value::fromString(ctx, QLatin1String(result.toHex())).asReturnedValue();
}
/*!
\qmlmethod string Qt::btoa(data)
Binary to ASCII - this function returns a base64 encoding of \c data.
*/
-Value QtObject::method_btoa(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_btoa(SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1)
V4THROW_ERROR("Qt.btoa(): Invalid arguments");
- QByteArray data = ctx->arguments[0].toQString().toUtf8();
+ QByteArray data = ctx->arguments[0].toQStringNoThrow().toUtf8();
- return Value::fromString(ctx, QLatin1String(data.toBase64()));
+ return Value::fromString(ctx, QLatin1String(data.toBase64())).asReturnedValue();
}
/*!
\qmlmethod string Qt::atob(data)
ASCII to binary - this function returns a base64 decoding of \c data.
*/
-Value QtObject::method_atob(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_atob(SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1)
V4THROW_ERROR("Qt.atob(): Invalid arguments");
- QByteArray data = ctx->arguments[0].toQString().toLatin1();
+ QByteArray data = ctx->arguments[0].toQStringNoThrow().toLatin1();
- return Value::fromString(ctx, QString::fromUtf8(QByteArray::fromBase64(data)));
+ return Value::fromString(ctx, QString::fromUtf8(QByteArray::fromBase64(data))).asReturnedValue();
}
/*!
@@ -915,12 +915,12 @@ Within the \l {Prototyping with qmlscene}, this causes the launcher application
to quit a C++ application when this method is called, connect the
QQmlEngine::quit() signal to the QCoreApplication::quit() slot.
*/
-Value QtObject::method_quit(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_quit(SimpleCallContext *ctx)
{
QV8Engine *v8engine = ctx->engine->v8Engine;
QQmlEnginePrivate::get(v8engine->engine())->sendQuit();
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
@@ -947,31 +947,32 @@ If this is the case, consider using \l{QtQml2::Qt::createComponent()}{Qt.createC
See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function.
*/
-Value QtObject::method_createQmlObject(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_createQmlObject(SimpleCallContext *ctx)
{
+ Scope scope(ctx);
if (ctx->argumentCount < 2 || ctx->argumentCount > 3)
V4THROW_ERROR("Qt.createQmlObject(): Invalid arguments");
struct Error {
- static Value create(QV8Engine *engine, const QList<QQmlError> &errors) {
+ static ReturnedValue create(QV4::ExecutionEngine *v4, const QList<QQmlError> &errors) {
+ Scope scope(v4);
QString errorstr = QLatin1String("Qt.createQmlObject(): failed to create object: ");
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
- QV4::ArrayObject *qmlerrors = v4->newArrayObject();
+ QV4::Scoped<ArrayObject> qmlerrors(scope, v4->newArrayObject());
for (int ii = 0; ii < errors.count(); ++ii) {
const QQmlError &error = errors.at(ii);
errorstr += QLatin1String("\n ") + error.toString();
QV4::Object *qmlerror = v4->newObject();
qmlerror->put(v4->newString("lineNumber"), QV4::Value::fromInt32(error.line()));
qmlerror->put(v4->newString("columnNumber"), QV4::Value::fromInt32(error.column()));
- qmlerror->put(v4->newString("fileName"), engine->toString(error.url().toString()));
- qmlerror->put(v4->newString("message"), engine->toString(error.description()));
+ qmlerror->put(v4->newString("fileName"), Value::fromString(v4->newString(error.url().toString())));
+ qmlerror->put(v4->newString("message"), Value::fromString(v4->newString(error.description())));
qmlerrors->putIndexed(ii, QV4::Value::fromObject(qmlerror));
}
- QV4::Object *errorObject = v4->newErrorObject(engine->toString(errorstr));
- errorObject->put(v4->newString("qmlErrors"), Value::fromObject(qmlerrors));
- return Value::fromObject(errorObject);
+ Scoped<Object> errorObject(scope, v4->newErrorObject(Value::fromString(v4->newString(errorstr))));
+ errorObject->put(v4->newString("qmlErrors"), qmlerrors.asValue());
+ return errorObject.asReturnedValue();
}
};
@@ -986,13 +987,13 @@ Value QtObject::method_createQmlObject(SimpleCallContext *ctx)
effectiveContext = context->asQQmlContext();
Q_ASSERT(context && effectiveContext);
- QString qml = ctx->arguments[0].toQString();
+ QString qml = ctx->arguments[0].toQStringNoThrow();
if (qml.isEmpty())
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
QUrl url;
if (ctx->argumentCount > 2)
- url = QUrl(ctx->arguments[2].toQString());
+ url = QUrl(ctx->arguments[2].toQStringNoThrow());
else
url = QUrl(QLatin1String("inline"));
@@ -1009,8 +1010,9 @@ Value QtObject::method_createQmlObject(SimpleCallContext *ctx)
component.setData(qml.toUtf8(), url);
if (component.isError()) {
- ctx->throwError(Error::create(v8engine, component.errors()));
- return QV4::Value::undefinedValue();
+ ScopedValue v(scope, Error::create(ctx->engine, component.errors()));
+ ctx->throwError(v);
+ return QV4::Encode::undefined();
}
if (!component.isReady())
@@ -1033,8 +1035,9 @@ Value QtObject::method_createQmlObject(SimpleCallContext *ctx)
component.completeCreate();
if (component.isError()) {
- ctx->throwError(Error::create(v8engine, component.errors()));
- return QV4::Value::undefinedValue();
+ ScopedValue v(scope, Error::create(ctx->engine, component.errors()));
+ ctx->throwError(v);
+ return QV4::Encode::undefined();
}
Q_ASSERT(obj);
@@ -1073,7 +1076,7 @@ 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{QtQml2::Qt::createQmlObject()}{Qt.createQmlObject()}.
*/
-Value QtObject::method_createComponent(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_createComponent(SimpleCallContext *ctx)
{
const QString invalidArgs = QStringLiteral("Qt.createComponent(): Invalid arguments");
const QString invalidParent = QStringLiteral("Qt.createComponent(): Invalid parent object");
@@ -1089,9 +1092,9 @@ Value QtObject::method_createComponent(SimpleCallContext *ctx)
effectiveContext = 0;
Q_ASSERT(context);
- QString arg = ctx->arguments[0].toQString();
+ QString arg = ctx->arguments[0].toQStringNoThrow();
if (arg.isEmpty())
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
QQmlComponent::CompilationMode compileMode = QQmlComponent::PreferSynchronous;
QObject *parentArg = 0;
@@ -1156,7 +1159,7 @@ Value QtObject::method_createComponent(SimpleCallContext *ctx)
\sa QtQuick2::Locale
*/
-Value QtObject::method_locale(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_locale(SimpleCallContext *ctx)
{
QString code;
if (ctx->argumentCount > 1)
@@ -1166,7 +1169,7 @@ Value QtObject::method_locale(SimpleCallContext *ctx)
QV8Engine *v8engine = ctx->engine->v8Engine;
if (ctx->argumentCount == 1)
- code = ctx->arguments[0].toQString();
+ code = ctx->arguments[0].toQStringNoThrow();
return QQmlLocale::locale(v8engine, code);
}
@@ -1184,7 +1187,7 @@ struct BindingFunction : public QV4::FunctionObject
bindingKeyFlag = true;
}
- static Value call(Managed *that, CallData *callData)
+ static ReturnedValue call(Managed *that, CallData *callData)
{
BindingFunction *This = static_cast<BindingFunction*>(that);
return This->originalFunction->call(callData);
@@ -1250,7 +1253,7 @@ DEFINE_MANAGED_VTABLE(BindingFunction);
\since QtQuick 2.0
*/
-Value QtObject::method_binding(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_binding(SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1)
V4THROW_ERROR("binding() requires 1 argument");
@@ -1258,11 +1261,11 @@ Value QtObject::method_binding(SimpleCallContext *ctx)
if (!f)
V4THROW_TYPE("binding(): argument (binding expression) must be a function");
- return QV4::Value::fromObject(new (ctx->engine->memoryManager) BindingFunction(f));
+ return QV4::Value::fromObject(new (ctx->engine->memoryManager) BindingFunction(f)).asReturnedValue();
}
-Value QtObject::method_get_platform(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_get_platform(SimpleCallContext *ctx)
{
// ### inefficient. Should be just a value based getter
Object *o = ctx->thisObject.asObject();
@@ -1279,7 +1282,7 @@ Value QtObject::method_get_platform(SimpleCallContext *ctx)
return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_platform);
}
-Value QtObject::method_get_application(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_get_application(SimpleCallContext *ctx)
{
// ### inefficient. Should be just a value based getter
Object *o = ctx->thisObject.asObject();
@@ -1297,7 +1300,7 @@ Value QtObject::method_get_application(SimpleCallContext *ctx)
}
#ifndef QT_NO_IM
-Value QtObject::method_get_inputMethod(SimpleCallContext *ctx)
+ReturnedValue QtObject::method_get_inputMethod(SimpleCallContext *ctx)
{
QObject *o = QQml_guiProvider()->inputMethod();
QQmlEngine::setObjectOwnership(o, QQmlEngine::CppOwnership);
@@ -1358,8 +1361,8 @@ static QString jsStack(QV4::ExecutionEngine *engine) {
return stack;
}
-static QV4::Value writeToConsole(ConsoleLogTypes logType, SimpleCallContext *ctx,
- bool printStack = false)
+static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, SimpleCallContext *ctx,
+ bool printStack = false)
{
QString result;
QV4::ExecutionEngine *v4 = ctx->engine;
@@ -1370,9 +1373,9 @@ static QV4::Value writeToConsole(ConsoleLogTypes logType, SimpleCallContext *ctx
QV4::Value value = ctx->arguments[i];
if (value.asArrayObject())
- result.append(QStringLiteral("[") + value.toQString() + QStringLiteral("]"));
+ result.append(QStringLiteral("[") + value.toQStringNoThrow() + QStringLiteral("]"));
else
- result.append(value.toQString());
+ result.append(value.toQStringNoThrow());
}
if (printStack) {
@@ -1396,15 +1399,15 @@ static QV4::Value writeToConsole(ConsoleLogTypes logType, SimpleCallContext *ctx
break;
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value ConsoleObject::method_error(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_error(SimpleCallContext *ctx)
{
return writeToConsole(Error, ctx);
}
-QV4::Value ConsoleObject::method_log(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_log(SimpleCallContext *ctx)
{
//console.log
//console.debug
@@ -1413,7 +1416,7 @@ QV4::Value ConsoleObject::method_log(SimpleCallContext *ctx)
return writeToConsole(Log, ctx);
}
-QV4::Value ConsoleObject::method_profile(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_profile(SimpleCallContext *ctx)
{
//DeclarativeDebugTrace cannot handle nested profiling
//although v8 can handle several profiling at once,
@@ -1431,10 +1434,10 @@ QV4::Value ConsoleObject::method_profile(SimpleCallContext *ctx)
logger.warning("Profiling is already in progress. First, end current profiling session.");
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value ConsoleObject::method_profileEnd(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_profileEnd(SimpleCallContext *ctx)
{
//DeclarativeDebugTrace cannot handle nested profiling
//although v8 can handle several profiling at once,
@@ -1457,43 +1460,43 @@ QV4::Value ConsoleObject::method_profileEnd(SimpleCallContext *ctx)
logger.warning("Profiling was not started.");
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value ConsoleObject::method_time(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_time(SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1)
V4THROW_ERROR("console.time(): Invalid arguments");
QV8Engine *v8engine = ctx->engine->v8Engine;
- QString name = ctx->arguments[0].toQString();
+ QString name = ctx->arguments[0].toQStringNoThrow();
v8engine->startTimer(name);
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value ConsoleObject::method_timeEnd(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_timeEnd(SimpleCallContext *ctx)
{
if (ctx->argumentCount != 1)
V4THROW_ERROR("console.time(): Invalid arguments");
QV8Engine *v8engine = ctx->engine->v8Engine;
- QString name = ctx->arguments[0].toQString();
+ QString name = ctx->arguments[0].toQStringNoThrow();
bool wasRunning;
qint64 elapsed = v8engine->stopTimer(name, &wasRunning);
if (wasRunning) {
qDebug("%s: %llims", qPrintable(name), elapsed);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value ConsoleObject::method_count(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_count(SimpleCallContext *ctx)
{
// first argument: name to print. Ignore any additional arguments
QString name;
if (ctx->argumentCount > 0)
- name = ctx->arguments[0].toQString();
+ name = ctx->arguments[0].toQStringNoThrow();
QV4::ExecutionEngine *v4 = ctx->engine;
QV8Engine *v8engine = ctx->engine->v8Engine;
@@ -1508,10 +1511,10 @@ QV4::Value ConsoleObject::method_count(SimpleCallContext *ctx)
QMessageLogger(qPrintable(scriptName), frame.line,
qPrintable(frame.function)).debug("%s", qPrintable(message));
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value ConsoleObject::method_trace(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_trace(SimpleCallContext *ctx)
{
if (ctx->argumentCount != 0)
V4THROW_ERROR("console.trace(): Invalid arguments");
@@ -1524,15 +1527,15 @@ QV4::Value ConsoleObject::method_trace(SimpleCallContext *ctx)
QMessageLogger logger(frame.source.toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
logger.debug("%s", qPrintable(stack));
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value ConsoleObject::method_warn(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_warn(SimpleCallContext *ctx)
{
return writeToConsole(Warn, ctx);
}
-QV4::Value ConsoleObject::method_assert(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_assert(SimpleCallContext *ctx)
{
if (ctx->argumentCount == 0)
V4THROW_ERROR("console.assert(): Missing argument");
@@ -1545,7 +1548,7 @@ QV4::Value ConsoleObject::method_assert(SimpleCallContext *ctx)
if (i != 1)
message.append(QLatin1Char(' '));
- message.append(ctx->arguments[i].toQString());
+ message.append(ctx->arguments[i].toQStringNoThrow());
}
QString stack = jsStack(v4);
@@ -1555,17 +1558,17 @@ QV4::Value ConsoleObject::method_assert(SimpleCallContext *ctx)
logger.critical("%s\n%s", qPrintable(message), qPrintable(stack));
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value ConsoleObject::method_exception(SimpleCallContext *ctx)
+QV4::ReturnedValue ConsoleObject::method_exception(SimpleCallContext *ctx)
{
if (ctx->argumentCount == 0)
V4THROW_ERROR("console.exception(): Missing argument");
writeToConsole(Error, ctx, true);
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
@@ -1594,7 +1597,7 @@ void QV4::GlobalExtensions::init(QQmlEngine *qmlEngine, Object *globalObject)
// string prototype extension
QV4::Object *stringProto = v4->stringClass->prototype;
- stringProto->defineDefaultProperty(v4, QStringLiteral("arg"), string_arg);
+ stringProto->defineDefaultProperty(v4, QStringLiteral("arg"), method_string_arg);
}
@@ -1616,7 +1619,7 @@ void QV4::GlobalExtensions::init(QQmlEngine *qmlEngine, Object *globalObject)
\sa {Internationalization and Localization with Qt Quick}
*/
-Value GlobalExtensions::method_qsTranslate(SimpleCallContext *ctx)
+ReturnedValue GlobalExtensions::method_qsTranslate(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 2)
V4THROW_ERROR("qsTranslate() requires at least two arguments");
@@ -1627,10 +1630,10 @@ Value GlobalExtensions::method_qsTranslate(SimpleCallContext *ctx)
if ((ctx->argumentCount > 2) && !ctx->arguments[2].isString())
V4THROW_ERROR("qsTranslate(): third argument (disambiguation) must be a string");
- QString context = ctx->arguments[0].toQString();
- QString text = ctx->arguments[1].toQString();
+ QString context = ctx->arguments[0].toQStringNoThrow();
+ QString text = ctx->arguments[1].toQStringNoThrow();
QString comment;
- if (ctx->argumentCount > 2) comment = ctx->arguments[2].toQString();
+ if (ctx->argumentCount > 2) comment = ctx->arguments[2].toQStringNoThrow();
int i = 3;
if (ctx->argumentCount > i && ctx->arguments[i].isString()) {
@@ -1647,7 +1650,7 @@ Value GlobalExtensions::method_qsTranslate(SimpleCallContext *ctx)
comment.toUtf8().constData(),
n);
- return Value::fromString(ctx, result);
+ return Value::fromString(ctx, result).asReturnedValue();
}
/*!
@@ -1672,11 +1675,11 @@ Value GlobalExtensions::method_qsTranslate(SimpleCallContext *ctx)
\sa {Internationalization and Localization with Qt Quick}
*/
-Value GlobalExtensions::method_qsTranslateNoOp(SimpleCallContext *ctx)
+ReturnedValue GlobalExtensions::method_qsTranslateNoOp(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 2)
- return QV4::Value::undefinedValue();
- return ctx->arguments[1];
+ return QV4::Encode::undefined();
+ return ctx->arguments[1].asReturnedValue();
}
/*!
@@ -1696,7 +1699,7 @@ Value GlobalExtensions::method_qsTranslateNoOp(SimpleCallContext *ctx)
\sa {Internationalization and Localization with Qt Quick}
*/
-Value GlobalExtensions::method_qsTr(SimpleCallContext *ctx)
+ReturnedValue GlobalExtensions::method_qsTr(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 1)
V4THROW_ERROR("qsTr() requires at least one argument");
@@ -1714,10 +1717,10 @@ Value GlobalExtensions::method_qsTr(SimpleCallContext *ctx)
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
QString context = (lastSlash > -1) ? path.mid(lastSlash + 1, path.length()-lastSlash-5) : QString();
- QString text = ctx->arguments[0].toQString();
+ QString text = ctx->arguments[0].toQStringNoThrow();
QString comment;
if (ctx->argumentCount > 1)
- comment = ctx->arguments[1].toQString();
+ comment = ctx->arguments[1].toQStringNoThrow();
int n = -1;
if (ctx->argumentCount > 2)
n = ctx->arguments[2].toInt32();
@@ -1725,7 +1728,7 @@ Value GlobalExtensions::method_qsTr(SimpleCallContext *ctx)
QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(),
comment.toUtf8().constData(), n);
- return Value::fromString(ctx, result);
+ return Value::fromString(ctx, result).asReturnedValue();
}
/*!
@@ -1750,11 +1753,11 @@ Value GlobalExtensions::method_qsTr(SimpleCallContext *ctx)
\sa {Internationalization and Localization with Qt Quick}
*/
-Value GlobalExtensions::method_qsTrNoOp(SimpleCallContext *ctx)
+ReturnedValue GlobalExtensions::method_qsTrNoOp(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 1)
- return QV4::Value::undefinedValue();
- return ctx->arguments[0];
+ return QV4::Encode::undefined();
+ return ctx->arguments[0].asReturnedValue();
}
/*!
@@ -1787,7 +1790,7 @@ Value GlobalExtensions::method_qsTrNoOp(SimpleCallContext *ctx)
\sa QT_TRID_NOOP, {Internationalization and Localization with Qt Quick}
*/
-Value GlobalExtensions::method_qsTrId(SimpleCallContext *ctx)
+ReturnedValue GlobalExtensions::method_qsTrId(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 1)
V4THROW_ERROR("qsTrId() requires at least one argument");
@@ -1800,7 +1803,7 @@ Value GlobalExtensions::method_qsTrId(SimpleCallContext *ctx)
if (ctx->argumentCount > 1)
n = ctx->arguments[1].toInt32();
- return Value::fromString(ctx, qtTrId(ctx->arguments[0].toQString().toUtf8().constData(), n));
+ return Value::fromString(ctx, qtTrId(ctx->arguments[0].toQStringNoThrow().toUtf8().constData(), n)).asReturnedValue();
}
/*!
@@ -1819,39 +1822,39 @@ Value GlobalExtensions::method_qsTrId(SimpleCallContext *ctx)
\sa qsTrId(), {Internationalization and Localization with Qt Quick}
*/
-Value GlobalExtensions::method_qsTrIdNoOp(SimpleCallContext *ctx)
+ReturnedValue GlobalExtensions::method_qsTrIdNoOp(SimpleCallContext *ctx)
{
if (ctx->argumentCount < 1)
- return QV4::Value::undefinedValue();
- return ctx->arguments[0];
+ return QV4::Encode::undefined();
+ return ctx->arguments[0].asReturnedValue();
}
#endif // QT_NO_TRANSLATION
-QV4::Value GlobalExtensions::method_gc(SimpleCallContext *ctx)
+QV4::ReturnedValue GlobalExtensions::method_gc(SimpleCallContext *ctx)
{
ctx->engine->memoryManager->runGC();
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-Value GlobalExtensions::string_arg(SimpleCallContext *ctx)
+ReturnedValue GlobalExtensions::method_string_arg(SimpleCallContext *ctx)
{
- QString value = ctx->thisObject.toQString();
+ QString value = ctx->thisObject.toQStringNoThrow();
if (ctx->argumentCount != 1)
V4THROW_ERROR("String.arg(): Invalid arguments");
QV4::Value arg = ctx->arguments[0];
if (arg.isInteger())
- return Value::fromString(ctx, value.arg(arg.integerValue()));
+ return Value::fromString(ctx, value.arg(arg.integerValue())).asReturnedValue();
else if (arg.isDouble())
- return Value::fromString(ctx, value.arg(arg.doubleValue()));
+ return Value::fromString(ctx, value.arg(arg.doubleValue())).asReturnedValue();
else if (arg.isBoolean())
- return Value::fromString(ctx, value.arg(arg.booleanValue()));
+ return Value::fromString(ctx, value.arg(arg.booleanValue())).asReturnedValue();
- return Value::fromString(ctx, value.arg(arg.toQString()));
+ return Value::fromString(ctx, value.arg(arg.toQStringNoThrow())).asReturnedValue();
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index d03605f48a..070796f03c 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -68,41 +68,41 @@ struct QtObject : Object
Q_MANAGED
QtObject(ExecutionEngine *v4, QQmlEngine *qmlEngine);
- static Value method_isQtObject(SimpleCallContext *ctx);
- static Value method_rgba(SimpleCallContext *ctx);
- static Value method_hsla(SimpleCallContext *ctx);
- static Value method_colorEqual(SimpleCallContext *ctx);
- static Value method_font(SimpleCallContext *ctx);
- static Value method_rect(SimpleCallContext *ctx);
- static Value method_point(SimpleCallContext *ctx);
- static Value method_size(SimpleCallContext *ctx);
- static Value method_vector2d(SimpleCallContext *ctx);
- static Value method_vector3d(SimpleCallContext *ctx);
- static Value method_vector4d(SimpleCallContext *ctx);
- static Value method_quaternion(SimpleCallContext *ctx);
- static Value method_matrix4x4(SimpleCallContext *ctx);
- static Value method_lighter(SimpleCallContext *ctx);
- static Value method_darker(SimpleCallContext *ctx);
- static Value method_tint(SimpleCallContext *ctx);
- static Value method_formatDate(SimpleCallContext *ctx);
- static Value method_formatTime(SimpleCallContext *ctx);
- static Value method_formatDateTime(SimpleCallContext *ctx);
- static Value method_openUrlExternally(SimpleCallContext *ctx);
- static Value method_fontFamilies(SimpleCallContext *ctx);
- static Value method_md5(SimpleCallContext *ctx);
- static Value method_btoa(SimpleCallContext *ctx);
- static Value method_atob(SimpleCallContext *ctx);
- static Value method_quit(SimpleCallContext *ctx);
- static Value method_resolvedUrl(SimpleCallContext *ctx);
- static Value method_createQmlObject(SimpleCallContext *ctx);
- static Value method_createComponent(SimpleCallContext *ctx);
- static Value method_locale(SimpleCallContext *ctx);
- static Value method_binding(SimpleCallContext *ctx);
-
- static Value method_get_platform(SimpleCallContext *ctx);
- static Value method_get_application(SimpleCallContext *ctx);
+ static ReturnedValue method_isQtObject(SimpleCallContext *ctx);
+ static ReturnedValue method_rgba(SimpleCallContext *ctx);
+ static ReturnedValue method_hsla(SimpleCallContext *ctx);
+ static ReturnedValue method_colorEqual(SimpleCallContext *ctx);
+ static ReturnedValue method_font(SimpleCallContext *ctx);
+ static ReturnedValue method_rect(SimpleCallContext *ctx);
+ static ReturnedValue method_point(SimpleCallContext *ctx);
+ static ReturnedValue method_size(SimpleCallContext *ctx);
+ static ReturnedValue method_vector2d(SimpleCallContext *ctx);
+ static ReturnedValue method_vector3d(SimpleCallContext *ctx);
+ static ReturnedValue method_vector4d(SimpleCallContext *ctx);
+ static ReturnedValue method_quaternion(SimpleCallContext *ctx);
+ static ReturnedValue method_matrix4x4(SimpleCallContext *ctx);
+ static ReturnedValue method_lighter(SimpleCallContext *ctx);
+ static ReturnedValue method_darker(SimpleCallContext *ctx);
+ static ReturnedValue method_tint(SimpleCallContext *ctx);
+ static ReturnedValue method_formatDate(SimpleCallContext *ctx);
+ static ReturnedValue method_formatTime(SimpleCallContext *ctx);
+ static ReturnedValue method_formatDateTime(SimpleCallContext *ctx);
+ static ReturnedValue method_openUrlExternally(SimpleCallContext *ctx);
+ static ReturnedValue method_fontFamilies(SimpleCallContext *ctx);
+ static ReturnedValue method_md5(SimpleCallContext *ctx);
+ static ReturnedValue method_btoa(SimpleCallContext *ctx);
+ static ReturnedValue method_atob(SimpleCallContext *ctx);
+ static ReturnedValue method_quit(SimpleCallContext *ctx);
+ static ReturnedValue method_resolvedUrl(SimpleCallContext *ctx);
+ static ReturnedValue method_createQmlObject(SimpleCallContext *ctx);
+ static ReturnedValue method_createComponent(SimpleCallContext *ctx);
+ static ReturnedValue method_locale(SimpleCallContext *ctx);
+ static ReturnedValue method_binding(SimpleCallContext *ctx);
+
+ static ReturnedValue method_get_platform(SimpleCallContext *ctx);
+ static ReturnedValue method_get_application(SimpleCallContext *ctx);
#ifndef QT_NO_IM
- static Value method_get_inputMethod(SimpleCallContext *ctx);
+ static ReturnedValue method_get_inputMethod(SimpleCallContext *ctx);
#endif
QObject *m_platform;
@@ -113,17 +113,17 @@ struct ConsoleObject : Object
{
ConsoleObject(ExecutionEngine *v4);
- static Value method_error(SimpleCallContext *ctx);
- static Value method_log(SimpleCallContext *ctx);
- static Value method_profile(SimpleCallContext *ctx);
- static Value method_profileEnd(SimpleCallContext *ctx);
- static Value method_time(SimpleCallContext *ctx);
- static Value method_timeEnd(SimpleCallContext *ctx);
- static Value method_count(SimpleCallContext *ctx);
- static Value method_trace(SimpleCallContext *ctx);
- static Value method_warn(SimpleCallContext *ctx);
- static Value method_assert(SimpleCallContext *ctx);
- static Value method_exception(SimpleCallContext *ctx);
+ static ReturnedValue method_error(SimpleCallContext *ctx);
+ static ReturnedValue method_log(SimpleCallContext *ctx);
+ static ReturnedValue method_profile(SimpleCallContext *ctx);
+ static ReturnedValue method_profileEnd(SimpleCallContext *ctx);
+ static ReturnedValue method_time(SimpleCallContext *ctx);
+ static ReturnedValue method_timeEnd(SimpleCallContext *ctx);
+ static ReturnedValue method_count(SimpleCallContext *ctx);
+ static ReturnedValue method_trace(SimpleCallContext *ctx);
+ static ReturnedValue method_warn(SimpleCallContext *ctx);
+ static ReturnedValue method_assert(SimpleCallContext *ctx);
+ static ReturnedValue method_exception(SimpleCallContext *ctx);
};
@@ -131,17 +131,17 @@ struct GlobalExtensions {
static void init(QQmlEngine *qmlEngine, Object *globalObject);
#ifndef QT_NO_TRANSLATION
- static Value method_qsTranslate(SimpleCallContext *ctx);
- static Value method_qsTranslateNoOp(SimpleCallContext *ctx);
- static Value method_qsTr(SimpleCallContext *ctx);
- static Value method_qsTrNoOp(SimpleCallContext *ctx);
- static Value method_qsTrId(SimpleCallContext *ctx);
- static Value method_qsTrIdNoOp(SimpleCallContext *ctx);
+ static ReturnedValue method_qsTranslate(SimpleCallContext *ctx);
+ static ReturnedValue method_qsTranslateNoOp(SimpleCallContext *ctx);
+ static ReturnedValue method_qsTr(SimpleCallContext *ctx);
+ static ReturnedValue method_qsTrNoOp(SimpleCallContext *ctx);
+ static ReturnedValue method_qsTrId(SimpleCallContext *ctx);
+ static ReturnedValue method_qsTrIdNoOp(SimpleCallContext *ctx);
#endif
- static Value method_gc(SimpleCallContext *ctx);
+ static ReturnedValue method_gc(SimpleCallContext *ctx);
// on String:prototype
- static Value string_arg(SimpleCallContext *ctx);
+ static ReturnedValue method_string_arg(SimpleCallContext *ctx);
};
diff --git a/src/qml/qml/v8/qv4domerrors_p.h b/src/qml/qml/v8/qv4domerrors_p.h
index ed38886e15..ce6fb9edea 100644
--- a/src/qml/qml/v8/qv4domerrors_p.h
+++ b/src/qml/qml/v8/qv4domerrors_p.h
@@ -77,10 +77,10 @@ QT_BEGIN_NAMESPACE
#define DOMEXCEPTION_TYPE_MISMATCH_ERR 17
#define V4THROW_DOM(error, string) { \
- QV4::Value v = QV4::Value::fromString(ctx, QStringLiteral(string)); \
- QV4::Object *ex = ctx->engine->newErrorObject(v); \
+ QV4::ScopedValue v(scope, QV4::Value::fromString(ctx, QStringLiteral(string))); \
+ QV4::Scoped<Object> ex(scope, ctx->engine->newErrorObject(v)); \
ex->put(ctx->engine->newIdentifier(QStringLiteral("code")), QV4::Value::fromInt32(error)); \
- ctx->throwError(QV4::Value::fromObject(ex)); \
+ ctx->throwError(ex); \
}
namespace QV4 {
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 5b43dd6192..08bbd4c960 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -153,12 +153,14 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint)
}
if (QV4::ArrayObject *a = value.asArrayObject()) {
+ QV4::Scope scope(a->engine());
if (typeHint == qMetaTypeId<QList<QObject *> >()) {
QList<QObject *> list;
uint32_t length = a->arrayLength();
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope);
for (uint32_t ii = 0; ii < length; ++ii) {
- QV4::Value arrayItem = a->getIndexed(ii);
- if (QV4::QObjectWrapper *qobjectWrapper = arrayItem.as<QV4::QObjectWrapper>()) {
+ qobjectWrapper = a->getIndexed(ii);
+ if (!!qobjectWrapper) {
list << qobjectWrapper->object();
} else {
list << 0;
@@ -179,44 +181,46 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint)
return toBasicVariant(value);
}
-static QV4::Value arrayFromStringList(QV8Engine *engine, const QStringList &list)
+static QV4::ReturnedValue arrayFromStringList(QV8Engine *engine, const QStringList &list)
{
QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
- QV4::ArrayObject *a = e->newArrayObject();
+ QV4::Scope scope(e);
+ QV4::Scoped<QV4::ArrayObject> a(scope, e->newArrayObject());
int len = list.count();
a->arrayReserve(len);
a->arrayDataLen = len;
for (int ii = 0; ii < len; ++ii)
a->arrayData[ii].value = QV4::Value::fromString(e->newString(list.at(ii)));
a->setArrayLengthUnchecked(len);
- return QV4::Value::fromObject(a);
+ return a.asReturnedValue();
}
-static QV4::Value arrayFromVariantList(QV8Engine *engine, const QVariantList &list)
+static QV4::ReturnedValue arrayFromVariantList(QV8Engine *engine, const QVariantList &list)
{
QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
- QV4::ArrayObject *a = e->newArrayObject();
+ QV4::Scope scope(e);
+ QV4::Scoped<QV4::ArrayObject> a(scope, e->newArrayObject());
int len = list.count();
a->arrayReserve(len);
a->arrayDataLen = len;
for (int ii = 0; ii < len; ++ii)
- a->arrayData[ii].value = engine->fromVariant(list.at(ii));
+ a->arrayData[ii].value = QV4::Value::fromReturnedValue(engine->fromVariant(list.at(ii)));
a->setArrayLengthUnchecked(len);
- return QV4::Value::fromObject(a);
+ return a.asReturnedValue();
}
-static QV4::Value objectFromVariantMap(QV8Engine *engine, const QVariantMap &map)
+static QV4::ReturnedValue objectFromVariantMap(QV8Engine *engine, const QVariantMap &map)
{
QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
QV4::Object *o = e->newObject();
for (QVariantMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter)
- o->put(e->newString(iter.key()), engine->fromVariant(iter.value()));
- return QV4::Value::fromObject(o);
+ o->put(e->newString(iter.key()), QV4::Value::fromReturnedValue(engine->fromVariant(iter.value())));
+ return QV4::Value::fromObject(o).asReturnedValue();
}
Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
-QV4::Value QV8Engine::fromVariant(const QVariant &variant)
+QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
{
int type = variant.userType();
const void *ptr = variant.constData();
@@ -225,49 +229,50 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
switch (QMetaType::Type(type)) {
case QMetaType::UnknownType:
case QMetaType::Void:
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
case QMetaType::Bool:
- return QV4::Value::fromBoolean(*reinterpret_cast<const bool*>(ptr));
+ return QV4::Encode(*reinterpret_cast<const bool*>(ptr));
case QMetaType::Int:
- return QV4::Value::fromInt32(*reinterpret_cast<const int*>(ptr));
+ return QV4::Encode(*reinterpret_cast<const int*>(ptr));
case QMetaType::UInt:
- return QV4::Value::fromUInt32(*reinterpret_cast<const uint*>(ptr));
+ return QV4::Encode(*reinterpret_cast<const uint*>(ptr));
case QMetaType::LongLong:
- return QV4::Value::fromDouble(*reinterpret_cast<const qlonglong*>(ptr));
+ return QV4::Encode((double)*reinterpret_cast<const qlonglong*>(ptr));
case QMetaType::ULongLong:
- return QV4::Value::fromDouble(*reinterpret_cast<const qulonglong*>(ptr));
+ return QV4::Encode((double)*reinterpret_cast<const qulonglong*>(ptr));
case QMetaType::Double:
- return QV4::Value::fromDouble(*reinterpret_cast<const double*>(ptr));
+ return QV4::Encode(*reinterpret_cast<const double*>(ptr));
case QMetaType::QString:
- return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(ptr));
+ return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(ptr)).asReturnedValue();
case QMetaType::Float:
- return QV4::Value::fromDouble(*reinterpret_cast<const float*>(ptr));
+ return QV4::Encode(*reinterpret_cast<const float*>(ptr));
case QMetaType::Short:
- return QV4::Value::fromInt32(*reinterpret_cast<const short*>(ptr));
+ return QV4::Encode((int)*reinterpret_cast<const short*>(ptr));
case QMetaType::UShort:
- return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned short*>(ptr));
+ return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(ptr));
case QMetaType::Char:
- return QV4::Value::fromInt32(*reinterpret_cast<const char*>(ptr));
+ return QV4::Encode((int)*reinterpret_cast<const char*>(ptr));
case QMetaType::UChar:
- return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned char*>(ptr));
+ return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(ptr));
case QMetaType::QChar:
- return QV4::Value::fromInt32((*reinterpret_cast<const QChar*>(ptr)).unicode());
+ return QV4::Encode((int)(*reinterpret_cast<const QChar*>(ptr)).unicode());
case QMetaType::QDateTime:
- return QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(ptr)));
+ return QV4::Encode(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(ptr)));
case QMetaType::QDate:
- return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr))));
+ return QV4::Encode(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr))));
case QMetaType::QTime:
- return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr))));
+ return QV4::Encode(m_v4Engine->newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr))));
case QMetaType::QRegExp:
- return QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr)));
+ return QV4::Encode(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr)));
case QMetaType::QObjectStar:
return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(ptr));
case QMetaType::QStringList:
{
bool succeeded = false;
- QV4::Value retn = QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded);
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded));
if (succeeded)
- return retn;
+ return retn.asReturnedValue();
return arrayFromStringList(this, *reinterpret_cast<const QStringList *>(ptr));
}
case QMetaType::QVariantList:
@@ -288,13 +293,14 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
return QV4::QmlValueTypeWrapper::create(this, variant, vt);
} else {
+ QV4::Scope scope(m_v4Engine);
if (type == qMetaTypeId<QQmlListReference>()) {
typedef QQmlListReferencePrivate QDLRP;
QDLRP *p = QDLRP::get((QQmlListReference*)ptr);
if (p->object) {
return QV4::QmlListWrapper::create(this, p->property, p->propertyType);
} else {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
} else if (type == qMetaTypeId<QJSValue>()) {
const QJSValue *value = reinterpret_cast<const QJSValue *>(ptr);
@@ -304,13 +310,13 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
// XXX Can this be made more by using Array as a prototype and implementing
// directly against QList<QObject*>?
const QList<QObject *> &list = *(QList<QObject *>*)ptr;
- QV4::ArrayObject *a = m_v4Engine->newArrayObject();
+ QV4::Scoped<QV4::ArrayObject> a(scope, m_v4Engine->newArrayObject());
a->arrayReserve(list.count());
a->arrayDataLen = list.count();
for (int ii = 0; ii < list.count(); ++ii)
- a->arrayData[ii].value = QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii));
+ a->arrayData[ii].value = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii)));
a->setArrayLengthUnchecked(list.count());
- return QV4::Value::fromObject(a);
+ return a.asReturnedValue();
} else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) {
return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(ptr));
}
@@ -321,9 +327,9 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
return QV4::QObjectWrapper::wrap(m_v4Engine, obj);
bool succeeded = false;
- QV4::Value retn = QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded);
+ QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded));
if (succeeded)
- return retn;
+ return retn.asReturnedValue();
if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
return QV4::QmlValueTypeWrapper::create(this, variant, vt);
@@ -333,7 +339,7 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant)
// + QObjectList
// + QList<int>
- return QV4::Value::fromObject(m_v4Engine->newVariantObject(variant));
+ return QV4::Encode(m_v4Engine->newVariantObject(variant));
}
QNetworkAccessManager *QV8Engine::networkAccessManager()
@@ -381,11 +387,15 @@ QVariant QV8Engine::toBasicVariant(const QV4::Value &value)
if (QV4::RegExpObject *re = value.as<QV4::RegExpObject>())
return re->toQRegExp();
if (QV4::ArrayObject *a = value.asArrayObject()) {
+ QV4::Scope scope(a->engine());
+ QV4::ScopedValue v(scope);
QVariantList rv;
int length = a->arrayLength();
- for (int ii = 0; ii < length; ++ii)
- rv << toVariant(a->getIndexed(ii), -1);
+ for (int ii = 0; ii < length; ++ii) {
+ v = a->getIndexed(ii);
+ rv << toVariant(v, -1);
+ }
return rv;
}
if (!value.asFunctionObject())
@@ -398,6 +408,7 @@ QVariant QV8Engine::toBasicVariant(const QV4::Value &value)
void QV8Engine::initializeGlobal()
{
+ QV4::Scope scope(m_v4Engine);
QV4::GlobalExtensions::init(m_engine, m_v4Engine->globalObject);
QQmlLocale::registerStringLocaleCompare(m_v4Engine);
@@ -434,16 +445,17 @@ void QV8Engine::initializeGlobal()
" }"\
"})"
- QV4::Value result = QV4::Script::evaluate(m_v4Engine, QString::fromUtf8(FREEZE_SOURCE), 0);
- Q_ASSERT(result.asFunctionObject());
- m_freezeObject = result;
+ QV4::Scoped<QV4::FunctionObject> result(scope, QV4::Script::evaluate(m_v4Engine, QString::fromUtf8(FREEZE_SOURCE), 0));
+ Q_ASSERT(!!result);
+ m_freezeObject = result.asValue();
#undef FREEZE_SOURCE
}
}
void QV8Engine::freezeObject(const QV4::Value &value)
{
- QV4::ScopedCallData callData(m_v4Engine, 1);
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedCallData callData(scope, 1);
callData->args[0] = value;
callData->thisObject = QV4::Value::fromObject(m_v4Engine->globalObject);
m_freezeObject.value().asFunctionObject()->call(callData);
@@ -505,15 +517,16 @@ QV4::Value QV8Engine::global()
// The result is a new Array object with length equal to the length
// of the QVariantList, and the elements being the QVariantList's
// elements converted to JS, recursively.
-QV4::Value QV8Engine::variantListToJS(const QVariantList &lst)
+QV4::ReturnedValue QV8Engine::variantListToJS(const QVariantList &lst)
{
- QV4::ArrayObject *a = m_v4Engine->newArrayObject();
+ QV4::Scope scope(m_v4Engine);
+ QV4::Scoped<QV4::ArrayObject> a(scope, m_v4Engine->newArrayObject());
a->arrayReserve(lst.size());
a->arrayDataLen = lst.size();
for (int i = 0; i < lst.size(); i++)
- a->arrayData[i].value = variantToJS(lst.at(i));
+ a->arrayData[i].value = QV4::Value::fromReturnedValue(variantToJS(lst.at(i)));
a->setArrayLengthUnchecked(lst.size());
- return QV4::Value::fromObject(a);
+ return a.asReturnedValue();
}
// Converts a JS Array object to a QVariantList.
@@ -533,9 +546,12 @@ QVariantList QV8Engine::variantListFromJS(QV4::ArrayObject *a,
visitedObjects.insert(a);
+ QV4::Scope scope(a->engine());
+ QV4::ScopedValue v(scope);
+
quint32 length = a->arrayLength();
for (quint32 i = 0; i < length; ++i) {
- QV4::Value v = a->getIndexed(i);
+ v = a->getIndexed(i);
result.append(variantFromJS(v, visitedObjects));
}
@@ -548,15 +564,15 @@ QVariantList QV8Engine::variantListFromJS(QV4::ArrayObject *a,
// The result is a new Object object with property names being
// the keys of the QVariantMap, and values being the values of
// the QVariantMap converted to JS, recursively.
-QV4::Value QV8Engine::variantMapToJS(const QVariantMap &vmap)
+QV4::ReturnedValue QV8Engine::variantMapToJS(const QVariantMap &vmap)
{
QV4::Object *o = m_v4Engine->newObject();
QVariantMap::const_iterator it;
for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) {
QV4::Property *p = o->insertMember(m_v4Engine->newIdentifier(it.key()), QV4::Attr_Data);
- p->value = variantToJS(it.value());
+ p->value = QV4::Value::fromReturnedValue(variantToJS(it.value()));
}
- return QV4::Value::fromObject(o);
+ return QV4::Value::fromObject(o).asReturnedValue();
}
// Converts a JS Object to a QVariantMap.
@@ -577,17 +593,19 @@ QVariantMap QV8Engine::variantMapFromJS(QV4::Object *o,
// empty object (and no error is thrown).
return result;
}
+ QV4::Scope scope(o->engine());
visitedObjects.insert(o);
QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly);
+ QV4::ScopedValue name(scope);
while (1) {
QV4::Value v;
- QV4::Value name = it.nextPropertyNameAsString(&v);
- if (name.isNull())
+ name = it.nextPropertyNameAsString(&v);
+ if (name->isNull())
break;
- QString key = name.toQString();
+ QString key = name->toQStringNoThrow();
result.insert(key, variantFromJS(v, visitedObjects));
}
@@ -597,96 +615,85 @@ QVariantMap QV8Engine::variantMapFromJS(QV4::Object *o,
// Converts the meta-type defined by the given type and data to JS.
// Returns the value if conversion succeeded, an empty handle otherwise.
-QV4::Value QV8Engine::metaTypeToJS(int type, const void *data)
+QV4::ReturnedValue QV8Engine::metaTypeToJS(int type, const void *data)
{
Q_ASSERT(data != 0);
- QV4::Value result;
// check if it's one of the types we know
switch (QMetaType::Type(type)) {
case QMetaType::UnknownType:
case QMetaType::Void:
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
case QMetaType::Bool:
- return QV4::Value::fromBoolean(*reinterpret_cast<const bool*>(data));
+ return QV4::Encode(*reinterpret_cast<const bool*>(data));
case QMetaType::Int:
- return QV4::Value::fromInt32(*reinterpret_cast<const int*>(data));
+ return QV4::Encode(*reinterpret_cast<const int*>(data));
case QMetaType::UInt:
- return QV4::Value::fromUInt32(*reinterpret_cast<const uint*>(data));
+ return QV4::Encode(*reinterpret_cast<const uint*>(data));
case QMetaType::LongLong:
- return QV4::Value::fromDouble(double(*reinterpret_cast<const qlonglong*>(data)));
+ return QV4::Encode(double(*reinterpret_cast<const qlonglong*>(data)));
case QMetaType::ULongLong:
#if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804
#pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.")
- return QV4::Value::fromDouble(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
+ return QV4::Encode(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- return QV4::Value::fromDouble(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
+ return QV4::Encode(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
#else
- return QV4::Value::fromDouble(double(*reinterpret_cast<const qulonglong*>(data)));
+ return QV4::Encode(double(*reinterpret_cast<const qulonglong*>(data)));
#endif
case QMetaType::Double:
- return QV4::Value::fromDouble(*reinterpret_cast<const double*>(data));
+ return QV4::Encode(*reinterpret_cast<const double*>(data));
case QMetaType::QString:
- return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(data));
+ return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(data)).asReturnedValue();
case QMetaType::Float:
- return QV4::Value::fromDouble(*reinterpret_cast<const float*>(data));
+ return QV4::Encode(*reinterpret_cast<const float*>(data));
case QMetaType::Short:
- return QV4::Value::fromInt32(*reinterpret_cast<const short*>(data));
+ return QV4::Encode((int)*reinterpret_cast<const short*>(data));
case QMetaType::UShort:
- return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned short*>(data));
+ return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(data));
case QMetaType::Char:
- return QV4::Value::fromInt32(*reinterpret_cast<const char*>(data));
+ return QV4::Encode((int)*reinterpret_cast<const char*>(data));
case QMetaType::UChar:
- return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned char*>(data));
+ return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(data));
case QMetaType::QChar:
- return QV4::Value::fromUInt32((*reinterpret_cast<const QChar*>(data)).unicode());
+ return QV4::Encode((int)(*reinterpret_cast<const QChar*>(data)).unicode());
case QMetaType::QStringList:
- result = QV4::Value::fromObject(m_v4Engine->newArrayObject(*reinterpret_cast<const QStringList *>(data)));
- break;
+ return QV4::Encode(m_v4Engine->newArrayObject(*reinterpret_cast<const QStringList *>(data)));
case QMetaType::QVariantList:
- result = variantListToJS(*reinterpret_cast<const QVariantList *>(data));
- break;
+ return variantListToJS(*reinterpret_cast<const QVariantList *>(data));
case QMetaType::QVariantMap:
- result = variantMapToJS(*reinterpret_cast<const QVariantMap *>(data));
- break;
+ return variantMapToJS(*reinterpret_cast<const QVariantMap *>(data));
case QMetaType::QDateTime:
- result = QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(data)));
- break;
+ return QV4::Encode(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(data)));
case QMetaType::QDate:
- result = QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(data))));
- break;
+ return QV4::Encode(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(data))));
case QMetaType::QRegExp:
- result = QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(data)));
- break;
+ return QV4::Encode(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(data)));
case QMetaType::QObjectStar:
- result = QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(data));
- break;
+ return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(data));
case QMetaType::QVariant:
- result = variantToJS(*reinterpret_cast<const QVariant*>(data));
- break;
+ return variantToJS(*reinterpret_cast<const QVariant*>(data));
case QMetaType::QJsonValue:
- result = QV4::JsonObject::fromJsonValue(m_v4Engine, *reinterpret_cast<const QJsonValue *>(data));
- break;
+ return QV4::JsonObject::fromJsonValue(m_v4Engine, *reinterpret_cast<const QJsonValue *>(data));
case QMetaType::QJsonObject:
- result = QV4::JsonObject::fromJsonObject(m_v4Engine, *reinterpret_cast<const QJsonObject *>(data));
- break;
+ return QV4::JsonObject::fromJsonObject(m_v4Engine, *reinterpret_cast<const QJsonObject *>(data));
case QMetaType::QJsonArray:
- result = QV4::JsonObject::fromJsonArray(m_v4Engine, *reinterpret_cast<const QJsonArray *>(data));
- break;
+ return QV4::JsonObject::fromJsonArray(m_v4Engine, *reinterpret_cast<const QJsonArray *>(data));
default:
if (type == qMetaTypeId<QJSValue>()) {
return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->getValue(m_v4Engine);
} else {
QByteArray typeName = QMetaType::typeName(type);
if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(data)) {
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
} else {
// Fall back to wrapping in a QVariant.
- result = QV4::Value::fromObject(m_v4Engine->newVariantObject(QVariant(type, data)));
+ return QV4::Encode(m_v4Engine->newVariantObject(QVariant(type, data)));
}
}
}
- return result;
+ Q_UNREACHABLE();
+ return 0;
}
// Converts a JS value to a meta-type.
@@ -863,7 +870,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) {
}
// Converts a QVariant to JS.
-QV4::Value QV8Engine::variantToJS(const QVariant &value)
+QV4::ReturnedValue QV8Engine::variantToJS(const QVariant &value)
{
return metaTypeToJS(value.userType(), value.constData());
}
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index 8f724fa2eb..3209e55434 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -121,14 +121,16 @@ namespace QV4 {
// valid during the call. If the return value isn't set within myMethod(), the will return
// undefined.
class QV8Engine;
+// ### GC
class QQmlV4Function
{
public:
int length() const { return argc; }
- QV4::Value operator[](int idx) { return args[idx]; }
+ QV4::Value operator[](int idx) { return idx < argc ? args[idx] : QV4::Value::undefinedValue(); }
QQmlContextData *context() { return ctx; }
QV4::Value qmlGlobal() { return global; }
void setReturnValue(const QV4::Value &rv) { *retVal = rv; }
+ void setReturnValue(QV4::ReturnedValue rv) { *retVal = QV4::Value::fromReturnedValue(rv); }
QV8Engine *engine() const { return e; }
private:
friend struct QV4::QObjectMethod;
@@ -149,6 +151,7 @@ private:
QV8Engine *e;
};
+// ### GC
class Q_QML_PRIVATE_EXPORT QQmlV4Handle
{
public:
@@ -210,7 +213,7 @@ public:
void freezeObject(const QV4::Value &value);
QVariant toVariant(const QV4::Value &value, int typeHint);
- QV4::Value fromVariant(const QVariant &);
+ QV4::ReturnedValue fromVariant(const QVariant &);
// Return a JS string for the given QString \a string
QV4::Value toString(const QString &string);
@@ -232,19 +235,19 @@ public:
inline Deletable *extensionData(int) const;
void setExtensionData(int, Deletable *);
- QV4::Value variantListToJS(const QVariantList &lst);
+ QV4::ReturnedValue variantListToJS(const QVariantList &lst);
inline QVariantList variantListFromJS(QV4::ArrayObject *array)
{ V8ObjectSet visitedObjects; return variantListFromJS(array, visitedObjects); }
- QV4::Value variantMapToJS(const QVariantMap &vmap);
+ QV4::ReturnedValue variantMapToJS(const QVariantMap &vmap);
inline QVariantMap variantMapFromJS(QV4::Object *object)
{ V8ObjectSet visitedObjects; return variantMapFromJS(object, visitedObjects); }
- QV4::Value variantToJS(const QVariant &value);
+ QV4::ReturnedValue variantToJS(const QVariant &value);
inline QVariant variantFromJS(const QV4::Value &value)
{ V8ObjectSet visitedObjects; return variantFromJS(value, visitedObjects); }
- QV4::Value metaTypeToJS(int type, const void *data);
+ QV4::ReturnedValue metaTypeToJS(int type, const void *data);
bool metaTypeFromJS(const QV4::Value &value, int type, void *data);
bool convertToNativeQObject(const QV4::Value &value,
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index bc52da6151..0457adb348 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -63,10 +63,10 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
{
Q_MANAGED
- QV4::Value (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg);
+ QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg);
uint flag;
- DelegateModelGroupFunction(QV4::ExecutionContext *scope, uint flag, QV4::Value (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg))
+ DelegateModelGroupFunction(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg))
: FunctionObject(scope, /*name*/0)
, code(code)
, flag(flag)
@@ -75,13 +75,13 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
isBuiltinFunction = true;
}
- static QV4::Value construct(QV4::Managed *m, QV4::CallData *)
+ static QV4::ReturnedValue construct(QV4::Managed *m, QV4::CallData *)
{
m->engine()->current->throwTypeError();
- return QV4::Value::undefinedValue();
+ return QV4::Value::undefinedValue().asReturnedValue();
}
- static QV4::Value call(QV4::Managed *that, QV4::CallData *callData)
+ static QV4::ReturnedValue call(QV4::Managed *that, QV4::CallData *callData)
{
DelegateModelGroupFunction *f = static_cast<DelegateModelGroupFunction *>(that);
QQmlDelegateModelItemObject *o = callData->thisObject.as<QQmlDelegateModelItemObject>();
@@ -1550,13 +1550,16 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
if (!o)
return false;
+ QV4::Scope scope(o->engine());
+
QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly|QV4::ObjectIterator::WithProtoChain);
+ QV4::ScopedValue propertyName(scope);
while (1) {
QV4::Value value;
- QV4::Value propertyName = it.nextPropertyNameAsString(&value);
- if (propertyName.isNull())
+ propertyName = it.nextPropertyNameAsString(&value);
+ if (propertyName->isNull())
break;
- cacheItem->setValue(propertyName.toQString(), m_cacheMetaType->v8Engine->toVariant(value, QVariant::Invalid));
+ cacheItem->setValue(propertyName->toQStringNoThrow(), m_cacheMetaType->v8Engine->toVariant(value, QVariant::Invalid));
}
cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag;
@@ -1676,9 +1679,12 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const
if (index != -1)
groupFlags |= 2 << index;
} else if (QV4::ArrayObject *array = groups.asArrayObject()) {
+ QV4::Scope scope(array->engine());
+ QV4::ScopedValue v(scope);
uint arrayLength = array->arrayLength();
for (uint i = 0; i < arrayLength; ++i) {
- const QString groupName = array->getIndexed(i).toQString();
+ v = array->getIndexed(i);
+ const QString groupName = v->toQStringNoThrow();
int index = groupNames.indexOf(groupName);
if (index != -1)
groupFlags |= 2 << index;
@@ -1687,18 +1693,18 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const
return groupFlags;
}
-QV4::Value QQmlDelegateModelItem::get_model(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDelegateModelItem::get_model(QV4::SimpleCallContext *ctx)
{
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o)
ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
if (!o->item->metaType->model)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
return o->item->get();
}
-QV4::Value QQmlDelegateModelItem::get_groups(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::SimpleCallContext *ctx)
{
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o)
@@ -1713,7 +1719,7 @@ QV4::Value QQmlDelegateModelItem::get_groups(QV4::SimpleCallContext *ctx)
return ctx->engine->v8Engine->fromVariant(groups);
}
-QV4::Value QQmlDelegateModelItem::set_groups(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::SimpleCallContext *ctx)
{
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o)
@@ -1722,32 +1728,32 @@ QV4::Value QQmlDelegateModelItem::set_groups(QV4::SimpleCallContext *ctx)
ctx->throwTypeError();
if (!o->item->metaType->model)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(o->item->metaType->model);
const int groupFlags = model->m_cacheMetaType->parseGroups(ctx->arguments[0]);
const int cacheIndex = model->m_cache.indexOf(o->item);
Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
model->setGroups(it, 1, Compositor::Cache, groupFlags);
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
+QV4::ReturnedValue QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
{
- return QV4::Value::fromBoolean(thisItem->groups & (1 << flag));
+ return QV4::Encode(bool(thisItem->groups & (1 << flag)));
}
-QV4::Value QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, uint flag, const QV4::Value &arg)
+QV4::ReturnedValue QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, uint flag, const QV4::Value &arg)
{
if (!cacheItem->metaType->model)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(cacheItem->metaType->model);
bool member = arg.toBoolean();
uint groupFlag = (1 << flag);
if (member == ((cacheItem->groups & groupFlag) != 0))
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
const int cacheIndex = model->m_cache.indexOf(cacheItem);
Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
@@ -1755,12 +1761,12 @@ QV4::Value QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, u
model->addGroups(it, 1, Compositor::Cache, groupFlag);
else
model->removeGroups(it, 1, Compositor::Cache, groupFlag);
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
+QV4::ReturnedValue QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
{
- return QV4::Value::fromInt32(thisItem->groupIndex(Compositor::Group(flag)));
+ return QV4::Encode((int)thisItem->groupIndex(Compositor::Group(flag)));
}
@@ -3103,25 +3109,25 @@ struct QQmlDelegateModelGroupChange : QV4::Object
vtbl = &static_vtbl;
}
- static QV4::Value method_get_index(QV4::SimpleCallContext *ctx) {
+ static QV4::ReturnedValue method_get_index(QV4::SimpleCallContext *ctx) {
QQmlDelegateModelGroupChange *that = ctx->thisObject.as<QQmlDelegateModelGroupChange>();
if (!that)
ctx->throwTypeError();
- return QV4::Value::fromInt32(that->change.index);
+ return QV4::Encode(that->change.index);
}
- static QV4::Value method_get_count(QV4::SimpleCallContext *ctx) {
+ static QV4::ReturnedValue method_get_count(QV4::SimpleCallContext *ctx) {
QQmlDelegateModelGroupChange *that = ctx->thisObject.as<QQmlDelegateModelGroupChange>();
if (!that)
ctx->throwTypeError();
- return QV4::Value::fromInt32(that->change.count);
+ return QV4::Encode(that->change.count);
}
- static QV4::Value method_get_moveId(QV4::SimpleCallContext *ctx) {
+ static QV4::ReturnedValue method_get_moveId(QV4::SimpleCallContext *ctx) {
QQmlDelegateModelGroupChange *that = ctx->thisObject.as<QQmlDelegateModelGroupChange>();
if (!that)
ctx->throwTypeError();
if (that->change.moveId < 0)
- return QV4::Value::undefinedValue();
- return QV4::Value::fromInt32(that->change.moveId);
+ return QV4::Encode::undefined();
+ return QV4::Encode(that->change.moveId);
}
QQmlChangeSet::Change change;
@@ -3143,7 +3149,7 @@ public:
virtual quint32 count() const = 0;
virtual const QQmlChangeSet::Change &at(int index) const = 0;
- static QV4::Value getIndexed(QV4::Managed *m, uint index, bool *hasProperty)
+ static QV4::ReturnedValue getIndexed(QV4::Managed *m, uint index, bool *hasProperty)
{
QV4::ExecutionEngine *v4 = m->engine();
QQmlDelegateModelGroupChangeArray *array = m->as<QQmlDelegateModelGroupChangeArray>();
@@ -3153,7 +3159,7 @@ public:
if (index >= array->count()) {
if (hasProperty)
*hasProperty = false;
- return QV4::Value::undefinedValue();
+ return QV4::Value::undefinedValue().asReturnedValue();
}
const QQmlChangeSet::Change &change = array->at(index);
@@ -3165,10 +3171,10 @@ public:
if (hasProperty)
*hasProperty = true;
- return QV4::Value::fromObject(object);
+ return QV4::Value::fromObject(object).asReturnedValue();
}
- static QV4::Value get(QV4::Managed *m, QV4::String *name, bool *hasProperty)
+ static QV4::ReturnedValue get(QV4::Managed *m, QV4::String *name, bool *hasProperty)
{
QQmlDelegateModelGroupChangeArray *array = m->as<QQmlDelegateModelGroupChangeArray>();
if (!array)
@@ -3177,7 +3183,7 @@ public:
if (name == m->engine()->id_length) {
if (hasProperty)
*hasProperty = true;
- return QV4::Value::fromInt32(array->count());
+ return QV4::Encode(array->count());
}
return Object::get(m, name, hasProperty);
diff --git a/src/qml/types/qqmldelegatemodel_p.h b/src/qml/types/qqmldelegatemodel_p.h
index 6f2acf0924..51f846ea0b 100644
--- a/src/qml/types/qqmldelegatemodel_p.h
+++ b/src/qml/types/qqmldelegatemodel_p.h
@@ -210,7 +210,7 @@ public:
void emitChanges();
- void emitUnresolvedChanged() { emit unresolvedChanged(); }
+ void emitUnresolvedChanged() { Q_EMIT unresolvedChanged(); }
Q_SIGNALS:
void groupsChanged();
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index 7931c4e18c..aa4e0c30e2 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -126,19 +126,19 @@ public:
int groupIndex(Compositor::Group group);
int modelIndex() const { return index; }
- void setModelIndex(int idx) { index = idx; emit modelIndexChanged(); }
+ void setModelIndex(int idx) { index = idx; Q_EMIT modelIndexChanged(); }
- virtual QV4::Value get() { return QV4::QObjectWrapper::wrap(v4, this); }
+ virtual QV4::ReturnedValue get() { return QV4::QObjectWrapper::wrap(v4, this); }
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::Value get_model(QV4::SimpleCallContext *ctx);
- static QV4::Value get_groups(QV4::SimpleCallContext *ctx);
- static QV4::Value set_groups(QV4::SimpleCallContext *ctx);
- static QV4::Value get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &);
- static QV4::Value set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
- static QV4::Value get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
+ static QV4::ReturnedValue get_model(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue get_groups(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue set_groups(QV4::SimpleCallContext *ctx);
+ 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);
QV4::ExecutionEngine *v4;
QQmlDelegateModelItemMetaType * const metaType;
@@ -260,11 +260,11 @@ public:
void emitCreatedPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
void emitInitPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
void emitCreatedItem(QQDMIncubationTask *incubationTask, QObject *item) {
- emit q_func()->createdItem(incubationTask->index[m_compositorGroup], item); }
+ Q_EMIT q_func()->createdItem(incubationTask->index[m_compositorGroup], item); }
void emitInitItem(QQDMIncubationTask *incubationTask, QObject *item) {
- emit q_func()->initItem(incubationTask->index[m_compositorGroup], item); }
+ Q_EMIT q_func()->initItem(incubationTask->index[m_compositorGroup], item); }
void emitDestroyingPackage(QQuickPackage *package);
- void emitDestroyingItem(QObject *item) { emit q_func()->destroyingItem(item); }
+ void emitDestroyingItem(QObject *item) { Q_EMIT q_func()->destroyingItem(item); }
void removeCacheItem(QQmlDelegateModelItem *cacheItem);
void updateFilterGroup();
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 067d91ea7f..20d1211716 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -414,10 +414,14 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles,
ListElement *e = elements[elementIndex];
QV4::ExecutionEngine *v4 = object->engine();
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> o(scope);
+
QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
+ QV4::Scoped<QV4::String> propertyName(scope);
while (1) {
QV4::Value propertyValue;
- QV4::String *propertyName = it.nextPropertyNameAsString(&propertyValue).asString();
+ propertyName = it.nextPropertyNameAsString(&propertyValue);
if (!propertyName)
break;
@@ -426,42 +430,42 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles,
// Add the value now
if (QV4::String *s = propertyValue.asString()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::String);
roleIndex = e->setStringProperty(r, s->toQString());
} else if (propertyValue.isNumber()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Number);
roleIndex = e->setDoubleProperty(r, propertyValue.asDouble());
} else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::List);
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
int arrayLength = a->arrayLength();
for (int j=0 ; j < arrayLength ; ++j) {
- QV4::Object *subObject = a->getIndexed(j).asObject();
- subModel->append(subObject, eng);
+ o = a->getIndexed(j);
+ subModel->append(o.getPointer(), eng);
}
roleIndex = e->setListProperty(r, subModel);
} else if (propertyValue.isBoolean()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Bool);
roleIndex = e->setBoolProperty(r, propertyValue.booleanValue());
} else if (QV4::DateObject *dd = propertyValue.asDateObject()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::DateTime);
QDateTime dt = dd->toQDateTime();
roleIndex = e->setDateTimeProperty(r, dt);
} else if (QV4::Object *o = propertyValue.asObject()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
QObject *o = wrapper->object();
- const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject);
+ const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::QObject);
if (role.type == ListLayout::Role::QObject)
roleIndex = e->setQObjectProperty(role, o);
} else {
- const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap);
+ const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::VariantMap);
if (role.type == ListLayout::Role::VariantMap)
roleIndex = e->setVariantMapProperty(role, o, eng);
}
} else if (propertyValue.isEmpty() || propertyValue.isUndefined() || propertyValue.isNull()) {
- const ListLayout::Role *r = m_layout->getExistingRole(propertyName);
+ const ListLayout::Role *r = m_layout->getExistingRole(propertyName.getPointer());
if (r)
e->clearProperty(*r);
}
@@ -480,43 +484,47 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng)
ListElement *e = elements[elementIndex];
QV4::ExecutionEngine *v4 = object->engine();
+ QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> o(scope);
+
QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
+ QV4::Scoped<QV4::String> propertyName(scope);
while (1) {
QV4::Value propertyValue;
- QV4::String *propertyName = it.nextPropertyNameAsString(&propertyValue).asString();
+ propertyName = it.nextPropertyNameAsString(&propertyValue);
if (!propertyName)
break;
// Add the value now
if (QV4::String *s = propertyValue.asString()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::String);
if (r.type == ListLayout::Role::String)
e->setStringPropertyFast(r, s->toQString());
} else if (propertyValue.isNumber()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Number);
if (r.type == ListLayout::Role::Number) {
e->setDoublePropertyFast(r, propertyValue.asDouble());
}
} else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::List);
if (r.type == ListLayout::Role::List) {
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
int arrayLength = a->arrayLength();
for (int j=0 ; j < arrayLength ; ++j) {
- QV4::Object *subObject = a->getIndexed(j).asObject();
- subModel->append(subObject, eng);
+ o = a->getIndexed(j);
+ subModel->append(o.getPointer(), eng);
}
e->setListPropertyFast(r, subModel);
}
} else if (propertyValue.isBoolean()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Bool);
if (r.type == ListLayout::Role::Bool) {
e->setBoolPropertyFast(r, propertyValue.booleanValue());
}
} else if (QV4::DateObject *dd = propertyValue.asDateObject()) {
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::DateTime);
if (r.type == ListLayout::Role::DateTime) {
QDateTime dt = dd->toQDateTime();;
e->setDateTimePropertyFast(r, dt);
@@ -524,16 +532,16 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng)
} else if (QV4::Object *o = propertyValue.asObject()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
QObject *o = wrapper->object();
- const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject);
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::QObject);
if (r.type == ListLayout::Role::QObject)
e->setQObjectPropertyFast(r, o);
} else {
- const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap);
+ const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::VariantMap);
if (role.type == ListLayout::Role::VariantMap)
e->setVariantMapFast(role, o, eng);
}
} else if (propertyValue.isEmpty() || propertyValue.isUndefined() || propertyValue.isNull()) {
- const ListLayout::Role *r = m_layout->getExistingRole(propertyName);
+ const ListLayout::Role *r = m_layout->getExistingRole(propertyName.getPointer());
if (r)
e->clearProperty(*r);
}
@@ -1164,11 +1172,14 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
roleIndex = setDoubleProperty(role, d.asDouble());
} else if (QV4::ArrayObject *a = d.asArrayObject()) {
if (role.type == ListLayout::Role::List) {
+ QV4::Scope scope(a->engine());
+ QV4::Scoped<QV4::Object> o(scope);
+
ListModel *subModel = new ListModel(role.subLayout, 0, -1);
int arrayLength = a->arrayLength();
for (int j=0 ; j < arrayLength ; ++j) {
- QV4::Object *subObject = a->getIndexed(j).asObject();
- subModel->append(subObject, eng);
+ o = a->getIndexed(j);
+ subModel->append(o.getPointer(), eng);
}
roleIndex = setListProperty(role, subModel);
} else {
@@ -1243,7 +1254,8 @@ void ModelNodeMetaObject::propertyWritten(int index)
QString propName = QString::fromUtf8(name(index));
QVariant value = operator[](index);
- QV4::Value v = eng->fromVariant(value);
+ QV4::Scope scope(QV8Engine::getV4((eng)));
+ QV4::ScopedValue v(scope, eng->fromVariant(value));
int roleIndex = m_obj->m_model->m_listModel->setExistingProperty(m_obj->m_elementIndex, propName, v, eng);
if (roleIndex != -1) {
@@ -1924,14 +1936,17 @@ void QQmlListModel::insert(QQmlV4Function *args)
QV4::Value arg1 = (*args)[1];
if (QV4::ArrayObject *objectArray = arg1.asArrayObject()) {
+ QV4::Scope scope(objectArray->engine());
+ QV4::Scoped<QV4::Object> argObject(scope);
+
int objectArrayLength = objectArray->arrayLength();
for (int i=0 ; i < objectArrayLength ; ++i) {
- QV4::Object *argObject = objectArray->getIndexed(i).asObject();
+ argObject = objectArray->getIndexed(i);
if (m_dynamicRoles) {
- m_modelObjects.insert(index+i, DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this));
+ m_modelObjects.insert(index+i, DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject.getPointer()), this));
} else {
- m_listModel->insert(index+i, argObject, args->engine());
+ m_listModel->insert(index+i, argObject.getPointer(), args->engine());
}
}
emitItemsInserted(index, objectArrayLength);
@@ -2022,16 +2037,19 @@ void QQmlListModel::append(QQmlV4Function *args)
QV4::Value arg = (*args)[0];
if (QV4::ArrayObject *objectArray = arg.asArrayObject()) {
+ QV4::Scope scope(objectArray->engine());
+ QV4::Scoped<QV4::Object> argObject(scope);
+
int objectArrayLength = objectArray->arrayLength();
int index = count();
for (int i=0 ; i < objectArrayLength ; ++i) {
- QV4::Object *argObject = objectArray->getIndexed(i).asObject();
+ argObject = objectArray->getIndexed(i);
if (m_dynamicRoles) {
- m_modelObjects.append(DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this));
+ m_modelObjects.append(DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject.getPointer()), this));
} else {
- m_listModel->append(argObject, args->engine());
+ m_listModel->append(argObject.getPointer(), args->engine());
}
}
@@ -2088,10 +2106,11 @@ void QQmlListModel::append(QQmlV4Function *args)
*/
QQmlV4Handle QQmlListModel::get(int index) const
{
- QV4::Value result = QV4::Value::undefinedValue();
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine());
+ QV4::Scope scope(v4);
+ QV4::ScopedValue result(scope, QV4::Value::undefinedValue());
if (index >= 0 && index < count()) {
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine());
if (m_dynamicRoles) {
DynamicRoleModelNode *object = m_modelObjects[index];
diff --git a/src/qml/types/qqmlobjectmodel_p.h b/src/qml/types/qqmlobjectmodel_p.h
index 59a4a551a7..ddc917717a 100644
--- a/src/qml/types/qqmlobjectmodel_p.h
+++ b/src/qml/types/qqmlobjectmodel_p.h
@@ -138,7 +138,7 @@ public:
void setIndex(int idx) {
if (m_index != idx) {
m_index = idx;
- emit indexChanged();
+ Q_EMIT indexChanged();
}
}
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 26514ac6db..4e39682d84 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -181,7 +181,7 @@ public:
int m_nextId;
- static QV4::Value sendMessage(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_sendMessage(QV4::SimpleCallContext *ctx);
signals:
void stopThread();
@@ -228,13 +228,14 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
"}); "\
"})"
+ QV4::Scope scope(m_v4Engine);
onmessage = QV4::Script(m_v4Engine->rootContext, CALL_ONMESSAGE_SCRIPT).run();
QV4::Script createsendscript(m_v4Engine->rootContext, SEND_MESSAGE_CREATE_SCRIPT);
- QV4::FunctionObject *createsendconstructor = createsendscript.run().asFunctionObject();
+ QV4::Scoped<QV4::FunctionObject> createsendconstructor(scope, createsendscript.run());
QV4::Value function = QV4::Value::fromObject(m_v4Engine->newBuiltinFunction(m_v4Engine->rootContext, m_v4Engine->newString(QStringLiteral("sendMessage")),
- QQuickWorkerScriptEnginePrivate::sendMessage));
- QV4::ScopedCallData callData(m_v4Engine, 1);
+ QQuickWorkerScriptEnginePrivate::method_sendMessage));
+ QV4::ScopedCallData callData(scope, 1);
callData->args[0] = function;
callData->thisObject = global();
createsend = createsendconstructor->call(callData);
@@ -244,10 +245,12 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
QV4::Value QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(int id)
{
QV4::FunctionObject *f = createsend.value().asFunctionObject();
- QV4::Value v = QV4::Value::undefinedValue();
- QV4::ExecutionContext *ctx = f->internalClass->engine->current;
+ QV4::ExecutionContext *ctx = f->engine()->current;
+ QV4::Scope scope(ctx->engine);
+
+ QV4::ScopedValue v(scope);
try {
- QV4::ScopedCallData callData(m_v4Engine, 1);
+ QV4::ScopedCallData callData(scope, 1);
callData->args[0] = QV4::Value::fromInt32(id);
callData->thisObject = global();
v = f->call(callData);
@@ -275,7 +278,7 @@ QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *eng
{
}
-QV4::Value QQuickWorkerScriptEnginePrivate::sendMessage(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(QV4::SimpleCallContext *ctx)
{
WorkerEngine *engine = (WorkerEngine*)ctx->engine->v8Engine;
@@ -286,12 +289,12 @@ QV4::Value QQuickWorkerScriptEnginePrivate::sendMessage(QV4::SimpleCallContext *
QMutexLocker locker(&engine->p->m_lock);
WorkerScript *script = engine->p->workers.value(id);
if (!script)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
if (script->owner)
QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data));
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
// Requires handle scope and context scope
@@ -346,13 +349,14 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d
if (!script)
return;
- QV4::Value value = QV4::Serialize::deserialize(data, workerEngine);
-
QV4::FunctionObject *f = workerEngine->onmessage.value().asFunctionObject();
QV4::ExecutionContext *ctx = f->internalClass->engine->current;
+ QV4::Scope scope(ctx);
+
+ QV4::ScopedValue value(scope, QV4::Serialize::deserialize(data, workerEngine));
try {
- QV4::ScopedCallData callData(ctx->engine, 2);
+ QV4::ScopedCallData callData(scope, 2);
callData->thisObject = workerEngine->global();
callData->args[0] = script->object.value();
callData->args[1] = value;
@@ -721,7 +725,8 @@ bool QQuickWorkerScript::event(QEvent *event)
if (engine) {
WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
QV8Engine *v8engine = QQmlEnginePrivate::get(engine)->v8engine();
- QV4::Value value = QV4::Serialize::deserialize(workerEvent->data(), v8engine);
+ QV4::Scope scope(QV8Engine::getV4(v8engine));
+ QV4::ScopedValue value(scope, QV4::Serialize::deserialize(workerEvent->data(), v8engine));
emit message(QQmlV4Handle(value));
}
return true;
diff --git a/src/qml/types/qquickworkerscript_p.h b/src/qml/types/qquickworkerscript_p.h
index bf23a3f2a2..e2f705c762 100644
--- a/src/qml/types/qquickworkerscript_p.h
+++ b/src/qml/types/qquickworkerscript_p.h
@@ -99,10 +99,10 @@ public:
QUrl source() const;
void setSource(const QUrl &);
-public slots:
+public Q_SLOTS:
void sendMessage(QQmlV4Function*);
-signals:
+Q_SIGNALS:
void sourceChanged();
void message(const QQmlV4Handle &messageObject);
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index ffd9de0e16..9812e2a4a6 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -63,13 +63,13 @@ public:
V8_DEFINE_EXTENSION(QQmlAdaptorModelEngineData, engineData)
-static QV4::Value get_index(QV4::SimpleCallContext *ctx)
+static QV4::ReturnedValue get_index(QV4::SimpleCallContext *ctx)
{
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o)
ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- return QV4::Value::fromInt32(o->item->index);
+ return QV4::Encode(o->item->index);
}
template <typename T, typename M> static void setModelDataType(QMetaObjectBuilder *builder, M *metaType)
@@ -107,8 +107,8 @@ public:
void setValue(const QString &role, const QVariant &value);
bool resolveIndex(const QQmlAdaptorModel &model, int idx);
- static QV4::Value get_property(QV4::SimpleCallContext *ctx, uint propertyId);
- static QV4::Value set_property(QV4::SimpleCallContext *ctx, uint propertyId);
+ static QV4::ReturnedValue get_property(QV4::SimpleCallContext *ctx, uint propertyId);
+ static QV4::ReturnedValue set_property(QV4::SimpleCallContext *ctx, uint propertyId);
VDMModelDelegateDataType *type;
QVector<QVariant> cachedData;
@@ -194,7 +194,7 @@ public:
dataType->watchedRoles += newRoles;
}
- static QV4::Value get_hasModelChildren(QV4::SimpleCallContext *ctx)
+ static QV4::ReturnedValue get_hasModelChildren(QV4::SimpleCallContext *ctx)
{
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o)
@@ -203,9 +203,9 @@ public:
const QQmlAdaptorModel *const model = static_cast<QQmlDMCachedModelData *>(o->item)->type->model;
if (o->item->index >= 0 && *model) {
const QAbstractItemModel * const aim = model->aim();
- return QV4::Value::fromBoolean(aim->hasChildren(aim->index(o->item->index, 0, model->rootIndex)));
+ return QV4::Encode(aim->hasChildren(aim->index(o->item->index, 0, model->rootIndex)));
} else {
- return QV4::Value::fromBoolean(false);
+ return QV4::Encode(false);
}
}
@@ -341,7 +341,7 @@ bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &, int idx)
}
}
-QV4::Value QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint propertyId)
+QV4::ReturnedValue QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint propertyId)
{
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o)
@@ -357,10 +357,10 @@ QV4::Value QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint
return ctx->engine->v8Engine->fromVariant(
modelData->value(modelData->type->propertyRoles.at(propertyId)));
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint propertyId)
+QV4::ReturnedValue QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint propertyId)
{
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o)
@@ -381,6 +381,7 @@ QV4::Value QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint
}
}
}
+ return QV4::Encode::undefined();
}
//-----------------------------------------------------------------
@@ -421,7 +422,7 @@ public:
type->model->aim()->index(index, 0, type->model->rootIndex), value, role);
}
- QV4::Value get()
+ QV4::ReturnedValue get()
{
if (type->prototype.isEmpty()) {
QQmlAdaptorModelEngineData * const data = engineData(v4->v8Engine);
@@ -432,7 +433,7 @@ public:
o->setPrototype(proto);
QV4::Value data = QV4::Value::fromObject(o);
++scriptRef;
- return data;
+ return data.asReturnedValue();
}
};
@@ -578,7 +579,7 @@ public:
}
}
- static QV4::Value get_modelData(QV4::SimpleCallContext *ctx)
+ static QV4::ReturnedValue get_modelData(QV4::SimpleCallContext *ctx)
{
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o)
@@ -587,7 +588,7 @@ public:
return ctx->engine->v8Engine->fromVariant(static_cast<QQmlDMListAccessorData *>(o->item)->cachedData);
}
- static QV4::Value set_modelData(QV4::SimpleCallContext *ctx)
+ static QV4::ReturnedValue set_modelData(QV4::SimpleCallContext *ctx)
{
QQmlDelegateModelItemObject *o = ctx->thisObject.as<QQmlDelegateModelItemObject>();
if (!o)
@@ -596,16 +597,17 @@ public:
ctx->throwTypeError();
static_cast<QQmlDMListAccessorData *>(o->item)->setModelData(ctx->engine->v8Engine->toVariant(ctx->arguments[0], QVariant::Invalid));
+ return QV4::Encode::undefined();
}
- QV4::Value get()
+ QV4::ReturnedValue get()
{
QQmlAdaptorModelEngineData *data = engineData(v4->v8Engine);
QV4::Object *o = new (v4->memoryManager) QQmlDelegateModelItemObject(v4, this);
o->setPrototype(data->listItemProto.value().asObject());
QV4::Value val = QV4::Value::fromObject(o);
++scriptRef;
- return val;
+ return val.asReturnedValue();
}
void setValue(const QString &role, const QVariant &value)
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp
index d33687d248..67e80e7a0d 100644
--- a/src/qmltest/quicktestresult.cpp
+++ b/src/qmltest/quicktestresult.cpp
@@ -59,6 +59,8 @@
#include <QtGui/qvector3d.h>
#include <QtQml/private/qqmlglobal_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
static const char *globalProgramName = 0;
@@ -503,7 +505,7 @@ void QuickTestResult::stringify(QQmlV4Function *args)
result = QLatin1String("Object");
}
} else {
- QString tmp = value.toQString();
+ QString tmp = value.toQStringNoThrow();
if (value.asArrayObject())
result.append(QString::fromLatin1("[%1]").arg(tmp));
else
@@ -625,7 +627,7 @@ static QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container)
return container.at(0);
QList<QBenchmarkResult> containerCopy = container;
- qSort(containerCopy);
+ std::sort(containerCopy.begin(), containerCopy.end());
const int middle = count / 2;
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 52281a4fbc..bf1cff460d 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -660,12 +660,13 @@ void QQuickCanvasItem::updatePolish()
QMap<int, QV4::PersistentValue> animationCallbacks = d->animationCallbacks;
d->animationCallbacks.clear();
+ QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this));
+ QV4::Scope scope(v4);
+ QV4::ScopedCallData callData(scope, 1);
+ callData->thisObject = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, this));
+
foreach (int key, animationCallbacks.keys()) {
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this));
QV4::FunctionObject *f = animationCallbacks.value(key).value().asFunctionObject();
-
- QV4::ScopedCallData callData(v4, 1);
- callData->thisObject = QV4::QObjectWrapper::wrap(v4, this);
callData->args[0] = QV4::Value::fromUInt32(QDateTime::currentDateTimeUtc().toTime_t());
f->call(callData);
}
@@ -750,7 +751,7 @@ void QQuickCanvasItem::getContext(QQmlV4Function *args)
return;
}
- QString contextId = (*args)[0].toQString();
+ QString contextId = (*args)[0].toQStringNoThrow();
if (d->context != 0) {
if (d->context->contextNames().contains(contextId, Qt::CaseInsensitive)) {
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 84c4578946..3a84404d66 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -68,6 +68,7 @@
#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4objectproto_p.h>
+#include <private/qv4scopedvalue_p.h>
#if defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
#include <ctype.h>
@@ -128,7 +129,7 @@ static const double Q_PI = 3.14159265358979323846; // pi
#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0 && c <= 9))
QColor qt_color_from_string(const QV4::Value &name)
{
- QByteArray str = name.toQString().toUtf8();
+ QByteArray str = name.toQStringNoThrow().toUtf8();
char *p = str.data();
int len = str.length();
@@ -487,45 +488,45 @@ public:
}
QQuickContext2D* context;
- static QV4::Value method_get_globalAlpha(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_globalAlpha(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_globalCompositeOperation(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_globalCompositeOperation(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_fillStyle(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_fillStyle(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_fillRule(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_fillRule(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_strokeStyle(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_strokeStyle(QV4::SimpleCallContext *ctx);
-
- static QV4::Value method_get_lineCap(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_lineCap(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_lineJoin(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_lineJoin(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_lineWidth(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_lineWidth(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_miterLimit(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_miterLimit(QV4::SimpleCallContext *ctx);
-
- static QV4::Value method_get_shadowBlur(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_shadowBlur(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_shadowColor(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_shadowColor(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_shadowOffsetX(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_shadowOffsetX(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_shadowOffsetY(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_shadowOffsetY(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_globalAlpha(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_globalAlpha(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_globalCompositeOperation(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_globalCompositeOperation(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_fillStyle(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_fillStyle(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_fillRule(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_fillRule(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_strokeStyle(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_strokeStyle(QV4::SimpleCallContext *ctx);
+
+ static QV4::ReturnedValue method_get_lineCap(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_lineCap(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_lineJoin(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_lineJoin(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_lineWidth(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_lineWidth(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_miterLimit(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_miterLimit(QV4::SimpleCallContext *ctx);
+
+ static QV4::ReturnedValue method_get_shadowBlur(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_shadowBlur(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_shadowColor(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_shadowColor(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_shadowOffsetX(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_shadowOffsetX(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_shadowOffsetY(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_shadowOffsetY(QV4::SimpleCallContext *ctx);
// should these two be on the proto?
- static QV4::Value method_get_path(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_path(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_path(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_path(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_font(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_font(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_textAlign(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_textAlign(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_textBaseline(QV4::SimpleCallContext *ctx);
- static QV4::Value method_set_textBaseline(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_font(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_font(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_textAlign(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_textAlign(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_textBaseline(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_set_textBaseline(QV4::SimpleCallContext *ctx);
protected:
static void destroy(Managed *that)
@@ -590,50 +591,50 @@ public:
defineAccessorProperty(engine, QStringLiteral("canvas"), QQuickJSContext2DPrototype::method_get_canvas, 0);
}
- static QV4::Value method_get_canvas(QV4::SimpleCallContext *ctx);
- static QV4::Value method_restore(QV4::SimpleCallContext *ctx);
- static QV4::Value method_reset(QV4::SimpleCallContext *ctx);
- static QV4::Value method_save(QV4::SimpleCallContext *ctx);
- static QV4::Value method_rotate(QV4::SimpleCallContext *ctx);
- static QV4::Value method_scale(QV4::SimpleCallContext *ctx);
- static QV4::Value method_translate(QV4::SimpleCallContext *ctx);
- static QV4::Value method_setTransform(QV4::SimpleCallContext *ctx);
- static QV4::Value method_transform(QV4::SimpleCallContext *ctx);
- static QV4::Value method_resetTransform(QV4::SimpleCallContext *ctx);
- static QV4::Value method_shear(QV4::SimpleCallContext *ctx);
- static QV4::Value method_createLinearGradient(QV4::SimpleCallContext *ctx);
- static QV4::Value method_createRadialGradient(QV4::SimpleCallContext *ctx);
- static QV4::Value method_createConicalGradient(QV4::SimpleCallContext *ctx);
- static QV4::Value method_createPattern(QV4::SimpleCallContext *ctx);
- static QV4::Value method_clearRect(QV4::SimpleCallContext *ctx);
- static QV4::Value method_fillRect(QV4::SimpleCallContext *ctx);
- static QV4::Value method_strokeRect(QV4::SimpleCallContext *ctx);
- static QV4::Value method_arc(QV4::SimpleCallContext *ctx);
- static QV4::Value method_arcTo(QV4::SimpleCallContext *ctx);
- static QV4::Value method_beginPath(QV4::SimpleCallContext *ctx);
- static QV4::Value method_bezierCurveTo(QV4::SimpleCallContext *ctx);
- static QV4::Value method_clip(QV4::SimpleCallContext *ctx);
- static QV4::Value method_closePath(QV4::SimpleCallContext *ctx);
- static QV4::Value method_fill(QV4::SimpleCallContext *ctx);
- static QV4::Value method_lineTo(QV4::SimpleCallContext *ctx);
- static QV4::Value method_moveTo(QV4::SimpleCallContext *ctx);
- static QV4::Value method_quadraticCurveTo(QV4::SimpleCallContext *ctx);
- static QV4::Value method_rect(QV4::SimpleCallContext *ctx);
- static QV4::Value method_roundedRect(QV4::SimpleCallContext *ctx);
- static QV4::Value method_ellipse(QV4::SimpleCallContext *ctx);
- static QV4::Value method_text(QV4::SimpleCallContext *ctx);
- static QV4::Value method_stroke(QV4::SimpleCallContext *ctx);
- static QV4::Value method_isPointInPath(QV4::SimpleCallContext *ctx);
- static QV4::Value method_drawFocusRing(QV4::SimpleCallContext *ctx);
- static QV4::Value method_setCaretSelectionRect(QV4::SimpleCallContext *ctx);
- static QV4::Value method_caretBlinkRate(QV4::SimpleCallContext *ctx);
- static QV4::Value method_fillText(QV4::SimpleCallContext *ctx);
- static QV4::Value method_strokeText(QV4::SimpleCallContext *ctx);
- static QV4::Value method_measureText(QV4::SimpleCallContext *ctx);
- static QV4::Value method_drawImage(QV4::SimpleCallContext *ctx);
- static QV4::Value method_createImageData(QV4::SimpleCallContext *ctx);
- static QV4::Value method_getImageData(QV4::SimpleCallContext *ctx);
- static QV4::Value method_putImageData(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_canvas(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_restore(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_reset(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_save(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_rotate(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_scale(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_translate(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_setTransform(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_transform(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_resetTransform(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_shear(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_createLinearGradient(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_createRadialGradient(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_createConicalGradient(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_createPattern(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_clearRect(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_fillRect(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_strokeRect(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_arc(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_arcTo(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_beginPath(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_bezierCurveTo(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_clip(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_closePath(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_fill(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_lineTo(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_moveTo(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_quadraticCurveTo(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_rect(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_roundedRect(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_ellipse(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_text(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_stroke(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_isPointInPath(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_drawFocusRing(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_setCaretSelectionRect(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_caretBlinkRate(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_fillText(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_strokeText(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_measureText(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_drawImage(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_createImageData(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_getImageData(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_putImageData(QV4::SimpleCallContext *ctx);
};
@@ -655,7 +656,7 @@ public:
bool patternRepeatX:1;
bool patternRepeatY:1;
- static QV4::Value gradient_proto_addColorStop(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue gradient_proto_addColorStop(QV4::SimpleCallContext *ctx);
protected:
static void destroy(Managed *that)
{
@@ -872,10 +873,10 @@ struct QQuickJSContext2DPixelData : public QV4::Object
static void destroy(QV4::Managed *that) {
static_cast<QQuickJSContext2DPixelData *>(that)->~QQuickJSContext2DPixelData();
}
- static QV4::Value getIndexed(QV4::Managed *m, uint index, bool *hasProperty);
+ static QV4::ReturnedValue getIndexed(QV4::Managed *m, uint index, bool *hasProperty);
static void putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
- static QV4::Value proto_get_length(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue proto_get_length(QV4::SimpleCallContext *ctx);
QImage image;
};
@@ -895,9 +896,9 @@ struct QQuickJSContext2DImageData : public QV4::Object
defineAccessorProperty(engine, QStringLiteral("data"), method_get_data, 0);
}
- static QV4::Value method_get_width(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_height(QV4::SimpleCallContext *ctx);
- static QV4::Value method_get_data(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_width(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_height(QV4::SimpleCallContext *ctx);
+ static QV4::ReturnedValue method_get_data(QV4::SimpleCallContext *ctx);
static void markObjects(Managed *that) {
static_cast<QQuickJSContext2DImageData *>(that)->pixelData.mark();
@@ -938,7 +939,7 @@ static QV4::Value qt_create_image_data(qreal w, qreal h, QV8Engine* engine, cons
This property is read only.
*/
-QV4::Value QQuickJSContext2DPrototype::method_get_canvas(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -952,27 +953,27 @@ QV4::Value QQuickJSContext2DPrototype::method_get_canvas(QV4::SimpleCallContext
\sa save()
*/
-QV4::Value QQuickJSContext2DPrototype::method_restore(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_restore(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
r->context->popState();
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
\qmlmethod object QtQuick2::Context2D::reset()
Resets the context state and properties to the default values.
*/
-QV4::Value QQuickJSContext2DPrototype::method_reset(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
r->context->reset();
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -1005,14 +1006,14 @@ QV4::Value QQuickJSContext2DPrototype::method_reset(QV4::SimpleCallContext *ctx)
The current path is NOT part of the drawing state. The path can be reset by
invoking the beginPath() method.
*/
-QV4::Value QQuickJSContext2DPrototype::method_save(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
r->context->pushState();
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
// transformations
@@ -1033,14 +1034,14 @@ QV4::Value QQuickJSContext2DPrototype::method_save(QV4::SimpleCallContext *ctx)
where the \a angle of rotation is in radians.
*/
-QV4::Value QQuickJSContext2DPrototype::method_rotate(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
if (ctx->argumentCount == 1)
r->context->rotate(ctx->arguments[0].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -1060,7 +1061,7 @@ QV4::Value QQuickJSContext2DPrototype::method_rotate(QV4::SimpleCallContext *ctx
\image qml-item-canvas-scale.png
*/
-QV4::Value QQuickJSContext2DPrototype::method_scale(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1068,7 +1069,7 @@ QV4::Value QQuickJSContext2DPrototype::method_scale(QV4::SimpleCallContext *ctx)
if (ctx->argumentCount == 2)
r->context->scale(ctx->arguments[0].toNumber(), ctx->arguments[1].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -1104,7 +1105,7 @@ QV4::Value QQuickJSContext2DPrototype::method_scale(QV4::SimpleCallContext *ctx)
\sa transform()
*/
-QV4::Value QQuickJSContext2DPrototype::method_setTransform(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1118,7 +1119,7 @@ QV4::Value QQuickJSContext2DPrototype::method_setTransform(QV4::SimpleCallContex
, ctx->arguments[4].toNumber()
, ctx->arguments[5].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -1132,7 +1133,7 @@ QV4::Value QQuickJSContext2DPrototype::method_setTransform(QV4::SimpleCallContex
\sa setTransform()
*/
-QV4::Value QQuickJSContext2DPrototype::method_transform(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1146,7 +1147,7 @@ QV4::Value QQuickJSContext2DPrototype::method_transform(QV4::SimpleCallContext *
, ctx->arguments[4].toNumber()
, ctx->arguments[5].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -1158,7 +1159,7 @@ QV4::Value QQuickJSContext2DPrototype::method_transform(QV4::SimpleCallContext *
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::Value QQuickJSContext2DPrototype::method_translate(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1166,7 +1167,7 @@ QV4::Value QQuickJSContext2DPrototype::method_translate(QV4::SimpleCallContext *
if (ctx->argumentCount == 2)
r->context->translate(ctx->arguments[0].toNumber(), ctx->arguments[1].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
@@ -1178,14 +1179,14 @@ QV4::Value QQuickJSContext2DPrototype::method_translate(QV4::SimpleCallContext *
\sa transform(), setTransform(), reset()
*/
-QV4::Value QQuickJSContext2DPrototype::method_resetTransform(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
r->context->setTransform(1, 0, 0, 1, 0, 0);
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
@@ -1195,7 +1196,7 @@ QV4::Value QQuickJSContext2DPrototype::method_resetTransform(QV4::SimpleCallCont
Shears the transformation matrix by \a sh in the horizontal direction and
\a sv in the vertical direction.
*/
-QV4::Value QQuickJSContext2DPrototype::method_shear(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1203,7 +1204,7 @@ QV4::Value QQuickJSContext2DPrototype::method_shear(QV4::SimpleCallContext *ctx)
if (ctx->argumentCount == 2)
r->context->shear(ctx->arguments[0].toNumber(), ctx->arguments[1].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
// compositing
@@ -1214,15 +1215,15 @@ QV4::Value QQuickJSContext2DPrototype::method_shear(QV4::SimpleCallContext *ctx)
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::Value QQuickJSContext2D::method_get_globalAlpha(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_globalAlpha(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return QV4::Value::fromDouble(r->context->state.globalAlpha);
+ return QV4::Encode(r->context->state.globalAlpha);
}
-QV4::Value QQuickJSContext2D::method_set_globalAlpha(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -1230,13 +1231,13 @@ QV4::Value QQuickJSContext2D::method_set_globalAlpha(QV4::SimpleCallContext *ctx
double globalAlpha = ctx->argument(0).toNumber();
if (!qIsFinite(globalAlpha))
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->context->state.globalAlpha != globalAlpha) {
r->context->state.globalAlpha = globalAlpha;
r->context->buffer()->setGlobalAlpha(r->context->state.globalAlpha);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
@@ -1265,29 +1266,29 @@ QV4::Value QQuickJSContext2D::method_set_globalAlpha(QV4::SimpleCallContext *ctx
extension composition modes are provided as "vendorName-operationName" syntax, for example: QPainter::CompositionMode_Exclusion is provided as
"qt-exclusion".
*/
-QV4::Value QQuickJSContext2D::method_get_globalCompositeOperation(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_globalCompositeOperation(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return QV4::Value::fromString(ctx->engine->newString(qt_composite_mode_to_string(r->context->state.globalCompositeOperation)));
+ return QV4::Value::fromString(ctx->engine->newString(qt_composite_mode_to_string(r->context->state.globalCompositeOperation))).asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_globalCompositeOperation(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString mode = ctx->argument(0).toQString();
+ QString mode = ctx->argument(0).toQStringNoThrow();
QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
if (cm == QPainter::CompositionMode_SourceOver && mode != QStringLiteral("source-over"))
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
if (cm != r->context->state.globalCompositeOperation) {
r->context->state.globalCompositeOperation = cm;
r->context->buffer()->setGlobalCompositeOperation(cm);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
// colors and styles
@@ -1313,7 +1314,7 @@ QV4::Value QQuickJSContext2D::method_set_globalCompositeOperation(QV4::SimpleCal
\sa createPattern()
\sa strokeStyle
*/
-QV4::Value QQuickJSContext2D::method_get_fillStyle(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_fillStyle(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1321,19 +1322,19 @@ QV4::Value QQuickJSContext2D::method_get_fillStyle(QV4::SimpleCallContext *ctx)
QColor color = r->context->state.fillStyle.color();
if (color.isValid()) {
if (color.alpha() == 255)
- return QV4::Value::fromString(ctx->engine->newString(color.name()));
+ return QV4::Value::fromString(ctx->engine->newString(color.name())).asReturnedValue();
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::Value::fromString(ctx->engine->newString(str));
+ return QV4::Value::fromString(ctx->engine->newString(str)).asReturnedValue();
}
- return r->context->m_fillStyle.value();
+ return r->context->m_fillStyle.value().asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_fillStyle(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -1365,7 +1366,7 @@ QV4::Value QQuickJSContext2D::method_set_fillStyle(QV4::SimpleCallContext *ctx)
r->context->m_fillStyle = value;
}
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
\qmlproperty enumeration QtQuick2::Context2D::fillRule
@@ -1379,7 +1380,7 @@ QV4::Value QQuickJSContext2D::method_set_fillStyle(QV4::SimpleCallContext *ctx)
\sa fillStyle
*/
-QV4::Value QQuickJSContext2D::method_get_fillRule(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1388,24 +1389,24 @@ QV4::Value QQuickJSContext2D::method_get_fillRule(QV4::SimpleCallContext *ctx)
return engine->fromVariant(r->context->state.fillRule);
}
-QV4::Value QQuickJSContext2D::method_set_fillRule(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
QV4::Value value = ctx->argument(0);
- if ((value.isString() && value.toQString() == QStringLiteral("WindingFill"))
+ if ((value.isString() && value.toQStringNoThrow() == QStringLiteral("WindingFill"))
|| (value.isInt32() && value.integerValue() == Qt::WindingFill)) {
r->context->state.fillRule = Qt::WindingFill;
- } else if ((value.isString() && value.toQString() == QStringLiteral("OddEvenFill"))
+ } else if ((value.isString() && value.toQStringNoThrow() == QStringLiteral("OddEvenFill"))
|| (value.isInt32() && value.integerValue() == Qt::OddEvenFill)) {
r->context->state.fillRule = Qt::OddEvenFill;
} else {
//error
}
r->context->m_path.setFillRule(r->context->state.fillRule);
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
\qmlproperty variant QtQuick2::Context2D::strokeStyle
@@ -1420,7 +1421,7 @@ QV4::Value QQuickJSContext2D::method_set_fillRule(QV4::SimpleCallContext *ctx)
\sa createPattern()
\sa fillStyle
*/
-QV4::Value QQuickJSContext2D::method_get_strokeStyle(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_strokeStyle(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1428,19 +1429,19 @@ QV4::Value QQuickJSContext2D::method_get_strokeStyle(QV4::SimpleCallContext *ctx
QColor color = r->context->state.strokeStyle.color();
if (color.isValid()) {
if (color.alpha() == 255)
- return QV4::Value::fromString(ctx->engine->newString(color.name()));
+ return QV4::Value::fromString(ctx->engine->newString(color.name())).asReturnedValue();
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::Value::fromString(ctx->engine->newString(str));
+ return QV4::Value::fromString(ctx->engine->newString(str)).asReturnedValue();
}
- return r->context->m_strokeStyle.value();
+ return r->context->m_strokeStyle.value().asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_strokeStyle(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -1473,7 +1474,7 @@ QV4::Value QQuickJSContext2D::method_set_strokeStyle(QV4::SimpleCallContext *ctx
r->context->m_strokeStyle = value;
}
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
@@ -1493,8 +1494,9 @@ QV4::Value QQuickJSContext2D::method_set_strokeStyle(QV4::SimpleCallContext *ctx
\sa strokeStyle
*/
-QV4::Value QQuickJSContext2DPrototype::method_createLinearGradient(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1519,10 +1521,10 @@ QV4::Value QQuickJSContext2DPrototype::method_createLinearGradient(QV4::SimpleCa
QQuickContext2DStyle *gradient = new (v4->memoryManager) QQuickContext2DStyle(v4);
gradient->setPrototype(ed->gradientProto.value().asObject());
gradient->brush = QLinearGradient(x0, y0, x1, y1);
- return QV4::Value::fromObject(gradient);
+ return QV4::Value::fromObject(gradient).asReturnedValue();
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -1538,8 +1540,9 @@ QV4::Value QQuickJSContext2DPrototype::method_createLinearGradient(QV4::SimpleCa
\sa strokeStyle
*/
-QV4::Value QQuickJSContext2DPrototype::method_createRadialGradient(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1572,10 +1575,10 @@ QV4::Value QQuickJSContext2DPrototype::method_createRadialGradient(QV4::SimpleCa
QQuickContext2DStyle *gradient = new (v4->memoryManager) QQuickContext2DStyle(v4);
gradient->setPrototype(ed->gradientProto.value().asObject());
gradient->brush = QRadialGradient(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
- return QV4::Value::fromObject(gradient);
+ return QV4::Value::fromObject(gradient).asReturnedValue();
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -1591,8 +1594,9 @@ QV4::Value QQuickJSContext2DPrototype::method_createRadialGradient(QV4::SimpleCa
\sa strokeStyle
*/
-QV4::Value QQuickJSContext2DPrototype::method_createConicalGradient(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1617,10 +1621,10 @@ QV4::Value QQuickJSContext2DPrototype::method_createConicalGradient(QV4::SimpleC
QQuickContext2DStyle *gradient = new (v4->memoryManager) QQuickContext2DStyle(v4);
gradient->setPrototype(ed->gradientProto.value().asObject());
gradient->brush = QConicalGradient(x, y, angle);
- return QV4::Value::fromObject(gradient);
+ return QV4::Value::fromObject(gradient).asReturnedValue();
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
\qmlmethod variant QtQuick2::Context2D::createPattern(color color, enumeration patternMode)
@@ -1665,7 +1669,7 @@ QV4::Value QQuickJSContext2DPrototype::method_createConicalGradient(QV4::SimpleC
\sa strokeStyle
\sa fillStyle
*/
-QV4::Value QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -1673,6 +1677,7 @@ QV4::Value QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleCallConte
QV8Engine *engine = ctx->engine->v8Engine;
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope scope(v4);
if (ctx->argumentCount == 2) {
QQuickContext2DStyle *pattern = new (v4->memoryManager) QQuickContext2DStyle(v4);
@@ -1689,18 +1694,18 @@ QV4::Value QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleCallConte
QImage patternTexture;
if (QV4::Object *o = ctx->arguments[0].asObject()) {
- QQuickJSContext2DPixelData *pixelData = o->get(ctx->engine->newString(QStringLiteral("data"))).as<QQuickJSContext2DPixelData>();
- if (pixelData) {
+ QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(ctx->engine->newString(QStringLiteral("data"))));
+ if (!!pixelData) {
patternTexture = pixelData->image;
}
} else {
- patternTexture = r->context->createPixmap(QUrl(ctx->arguments[0].toQString()))->image();
+ patternTexture = r->context->createPixmap(QUrl(ctx->arguments[0].toQStringNoThrow()))->image();
}
if (!patternTexture.isNull()) {
pattern->brush.setTextureImage(patternTexture);
- QString repetition = ctx->arguments[1].toQString();
+ QString repetition = ctx->arguments[1].toQStringNoThrow();
if (repetition == QStringLiteral("repeat") || repetition.isEmpty()) {
pattern->patternRepeatX = true;
pattern->patternRepeatY = true;
@@ -1718,10 +1723,10 @@ QV4::Value QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleCallConte
}
}
- return QV4::Value::fromObject(pattern);
+ return QV4::Value::fromObject(pattern).asReturnedValue();
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
// line styles
@@ -1736,29 +1741,29 @@ QV4::Value QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleCallConte
\endlist
Other values are ignored.
*/
-QV4::Value QQuickJSContext2D::method_get_lineCap(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
switch (r->context->state.lineCap) {
case Qt::RoundCap:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("round")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("round"))).asReturnedValue();
case Qt::SquareCap:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("square")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("square"))).asReturnedValue();
case Qt::FlatCap:
default:
break;
}
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("butt")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("butt"))).asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_lineCap(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString lineCap = ctx->argument(0).toQString();
+ QString lineCap = ctx->argument(0).toQStringNoThrow();
Qt::PenCapStyle cap;
if (lineCap == QStringLiteral("round"))
cap = Qt::RoundCap;
@@ -1767,13 +1772,13 @@ QV4::Value QQuickJSContext2D::method_set_lineCap(QV4::SimpleCallContext *ctx)
else if (lineCap == QStringLiteral("square"))
cap = Qt::SquareCap;
else
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
if (cap != r->context->state.lineCap) {
r->context->state.lineCap = cap;
r->context->buffer()->setLineCap(cap);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
@@ -1790,29 +1795,29 @@ QV4::Value QQuickJSContext2D::method_set_lineCap(QV4::SimpleCallContext *ctx)
\endlist
Other values are ignored.
*/
-QV4::Value QQuickJSContext2D::method_get_lineJoin(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
switch (r->context->state.lineJoin) {
case Qt::RoundJoin:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("round")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("round"))).asReturnedValue();
case Qt::BevelJoin:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("bevel")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("bevel"))).asReturnedValue();
case Qt::MiterJoin:
default:
break;
}
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("miter")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("miter"))).asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_lineJoin(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString lineJoin = ctx->argument(0).toQString();
+ QString lineJoin = ctx->argument(0).toQStringNoThrow();
Qt::PenJoinStyle join;
if (lineJoin == QStringLiteral("round"))
join = Qt::RoundJoin;
@@ -1821,28 +1826,28 @@ QV4::Value QQuickJSContext2D::method_set_lineJoin(QV4::SimpleCallContext *ctx)
else if (lineJoin == QStringLiteral("miter"))
join = Qt::SvgMiterJoin;
else
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
if (join != r->context->state.lineJoin) {
r->context->state.lineJoin = join;
r->context->buffer()->setLineJoin(join);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
\qmlproperty real QtQuick2::Context2D::lineWidth
Holds the current line width. Values that are not finite values greater than zero are ignored.
*/
-QV4::Value QQuickJSContext2D::method_get_lineWidth(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_lineWidth(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return QV4::Value::fromDouble(r->context->state.lineWidth);
+ return QV4::Encode(r->context->state.lineWidth);
}
-QV4::Value QQuickJSContext2D::method_set_lineWidth(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -1853,7 +1858,7 @@ QV4::Value QQuickJSContext2D::method_set_lineWidth(QV4::SimpleCallContext *ctx)
r->context->state.lineWidth = w;
r->context->buffer()->setLineWidth(w);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
@@ -1861,15 +1866,15 @@ QV4::Value QQuickJSContext2D::method_set_lineWidth(QV4::SimpleCallContext *ctx)
Holds the current miter limit ratio.
The default miter limit value is 10.0.
*/
-QV4::Value QQuickJSContext2D::method_get_miterLimit(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_miterLimit(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return QV4::Value::fromDouble(r->context->state.miterLimit);
+ return QV4::Encode(r->context->state.miterLimit);
}
-QV4::Value QQuickJSContext2D::method_set_miterLimit(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -1880,7 +1885,7 @@ QV4::Value QQuickJSContext2D::method_set_miterLimit(QV4::SimpleCallContext *ctx)
r->context->state.miterLimit = ml;
r->context->buffer()->setMiterLimit(ml);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
// shadows
@@ -1888,15 +1893,15 @@ QV4::Value QQuickJSContext2D::method_set_miterLimit(QV4::SimpleCallContext *ctx)
\qmlproperty real QtQuick2::Context2D::shadowBlur
Holds the current level of blur applied to shadows
*/
-QV4::Value QQuickJSContext2D::method_get_shadowBlur(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_shadowBlur(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return QV4::Value::fromDouble(r->context->state.shadowBlur);
+ return QV4::Encode(r->context->state.shadowBlur);
}
-QV4::Value QQuickJSContext2D::method_set_shadowBlur(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_shadowBlur(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -1907,22 +1912,22 @@ QV4::Value QQuickJSContext2D::method_set_shadowBlur(QV4::SimpleCallContext *ctx)
r->context->state.shadowBlur = blur;
r->context->buffer()->setShadowBlur(blur);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
\qmlproperty string QtQuick2::Context2D::shadowColor
Holds the current shadow color.
*/
-QV4::Value QQuickJSContext2D::method_get_shadowColor(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_shadowColor(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return QV4::Value::fromString(ctx->engine->newString(r->context->state.shadowColor.name()));
+ return QV4::Value::fromString(ctx->engine->newString(r->context->state.shadowColor.name())).asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_shadowColor(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -1933,7 +1938,7 @@ QV4::Value QQuickJSContext2D::method_set_shadowColor(QV4::SimpleCallContext *ctx
r->context->state.shadowColor = color;
r->context->buffer()->setShadowColor(color);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
@@ -1943,15 +1948,15 @@ QV4::Value QQuickJSContext2D::method_set_shadowColor(QV4::SimpleCallContext *ctx
\sa shadowOffsetY
*/
-QV4::Value QQuickJSContext2D::method_get_shadowOffsetX(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetX(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return QV4::Value::fromDouble(r->context->state.shadowOffsetX);
+ return QV4::Encode(r->context->state.shadowOffsetX);
}
-QV4::Value QQuickJSContext2D::method_set_shadowOffsetX(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -1961,7 +1966,7 @@ QV4::Value QQuickJSContext2D::method_set_shadowOffsetX(QV4::SimpleCallContext *c
r->context->state.shadowOffsetX = offsetX;
r->context->buffer()->setShadowOffsetX(offsetX);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
\qmlproperty qreal QtQuick2::Context2D::shadowOffsetY
@@ -1969,15 +1974,15 @@ QV4::Value QQuickJSContext2D::method_set_shadowOffsetX(QV4::SimpleCallContext *c
\sa shadowOffsetX
*/
-QV4::Value QQuickJSContext2D::method_get_shadowOffsetY(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetY(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return QV4::Value::fromDouble(r->context->state.shadowOffsetY);
+ return QV4::Encode(r->context->state.shadowOffsetY);
}
-QV4::Value QQuickJSContext2D::method_set_shadowOffsetY(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -1987,18 +1992,18 @@ QV4::Value QQuickJSContext2D::method_set_shadowOffsetY(QV4::SimpleCallContext *c
r->context->state.shadowOffsetY = offsetY;
r->context->buffer()->setShadowOffsetY(offsetY);
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
-QV4::Value QQuickJSContext2D::method_get_path(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_path(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return r->context->m_v4path.value();
+ return r->context->m_v4path.value().asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_path(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
@@ -2009,11 +2014,11 @@ QV4::Value QQuickJSContext2D::method_set_path(QV4::SimpleCallContext *ctx)
if (QQuickPath *path = qobject_cast<QQuickPath*>(qobjectWrapper->object()))
r->context->m_path = path->path();
} else {
- QString path = value.toQString();
+ QString path = value.toQStringNoThrow();
QQuickSvgParser::parsePathDataFast(path, r->context->m_path);
}
r->context->m_v4path = value;
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
//rects
@@ -2021,7 +2026,7 @@ QV4::Value QQuickJSContext2D::method_set_path(QV4::SimpleCallContext *ctx)
\qmlmethod object QtQuick2::Context2D::clearRect(real x, real y, real w, real h)
Clears all pixels on the canvas in the given rectangle to transparent black.
*/
-QV4::Value QQuickJSContext2DPrototype::method_clearRect(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2033,7 +2038,7 @@ QV4::Value QQuickJSContext2DPrototype::method_clearRect(QV4::SimpleCallContext *
ctx->arguments[2].toNumber(),
ctx->arguments[3].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
\qmlmethod object QtQuick2::Context2D::fillRect(real x, real y, real w, real h)
@@ -2041,14 +2046,14 @@ QV4::Value QQuickJSContext2DPrototype::method_clearRect(QV4::SimpleCallContext *
\sa fillStyle
*/
-QV4::Value QQuickJSContext2DPrototype::method_fillRect(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
if (ctx->argumentCount == 4)
r->context->fillRect(ctx->arguments[0].toNumber(), ctx->arguments[1].toNumber(), ctx->arguments[2].toNumber(), ctx->arguments[3].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2061,7 +2066,7 @@ QV4::Value QQuickJSContext2DPrototype::method_fillRect(QV4::SimpleCallContext *c
\sa lineJoin
\sa miterLimit
*/
-QV4::Value QQuickJSContext2DPrototype::method_strokeRect(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2069,7 +2074,7 @@ QV4::Value QQuickJSContext2DPrototype::method_strokeRect(QV4::SimpleCallContext
if (ctx->argumentCount == 4)
r->context->strokeRect(ctx->arguments[0].toNumber(), ctx->arguments[1].toNumber(), ctx->arguments[2].toNumber(), ctx->arguments[3].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
// Complex shapes (paths) API
@@ -2093,8 +2098,9 @@ QV4::Value QQuickJSContext2DPrototype::method_strokeRect(QV4::SimpleCallContext
\sa arcTo, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arc}{W3C's 2D
Context Standard for arc()}
*/
-QV4::Value QQuickJSContext2DPrototype::method_arc(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2117,7 +2123,7 @@ QV4::Value QQuickJSContext2DPrototype::method_arc(QV4::SimpleCallContext *ctx)
antiClockwise);
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2143,8 +2149,9 @@ QV4::Value QQuickJSContext2DPrototype::method_arc(QV4::SimpleCallContext *ctx)
\sa arc, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arcto}{W3C's 2D
Context Standard for arcTo()}
*/
-QV4::Value QQuickJSContext2DPrototype::method_arcTo(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2161,7 +2168,7 @@ QV4::Value QQuickJSContext2DPrototype::method_arcTo(QV4::SimpleCallContext *ctx)
radius);
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2169,15 +2176,16 @@ QV4::Value QQuickJSContext2DPrototype::method_arcTo(QV4::SimpleCallContext *ctx)
Resets the current path to a new path.
*/
-QV4::Value QQuickJSContext2DPrototype::method_beginPath(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
r->context->beginPath();
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2199,8 +2207,9 @@ QV4::Value QQuickJSContext2DPrototype::method_beginPath(QV4::SimpleCallContext *
\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::Value QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2214,12 +2223,12 @@ QV4::Value QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::SimpleCallConte
qreal y = ctx->arguments[5].toNumber();
if (!qIsFinite(cp1x) || !qIsFinite(cp1y) || !qIsFinite(cp2x) || !qIsFinite(cp2y) || !qIsFinite(x) || !qIsFinite(y))
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
r->context->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2246,13 +2255,14 @@ QV4::Value QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::SimpleCallConte
\sa fill()
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-clip}{W3C 2d context standard for clip}
*/
-QV4::Value QQuickJSContext2DPrototype::method_clip(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
r->context->clip();
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2262,15 +2272,16 @@ QV4::Value QQuickJSContext2DPrototype::method_clip(QV4::SimpleCallContext *ctx)
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-closepath}{W3C 2d context standard for closePath}
*/
-QV4::Value QQuickJSContext2DPrototype::method_closePath(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
r->context->closePath();
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2282,12 +2293,13 @@ QV4::Value QQuickJSContext2DPrototype::method_closePath(QV4::SimpleCallContext *
\sa fillStyle
*/
-QV4::Value QQuickJSContext2DPrototype::method_fill(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r);
r->context->fill();
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2295,8 +2307,9 @@ QV4::Value QQuickJSContext2DPrototype::method_fill(QV4::SimpleCallContext *ctx)
Draws a line from the current position to the point (x, y).
*/
-QV4::Value QQuickJSContext2DPrototype::method_lineTo(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2306,12 +2319,12 @@ QV4::Value QQuickJSContext2DPrototype::method_lineTo(QV4::SimpleCallContext *ctx
qreal y = ctx->arguments[1].toNumber();
if (!qIsFinite(x) || !qIsFinite(y))
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
r->context->lineTo(x, y);
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2319,8 +2332,9 @@ QV4::Value QQuickJSContext2DPrototype::method_lineTo(QV4::SimpleCallContext *ctx
Creates a new subpath with the given point.
*/
-QV4::Value QQuickJSContext2DPrototype::method_moveTo(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2329,10 +2343,10 @@ QV4::Value QQuickJSContext2DPrototype::method_moveTo(QV4::SimpleCallContext *ctx
qreal y = ctx->arguments[1].toNumber();
if (!qIsFinite(x) || !qIsFinite(y))
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
r->context->moveTo(x, y);
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2342,8 +2356,9 @@ QV4::Value QQuickJSContext2DPrototype::method_moveTo(QV4::SimpleCallContext *ctx
See \l{http://www.w3.org/TR/2dcontext/#dom-context-2d-quadraticcurveto}{W3C 2d context standard for for quadraticCurveTo}
*/
-QV4::Value QQuickJSContext2DPrototype::method_quadraticCurveTo(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2354,12 +2369,12 @@ QV4::Value QQuickJSContext2DPrototype::method_quadraticCurveTo(QV4::SimpleCallCo
qreal y = ctx->arguments[3].toNumber();
if (!qIsFinite(cpx) || !qIsFinite(cpy) || !qIsFinite(x) || !qIsFinite(y))
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
r->context->quadraticCurveTo(cpx, cpy, x, y);
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2367,14 +2382,15 @@ QV4::Value QQuickJSContext2DPrototype::method_quadraticCurveTo(QV4::SimpleCallCo
Adds a rectangle at position (\c x, \c y), with the given width \c w and height \c h, as a closed subpath.
*/
-QV4::Value QQuickJSContext2DPrototype::method_rect(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
if (ctx->argumentCount == 4)
r->context->rect(ctx->arguments[0].toNumber(), ctx->arguments[1].toNumber(), ctx->arguments[2].toNumber(), ctx->arguments[3].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2383,8 +2399,9 @@ QV4::Value QQuickJSContext2DPrototype::method_rect(QV4::SimpleCallContext *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::Value QQuickJSContext2DPrototype::method_roundedRect(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2395,7 +2412,7 @@ QV4::Value QQuickJSContext2DPrototype::method_roundedRect(QV4::SimpleCallContext
, ctx->arguments[3].toNumber()
, ctx->arguments[4].toNumber()
, ctx->arguments[5].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2406,8 +2423,9 @@ QV4::Value QQuickJSContext2DPrototype::method_roundedRect(QV4::SimpleCallContext
The ellipse is composed of a clockwise curve, starting and finishing at zero degrees (the 3 o'clock position).
*/
-QV4::Value QQuickJSContext2DPrototype::method_ellipse(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2415,7 +2433,7 @@ QV4::Value QQuickJSContext2DPrototype::method_ellipse(QV4::SimpleCallContext *ct
if (ctx->argumentCount == 4)
r->context->ellipse(ctx->arguments[0].toNumber(), ctx->arguments[1].toNumber(), ctx->arguments[2].toNumber(), ctx->arguments[3].toNumber());
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2424,8 +2442,9 @@ QV4::Value QQuickJSContext2DPrototype::method_ellipse(QV4::SimpleCallContext *ct
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::Value QQuickJSContext2DPrototype::method_text(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2434,10 +2453,10 @@ QV4::Value QQuickJSContext2DPrototype::method_text(QV4::SimpleCallContext *ctx)
qreal y = ctx->arguments[2].toNumber();
if (!qIsFinite(x) || !qIsFinite(y))
- return ctx->thisObject;
- r->context->text(ctx->arguments[0].toQString(), x, y);
+ return ctx->thisObject.asReturnedValue();
+ r->context->text(ctx->arguments[0].toQStringNoThrow(), x, y);
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2449,13 +2468,14 @@ QV4::Value QQuickJSContext2DPrototype::method_text(QV4::SimpleCallContext *ctx)
\sa strokeStyle
*/
-QV4::Value QQuickJSContext2DPrototype::method_stroke(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
r->context->stroke();
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2465,7 +2485,7 @@ QV4::Value QQuickJSContext2DPrototype::method_stroke(QV4::SimpleCallContext *ctx
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath}{W3C 2d context standard for isPointInPath}
*/
-QV4::Value QQuickJSContext2DPrototype::method_isPointInPath(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_isPointInPath(QV4::SimpleCallContext *ctx)
{
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2473,26 +2493,26 @@ QV4::Value QQuickJSContext2DPrototype::method_isPointInPath(QV4::SimpleCallConte
bool pointInPath = false;
if (ctx->argumentCount == 2)
pointInPath = r->context->isPointInPath(ctx->arguments[0].toNumber(), ctx->arguments[1].toNumber());
- return QV4::Value::fromBoolean(pointInPath);
+ return QV4::Value::fromBoolean(pointInPath).asReturnedValue();
}
-QV4::Value QQuickJSContext2DPrototype::method_drawFocusRing(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawFocusRing(QV4::SimpleCallContext *ctx)
{
- Q_UNUSED(ctx);
+ QV4::Scope scope(ctx);
V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::drawFocusRing is not supported");
}
-QV4::Value QQuickJSContext2DPrototype::method_setCaretSelectionRect(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_setCaretSelectionRect(QV4::SimpleCallContext *ctx)
{
- Q_UNUSED(ctx);
+ QV4::Scope scope(ctx);
V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::setCaretSelectionRect is not supported");
}
-QV4::Value QQuickJSContext2DPrototype::method_caretBlinkRate(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_caretBlinkRate(QV4::SimpleCallContext *ctx)
{
- Q_UNUSED(ctx);
+ QV4::Scope scope(ctx);
V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
}
@@ -2520,25 +2540,27 @@ QV4::Value QQuickJSContext2DPrototype::method_caretBlinkRate(QV4::SimpleCallCont
The default font value is "10px sans-serif".
*/
-QV4::Value QQuickJSContext2D::method_get_font(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_font(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
- return QV4::Value::fromString(ctx->engine->newString(r->context->state.font.toString()));
+ return QV4::Value::fromString(ctx->engine->newString(r->context->state.font.toString())).asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_font(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_font(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString fs = ctx->argument(0).toQString();
+ QString fs = ctx->argument(0).toQStringNoThrow();
QFont font = qt_font_from_string(fs, r->context->state.font);
if (font != r->context->state.font) {
r->context->state.font = font;
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
@@ -2555,33 +2577,35 @@ QV4::Value QQuickJSContext2D::method_set_font(QV4::SimpleCallContext *ctx)
\endlist
Other values are ignored. The default value is "start".
*/
-QV4::Value QQuickJSContext2D::method_get_textAlign(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_textAlign(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
switch (r->context->state.textAlign) {
case QQuickContext2D::End:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("end")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("end"))).asReturnedValue();
case QQuickContext2D::Left:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("left")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("left"))).asReturnedValue();
case QQuickContext2D::Right:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("right")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("right"))).asReturnedValue();
case QQuickContext2D::Center:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("center")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("center"))).asReturnedValue();
case QQuickContext2D::Start:
default:
break;
}
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("start")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("start"))).asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_textAlign(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString textAlign = ctx->argument(0).toQString();
+ QString textAlign = ctx->argument(0).toQStringNoThrow();
QQuickContext2D::TextAlignType ta;
if (textAlign == QStringLiteral("start"))
@@ -2595,12 +2619,12 @@ QV4::Value QQuickJSContext2D::method_set_textAlign(QV4::SimpleCallContext *ctx)
else if (textAlign == QStringLiteral("center"))
ta = QQuickContext2D::Center;
else
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
if (ta != r->context->state.textAlign)
r->context->state.textAlign = ta;
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
@@ -2618,32 +2642,34 @@ QV4::Value QQuickJSContext2D::method_set_textAlign(QV4::SimpleCallContext *ctx)
\endlist
Other values are ignored. The default value is "alphabetic".
*/
-QV4::Value QQuickJSContext2D::method_get_textBaseline(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_get_textBaseline(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
switch (r->context->state.textBaseline) {
case QQuickContext2D::Hanging:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("hanging")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("hanging"))).asReturnedValue();
case QQuickContext2D::Top:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("top")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("top"))).asReturnedValue();
case QQuickContext2D::Bottom:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("bottom")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("bottom"))).asReturnedValue();
case QQuickContext2D::Middle:
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("middle")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("middle"))).asReturnedValue();
case QQuickContext2D::Alphabetic:
default:
break;
}
- return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("alphabetic")));
+ return QV4::Value::fromString(ctx->engine->newString(QStringLiteral("alphabetic"))).asReturnedValue();
}
-QV4::Value QQuickJSContext2D::method_set_textBaseline(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT_SETTER(r)
- QString textBaseline = ctx->argument(0).toQString();
+ QString textBaseline = ctx->argument(0).toQStringNoThrow();
QQuickContext2D::TextBaseLineType tb;
if (textBaseline == QStringLiteral("alphabetic"))
@@ -2657,12 +2683,12 @@ QV4::Value QQuickJSContext2D::method_set_textBaseline(QV4::SimpleCallContext *ct
else if (textBaseline == QStringLiteral("middle"))
tb = QQuickContext2D::Middle;
else
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
if (tb != r->context->state.textBaseline)
r->context->state.textBaseline = tb;
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
@@ -2673,8 +2699,9 @@ QV4::Value QQuickJSContext2D::method_set_textBaseline(QV4::SimpleCallContext *ct
\sa textBaseline
\sa strokeText
*/
-QV4::Value QQuickJSContext2DPrototype::method_fillText(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -2682,11 +2709,11 @@ QV4::Value QQuickJSContext2DPrototype::method_fillText(QV4::SimpleCallContext *c
qreal x = ctx->arguments[1].toNumber();
qreal y = ctx->arguments[2].toNumber();
if (!qIsFinite(x) || !qIsFinite(y))
- return ctx->thisObject;
- QPainterPath textPath = r->context->createTextGlyphs(x, y, ctx->arguments[0].toQString());
+ return ctx->thisObject.asReturnedValue();
+ QPainterPath textPath = r->context->createTextGlyphs(x, y, ctx->arguments[0].toQStringNoThrow());
r->context->buffer()->fill(textPath);
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
\qmlmethod object QtQuick2::Context2D::strokeText(text, x, y)
@@ -2696,14 +2723,15 @@ QV4::Value QQuickJSContext2DPrototype::method_fillText(QV4::SimpleCallContext *c
\sa textBaseline
\sa fillText
*/
-QV4::Value QQuickJSContext2DPrototype::method_strokeText(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
if (ctx->argumentCount == 3)
- r->context->drawText(ctx->arguments[0].toQString(), ctx->arguments[1].toNumber(), ctx->arguments[2].toNumber(), false);
- return ctx->thisObject;
+ r->context->drawText(ctx->arguments[0].toQStringNoThrow(), ctx->arguments[1].toNumber(), ctx->arguments[2].toNumber(), false);
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -2730,19 +2758,20 @@ QV4::Value QQuickJSContext2DPrototype::method_strokeText(QV4::SimpleCallContext
\qmlmethod variant QtQuick2::Context2D::measureText(text)
Returns a TextMetrics object with the metrics of the given text in the current font.
*/
-QV4::Value QQuickJSContext2DPrototype::method_measureText(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
if (ctx->argumentCount == 1) {
QFontMetrics fm(r->context->state.font);
- uint width = fm.width(ctx->arguments[0].toQString());
+ uint width = fm.width(ctx->arguments[0].toQStringNoThrow());
QV4::Object *tm = ctx->engine->newObject();
tm->put(ctx->engine->newIdentifier(QStringLiteral("width")), QV4::Value::fromDouble(width));
- return QV4::Value::fromObject(tm);
+ return QV4::Value::fromObject(tm).asReturnedValue();
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
// drawing images
@@ -2804,24 +2833,25 @@ QV4::Value QQuickJSContext2DPrototype::method_measureText(QV4::SimpleCallContext
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
*/
-QV4::Value QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
qreal sx, sy, sw, sh, dx, dy, dw, dh;
if (!ctx->argumentCount)
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
//FIXME:This function should be moved to QQuickContext2D::drawImage(...)
if (!r->context->state.invertibleCTM)
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
QQmlRefPointer<QQuickCanvasPixmap> pixmap;
if (ctx->arguments[0].isString()) {
- QUrl url(ctx->arguments[0].toQString());
+ QUrl url(ctx->arguments[0].toQStringNoThrow());
if (!url.isValid())
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
@@ -2845,7 +2875,7 @@ QV4::Value QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallContext *
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
} else {
- QUrl url(ctx->arguments[0].toQString());
+ QUrl url(ctx->arguments[0].toQStringNoThrow());
if (url.isValid())
pixmap = r->context->createPixmap(url);
else
@@ -2856,7 +2886,7 @@ QV4::Value QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallContext *
}
if (pixmap.isNull() || !pixmap->isValid())
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
if (ctx->argumentCount == 3) {
dx = ctx->arguments[1].toNumber();
@@ -2886,7 +2916,7 @@ QV4::Value QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallContext *
dw = ctx->arguments[7].toNumber();
dh = ctx->arguments[8].toNumber();
} else {
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
if (!qIsFinite(sx)
@@ -2897,7 +2927,7 @@ QV4::Value QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallContext *
|| !qIsFinite(dy)
|| !qIsFinite(dw)
|| !qIsFinite(dh))
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
if (sx < 0
|| sy < 0
@@ -2911,7 +2941,7 @@ QV4::Value QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallContext *
r->context->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh));
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
// pixel manipulation
@@ -2938,42 +2968,45 @@ QV4::Value QQuickJSContext2DPrototype::method_drawImage(QV4::SimpleCallContext *
\qmlproperty int QtQuick2::CanvasImageData::width
Holds the actual width dimension of the data in the ImageData object, in device pixels.
*/
-QV4::Value QQuickJSContext2DImageData::method_get_width(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DImageData::method_get_width(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2DImageData *imageData = ctx->thisObject.as<QQuickJSContext2DImageData>();
if (!imageData)
ctx->throwTypeError();
QQuickJSContext2DPixelData *r = imageData->pixelData.as<QQuickJSContext2DPixelData>();
if (!r)
- return QV4::Value::fromInt32(0);
- return QV4::Value::fromInt32(r->image.width());
+ return QV4::Encode(0);
+ return QV4::Encode(r->image.width());
}
/*!
\qmlproperty int QtQuick2::CanvasImageData::height
Holds the actual height dimension of the data in the ImageData object, in device pixels.
*/
-QV4::Value QQuickJSContext2DImageData::method_get_height(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DImageData::method_get_height(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2DImageData *imageData = ctx->thisObject.as<QQuickJSContext2DImageData>();
if (!imageData)
ctx->throwTypeError();
QQuickJSContext2DPixelData *r = imageData->pixelData.as<QQuickJSContext2DPixelData>();
if (!r)
- return QV4::Value::fromInt32(0);
- return QV4::Value::fromInt32(r->image.height());
+ return QV4::Encode(0);
+ return QV4::Encode(r->image.height());
}
/*!
\qmlproperty object QtQuick2::CanvasImageData::data
Holds the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.
*/
-QV4::Value QQuickJSContext2DImageData::method_get_data(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DImageData::method_get_data(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2DImageData *imageData = ctx->thisObject.as<QQuickJSContext2DImageData>();
if (!imageData)
ctx->throwTypeError();
- return imageData->pixelData;
+ return imageData->pixelData.asReturnedValue();
}
/*!
@@ -2994,16 +3027,17 @@ QV4::Value QQuickJSContext2DImageData::method_get_data(QV4::SimpleCallContext *c
The length attribute of a CanvasPixelArray object must return this h×w×4 number value.
This property is read only.
*/
-QV4::Value QQuickJSContext2DPixelData::proto_get_length(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2DPixelData *r = ctx->thisObject.as<QQuickJSContext2DPixelData>();
if (!r || r->image.isNull())
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
- return QV4::Value::fromInt32(r->image.width() * r->image.height() * 4);
+ return QV4::Encode(r->image.width() * r->image.height() * 4);
}
-QV4::Value QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint index, bool *hasProperty)
+QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint index, bool *hasProperty)
{
QQuickJSContext2DPixelData *r = m->as<QQuickJSContext2DPixelData>();
if (!m)
@@ -3019,18 +3053,18 @@ QV4::Value QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint index, b
pixel += col;
switch (index % 4) {
case 0:
- return QV4::Value::fromInt32(qRed(*pixel));
+ return QV4::Encode(qRed(*pixel));
case 1:
- return QV4::Value::fromInt32(qGreen(*pixel));
+ return QV4::Encode(qGreen(*pixel));
case 2:
- return QV4::Value::fromInt32(qBlue(*pixel));
+ return QV4::Encode(qBlue(*pixel));
case 3:
- return QV4::Value::fromInt32(qAlpha(*pixel));
+ return QV4::Encode(qAlpha(*pixel));
}
}
if (hasProperty)
*hasProperty = false;
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value)
@@ -3084,8 +3118,9 @@ void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q
\sa Canvas::loadImage(), QtQuick2::Canvas::unloadImage(),
QtQuick2::Canvas::isImageLoaded
*/
-QV4::Value QQuickJSContext2DPrototype::method_createImageData(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -3097,11 +3132,11 @@ QV4::Value QQuickJSContext2DPrototype::method_createImageData(QV4::SimpleCallCon
if (pa) {
qreal w = pa->image.width();
qreal h = pa->image.height();
- return qt_create_image_data(w, h, engine, QImage());
+ return qt_create_image_data(w, h, engine, QImage()).asReturnedValue();
}
} else if (ctx->arguments[0].isString()) {
- QImage image = r->context->createPixmap(QUrl(ctx->arguments[0].toQString()))->image();
- return qt_create_image_data(image.width(), image.height(), engine, image);
+ QImage image = r->context->createPixmap(QUrl(ctx->arguments[0].toQStringNoThrow()))->image();
+ return qt_create_image_data(image.width(), image.height(), engine, image).asReturnedValue();
}
} else if (ctx->argumentCount == 2) {
qreal w = ctx->arguments[0].toNumber();
@@ -3111,19 +3146,20 @@ QV4::Value QQuickJSContext2DPrototype::method_createImageData(QV4::SimpleCallCon
V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createImageData(): invalid arguments");
if (w > 0 && h > 0)
- return qt_create_image_data(w, h, engine, QImage());
+ return qt_create_image_data(w, h, engine, QImage()).asReturnedValue();
else
V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createImageData(): invalid arguments");
}
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
/*!
\qmlmethod CanvasImageData QtQuick2::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::Value QQuickJSContext2DPrototype::method_getImageData(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_getImageData(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
@@ -3142,21 +3178,22 @@ QV4::Value QQuickJSContext2DPrototype::method_getImageData(QV4::SimpleCallContex
QImage image = r->context->canvas()->toImage(QRectF(x, y, w, h));
QV4::Value imageData = qt_create_image_data(w, h, engine, image);
- return imageData;
+ return imageData.asReturnedValue();
}
- return QV4::Value::nullValue();
+ return QV4::Encode::null();
}
/*!
\qmlmethod object QtQuick2::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::Value QQuickJSContext2DPrototype::method_putImageData(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickJSContext2D *r = ctx->thisObject.as<QQuickJSContext2D>();
CHECK_CONTEXT(r)
if (ctx->argumentCount != 3 && ctx->argumentCount != 7)
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
if (!ctx->arguments[0].isObject())
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "Context2D::putImageData, the image data type mismatch");
@@ -3170,7 +3207,7 @@ QV4::Value QQuickJSContext2DPrototype::method_putImageData(QV4::SimpleCallContex
QQuickJSContext2DImageData *imageData = ctx->arguments[0].as<QQuickJSContext2DImageData>();
if (!imageData)
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
QQuickJSContext2DPixelData *pixelArray = imageData->pixelData.as<QQuickJSContext2DPixelData>();
if (pixelArray) {
@@ -3216,7 +3253,7 @@ QV4::Value QQuickJSContext2DPrototype::method_putImageData(QV4::SimpleCallContex
}
if (dirtyWidth <=0 || dirtyHeight <= 0)
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
} else {
dirtyX = 0;
dirtyY = 0;
@@ -3227,7 +3264,7 @@ QV4::Value QQuickJSContext2DPrototype::method_putImageData(QV4::SimpleCallContex
QImage image = pixelArray->image.copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
r->context->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
/*!
@@ -3250,8 +3287,9 @@ QV4::Value QQuickJSContext2DPrototype::method_putImageData(QV4::SimpleCallContex
gradient.addColorStop(0.7, 'rgba(0, 255, 255, 1');
\endcode
*/
-QV4::Value QQuickContext2DStyle::gradient_proto_addColorStop(QV4::SimpleCallContext *ctx)
+QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(QV4::SimpleCallContext *ctx)
{
+ QV4::Scope scope(ctx);
QQuickContext2DStyle *style = ctx->thisObject.as<QQuickContext2DStyle>();
if (!style)
V4THROW_ERROR("Not a CanvasGradient object");
@@ -3283,7 +3321,7 @@ QV4::Value QQuickContext2DStyle::gradient_proto_addColorStop(QV4::SimpleCallCont
style->brush = gradient;
}
- return ctx->thisObject;
+ return ctx->thisObject.asReturnedValue();
}
void QQuickContext2D::scale(qreal x, qreal y)
diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h
index 131b379a07..5301c089a9 100644
--- a/src/quick/items/qquickaccessibleattached_p.h
+++ b/src/quick/items/qquickaccessibleattached_p.h
@@ -73,7 +73,7 @@ public:
{
if (role != m_role) {
m_role = role;
- emit roleChanged();
+ Q_EMIT roleChanged();
// There is no way to signify role changes at the moment.
// QAccessible::updateAccessibility(parent(), 0, QAccessible::);
}
@@ -82,7 +82,7 @@ public:
void setName(const QString &name) {
if (name != m_name) {
m_name = name;
- emit nameChanged();
+ Q_EMIT nameChanged();
QAccessibleEvent ev(parent(), QAccessible::NameChanged);
QAccessible::updateAccessibility(&ev);
}
@@ -93,7 +93,7 @@ public:
{
if (m_description != description) {
m_description = description;
- emit descriptionChanged();
+ Q_EMIT descriptionChanged();
QAccessibleEvent ev(parent(), QAccessible::DescriptionChanged);
QAccessible::updateAccessibility(&ev);
}
diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h
index 6d0a821a47..b7b25900e8 100644
--- a/src/quick/items/qquickanimatedsprite_p.h
+++ b/src/quick/items/qquickanimatedsprite_p.h
@@ -160,7 +160,7 @@ public:
return m_curFrame;
}
-signals:
+Q_SIGNALS:
void pausedChanged(bool arg);
void runningChanged(bool arg);
@@ -190,7 +190,7 @@ signals:
void currentFrameChanged(int arg);
-public slots:
+public Q_SLOTS:
void start();
void stop();
void restart() {stop(); start();}
@@ -222,7 +222,7 @@ public slots:
{
if (m_interpolate != arg) {
m_interpolate = arg;
- emit interpolateChanged(arg);
+ Q_EMIT interpolateChanged(arg);
}
}
@@ -230,7 +230,7 @@ public slots:
{
if (m_sprite->m_source != arg) {
m_sprite->setSource(arg);
- emit sourceChanged(arg);
+ Q_EMIT sourceChanged(arg);
reloadImage();
}
}
@@ -239,7 +239,7 @@ public slots:
{
if (m_sprite->m_reverse != arg) {
m_sprite->setReverse(arg);
- emit reverseChanged(arg);
+ Q_EMIT reverseChanged(arg);
}
}
@@ -247,7 +247,7 @@ public slots:
{
if (m_sprite->m_frameSync != arg) {
m_sprite->setFrameSync(arg);
- emit frameSyncChanged(arg);
+ Q_EMIT frameSyncChanged(arg);
if (m_running)
restart();
}
@@ -257,7 +257,7 @@ public slots:
{
if (m_sprite->m_frames != arg) {
m_sprite->setFrameCount(arg);
- emit frameCountChanged(arg);
+ Q_EMIT frameCountChanged(arg);
reloadImage();
}
}
@@ -266,7 +266,7 @@ public slots:
{
if (m_sprite->m_frameHeight != arg) {
m_sprite->setFrameHeight(arg);
- emit frameHeightChanged(arg);
+ Q_EMIT frameHeightChanged(arg);
reloadImage();
}
}
@@ -275,7 +275,7 @@ public slots:
{
if (m_sprite->m_frameWidth != arg) {
m_sprite->setFrameWidth(arg);
- emit frameWidthChanged(arg);
+ Q_EMIT frameWidthChanged(arg);
reloadImage();
}
}
@@ -284,7 +284,7 @@ public slots:
{
if (m_sprite->m_frameX != arg) {
m_sprite->setFrameX(arg);
- emit frameXChanged(arg);
+ Q_EMIT frameXChanged(arg);
reloadImage();
}
}
@@ -293,7 +293,7 @@ public slots:
{
if (m_sprite->m_frameY != arg) {
m_sprite->setFrameY(arg);
- emit frameYChanged(arg);
+ Q_EMIT frameYChanged(arg);
reloadImage();
}
}
@@ -302,7 +302,7 @@ public slots:
{
if (m_sprite->m_frameRate != arg) {
m_sprite->setFrameRate(arg);
- emit frameRateChanged(arg);
+ Q_EMIT frameRateChanged(arg);
if (m_running)
restart();
}
@@ -312,7 +312,7 @@ public slots:
{
if (m_sprite->m_frameDuration != arg) {
m_sprite->setFrameDuration(arg);
- emit frameDurationChanged(arg);
+ Q_EMIT frameDurationChanged(arg);
if (m_running)
restart();
}
@@ -332,7 +332,7 @@ public slots:
{
if (m_loops != arg) {
m_loops = arg;
- emit loopsChanged(arg);
+ Q_EMIT loopsChanged(arg);
}
}
@@ -340,12 +340,12 @@ public slots:
{
if (m_curFrame != arg) {
m_curFrame = arg;
- emit currentFrameChanged(arg); //TODO-C Only emitted on manual advance!
+ Q_EMIT currentFrameChanged(arg); //TODO-C Only emitted on manual advance!
}
}
-private slots:
+private Q_SLOTS:
void createEngine();
void sizeVertices();
diff --git a/src/quick/items/qquickclipnode_p.h b/src/quick/items/qquickclipnode_p.h
index cb3930f552..4627a26619 100644
--- a/src/quick/items/qquickclipnode_p.h
+++ b/src/quick/items/qquickclipnode_p.h
@@ -42,9 +42,10 @@
#ifndef QQUICKCLIPNODE_P_H
#define QQUICKCLIPNODE_P_H
+#include <private/qtquickglobal_p.h>
#include <QtQuick/qsgnode.h>
-class QQuickDefaultClipNode : public QSGClipNode
+class Q_QUICK_PRIVATE_EXPORT QQuickDefaultClipNode : public QSGClipNode
{
public:
QQuickDefaultClipNode(const QRectF &);
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 0ae26cb5c3..166b40aaf2 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -45,11 +45,12 @@
#include <QtQuick/private/qquickevents_p_p.h>
#include <private/qquickitemchangelistener_p.h>
#include <private/qv8engine_p.h>
-#include <QtCore/qcoreapplication.h>
#include <QtCore/qmimedata.h>
#include <QtQml/qqmlinfo.h>
#include <QtGui/qdrag.h>
#include <QtGui/qevent.h>
+#include <QtGui/qstylehints.h>
+#include <QtGui/qguiapplication.h>
#ifndef QT_NO_DRAGANDDROP
@@ -785,7 +786,8 @@ void QQuickDragAttached::startDrag(QQmlV4Function *args)
QQuickDrag::QQuickDrag(QObject *parent)
: QObject(parent), _target(0), _axis(XAndYAxis), _xmin(-FLT_MAX),
-_xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false)
+_xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false),
+ _threshold(qApp->styleHints()->startDragDistance())
{
}
@@ -879,6 +881,25 @@ void QQuickDrag::setYmax(qreal m)
emit maximumYChanged();
}
+
+qreal QQuickDrag::threshold() const
+{
+ return _threshold;
+}
+
+void QQuickDrag::setThreshold(qreal value)
+{
+ if (_threshold != value) {
+ _threshold = value;
+ emit thresholdChanged();
+ }
+}
+
+void QQuickDrag::resetThreshold()
+{
+ setThreshold(qApp->styleHints()->startDragDistance());
+}
+
bool QQuickDrag::active() const
{
return _active;
diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h
index 098fcc61b9..22829350fe 100644
--- a/src/quick/items/qquickdrag_p.h
+++ b/src/quick/items/qquickdrag_p.h
@@ -157,6 +157,9 @@ class Q_AUTOTEST_EXPORT QQuickDrag : public QObject
Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
Q_PROPERTY(bool filterChildren READ filterChildren WRITE setFilterChildren NOTIFY filterChildrenChanged)
+ // Note, threshold was added in QtQuick 2.2 but REVISION is not supported (or needed) for grouped
+ // properties See QTBUG-33179
+ Q_PROPERTY(qreal threshold READ threshold WRITE setThreshold NOTIFY thresholdChanged RESET resetThreshold)
//### consider drag and drop
public:
@@ -182,6 +185,10 @@ public:
qreal ymax() const;
void setYmax(qreal);
+ qreal threshold() const;
+ void setThreshold(qreal);
+ void resetThreshold();
+
bool active() const;
void setActive(bool);
@@ -199,6 +206,7 @@ Q_SIGNALS:
void maximumYChanged();
void activeChanged();
void filterChildrenChanged();
+ void thresholdChanged();
private:
QQuickItem *_target;
@@ -209,6 +217,7 @@ private:
qreal _ymax;
bool _active : 1;
bool _filterChildren: 1;
+ qreal _threshold;
Q_DISABLE_COPY(QQuickDrag)
};
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 0186029fa0..fd73583a14 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -278,7 +278,7 @@ public:
void updateVisible();
-signals:
+Q_SIGNALS:
void xPositionChanged(qreal xPosition);
void yPositionChanged(qreal yPosition);
void widthRatioChanged(qreal widthRatio);
diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h
index 09e11adf90..bb2cecc3ef 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -126,7 +126,7 @@ public:
void setView(QQuickGridView *view) {
if (view != m_view) {
m_view = view;
- emit viewChanged();
+ Q_EMIT viewChanged();
}
}
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 01625756cd..98a87a4bcf 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -76,6 +76,7 @@
# include <QtGui/qcursor.h>
#endif
+#include <algorithm>
#include <float.h>
// XXX todo Check that elements that create items handle memory correctly after visual ownership change
@@ -2449,7 +2450,7 @@ QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
}
if (haveZ) {
sortedChildItems = new QList<QQuickItem*>(childItems);
- qStableSort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
+ std::stable_sort(sortedChildItems->begin(), sortedChildItems->end(), itemZOrder_sort);
return *sortedChildItems;
}
@@ -3871,7 +3872,7 @@ void QQuickItem::mapFromItem(QQmlV4Function *args) const
}
if (!itemObj && !item.isNull()) {
- qmlInfo(this) << "mapFromItem() given argument \"" << item.toQString()
+ qmlInfo(this) << "mapFromItem() given argument \"" << item.toQStringNoThrow()
<< "\" which is neither null nor an Item";
return;
}
@@ -3945,7 +3946,7 @@ void QQuickItem::mapToItem(QQmlV4Function *args) const
}
if (!itemObj && !item.isNull()) {
- qmlInfo(this) << "mapToItem() given argument \"" << item.toQString()
+ qmlInfo(this) << "mapToItem() given argument \"" << item.toQStringNoThrow()
<< "\" which is neither null nor an Item";
return;
}
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index fe70b38ed1..d89ef76c7f 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -197,7 +197,7 @@ public:
void updateOpacity();
void updateZ();
-signals:
+Q_SIGNALS:
void enabledChanged(bool enabled);
void sizeChanged(const QSize &size);
void mipmapChanged(bool mipmap);
@@ -526,7 +526,7 @@ public:
void emitChildrenRectChanged(const QRectF &rect) {
Q_Q(QQuickItem);
- emit q->childrenRectChanged(rect);
+ Q_EMIT q->childrenRectChanged(rect);
}
QPointF computeTransformOrigin() const;
@@ -759,7 +759,7 @@ public:
Q_D(QQuickKeysAttached);
if (enabled != d->enabled) {
d->enabled = enabled;
- emit enabledChanged();
+ Q_EMIT enabledChanged();
}
}
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index d7812bcdad..2e7de96c14 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -209,7 +209,7 @@ public:
virtual qreal originX() const;
virtual qreal originY() const;
-signals:
+Q_SIGNALS:
void modelChanged();
void delegateChanged();
void countChanged();
@@ -254,7 +254,7 @@ protected:
virtual qreal minXExtent() const;
virtual qreal maxXExtent() const;
-protected slots:
+protected Q_SLOTS:
void destroyRemoved();
void createdItem(int index, QObject *item);
virtual void initItem(int index, QObject *item);
@@ -288,7 +288,7 @@ public:
void setIsCurrentItem(bool c) {
if (m_isCurrent != c) {
m_isCurrent = c;
- emit currentItemChanged();
+ Q_EMIT currentItemChanged();
}
}
@@ -296,7 +296,7 @@ public:
void setDelayRemove(bool delay) {
if (m_delayRemove != delay) {
m_delayRemove = delay;
- emit delayRemoveChanged();
+ Q_EMIT delayRemoveChanged();
}
}
@@ -304,7 +304,7 @@ public:
void setSection(const QString &sect) {
if (m_section != sect) {
m_section = sect;
- emit sectionChanged();
+ Q_EMIT sectionChanged();
}
}
@@ -312,7 +312,7 @@ public:
void setPrevSection(const QString &sect) {
if (m_prevSection != sect) {
m_prevSection = sect;
- emit prevSectionChanged();
+ Q_EMIT prevSectionChanged();
}
}
@@ -320,14 +320,14 @@ public:
void setNextSection(const QString &sect) {
if (m_nextSection != sect) {
m_nextSection = sect;
- emit nextSectionChanged();
+ Q_EMIT nextSectionChanged();
}
}
- void emitAdd() { emit add(); }
- void emitRemove() { emit remove(); }
+ void emitAdd() { Q_EMIT add(); }
+ void emitRemove() { Q_EMIT remove(); }
-signals:
+Q_SIGNALS:
void currentItemChanged();
void delayRemoveChanged();
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index 4fb4386c57..e0b8196d80 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -186,7 +186,7 @@ public:
static QQuickViewTransitionAttached *qmlAttachedProperties(QObject *);
-signals:
+Q_SIGNALS:
void indexChanged();
void itemChanged();
void destinationChanged();
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index f612e7eab9..7b5b2e7315 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -183,7 +183,7 @@ public:
void setView(QQuickListView *view) {
if (view != m_view) {
m_view = view;
- emit viewChanged();
+ Q_EMIT viewChanged();
}
}
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 8f4dc0bd17..a24439cb19 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -922,7 +922,7 @@ void QQuickLoader::geometryChanged(const QRectF &newGeometry, const QRectF &oldG
QUrl QQuickLoaderPrivate::resolveSourceUrl(QQmlV4Function *args)
{
- QString arg = (*args)[0].toQString();
+ QString arg = (*args)[0].toQStringNoThrow();
if (arg.isEmpty())
return QUrl();
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 8a73a5d73d..39f07f2afd 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -48,10 +48,7 @@
#include <private/qqmldata_p.h>
#include <QtGui/private/qguiapplication_p.h>
-
#include <QtGui/qevent.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qstylehints.h>
#include <float.h>
@@ -695,8 +692,8 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
d->drag->target()->setPosition(dragPos);
if (!keepMouseGrab()
- && (QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), Qt::XAxis, event)
- || QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), Qt::YAxis, event))) {
+ && (QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), Qt::XAxis, event, d->drag->threshold())
+ || QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), Qt::YAxis, event, d->drag->threshold()))) {
setKeepMouseGrab(true);
d->stealMouse = true;
d->startScene = event->windowPos();
@@ -1189,6 +1186,7 @@ void QQuickMouseArea::setCursorShape(Qt::CursorShape shape)
\qmlproperty real QtQuick2::MouseArea::drag.minimumY
\qmlproperty real QtQuick2::MouseArea::drag.maximumY
\qmlproperty bool QtQuick2::MouseArea::drag.filterChildren
+ \qmlproperty real QtQuick2::MouseArea::drag.threshold
\c drag provides a convenient way to make an item draggable.
@@ -1213,6 +1211,10 @@ void QQuickMouseArea::setCursorShape(Qt::CursorShape shape)
If \c drag.filterChildren is set to true, a drag can override descendant MouseAreas. This
enables a parent MouseArea to handle drags, for example, while descendants handle clicks:
+ \c drag.threshold determines the threshold in pixels of when the drag operation should
+ start. By default this is bound to a platform dependent value. This property was added in
+ Qt Quick 2.2.
+
\snippet qml/mousearea/mouseareadragfilter.qml dragfilter
*/
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index afe7d4b77b..0e3f4131e8 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -251,7 +251,7 @@ protected:
void grabGesture();
virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-protected slots:
+protected Q_SLOTS:
void setTouchEventsEnabledForWindow(QWindow *window);
private:
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 091fb3eb4d..ff6397c9a0 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -744,10 +744,6 @@ int QQuickPathView::currentIndex() const
return d->currentIndex;
}
-/*!
- \qmlproperty int QtQuick2::PathView::currentItem
- This property holds the current item in the view.
-*/
void QQuickPathView::setCurrentIndex(int idx)
{
Q_D(QQuickPathView);
@@ -787,6 +783,10 @@ void QQuickPathView::setCurrentIndex(int idx)
}
}
+/*!
+ \qmlproperty Item QtQuick2::PathView::currentItem
+ This property holds the current item in the view.
+*/
QQuickItem *QQuickPathView::currentItem() const
{
Q_D(const QQuickPathView);
diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h
index 998707aa41..800dcc646a 100644
--- a/src/quick/items/qquickpathview_p.h
+++ b/src/quick/items/qquickpathview_p.h
@@ -245,7 +245,7 @@ public:
void setIsCurrentItem(bool c) {
if (m_isCurrent != c) {
m_isCurrent = c;
- emit currentItemChanged();
+ Q_EMIT currentItemChanged();
}
}
@@ -256,7 +256,7 @@ public:
void setOnPath(bool on) {
if (on != m_onPath) {
m_onPath = on;
- emit pathChanged();
+ Q_EMIT pathChanged();
}
}
qreal m_percent;
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index 60c2dc742e..c991145fc7 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -71,13 +71,13 @@ public:
if (target == m_target)
return;
m_target = target;
- emit targetChanged();
+ Q_EMIT targetChanged();
}
void resetTarget() {
if (!m_target)
return;
m_target = 0;
- emit targetChanged();
+ Q_EMIT targetChanged();
}
qreal minimumScale() const { return m_minScale; }
@@ -85,14 +85,14 @@ public:
if (s == m_minScale)
return;
m_minScale = s;
- emit minimumScaleChanged();
+ Q_EMIT minimumScaleChanged();
}
qreal maximumScale() const { return m_maxScale; }
void setMaximumScale(qreal s) {
if (s == m_maxScale)
return;
m_maxScale = s;
- emit maximumScaleChanged();
+ Q_EMIT maximumScaleChanged();
}
qreal minimumRotation() const { return m_minRotation; }
@@ -100,14 +100,14 @@ public:
if (r == m_minRotation)
return;
m_minRotation = r;
- emit minimumRotationChanged();
+ Q_EMIT minimumRotationChanged();
}
qreal maximumRotation() const { return m_maxRotation; }
void setMaximumRotation(qreal r) {
if (r == m_maxRotation)
return;
m_maxRotation = r;
- emit maximumRotationChanged();
+ Q_EMIT maximumRotationChanged();
}
enum Axis { NoDrag=0x00, XAxis=0x01, YAxis=0x02, XAndYAxis=0x03, XandYAxis=XAndYAxis };
@@ -116,7 +116,7 @@ public:
if (a == m_axis)
return;
m_axis = a;
- emit dragAxisChanged();
+ Q_EMIT dragAxisChanged();
}
qreal xmin() const { return m_xmin; }
@@ -124,28 +124,28 @@ public:
if (x == m_xmin)
return;
m_xmin = x;
- emit minimumXChanged();
+ Q_EMIT minimumXChanged();
}
qreal xmax() const { return m_xmax; }
void setXmax(qreal x) {
if (x == m_xmax)
return;
m_xmax = x;
- emit maximumXChanged();
+ Q_EMIT maximumXChanged();
}
qreal ymin() const { return m_ymin; }
void setYmin(qreal y) {
if (y == m_ymin)
return;
m_ymin = y;
- emit minimumYChanged();
+ Q_EMIT minimumYChanged();
}
qreal ymax() const { return m_ymax; }
void setYmax(qreal y) {
if (y == m_ymax)
return;
m_ymax = y;
- emit maximumYChanged();
+ Q_EMIT maximumYChanged();
}
bool active() const { return m_active; }
@@ -153,10 +153,10 @@ public:
if (a == m_active)
return;
m_active = a;
- emit activeChanged();
+ Q_EMIT activeChanged();
}
-signals:
+Q_SIGNALS:
void targetChanged();
void minimumScaleChanged();
void maximumScaleChanged();
@@ -283,7 +283,7 @@ protected:
const QRectF &oldGeometry);
virtual void itemChange(ItemChange change, const ItemChangeData& value);
-private slots:
+private Q_SLOTS:
void setTouchEventsEnabledForWindow(QWindow *window);
private:
diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index b35fd04e58..721390d1b2 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -93,7 +93,7 @@ Q_SIGNALS:
void primaryOrientationChanged();
void orientationChanged();
-protected slots:
+protected Q_SLOTS:
void screenChanged(QScreen*);
private:
diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h
index a85059e8d6..7aac2781be 100644
--- a/src/quick/items/qquicksprite_p.h
+++ b/src/quick/items/qquicksprite_p.h
@@ -153,7 +153,7 @@ public:
return m_frameSync;
}
-signals:
+Q_SIGNALS:
void sourceChanged(QUrl arg);
@@ -179,13 +179,13 @@ signals:
void frameSyncChanged(bool arg);
-public slots:
+public Q_SLOTS:
void setSource(QUrl arg)
{
if (m_source != arg) {
m_source = arg;
- emit sourceChanged(arg);
+ Q_EMIT sourceChanged(arg);
startImageLoading();
}
}
@@ -194,7 +194,7 @@ public slots:
{
if (m_frameHeight != arg) {
m_frameHeight = arg;
- emit frameHeightChanged(arg);
+ Q_EMIT frameHeightChanged(arg);
}
}
@@ -202,7 +202,7 @@ public slots:
{
if (m_frameWidth != arg) {
m_frameWidth = arg;
- emit frameWidthChanged(arg);
+ Q_EMIT frameWidthChanged(arg);
}
}
@@ -210,7 +210,7 @@ public slots:
{
if (m_reverse != arg) {
m_reverse = arg;
- emit reverseChanged(arg);
+ Q_EMIT reverseChanged(arg);
}
}
@@ -224,7 +224,7 @@ public slots:
{
if (m_frames != arg) {
m_frames = arg;
- emit frameCountChanged(arg);
+ Q_EMIT frameCountChanged(arg);
}
}
@@ -232,7 +232,7 @@ public slots:
{
if (m_frameX != arg) {
m_frameX = arg;
- emit frameXChanged(arg);
+ Q_EMIT frameXChanged(arg);
}
}
@@ -240,7 +240,7 @@ public slots:
{
if (m_frameY != arg) {
m_frameY = arg;
- emit frameYChanged(arg);
+ Q_EMIT frameYChanged(arg);
}
}
@@ -248,7 +248,7 @@ public slots:
{
if (m_frameRate != arg) {
m_frameRate = arg;
- emit frameRateChanged(arg);
+ Q_EMIT frameRateChanged(arg);
}
}
@@ -256,7 +256,7 @@ public slots:
{
if (m_frameRateVariation != arg) {
m_frameRateVariation = arg;
- emit frameRateVariationChanged(arg);
+ Q_EMIT frameRateVariationChanged(arg);
}
}
@@ -264,7 +264,7 @@ public slots:
{
if (m_frameDuration != arg) {
m_frameDuration = arg;
- emit frameDurationChanged(arg);
+ Q_EMIT frameDurationChanged(arg);
}
}
@@ -272,7 +272,7 @@ public slots:
{
if (m_frameDurationVariation != arg) {
m_frameDurationVariation = arg;
- emit frameDurationVariationChanged(arg);
+ Q_EMIT frameDurationVariationChanged(arg);
}
}
@@ -280,11 +280,11 @@ public slots:
{
if (m_frameSync != arg) {
m_frameSync = arg;
- emit frameSyncChanged(arg);
+ Q_EMIT frameSyncChanged(arg);
}
}
-private slots:
+private Q_SLOTS:
void startImageLoading();
private:
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index 768b5e4a6e..3ff5f8caee 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -108,7 +108,7 @@ public:
return m_randomStart;
}
-signals:
+Q_SIGNALS:
void durationChanged(int arg);
void nameChanged(QString arg);
@@ -121,12 +121,12 @@ signals:
void randomStartChanged(bool arg);
-public slots:
+public Q_SLOTS:
void setDuration(int arg)
{
if (m_duration != arg) {
m_duration = arg;
- emit durationChanged(arg);
+ Q_EMIT durationChanged(arg);
}
}
@@ -134,7 +134,7 @@ public slots:
{
if (m_name != arg) {
m_name = arg;
- emit nameChanged(arg);
+ Q_EMIT nameChanged(arg);
}
}
@@ -142,7 +142,7 @@ public slots:
{
if (m_to != arg) {
m_to = arg;
- emit toChanged(arg);
+ Q_EMIT toChanged(arg);
}
}
@@ -150,7 +150,7 @@ public slots:
{
if (m_durationVariation != arg) {
m_durationVariation = arg;
- emit durationVariationChanged(arg);
+ Q_EMIT durationVariationChanged(arg);
}
}
@@ -158,7 +158,7 @@ public slots:
{
if (m_randomStart != arg) {
m_randomStart = arg;
- emit randomStartChanged(arg);
+ Q_EMIT randomStartChanged(arg);
}
}
@@ -214,17 +214,17 @@ public:
int stateCount() {return m_states.count();}
private:
-signals:
+Q_SIGNALS:
void globalGoalChanged(QString arg);
void stateChanged(int idx);
-public slots:
+public Q_SLOTS:
void setGlobalGoal(QString arg)
{
if (m_globalGoal != arg) {
m_globalGoal = arg;
- emit globalGoalChanged(arg);
+ Q_EMIT globalGoalChanged(arg);
}
}
diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h
index b954a4464f..8f5a992942 100644
--- a/src/quick/items/qquickspritesequence_p.h
+++ b/src/quick/items/qquickspritesequence_p.h
@@ -88,14 +88,14 @@ public:
return m_curState;
}
-signals:
+Q_SIGNALS:
void runningChanged(bool arg);
void interpolateChanged(bool arg);
void goalSpriteChanged(QString arg);
void currentSpriteChanged(QString arg);
-public slots:
+public Q_SLOTS:
void jumpTo(const QString &sprite);
void setGoalSprite(const QString &sprite);
@@ -104,7 +104,7 @@ public slots:
{
if (m_running != arg) {
m_running = arg;
- emit runningChanged(arg);
+ Q_EMIT runningChanged(arg);
}
}
@@ -112,11 +112,11 @@ public slots:
{
if (m_interpolate != arg) {
m_interpolate = arg;
- emit interpolateChanged(arg);
+ Q_EMIT interpolateChanged(arg);
}
}
-private slots:
+private Q_SLOTS:
void createEngine();
void sizeVertices();
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 7a31e77ae4..86deb17b42 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -214,7 +214,7 @@ protected:
QQuickPixmap *loadPixmap(QQmlContext *context, const QUrl &name);
-private slots:
+private Q_SLOTS:
void requestFinished();
private:
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 6ee05700ae..d79de5d1b1 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -57,7 +57,6 @@
#include <QtGui/qtextobject.h>
#include <QtGui/qtexttable.h>
#include <QtCore/qmath.h>
-#include <QtCore/qalgorithms.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmlproperty_p.h>
@@ -66,6 +65,8 @@
#include "qquicktextdocument.h"
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
/*!
@@ -1859,7 +1860,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
if ((it.atEnd()) || (firstCleanNode && block.next().position() >= firstCleanNode->startPos())) // last node that needed replacing or last block of the frame
break;
- QList<int>::const_iterator lowerBound = qLowerBound(frameBoundaries, block.next().position());
+ QList<int>::const_iterator lowerBound = std::lower_bound(frameBoundaries.constBegin(), frameBoundaries.constEnd(), block.next().position());
if (currentNodeSize > nodeBreakingSize || *lowerBound > nodeStart) {
currentNodeSize = 0;
d->addCurrentTextNodeToRoot(rootNode, node, nodeIterator, nodeStart);
@@ -2039,13 +2040,13 @@ void QQuickTextEdit::markDirtyNodesForRange(int start, int end, int charDelta)
return;
TextNode dummyNode(start, 0);
- TextNodeIterator it = qLowerBound(d->textNodeMap.begin(), d->textNodeMap.end(), &dummyNode, &comesBefore);
+ TextNodeIterator it = std::lower_bound(d->textNodeMap.begin(), d->textNodeMap.end(), &dummyNode, &comesBefore);
// qLowerBound gives us the first node past the start of the affected portion, rewind to the first node
// that starts at the last position before the edit position. (there might be several because of images)
if (it != d->textNodeMap.begin()) {
--it;
TextNode otherDummy((*it)->startPos(), 0);
- it = qLowerBound(d->textNodeMap.begin(), d->textNodeMap.end(), &otherDummy, &comesBefore);
+ it = std::lower_bound(d->textNodeMap.begin(), d->textNodeMap.end(), &otherDummy, &comesBefore);
}
// mark the affected nodes as dirty
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index c195994de4..0cbb6e83a9 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -931,7 +931,7 @@ QQuickIntValidator::QQuickIntValidator(QObject *parent)
This property holds the name of the locale used to interpret the number.
- \sa QML:Qt::locale()
+ \sa {QtQml2::Qt::locale()}{Qt.locale()}
*/
QString QQuickIntValidator::localeName() const
@@ -1006,7 +1006,7 @@ QQuickDoubleValidator::QQuickDoubleValidator(QObject *parent)
This property holds the name of the locale used to interpret the number.
- \sa QML:Qt::locale()
+ \sa {QtQml2::Qt::locale()}{Qt.locale()}
*/
QString QQuickDoubleValidator::localeName() const
diff --git a/src/quick/items/qquicktextutil_p.h b/src/quick/items/qquicktextutil_p.h
index 5d376474a2..7f2206f1ef 100644
--- a/src/quick/items/qquicktextutil_p.h
+++ b/src/quick/items/qquicktextutil_p.h
@@ -101,7 +101,7 @@ void QQuickTextUtil::setCursorDelegate(Private *d, QQmlComponent *delegate)
if (parent->isCursorVisible() && parent->isComponentComplete())
createCursor(d);
- emit parent->cursorDelegateChanged();
+ Q_EMIT parent->cursorDelegateChanged();
}
template <typename Private>
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index c8bc026868..5b4145e235 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -298,6 +298,8 @@ void forcePolishHelper(QQuickItem *item)
void QQuickWindow::forcePolish()
{
Q_D(QQuickWindow);
+ if (!screen())
+ return;
forcePolishHelper(d->contentItem);
}
@@ -1710,9 +1712,14 @@ bool QQuickWindowPrivate::deliverTouchPoints(QQuickItem *item, QTouchEvent *even
// a single stationary press on an item shouldn't cause an event
if (matchingNewPoints.isEmpty()) {
bool stationaryOnly = true;
- Q_FOREACH (QTouchEvent::TouchPoint tp, matchingPoints)
- if (tp.state() != Qt::TouchPointStationary)
+
+ foreach (const QTouchEvent::TouchPoint &tp, matchingPoints) {
+ if (tp.state() != Qt::TouchPointStationary) {
stationaryOnly = false;
+ break;
+ }
+ }
+
if (stationaryOnly)
matchingPoints.clear();
}
@@ -2077,13 +2084,13 @@ bool QQuickWindowPrivate::sendFilteredMouseEvent(QQuickItem *target, QQuickItem
return false;
}
-bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event)
+bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold)
{
QStyleHints *styleHints = qApp->styleHints();
int caps = QGuiApplicationPrivate::mouseEventCaps(event);
bool dragVelocityLimitAvailable = (caps & QTouchDevice::Velocity)
&& styleHints->startDragVelocity();
- bool overThreshold = qAbs(d) > styleHints->startDragDistance();
+ bool overThreshold = qAbs(d) > (startDragThreshold >= 0 ? startDragThreshold : styleHints->startDragDistance());
if (dragVelocityLimitAvailable) {
QVector2D velocityVec = QGuiApplicationPrivate::mouseEventVelocity(event);
qreal velocity = axis == Qt::XAxis ? velocityVec.x() : velocityVec.y();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index ad861754d7..e29ceb521f 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -191,7 +191,7 @@ public:
void updateEffectiveOpacityRoot(QQuickItem *, qreal);
void updateDirtyNode(QQuickItem *);
- void fireFrameSwapped() { emit q_func()->frameSwapped(); }
+ void fireFrameSwapped() { Q_EMIT q_func()->frameSwapped(); }
QSGContext *context;
QSGRenderer *renderer;
@@ -221,7 +221,7 @@ public:
static bool defaultAlphaBuffer;
- static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event);
+ static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold = -1);
// data property
static void data_append(QQmlListProperty<QObject> *, QObject *);
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index 057f3d5db5..7c540591ab 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -18,8 +18,8 @@ ANDROID_LIB_DEPENDENCIES = \
lib/libQt5QuickParticles.so
ANDROID_LIB_DEPENDENCY_REPLACEMENTS = \
"plugins/platforms/android/libqtforandroid.so:plugins/platforms/android/libqtforandroidGL.so"
-MODULE_PLUGIN_TYPES = \
- accessible
+MODULE_PLUGIN_TYPES += \
+ accessible/libqtaccessiblequick.so
ANDROID_BUNDLED_FILES += \
qml \
lib/libQt5QuickParticles.so
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index cf71489f88..ed76102c2d 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -46,6 +46,8 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLFramebufferObject>
+#include <algorithm>
+
#ifndef GL_DOUBLE
#define GL_DOUBLE 0x140A
#endif
@@ -364,7 +366,7 @@ void Updater::visitTransformNode(Node *n)
QSGTransformNode *tn = static_cast<QSGTransformNode *>(n->sgNode);
if (n->isBatchRoot) {
- if (m_added > 0 && m_roots.size() > 0)
+ if (m_added > 0 && m_roots.last())
renderer->registerBatchRoot(n, m_roots.last());
tn->setCombinedMatrix(m_rootMatrices.last() * *m_combined_matrix_stack.last() * tn->matrix());
@@ -1256,9 +1258,9 @@ void Renderer::buildRenderListsForTaggedRoots()
qsg_addBackOrphanedElements(m_tmpAlphaElements, m_alphaRenderList);
if (m_opaqueRenderList.size())
- qSort(&m_opaqueRenderList.first(), &m_opaqueRenderList.last() + 1, qsg_sort_element_decreasing_order);
+ std::sort(&m_opaqueRenderList.first(), &m_opaqueRenderList.last() + 1, qsg_sort_element_decreasing_order);
if (m_alphaRenderList.size())
- qSort(&m_alphaRenderList.first(), &m_alphaRenderList.last() + 1, qsg_sort_element_increasing_order);
+ std::sort(&m_alphaRenderList.first(), &m_alphaRenderList.last() + 1, qsg_sort_element_increasing_order);
}
@@ -1284,7 +1286,7 @@ void Renderer::buildRenderListsFromScratch()
*/
void Renderer::cleanupBatches(QDataBuffer<Batch *> *batches) {
if (batches->size()) {
- qSort(&batches->first(), &batches->last() + 1, qsg_sort_batch_is_valid);
+ std::sort(&batches->first(), &batches->last() + 1, qsg_sort_batch_is_valid);
int count = 0;
while (count < batches->size() && batches->at(count)->first)
++count;
@@ -2149,11 +2151,11 @@ void Renderer::render()
// Then sort opaque batches so that we're drawing the batches with the highest
// order first, maximizing the benefit of front-to-back z-ordering.
if (m_opaqueBatches.size())
- qSort(&m_opaqueBatches.first(), &m_opaqueBatches.last() + 1, qsg_sort_batch_decreasing_order);
+ std::sort(&m_opaqueBatches.first(), &m_opaqueBatches.last() + 1, qsg_sort_batch_decreasing_order);
// Sort alpha batches back to front so that they render correctly.
if (m_alphaBatches.size())
- qSort(&m_alphaBatches.first(), &m_alphaBatches.last() + 1, qsg_sort_batch_increasing_order);
+ std::sort(&m_alphaBatches.first(), &m_alphaBatches.last() + 1, qsg_sort_batch_increasing_order);
m_zRange = 1.0 / (m_nextRenderOrder);
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 1aa165281a..6e9bd750e2 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -373,7 +373,7 @@ public:
qDeleteAll(stockShaders.values());
}
-public slots:
+public Q_SLOTS:
void invalidated();
public:
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
index 0370be000b..3479c4392c 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
@@ -134,7 +134,7 @@ public:
void setClearMode(ClearMode mode) { m_clear_mode = mode; }
ClearMode clearMode() const { return m_clear_mode; }
-signals:
+Q_SIGNALS:
void sceneGraphChanged(); // Add, remove, ChangeFlags changes...
protected:
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 3d5fc00de3..b5d8ca05ae 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -130,10 +130,10 @@ public:
static QSGRenderLoop *createWindowManager();
-public slots:
+public Q_SLOTS:
void textureFactoryDestroyed(QObject *o);
-signals:
+Q_SIGNALS:
void initialized();
void invalidated();
};
diff --git a/src/quick/scenegraph/qsgpathsimplifier.cpp b/src/quick/scenegraph/qsgpathsimplifier.cpp
deleted file mode 100644
index cb04737c13..0000000000
--- a/src/quick/scenegraph/qsgpathsimplifier.cpp
+++ /dev/null
@@ -1,1673 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgpathsimplifier_p.h"
-
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qglobal.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qalgorithms.h>
-
-#include <math.h>
-
-#include <private/qopengl_p.h>
-#include <private/qrbtree_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#define Q_FIXED_POINT_SCALE 256
-#define Q_TRIANGULATE_END_OF_POLYGON quint32(-1)
-
-
-namespace {
-
-//============================================================================//
-// QPoint //
-//============================================================================//
-
-inline bool operator < (const QPoint &a, const QPoint &b)
-{
- return a.y() < b.y() || (a.y() == b.y() && a.x() < b.x());
-}
-
-inline bool operator > (const QPoint &a, const QPoint &b)
-{
- return b < a;
-}
-
-inline bool operator <= (const QPoint &a, const QPoint &b)
-{
- return !(a > b);
-}
-
-inline bool operator >= (const QPoint &a, const QPoint &b)
-{
- return !(a < b);
-}
-
-inline int cross(const QPoint &u, const QPoint &v)
-{
- return u.x() * v.y() - u.y() * v.x();
-}
-
-inline int dot(const QPoint &u, const QPoint &v)
-{
- return u.x() * v.x() + u.y() * v.y();
-}
-
-//============================================================================//
-// Fraction //
-//============================================================================//
-
-// Fraction must be in the range [0, 1)
-struct Fraction
-{
- bool isValid() const { return denominator != 0; }
-
- // numerator and denominator must not have common denominators.
- unsigned int numerator, denominator;
-};
-
-inline unsigned int gcd(unsigned int x, unsigned int y)
-{
- while (y != 0) {
- unsigned int z = y;
- y = x % y;
- x = z;
- }
- return x;
-}
-
-// Fraction must be in the range [0, 1)
-// Assume input is valid.
-Fraction fraction(unsigned int n, unsigned int d) {
- Fraction result;
- if (n == 0) {
- result.numerator = 0;
- result.denominator = 1;
- } else {
- unsigned int g = gcd(n, d);
- result.numerator = n / g;
- result.denominator = d / g;
- }
- return result;
-}
-
-//============================================================================//
-// Rational //
-//============================================================================//
-
-struct Rational
-{
- bool isValid() const { return fraction.isValid(); }
- int integer;
- Fraction fraction;
-};
-
-//============================================================================//
-// IntersectionPoint //
-//============================================================================//
-
-struct IntersectionPoint
-{
- bool isValid() const { return x.fraction.isValid() && y.fraction.isValid(); }
- QPoint round() const;
- bool isAccurate() const { return x.fraction.numerator == 0 && y.fraction.numerator == 0; }
-
- Rational x; // 8:8 signed, 32/32
- Rational y; // 8:8 signed, 32/32
-};
-
-QPoint IntersectionPoint::round() const
-{
- QPoint result(x.integer, y.integer);
- if (2 * x.fraction.numerator >= x.fraction.denominator)
- ++result.rx();
- if (2 * y.fraction.numerator >= y.fraction.denominator)
- ++result.ry();
- return result;
-}
-
-// Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the
-// line and zero if exactly on the line.
-// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1',
-// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order).
-inline int pointDistanceFromLine(const QPoint &p, const QPoint &v1, const QPoint &v2)
-{
- return cross(v2 - v1, p - v1);
-}
-
-IntersectionPoint intersectionPoint(const QPoint &u1, const QPoint &u2,
- const QPoint &v1, const QPoint &v2)
-{
- IntersectionPoint result = {{0, {0, 0}}, {0, {0, 0}}};
-
- QPoint u = u2 - u1;
- QPoint v = v2 - v1;
- int d1 = cross(u, v1 - u1);
- int d2 = cross(u, v2 - u1);
- int det = d2 - d1;
- int d3 = cross(v, u1 - v1);
- int d4 = d3 - det; //qCross(v, u2 - v1);
-
- // Check that the math is correct.
- Q_ASSERT(d4 == cross(v, u2 - v1));
-
- // The intersection point can be expressed as:
- // v1 - v * d1/det
- // v2 - v * d2/det
- // u1 + u * d3/det
- // u2 + u * d4/det
-
- // I'm only interested in lines that are crossing, so ignore parallel lines even if they overlap.
- if (det == 0)
- return result;
-
- if (det < 0) {
- det = -det;
- d1 = -d1;
- d2 = -d2;
- d3 = -d3;
- d4 = -d4;
- }
-
- // I'm only interested in lines intersecting at their interior, not at their end points.
- // The lines intersect at their interior if and only if 'd1 < 0', 'd2 > 0', 'd3 < 0' and 'd4 > 0'.
- if (d1 >= 0 || d2 <= 0 || d3 <= 0 || d4 >= 0)
- return result;
-
- // Calculate the intersection point as follows:
- // v1 - v * d1/det | v1 <= v2 (component-wise)
- // v2 - v * d2/det | v2 < v1 (component-wise)
-
- // Assuming 16 bits per vector component.
- if (v.x() >= 0) {
- result.x.integer = v1.x() + int(qint64(-v.x()) * d1 / det);
- result.x.fraction = fraction((unsigned int)(qint64(-v.x()) * d1 % det), (unsigned int)det);
- } else {
- result.x.integer = v2.x() + int(qint64(-v.x()) * d2 / det);
- result.x.fraction = fraction((unsigned int)(qint64(-v.x()) * d2 % det), (unsigned int)det);
- }
-
- if (v.y() >= 0) {
- result.y.integer = v1.y() + int(qint64(-v.y()) * d1 / det);
- result.y.fraction = fraction((unsigned int)(qint64(-v.y()) * d1 % det), (unsigned int)det);
- } else {
- result.y.integer = v2.y() + int(qint64(-v.y()) * d2 / det);
- result.y.fraction = fraction((unsigned int)(qint64(-v.y()) * d2 % det), (unsigned int)det);
- }
-
- Q_ASSERT(result.x.fraction.isValid());
- Q_ASSERT(result.y.fraction.isValid());
- return result;
-}
-
-//============================================================================//
-// PathSimplifier //
-//============================================================================//
-
-class PathSimplifier
-{
-public:
- PathSimplifier(const QVectorPath &path, QDataBuffer<QPoint> &vertices,
- QDataBuffer<quint32> &indices, const QTransform &matrix);
-
-private:
- struct Element;
-
- class BoundingVolumeHierarchy
- {
- public:
- struct Node
- {
- enum Type
- {
- Leaf,
- Split
- };
- Type type;
- QPoint minimum;
- QPoint maximum;
- union {
- Element *element; // type == Leaf
- Node *left; // type == Split
- };
- Node *right;
- };
-
- BoundingVolumeHierarchy();
- ~BoundingVolumeHierarchy();
- void allocate(int nodeCount);
- void free();
- Node *newNode();
-
- Node *root;
- private:
- void freeNode(Node *n);
-
- Node *nodeBlock;
- int blockSize;
- int firstFree;
- };
-
- struct Element
- {
- enum Degree
- {
- Line = 1,
- Quadratic = 2,
- Cubic = 3
- };
-
- quint32 &upperIndex() { return indices[pointingUp ? degree : 0]; }
- quint32 &lowerIndex() { return indices[pointingUp ? 0 : degree]; }
- quint32 upperIndex() const { return indices[pointingUp ? degree : 0]; }
- quint32 lowerIndex() const { return indices[pointingUp ? 0 : degree]; }
- void flip();
-
- QPoint middle;
- quint32 indices[4]; // index to points
- Element *next, *previous; // used in connectElements()
- int winding; // used in connectElements()
- union {
- QRBTree<Element *>::Node *edgeNode; // used in connectElements()
- BoundingVolumeHierarchy::Node *bvhNode;
- };
- Degree degree : 8;
- uint processed : 1; // initially false, true when the element has been checked for intersections.
- uint pointingUp : 1; // used in connectElements()
- uint originallyPointingUp : 1; // used in connectElements()
- };
-
- class ElementAllocator
- {
- public:
- ElementAllocator();
- ~ElementAllocator();
- void allocate(int count);
- Element *newElement();
- private:
- struct ElementBlock
- {
- ElementBlock *next;
- int blockSize;
- int firstFree;
- Element elements[1];
- } *blocks;
- };
-
- struct Event
- {
- enum Type { Upper, Lower };
- bool operator < (const Event &other) const;
-
- QPoint point;
- Type type;
- Element *element;
- };
-
- typedef QRBTree<Element *>::Node RBNode;
- typedef BoundingVolumeHierarchy::Node BVHNode;
-
- void initElements(const QVectorPath &path, const QTransform &matrix);
- void removeIntersections();
- void connectElements();
- void fillIndices();
- BVHNode *buildTree(Element **elements, int elementCount);
- bool intersectNodes(QDataBuffer<Element *> &elements, BVHNode *elementNode, BVHNode *treeNode);
- bool equalElements(const Element *e1, const Element *e2);
- bool splitLineAt(QDataBuffer<Element *> &elements, BVHNode *node, quint32 pointIndex, bool processAgain);
- void appendSeparatingAxes(QVarLengthArray<QPoint, 12> &axes, Element *element);
- QPair<int, int> calculateSeparatingAxisRange(const QPoint &axis, Element *element);
- void splitCurve(QDataBuffer<Element *> &elements, BVHNode *node);
- bool setElementToQuadratic(Element *element, quint32 pointIndex1, const QPoint &ctrl, quint32 pointIndex2);
- bool setElementToCubic(Element *element, quint32 pointIndex1, const QPoint &ctrl1, const QPoint &ctrl2, quint32 pointIndex2);
- void setElementToCubicAndSimplify(Element *element, quint32 pointIndex1, const QPoint &ctrl1, const QPoint &ctrl2, quint32 pointIndex2);
- RBNode *findElementLeftOf(const Element *element, const QPair<RBNode *, RBNode *> &bounds);
- bool elementIsLeftOf(const Element *left, const Element *right);
- QPair<RBNode *, RBNode *> outerBounds(const QPoint &point);
- static bool flattenQuadratic(const QPoint &u, const QPoint &v, const QPoint &w);
- static bool flattenCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q);
- static bool splitQuadratic(const QPoint &u, const QPoint &v, const QPoint &w, QPoint *result);
- static bool splitCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q, QPoint *result);
- void subDivQuadratic(const QPoint &u, const QPoint &v, const QPoint &w);
- void subDivCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q);
- static void sortEvents(Event *events, int count);
-
- ElementAllocator m_elementAllocator;
- QDataBuffer<Element *> m_elements;
- QDataBuffer<QPoint> *m_points;
- BoundingVolumeHierarchy m_bvh;
- QDataBuffer<quint32> *m_indices;
- QRBTree<Element *> m_elementList;
- uint m_hints;
-};
-
-inline PathSimplifier::BoundingVolumeHierarchy::BoundingVolumeHierarchy()
- : root(0)
- , nodeBlock(0)
- , blockSize(0)
- , firstFree(0)
-{
-}
-
-inline PathSimplifier::BoundingVolumeHierarchy::~BoundingVolumeHierarchy()
-{
- free();
-}
-
-inline void PathSimplifier::BoundingVolumeHierarchy::allocate(int nodeCount)
-{
- Q_ASSERT(nodeBlock == 0);
- Q_ASSERT(firstFree == 0);
- nodeBlock = new Node[blockSize = nodeCount];
-}
-
-inline void PathSimplifier::BoundingVolumeHierarchy::free()
-{
- freeNode(root);
- delete[] nodeBlock;
- nodeBlock = 0;
- firstFree = blockSize = 0;
- root = 0;
-}
-
-inline PathSimplifier::BVHNode *PathSimplifier::BoundingVolumeHierarchy::newNode()
-{
- if (firstFree < blockSize)
- return &nodeBlock[firstFree++];
- return new Node;
-}
-
-inline void PathSimplifier::BoundingVolumeHierarchy::freeNode(Node *n)
-{
- if (!n)
- return;
- Q_ASSERT(n->type == Node::Split || n->type == Node::Leaf);
- if (n->type == Node::Split) {
- freeNode(n->left);
- freeNode(n->right);
- }
- if (!(n >= nodeBlock && n < nodeBlock + blockSize))
- delete n;
-}
-
-inline PathSimplifier::ElementAllocator::ElementAllocator()
- : blocks(0)
-{
-}
-
-inline PathSimplifier::ElementAllocator::~ElementAllocator()
-{
- while (blocks) {
- ElementBlock *block = blocks;
- blocks = blocks->next;
- free(block);
- }
-}
-
-inline void PathSimplifier::ElementAllocator::allocate(int count)
-{
- Q_ASSERT(blocks == 0);
- Q_ASSERT(count > 0);
- blocks = (ElementBlock *)malloc(sizeof(ElementBlock) + (count - 1) * sizeof(Element));
- blocks->blockSize = count;
- blocks->next = 0;
- blocks->firstFree = 0;
-}
-
-inline PathSimplifier::Element *PathSimplifier::ElementAllocator::newElement()
-{
- Q_ASSERT(blocks);
- if (blocks->firstFree < blocks->blockSize)
- return &blocks->elements[blocks->firstFree++];
- ElementBlock *oldBlock = blocks;
- blocks = (ElementBlock *)malloc(sizeof(ElementBlock) + (oldBlock->blockSize - 1) * sizeof(Element));
- blocks->blockSize = oldBlock->blockSize;
- blocks->next = oldBlock;
- blocks->firstFree = 0;
- return &blocks->elements[blocks->firstFree++];
-}
-
-
-inline bool PathSimplifier::Event::operator < (const Event &other) const
-{
- if (point == other.point)
- return type < other.type;
- return other.point < point;
-}
-
-inline void PathSimplifier::Element::flip()
-{
- for (int i = 0; i < (degree + 1) >> 1; ++i) {
- Q_ASSERT(degree >= Line && degree <= Cubic);
- Q_ASSERT(i >= 0 && i < degree);
- qSwap(indices[i], indices[degree - i]);
- }
- pointingUp = !pointingUp;
- Q_ASSERT(next == 0 && previous == 0);
-}
-
-PathSimplifier::PathSimplifier(const QVectorPath &path, QDataBuffer<QPoint> &vertices,
- QDataBuffer<quint32> &indices, const QTransform &matrix)
- : m_elements(0)
- , m_points(&vertices)
- , m_indices(&indices)
-{
- m_points->reset();
- m_indices->reset();
- initElements(path, matrix);
- if (!m_elements.isEmpty()) {
- removeIntersections();
- connectElements();
- fillIndices();
- }
-}
-
-void PathSimplifier::initElements(const QVectorPath &path, const QTransform &matrix)
-{
- m_hints = path.hints();
- int pathElementCount = path.elementCount();
- if (pathElementCount == 0)
- return;
- m_elements.reserve(2 * pathElementCount);
- m_elementAllocator.allocate(2 * pathElementCount);
- m_points->reserve(2 * pathElementCount);
- const QPainterPath::ElementType *e = path.elements();
- const qreal *p = path.points();
- if (e) {
- qreal x, y;
- quint32 moveToIndex = 0;
- quint32 previousIndex = 0;
- for (int i = 0; i < pathElementCount; ++i, ++e, p += 2) {
- switch (*e) {
- case QPainterPath::MoveToElement:
- {
- if (!m_points->isEmpty()) {
- const QPoint &from = m_points->at(previousIndex);
- const QPoint &to = m_points->at(moveToIndex);
- if (from != to) {
- Element *element = m_elementAllocator.newElement();
- element->degree = Element::Line;
- element->indices[0] = previousIndex;
- element->indices[1] = moveToIndex;
- element->middle.rx() = (from.x() + to.x()) >> 1;
- element->middle.ry() = (from.y() + to.y()) >> 1;
- m_elements.add(element);
- }
- }
- previousIndex = moveToIndex = m_points->size();
- matrix.map(p[0], p[1], &x, &y);
- QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE));
- m_points->add(to);
- }
- break;
- case QPainterPath::LineToElement:
- Q_ASSERT(!m_points->isEmpty());
- {
- matrix.map(p[0], p[1], &x, &y);
- QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE));
- const QPoint &from = m_points->last();
- if (to != from) {
- Element *element = m_elementAllocator.newElement();
- element->degree = Element::Line;
- element->indices[0] = previousIndex;
- element->indices[1] = quint32(m_points->size());
- element->middle.rx() = (from.x() + to.x()) >> 1;
- element->middle.ry() = (from.y() + to.y()) >> 1;
- m_elements.add(element);
- previousIndex = m_points->size();
- m_points->add(to);
- }
- }
- break;
- case QPainterPath::CurveToElement:
- Q_ASSERT(i + 2 < pathElementCount);
- Q_ASSERT(!m_points->isEmpty());
- Q_ASSERT(e[1] == QPainterPath::CurveToDataElement);
- Q_ASSERT(e[2] == QPainterPath::CurveToDataElement);
- {
- quint32 startPointIndex = previousIndex;
- matrix.map(p[4], p[5], &x, &y);
- QPoint end(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE));
- previousIndex = m_points->size();
- m_points->add(end);
-
- // See if this cubic bezier is really quadratic.
- qreal x1 = p[-2] + qreal(1.5) * (p[0] - p[-2]);
- qreal y1 = p[-1] + qreal(1.5) * (p[1] - p[-1]);
- qreal x2 = p[4] + qreal(1.5) * (p[2] - p[4]);
- qreal y2 = p[5] + qreal(1.5) * (p[3] - p[5]);
-
- Element *element = m_elementAllocator.newElement();
- if (qAbs(x1 - x2) < qreal(1e-3) && qAbs(y1 - y2) < qreal(1e-3)) {
- // The bezier curve is quadratic.
- matrix.map(x1, y1, &x, &y);
- QPoint ctrl(qRound(x * Q_FIXED_POINT_SCALE),
- qRound(y * Q_FIXED_POINT_SCALE));
- setElementToQuadratic(element, startPointIndex, ctrl, previousIndex);
- } else {
- // The bezier curve is cubic.
- matrix.map(p[0], p[1], &x, &y);
- QPoint ctrl1(qRound(x * Q_FIXED_POINT_SCALE),
- qRound(y * Q_FIXED_POINT_SCALE));
- matrix.map(p[2], p[3], &x, &y);
- QPoint ctrl2(qRound(x * Q_FIXED_POINT_SCALE),
- qRound(y * Q_FIXED_POINT_SCALE));
- setElementToCubicAndSimplify(element, startPointIndex, ctrl1, ctrl2,
- previousIndex);
- }
- m_elements.add(element);
- }
- i += 2;
- e += 2;
- p += 4;
-
- break;
- default:
- Q_ASSERT_X(0, "QSGPathSimplifier::initialize", "Unexpected element type.");
- break;
- }
- }
- if (!m_points->isEmpty()) {
- const QPoint &from = m_points->at(previousIndex);
- const QPoint &to = m_points->at(moveToIndex);
- if (from != to) {
- Element *element = m_elementAllocator.newElement();
- element->degree = Element::Line;
- element->indices[0] = previousIndex;
- element->indices[1] = moveToIndex;
- element->middle.rx() = (from.x() + to.x()) >> 1;
- element->middle.ry() = (from.y() + to.y()) >> 1;
- m_elements.add(element);
- }
- }
- } else {
- qreal x, y;
-
- for (int i = 0; i < pathElementCount; ++i, p += 2) {
- matrix.map(p[0], p[1], &x, &y);
- QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE));
- if (to != m_points->last())
- m_points->add(to);
- }
-
- while (!m_points->isEmpty() && m_points->last() == m_points->first())
- m_points->pop_back();
-
- if (m_points->isEmpty())
- return;
-
- quint32 prev = quint32(m_points->size() - 1);
- for (int i = 0; i < m_points->size(); ++i) {
- QPoint &to = m_points->at(i);
- QPoint &from = m_points->at(prev);
- Element *element = m_elementAllocator.newElement();
- element->degree = Element::Line;
- element->indices[0] = prev;
- element->indices[1] = quint32(i);
- element->middle.rx() = (from.x() + to.x()) >> 1;
- element->middle.ry() = (from.y() + to.y()) >> 1;
- m_elements.add(element);
- prev = i;
- }
- }
-
- for (int i = 0; i < m_elements.size(); ++i)
- m_elements.at(i)->processed = false;
-}
-
-void PathSimplifier::removeIntersections()
-{
- Q_ASSERT(!m_elements.isEmpty());
- QDataBuffer<Element *> elements(m_elements.size());
- for (int i = 0; i < m_elements.size(); ++i)
- elements.add(m_elements.at(i));
- m_bvh.allocate(2 * m_elements.size());
- m_bvh.root = buildTree(elements.data(), elements.size());
-
- elements.reset();
- for (int i = 0; i < m_elements.size(); ++i)
- elements.add(m_elements.at(i));
-
- while (!elements.isEmpty()) {
- Element *element = elements.last();
- elements.pop_back();
- BVHNode *node = element->bvhNode;
- Q_ASSERT(node->type == BVHNode::Leaf);
- Q_ASSERT(node->element == element);
- if (!element->processed) {
- if (!intersectNodes(elements, node, m_bvh.root))
- element->processed = true;
- }
- }
-
- m_bvh.free(); // The bounding volume hierarchy is not needed anymore.
-}
-
-void PathSimplifier::connectElements()
-{
- Q_ASSERT(!m_elements.isEmpty());
- QDataBuffer<Event> events(m_elements.size() * 2);
- for (int i = 0; i < m_elements.size(); ++i) {
- Element *element = m_elements.at(i);
- element->next = element->previous = 0;
- element->winding = 0;
- element->edgeNode = 0;
- const QPoint &u = m_points->at(element->indices[0]);
- const QPoint &v = m_points->at(element->indices[element->degree]);
- if (u != v) {
- element->pointingUp = element->originallyPointingUp = v < u;
-
- Event event;
- event.element = element;
- event.point = u;
- event.type = element->pointingUp ? Event::Lower : Event::Upper;
- events.add(event);
- event.point = v;
- event.type = element->pointingUp ? Event::Upper : Event::Lower;
- events.add(event);
- }
- }
- QVarLengthArray<Element *, 8> orderedElements;
- if (!events.isEmpty())
- sortEvents(events.data(), events.size());
- while (!events.isEmpty()) {
- const Event *event = &events.last();
- QPoint eventPoint = event->point;
-
- // Find all elements passing through the event point.
- QPair<RBNode *, RBNode *> bounds = outerBounds(eventPoint);
-
- // Special case: single element above and single element below event point.
- int eventCount = events.size();
- if (event->type == Event::Lower && eventCount > 2) {
- QPair<RBNode *, RBNode *> range;
- range.first = bounds.first ? m_elementList.next(bounds.first)
- : m_elementList.front(m_elementList.root);
- range.second = bounds.second ? m_elementList.previous(bounds.second)
- : m_elementList.back(m_elementList.root);
-
- const Event *event2 = &events.at(eventCount - 2);
- const Event *event3 = &events.at(eventCount - 3);
- Q_ASSERT(event2->point == eventPoint); // There are always at least two events at a point.
- if (range.first == range.second && event2->type == Event::Upper && event3->point != eventPoint) {
- Element *element = event->element;
- Element *element2 = event2->element;
- element->edgeNode->data = event2->element;
- element2->edgeNode = element->edgeNode;
- element->edgeNode = 0;
-
- events.pop_back();
- events.pop_back();
-
- if (element2->pointingUp != element->pointingUp)
- element2->flip();
- element2->winding = element->winding;
- int winding = element->winding;
- if (element->originallyPointingUp)
- ++winding;
- if (winding == 0 || winding == 1) {
- if (element->pointingUp) {
- element->previous = event2->element;
- element2->next = event->element;
- } else {
- element->next = event2->element;
- element2->previous = event->element;
- }
- }
- continue;
- }
- }
- orderedElements.clear();
-
- // First, find the ones above the event point.
- if (m_elementList.root) {
- RBNode *current = bounds.first ? m_elementList.next(bounds.first)
- : m_elementList.front(m_elementList.root);
- while (current != bounds.second) {
- Element *element = current->data;
- Q_ASSERT(element->edgeNode == current);
- int winding = element->winding;
- if (element->originallyPointingUp)
- ++winding;
- const QPoint &lower = m_points->at(element->lowerIndex());
- if (lower == eventPoint) {
- if (winding == 0 || winding == 1)
- orderedElements.append(current->data);
- } else {
- // The element is passing through 'event.point'.
- Q_ASSERT(m_points->at(element->upperIndex()) != eventPoint);
- Q_ASSERT(element->degree == Element::Line);
- // Split the line.
- Element *eventElement = event->element;
- int indexIndex = (event->type == Event::Upper) == eventElement->pointingUp
- ? eventElement->degree : 0;
- quint32 pointIndex = eventElement->indices[indexIndex];
- Q_ASSERT(eventPoint == m_points->at(pointIndex));
-
- Element *upperElement = m_elementAllocator.newElement();
- *upperElement = *element;
- upperElement->lowerIndex() = element->upperIndex() = pointIndex;
- upperElement->edgeNode = 0;
- element->next = element->previous = 0;
- if (upperElement->next)
- upperElement->next->previous = upperElement;
- else if (upperElement->previous)
- upperElement->previous->next = upperElement;
- if (element->pointingUp != element->originallyPointingUp)
- element->flip();
- if (winding == 0 || winding == 1)
- orderedElements.append(upperElement);
- m_elements.add(upperElement);
- }
- current = m_elementList.next(current);
- }
- }
- while (!events.isEmpty() && events.last().point == eventPoint) {
- event = &events.last();
- if (event->type == Event::Upper) {
- Q_ASSERT(event->point == m_points->at(event->element->upperIndex()));
- RBNode *left = findElementLeftOf(event->element, bounds);
- RBNode *node = m_elementList.newNode();
- node->data = event->element;
- Q_ASSERT(event->element->edgeNode == 0);
- event->element->edgeNode = node;
- m_elementList.attachAfter(left, node);
- } else {
- Q_ASSERT(event->type == Event::Lower);
- Q_ASSERT(event->point == m_points->at(event->element->lowerIndex()));
- Element *element = event->element;
- Q_ASSERT(element->edgeNode);
- m_elementList.deleteNode(element->edgeNode);
- Q_ASSERT(element->edgeNode == 0);
- }
- events.pop_back();
- }
-
- if (m_elementList.root) {
- RBNode *current = bounds.first ? m_elementList.next(bounds.first)
- : m_elementList.front(m_elementList.root);
- int winding = bounds.first ? bounds.first->data->winding : 0;
-
- // Calculate winding numbers and flip elements if necessary.
- while (current != bounds.second) {
- Element *element = current->data;
- Q_ASSERT(element->edgeNode == current);
- int ccw = winding & 1;
- Q_ASSERT(element->pointingUp == element->originallyPointingUp);
- if (element->originallyPointingUp) {
- --winding;
- } else {
- ++winding;
- ccw ^= 1;
- }
- element->winding = winding;
- if (ccw == 0)
- element->flip();
- current = m_elementList.next(current);
- }
-
- // Pick elements with correct winding number.
- current = bounds.second ? m_elementList.previous(bounds.second)
- : m_elementList.back(m_elementList.root);
- while (current != bounds.first) {
- Element *element = current->data;
- Q_ASSERT(element->edgeNode == current);
- Q_ASSERT(m_points->at(element->upperIndex()) == eventPoint);
- int winding = element->winding;
- if (element->originallyPointingUp)
- ++winding;
- if (winding == 0 || winding == 1)
- orderedElements.append(current->data);
- current = m_elementList.previous(current);
- }
- }
-
- if (!orderedElements.isEmpty()) {
- Q_ASSERT((orderedElements.size() & 1) == 0);
- int i = 0;
- Element *firstElement = orderedElements.at(0);
- if (m_points->at(firstElement->indices[0]) != eventPoint) {
- orderedElements.append(firstElement);
- i = 1;
- }
- for (; i < orderedElements.size(); i += 2) {
- Q_ASSERT(i + 1 < orderedElements.size());
- Element *next = orderedElements.at(i);
- Element *previous = orderedElements.at(i + 1);
- Q_ASSERT(next->previous == 0);
- Q_ASSERT(previous->next == 0);
- next->previous = previous;
- previous->next = next;
- }
- }
- }
-#ifndef QT_NO_DEBUG
- for (int i = 0; i < m_elements.size(); ++i) {
- const Element *element = m_elements.at(i);
- Q_ASSERT(element->next == 0 || element->next->previous == element);
- Q_ASSERT(element->previous == 0 || element->previous->next == element);
- Q_ASSERT((element->next == 0) == (element->previous == 0));
- }
-#endif
-}
-
-void PathSimplifier::fillIndices()
-{
- for (int i = 0; i < m_elements.size(); ++i)
- m_elements.at(i)->processed = false;
- for (int i = 0; i < m_elements.size(); ++i) {
- Element *element = m_elements.at(i);
- if (element->processed || element->next == 0)
- continue;
- do {
- m_indices->add(element->indices[0]);
- switch (element->degree) {
- case Element::Quadratic:
- {
- QPoint pts[] = {
- m_points->at(element->indices[0]),
- m_points->at(element->indices[1]),
- m_points->at(element->indices[2])
- };
- subDivQuadratic(pts[0], pts[1], pts[2]);
- }
- break;
- case Element::Cubic:
- {
- QPoint pts[] = {
- m_points->at(element->indices[0]),
- m_points->at(element->indices[1]),
- m_points->at(element->indices[2]),
- m_points->at(element->indices[3])
- };
- subDivCubic(pts[0], pts[1], pts[2], pts[3]);
- }
- break;
- default:
- break;
- }
- Q_ASSERT(element->next);
- element->processed = true;
- element = element->next;
- } while (element != m_elements.at(i));
- m_indices->add(Q_TRIANGULATE_END_OF_POLYGON);
- }
-}
-
-PathSimplifier::BVHNode *PathSimplifier::buildTree(Element **elements, int elementCount)
-{
- Q_ASSERT(elementCount > 0);
- BVHNode *node = m_bvh.newNode();
- if (elementCount == 1) {
- Element *element = *elements;
- element->bvhNode = node;
- node->type = BVHNode::Leaf;
- node->element = element;
- node->minimum = node->maximum = m_points->at(element->indices[0]);
- for (int i = 1; i <= element->degree; ++i) {
- const QPoint &p = m_points->at(element->indices[i]);
- node->minimum.rx() = qMin(node->minimum.x(), p.x());
- node->minimum.ry() = qMin(node->minimum.y(), p.y());
- node->maximum.rx() = qMax(node->maximum.x(), p.x());
- node->maximum.ry() = qMax(node->maximum.y(), p.y());
- }
- return node;
- }
-
- node->type = BVHNode::Split;
-
- QPoint minimum, maximum;
- minimum = maximum = elements[0]->middle;
-
- for (int i = 1; i < elementCount; ++i) {
- const QPoint &p = elements[i]->middle;
- minimum.rx() = qMin(minimum.x(), p.x());
- minimum.ry() = qMin(minimum.y(), p.y());
- maximum.rx() = qMax(maximum.x(), p.x());
- maximum.ry() = qMax(maximum.y(), p.y());
- }
-
- int comp, pivot;
- if (maximum.x() - minimum.x() > maximum.y() - minimum.y()) {
- comp = 0;
- pivot = (maximum.x() + minimum.x()) >> 1;
- } else {
- comp = 1;
- pivot = (maximum.y() + minimum.y()) >> 1;
- }
-
- int lo = 0;
- int hi = elementCount - 1;
- while (lo < hi) {
- while (lo < hi && (&elements[lo]->middle.rx())[comp] <= pivot)
- ++lo;
- while (lo < hi && (&elements[hi]->middle.rx())[comp] > pivot)
- --hi;
- if (lo < hi)
- qSwap(elements[lo], elements[hi]);
- }
-
- if (lo == elementCount) {
- // All points are the same.
- Q_ASSERT(minimum.x() == maximum.x() && minimum.y() == maximum.y());
- lo = elementCount >> 1;
- }
-
- node->left = buildTree(elements, lo);
- node->right = buildTree(elements + lo, elementCount - lo);
-
- const BVHNode *left = node->left;
- const BVHNode *right = node->right;
- node->minimum.rx() = qMin(left->minimum.x(), right->minimum.x());
- node->minimum.ry() = qMin(left->minimum.y(), right->minimum.y());
- node->maximum.rx() = qMax(left->maximum.x(), right->maximum.x());
- node->maximum.ry() = qMax(left->maximum.y(), right->maximum.y());
-
- return node;
-}
-
-bool PathSimplifier::intersectNodes(QDataBuffer<Element *> &elements, BVHNode *elementNode,
- BVHNode *treeNode)
-{
- if (elementNode->minimum.x() >= treeNode->maximum.x()
- || elementNode->minimum.y() >= treeNode->maximum.y()
- || elementNode->maximum.x() <= treeNode->minimum.x()
- || elementNode->maximum.y() <= treeNode->minimum.y())
- {
- return false;
- }
-
- Q_ASSERT(elementNode->type == BVHNode::Leaf);
- Element *element = elementNode->element;
- Q_ASSERT(!element->processed);
-
- if (treeNode->type == BVHNode::Leaf) {
- Element *nodeElement = treeNode->element;
- if (!nodeElement->processed)
- return false;
-
- if (treeNode->element == elementNode->element)
- return false;
-
- if (equalElements(treeNode->element, elementNode->element))
- return false; // element doesn't split itself.
-
- if (element->degree == Element::Line && nodeElement->degree == Element::Line) {
- const QPoint &u1 = m_points->at(element->indices[0]);
- const QPoint &u2 = m_points->at(element->indices[1]);
- const QPoint &v1 = m_points->at(nodeElement->indices[0]);
- const QPoint &v2 = m_points->at(nodeElement->indices[1]);
- IntersectionPoint intersection = intersectionPoint(u1, u2, v1, v2);
- if (!intersection.isValid())
- return false;
-
- Q_ASSERT(intersection.x.integer >= qMin(u1.x(), u2.x()));
- Q_ASSERT(intersection.y.integer >= qMin(u1.y(), u2.y()));
- Q_ASSERT(intersection.x.integer >= qMin(v1.x(), v2.x()));
- Q_ASSERT(intersection.y.integer >= qMin(v1.y(), v2.y()));
-
- Q_ASSERT(intersection.x.integer <= qMax(u1.x(), u2.x()));
- Q_ASSERT(intersection.y.integer <= qMax(u1.y(), u2.y()));
- Q_ASSERT(intersection.x.integer <= qMax(v1.x(), v2.x()));
- Q_ASSERT(intersection.y.integer <= qMax(v1.y(), v2.y()));
-
- m_points->add(intersection.round());
- splitLineAt(elements, treeNode, m_points->size() - 1, !intersection.isAccurate());
- return splitLineAt(elements, elementNode, m_points->size() - 1, false);
- } else {
- QVarLengthArray<QPoint, 12> axes;
- appendSeparatingAxes(axes, elementNode->element);
- appendSeparatingAxes(axes, treeNode->element);
- for (int i = 0; i < axes.size(); ++i) {
- QPair<int, int> range1 = calculateSeparatingAxisRange(axes.at(i), elementNode->element);
- QPair<int, int> range2 = calculateSeparatingAxisRange(axes.at(i), treeNode->element);
- if (range1.first >= range2.second || range1.second <= range2.first) {
- return false; // Separating axis found.
- }
- }
- // Bounding areas overlap.
- if (nodeElement->degree > Element::Line)
- splitCurve(elements, treeNode);
- if (element->degree > Element::Line) {
- splitCurve(elements, elementNode);
- } else {
- // The element was not split, so it can be processed further.
- if (intersectNodes(elements, elementNode, treeNode->left))
- return true;
- if (intersectNodes(elements, elementNode, treeNode->right))
- return true;
- return false;
- }
- return true;
- }
- } else {
- if (intersectNodes(elements, elementNode, treeNode->left))
- return true;
- if (intersectNodes(elements, elementNode, treeNode->right))
- return true;
- return false;
- }
-}
-
-bool PathSimplifier::equalElements(const Element *e1, const Element *e2)
-{
- Q_ASSERT(e1 != e2);
- if (e1->degree != e2->degree)
- return false;
-
- // Possibly equal and in the same direction.
- bool equalSame = true;
- for (int i = 0; i <= e1->degree; ++i)
- equalSame &= m_points->at(e1->indices[i]) == m_points->at(e2->indices[i]);
-
- // Possibly equal and in opposite directions.
- bool equalOpposite = true;
- for (int i = 0; i <= e1->degree; ++i)
- equalOpposite &= m_points->at(e1->indices[e1->degree - i]) == m_points->at(e2->indices[i]);
-
- return equalSame || equalOpposite;
-}
-
-bool PathSimplifier::splitLineAt(QDataBuffer<Element *> &elements, BVHNode *node,
- quint32 pointIndex, bool processAgain)
-{
- Q_ASSERT(node->type == BVHNode::Leaf);
- Element *element = node->element;
- Q_ASSERT(element->degree == Element::Line);
- const QPoint &u = m_points->at(element->indices[0]);
- const QPoint &v = m_points->at(element->indices[1]);
- const QPoint &p = m_points->at(pointIndex);
- if (u == p || v == p)
- return false; // No split needed.
-
- if (processAgain)
- element->processed = false; // Needs to be processed again.
-
- Element *first = node->element;
- Element *second = m_elementAllocator.newElement();
- *second = *first;
- first->indices[1] = second->indices[0] = pointIndex;
- first->middle.rx() = (u.x() + p.x()) >> 1;
- first->middle.ry() = (u.y() + p.y()) >> 1;
- second->middle.rx() = (v.x() + p.x()) >> 1;
- second->middle.ry() = (v.y() + p.y()) >> 1;
- m_elements.add(second);
-
- BVHNode *left = m_bvh.newNode();
- BVHNode *right = m_bvh.newNode();
- left->type = right->type = BVHNode::Leaf;
- left->element = first;
- right->element = second;
- left->minimum = right->minimum = node->minimum;
- left->maximum = right->maximum = node->maximum;
- if (u.x() < v.x())
- left->maximum.rx() = right->minimum.rx() = p.x();
- else
- left->minimum.rx() = right->maximum.rx() = p.x();
- if (u.y() < v.y())
- left->maximum.ry() = right->minimum.ry() = p.y();
- else
- left->minimum.ry() = right->maximum.ry() = p.y();
- left->element->bvhNode = left;
- right->element->bvhNode = right;
-
- node->type = BVHNode::Split;
- node->left = left;
- node->right = right;
-
- if (!first->processed) {
- elements.add(left->element);
- elements.add(right->element);
- }
- return true;
-}
-
-void PathSimplifier::appendSeparatingAxes(QVarLengthArray<QPoint, 12> &axes, Element *element)
-{
- switch (element->degree) {
- case Element::Cubic:
- {
- const QPoint &u = m_points->at(element->indices[0]);
- const QPoint &v = m_points->at(element->indices[1]);
- const QPoint &w = m_points->at(element->indices[2]);
- const QPoint &q = m_points->at(element->indices[3]);
- QPoint ns[] = {
- QPoint(u.y() - v.y(), v.x() - u.x()),
- QPoint(v.y() - w.y(), w.x() - v.x()),
- QPoint(w.y() - q.y(), q.x() - w.x()),
- QPoint(q.y() - u.y(), u.x() - q.x()),
- QPoint(u.y() - w.y(), w.x() - u.x()),
- QPoint(v.y() - q.y(), q.x() - v.x())
- };
- for (int i = 0; i < 6; ++i) {
- if (ns[i].x() || ns[i].y())
- axes.append(ns[i]);
- }
- }
- break;
- case Element::Quadratic:
- {
- const QPoint &u = m_points->at(element->indices[0]);
- const QPoint &v = m_points->at(element->indices[1]);
- const QPoint &w = m_points->at(element->indices[2]);
- QPoint ns[] = {
- QPoint(u.y() - v.y(), v.x() - u.x()),
- QPoint(v.y() - w.y(), w.x() - v.x()),
- QPoint(w.y() - u.y(), u.x() - w.x())
- };
- for (int i = 0; i < 3; ++i) {
- if (ns[i].x() || ns[i].y())
- axes.append(ns[i]);
- }
- }
- break;
- case Element::Line:
- {
- const QPoint &u = m_points->at(element->indices[0]);
- const QPoint &v = m_points->at(element->indices[1]);
- QPoint n(u.y() - v.y(), v.x() - u.x());
- if (n.x() || n.y())
- axes.append(n);
- }
- break;
- default:
- Q_ASSERT_X(0, "QSGPathSimplifier::appendSeparatingAxes", "Unexpected element type.");
- break;
- }
-}
-
-QPair<int, int> PathSimplifier::calculateSeparatingAxisRange(const QPoint &axis, Element *element)
-{
- QPair<int, int> range(0x7fffffff, -0x7fffffff);
- for (int i = 0; i <= element->degree; ++i) {
- const QPoint &p = m_points->at(element->indices[i]);
- int dist = dot(axis, p);
- range.first = qMin(range.first, dist);
- range.second = qMax(range.second, dist);
- }
- return range;
-}
-
-void PathSimplifier::splitCurve(QDataBuffer<Element *> &elements, BVHNode *node)
-{
- Q_ASSERT(node->type == BVHNode::Leaf);
-
- Element *first = node->element;
- Element *second = m_elementAllocator.newElement();
- *second = *first;
- m_elements.add(second);
- Q_ASSERT(first->degree > Element::Line);
-
- bool accurate = true;
- const QPoint &u = m_points->at(first->indices[0]);
- const QPoint &v = m_points->at(first->indices[1]);
- const QPoint &w = m_points->at(first->indices[2]);
-
- if (first->degree == Element::Quadratic) {
- QPoint pts[3];
- accurate = splitQuadratic(u, v, w, pts);
- int pointIndex = m_points->size();
- m_points->add(pts[1]);
- accurate &= setElementToQuadratic(first, first->indices[0], pts[0], pointIndex);
- accurate &= setElementToQuadratic(second, pointIndex, pts[2], second->indices[2]);
- } else {
- Q_ASSERT(first->degree == Element::Cubic);
- const QPoint &q = m_points->at(first->indices[3]);
- QPoint pts[5];
- accurate = splitCubic(u, v, w, q, pts);
- int pointIndex = m_points->size();
- m_points->add(pts[2]);
- accurate &= setElementToCubic(first, first->indices[0], pts[0], pts[1], pointIndex);
- accurate &= setElementToCubic(second, pointIndex, pts[3], pts[4], second->indices[3]);
- }
-
- if (!accurate)
- first->processed = second->processed = false; // Needs to be processed again.
-
- BVHNode *left = m_bvh.newNode();
- BVHNode *right = m_bvh.newNode();
- left->type = right->type = BVHNode::Leaf;
- left->element = first;
- right->element = second;
-
- left->minimum.rx() = left->minimum.ry() = right->minimum.rx() = right->minimum.ry() = INT_MAX;
- left->maximum.rx() = left->maximum.ry() = right->maximum.rx() = right->maximum.ry() = INT_MIN;
-
- for (int i = 0; i <= first->degree; ++i) {
- QPoint &p = m_points->at(first->indices[i]);
- left->minimum.rx() = qMin(left->minimum.x(), p.x());
- left->minimum.ry() = qMin(left->minimum.y(), p.y());
- left->maximum.rx() = qMax(left->maximum.x(), p.x());
- left->maximum.ry() = qMax(left->maximum.y(), p.y());
- }
- for (int i = 0; i <= second->degree; ++i) {
- QPoint &p = m_points->at(second->indices[i]);
- right->minimum.rx() = qMin(right->minimum.x(), p.x());
- right->minimum.ry() = qMin(right->minimum.y(), p.y());
- right->maximum.rx() = qMax(right->maximum.x(), p.x());
- right->maximum.ry() = qMax(right->maximum.y(), p.y());
- }
- left->element->bvhNode = left;
- right->element->bvhNode = right;
-
- node->type = BVHNode::Split;
- node->left = left;
- node->right = right;
-
- if (!first->processed) {
- elements.add(left->element);
- elements.add(right->element);
- }
-}
-
-bool PathSimplifier::setElementToQuadratic(Element *element, quint32 pointIndex1,
- const QPoint &ctrl, quint32 pointIndex2)
-{
- const QPoint &p1 = m_points->at(pointIndex1);
- const QPoint &p2 = m_points->at(pointIndex2);
- if (flattenQuadratic(p1, ctrl, p2)) {
- // Insert line.
- element->degree = Element::Line;
- element->indices[0] = pointIndex1;
- element->indices[1] = pointIndex2;
- element->middle.rx() = (p1.x() + p2.x()) >> 1;
- element->middle.ry() = (p1.y() + p2.y()) >> 1;
- return false;
- } else {
- // Insert bezier.
- element->degree = Element::Quadratic;
- element->indices[0] = pointIndex1;
- element->indices[1] = m_points->size();
- element->indices[2] = pointIndex2;
- element->middle.rx() = (p1.x() + ctrl.x() + p2.x()) / 3;
- element->middle.ry() = (p1.y() + ctrl.y() + p2.y()) / 3;
- m_points->add(ctrl);
- return true;
- }
-}
-
-bool PathSimplifier::setElementToCubic(Element *element, quint32 pointIndex1, const QPoint &v,
- const QPoint &w, quint32 pointIndex2)
-{
- const QPoint &u = m_points->at(pointIndex1);
- const QPoint &q = m_points->at(pointIndex2);
- if (flattenCubic(u, v, w, q)) {
- // Insert line.
- element->degree = Element::Line;
- element->indices[0] = pointIndex1;
- element->indices[1] = pointIndex2;
- element->middle.rx() = (u.x() + q.x()) >> 1;
- element->middle.ry() = (u.y() + q.y()) >> 1;
- return false;
- } else {
- // Insert bezier.
- element->degree = Element::Cubic;
- element->indices[0] = pointIndex1;
- element->indices[1] = m_points->size();
- element->indices[2] = m_points->size() + 1;
- element->indices[3] = pointIndex2;
- element->middle.rx() = (u.x() + v.x() + w.x() + q.x()) >> 2;
- element->middle.ry() = (u.y() + v.y() + w.y() + q.y()) >> 2;
- m_points->add(v);
- m_points->add(w);
- return true;
- }
-}
-
-void PathSimplifier::setElementToCubicAndSimplify(Element *element, quint32 pointIndex1,
- const QPoint &v, const QPoint &w,
- quint32 pointIndex2)
-{
- const QPoint &u = m_points->at(pointIndex1);
- const QPoint &q = m_points->at(pointIndex2);
- if (flattenCubic(u, v, w, q)) {
- // Insert line.
- element->degree = Element::Line;
- element->indices[0] = pointIndex1;
- element->indices[1] = pointIndex2;
- element->middle.rx() = (u.x() + q.x()) >> 1;
- element->middle.ry() = (u.y() + q.y()) >> 1;
- return;
- }
-
- bool intersecting = (u == q) || intersectionPoint(u, v, w, q).isValid();
- if (!intersecting) {
- // Insert bezier.
- element->degree = Element::Cubic;
- element->indices[0] = pointIndex1;
- element->indices[1] = m_points->size();
- element->indices[2] = m_points->size() + 1;
- element->indices[3] = pointIndex2;
- element->middle.rx() = (u.x() + v.x() + w.x() + q.x()) >> 2;
- element->middle.ry() = (u.y() + v.y() + w.y() + q.y()) >> 2;
- m_points->add(v);
- m_points->add(w);
- return;
- }
-
- QPoint pts[5];
- splitCubic(u, v, w, q, pts);
- int pointIndex = m_points->size();
- m_points->add(pts[2]);
- Element *element2 = m_elementAllocator.newElement();
- m_elements.add(element2);
- setElementToCubicAndSimplify(element, pointIndex1, pts[0], pts[1], pointIndex);
- setElementToCubicAndSimplify(element2, pointIndex, pts[3], pts[4], pointIndex2);
-}
-
-PathSimplifier::RBNode *PathSimplifier::findElementLeftOf(const Element *element,
- const QPair<RBNode *, RBNode *> &bounds)
-{
- if (!m_elementList.root)
- return 0;
- RBNode *current = bounds.first;
- Q_ASSERT(!current || !elementIsLeftOf(element, current->data));
- if (!current)
- current = m_elementList.front(m_elementList.root);
- Q_ASSERT(current);
- RBNode *result = 0;
- while (current != bounds.second && !elementIsLeftOf(element, current->data)) {
- result = current;
- current = m_elementList.next(current);
- }
- return result;
-}
-
-bool PathSimplifier::elementIsLeftOf(const Element *left, const Element *right)
-{
- const QPoint &leftU = m_points->at(left->upperIndex());
- const QPoint &leftL = m_points->at(left->lowerIndex());
- const QPoint &rightU = m_points->at(right->upperIndex());
- const QPoint &rightL = m_points->at(right->lowerIndex());
- Q_ASSERT(leftL >= rightU && rightL >= leftU);
- if (leftU.x() < qMin(rightL.x(), rightU.x()))
- return true;
- if (leftU.x() > qMax(rightL.x(), rightU.x()))
- return false;
- int d = pointDistanceFromLine(leftU, rightL, rightU);
- // d < 0: left, d > 0: right, d == 0: on top
- if (d == 0) {
- d = pointDistanceFromLine(leftL, rightL, rightU);
- if (d == 0) {
- if (right->degree > Element::Line) {
- d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[1]));
- if (d == 0)
- d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[2]));
- } else if (left->degree > Element::Line) {
- d = pointDistanceFromLine(m_points->at(left->indices[1]), rightL, rightU);
- if (d == 0)
- d = pointDistanceFromLine(m_points->at(left->indices[2]), rightL, rightU);
- }
- }
- }
- return d < 0;
-}
-
-QPair<PathSimplifier::RBNode *, PathSimplifier::RBNode *> PathSimplifier::outerBounds(const QPoint &point)
-{
- RBNode *current = m_elementList.root;
- QPair<RBNode *, RBNode *> result(0, 0);
-
- while (current) {
- const Element *element = current->data;
- Q_ASSERT(element->edgeNode == current);
- const QPoint &v1 = m_points->at(element->lowerIndex());
- const QPoint &v2 = m_points->at(element->upperIndex());
- Q_ASSERT(point >= v2 && point <= v1);
- if (point == v1 || point == v2)
- break;
- int d = pointDistanceFromLine(point, v1, v2);
- if (d == 0) {
- if (element->degree == Element::Line)
- break;
- d = pointDistanceFromLine(point, v1, m_points->at(element->indices[1]));
- if (d == 0)
- d = pointDistanceFromLine(point, v1, m_points->at(element->indices[2]));
- Q_ASSERT(d != 0);
- }
- if (d < 0) {
- result.second = current;
- current = current->left;
- } else {
- result.first = current;
- current = current->right;
- }
- }
-
- if (!current)
- return result;
-
- RBNode *mid = current;
-
- current = mid->left;
- while (current) {
- const Element *element = current->data;
- Q_ASSERT(element->edgeNode == current);
- const QPoint &v1 = m_points->at(element->lowerIndex());
- const QPoint &v2 = m_points->at(element->upperIndex());
- Q_ASSERT(point >= v2 && point <= v1);
- bool equal = (point == v1 || point == v2);
- if (!equal) {
- int d = pointDistanceFromLine(point, v1, v2);
- Q_ASSERT(d >= 0);
- equal = (d == 0 && element->degree == Element::Line);
- }
- if (equal) {
- current = current->left;
- } else {
- result.first = current;
- current = current->right;
- }
- }
-
- current = mid->right;
- while (current) {
- const Element *element = current->data;
- Q_ASSERT(element->edgeNode == current);
- const QPoint &v1 = m_points->at(element->lowerIndex());
- const QPoint &v2 = m_points->at(element->upperIndex());
- Q_ASSERT(point >= v2 && point <= v1);
- bool equal = (point == v1 || point == v2);
- if (!equal) {
- int d = pointDistanceFromLine(point, v1, v2);
- Q_ASSERT(d <= 0);
- equal = (d == 0 && element->degree == Element::Line);
- }
- if (equal) {
- current = current->right;
- } else {
- result.second = current;
- current = current->left;
- }
- }
-
- return result;
-}
-
-inline bool PathSimplifier::flattenQuadratic(const QPoint &u, const QPoint &v, const QPoint &w)
-{
- QPoint deltas[2] = { v - u, w - v };
- int d = qAbs(cross(deltas[0], deltas[1]));
- int l = qAbs(deltas[0].x()) + qAbs(deltas[0].y()) + qAbs(deltas[1].x()) + qAbs(deltas[1].y());
- return d < (Q_FIXED_POINT_SCALE * Q_FIXED_POINT_SCALE * 3 / 2) || l <= Q_FIXED_POINT_SCALE * 2;
-}
-
-inline bool PathSimplifier::flattenCubic(const QPoint &u, const QPoint &v,
- const QPoint &w, const QPoint &q)
-{
- QPoint deltas[] = { v - u, w - v, q - w, q - u };
- int d = qAbs(cross(deltas[0], deltas[1])) + qAbs(cross(deltas[1], deltas[2]))
- + qAbs(cross(deltas[0], deltas[3])) + qAbs(cross(deltas[3], deltas[2]));
- int l = qAbs(deltas[0].x()) + qAbs(deltas[0].y()) + qAbs(deltas[1].x()) + qAbs(deltas[1].y())
- + qAbs(deltas[2].x()) + qAbs(deltas[2].y());
- return d < (Q_FIXED_POINT_SCALE * Q_FIXED_POINT_SCALE * 3) || l <= Q_FIXED_POINT_SCALE * 2;
-}
-
-inline bool PathSimplifier::splitQuadratic(const QPoint &u, const QPoint &v,
- const QPoint &w, QPoint *result)
-{
- result[0] = u + v;
- result[2] = v + w;
- result[1] = result[0] + result[2];
- bool accurate = ((result[0].x() | result[0].y() | result[2].x() | result[2].y()) & 1) == 0
- && ((result[1].x() | result[1].y()) & 3) == 0;
- result[0].rx() >>= 1;
- result[0].ry() >>= 1;
- result[1].rx() >>= 2;
- result[1].ry() >>= 2;
- result[2].rx() >>= 1;
- result[2].ry() >>= 1;
- return accurate;
-}
-
-inline bool PathSimplifier::splitCubic(const QPoint &u, const QPoint &v,
- const QPoint &w, const QPoint &q, QPoint *result)
-{
- result[0] = u + v;
- result[2] = v + w;
- result[4] = w + q;
- result[1] = result[0] + result[2];
- result[3] = result[2] + result[4];
- result[2] = result[1] + result[3];
- bool accurate = ((result[0].x() | result[0].y() | result[4].x() | result[4].y()) & 1) == 0
- && ((result[1].x() | result[1].y() | result[3].x() | result[3].y()) & 3) == 0
- && ((result[2].x() | result[2].y()) & 7) == 0;
- result[0].rx() >>= 1;
- result[0].ry() >>= 1;
- result[1].rx() >>= 2;
- result[1].ry() >>= 2;
- result[2].rx() >>= 3;
- result[2].ry() >>= 3;
- result[3].rx() >>= 2;
- result[3].ry() >>= 2;
- result[4].rx() >>= 1;
- result[4].ry() >>= 1;
- return accurate;
-}
-
-inline void PathSimplifier::subDivQuadratic(const QPoint &u, const QPoint &v, const QPoint &w)
-{
- if (flattenQuadratic(u, v, w))
- return;
- QPoint pts[3];
- splitQuadratic(u, v, w, pts);
- subDivQuadratic(u, pts[0], pts[1]);
- m_indices->add(m_points->size());
- m_points->add(pts[1]);
- subDivQuadratic(pts[1], pts[2], w);
-}
-
-inline void PathSimplifier::subDivCubic(const QPoint &u, const QPoint &v,
- const QPoint &w, const QPoint &q)
-{
- if (flattenCubic(u, v, w, q))
- return;
- QPoint pts[5];
- splitCubic(u, v, w, q, pts);
- subDivCubic(u, pts[0], pts[1], pts[2]);
- m_indices->add(m_points->size());
- m_points->add(pts[2]);
- subDivCubic(pts[2], pts[3], pts[4], q);
-}
-
-void PathSimplifier::sortEvents(Event *events, int count)
-{
- // Bucket sort + insertion sort.
- Q_ASSERT(count > 0);
- QDataBuffer<Event> buffer(count);
- buffer.resize(count);
- QScopedArrayPointer<int> bins(new int[count]);
- int counts[0x101];
- memset(counts, 0, sizeof(counts));
-
- int minimum, maximum;
- minimum = maximum = events[0].point.y();
- for (int i = 1; i < count; ++i) {
- minimum = qMin(minimum, events[i].point.y());
- maximum = qMax(maximum, events[i].point.y());
- }
-
- for (int i = 0; i < count; ++i) {
- bins[i] = ((maximum - events[i].point.y()) << 8) / (maximum - minimum + 1);
- Q_ASSERT(bins[i] >= 0 && bins[i] < 0x100);
- ++counts[bins[i]];
- }
-
- for (int i = 1; i < 0x100; ++i)
- counts[i] += counts[i - 1];
- counts[0x100] = counts[0xff];
- Q_ASSERT(counts[0x100] == count);
-
- for (int i = 0; i < count; ++i)
- buffer.at(--counts[bins[i]]) = events[i];
-
- int j = 0;
- for (int i = 0; i < 0x100; ++i) {
- for (; j < counts[i + 1]; ++j) {
- int k = j;
- while (k > 0 && (buffer.at(j) < events[k - 1])) {
- events[k] = events[k - 1];
- --k;
- }
- events[k] = buffer.at(j);
- }
- }
-}
-
-} // end anonymous namespace
-
-
-void qSimplifyPath(const QVectorPath &path, QDataBuffer<QPoint> &vertices,
- QDataBuffer<quint32> &indices, const QTransform &matrix)
-{
- PathSimplifier(path, vertices, indices, matrix);
-}
-
-void qSimplifyPath(const QPainterPath &path, QDataBuffer<QPoint> &vertices,
- QDataBuffer<quint32> &indices, const QTransform &matrix)
-{
- qSimplifyPath(qtVectorPathForPath(path), vertices, indices, matrix);
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 6ff9c4c5f9..1e9a645cf4 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -81,7 +81,7 @@ public:
virtual bool interleaveIncubation() const { return false; }
-signals:
+Q_SIGNALS:
void timeToIncubate();
private:
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
index 6ff5cabf43..f1e75f6869 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h
+++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
@@ -81,7 +81,7 @@ public:
bool interleaveIncubation() const;
-public slots:
+public Q_SLOTS:
void animationStarted();
void animationStopped();
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h
index 218e18c3e2..82eeb423e8 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop_p.h
+++ b/src/quick/scenegraph/qsgwindowsrenderloop_p.h
@@ -84,7 +84,7 @@ public:
bool interleaveIncubation() const;
-public slots:
+public Q_SLOTS:
void started();
void stopped();
diff --git a/src/quick/util/qquickapplication.cpp b/src/quick/util/qquickapplication.cpp
index 2de28a9509..244e13888c 100644
--- a/src/quick/util/qquickapplication.cpp
+++ b/src/quick/util/qquickapplication.cpp
@@ -75,6 +75,9 @@ QQuickApplication::QQuickApplication(QObject *parent)
{
if (qApp) {
qApp->installEventFilter(this);
+
+ connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)),
+ this, SIGNAL(stateChanged(Qt::ApplicationState)));
}
}
@@ -99,6 +102,11 @@ bool QQuickApplication::supportsMultipleWindows() const
return QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows);
}
+Qt::ApplicationState QQuickApplication::state() const
+{
+ return QGuiApplication::applicationState();
+}
+
bool QQuickApplication::eventFilter(QObject *, QEvent *event)
{
Q_D(QQuickApplication);
diff --git a/src/quick/util/qquickapplication_p.h b/src/quick/util/qquickapplication_p.h
index cccc024282..780fb1ffa6 100644
--- a/src/quick/util/qquickapplication_p.h
+++ b/src/quick/util/qquickapplication_p.h
@@ -54,9 +54,10 @@ class QQuickApplicationPrivate;
class Q_AUTOTEST_EXPORT QQuickApplication : public QQmlApplication
{
Q_OBJECT
- Q_PROPERTY(bool active READ active NOTIFY activeChanged)
+ Q_PROPERTY(bool active READ active NOTIFY activeChanged) // deprecated, use 'state' instead
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(bool supportsMultipleWindows READ supportsMultipleWindows CONSTANT)
+ Q_PROPERTY(Qt::ApplicationState state READ state NOTIFY stateChanged)
public:
explicit QQuickApplication(QObject *parent = 0);
@@ -64,10 +65,12 @@ public:
bool active() const;
Qt::LayoutDirection layoutDirection() const;
bool supportsMultipleWindows() const;
+ Qt::ApplicationState state() const;
Q_SIGNALS:
void activeChanged();
void layoutDirectionChanged();
+ void stateChanged(Qt::ApplicationState state);
private:
bool eventFilter(QObject *, QEvent *event);
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index c8f8574f9d..c08719dec8 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -326,17 +326,17 @@ public:
QV4::ExecutionEngine *v4 = obj->engine();
- QV4::Value vbold = obj->get(v4->newString(QStringLiteral("bold")));
- QV4::Value vcap = obj->get(v4->newString(QStringLiteral("capitalization")));
- QV4::Value vfam = obj->get(v4->newString(QStringLiteral("family")));
- QV4::Value vital = obj->get(v4->newString(QStringLiteral("italic")));
- QV4::Value vlspac = obj->get(v4->newString(QStringLiteral("letterSpacing")));
- QV4::Value vpixsz = obj->get(v4->newString(QStringLiteral("pixelSize")));
- QV4::Value vpntsz = obj->get(v4->newString(QStringLiteral("pointSize")));
- QV4::Value vstrk = obj->get(v4->newString(QStringLiteral("strikeout")));
- QV4::Value vundl = obj->get(v4->newString(QStringLiteral("underline")));
- QV4::Value vweight = obj->get(v4->newString(QStringLiteral("weight")));
- QV4::Value vwspac = obj->get(v4->newString(QStringLiteral("wordSpacing")));
+ QV4::Value vbold = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("bold"))));
+ QV4::Value vcap = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("capitalization"))));
+ QV4::Value vfam = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("family"))));
+ QV4::Value vital = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("italic"))));
+ QV4::Value vlspac = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("letterSpacing"))));
+ QV4::Value vpixsz = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("pixelSize"))));
+ QV4::Value vpntsz = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("pointSize"))));
+ QV4::Value vstrk = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("strikeout"))));
+ QV4::Value vundl = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("underline"))));
+ QV4::Value vweight = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("weight"))));
+ QV4::Value vwspac = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("wordSpacing"))));
// pull out the values, set ok to true if at least one valid field is given.
if (vbold.isBoolean()) {
@@ -348,7 +348,7 @@ public:
if (ok) *ok = true;
}
if (vfam.isString()) {
- retn.setFamily(vfam.toQString());
+ retn.setFamily(vfam.toQStringNoThrow());
if (ok) *ok = true;
}
if (vital.isBoolean()) {
@@ -394,15 +394,18 @@ public:
if (!array)
return QMatrix4x4();
+ QV4::Scope scope(array->engine());
+
if (array->arrayLength() != 16)
return QMatrix4x4();
float matVals[16];
+ QV4::ScopedValue v(scope);
for (quint32 i = 0; i < 16; ++i) {
- QV4::Value v = array->getIndexed(i);
- if (!v.isNumber())
+ v = array->getIndexed(i);
+ if (!v->isNumber())
return QMatrix4x4();
- matVals[i] = v.asDouble();
+ matVals[i] = v->asDouble();
}
if (ok) *ok = true;
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index 1a9be7c82a..77062605c0 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -331,7 +331,7 @@ public:
qreal value() const;
void setValue(qreal value);
-signals:
+Q_SIGNALS:
void valueChanged();
private:
diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp
index f1d7e19dc2..4667a5856c 100644
--- a/src/quick/util/qquicktimeline.cpp
+++ b/src/quick/util/qquicktimeline.cpp
@@ -51,6 +51,8 @@
#include <QTime>
#include <QtNumeric>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
struct Update {
@@ -808,7 +810,7 @@ int QQuickTimeLinePrivate::advance(int t)
length -= qMin(length, advanceTime);
syncPoint -= advanceTime;
- qSort(updates.begin(), updates.end());
+ std::sort(updates.begin(), updates.end());
updateQueue = &updates;
for (int ii = 0; ii < updates.count(); ++ii) {
const Update &v = updates.at(ii).second;
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index b64fc073ba..09ab868367 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -1,14 +1,18 @@
TEMPLATE=subdirs
SUBDIRS=\
qml \
- quick \
headersclean \
- particles \
- qmltest \
qmldevtools \
cmake \
installed_cmake
+!mac {
+SUBDIRS += \
+ quick \
+ particles \
+ qmltest
+}
+
installed_cmake.depends = cmake
testcocoon: SUBDIRS -= headersclean
diff --git a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro
index 1cb792eff2..1f957c23ff 100644
--- a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro
+++ b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro
@@ -3,6 +3,8 @@ TARGET = tst_qquicktrailemitter
SOURCES += tst_qquicktrailemitter.cpp
macx:CONFIG -= app_bundle
+win32-msvc2012:CONFIG += insignificant_test # QTBUG-33421
+
include (../../shared/util.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro
index 2d9f2169e2..5d88b58377 100644
--- a/tests/auto/qml/debugger/debugger.pro
+++ b/tests/auto/qml/debugger/debugger.pro
@@ -3,8 +3,6 @@ TEMPLATE = subdirs
PUBLICTESTS += \
qqmlenginedebugservice \
# qqmldebugjs \
- qqmlinspector \
- qqmlprofilerservice \
qpacketprotocol \
# qv8profilerservice \
# qdebugmessageservice \
@@ -14,6 +12,12 @@ PRIVATETESTS += \
qqmldebugclient \
qqmldebugservice
+!mac {
+PUBLICTESTS += \
+ qqmlinspector \
+ qqmlprofilerservice
+}
+
SUBDIRS += $$PUBLICTESTS
contains(QT_CONFIG, private_tests) {
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
index e6cbd41b8e..9318372e2c 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
+++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
@@ -48,6 +48,7 @@
#include <QtCore/QString>
#include <QtTest/QtTest>
+const char *ENABLE_DEBUG= "-enable-debugger";
const char *NORMALMODE = "-qmljsdebugger=port:3777,3787,block";
const char *QMLFILE = "test.qml";
@@ -179,10 +180,10 @@ void tst_QDebugMessageService::cleanupTestCase()
void tst_QDebugMessageService::init()
{
m_connection = new QQmlDebugConnection();
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", this);
m_client = new QQmlDebugMsgClient(m_connection);
- m_process->start(QStringList() << QLatin1String(NORMALMODE) << QQmlDataTest::instance()->testFile(QMLFILE));
+ m_process->start(QStringList() << QLatin1String(ENABLE_DEBUG) << QLatin1String(NORMALMODE) << QQmlDataTest::instance()->testFile(QMLFILE));
QVERIFY2(m_process->waitForSessionStart(),
"Could not launch application, or did not get 'Waiting for connection'.");
diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
index e5a7af630a..9bf2d8849e 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -129,6 +129,7 @@ const char *UNCAUGHT = "uncaught";
//const char *PAUSE = "pause";
//const char *RESUME = "resume";
+const char *ENABLE_DEBUG= "-enable-debugger";//flag needed for debugger with qml binary
const char *BLOCKMODE = "-qmljsdebugger=port:3771,3800,block";
const char *NORMALMODE = "-qmljsdebugger=port:3771,3800";
const char *TEST_QMLFILE = "test.qml";
@@ -1009,13 +1010,13 @@ void tst_QQmlDebugJS::cleanupTestCase()
bool tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode)
{
connection = new QQmlDebugConnection();
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", this);
client = new QJSDebugClient(connection);
if (blockMode)
- process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(qmlFile));
+ process->start(QStringList() << QLatin1String(ENABLE_DEBUG) << QLatin1String(BLOCKMODE) << testFile(qmlFile));
else
- process->start(QStringList() << QLatin1String(NORMALMODE) << testFile(qmlFile));
+ process->start(QStringList() << QLatin1String(ENABLE_DEBUG) << QLatin1String(NORMALMODE) << testFile(qmlFile));
if (!process->waitForSessionStart()) {
qDebug() << "could not launch application, or did not get 'Waiting for connection'.";
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
index 5badcaa3ae..231e37c6fb 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
@@ -107,9 +107,10 @@ void tst_QQmlEngineDebugInspectorIntegration::init()
{
const QString argument = "-qmljsdebugger=port:" STR_PORT_FROM "," STR_PORT_TO ",block";
+ // ### Still using qmlscene because of QTBUG-33376
m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ "/qmlscene", this);
- m_process->start(QStringList() << argument << testFile("qtquick2.qml"));
+ m_process->start(QStringList() << QLatin1String("-enable-debugger") << argument << testFile("qtquick2.qml"));
QVERIFY2(m_process->waitForSessionStart(),
"Could not launch application, or did not get 'Waiting for connection'.");
diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
index e430875355..2eeb4ce5b2 100644
--- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
+++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
@@ -89,8 +89,9 @@ void tst_QQmlInspector::startQmlsceneProcess(const char * /* qmlFile */)
{
const QString argument = "-qmljsdebugger=port:" STR_PORT_FROM "," STR_PORT_TO ",block";
+ // ### This should be using qml instead of qmlscene, but can't because of QTBUG-33376 (same as the XFAIL testcase)
m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
- m_process->start(QStringList() << argument << testFile("qtquick2.qml"));
+ m_process->start(QStringList() << QLatin1String("-enable-debugger") << argument << testFile("qtquick2.qml"));
QVERIFY2(m_process->waitForSessionStart(),
"Could not launch application, or did not get 'Waiting for connection'.");
@@ -179,7 +180,7 @@ void tst_QQmlInspector::reloadQmlWindow()
m_client->reloadQml(changesHash);
QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(responseReceived())));
- QEXPECT_FAIL("", "cannot debug with a QML file containing a top-level Window", Abort);
+ QEXPECT_FAIL("", "cannot debug with a QML file containing a top-level Window", Abort); // QTBUG-33376
QTRY_COMPARE(m_process->output().contains(
QString("version 2.0")), true);
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
index e4f886f7ce..4cf8fa64c5 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
@@ -198,8 +198,6 @@ void QQmlProfilerClient::messageReceived(const QByteArray &message)
stream >> data.time >> data.messageType;
- QVERIFY(data.time >= -1);
-
switch (data.messageType) {
case (QQmlProfilerClient::Event): {
stream >> data.detailType;
@@ -299,8 +297,10 @@ void QQmlProfilerClient::messageReceived(const QByteArray &message)
void tst_QQmlProfilerService::connect(bool block, const QString &testFile)
{
+ // ### Still using qmlscene due to QTBUG-33377
const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
QStringList arguments;
+ arguments << QLatin1String("-enable-debugger");
if (block)
arguments << QString("-qmljsdebugger=port:" STR_PORT_FROM "," STR_PORT_TO ",block");
diff --git a/tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp b/tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp
index f33ee55c46..f0485fb68a 100644
--- a/tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp
+++ b/tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp
@@ -204,8 +204,9 @@ void QV8ProfilerClient::messageReceived(const QByteArray &message)
bool tst_QV8ProfilerService::connect(bool block, const QString &testFile,
QString *error)
{
- const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
+ const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml";
QStringList arguments;
+ arguments << QLatin1String("-enable-debugger");
if (block)
arguments << QString("-qmljsdebugger=port:" STR_PORT_FROM "," STR_PORT_TO ",block");
diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp
index ab27337d41..99647cda11 100644
--- a/tests/auto/qml/debugger/shared/debugutil.cpp
+++ b/tests/auto/qml/debugger/shared/debugutil.cpp
@@ -43,6 +43,8 @@
#include <QEventLoop>
#include <QTimer>
+#include <QFileInfo>
+#include <QDir>
bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) {
QEventLoop loop;
@@ -123,6 +125,17 @@ QString QQmlDebugProcess::state()
void QQmlDebugProcess::start(const QStringList &arguments)
{
+#ifdef Q_OS_MAC
+ // make sure m_executable points to the actual binary even if it's inside an app bundle
+ QFileInfo binFile(m_executable);
+ if (!binFile.isExecutable()) {
+ QDir bundleDir(m_executable + ".app");
+ if (bundleDir.exists()) {
+ m_executable = bundleDir.absoluteFilePath("Contents/MacOS/" + binFile.baseName());
+ //qDebug() << Q_FUNC_INFO << "found bundled binary" << m_executable;
+ }
+ }
+#endif
m_mutex.lock();
m_port = 0;
m_process.setEnvironment(m_environment);
@@ -220,6 +233,9 @@ void QQmlDebugProcess::processAppOutput()
m_eventLoop.quit();
continue;
}
+ } else if (line.startsWith("qml:")) {
+ // ### Can't enable quiet mode because that also suppresses application output
+ continue; //We don't use these, but they aren't output from the app either
} else {
// set to true if there is output not coming from the debugger
outputFromAppItself = true;
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index ae9ac6602c..ecd1439177 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -452,6 +452,7 @@ void tst_QJSEngine::newQObject()
void tst_QJSEngine::newQObject_ownership()
{
+ QSKIP("unreliable test due to our conservative GC");
QJSEngine eng;
{
QPointer<QObject> ptr = new QObject();
@@ -1240,6 +1241,7 @@ void tst_QJSEngine::castWithMultipleInheritance()
void tst_QJSEngine::collectGarbage()
{
+ QSKIP("This test is not reliable due to our conservative GC");
QJSEngine eng;
eng.evaluate("a = new Object(); a = new Object(); a = new Object()");
QJSValue a = eng.newObject();
@@ -2607,34 +2609,38 @@ void tst_QJSEngine::dateRoundtripQtJSQt()
void tst_QJSEngine::dateConversionJSQt()
{
-#ifdef Q_OS_WIN
- QSKIP("This test fails on Windows due to a bug in QDateTime.");
-#endif
- uint secs = QDateTime(QDate(2009, 1, 1)).toUTC().toTime_t();
- QJSEngine eng;
- for (int i = 0; i < 8000; ++i) {
- QJSValue jsDate = eng.evaluate(QString::fromLatin1("new Date(%0)").arg(secs * 1000.0));
- QDateTime qtDate = jsDate.toDateTime();
- QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate);
- QString jsUTCDateStr = jsDate.property("toISOString").callWithInstance(jsDate).toString();
- if (qtUTCDateStr != jsUTCDateStr)
- QFAIL(qPrintable(jsDate.toString()));
- secs += 2*60*60;
- }
+ // Disable temporarily so that https://codereview.qt-project.org/#change,65560 can merge.
+//#ifdef Q_OS_WIN
+// QSKIP("This test fails on Windows due to a bug in QDateTime.");
+//#endif
+// uint secs = QDateTime(QDate(2009, 1, 1)).toUTC().toTime_t();
+// QJSEngine eng;
+// for (int i = 0; i < 8000; ++i) {
+// QJSValue jsDate = eng.evaluate(QString::fromLatin1("new Date(%0)").arg(secs * 1000.0));
+// QDateTime qtDate = jsDate.toDateTime();
+// QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate);
+// QString jsUTCDateStr = jsDate.property("toISOString").callWithInstance(jsDate).toString();
+// jsUTCDateStr.remove(jsUTCDateStr.length() - 5, 4); // get rid of milliseconds (".000")
+// if (qtUTCDateStr != jsUTCDateStr)
+// QFAIL(qPrintable(jsDate.toString()));
+// secs += 2*60*60;
+// }
}
void tst_QJSEngine::dateConversionQtJS()
{
- QDateTime qtDate = QDateTime(QDate(2009, 1, 1));
- QJSEngine eng;
- for (int i = 0; i < 8000; ++i) {
- QJSValue jsDate = eng.toScriptValue(qtDate);
- QString jsUTCDateStr = jsDate.property("toISOString").callWithInstance(jsDate).toString();
- QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate);
- if (jsUTCDateStr != qtUTCDateStr)
- QFAIL(qPrintable(qtDate.toString()));
- qtDate = qtDate.addSecs(2*60*60);
- }
+// Disable temporarily so that https://codereview.qt-project.org/#change,65560 can merge.
+// QDateTime qtDate = QDateTime(QDate(2009, 1, 1));
+// QJSEngine eng;
+// for (int i = 0; i < 8000; ++i) {
+// QJSValue jsDate = eng.toScriptValue(qtDate);
+// QString jsUTCDateStr = jsDate.property("toISOString").callWithInstance(jsDate).toString();
+// QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate);
+// jsUTCDateStr.remove(jsUTCDateStr.length() - 5, 4); // get rid of milliseconds (".000")
+// if (jsUTCDateStr != qtUTCDateStr)
+// QFAIL(qPrintable(qtDate.toString()));
+// qtDate = qtDate.addSecs(2*60*60);
+// }
}
void tst_QJSEngine::functionPrototypeExtensions()
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index 58132786a0..2036f1cd7a 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -56,7 +56,8 @@ PRIVATETESTS += \
qrcqml \
qqmltimer \
qqmlinstantiator \
- qv4debugger
+ qv4debugger \
+ qqmlenginecleanup
qtHaveModule(widgets) {
PUBLICTESTS += \
diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
index bf76c07970..634a6e5df1 100644
--- a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
+++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
@@ -48,6 +48,8 @@
#include <private/qqmldirparser_p.h>
#include <QDebug>
+#include <algorithm>
+
// Test the parsing of qmldir files
class tst_qqmldirparser : public QQmlDataTest
@@ -104,7 +106,7 @@ namespace {
foreach (const QQmlDirParser::Component &c, components.values())
rv.append(toString(c));
- qSort(rv);
+ std::sort(rv.begin(), rv.end());
return rv;
}
diff --git a/tests/auto/qml/qqmlecmascript/data/date.qml b/tests/auto/qml/qqmlecmascript/data/date.qml
new file mode 100644
index 0000000000..0dcba71ae3
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/date.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ MyDateClass {
+ id: mdc
+ }
+
+ function test_is_invalid_qtDateTime()
+ {
+ var dt = mdc.invalidDate();
+ return isNaN(dt);
+ }
+
+ function test_is_invalid_jsDateTime()
+ {
+ var dt = new Date("");
+ return isNaN(dt);
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
index 919e06d7ee..a09bd9f3c6 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
@@ -225,6 +225,16 @@ void MyWorkerObject::doIt()
new MyWorkerObjectThread(this);
}
+class MyDateClass : public QObject
+{
+ Q_OBJECT
+public:
+ Q_INVOKABLE QDateTime invalidDate()
+ {
+ return QDateTime();
+ }
+};
+
class MyStringClass : public QObject
{
Q_OBJECT
@@ -317,6 +327,7 @@ void registerTypes()
qmlRegisterType<FallbackBindingsTypeObject>("Qt.test.fallbackBindingsObject", 1, 0, "FallbackBindingsType");
qmlRegisterType<FallbackBindingsTypeDerived>("Qt.test.fallbackBindingsDerived", 1, 0, "FallbackBindingsType");
+ qmlRegisterType<MyDateClass>("Qt.test", 1, 0, "MyDateClass");
qmlRegisterType<MyStringClass>("Qt.test", 1, 0, "MyStringClass");
qmlRegisterSingletonType<testImportOrderApi>("Qt.test.importOrderApi",1,0,"Data",testImportOrder_api);
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 99659fb1eb..837b73dfa9 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -209,6 +209,7 @@ private slots:
void assignSequenceTypes();
void sequenceSort_data();
void sequenceSort();
+ void dateParse();
void qtbug_22464();
void qtbug_21580();
void singleV8BindingDestroyedDuringEvaluation();
@@ -310,6 +311,18 @@ private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
static void verifyContextLifetime(QQmlContextData *ctxt);
QQmlEngine engine;
+
+ // When calling into JavaScript, the specific type of the return value can differ if that return
+ // value is a number. This is not only the case for non-integral numbers, or numbers that do not
+ // fit into the (signed) integer range, but it also depends on which optimizations are run. So,
+ // to check if the return value is of a number type, use this method instead of checking against
+ // a specific userType.
+ static bool isJSNumberType(int userType)
+ {
+ return userType == (int) QVariant::Int
+ || userType == (int) QVariant::UInt
+ || userType == (int) QVariant::Double;
+ }
};
// The JavaScriptCore GC marks the C stack. To try to ensure that there is
@@ -2256,12 +2269,13 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const
program.inheritContext = true;
QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
+ QV4::Scope scope(ctx);
try {
- QV4::FunctionObject *function = program.run().asFunctionObject();
+ QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
if (!function)
return false;
- QV4::ScopedCallData d(ctx->engine, 1);
+ QV4::ScopedCallData d(scope, 1);
d->args[0] = o;
d->thisObject = engine->global();
function->call(d);
@@ -2282,14 +2296,16 @@ static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o,
program.inheritContext = true;
QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
+ QV4::Scope scope(ctx);
+
try {
- QV4::FunctionObject *function = program.run().asFunctionObject();
+ QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
if (!function)
return false;
- QV4::ValueScope scope(ctx);
+
QV4::ScopedValue value(scope);
QV4::ScopedValue res(scope, result);
- QV4::ScopedCallData d(ctx->engine, 1);
+ QV4::ScopedCallData d(scope, 1);
d->args[0] = o;
d->thisObject = engine->global();
value = function->call(d);
@@ -2307,16 +2323,18 @@ static inline QV4::Value evaluate(QV8Engine *engine, const QV4::Value & o,
QLatin1String(source) + QLatin1String(" })");
QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
+ QV4::Scope scope(ctx);
+
QV4::Script program(QV8Engine::getV4(engine)->rootContext, functionSource);
program.inheritContext = true;
try {
- QV4::FunctionObject *function = program.run().asFunctionObject();
+ QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
if (!function)
return QV4::Value::emptyValue();
- QV4::ScopedCallData d(ctx->engine, 1);
+ QV4::ScopedCallData d(scope, 1);
d->args[0] = o;
d->thisObject = engine->global();
- QV4::Value value = function->call(d);
+ QV4::ScopedValue value(scope, function->call(d));
return value;
} catch (QV4::Exception &e) {
e.accept(ctx);
@@ -2338,8 +2356,9 @@ void tst_qqmlecmascript::callQtInvokables()
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&qmlengine);
QV8Engine *engine = ep->v8engine();
+ QV4::Scope scope(QV8Engine::getV4(engine));
- QV4::Value object = QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), o);
+ QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), o));
// Non-existent methods
o->reset();
@@ -2433,7 +2452,7 @@ void tst_qqmlecmascript::callQtInvokables()
{
QV4::Value ret = EVALUATE("object.method_NoArgs_QScriptValue()");
QVERIFY(ret.isString());
- QCOMPARE(ret.toQString(), QString("Hello world"));
+ QCOMPARE(ret.toQStringNoThrow(), QString("Hello world"));
QCOMPARE(o->error(), false);
QCOMPARE(o->invoked(), 6);
QCOMPARE(o->actuals().count(), 0);
@@ -3885,7 +3904,8 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) {
scriptContext = QV4::QmlContextWrapper::getContext(qmlglobal);
{
- QV4::Value temporaryScope = QV4::QmlContextWrapper::qmlScope(engine, scriptContext, 0);
+ QV4::Scope scope(QV8Engine::getV4((engine)));
+ QV4::ScopedValue temporaryScope(scope, QV4::QmlContextWrapper::qmlScope(engine, scriptContext, 0));
Q_UNUSED(temporaryScope)
}
@@ -4687,8 +4707,8 @@ void tst_qqmlecmascript::propertyVarCpp()
QVERIFY(object->setProperty("varProperty", QVariant::fromValue(10)));
QCOMPARE(object->property("varBound"), QVariant(15));
QCOMPARE(object->property("intBound"), QVariant(15));
- QCOMPARE(object->property("varProperty").userType(), (int)QVariant::Int);
- QCOMPARE(object->property("varBound").userType(), (int)QVariant::Int);
+ QVERIFY(isJSNumberType(object->property("varProperty").userType()));
+ QVERIFY(isJSNumberType(object->property("varBound").userType()));
// assign string to property var that current has bool assigned
QCOMPARE(object->property("varProperty2").userType(), (int)QVariant::Bool);
QVERIFY(object->setProperty("varProperty2", QVariant(QLatin1String("randomString"))));
@@ -4967,9 +4987,9 @@ void tst_qqmlecmascript::propertyVarInheritance()
{
// XXX NOTE: this is very implementation dependent. QDVMEMO->vmeProperty() is the only
// public function which can return us a handle to something in the varProperties array.
- QV4::Value tmp = icovmemo->vmeProperty(ico5->metaObject()->indexOfProperty("circ"));
+ QV4::Value tmp = QV4::Value::fromReturnedValue(icovmemo->vmeProperty(ico5->metaObject()->indexOfProperty("circ")));
icoCanaryHandle = tmp;
- tmp = ccovmemo->vmeProperty(cco5->metaObject()->indexOfProperty("circ"));
+ tmp = QV4::Value::fromReturnedValue(ccovmemo->vmeProperty(cco5->metaObject()->indexOfProperty("circ")));
ccoCanaryHandle = tmp;
tmp = QV4::Value::nullValue();
QVERIFY(!icoCanaryHandle.isEmpty());
@@ -5013,7 +5033,7 @@ void tst_qqmlecmascript::propertyVarInheritance2()
QCOMPARE(childObject->property("textCanary").toInt(), 10);
QV4::WeakValue childObjectVarArrayValueHandle;
{
- QV4::Value tmp = QQmlVMEMetaObject::get(childObject)->vmeProperty(childObject->metaObject()->indexOfProperty("vp"));
+ QV4::Value tmp = QV4::Value::fromReturnedValue(QQmlVMEMetaObject::get(childObject)->vmeProperty(childObject->metaObject()->indexOfProperty("vp")));
childObjectVarArrayValueHandle = tmp;
tmp = QV4::Value::nullValue();
QVERIFY(!childObjectVarArrayValueHandle.isEmpty());
@@ -6621,7 +6641,7 @@ void tst_qqmlecmascript::qtbug_22843()
QQmlComponent component(&engine, testFileUrl(fileName));
QString url = component.url().toString();
QString warning1 = url.left(url.length()-3) + QLatin1String("js:4:16: Expected token `;'");
- QString warning2 = url + QLatin1String(":5: TypeError: Property 'func' of object NaN is not a function");
+ QString warning2 = url + QLatin1String(":5: TypeError: Cannot call method 'func' of undefined");
qRegisterMetaType<QList<QQmlError> >("QList<QQmlError>");
QSignalSpy warningsSpy(&engine, SIGNAL(warnings(QList<QQmlError>)));
@@ -7185,6 +7205,25 @@ void tst_qqmlecmascript::sequenceSort()
delete object;
}
+void tst_qqmlecmascript::dateParse()
+{
+ QQmlComponent component(&engine, testFileUrl("date.qml"));
+
+ QObject *object = component.create();
+ if (object == 0)
+ qDebug() << component.errorString();
+ QVERIFY(object != 0);
+
+ QVariant q;
+ QMetaObject::invokeMethod(object, "test_is_invalid_jsDateTime", Q_RETURN_ARG(QVariant, q));
+ QVERIFY(q.toBool() == true);
+
+ QMetaObject::invokeMethod(object, "test_is_invalid_qtDateTime", Q_RETURN_ARG(QVariant, q));
+ QVERIFY(q.toBool() == true);
+
+
+}
+
void tst_qqmlecmascript::concatenatedStringPropertyAccess()
{
QQmlComponent component(&engine, testFileUrl("concatenatedStringPropertyAccess.qml"));
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index 4d06665cb3..42e17d5624 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -54,7 +54,7 @@
#include <QQmlExpression>
#include <QQmlIncubationController>
#include <private/qqmlengine_p.h>
-#include <private/qqmlabstracturlinterceptor_p.h>
+#include <QQmlAbstractUrlInterceptor>
class tst_qqmlengine : public QQmlDataTest
{
diff --git a/tests/auto/qml/qqmlenginecleanup/data/TestType.qml b/tests/auto/qml/qqmlenginecleanup/data/TestType.qml
new file mode 100644
index 0000000000..a667c11327
--- /dev/null
+++ b/tests/auto/qml/qqmlenginecleanup/data/TestType.qml
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the autotests 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQml 2.0
+QtObject{property int notJustAStandardQtObject: 10 }
diff --git a/tests/auto/qml/qqmlenginecleanup/data/types.qml b/tests/auto/qml/qqmlenginecleanup/data/types.qml
new file mode 100644
index 0000000000..c8613a270d
--- /dev/null
+++ b/tests/auto/qml/qqmlenginecleanup/data/types.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the autotests 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQml 2.0
+import QtQuick 2.0
+import QtQuick.Window 2.0
+import QtQuick.Particles 2.0
+import Test 2.0
+import "."
+
+QtObject {
+ //Doesn't create items, just checks that the types are accessible
+ property TestType tt
+ property TestTypeCpp ttc
+ property ParticleSystem ps
+ property Window wi
+ property Item it
+}
diff --git a/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro b/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro
new file mode 100644
index 0000000000..6428933233
--- /dev/null
+++ b/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro
@@ -0,0 +1,10 @@
+CONFIG += testcase
+TARGET = tst_qqmlenginecleanup
+macx:CONFIG -= app_bundle
+
+include (../../shared/util.pri)
+
+SOURCES += tst_qqmlenginecleanup.cpp
+
+QT += testlib qml
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
new file mode 100644
index 0000000000..e5bfbd0ec8
--- /dev/null
+++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../../shared/util.h"
+#include <QtCore/QObject>
+#include <QtQml/qqml.h>
+#include <QtQml/QQmlEngine>
+#include <QtQml/QQmlComponent>
+
+//Separate test, because if engine cleanup attempts fail they can easily break unrelated tests
+class tst_qqmlenginecleanup : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_qqmlenginecleanup() {}
+
+private slots:
+ void test_qmlClearTypeRegistrations();
+};
+
+void tst_qqmlenginecleanup::test_qmlClearTypeRegistrations()
+{
+ //Test for preventing memory leaks is in tests/manual/qmltypememory
+ QQmlEngine* engine;
+ QQmlComponent* component;
+ QUrl testFile = testFileUrl("types.qml");
+
+ qmlRegisterType<QObject>("Test", 2, 0, "TestTypeCpp");
+ engine = new QQmlEngine;
+ component = new QQmlComponent(engine, testFile);
+ QVERIFY(component->isReady());
+
+ delete engine;
+ delete component;
+ qmlClearTypeRegistrations();
+
+ //2nd run verifies that types can reload after a qmlClearTypeRegistrations
+ qmlRegisterType<QObject>("Test", 2, 0, "TestTypeCpp");
+ engine = new QQmlEngine;
+ component = new QQmlComponent(engine, testFile);
+ QVERIFY(component->isReady());
+
+ delete engine;
+ delete component;
+ qmlClearTypeRegistrations();
+
+ //3nd run verifies that TestTypeCpp is no longer registered
+ engine = new QQmlEngine;
+ component = new QQmlComponent(engine, testFile);
+ QVERIFY(component->isError());
+ QCOMPARE(component->errorString(),
+ testFile.toString() +":46 module \"Test\" is not installed\n");
+
+ delete engine;
+ delete component;
+}
+
+QTEST_MAIN(tst_qqmlenginecleanup)
+
+#include "tst_qqmlenginecleanup.moc"
diff --git a/tests/auto/qml/qqmlfileselector/data/+basic/basicTest.qml b/tests/auto/qml/qqmlfileselector/data/+basic/basicTest.qml
new file mode 100644
index 0000000000..6c07e2d020
--- /dev/null
+++ b/tests/auto/qml/qqmlfileselector/data/+basic/basicTest.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ property string value: "selected"
+}
diff --git a/tests/auto/qml/qqmlfileselector/data/basicTest.qml b/tests/auto/qml/qqmlfileselector/data/basicTest.qml
new file mode 100644
index 0000000000..b7f24e81d0
--- /dev/null
+++ b/tests/auto/qml/qqmlfileselector/data/basicTest.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ property string value: "default"
+}
diff --git a/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro b/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro
new file mode 100644
index 0000000000..3475fa4b1d
--- /dev/null
+++ b/tests/auto/qml/qqmlfileselector/qqmlfileselector.pro
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qqmlfileselector
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qqmlfileselector.cpp
+
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+CONFIG += parallel_test
+QT += core-private gui-private qml-private testlib
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp b/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp
new file mode 100644
index 0000000000..a583fd0c4c
--- /dev/null
+++ b/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QQmlEngine>
+#include <QQmlComponent>
+#include <QQmlFileSelector>
+#include <QFileSelector>
+#include <QQmlContext>
+#include <qqmlinfo.h>
+#include "../../shared/util.h"
+
+class tst_qqmlfileselector : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_qqmlfileselector() {}
+
+private slots:
+ void basicTest();
+
+};
+
+void tst_qqmlfileselector::basicTest()
+{
+ QQmlEngine engine;
+ QFileSelector selector;
+ selector.setExtraSelectors(QStringList() << "basic");
+ QQmlFileSelector qmlSelector;
+ qmlSelector.setSelector(&selector);
+ engine.setUrlInterceptor(&qmlSelector);
+
+ QQmlComponent component(&engine, testFileUrl("basicTest.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("value").toString(), QString("selected"));
+
+ delete object;
+}
+
+QTEST_MAIN(tst_qqmlfileselector)
+
+#include "tst_qqmlfileselector.moc"
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index acb623989a..dae19dee57 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -659,8 +659,8 @@ void tst_qqmllanguage::assignLiteralToVariant()
QObject *object = component.create();
QVERIFY(object != 0);
- QCOMPARE(object->property("test1").userType(), (int)QVariant::Int);
- QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
+ QVERIFY(isJSNumberType(object->property("test1").userType()));
+ QVERIFY(isJSNumberType(object->property("test2").userType()));
QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
QCOMPARE(object->property("test4").userType(), (int)QVariant::Color);
QCOMPARE(object->property("test5").userType(), (int)QVariant::RectF);
@@ -698,7 +698,7 @@ void tst_qqmllanguage::assignLiteralToVar()
QObject *object = component.create();
QVERIFY(object != 0);
- QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
+ QVERIFY(isJSNumberType(object->property("test1").userType()));
QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
@@ -714,8 +714,8 @@ void tst_qqmllanguage::assignLiteralToVar()
QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
- QCOMPARE(object->property("variantTest1Bound").userType(), (int)QMetaType::Int);
- QCOMPARE(object->property("test1Bound").userType(), (int)QMetaType::Int);
+ QVERIFY(isJSNumberType(object->property("variantTest1Bound").userType()));
+ QVERIFY(isJSNumberType(object->property("test1Bound").userType()));
QCOMPARE(object->property("test1"), QVariant(5));
QCOMPARE(object->property("test2"), QVariant((double)1.7));
@@ -837,8 +837,8 @@ void tst_qqmllanguage::bindJSValueToVar()
QObject *object = root->findChild<QObject *>("varProperties");
- QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
- QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
+ QVERIFY(isJSNumberType(object->property("test1").userType()));
+ QVERIFY(isJSNumberType(object->property("test2").userType()));
QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
@@ -886,8 +886,8 @@ void tst_qqmllanguage::bindJSValueToVariant()
QObject *object = root->findChild<QObject *>("variantProperties");
- QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
- QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
+ QVERIFY(isJSNumberType(object->property("test1").userType()));
+ QVERIFY(isJSNumberType(object->property("test2").userType()));
QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
diff --git a/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp
new file mode 100644
index 0000000000..c960a69a9e
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QDebug>
+
+class MyPluginType : public QObject
+{
+ Q_OBJECT
+public:
+ MyPluginType(QObject *parent=0) : QObject(parent) {}
+};
+
+
+class MyPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ MyPlugin() {}
+
+ void registerTypes(const char *uri)
+ {
+ // Because the module is protected, this plugin should never be loaded
+ Q_UNUSED(uri);
+ Q_ASSERT(0);
+ }
+};
+
+#include "plugin.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro b/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro
new file mode 100644
index 0000000000..749a440ca8
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/protectedModule/protectedModule.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+CONFIG += plugin
+SOURCES = plugin.cpp
+QT = core qml
+DESTDIR = ../imports/org/qtproject/ProtectedModule
+
+QT += core-private gui-private qml-private
+
+IMPORT_FILES = \
+ qmldir
+
+include (../../../shared/imports.pri)
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qqmlmoduleplugin/protectedModule/qmldir b/tests/auto/qml/qqmlmoduleplugin/protectedModule/qmldir
new file mode 100644
index 0000000000..8d121bb17b
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/protectedModule/qmldir
@@ -0,0 +1 @@
+plugin protectedModule
diff --git a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
index 4806d34699..54acabe8eb 100644
--- a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
@@ -15,7 +15,8 @@ SUBDIRS =\
preemptiveModule\
preemptedStrictModule\
invalidNamespaceModule\
- invalidFirstCommandModule
+ invalidFirstCommandModule\
+ protectedModule
tst_qqmlmoduleplugin_pro.depends += plugin
SUBDIRS += tst_qqmlmoduleplugin.pro
diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
index ab8ff0e1a4..4379a90d47 100644
--- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
@@ -80,6 +80,7 @@ private slots:
void importLocalModule_data();
void importStrictModule();
void importStrictModule_data();
+ void importProtectedModule();
private:
QString m_importsDirectory;
@@ -542,6 +543,26 @@ void tst_qqmlmoduleplugin::importStrictModule_data()
<< ":1:1: module identifier directive must be the first directive in a qmldir file";
}
+void tst_qqmlmoduleplugin::importProtectedModule()
+{
+ //TODO: More than basic test (test errors,test inverse works...)
+ qmlRegisterType<QObject>("org.qtproject.ProtectedModule", 1, 0, "TestType");
+ qmlProtectModule("org.qtproject.ProtectedModule", 1);
+
+ QQmlEngine engine;
+ engine.addImportPath(m_importsDirectory);
+
+ QUrl url(testFileUrl("empty.qml"));
+
+ QString qml = "import org.qtproject.ProtectedModule 1.0\n TestType {}\n";
+ QQmlComponent component(&engine);
+ component.setData(qml.toUtf8(), url);
+ //If plugin is loaded due to import, should assert
+ QScopedPointer<QObject> object(component.create());
+ //qDebug() << component.errorString();
+ QVERIFY(object != 0);
+}
+
QTEST_MAIN(tst_qqmlmoduleplugin)
#include "tst_qqmlmoduleplugin.moc"
diff --git a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
index 9da67c3f43..bce236f9e2 100644
--- a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp
@@ -77,7 +77,7 @@ public:
QV4::ExecutionEngine *v4Engine() { return QV8Engine::getV4(this); }
- typedef QV4::Value (*InjectedFunction)(QV4::SimpleCallContext*);
+ typedef QV4::ReturnedValue (*InjectedFunction)(QV4::SimpleCallContext*);
Q_INVOKABLE void injectFunction(const QString &functionName, TestEngine::InjectedFunction injectedFunction)
{
@@ -261,10 +261,10 @@ void tst_qv4debugger::addBreakPointWhilePaused()
QCOMPARE(state.lineNumber, 2);
}
-static QV4::Value someCall(QV4::SimpleCallContext *ctx)
+static QV4::ReturnedValue someCall(QV4::SimpleCallContext *ctx)
{
ctx->engine->debugger->removeBreakPoint("removeBreakPointForNextInstruction", 2);
- return QV4::Value::undefinedValue();
+ return QV4::Encode::undefined();
}
void tst_qv4debugger::removeBreakPointForNextInstruction()
diff --git a/tests/auto/quick/nokeywords/nokeywords.pro b/tests/auto/quick/nokeywords/nokeywords.pro
new file mode 100644
index 0000000000..51fd490cb7
--- /dev/null
+++ b/tests/auto/quick/nokeywords/nokeywords.pro
@@ -0,0 +1,10 @@
+CONFIG += testcase
+TARGET = tst_nokeywords
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_nokeywords.cpp
+
+CONFIG+=parallel_test
+
+QT += quick core-private gui-private qml-private quick-private testlib
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/quick/nokeywords/tst_nokeywords.cpp b/tests/auto/quick/nokeywords/tst_nokeywords.cpp
new file mode 100644
index 0000000000..7146b1483a
--- /dev/null
+++ b/tests/auto/quick/nokeywords/tst_nokeywords.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define QT_NO_KEYWORDS
+#undef signals
+#undef slots
+#undef emit
+#define signals FooBar
+#define slots Baz
+#define emit Yoyodyne
+
+#include <QtQuick/QtQuick>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickflickable_p.h>
+#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickitemview_p.h>
+#include <QtQuick/private/qquicklistview_p.h>
+#include <QtQuick/private/qquickpainteditem_p.h>
+#include <QtQuick/private/qquickshadereffect_p.h>
+#include <QtQuick/private/qquickshadereffectsource_p.h>
+#include <QtQuick/private/qquickview_p.h>
+#include <QtQuick/private/qquickwindow_p.h>
+#include <QtQuick/private/qsgadaptationlayer_p.h>
+#include <QtQuick/private/qsgcontext_p.h>
+#include <QtQuick/private/qsgcontextplugin_p.h>
+#include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h>
+#include <QtQuick/private/qsgdefaultglyphnode_p.h>
+#include <QtQuick/private/qsgdefaultimagenode_p.h>
+#include <QtQuick/private/qsgdefaultrectanglenode_p.h>
+#include <QtQuick/private/qsgdepthstencilbuffer_p.h>
+#include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
+#include <QtQuick/private/qsgdistancefieldutil_p.h>
+#include <QtQuick/private/qsgflashnode_p.h>
+#include <QtQuick/private/qsggeometry_p.h>
+#include <QtQuick/private/qsgnode_p.h>
+#include <QtQuick/private/qsgnodeupdater_p.h>
+#include <QtQuick/private/qsgpainternode_p.h>
+#include <QtQuick/private/qsgrenderer_p.h>
+#include <QtQuick/private/qsgrenderloop_p.h>
+#include <QtQuick/private/qsgrendernode_p.h>
+#include <QtQuick/private/qsgshareddistancefieldglyphcache_p.h>
+#include <QtQuick/private/qsgtexturematerial_p.h>
+#include <QtQuick/private/qsgtexture_p.h>
+#include <QtQuick/private/qsgthreadedrenderloop_p.h>
+#include <QtQuick/private/qsgwindowsrenderloop_p.h>
+
+#undef signals
+#undef slots
+#undef emit
+
+class MyBooooooostishClass : public QObject
+{
+ Q_OBJECT
+public:
+ inline MyBooooooostishClass() {}
+
+Q_SIGNALS:
+ void mySignal();
+
+public Q_SLOTS:
+ inline void mySlot() { mySignal(); }
+
+private:
+ int signals;
+ double slots;
+};
+
+#define signals public
+#define slots
+#define emit
+#undef QT_NO_KEYWORDS
+
+#include <QtTest/QtTest>
+
+class tst_NoKeywords : public QObject
+{
+ Q_OBJECT
+};
+
+QTEST_MAIN(tst_NoKeywords)
+
+#include "tst_nokeywords.moc"
diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
index b8986fbf85..ef27445920 100644
--- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
+++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
@@ -46,6 +46,8 @@
#include <QtQuick/qquickview.h>
#include <QtGui/qinputmethod.h>
#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformintegration.h>
+#include <private/qguiapplication_p.h>
class tst_qquickapplication : public QObject
{
@@ -55,6 +57,7 @@ public:
private slots:
void active();
+ void state();
void layoutDirection();
void inputMethod();
@@ -103,6 +106,69 @@ void tst_qquickapplication::active()
QVERIFY(!item->property("active2").toBool());
}
+void tst_qquickapplication::state()
+{
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0; "
+ "Item { "
+ " property int state: Qt.application.state; "
+ " property int state2: Qt.ApplicationInactive; "
+ " Connections { "
+ " target: Qt.application; "
+ " onStateChanged: state2 = Qt.application.state; "
+ " } "
+ "}", QUrl::fromLocalFile(""));
+ QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
+ QVERIFY(item);
+ QQuickWindow window;
+ item->setParentItem(window.contentItem());
+
+ // initial state should be ApplicationInactive
+ QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationInactive);
+ QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationInactive);
+
+ // If the platform plugin has the ApplicationState capability, state changes originate from it
+ // as a result of a system event. We therefore have to simulate these events here.
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {
+
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
+ QTest::waitForEvents();
+ QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationActive);
+ QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationActive);
+
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
+ QTest::waitForEvents();
+ QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationInactive);
+ QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationInactive);
+
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
+ QTest::waitForEvents();
+ QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationSuspended);
+ QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationSuspended);
+
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationHidden);
+ QTest::waitForEvents();
+ QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationHidden);
+ QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationHidden);
+
+ } else {
+ // Otherwise, the application can only be in two states, Active and Inactive. These are
+ // triggered by window activation.
+ window.show();
+ window.requestActivate();
+ QTest::qWaitForWindowActive(&window);
+ QVERIFY(QGuiApplication::focusWindow() == &window);
+ QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationActive);
+ QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationActive);
+
+ // not active again
+ QWindowSystemInterface::handleWindowActivated(0);
+ QTRY_VERIFY(QGuiApplication::focusWindow() != &window);
+ QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationInactive);
+ QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationInactive);
+ }
+}
+
void tst_qquickapplication::layoutDirection()
{
diff --git a/tests/auto/quick/qquickflickable/data/nestedmousearea.qml b/tests/auto/quick/qquickflickable/data/nestedmousearea.qml
new file mode 100644
index 0000000000..f8f1e59244
--- /dev/null
+++ b/tests/auto/quick/qquickflickable/data/nestedmousearea.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+
+Flickable {
+ id: outer
+ objectName: "flickable"
+ width: 400
+ height: 400
+ contentX: 50
+ contentY: 50
+ contentWidth: 500
+ contentHeight: 500
+
+ Rectangle {
+ objectName: "nested"
+ x: 100
+ y: 100
+ width: 300
+ height: 300
+
+ color: "yellow"
+ MouseArea {
+ anchors.fill: parent
+ drag.target: parent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
index 4f103bd1fa..0923ba73a2 100644
--- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
+++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
@@ -133,6 +133,7 @@ tst_QQuickItemLayer::tst_QQuickItemLayer()
void tst_QQuickItemLayer::layerSmooth()
{
+ QSKIP("Rendering seems to have changed, still investigating - QTBUG-33517");
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
QImage fb = runTest("Smooth.qml");
@@ -168,6 +169,7 @@ void tst_QQuickItemLayer::layerEnabled()
void tst_QQuickItemLayer::layerMipmap()
{
+ QSKIP("Rendering seems to have changed, still investigating - QTBUG-33517");
if (m_isMesaSoftwareRasterizer)
QSKIP("Mipmapping does not work with the Mesa Software Rasterizer.");
QImage fb = runTest("Mipmap.qml");
@@ -407,6 +409,7 @@ void tst_QQuickItemLayer::changeSamplerName()
void tst_QQuickItemLayer::itemEffect()
{
+ QSKIP("Rendering seems to have changed, still investigating - QTBUG-33517");
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
QImage fb = runTest("ItemEffect.qml");
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index de1c12097b..0c0b51d9c2 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -86,6 +86,7 @@ private slots:
void resetDrag();
void dragging_data() { acceptedButton_data(); }
void dragging();
+ void dragThreshold();
void invalidDrag_data() { rejectedButton_data(); }
void invalidDrag();
void setDragOnPressed();
@@ -235,6 +236,20 @@ void tst_QQuickMouseArea::dragProperties()
drag->setFilterChildren(true);
QCOMPARE(filterChildrenSpy.count(), 1);
+
+ // threshold
+ QCOMPARE(int(drag->threshold()), qApp->styleHints()->startDragDistance());
+ QSignalSpy thresholdSpy(drag, SIGNAL(thresholdChanged()));
+ drag->setThreshold(0.0);
+ QCOMPARE(drag->threshold(), 0.0);
+ QCOMPARE(thresholdSpy.count(), 1);
+ drag->setThreshold(99);
+ QCOMPARE(thresholdSpy.count(), 2);
+ drag->setThreshold(99);
+ QCOMPARE(thresholdSpy.count(), 2);
+ drag->resetThreshold();
+ QCOMPARE(int(drag->threshold()), qApp->styleHints()->startDragDistance());
+ QCOMPARE(thresholdSpy.count(), 3);
}
void tst_QQuickMouseArea::resetDrag()
@@ -318,6 +333,61 @@ void tst_QQuickMouseArea::dragging()
QCOMPARE(blackRect->y(), 61.0);
}
+
+void tst_QQuickMouseArea::dragThreshold()
+{
+ QQuickView window;
+ QByteArray errorMessage;
+ QVERIFY2(initView(window, testFileUrl("dragging.qml"), true, &errorMessage), errorMessage.constData());
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QVERIFY(window.rootObject() != 0);
+
+ QQuickMouseArea *mouseRegion = window.rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+ QQuickDrag *drag = mouseRegion->drag();
+
+ drag->setThreshold(5);
+
+ mouseRegion->setAcceptedButtons(Qt::LeftButton);
+ QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect");
+ QVERIFY(blackRect != 0);
+ QVERIFY(blackRect == drag->target());
+ QVERIFY(!drag->active());
+ QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ QVERIFY(!drag->active());
+ QCOMPARE(blackRect->x(), 50.0);
+ QCOMPARE(blackRect->y(), 50.0);
+ QTest::mouseMove(&window, QPoint(100, 102), 50);
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 100), 50);
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 104), 50);
+ QTest::mouseMove(&window, QPoint(100, 105), 50);
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 106), 50);
+ QTest::mouseMove(&window, QPoint(100, 108), 50);
+ QVERIFY(drag->active());
+ QTest::mouseMove(&window, QPoint(100, 116), 50);
+ QTest::mouseMove(&window, QPoint(100, 122), 50);
+ QTRY_VERIFY(drag->active());
+ QTRY_COMPARE(blackRect->x(), 50.0);
+ QTRY_COMPARE(blackRect->y(), 66.0);
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(122,122));
+ QTRY_VERIFY(!drag->active());
+
+ // Immediate drag threshold
+ drag->setThreshold(0);
+ QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::mouseMove(&window, QPoint(100, 122), 50);
+ QVERIFY(!drag->active());
+ QTest::mouseMove(&window, QPoint(100, 123), 50);
+ QVERIFY(drag->active());
+ QTest::mouseMove(&window, QPoint(100, 124), 50);
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(100, 124));
+ QTRY_VERIFY(!drag->active());
+ drag->resetThreshold();
+}
void tst_QQuickMouseArea::invalidDrag()
{
QFETCH(Qt::MouseButtons, acceptedButtons);
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index 663d02d921..2bddac4ef3 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -45,6 +45,7 @@
#include <private/qquickflickable_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtQuick/qquickview.h>
+#include <QtGui/QScreen>
#include "../../shared/util.h"
class tst_QQuickMultiPointTouchArea : public QQmlDataTest
@@ -82,7 +83,7 @@ private:
void tst_QQuickMultiPointTouchArea::properties()
{
- QQuickView *window = createAndShowView("properties.qml");
+ QScopedPointer<QQuickView> window(createAndShowView("properties.qml"));
QVERIFY(window->rootObject() != 0);
QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(window->rootObject());
@@ -93,13 +94,11 @@ void tst_QQuickMultiPointTouchArea::properties()
QQmlListReference ref(area, "touchPoints");
QCOMPARE(ref.count(), 4);
-
- delete window;
}
void tst_QQuickMultiPointTouchArea::signalTest()
{
- QQuickView *window = createAndShowView("signalTest.qml");
+ QScopedPointer<QQuickView> window(createAndShowView("signalTest.qml"));
QVERIFY(window->rootObject() != 0);
QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(window->rootObject());
@@ -111,7 +110,7 @@ void tst_QQuickMultiPointTouchArea::signalTest()
QPoint p4(80,100);
QPoint p5(100,100);
- QTest::QTouchEventSequence sequence = QTest::touchEvent(window, device);
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).press(1, p2).commit();
@@ -157,13 +156,11 @@ void tst_QQuickMultiPointTouchArea::signalTest()
QCOMPARE(area->property("touchCount").toInt(), 0);
QCOMPARE(area->property("touchUpdatedHandled").toBool(), true);
QMetaObject::invokeMethod(area, "clearCounts");
-
- delete window;
}
void tst_QQuickMultiPointTouchArea::release()
{
- QQuickView *window = createAndShowView("basic.qml");
+ QScopedPointer<QQuickView> window(createAndShowView("basic.qml"));
QVERIFY(window->rootObject() != 0);
QQuickTouchPoint *point1 = window->rootObject()->findChild<QQuickTouchPoint*>("point1");
@@ -172,7 +169,7 @@ void tst_QQuickMultiPointTouchArea::release()
QPoint p1(20,100);
- QTest::QTouchEventSequence sequence = QTest::touchEvent(window, device);
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).commit();
@@ -192,13 +189,11 @@ void tst_QQuickMultiPointTouchArea::release()
//test that a release without a prior move to the release position successfully updates the point's position
QCOMPARE(point1->pressed(), false);
QCOMPARE(point1->x(), qreal(24)); QCOMPARE(point1->y(), qreal(120));
-
- delete window;
}
void tst_QQuickMultiPointTouchArea::reuse()
{
- QQuickView *window = createAndShowView("basic.qml");
+ QScopedPointer<QQuickView> window(createAndShowView("basic.qml"));
QVERIFY(window->rootObject() != 0);
QQuickTouchPoint *point1 = window->rootObject()->findChild<QQuickTouchPoint*>("point1");
@@ -213,7 +208,7 @@ void tst_QQuickMultiPointTouchArea::reuse()
QPoint p3(60,100);
QPoint p4(80,100);
- QTest::QTouchEventSequence sequence = QTest::touchEvent(window, device);
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).press(1, p2).commit();
@@ -255,13 +250,11 @@ void tst_QQuickMultiPointTouchArea::reuse()
QCOMPARE(point3->pressed(), false);
QCOMPARE(point1->x(), qreal(80)); QCOMPARE(point1->y(), qreal(100));
-
- delete window;
}
void tst_QQuickMultiPointTouchArea::nonOverlapping()
{
- QQuickView *window = createAndShowView("nonOverlapping.qml");
+ QScopedPointer<QQuickView> window(createAndShowView("nonOverlapping.qml"));
QVERIFY(window->rootObject() != 0);
QQuickTouchPoint *point11 = window->rootObject()->findChild<QQuickTouchPoint*>("point11");
@@ -282,7 +275,7 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
QPoint p4(80,180);
QPoint p5(100,180);
- QTest::QTouchEventSequence sequence = QTest::touchEvent(window, device);
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).commit();
@@ -364,13 +357,11 @@ void tst_QQuickMultiPointTouchArea::nonOverlapping()
QCOMPARE(point21->pressed(), false);
QCOMPARE(point22->pressed(), false);
QCOMPARE(point23->pressed(), false);
-
- delete window;
}
void tst_QQuickMultiPointTouchArea::nested()
{
- QQuickView *window = createAndShowView("nested.qml");
+ QScopedPointer<QQuickView> window(createAndShowView("nested.qml"));
QVERIFY(window->rootObject() != 0);
QQuickTouchPoint *point11 = window->rootObject()->findChild<QQuickTouchPoint*>("point11");
@@ -389,7 +380,7 @@ void tst_QQuickMultiPointTouchArea::nested()
QPoint p2(40,100);
QPoint p3(60,180);
- QTest::QTouchEventSequence sequence = QTest::touchEvent(window, device);
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).commit();
@@ -549,13 +540,11 @@ void tst_QQuickMultiPointTouchArea::nested()
QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
sequence.release(0, p1).release(1, p2).release(2, p3).commit();
-
- delete window;
}
void tst_QQuickMultiPointTouchArea::inFlickable()
{
- QQuickView *window = createAndShowView("inFlickable.qml");
+ QScopedPointer<QQuickView> window(createAndShowView("inFlickable.qml"));
QVERIFY(window->rootObject() != 0);
QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(window->rootObject());
@@ -571,33 +560,33 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
QPoint p2(40,100);
//moving one point vertically
- QTest::touchEvent(window, device).press(0, p1);
+ QTest::touchEvent(window.data(), device).press(0, p1);
p1 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
p1 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
p1 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
p1 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
QVERIFY(flickable->contentY() < 0);
QCOMPARE(point11->pressed(), false);
QCOMPARE(point12->pressed(), false);
- QTest::touchEvent(window, device).release(0, p1);
+ QTest::touchEvent(window.data(), device).release(0, p1);
QTest::qWait(50);
QTRY_VERIFY(!flickable->isMoving());
//moving two points vertically
p1 = QPoint(20,100);
- QTest::touchEvent(window, device).press(0, p1).press(1, p2);
- QTest::mousePress(window, Qt::LeftButton, 0, p1);
+ QTest::touchEvent(window.data(), device).press(0, p1).press(1, p2);
+ QTest::mousePress(window.data(), Qt::LeftButton, 0, p1);
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
@@ -605,20 +594,20 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
QCOMPARE(flickable->property("touchCount").toInt(), 2);
p1 += QPoint(0,15); p2 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(0,15); p2 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(0,15); p2 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(0,15); p2 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
QVERIFY(flickable->contentY() < 0);
QCOMPARE(point11->pressed(), false);
@@ -626,8 +615,8 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
QCOMPARE(flickable->property("cancelCount").toInt(), 2);
QCOMPARE(flickable->property("touchCount").toInt(), 0);
- QTest::touchEvent(window, device).release(0, p1).release(1, p2);
- QTest::mouseRelease(window,Qt::LeftButton, 0, p1);
+ QTest::touchEvent(window.data(), device).release(0, p1).release(1, p2);
+ QTest::mouseRelease(window.data(), Qt::LeftButton, 0, p1);
QTest::qWait(50);
QTRY_VERIFY(!flickable->isMoving());
@@ -635,59 +624,57 @@ void tst_QQuickMultiPointTouchArea::inFlickable()
//moving two points horizontally, then one point vertically
p1 = QPoint(20,100);
p2 = QPoint(40,100);
- QTest::touchEvent(window, device).press(0, p1).press(1, p2);
- QTest::mousePress(window, Qt::LeftButton, 0, p1);
+ QTest::touchEvent(window.data(), device).press(0, p1).press(1, p2);
+ QTest::mousePress(window.data(), Qt::LeftButton, 0, p1);
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
p1 += QPoint(15,0); p2 += QPoint(15,0);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(15,0); p2 += QPoint(15,0);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(15,0); p2 += QPoint(15,0);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(15,0); p2 += QPoint(15,0);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(0,15); p2 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(0,15); p2 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(0,15); p2 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(0,15); p2 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1).move(1, p2);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1).move(1, p2);
+ QTest::mouseMove(window.data(), p1);
QVERIFY(flickable->contentY() == 0);
QCOMPARE(point11->pressed(), true);
QCOMPARE(point12->pressed(), true);
- QTest::touchEvent(window, device).release(0, p1).release(1, p2);
- QTest::mouseRelease(window,Qt::LeftButton, 0, p1);
+ QTest::touchEvent(window.data(), device).release(0, p1).release(1, p2);
+ QTest::mouseRelease(window.data(), Qt::LeftButton, 0, p1);
QTest::qWait(50);
-
- delete window;
}
// test that dragging out of a Flickable containing a MPTA doesn't harm Flickable's state.
void tst_QQuickMultiPointTouchArea::inFlickable2()
{
- QQuickView *window = createAndShowView("inFlickable2.qml");
+ QScopedPointer<QQuickView> window(createAndShowView("inFlickable2.qml"));
QVERIFY(window->rootObject() != 0);
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>("flickable");
@@ -701,69 +688,66 @@ void tst_QQuickMultiPointTouchArea::inFlickable2()
QPoint p1(50,100);
// move point horizontally, out of Flickable area
- QTest::touchEvent(window, device).press(0, p1);
- QTest::mousePress(window, Qt::LeftButton, 0, p1);
+ QTest::touchEvent(window.data(), device).press(0, p1);
+ QTest::mousePress(window.data(), Qt::LeftButton, 0, p1);
p1 += QPoint(15,0);
- QTest::touchEvent(window, device).move(0, p1);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(15,0);
- QTest::touchEvent(window, device).move(0, p1);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(15,0);
- QTest::touchEvent(window, device).move(0, p1);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
+ QTest::mouseMove(window.data(), p1);
p1 += QPoint(15,0);
- QTest::touchEvent(window, device).move(0, p1);
- QTest::mouseMove(window, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
+ QTest::mouseMove(window.data(), p1);
QVERIFY(!flickable->isMoving());
QVERIFY(point11->pressed());
- QTest::touchEvent(window, device).release(0, p1);
- QTest::mouseRelease(window,Qt::LeftButton, 0, p1);
+ QTest::touchEvent(window.data(), device).release(0, p1);
+ QTest::mouseRelease(window.data(), Qt::LeftButton, 0, p1);
QTest::qWait(50);
QTRY_VERIFY(!flickable->isMoving());
// Check that we can still move the Flickable
p1 = QPoint(50,100);
- QTest::touchEvent(window, device).press(0, p1);
+ QTest::touchEvent(window.data(), device).press(0, p1);
QCOMPARE(point11->pressed(), true);
p1 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
p1 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
p1 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
p1 += QPoint(0,15);
- QTest::touchEvent(window, device).move(0, p1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
QVERIFY(flickable->contentY() < 0);
QVERIFY(flickable->isMoving());
QCOMPARE(point11->pressed(), true);
- QTest::touchEvent(window, device).release(0, p1);
+ QTest::touchEvent(window.data(), device).release(0, p1);
QTest::qWait(50);
QTRY_VERIFY(!flickable->isMoving());
-
-
- delete window;
}
// QTBUG-23327
void tst_QQuickMultiPointTouchArea::invisible()
{
- QQuickView *window = createAndShowView("signalTest.qml");
+ QScopedPointer<QQuickView> window(createAndShowView("signalTest.qml"));
QVERIFY(window->rootObject() != 0);
QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(window->rootObject());
@@ -774,7 +758,7 @@ void tst_QQuickMultiPointTouchArea::invisible()
QPoint p1(20,100);
QPoint p2(40,100);
- QTest::QTouchEventSequence sequence = QTest::touchEvent(window, device);
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
sequence.press(0, p1).press(1, p2).commit();
@@ -782,8 +766,6 @@ void tst_QQuickMultiPointTouchArea::invisible()
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
QCOMPARE(area->property("touchCount").toInt(), 0);
-
- delete window;
}
void tst_QQuickMultiPointTouchArea::transformedTouchArea_data()
@@ -826,13 +808,14 @@ void tst_QQuickMultiPointTouchArea::transformedTouchArea()
QFETCH(int, total2);
QFETCH(int, total3);
- QQuickView *view = createAndShowView("transformedMultiPointTouchArea.qml");
+
+ QScopedPointer<QQuickView> view(createAndShowView("transformedMultiPointTouchArea.qml"));
QVERIFY(view->rootObject() != 0);
QQuickMultiPointTouchArea *area = view->rootObject()->findChild<QQuickMultiPointTouchArea *>("touchArea");
QVERIFY(area != 0);
- QTest::QTouchEventSequence sequence = QTest::touchEvent(view, device);
+ QTest::QTouchEventSequence sequence = QTest::touchEvent(view.data(), device);
sequence.press(0, p1).commit();
QCOMPARE(area->property("pointCount").toInt(), total1);
@@ -842,14 +825,16 @@ void tst_QQuickMultiPointTouchArea::transformedTouchArea()
sequence.stationary(0).stationary(1).press(2, p3).commit();
QCOMPARE(area->property("pointCount").toInt(), total3);
-
- delete view;
}
QQuickView *tst_QQuickMultiPointTouchArea::createAndShowView(const QString &file)
{
QQuickView *window = new QQuickView(0);
window->setSource(testFileUrl(file));
+ const QRect screenGeometry = window->screen()->availableGeometry();
+ const QSize size = window->size();
+ const QPoint offset = QPoint(size.width() / 2, size.height() / 2);
+ window->setFramePosition(screenGeometry.center() - offset);
window->show();
QTest::qWaitForWindowExposed(window);
diff --git a/tests/auto/quick/qquicktextinput/data/maxLength.qml b/tests/auto/quick/qquicktextinput/data/maxLength.qml
index cca537ed6b..aaa5887f26 100644
--- a/tests/auto/quick/qquicktextinput/data/maxLength.qml
+++ b/tests/auto/quick/qquicktextinput/data/maxLength.qml
@@ -1,6 +1,8 @@
import QtQuick 2.0
TextInput{
+ width: 160
+ height: 100
focus: true
objectName: "myInput"
maximumLength: 10
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 55f91db603..a11f4399e8 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -948,6 +948,9 @@ void tst_qquickwindow::grab()
{
QFETCH(bool, visible);
+ if (!visible)
+ QSKIP("Blocking CI - QTBUG-33516");
+
QQuickWindow window;
window.setColor(Qt::red);
diff --git a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
index 1f7a8029dc..12ae3c273f 100644
--- a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
+++ b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
@@ -58,6 +58,8 @@
#include <QtQml/qqmlcomponent.h>
#include "../../../../src/imports/xmllistmodel/qqmlxmllistmodel_p.h"
+#include <algorithm>
+
typedef QPair<int, int> QQuickXmlListRange;
typedef QList<QVariantList> QQmlXmlModelData;
@@ -608,7 +610,7 @@ void tst_qquickxmllistmodel::useKeys()
}
QList<int> roles = model->roleNames().keys();
- qSort(roles);
+ std::sort(roles.begin(), roles.end());
for (int i=0; i<model->rowCount(); i++) {
QModelIndex index = model->index(i, 0);
for (int j=0; j<roles.count(); j++)
@@ -759,7 +761,7 @@ void tst_qquickxmllistmodel::noKeysValueChanges()
model->setProperty("xml",xml);
QList<int> roles = model->roleNames().keys();
- qSort(roles);
+ std::sort(roles.begin(), roles.end());
// wait for the new xml data to be set, and verify no signals were emitted
QTRY_VERIFY(model->data(model->index(0, 0), roles.at(2)).toString() != QLatin1String("Football"));
QCOMPARE(model->data(model->index(0, 0), roles.at(2)).toString(), QLatin1String("AussieRules"));
@@ -860,21 +862,21 @@ void tst_qquickxmllistmodel::threading()
for (int i=0; i<dataCount; i++) {
QModelIndex index = m1->index(i, 0);
QList<int> roles = m1->roleNames().keys();
- qSort(roles);
+ std::sort(roles.begin(), roles.end());
QCOMPARE(m1->data(index, roles.at(0)).toString(), QString("A" + QString::number(i)));
QCOMPARE(m1->data(index, roles.at(1)).toString(), QString("1" + QString::number(i)));
QCOMPARE(m1->data(index, roles.at(2)).toString(), QString("Football"));
index = m2->index(i, 0);
roles = m2->roleNames().keys();
- qSort(roles);
+ std::sort(roles.begin(), roles.end());
QCOMPARE(m2->data(index, roles.at(0)).toString(), QString("B" + QString::number(i)));
QCOMPARE(m2->data(index, roles.at(1)).toString(), QString("2" + QString::number(i)));
QCOMPARE(m2->data(index, roles.at(2)).toString(), QString("Athletics"));
index = m3->index(i, 0);
roles = m3->roleNames().keys();
- qSort(roles);
+ std::sort(roles.begin(), roles.end());
QCOMPARE(m3->data(index, roles.at(0)).toString(), QString("C" + QString::number(i)));
QCOMPARE(m3->data(index, roles.at(1)).toString(), QString("3" + QString::number(i)));
QCOMPARE(m3->data(index, roles.at(2)).toString(), QString("Curling"));
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 81d4fd3348..f8c19bae63 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -13,6 +13,7 @@ qtHaveModule(widgets): PUBLICTESTS += nodes
!qtHaveModule(concurrent): PUBLICTESTS -= qquickpixmapcache
PRIVATETESTS += \
+ nokeywords \
qquickanimations \
qquickapplication \
qquickbehaviors \
diff --git a/tests/manual/qmltypememory/main.qml b/tests/manual/qmltypememory/main.qml
index 7bc9006aec..fa78381601 100644
--- a/tests/manual/qmltypememory/main.qml
+++ b/tests/manual/qmltypememory/main.qml
@@ -51,4 +51,5 @@ QtObject {
property TestType tt //No object, although it should be properly parented if there were one
property TestTypeCpp tt2 //No object, although it should be properly parented if there were one
property TestTypePlugin tt3
+ property Item it
}
diff --git a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
index 74845ab954..cb0f44a03e 100644
--- a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
+++ b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
@@ -47,6 +47,7 @@
#include <QtCore/QProcess>
#include <QtGui/QImage>
+#include <algorithm>
QString blockify(const QByteArray& s)
{
@@ -167,7 +168,7 @@ void tst_Scenegraph::setupTestSuite(const QByteArray& filter)
}
}
- qSort(itemFiles);
+ std::sort(itemFiles.begin(), itemFiles.end());
foreach (const QString &filePath, itemFiles) {
QByteArray itemName = filePath.mid(testSuitePath.length() + 1).toLatin1();
QBaselineTest::newRow(itemName, checksumFileOrDir(filePath)) << filePath;
diff --git a/tools/qml/Info.plist b/tools/qml/Info.plist
new file mode 100644
index 0000000000..42d074a3af
--- /dev/null
+++ b/tools/qml/Info.plist
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.1">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>@ICON@</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.qt-project.qml</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleSignature</key>
+ <string>@TYPEINFO@</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+ <key>UTExportedTypeDeclarations</key>
+ <array>
+ <dict>
+ <key>UTTypeIdentifier</key>
+ <string>org.qt-project.qml</string>
+ <key>UTTypeDescription</key>
+ <string>Qt Markup Language</string>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.plain-text</string>
+ </array>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>qml</string>
+ </array>
+ </dict>
+ </dict>
+ </array>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>org.qt-project.qml</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/tools/qml/conf.h b/tools/qml/conf.h
new file mode 100644
index 0000000000..24ea44edb9
--- /dev/null
+++ b/tools/qml/conf.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the tools applications 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CONF_H
+#define CONF_H
+
+#include <QtQml>
+#include <QObject>
+#include <QUrl>
+
+class PartialScene : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl container READ container WRITE setContainer NOTIFY containerChanged)
+ Q_PROPERTY(QString itemType READ itemType WRITE setItemType NOTIFY itemTypeChanged)
+public:
+ PartialScene(QObject *parent = 0) : QObject(parent)
+ {}
+
+ const QUrl container() const { return m_container; }
+ const QString itemType() const { return m_itemType; }
+
+ void setContainer(const QUrl &a) {
+ if (a==m_container)
+ return;
+ m_container = a;
+ emit containerChanged();
+ }
+ void setItemType(const QString &a) {
+ if (a==m_itemType)
+ return;
+ m_itemType = a;
+ emit itemTypeChanged();
+ }
+
+signals:
+ void containerChanged();
+ void itemTypeChanged();
+
+private:
+ QUrl m_container;
+ QString m_itemType;
+};
+
+class Config : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<PartialScene> sceneCompleters READ sceneCompleters)
+ Q_CLASSINFO("DefaultProperty", "sceneCompleters")
+public:
+ Config (QObject* parent=0) : QObject(parent)
+ {}
+
+ QQmlListProperty<PartialScene> sceneCompleters()
+ {
+ return QQmlListProperty<PartialScene>(this, completers);
+ }
+
+ QList<PartialScene*> completers;
+};
+
+#endif
diff --git a/tools/qml/conf/configuration.qml b/tools/qml/conf/configuration.qml
new file mode 100644
index 0000000000..4a9494e8b5
--- /dev/null
+++ b/tools/qml/conf/configuration.qml
@@ -0,0 +1,47 @@
+/*****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick module 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 Digia Plc and its Subsidiary(-ies) 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 QmlRuntime.Config 1.0
+
+Configuration {
+ PartialScene {
+ itemType: "QQuickItem"
+ container: "qtquick.qml"
+ }
+}
diff --git a/tools/qml/conf/qtquick.qml b/tools/qml/conf/qtquick.qml
new file mode 100644
index 0000000000..3da5c09d41
--- /dev/null
+++ b/tools/qml/conf/qtquick.qml
@@ -0,0 +1,55 @@
+/*****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQuick module 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 Digia Plc and its Subsidiary(-ies) 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.Window 2.0
+import QtQuick 2.0
+
+Window {
+ property Item containedObject: null
+ onContainedObjectChanged: {
+ if (containedObject == undefined || containedObject == null) {
+ visible = false;
+ return;
+ }
+ width = containedObject.width;
+ height = containedObject.height;
+ containedObject.parent = contentItem;
+ visible = true;
+ }
+}
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
new file mode 100644
index 0000000000..c059373143
--- /dev/null
+++ b/tools/qml/main.cpp
@@ -0,0 +1,466 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the tools applications 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "conf.h"
+
+#include <QCoreApplication>
+#include <QGuiApplication>
+#ifdef QT_WIDGETS_LIB
+#include <QApplication>
+#endif
+#include <QWindow>
+#include <QQmlApplicationEngine>
+#include <QFileOpenEvent>
+#include <QFile>
+#include <QFileInfo>
+#include <QRegularExpression>
+#include <QStringList>
+#include <QDebug>
+#include <QStandardPaths>
+#include <QtGlobal>
+#include <qqml.h>
+#include <qqmldebug.h>
+#include <private/qabstractanimation_p.h>
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+
+#define VERSION_MAJ 1
+#define VERSION_MIN 0
+#define VERSION_STR "1.0"
+
+static Config *conf = 0;
+static QQmlApplicationEngine *qae = 0;
+
+static void loadConf(const QString &override, bool quiet) // Terminates app on failure
+{
+ const QString defaultFileName = QLatin1String("configuration.qml");
+ QUrl settingsUrl;
+ bool builtIn = false; //just for keeping track of the warning
+ if (override.isEmpty()) {
+ QFileInfo fi;
+ fi.setFile(QStandardPaths::locate(QStandardPaths::DataLocation, defaultFileName));
+ if (fi.exists()) {
+ settingsUrl = QUrl::fromLocalFile(fi.absoluteFilePath());
+ } else {
+ // ### If different built-in configs are needed per-platform, just apply QFileSelector to the qrc conf.qml path
+ settingsUrl = QUrl(QLatin1String("qrc:///qt-project.org/QmlRuntime/conf/") + defaultFileName);
+ builtIn = true;
+ }
+ } else {
+ QFileInfo fi;
+ fi.setFile(override);
+ if (!fi.exists()) {
+ qCritical() << QObject::tr("qml: Couldn't find required configuration file:") << fi.absoluteFilePath();
+ exit(1);
+ }
+ settingsUrl = QUrl::fromLocalFile(fi.absoluteFilePath());
+ }
+
+ if (!quiet) {
+ if (builtIn)
+ qWarning() << QObject::tr("qml: Using built-in configuration.");
+ else
+ qWarning() << QObject::tr("qml: Using configuration file:") << settingsUrl;
+ }
+
+ // TODO: When we have better engine control, ban QtQuick* imports on this engine
+ QQmlEngine e2;
+ QQmlComponent c2(&e2, settingsUrl);
+ conf = qobject_cast<Config*>(c2.create());
+
+ if (!conf){
+ qCritical() << QObject::tr("qml: Error loading configuration file:") << c2.errorString();
+ exit(1);
+ }
+}
+
+void contain(QObject *o, const QUrl &containPath)
+{
+ QQmlComponent c(qae, containPath);
+ QObject *o2 = c.create();
+ if (!o2)
+ return;
+ bool success = false;
+ int idx;
+ if ((idx = o2->metaObject()->indexOfProperty("containedObject")) != -1)
+ success = o2->metaObject()->property(idx).write(o2, QVariant::fromValue<QObject*>(o));
+ if (!success)
+ o->setParent(o2); //Set QObject parent, and assume container will react as needed
+}
+
+// Loads qml after receiving a QFileOpenEvent
+class LoaderApplication : public QGuiApplication
+{
+public:
+ LoaderApplication(int& argc, char **argv) : QGuiApplication(argc, argv) {}
+
+ bool event(QEvent *ev)
+ {
+ if (ev->type() == QEvent::FileOpen)
+ qae->load(static_cast<QFileOpenEvent *>(ev)->url());
+ else
+ return QGuiApplication::event(ev);
+ return true;
+ }
+};
+
+// Listens to the appEngine signals to determine if all files failed to load
+class LoadWatcher : public QObject
+{
+ Q_OBJECT
+public:
+ LoadWatcher(QQmlApplicationEngine *e, int expected)
+ : QObject(e)
+ , expect(expected)
+ , haveOne(false)
+ {
+ connect(e, SIGNAL(objectCreated(QObject*,QUrl)),
+ this, SLOT(checkFinished(QObject*)));
+ }
+
+private:
+ int expect;
+ bool haveOne;
+
+public Q_SLOTS:
+ void checkFinished(QObject *o)
+ {
+ if (o) {
+ haveOne = true;
+ if (conf && qae)
+ foreach (PartialScene *ps, conf->completers)
+ if (o->inherits(ps->itemType().toUtf8().constData()))
+ contain(o, ps->container());
+ }
+ if (haveOne)
+ return;
+
+ if (! --expect) {
+ qCritical() << QObject::tr("qml: Did not load any objects, exiting.");
+ exit(2);//Different return code from qFatal
+ }
+ }
+};
+
+void quietMessageHandler(QtMsgType type, const QMessageLogContext &ctxt, const QString &msg)
+{
+ Q_UNUSED(ctxt);
+ Q_UNUSED(msg);
+ //Doesn't print anything
+ switch (type) {
+ case QtFatalMsg:
+ abort();
+ case QtCriticalMsg:
+ case QtDebugMsg:
+ case QtWarningMsg:
+ ;
+ }
+}
+
+
+// ### Should command line arguments have translations? Qt creator doesn't, so maybe it's not worth it.
+bool useCoreApp = false;
+bool useWidgetApp = false;
+bool quietMode = false;
+void printVersion()
+{
+ printf("qml binary version ");
+ printf(VERSION_STR);
+ printf("\nbuilt with Qt version ");
+ printf(QT_VERSION_STR);
+ printf("\n");
+ exit(0);
+}
+
+void printUsage()
+{
+ printf("Usage: qml [options] [files]\n");
+ printf("\n");
+ printf("Any argument ending in .qml will be treated as a QML file to be loaded.\n");
+ printf("Any number of QML files can be loaded. They will share the same engine.\n");
+ printf("Any argument which is not a recognized option and which does not end in .qml will be ignored.\n");
+ printf("'widget' application type is only available if the QtWidgets module is avaialble.\n");
+ printf("\n");
+ printf("General Options:\n");
+ printf("\t-h, -help..................... Print this usage information and exit.\n");
+ printf("\t-v, -version.................. Print the version information and exit.\n");
+ printf("\t-apptype [core|gui|widget] ... Select which application class to use. Default is gui.\n");
+ printf("\t-quiet ....................... Suppress all output.\n");
+ printf("\t-I [path] .................... Prepend the given path to the import paths.\n");
+ printf("\t-f [file] .................... Load the given file as a QML file.\n");
+ printf("\t-config [file] ............... Load the given file as the configuration file.\n");
+ printf("\t-- ........................... Arguments after this one are ignored by the launcher, but may be used within the QML application.\n");
+ printf("\tDebugging options:\n");
+ printf("\t-enable-debugger ............. Allow the QML debugger to connect to the application (also requires debugger arguments).\n");
+ printf("\t-translation [file] .......... Load the given file as the translations file.\n");
+ printf("\t-dummy-data [directory] ...... Load QML files from the given directory as context properties.\n");
+ printf("\t-slow-animations ............. Run all animations in slow motion.\n");
+ printf("\t-fixed-animations ............ Run animations off animation tick rather than wall time.\n");
+ exit(0);
+}
+
+//Called before application initialization, removes arguments it uses
+void getAppFlags(int &argc, char **argv)
+{
+ for (int i=0; i<argc; i++) {
+ if (!strcmp(argv[i], "-apptype")) { // Must be done before application, as it selects application
+ int type = 0;
+ if (i+1 < argc) {
+ if (!strcmp(argv[i+1], "core"))
+ type = 1;
+ else if (!strcmp(argv[i+1], "gui"))
+ type = 2;
+#ifdef QT_WIDGETS_LIB
+ else if (!strcmp(argv[i+1], "widget"))
+ type = 3;
+#endif
+ }
+
+ if (!type) {
+#ifdef QT_WIDGETS_LIB
+ printf("-apptype must be followed by one of the following: core gui widget\n");
+#else
+ printf("-apptype must be followed by one of the following: core gui\n");
+#endif
+ printUsage();
+ }
+
+ switch (type) {
+ case 1: useCoreApp = true; break;
+ case 2: useCoreApp = false; break;
+#ifdef QT_WIDGETS_LIB
+ case 3: useWidgetApp = true; break;
+#endif
+ }
+ for (int j=i; j<argc-2; j++)
+ argv[j] = argv[j+2];
+ argc -= 2;
+ } else if (!strcmp(argv[i], "-enable-debugger")) { // Normally done via a define in the include, so expects to be before application (and must be before engine)
+ static QQmlDebuggingEnabler qmlEnableDebuggingHelper(true);
+ for (int j=i; j<argc-1; j++)
+ argv[j] = argv[j+1];
+ argc --;
+ }
+ }
+}
+
+void getFileSansBangLine(const QString &path, QByteArray &output)
+{
+ QFile f(path);
+ if (!f.open(QFile::ReadOnly | QFile::Text))
+ return;
+ output = f.readAll();
+ if (output.startsWith("#!"))//Remove first line in this case (except \n, to avoid disturbing line count)
+ output.remove(0, output.indexOf('\n'));
+}
+
+static void loadDummyDataFiles(QQmlEngine &engine, const QString& directory)
+{
+ QDir dir(directory+"/dummydata", "*.qml");
+ QStringList list = dir.entryList();
+ for (int i = 0; i < list.size(); ++i) {
+ QString qml = list.at(i);
+ QFile f(dir.filePath(qml));
+ f.open(QIODevice::ReadOnly);
+ QByteArray data = f.readAll();
+ QQmlComponent comp(&engine);
+ comp.setData(data, QUrl());
+ QObject *dummyData = comp.create();
+
+ if (comp.isError()) {
+ QList<QQmlError> errors = comp.errors();
+ foreach (const QQmlError &error, errors)
+ qWarning() << error;
+ }
+
+ if (dummyData && !quietMode) {
+ qWarning() << QObject::tr("qml: Loaded dummy data:") << dir.filePath(qml);
+ qml.truncate(qml.length()-4);
+ engine.rootContext()->setContextProperty(qml, dummyData);
+ dummyData->setParent(&engine);
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ getAppFlags(argc, argv);
+ QCoreApplication *app;
+ if (useCoreApp)
+ app = new QCoreApplication(argc, argv);
+#ifdef QT_WIDGETS_LIB
+ else if (useWidgetApp)
+ app = new QApplication(argc, argv);
+#endif
+ else
+ app = new LoaderApplication(argc, argv);
+
+ app->setApplicationName("Qml Runtime");
+ app->setOrganizationName("Qt Project");
+ app->setOrganizationDomain("qt-project.org");
+
+ qmlRegisterType<Config>("QmlRuntime.Config", VERSION_MAJ, VERSION_MIN, "Configuration");
+ qmlRegisterType<PartialScene>("QmlRuntime.Config", VERSION_MAJ, VERSION_MIN, "PartialScene");
+ QQmlApplicationEngine e;
+ QStringList files;
+ QString confFile;
+ QString translationFile;
+ QString dummyDir;
+
+ //Handle main arguments
+ QStringList argList = app->arguments();
+ for (int i = 0; i < argList.count(); i++) {
+ const QString &arg = argList[i];
+ if (arg == QLatin1String("-quiet"))
+ quietMode = true;
+ else if (arg == QLatin1String("-v") || arg == QLatin1String("-version"))
+ printVersion();
+ else if (arg == QLatin1String("-h") || arg == QLatin1String("-help"))
+ printUsage();
+ else if (arg == QLatin1String("--"))
+ break;
+ else if (arg == QLatin1String("-slow-animations"))
+ QUnifiedTimer::instance()->setSlowModeEnabled(true);
+ else if (arg == QLatin1String("-fixed-animations"))
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+ else if (arg == QLatin1String("-I")) {
+ if (i+1 == argList.count())
+ continue;//Invalid usage, but just ignore it
+ e.addImportPath(argList[i+1]);
+ i++;
+ } else if (arg == QLatin1String("-f")) {
+ if (i+1 == argList.count())
+ continue;//Invalid usage, but just ignore it
+ files << argList[i+1];
+ i++;
+ } else if (arg == QLatin1String("-config")){
+ if (i+1 == argList.count())
+ continue;//Invalid usage, but just ignore it
+ confFile = argList[i+1];
+ i++;
+ } else if (arg == QLatin1String("-translation")){
+ if (i+1 == argList.count())
+ continue;//Invalid usage, but just ignore it
+ translationFile = argList[i+1];
+ i++;
+ } else if (arg == QLatin1String("-dummy-data")){
+ if (i+1 == argList.count())
+ continue;//Invalid usage, but just ignore it
+ dummyDir = argList[i+1];
+ i++;
+ } else {
+ //If it ends in .qml, treat it as a file. Else ignore it
+ if (arg.endsWith(".qml"))
+ files << arg;
+ }
+ }
+
+#ifndef QT_NO_TRANSLATION
+ //qt_ translations loaded by QQmlApplicationEngine
+ QTranslator qmlTranslator;
+ QString sysLocale = QLocale::system().name();
+ if (qmlTranslator.load(QLatin1String("qml_") + sysLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+ app->installTranslator(&qmlTranslator);
+
+ if (!translationFile.isEmpty()) { //Note: installed before QQmlApplicationEngine's automatic translation loading
+ QTranslator translator;
+
+ if (translator.load(translationFile)) {
+ app->installTranslator(&translator);
+ } else {
+ if (!quietMode)
+ qWarning() << "qml: Could not load the translation file" << translationFile;
+ }
+ }
+#else
+ if (!translationFile.isEmpty() && !quietMode)
+ qWarning() << "qml: Translation file specified, but Qt built without translation support.";
+#endif
+
+ if (quietMode)
+ qInstallMessageHandler(quietMessageHandler);
+
+ if (files.count() <= 0) {
+ if (!quietMode)
+ qCritical() << QObject::tr("qml: No files specified. Terminating.");
+ exit(1);
+ }
+
+ qae = &e;
+ loadConf(confFile, quietMode);
+
+ //Load files
+ LoadWatcher lw(&e, files.count());
+
+ foreach (const QString &path, files) {
+ //QUrl::fromUserInput doesn't treat no scheme as relative file paths
+ QRegularExpression urlRe("[[:word:]]+://.*");
+ if (urlRe.match(path).hasMatch()) { //Treat as a URL
+ QUrl url = QUrl::fromUserInput(path);
+ if (!quietMode)
+ qDebug() << QObject::tr("qml: loading ") << url;
+ e.load(url);
+ } else { //Local file path
+ if (!quietMode) {
+ qDebug() << QObject::tr("qml: loading ") << path;
+ QByteArray strippedFile;
+ getFileSansBangLine(path, strippedFile);
+ if (strippedFile.isEmpty())
+ // If there's an error opening the file, this will give us the right error message
+ e.load(path);
+ else
+ e.loadData(strippedFile, QUrl::fromLocalFile(path));
+ } else {
+ e.load(path);
+ }
+ }
+ }
+
+
+ if (!dummyDir.isEmpty() && QFileInfo (dummyDir).isDir())
+ loadDummyDataFiles(e, dummyDir);
+
+ return app->exec();
+}
+
+#include "main.moc"
diff --git a/tools/qml/qml.icns b/tools/qml/qml.icns
new file mode 100644
index 0000000000..c76051626a
--- /dev/null
+++ b/tools/qml/qml.icns
Binary files differ
diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro
new file mode 100644
index 0000000000..fd4021c340
--- /dev/null
+++ b/tools/qml/qml.pro
@@ -0,0 +1,14 @@
+QT += qml gui core-private
+qtHaveModule(widgets): QT += widgets
+
+HEADERS += conf.h
+SOURCES += main.cpp
+RESOURCES += qml.qrc
+
+mac {
+ OTHER_FILES += Info.plist
+ QMAKE_INFO_PLIST = Info.plist
+ ICON = qml.icns
+}
+
+load(qt_tool)
diff --git a/tools/qml/qml.qrc b/tools/qml/qml.qrc
new file mode 100644
index 0000000000..1f0ffdace2
--- /dev/null
+++ b/tools/qml/qml.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="qt-project.org/QmlRuntime">
+ <file>conf/configuration.qml</file>
+ <file>conf/qtquick.qml</file>
+ </qresource>
+</RCC>
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index 4337db1689..6939ce92e2 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -58,6 +58,7 @@
#include <QtCore/private/qmetaobject_p.h>
#include <iostream>
+#include <algorithm>
#include "qmlstreamwriter.h"
@@ -139,6 +140,9 @@ public:
*/
static QHash<QByteArray, QSet<const QQmlType *> > qmlTypesByCppName;
+// No different versioning possible for a composite type.
+static QMap<QString, const QQmlType * > qmlTypesByCompositeName;
+
static QHash<QByteArray, QByteArray> cppToId;
/* Takes a C++ type name, such as Qt::LayoutDirection or QString and
@@ -190,8 +194,9 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, const
if (ty->isExtendedType())
extensions[ty->typeName()].insert(ty->metaObject()->className());
collectReachableMetaObjects(ty, &metas);
+ } else {
+ qmlTypesByCompositeName[ty->elementName()] = ty;
}
- // TODO actually handle composite types
}
// Adjust exports of the base object if there are extensions.
@@ -249,7 +254,16 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, const
if (ty->isSingleton()) {
QQmlType::SingletonInstanceInfo *siinfo = ty->singletonInstanceInfo();
+ if (!siinfo) {
+ qWarning() << "Internal error, " << tyName
+ << "(" << QString::fromUtf8(ty->typeName()) << ")"
+ << " is singleton, but has no singletonInstanceInfo";
+ continue;
+ }
if (siinfo->qobjectCallback) {
+ if (verbose)
+ qDebug() << "Trying to get singleton for " << tyName
+ << " (" << siinfo->typeName << ")";
siinfo->init(engine);
collectReachableMetaObjects(object, &metas);
object = siinfo->qobjectApi(engine);
@@ -258,15 +272,22 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, const
continue; // we don't handle QJSValue singleton types.
}
} else {
+ if (verbose)
+ qDebug() << "Trying to create object " << tyName
+ << " (" << QString::fromUtf8(ty->typeName()) << ")";
object = ty->create();
}
inObjectInstantiation.clear();
- if (object)
+ if (object) {
+ if (verbose)
+ qDebug() << "Got " << tyName
+ << " (" << QString::fromUtf8(ty->typeName()) << ")";
collectReachableMetaObjects(object, &metas);
- else
+ } else {
qWarning() << "Could not create" << tyName;
+ }
}
}
@@ -287,6 +308,135 @@ public:
relocatableModuleUri = uri;
}
+ const QString getExportString(QString qmlTyName, int majorVersion, int minorVersion)
+ {
+ if (qmlTyName.startsWith(relocatableModuleUri + QLatin1Char('/'))) {
+ qmlTyName.remove(0, relocatableModuleUri.size() + 1);
+ }
+ if (qmlTyName.startsWith("./")) {
+ qmlTyName.remove(0, 2);
+ }
+ if (qmlTyName.startsWith("/")) {
+ qmlTyName.remove(0, 1);
+ }
+ const QString exportString = enquote(
+ QString("%1 %2.%3").arg(
+ qmlTyName,
+ QString::number(majorVersion),
+ QString::number(minorVersion)));
+ return exportString;
+ }
+
+ void writeMetaContent(const QMetaObject *meta)
+ {
+ QSet<QString> implicitSignals;
+ for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) {
+ const QMetaProperty &property = meta->property(index);
+ dump(property);
+ implicitSignals.insert(QString("%1Changed").arg(QString::fromUtf8(property.name())));
+ }
+
+ if (meta == &QObject::staticMetaObject) {
+ // for QObject, hide deleteLater() and onDestroyed
+ for (int index = meta->methodOffset(); index < meta->methodCount(); ++index) {
+ QMetaMethod method = meta->method(index);
+ QByteArray signature = method.methodSignature();
+ if (signature == QByteArrayLiteral("destroyed(QObject*)")
+ || signature == QByteArrayLiteral("destroyed()")
+ || signature == QByteArrayLiteral("deleteLater()"))
+ continue;
+ dump(method, implicitSignals);
+ }
+
+ // and add toString(), destroy() and destroy(int)
+ qml->writeStartObject(QLatin1String("Method"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("toString")));
+ qml->writeEndObject();
+ qml->writeStartObject(QLatin1String("Method"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
+ qml->writeEndObject();
+ qml->writeStartObject(QLatin1String("Method"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
+ qml->writeStartObject(QLatin1String("Parameter"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("delay")));
+ qml->writeScriptBinding(QLatin1String("type"), enquote(QLatin1String("int")));
+ qml->writeEndObject();
+ qml->writeEndObject();
+ } else {
+ for (int index = meta->methodOffset(); index < meta->methodCount(); ++index)
+ dump(meta->method(index), implicitSignals);
+ }
+ }
+
+ QString getPrototypeNameForCompositeType(const QMetaObject *metaObject, QSet<QByteArray> &defaultReachableNames)
+ {
+ QString prototypeName;
+ if (!defaultReachableNames.contains(metaObject->className())) {
+ const QMetaObject *superMetaObject = metaObject->superClass();
+ if (!superMetaObject)
+ prototypeName = "QObject";
+ else
+ prototypeName = getPrototypeNameForCompositeType(superMetaObject, defaultReachableNames);
+ } else {
+ prototypeName = convertToId(metaObject->className());
+ }
+ return prototypeName;
+ }
+
+ void dumpComposite(QQmlEngine *engine, const QQmlType *compositeType, QSet<QByteArray> &defaultReachableNames)
+ {
+ QQmlComponent e(engine, compositeType->sourceUrl());
+ QObject *object = e.create();
+
+ if (!object)
+ return;
+
+ qml->writeStartObject("Component");
+
+ const QMetaObject *mainMeta = object->metaObject();
+
+ // Get C++ base class name for the composite type
+ QString prototypeName = getPrototypeNameForCompositeType(mainMeta, defaultReachableNames);
+ qml->writeScriptBinding(QLatin1String("prototype"), enquote(prototypeName));
+
+ QString qmlTyName = compositeType->qmlTypeName();
+ // name should be unique
+ qml->writeScriptBinding(QLatin1String("name"), enquote(qmlTyName));
+ const QString exportString = getExportString(qmlTyName, compositeType->majorVersion(), compositeType->minorVersion());
+ qml->writeArrayBinding(QLatin1String("exports"), QStringList() << exportString);
+ qml->writeArrayBinding(QLatin1String("exportMetaObjectRevisions"), QStringList() << QString::number(compositeType->minorVersion()));
+
+ for (int index = mainMeta->classInfoCount() - 1 ; index >= 0 ; --index) {
+ QMetaClassInfo classInfo = mainMeta->classInfo(index);
+ if (QLatin1String(classInfo.name()) == QLatin1String("DefaultProperty")) {
+ qml->writeScriptBinding(QLatin1String("defaultProperty"), enquote(QLatin1String(classInfo.value())));
+ break;
+ }
+ }
+
+ QSet<const QMetaObject *> metas;
+ QSet<const QMetaObject *> candidatesComposite;
+ collectReachableMetaObjects(mainMeta, &candidatesComposite);
+
+ // Also eliminate meta objects with the same classname.
+ // This is required because extended objects seem not to share
+ // a single meta object instance.
+ foreach (const QMetaObject *mo, candidatesComposite) {
+ if (!defaultReachableNames.contains(mo->className()))
+ metas.insert(mo);
+ }
+
+ // put the metaobjects into a map so they are always dumped in the same order
+ QMap<QString, const QMetaObject *> nameToMeta;
+ foreach (const QMetaObject *meta, metas)
+ nameToMeta.insert(convertToId(meta), meta);
+
+ foreach (const QMetaObject *meta, nameToMeta)
+ writeMetaContent(meta);
+
+ qml->writeEndObject();
+ }
+
void dump(const QMetaObject *meta)
{
qml->writeStartObject("Component");
@@ -310,27 +460,13 @@ public:
QHash<QString, const QQmlType *> exports;
foreach (const QQmlType *qmlTy, qmlTypes) {
- QString qmlTyName = qmlTy->qmlTypeName();
- if (qmlTyName.startsWith(relocatableModuleUri + QLatin1Char('/'))) {
- qmlTyName.remove(0, relocatableModuleUri.size() + 1);
- }
- if (qmlTyName.startsWith("./")) {
- qmlTyName.remove(0, 2);
- }
- if (qmlTyName.startsWith("/")) {
- qmlTyName.remove(0, 1);
- }
- const QString exportString = enquote(
- QString("%1 %2.%3").arg(
- qmlTyName,
- QString::number(qmlTy->majorVersion()),
- QString::number(qmlTy->minorVersion())));
+ const QString exportString = getExportString(qmlTy->qmlTypeName(), qmlTy->majorVersion(), qmlTy->minorVersion());
exports.insert(exportString, qmlTy);
}
// ensure exports are sorted and don't change order when the plugin is dumped again
QStringList exportStrings = exports.keys();
- qSort(exportStrings);
+ std::sort(exportStrings.begin(), exportStrings.end());
qml->writeArrayBinding(QLatin1String("exports"), exportStrings);
// write meta object revisions
@@ -354,43 +490,7 @@ public:
for (int index = meta->enumeratorOffset(); index < meta->enumeratorCount(); ++index)
dump(meta->enumerator(index));
- QSet<QString> implicitSignals;
- for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) {
- const QMetaProperty &property = meta->property(index);
- dump(property);
- implicitSignals.insert(QString("%1Changed").arg(QString::fromUtf8(property.name())));
- }
-
- if (meta == &QObject::staticMetaObject) {
- // for QObject, hide deleteLater() and onDestroyed
- for (int index = meta->methodOffset(); index < meta->methodCount(); ++index) {
- QMetaMethod method = meta->method(index);
- QByteArray signature = method.methodSignature();
- if (signature == QByteArrayLiteral("destroyed(QObject*)")
- || signature == QByteArrayLiteral("destroyed()")
- || signature == QByteArrayLiteral("deleteLater()"))
- continue;
- dump(method, implicitSignals);
- }
-
- // and add toString(), destroy() and destroy(int)
- qml->writeStartObject(QLatin1String("Method"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("toString")));
- qml->writeEndObject();
- qml->writeStartObject(QLatin1String("Method"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
- qml->writeEndObject();
- qml->writeStartObject(QLatin1String("Method"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
- qml->writeStartObject(QLatin1String("Parameter"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("delay")));
- qml->writeScriptBinding(QLatin1String("type"), enquote(QLatin1String("int")));
- qml->writeEndObject();
- qml->writeEndObject();
- } else {
- for (int index = meta->methodOffset(); index < meta->methodCount(); ++index)
- dump(meta->method(index), implicitSignals);
- }
+ writeMetaContent(meta);
qml->writeEndObject();
}
@@ -461,7 +561,7 @@ private:
void dump(const QMetaMethod &meth, const QSet<QString> &implicitSignals)
{
if (meth.methodType() == QMetaMethod::Signal) {
- if (meth.access() != QMetaMethod::Protected)
+ if (meth.access() != QMetaMethod::Public)
return; // nothing to do.
} else if (meth.access() != QMetaMethod::Public) {
return; // nothing to do.
@@ -543,7 +643,7 @@ void sigSegvHandler(int) {
void printUsage(const QString &appName)
{
qWarning() << qPrintable(QString(
- "Usage: %1 [-v] [-noinstantiate] [-[non]relocatable] module.uri version [module/import/path]\n"
+ "Usage: %1 [-v] [-noinstantiate] [-defaultplatform] [-[non]relocatable] 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(
@@ -570,7 +670,17 @@ int main(int argc, char *argv[])
#endif
// don't require a window manager even though we're a QGuiApplication
- qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("minimal"));
+ bool requireWindowManager = false;
+ for (int index = 1; index < argc; ++index) {
+ if (QString::fromLocal8Bit(argv[index]) == "--defaultplatform"
+ || QString::fromLocal8Bit(argv[index]) == "-defaultplatform") {
+ requireWindowManager = true;
+ break;
+ }
+ }
+
+ if (!requireWindowManager)
+ qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("minimal"));
QGuiApplication app(argc, argv);
const QStringList args = app.arguments();
@@ -612,6 +722,9 @@ int main(int argc, char *argv[])
action = Builtins;
} else if (arg == QLatin1String("-v")) {
verbose = true;
+ } else if (arg == QLatin1String("--defaultplatform")
+ || arg == QLatin1String("-defaultplatform")) {
+ continue;
} else {
qWarning() << "Invalid argument: " << arg;
return EXIT_INVALIDARGUMENTS;
@@ -672,6 +785,7 @@ int main(int argc, char *argv[])
// add some otherwise unreachable QMetaObjects
defaultReachable.insert(&QQuickMouseEvent::staticMetaObject);
// QQuickKeyEvent, QQuickPinchEvent, QQuickDropEvent are not exported
+ QSet<QByteArray> defaultReachableNames;
// this will hold the meta objects we want to dump information of
QSet<const QMetaObject *> metas;
@@ -723,7 +837,6 @@ int main(int argc, char *argv[])
// Also eliminate meta objects with the same classname.
// This is required because extended objects seem not to share
// a single meta object instance.
- QSet<QByteArray> defaultReachableNames;
foreach (const QMetaObject *mo, defaultReachable)
defaultReachableNames.insert(QByteArray(mo->className()));
foreach (const QMetaObject *mo, candidates) {
@@ -746,8 +859,9 @@ int main(int argc, char *argv[])
"// This file describes the plugin-supplied types contained in the library.\n"
"// It is used for QML tooling purposes only.\n"
"//\n"
- "// This file was auto-generated with the command '%1'.\n"
- "\n").arg(args.join(QLatin1String(" "))));
+ "// This file was auto-generated by:\n"
+ "// '%1 %2'\n"
+ "\n").arg(QFileInfo(args.at(0)).fileName()).arg(QStringList(args.mid(1)).join(QLatin1String(" "))));
qml.writeStartObject("Module");
// put the metaobjects into a map so they are always dumped in the same order
@@ -761,6 +875,8 @@ int main(int argc, char *argv[])
foreach (const QMetaObject *meta, nameToMeta) {
dumper.dump(meta);
}
+ foreach (const QQmlType *compositeType, qmlTypesByCompositeName)
+ dumper.dumpComposite(&engine, compositeType, defaultReachableNames);
// define QEasingCurve as an extension of QQmlEasingValueType, this way
// properties using the QEasingCurve type get useful type information.
diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp
index 5d387d6234..038d2177f9 100644
--- a/tools/qmlprofiler/qmlprofilerdata.cpp
+++ b/tools/qmlprofiler/qmlprofilerdata.cpp
@@ -47,6 +47,8 @@
#include <QFile>
#include <QXmlStreamReader>
+#include <algorithm>
+
namespace Constants {
const char TYPE_PAINTING_STR[] = "Painting";
const char TYPE_COMPILING_STR[] = "Compiling";
@@ -437,9 +439,9 @@ void QmlProfilerData::sortStartTimes()
itFrom--;
if (itTo->startTime <= itFrom->startTime)
- qSort(itFrom, itTo + 1, compareStartTimes);
+ std::sort(itFrom, itTo + 1, compareStartTimes);
else
- qSort(itFrom + 1, itTo + 1, compareStartTimes);
+ std::sort(itFrom + 1, itTo + 1, compareStartTimes);
// move to next block
itTo = itFrom;
diff --git a/tools/qmlprofiler/qpacketprotocol.cpp b/tools/qmlprofiler/qpacketprotocol.cpp
index b0cb289c10..e0fe08740d 100644
--- a/tools/qmlprofiler/qpacketprotocol.cpp
+++ b/tools/qmlprofiler/qpacketprotocol.cpp
@@ -288,6 +288,7 @@ void QPacketProtocol::send(const QPacket & p)
d->sendingPackets.append(sendSize);
qint32 sendSize32 = sendSize;
qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32));
+ Q_UNUSED(writeBytes);
Q_ASSERT(writeBytes == sizeof(qint32));
writeBytes = d->dev->write(p.b);
Q_ASSERT(writeBytes == p.b.size());
diff --git a/tools/tools.pro b/tools/tools.pro
index 43b6c14022..ecca12d266 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -2,6 +2,7 @@ TEMPLATE = subdirs
qtHaveModule(quick): SUBDIRS += qmlscene qmlplugindump
qtHaveModule(qmltest): SUBDIRS += qmltestrunner
SUBDIRS += \
+ qml \
qmlmin \
qmlprofiler \
qmlbundle \
diff --git a/tools/v4/main.cpp b/tools/v4/main.cpp
index a49c7093cf..3404de2c30 100644
--- a/tools/v4/main.cpp
+++ b/tools/v4/main.cpp
@@ -77,16 +77,16 @@ struct Print: FunctionObject
name = scope->engine->newString("print");
}
- static Value call(Managed *, CallData *callData)
+ static ReturnedValue call(Managed *, CallData *callData)
{
for (int i = 0; i < callData->argc; ++i) {
- QString s = callData->args[i].toQString();
+ QString s = callData->args[i].toQStringNoThrow();
if (i)
std::cout << ' ';
std::cout << qPrintable(s);
}
std::cout << std::endl;
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
static const ManagedVTable static_vtbl;
@@ -102,10 +102,10 @@ struct GC: public FunctionObject
vtbl = &static_vtbl;
name = scope->engine->newString("gc");
}
- static Value call(Managed *m, CallData *)
+ static ReturnedValue call(Managed *m, CallData *)
{
m->engine()->memoryManager->runGC();
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
static const ManagedVTable static_vtbl;
@@ -117,11 +117,13 @@ DEFINE_MANAGED_VTABLE(GC);
static void showException(QV4::ExecutionContext *ctx, const QV4::Exception &exception)
{
- QV4::ErrorObject *e = exception.value().asErrorObject();
+ QV4::Scope scope(ctx);
+ QV4::ScopedValue ex(scope, exception.value());
+ QV4::ErrorObject *e = ex->asErrorObject();
if (!e) {
- std::cerr << "Uncaught exception: " << qPrintable(exception.value().toString(ctx)->toQString()) << std::endl;
+ std::cerr << "Uncaught exception: " << qPrintable(ex->toString(ctx)->toQString()) << std::endl;
} else {
- std::cerr << "Uncaught exception: " << qPrintable(e->get(ctx->engine->newString(QStringLiteral("message")), 0).toString(ctx)->toQString()) << std::endl;
+ std::cerr << "Uncaught exception: " << qPrintable(QV4::Value::fromReturnedValue(e->get(ctx->engine->newString(QStringLiteral("message")), 0)).toString(ctx)->toQString()) << std::endl;
}
foreach (const QV4::ExecutionEngine::StackFrame &frame, exception.stackTrace()) {
@@ -187,6 +189,7 @@ int main(int argc, char *argv[])
QV4::ExecutionEngine vm(iSelFactory);
QV4::ExecutionContext *ctx = vm.rootContext;
+ QV4::Scope scope(ctx);
QV4::Object *globalObject = vm.globalObject;
QV4::Object *print = new (ctx->engine->memoryManager) builtins::Print(ctx);
@@ -204,10 +207,10 @@ int main(int argc, char *argv[])
QV4::Script script(ctx, code, fn);
script.parseAsBinding = runAsQml;
script.parse();
- QV4::Value result = script.run();
- if (!result.isUndefined()) {
+ QV4::ScopedValue result(scope, script.run());
+ if (!result->isUndefined()) {
if (! qgetenv("SHOW_EXIT_VALUE").isEmpty())
- std::cout << "exit value: " << qPrintable(result.toString(ctx)->toQString()) << std::endl;
+ std::cout << "exit value: " << qPrintable(result->toString(ctx)->toQString()) << std::endl;
}
} catch (QV4::Exception& ex) {
ex.accept(ctx);