aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/double-conversion/README2
-rw-r--r--src/3rdparty/double-conversion/bignum-dtoa.cc11
-rw-r--r--src/3rdparty/double-conversion/bignum.cc24
-rw-r--r--src/3rdparty/double-conversion/cached-powers.cc1
-rw-r--r--src/3rdparty/double-conversion/double-conversion.cc194
-rw-r--r--src/3rdparty/double-conversion/double-conversion.h33
-rw-r--r--src/3rdparty/double-conversion/fast-dtoa.cc19
-rw-r--r--src/3rdparty/double-conversion/fixed-dtoa.cc14
-rw-r--r--src/3rdparty/double-conversion/ieee.h4
-rw-r--r--src/3rdparty/double-conversion/strtod.cc5
-rw-r--r--src/3rdparty/double-conversion/utils.h20
-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/qmldir4
-rw-r--r--src/imports/dialogs-private/qquickfontlistmodel.cpp290
-rw-r--r--src/imports/dialogs-private/qquickfontlistmodel_p.h125
-rw-r--r--src/imports/dialogs-private/qquickwritingsystemlistmodel.cpp176
-rw-r--r--src/imports/dialogs-private/qquickwritingsystemlistmodel_p.h100
-rw-r--r--src/imports/dialogs/DefaultColorDialog.qml362
-rw-r--r--src/imports/dialogs/DefaultFileDialog.qml394
-rw-r--r--src/imports/dialogs/DefaultFontDialog.qml483
-rw-r--r--src/imports/dialogs/DefaultMessageDialog.qml330
-rw-r--r--src/imports/dialogs/WidgetColorDialog.qml44
-rw-r--r--src/imports/dialogs/WidgetFileDialog.qml44
-rw-r--r--src/imports/dialogs/WidgetFontDialog.qml44
-rw-r--r--src/imports/dialogs/WidgetMessageDialog.qml44
-rw-r--r--src/imports/dialogs/dialogs.pro97
-rw-r--r--src/imports/dialogs/doc/images/critical.pngbin253 -> 0 bytes
-rw-r--r--src/imports/dialogs/doc/images/information.pngbin254 -> 0 bytes
-rw-r--r--src/imports/dialogs/doc/images/question.pngbin257 -> 0 bytes
-rw-r--r--src/imports/dialogs/doc/images/replacefile.pngbin4304 -> 0 bytes
-rw-r--r--src/imports/dialogs/doc/images/warning.pngbin224 -> 0 bytes
-rw-r--r--src/imports/dialogs/doc/qtquickdialogs.qdocconf41
-rw-r--r--src/imports/dialogs/doc/src/qtquickdialogs-examples.qdoc36
-rw-r--r--src/imports/dialogs/doc/src/qtquickdialogs-index.qdoc58
-rw-r--r--src/imports/dialogs/images/checkers.pngbin149 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/checkmark.pngbin809 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/copy.pngbin1338 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/critical.pngbin253 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/crosshairs.pngbin876 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/folder.pngbin1841 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/information.pngbin254 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/question.pngbin257 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/slider_handle.pngbin1551 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/sunken_frame.pngbin623 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/up.pngbin662 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/warning.pngbin224 -> 0 bytes
-rw-r--r--src/imports/dialogs/images/window_border.pngbin588 -> 0 bytes
-rw-r--r--src/imports/dialogs/plugin.cpp214
-rw-r--r--src/imports/dialogs/plugins.qmltypes654
-rw-r--r--src/imports/dialogs/qml/Button.qml86
-rw-r--r--src/imports/dialogs/qml/CheckBox.qml96
-rwxr-xr-xsrc/imports/dialogs/qml/ColorSlider.qml138
-rw-r--r--src/imports/dialogs/qml/DefaultWindowDecoration.qml71
-rw-r--r--src/imports/dialogs/qml/EdgeFade.qml63
-rw-r--r--src/imports/dialogs/qml/TextField.qml89
-rw-r--r--src/imports/dialogs/qml/qmldir5
-rw-r--r--src/imports/dialogs/qmldir4
-rw-r--r--src/imports/dialogs/qquickabstractcolordialog.cpp134
-rw-r--r--src/imports/dialogs/qquickabstractcolordialog_p.h113
-rw-r--r--src/imports/dialogs/qquickabstractdialog.cpp337
-rw-r--r--src/imports/dialogs/qquickabstractdialog_p.h145
-rw-r--r--src/imports/dialogs/qquickabstractfiledialog.cpp194
-rw-r--r--src/imports/dialogs/qquickabstractfiledialog_p.h122
-rw-r--r--src/imports/dialogs/qquickabstractfontdialog.cpp150
-rw-r--r--src/imports/dialogs/qquickabstractfontdialog_p.h113
-rw-r--r--src/imports/dialogs/qquickabstractmessagedialog.cpp179
-rw-r--r--src/imports/dialogs/qquickabstractmessagedialog_p.h165
-rw-r--r--src/imports/dialogs/qquickcolordialog.cpp119
-rw-r--r--src/imports/dialogs/qquickcolordialog_p.h80
-rw-r--r--src/imports/dialogs/qquickfiledialog.cpp172
-rw-r--r--src/imports/dialogs/qquickfiledialog_p.h93
-rw-r--r--src/imports/dialogs/qquickfontdialog.cpp120
-rw-r--r--src/imports/dialogs/qquickfontdialog_p.h80
-rw-r--r--src/imports/dialogs/qquickmessagedialog.cpp133
-rw-r--r--src/imports/dialogs/qquickmessagedialog_p.h85
-rw-r--r--src/imports/dialogs/qquickplatformcolordialog.cpp254
-rw-r--r--src/imports/dialogs/qquickplatformcolordialog_p.h78
-rw-r--r--src/imports/dialogs/qquickplatformfiledialog.cpp314
-rw-r--r--src/imports/dialogs/qquickplatformfiledialog_p.h78
-rw-r--r--src/imports/dialogs/qquickplatformfontdialog.cpp252
-rw-r--r--src/imports/dialogs/qquickplatformmessagedialog.cpp398
-rw-r--r--src/imports/dialogs/qquickplatformmessagedialog_p.h78
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.cpp8
-rw-r--r--src/imports/imports.pro4
-rw-r--r--src/imports/localstorage/plugin.cpp11
-rw-r--r--src/imports/settings/qqmlsettings.cpp3
-rw-r--r--src/imports/widgets/plugins.qmltypes302
-rw-r--r--src/imports/widgets/qmessageboxhelper_p.h107
-rw-r--r--src/imports/widgets/qmldir4
-rw-r--r--src/imports/widgets/qquickqcolordialog.cpp175
-rw-r--r--src/imports/widgets/qquickqfiledialog.cpp215
-rw-r--r--src/imports/widgets/qquickqfiledialog_p.h107
-rw-r--r--src/imports/widgets/qquickqfontdialog.cpp178
-rw-r--r--src/imports/widgets/qquickqfontdialog_p.h78
-rw-r--r--src/imports/widgets/qquickqmessagebox.cpp144
-rw-r--r--src/imports/widgets/widgets.pro32
-rw-r--r--src/imports/widgets/widgetsplugin.cpp89
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel.cpp10
-rw-r--r--src/particles/qquickv4particledata.cpp6
-rw-r--r--src/particles/qquickv4particledata_p.h2
-rw-r--r--src/plugins/accessible/quick/qaccessiblequickitem.cpp54
-rw-r--r--src/plugins/accessible/shared/qqmlaccessible.cpp2
-rw-r--r--src/plugins/qmltooling/shared/qpacketprotocol.cpp2
-rw-r--r--src/qml/compiler/compiler.pri6
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp544
-rw-r--r--src/qml/compiler/qqmlcodegenerator_p.h143
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp1908
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h247
-rw-r--r--src/qml/compiler/qv4compileddata.cpp72
-rw-r--r--src/qml/compiler/qv4compileddata_p.h106
-rw-r--r--src/qml/compiler/qv4compiler.cpp21
-rw-r--r--src/qml/compiler/qv4compiler_p.h2
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h107
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp115
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h32
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp329
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h4
-rw-r--r--src/qml/compiler/qv4isel_p.h2
-rw-r--r--src/qml/compiler/qv4isel_util_p.h36
-rw-r--r--src/qml/compiler/qv4jsir.cpp16
-rw-r--r--src/qml/compiler/qv4regalloc.cpp5
-rw-r--r--src/qml/compiler/qv4ssa.cpp18
-rw-r--r--src/qml/compiler/qv4ssa_p.h2
-rw-r--r--src/qml/debugger/debugger.pri13
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice.cpp (renamed from src/imports/dialogs/qquickdialogassets_p.h)65
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p.h (renamed from src/imports/widgets/qquickqmessagebox_p.h)36
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p_p.h (renamed from src/imports/widgets/qquickqcolordialog_p.h)32
-rw-r--r--src/qml/debugger/qqmldebugserver.cpp417
-rw-r--r--src/qml/debugger/qqmldebugserver_p.h6
-rw-r--r--src/qml/debugger/qqmldebugservice.cpp18
-rw-r--r--src/qml/debugger/qqmldebugservice_p.h10
-rw-r--r--src/qml/debugger/qqmlenginecontrolservice.cpp145
-rw-r--r--src/qml/debugger/qqmlenginecontrolservice_p.h (renamed from src/imports/dialogs/qquickplatformfontdialog_p.h)52
-rw-r--r--src/qml/debugger/qqmlenginedebugservice.cpp18
-rw-r--r--src/qml/debugger/qqmlenginedebugservice_p.h4
-rw-r--r--src/qml/debugger/qqmlprofilerservice.cpp526
-rw-r--r--src/qml/debugger/qqmlprofilerservice_p.h401
-rw-r--r--src/qml/debugger/qv4debugservice.cpp45
-rw-r--r--src/qml/debugger/qv4debugservice_p.h9
-rw-r--r--src/qml/debugger/qv4profilerservice.cpp (renamed from src/qml/debugger/qv8profilerservice.cpp)101
-rw-r--r--src/qml/debugger/qv4profilerservice_p.h (renamed from src/qml/debugger/qv8profilerservice_p.h)37
-rw-r--r--src/qml/doc/snippets/delegatemodel/visualdatamodel_rootindex/view.qml2
-rw-r--r--src/qml/doc/snippets/qml/SelfDestroyingRect.qml4
-rw-r--r--src/qml/doc/snippets/qml/createQmlObject.qml2
-rw-r--r--src/qml/doc/snippets/qml/listmodel/listmodel-nested.qml2
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/inline-component.qml4
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/inline-text-component.qml4
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/non-trivial.qml4
-rw-r--r--src/qml/doc/snippets/qml/qml-documents/qmldocuments.qml2
-rw-r--r--src/qml/doc/snippets/qml/qtobject.qml2
-rw-r--r--src/qml/jsapi/qjsvalue.cpp6
-rw-r--r--src/qml/jsapi/qjsvalue_p.h2
-rw-r--r--src/qml/jsapi/qjsvalueiterator.cpp27
-rw-r--r--src/qml/jsapi/qjsvalueiterator_p.h6
-rw-r--r--src/qml/jsruntime/jsruntime.pri6
-rw-r--r--src/qml/jsruntime/qv4alloca_p.h4
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp50
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h17
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp771
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h219
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp190
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4context.cpp47
-rw-r--r--src/qml/jsruntime/qv4context_p.h27
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp9
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h11
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp10
-rw-r--r--src/qml/jsruntime/qv4engine.cpp84
-rw-r--r--src/qml/jsruntime/qv4engine_p.h121
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp41
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h34
-rw-r--r--src/qml/jsruntime/qv4function.cpp2
-rw-r--r--src/qml/jsruntime/qv4function_p.h4
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp62
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h38
-rw-r--r--src/qml/jsruntime/qv4global_p.h16
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4include.cpp6
-rw-r--r--src/qml/jsruntime/qv4include_p.h2
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp2
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp28
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp193
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h15
-rw-r--r--src/qml/jsruntime/qv4managed.cpp97
-rw-r--r--src/qml/jsruntime/qv4managed_p.h261
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp10
-rw-r--r--src/qml/jsruntime/qv4mathobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4mm.cpp13
-rw-r--r--src/qml/jsruntime/qv4mm_p.h2
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4object.cpp754
-rw-r--r--src/qml/jsruntime/qv4object_p.h331
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp77
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h17
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp125
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h2
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp255
-rw-r--r--src/qml/jsruntime/qv4persistent_p.h167
-rw-r--r--src/qml/jsruntime/qv4property_p.h43
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp85
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h14
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp70
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h12
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp26
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h12
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp98
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h21
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h327
-rw-r--r--src/qml/jsruntime/qv4script.cpp16
-rw-r--r--src/qml/jsruntime/qv4script_p.h2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp48
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp17
-rw-r--r--src/qml/jsruntime/qv4serialize_p.h2
-rw-r--r--src/qml/jsruntime/qv4sparsearray.cpp90
-rw-r--r--src/qml/jsruntime/qv4sparsearray_p.h41
-rw-r--r--src/qml/jsruntime/qv4string.cpp22
-rw-r--r--src/qml/jsruntime/qv4string_p.h20
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp48
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h9
-rw-r--r--src/qml/jsruntime/qv4value.cpp215
-rw-r--r--src/qml/jsruntime/qv4value_def_p.h476
-rw-r--r--src/qml/jsruntime/qv4value_inl_p.h283
-rw-r--r--src/qml/jsruntime/qv4value_p.h718
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h6
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp133
-rw-r--r--src/qml/jsruntime/qv4vme_moth_p.h3
-rw-r--r--src/qml/parser/qqmljslexer.cpp2
-rw-r--r--src/qml/parser/qqmljsmemorypool_p.h2
-rw-r--r--src/qml/qml/ftw/qbitfield_p.h8
-rw-r--r--src/qml/qml/ftw/qfieldlist_p.h4
-rw-r--r--src/qml/qml/ftw/qfinitestack_p.h10
-rw-r--r--src/qml/qml/ftw/qhashedstring.cpp6
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h68
-rw-r--r--src/qml/qml/ftw/qhashfield_p.h4
-rw-r--r--src/qml/qml/ftw/qintrusivelist.cpp4
-rw-r--r--src/qml/qml/ftw/qintrusivelist_p.h82
-rw-r--r--src/qml/qml/ftw/qqmlpool_p.h18
-rw-r--r--src/qml/qml/ftw/qqmlrefcount_p.h32
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp20
-rw-r--r--src/qml/qml/ftw/qqmlthread_p.h2
-rw-r--r--src/qml/qml/ftw/qrecursionwatcher_p.h2
-rw-r--r--src/qml/qml/qqml.h32
-rw-r--r--src/qml/qml/qqmlbinding.cpp3
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp2
-rw-r--r--src/qml/qml/qqmlcleanup.cpp4
-rw-r--r--src/qml/qml/qqmlcleanup_p.h2
-rw-r--r--src/qml/qml/qqmlcompileddata.cpp26
-rw-r--r--src/qml/qml/qqmlcompiler.cpp118
-rw-r--r--src/qml/qml/qqmlcompiler_p.h50
-rw-r--r--src/qml/qml/qqmlcomponent.cpp25
-rw-r--r--src/qml/qml/qqmlcomponent_p.h6
-rw-r--r--src/qml/qml/qqmlcontext.cpp6
-rw-r--r--src/qml/qml/qqmlcontext_p.h2
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp10
-rw-r--r--src/qml/qml/qqmlcontextwrapper_p.h6
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp83
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h25
-rw-r--r--src/qml/qml/qqmldata_p.h9
-rw-r--r--src/qml/qml/qqmlengine.cpp22
-rw-r--r--src/qml/qml/qqmlengine_p.h50
-rw-r--r--src/qml/qml/qqmlerror.cpp4
-rw-r--r--src/qml/qml/qqmlglobal_p.h10
-rw-r--r--src/qml/qml/qqmlguard_p.h14
-rw-r--r--src/qml/qml/qqmlimport.cpp25
-rw-r--r--src/qml/qml/qqmlincubator.cpp107
-rw-r--r--src/qml/qml/qqmlincubator.h10
-rw-r--r--src/qml/qml/qqmlincubator_p.h9
-rw-r--r--src/qml/qml/qqmlinfo.cpp4
-rw-r--r--src/qml/qml/qqmlinstruction_p.h16
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp2
-rw-r--r--src/qml/qml/qqmllist.cpp26
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp20
-rw-r--r--src/qml/qml/qqmllistwrapper_p.h6
-rw-r--r--src/qml/qml/qqmllocale.cpp90
-rw-r--r--src/qml/qml/qqmllocale_p.h58
-rw-r--r--src/qml/qml/qqmlmetatype.cpp20
-rw-r--r--src/qml/qml/qqmlmetatype_p.h4
-rw-r--r--src/qml/qml/qqmlnotifier.cpp2
-rw-r--r--src/qml/qml/qqmlnotifier_p.h4
-rw-r--r--src/qml/qml/qqmlnullablevalue_p_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp1590
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h132
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp2
-rw-r--r--src/qml/qml/qqmlparserstatus.cpp2
-rw-r--r--src/qml/qml/qqmlparserstatus.h1
-rw-r--r--src/qml/qml/qqmlprivate.h8
-rw-r--r--src/qml/qml/qqmlproperty.cpp2
-rw-r--r--src/qml/qml/qqmlproperty.h2
-rw-r--r--src/qml/qml/qqmlproperty_p.h4
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp6
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h4
-rw-r--r--src/qml/qml/qqmlproxymetaobject.cpp4
-rw-r--r--src/qml/qml/qqmlscript.cpp94
-rw-r--r--src/qml/qml/qqmlscript_p.h26
-rw-r--r--src/qml/qml/qqmlscriptstring.h4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp312
-rw-r--r--src/qml/qml/qqmltypeloader_p.h18
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp2
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp8
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h4
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h4
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp4
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h4
-rw-r--r--src/qml/qml/qqmlvme.cpp142
-rw-r--r--src/qml/qml/qqmlvme_p.h55
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp45
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h4
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp94
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp16
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h2
-rw-r--r--src/qml/qml/v8/qv8engine.cpp53
-rw-r--r--src/qml/qml/v8/qv8engine_p.h8
-rw-r--r--src/qml/qml/v8/qv8profiler_p.h42
-rw-r--r--src/qml/qml/v8/v8.pri1
-rw-r--r--src/qml/types/qqmlconnections.cpp38
-rw-r--r--src/qml/types/qqmlconnections_p.h1
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp67
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h4
-rw-r--r--src/qml/types/qqmllistmodel.cpp174
-rw-r--r--src/qml/types/qqmllistmodel_p.h6
-rw-r--r--src/qml/types/qquickworkerscript.cpp14
-rw-r--r--src/qml/util/qqmladaptormodel.cpp5
-rw-r--r--src/quick/doc/snippets/qml/animatedimage.qml2
-rw-r--r--src/quick/doc/snippets/qml/listview/listview.qml2
-rw-r--r--src/quick/doc/snippets/qml/loader/connections.qml2
-rw-r--r--src/quick/doc/snippets/qml/loader/simple.qml2
-rw-r--r--src/quick/doc/snippets/qml/parentanimation.qml4
-rw-r--r--src/quick/doc/snippets/qml/parentchange.qml4
-rw-r--r--src/quick/doc/snippets/qml/propertyanimation.qml4
-rw-r--r--src/quick/doc/snippets/qml/propertychanges.qml4
-rw-r--r--src/quick/doc/snippets/qml/repeaters/repeater.qml6
-rw-r--r--src/quick/doc/snippets/qml/rotationanimation.qml4
-rw-r--r--src/quick/doc/snippets/qml/row.qml2
-rw-r--r--src/quick/doc/snippets/qml/state.qml4
-rw-r--r--src/quick/doc/snippets/qml/transition-from-to.qml2
-rw-r--r--src/quick/doc/snippets/qml/transition-reversible.qml2
-rw-r--r--src/quick/doc/snippets/qml/transition.qml4
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp8
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp75
-rw-r--r--src/quick/items/context2d/qquickcontext2d_p.h2
-rw-r--r--src/quick/items/qquickaccessibleattached.cpp51
-rw-r--r--src/quick/items/qquickaccessibleattached_p.h80
-rw-r--r--src/quick/items/qquickgridview.cpp40
-rw-r--r--src/quick/items/qquickimage.cpp11
-rw-r--r--src/quick/items/qquickitem.cpp246
-rw-r--r--src/quick/items/qquickitem.h8
-rw-r--r--src/quick/items/qquickitem_p.h17
-rw-r--r--src/quick/items/qquickitemsmodule.cpp5
-rw-r--r--src/quick/items/qquickitemview.cpp40
-rw-r--r--src/quick/items/qquickitemview_p.h10
-rw-r--r--src/quick/items/qquickitemview_p_p.h2
-rw-r--r--src/quick/items/qquicklistview.cpp39
-rw-r--r--src/quick/items/qquickloader_p_p.h2
-rw-r--r--src/quick/items/qquickmousearea.cpp5
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp5
-rw-r--r--src/quick/items/qquickrectangle.cpp14
-rw-r--r--src/quick/items/qquickscreen.cpp2
-rw-r--r--src/quick/items/qquicktext.cpp86
-rw-r--r--src/quick/items/qquicktext_p.h3
-rw-r--r--src/quick/items/qquicktext_p_p.h9
-rw-r--r--src/quick/items/qquicktextedit.cpp28
-rw-r--r--src/quick/items/qquicktextedit_p.h2
-rw-r--r--src/quick/items/qquicktextinput.cpp5
-rw-r--r--src/quick/items/qquicktextnode.cpp8
-rw-r--r--src/quick/items/qquicktranslate.cpp75
-rw-r--r--src/quick/items/qquicktranslate_p.h23
-rw-r--r--src/quick/items/qquickview.cpp37
-rw-r--r--src/quick/items/qquickview_p.h22
-rw-r--r--src/quick/items/qquickwindow.cpp121
-rw-r--r--src/quick/items/qquickwindow_p.h4
-rw-r--r--src/quick/quick.pro2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp354
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h24
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry.cpp10
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp13
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h2
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp11
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp24
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h3
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp11
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp24
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp38
-rw-r--r--src/quick/scenegraph/scenegraph.pri4
-rw-r--r--src/quick/scenegraph/scenegraph.qrc2
-rw-r--r--src/quick/scenegraph/shaders/visualization.frag11
-rw-r--r--src/quick/scenegraph/shaders/visualization.vert22
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp22
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp31
-rw-r--r--src/quick/util/qquickanimatorjob.cpp2
-rw-r--r--src/quick/util/qquickbehavior.cpp11
-rw-r--r--src/quick/util/qquickglobal.cpp2
-rw-r--r--src/quick/util/qquickimageprovider.cpp18
-rw-r--r--src/quick/util/qquickpixmapcache.cpp74
-rw-r--r--src/quick/util/qquickpropertychanges.cpp61
-rw-r--r--src/quick/util/qquickpropertychanges_p.h2
-rw-r--r--src/quick/util/qquickstate_p_p.h2
-rw-r--r--src/quick/util/qquicktimeline.cpp24
-rw-r--r--src/quick/util/qquicktransitionmanager.cpp12
-rw-r--r--src/quick/util/qquicktransitionmanager_p_p.h2
407 files changed, 11795 insertions, 17101 deletions
diff --git a/src/3rdparty/double-conversion/README b/src/3rdparty/double-conversion/README
index 40ed4a7efd..3a9733d795 100644
--- a/src/3rdparty/double-conversion/README
+++ b/src/3rdparty/double-conversion/README
@@ -3,4 +3,4 @@ from
http://code.google.com/p/double-conversion/
-commit e5b34421b763f7bf7e4f9081403db417d5a55a36
+commit 2fb03de56faa32bbba5e02222528e7b760f71d77
diff --git a/src/3rdparty/double-conversion/bignum-dtoa.cc b/src/3rdparty/double-conversion/bignum-dtoa.cc
index b6c2e85d17..f1ad7a5ae8 100644
--- a/src/3rdparty/double-conversion/bignum-dtoa.cc
+++ b/src/3rdparty/double-conversion/bignum-dtoa.cc
@@ -192,13 +192,13 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
delta_plus = delta_minus;
}
*length = 0;
- while (true) {
+ for (;;) {
uint16_t digit;
digit = numerator->DivideModuloIntBignum(*denominator);
ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
// digit = numerator / denominator (integer division).
// numerator = numerator % denominator.
- buffer[(*length)++] = digit + '0';
+ buffer[(*length)++] = static_cast<char>(digit + '0');
// Can we stop already?
// If the remainder of the division is less than the distance to the lower
@@ -282,7 +282,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
// exponent (decimal_point), when rounding upwards.
static void GenerateCountedDigits(int count, int* decimal_point,
Bignum* numerator, Bignum* denominator,
- Vector<char>(buffer), int* length) {
+ Vector<char> buffer, int* length) {
ASSERT(count >= 0);
for (int i = 0; i < count - 1; ++i) {
uint16_t digit;
@@ -290,7 +290,7 @@ static void GenerateCountedDigits(int count, int* decimal_point,
ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
// digit = numerator / denominator (integer division).
// numerator = numerator % denominator.
- buffer[i] = digit + '0';
+ buffer[i] = static_cast<char>(digit + '0');
// Prepare for next iteration.
numerator->Times10();
}
@@ -300,7 +300,8 @@ static void GenerateCountedDigits(int count, int* decimal_point,
if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
digit++;
}
- buffer[count - 1] = digit + '0';
+ ASSERT(digit <= 10);
+ buffer[count - 1] = static_cast<char>(digit + '0');
// Correct bad digits (in case we had a sequence of '9's). Propagate the
// carry until we hat a non-'9' or til we reach the first digit.
for (int i = count - 1; i > 0; --i) {
diff --git a/src/3rdparty/double-conversion/bignum.cc b/src/3rdparty/double-conversion/bignum.cc
index 747491a089..2743d67e8d 100644
--- a/src/3rdparty/double-conversion/bignum.cc
+++ b/src/3rdparty/double-conversion/bignum.cc
@@ -40,6 +40,7 @@ Bignum::Bignum()
template<typename S>
static int BitSize(S value) {
+ (void) value; // Mark variable as used.
return 8 * sizeof(value);
}
@@ -122,9 +123,8 @@ void Bignum::AssignDecimalString(Vector<const char> value) {
static int HexCharValue(char c) {
if ('0' <= c && c <= '9') return c - '0';
if ('a' <= c && c <= 'f') return 10 + c - 'a';
- if ('A' <= c && c <= 'F') return 10 + c - 'A';
- UNREACHABLE();
- return 0; // To make compiler happy.
+ ASSERT('A' <= c && c <= 'F');
+ return 10 + c - 'A';
}
@@ -501,13 +501,14 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
// Start by removing multiples of 'other' until both numbers have the same
// number of digits.
while (BigitLength() > other.BigitLength()) {
- // This naive approach is extremely inefficient if the this divided other
- // might be big. This function is implemented for doubleToString where
+ // This naive approach is extremely inefficient if `this` divided by other
+ // is big. This function is implemented for doubleToString where
// the result should be small (less than 10).
ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16));
+ ASSERT(bigits_[used_digits_ - 1] < 0x10000);
// Remove the multiples of the first digit.
// Example this = 23 and other equals 9. -> Remove 2 multiples.
- result += bigits_[used_digits_ - 1];
+ result += static_cast<uint16_t>(bigits_[used_digits_ - 1]);
SubtractTimes(other, bigits_[used_digits_ - 1]);
}
@@ -523,13 +524,15 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
// Shortcut for easy (and common) case.
int quotient = this_bigit / other_bigit;
bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient;
- result += quotient;
+ ASSERT(quotient < 0x10000);
+ result += static_cast<uint16_t>(quotient);
Clamp();
return result;
}
int division_estimate = this_bigit / (other_bigit + 1);
- result += division_estimate;
+ ASSERT(division_estimate < 0x10000);
+ result += static_cast<uint16_t>(division_estimate);
SubtractTimes(other, division_estimate);
if (other_bigit * (division_estimate + 1) > this_bigit) {
@@ -560,8 +563,8 @@ static int SizeInHexChars(S number) {
static char HexCharOfValue(int value) {
ASSERT(0 <= value && value <= 16);
- if (value < 10) return value + '0';
- return value - 10 + 'A';
+ if (value < 10) return static_cast<char>(value + '0');
+ return static_cast<char>(value - 10 + 'A');
}
@@ -755,7 +758,6 @@ void Bignum::SubtractTimes(const Bignum& other, int factor) {
Chunk difference = bigits_[i] - borrow;
bigits_[i] = difference & kBigitMask;
borrow = difference >> (kChunkSize - 1);
- ++i;
}
Clamp();
}
diff --git a/src/3rdparty/double-conversion/cached-powers.cc b/src/3rdparty/double-conversion/cached-powers.cc
index 7067fca4a9..f2d53de52b 100644
--- a/src/3rdparty/double-conversion/cached-powers.cc
+++ b/src/3rdparty/double-conversion/cached-powers.cc
@@ -153,6 +153,7 @@ void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
ASSERT(0 <= index && index < kCachedPowersLength);
CachedPower cached_power = kCachedPowers[index];
ASSERT(min_exponent <= cached_power.binary_exponent);
+ (void) max_exponent; // Mark variable as used.
ASSERT(cached_power.binary_exponent <= max_exponent);
*decimal_exponent = cached_power.decimal_exponent;
*power = DiyFp(cached_power.significand, cached_power.binary_exponent);
diff --git a/src/3rdparty/double-conversion/double-conversion.cc b/src/3rdparty/double-conversion/double-conversion.cc
index a79fe92d22..909985be82 100644
--- a/src/3rdparty/double-conversion/double-conversion.cc
+++ b/src/3rdparty/double-conversion/double-conversion.cc
@@ -348,7 +348,6 @@ static BignumDtoaMode DtoaToBignumDtoaMode(
case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
default:
UNREACHABLE();
- return BIGNUM_DTOA_SHORTEST; // To silence compiler.
}
}
@@ -403,8 +402,8 @@ void DoubleToStringConverter::DoubleToAscii(double v,
vector, length, point);
break;
default:
- UNREACHABLE();
fast_worked = false;
+ UNREACHABLE();
}
if (fast_worked) return;
@@ -417,8 +416,9 @@ void DoubleToStringConverter::DoubleToAscii(double v,
// Consumes the given substring from the iterator.
// Returns false, if the substring does not match.
-static bool ConsumeSubString(const char** current,
- const char* end,
+template <class Iterator>
+static bool ConsumeSubString(Iterator* current,
+ Iterator end,
const char* substring) {
ASSERT(**current == *substring);
for (substring++; *substring != '\0'; substring++) {
@@ -440,10 +440,36 @@ static bool ConsumeSubString(const char** current,
const int kMaxSignificantDigits = 772;
+static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
+static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
+
+
+static const uc16 kWhitespaceTable16[] = {
+ 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
+ 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
+};
+static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
+
+
+static bool isWhitespace(int x) {
+ if (x < 128) {
+ for (int i = 0; i < kWhitespaceTable7Length; i++) {
+ if (kWhitespaceTable7[i] == x) return true;
+ }
+ } else {
+ for (int i = 0; i < kWhitespaceTable16Length; i++) {
+ if (kWhitespaceTable16[i] == x) return true;
+ }
+ }
+ return false;
+}
+
+
// Returns true if a nonspace found and false if the end has reached.
-static inline bool AdvanceToNonspace(const char** current, const char* end) {
+template <class Iterator>
+static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
while (*current != end) {
- if (**current != ' ') return true;
+ if (!isWhitespace(**current)) return true;
++*current;
}
return false;
@@ -462,26 +488,50 @@ static double SignedZero(bool sign) {
}
+// Returns true if 'c' is a decimal digit that is valid for the given radix.
+//
+// The function is small and could be inlined, but VS2012 emitted a warning
+// because it constant-propagated the radix and concluded that the last
+// condition was always true. By moving it into a separate function the
+// compiler wouldn't warn anymore.
+static bool IsDecimalDigitForRadix(int c, int radix) {
+ return '0' <= c && c <= '9' && (c - '0') < radix;
+}
+
+// Returns true if 'c' is a character digit that is valid for the given radix.
+// The 'a_character' should be 'a' or 'A'.
+//
+// The function is small and could be inlined, but VS2012 emitted a warning
+// because it constant-propagated the radix and concluded that the first
+// condition was always false. By moving it into a separate function the
+// compiler wouldn't warn anymore.
+static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
+ return radix > 10 && c >= a_character && c < a_character + radix - 10;
+}
+
+
// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
-template <int radix_log_2>
-static double RadixStringToIeee(const char* current,
- const char* end,
+template <int radix_log_2, class Iterator>
+static double RadixStringToIeee(Iterator* current,
+ Iterator end,
bool sign,
bool allow_trailing_junk,
double junk_string_value,
bool read_as_double,
- const char** trailing_pointer) {
- ASSERT(current != end);
+ bool* result_is_junk) {
+ ASSERT(*current != end);
const int kDoubleSize = Double::kSignificandSize;
const int kSingleSize = Single::kSignificandSize;
const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
+ *result_is_junk = true;
+
// Skip leading 0s.
- while (*current == '0') {
- ++current;
- if (current == end) {
- *trailing_pointer = end;
+ while (**current == '0') {
+ ++(*current);
+ if (*current == end) {
+ *result_is_junk = false;
return SignedZero(sign);
}
}
@@ -492,14 +542,14 @@ static double RadixStringToIeee(const char* current,
do {
int digit;
- if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
- digit = static_cast<char>(*current) - '0';
- } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
- digit = static_cast<char>(*current) - 'a' + 10;
- } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
- digit = static_cast<char>(*current) - 'A' + 10;
+ if (IsDecimalDigitForRadix(**current, radix)) {
+ digit = static_cast<char>(**current) - '0';
+ } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
+ digit = static_cast<char>(**current) - 'a' + 10;
+ } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
+ digit = static_cast<char>(**current) - 'A' + 10;
} else {
- if (allow_trailing_junk || !AdvanceToNonspace(&current, end)) {
+ if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
break;
} else {
return junk_string_value;
@@ -523,14 +573,14 @@ static double RadixStringToIeee(const char* current,
exponent = overflow_bits_count;
bool zero_tail = true;
- while (true) {
- ++current;
- if (current == end || !isDigit(*current, radix)) break;
- zero_tail = zero_tail && *current == '0';
+ for (;;) {
+ ++(*current);
+ if (*current == end || !isDigit(**current, radix)) break;
+ zero_tail = zero_tail && **current == '0';
exponent += radix_log_2;
}
- if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+ if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
return junk_string_value;
}
@@ -552,13 +602,13 @@ static double RadixStringToIeee(const char* current,
}
break;
}
- ++current;
- } while (current != end);
+ ++(*current);
+ } while (*current != end);
ASSERT(number < ((int64_t)1 << kSignificandSize));
ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
- *trailing_pointer = current;
+ *result_is_junk = false;
if (exponent == 0) {
if (sign) {
@@ -573,13 +623,14 @@ static double RadixStringToIeee(const char* current,
}
+template <class Iterator>
double StringToDoubleConverter::StringToIeee(
- const char* input,
+ Iterator input,
int length,
- int* processed_characters_count,
- bool read_as_double) {
- const char* current = input;
- const char* end = input + length;
+ bool read_as_double,
+ int* processed_characters_count) const {
+ Iterator current = input;
+ Iterator end = input + length;
*processed_characters_count = 0;
@@ -600,7 +651,7 @@ double StringToDoubleConverter::StringToIeee(
if (allow_leading_spaces || allow_trailing_spaces) {
if (!AdvanceToNonspace(&current, end)) {
- *processed_characters_count = current - input;
+ *processed_characters_count = static_cast<int>(current - input);
return empty_string_value_;
}
if (!allow_leading_spaces && (input != current)) {
@@ -626,7 +677,7 @@ double StringToDoubleConverter::StringToIeee(
if (*current == '+' || *current == '-') {
sign = (*current == '-');
++current;
- const char* next_non_space = current;
+ Iterator next_non_space = current;
// Skip following spaces (if allowed).
if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
if (!allow_spaces_after_sign && (current != next_non_space)) {
@@ -649,7 +700,7 @@ double StringToDoubleConverter::StringToIeee(
}
ASSERT(buffer_pos == 0);
- *processed_characters_count = current - input;
+ *processed_characters_count = static_cast<int>(current - input);
return sign ? -Double::Infinity() : Double::Infinity();
}
}
@@ -668,7 +719,7 @@ double StringToDoubleConverter::StringToIeee(
}
ASSERT(buffer_pos == 0);
- *processed_characters_count = current - input;
+ *processed_characters_count = static_cast<int>(current - input);
return sign ? -Double::NaN() : Double::NaN();
}
}
@@ -677,7 +728,7 @@ double StringToDoubleConverter::StringToIeee(
if (*current == '0') {
++current;
if (current == end) {
- *processed_characters_count = current - input;
+ *processed_characters_count = static_cast<int>(current - input);
return SignedZero(sign);
}
@@ -690,17 +741,17 @@ double StringToDoubleConverter::StringToIeee(
return junk_string_value_; // "0x".
}
- const char* tail_pointer = NULL;
- double result = RadixStringToIeee<4>(current,
+ bool result_is_junk;
+ double result = RadixStringToIeee<4>(&current,
end,
sign,
allow_trailing_junk,
junk_string_value_,
read_as_double,
- &tail_pointer);
- if (tail_pointer != NULL) {
- if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end);
- *processed_characters_count = tail_pointer - input;
+ &result_is_junk);
+ if (!result_is_junk) {
+ if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
+ *processed_characters_count = static_cast<int>(current - input);
}
return result;
}
@@ -709,7 +760,7 @@ double StringToDoubleConverter::StringToIeee(
while (*current == '0') {
++current;
if (current == end) {
- *processed_characters_count = current - input;
+ *processed_characters_count = static_cast<int>(current - input);
return SignedZero(sign);
}
}
@@ -757,7 +808,7 @@ double StringToDoubleConverter::StringToIeee(
while (*current == '0') {
++current;
if (current == end) {
- *processed_characters_count = current - input;
+ *processed_characters_count = static_cast<int>(current - input);
return SignedZero(sign);
}
exponent--; // Move this 0 into the exponent.
@@ -855,16 +906,17 @@ double StringToDoubleConverter::StringToIeee(
if (octal) {
double result;
- const char* tail_pointer = NULL;
- result = RadixStringToIeee<3>(buffer,
+ bool result_is_junk;
+ char* start = buffer;
+ result = RadixStringToIeee<3>(&start,
buffer + buffer_pos,
sign,
allow_trailing_junk,
junk_string_value_,
read_as_double,
- &tail_pointer);
- ASSERT(tail_pointer != NULL);
- *processed_characters_count = current - input;
+ &result_is_junk);
+ ASSERT(!result_is_junk);
+ *processed_characters_count = static_cast<int>(current - input);
return result;
}
@@ -882,8 +934,42 @@ double StringToDoubleConverter::StringToIeee(
} else {
converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
}
- *processed_characters_count = current - input;
+ *processed_characters_count = static_cast<int>(current - input);
return sign? -converted: converted;
}
+
+double StringToDoubleConverter::StringToDouble(
+ const char* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return StringToIeee(buffer, length, true, processed_characters_count);
+}
+
+
+double StringToDoubleConverter::StringToDouble(
+ const uc16* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return StringToIeee(buffer, length, true, processed_characters_count);
+}
+
+
+float StringToDoubleConverter::StringToFloat(
+ const char* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return static_cast<float>(StringToIeee(buffer, length, false,
+ processed_characters_count));
+}
+
+
+float StringToDoubleConverter::StringToFloat(
+ const uc16* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return static_cast<float>(StringToIeee(buffer, length, false,
+ processed_characters_count));
+}
+
} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/double-conversion.h b/src/3rdparty/double-conversion/double-conversion.h
index f98edae75a..6bdfa8d25d 100644
--- a/src/3rdparty/double-conversion/double-conversion.h
+++ b/src/3rdparty/double-conversion/double-conversion.h
@@ -415,9 +415,10 @@ class StringToDoubleConverter {
// junk, too.
// - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of
// a double literal.
- // - ALLOW_LEADING_SPACES: skip over leading spaces.
- // - ALLOW_TRAILING_SPACES: ignore trailing spaces.
- // - ALLOW_SPACES_AFTER_SIGN: ignore spaces after the sign.
+ // - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces,
+ // new-lines, and tabs.
+ // - ALLOW_TRAILING_SPACES: ignore trailing whitespace.
+ // - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign.
// Ex: StringToDouble("- 123.2") -> -123.2.
// StringToDouble("+ 123.2") -> 123.2
//
@@ -502,19 +503,24 @@ class StringToDoubleConverter {
// in the 'processed_characters_count'. Trailing junk is never included.
double StringToDouble(const char* buffer,
int length,
- int* processed_characters_count) {
- return StringToIeee(buffer, length, processed_characters_count, true);
- }
+ int* processed_characters_count) const;
+
+ // Same as StringToDouble above but for 16 bit characters.
+ double StringToDouble(const uc16* buffer,
+ int length,
+ int* processed_characters_count) const;
// Same as StringToDouble but reads a float.
// Note that this is not equivalent to static_cast<float>(StringToDouble(...))
// due to potential double-rounding.
float StringToFloat(const char* buffer,
int length,
- int* processed_characters_count) {
- return static_cast<float>(StringToIeee(buffer, length,
- processed_characters_count, false));
- }
+ int* processed_characters_count) const;
+
+ // Same as StringToFloat above but for 16 bit characters.
+ float StringToFloat(const uc16* buffer,
+ int length,
+ int* processed_characters_count) const;
private:
const int flags_;
@@ -523,10 +529,11 @@ class StringToDoubleConverter {
const char* const infinity_symbol_;
const char* const nan_symbol_;
- double StringToIeee(const char* buffer,
+ template <class Iterator>
+ double StringToIeee(Iterator start_pointer,
int length,
- int* processed_characters_count,
- bool read_as_double);
+ bool read_as_double,
+ int* processed_characters_count) const;
DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
};
diff --git a/src/3rdparty/double-conversion/fast-dtoa.cc b/src/3rdparty/double-conversion/fast-dtoa.cc
index 1a0f823509..61350383a9 100644
--- a/src/3rdparty/double-conversion/fast-dtoa.cc
+++ b/src/3rdparty/double-conversion/fast-dtoa.cc
@@ -248,10 +248,7 @@ static void BiggestPowerTen(uint32_t number,
// Note: kPowersOf10[i] == 10^(i-1).
exponent_plus_one_guess++;
// We don't have any guarantees that 2^number_bits <= number.
- // TODO(floitsch): can we change the 'while' into an 'if'? We definitely see
- // number < (2^number_bits - 1), but I haven't encountered
- // number < (2^number_bits - 2) yet.
- while (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
+ if (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
exponent_plus_one_guess--;
}
*power = kSmallPowersOfTen[exponent_plus_one_guess];
@@ -350,7 +347,8 @@ static bool DigitGen(DiyFp low,
// that is smaller than integrals.
while (*kappa > 0) {
int digit = integrals / divisor;
- buffer[*length] = '0' + digit;
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
integrals %= divisor;
(*kappa)--;
@@ -379,13 +377,14 @@ static bool DigitGen(DiyFp low,
ASSERT(one.e() >= -60);
ASSERT(fractionals < one.f());
ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
- while (true) {
+ for (;;) {
fractionals *= 10;
unit *= 10;
unsafe_interval.set_f(unsafe_interval.f() * 10);
// Integer division by one.
int digit = static_cast<int>(fractionals >> -one.e());
- buffer[*length] = '0' + digit;
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
fractionals &= one.f() - 1; // Modulo by one.
(*kappa)--;
@@ -459,7 +458,8 @@ static bool DigitGenCounted(DiyFp w,
// that is smaller than 'integrals'.
while (*kappa > 0) {
int digit = integrals / divisor;
- buffer[*length] = '0' + digit;
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
requested_digits--;
integrals %= divisor;
@@ -492,7 +492,8 @@ static bool DigitGenCounted(DiyFp w,
w_error *= 10;
// Integer division by one.
int digit = static_cast<int>(fractionals >> -one.e());
- buffer[*length] = '0' + digit;
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
requested_digits--;
fractionals &= one.f() - 1; // Modulo by one.
diff --git a/src/3rdparty/double-conversion/fixed-dtoa.cc b/src/3rdparty/double-conversion/fixed-dtoa.cc
index 6d63c71858..aef65fdc21 100644
--- a/src/3rdparty/double-conversion/fixed-dtoa.cc
+++ b/src/3rdparty/double-conversion/fixed-dtoa.cc
@@ -133,7 +133,7 @@ static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
while (number != 0) {
int digit = number % 10;
number /= 10;
- buffer[(*length) + number_length] = '0' + digit;
+ buffer[(*length) + number_length] = static_cast<char>('0' + digit);
number_length++;
}
// Exchange the digits.
@@ -150,10 +150,8 @@ static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
}
-static void FillDigits64FixedLength(uint64_t number, int requested_length,
+static void FillDigits64FixedLength(uint64_t number,
Vector<char> buffer, int* length) {
- (void) requested_length;
-
const uint32_t kTen7 = 10000000;
// For efficiency cut the number into 3 uint32_t parts, and print those.
uint32_t part2 = static_cast<uint32_t>(number % kTen7);
@@ -255,7 +253,8 @@ static void FillFractionals(uint64_t fractionals, int exponent,
fractionals *= 5;
point--;
int digit = static_cast<int>(fractionals >> point);
- buffer[*length] = '0' + digit;
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
fractionals -= static_cast<uint64_t>(digit) << point;
}
@@ -276,7 +275,8 @@ static void FillFractionals(uint64_t fractionals, int exponent,
fractionals128.Multiply(5);
point--;
int digit = fractionals128.DivModPowerOf2(point);
- buffer[*length] = '0' + digit;
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
}
if (fractionals128.BitAt(point - 1) == 1) {
@@ -360,7 +360,7 @@ bool FastFixedDtoa(double v,
remainder = (dividend % divisor) << exponent;
}
FillDigits32(quotient, buffer, length);
- FillDigits64FixedLength(remainder, divisor_power, buffer, length);
+ FillDigits64FixedLength(remainder, buffer, length);
*decimal_point = *length;
} else if (exponent >= 0) {
// 0 <= exponent <= 11
diff --git a/src/3rdparty/double-conversion/ieee.h b/src/3rdparty/double-conversion/ieee.h
index 839dc47d45..661141d1a8 100644
--- a/src/3rdparty/double-conversion/ieee.h
+++ b/src/3rdparty/double-conversion/ieee.h
@@ -256,6 +256,8 @@ class Double {
return (significand & kSignificandMask) |
(biased_exponent << kPhysicalSignificandSize);
}
+
+ DISALLOW_COPY_AND_ASSIGN(Double);
};
class Single {
@@ -391,6 +393,8 @@ class Single {
static const uint32_t kNaN = 0x7FC00000;
const uint32_t d32_;
+
+ DISALLOW_COPY_AND_ASSIGN(Single);
};
} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/strtod.cc b/src/3rdparty/double-conversion/strtod.cc
index 2620fbbf0f..34717562bd 100644
--- a/src/3rdparty/double-conversion/strtod.cc
+++ b/src/3rdparty/double-conversion/strtod.cc
@@ -137,7 +137,7 @@ static void TrimAndCut(Vector<const char> buffer, int exponent,
Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
exponent += left_trimmed.length() - right_trimmed.length();
if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
- (void)space_size; // Silence unused parameter warning in release build
+ (void) space_size; // Mark variable as used.
ASSERT(space_size >= kMaxSignificantDecimalDigits);
CutToMaxSignificantDigits(right_trimmed, exponent,
buffer_copy_space, updated_exponent);
@@ -264,7 +264,6 @@ static DiyFp AdjustmentPowerOfTen(int exponent) {
case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
default:
UNREACHABLE();
- return DiyFp(0, 0);
}
}
@@ -516,7 +515,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
double double_next2 = Double(double_next).NextDouble();
f4 = static_cast<float>(double_next2);
}
- (void)f2; // Silence unused parameter warning in release builds
+ (void) f2; // Mark variable as used.
ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
// If the guess doesn't lie near a single-precision boundary we can simply
diff --git a/src/3rdparty/double-conversion/utils.h b/src/3rdparty/double-conversion/utils.h
index 1eca476913..53eec64282 100644
--- a/src/3rdparty/double-conversion/utils.h
+++ b/src/3rdparty/double-conversion/utils.h
@@ -36,7 +36,8 @@
# if defined(WINCE) || defined(_WIN32_WCE)
# define ASSERT(condition)
# else
-# define ASSERT(condition) (assert(condition))
+# define ASSERT(condition) \
+ assert(condition);
# endif
#endif
#ifndef UNIMPLEMENTED
@@ -59,10 +60,12 @@
#if defined(_M_X64) || defined(__x86_64__) || \
defined(__ARMEL__) || defined(__avr32__) || _M_ARM_FP || \
defined(__hppa__) || defined(__ia64__) || \
- defined(__mips__) || defined(__powerpc__) || \
+ defined(__mips__) || \
+ defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
defined(__SH4__) || defined(__alpha__) || \
- defined(_MIPS_ARCH_MIPS32R2)
+ defined(_MIPS_ARCH_MIPS32R2) || \
+ defined(__AARCH64EL__)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
#if defined(_WIN32)
@@ -77,6 +80,11 @@
#error Target architecture was not detected as supported by Double-Conversion.
#endif
+#if defined(__GNUC__)
+#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
+#else
+#define DOUBLE_CONVERSION_UNUSED
+#endif
#if defined(_WIN32) && !defined(__MINGW32__)
@@ -96,6 +104,8 @@ typedef unsigned __int64 uint64_t;
#endif
+typedef uint16_t uc16;
+
// The following macro works on both 32 and 64-bit platforms.
// Usage: instead of writing 0x1234567890123456
// write UINT64_2PART_C(0x12345678,90123456);
@@ -302,8 +312,8 @@ template <class Dest, class Source>
inline Dest BitCast(const Source& source) {
// Compile time assertion: sizeof(Dest) == sizeof(Source)
// A compile error here means your Dest and Source have different sizes.
- char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
- (void) VerifySizesAreEqual;
+ DOUBLE_CONVERSION_UNUSED
+ typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
Dest dest;
memmove(&dest, &source, sizeof(dest));
diff --git a/src/imports/dialogs-private/dialogs-private.pro b/src/imports/dialogs-private/dialogs-private.pro
deleted file mode 100644
index 7f04617ef5..0000000000
--- a/src/imports/dialogs-private/dialogs-private.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-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 += 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
deleted file mode 100644
index f920df30f3..0000000000
--- a/src/imports/dialogs-private/dialogsprivateplugin.cpp
+++ /dev/null
@@ -1,66 +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 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
deleted file mode 100644
index c371f8bb8c..0000000000
--- a/src/imports/dialogs-private/qmldir
+++ /dev/null
@@ -1,4 +0,0 @@
-module QtQuick.Dialogs.Private
-plugin dialogsprivateplugin
-typeinfo plugins.qmltypes
-classname QtQuick2DialogsPrivatePlugin
diff --git a/src/imports/dialogs-private/qquickfontlistmodel.cpp b/src/imports/dialogs-private/qquickfontlistmodel.cpp
deleted file mode 100644
index 96d1824ef6..0000000000
--- a/src/imports/dialogs-private/qquickfontlistmodel.cpp
+++ /dev/null
@@ -1,290 +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 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/qqmlcontext.h>
-#include <private/qqmlengine_p.h>
-#include <private/qv8engine_p.h>
-#include <private/qv4value_p.h>
-#include <private/qv4engine_p.h>
-#include <private/qv4object_p.h>
-
-QT_BEGIN_NAMESPACE
-
-using namespace QV4;
-
-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);
-}
-
-QQmlV4Handle QQuickFontListModel::get(int idx) const
-{
- Q_D(const QQuickFontListModel);
-
- if (idx < 0 || idx >= count())
- return QQmlV4Handle(Encode::undefined());
-
- QQmlEngine *engine = qmlContext(this)->engine();
- QV8Engine *v8engine = QQmlEnginePrivate::getV8Engine(engine);
- ExecutionEngine *v4engine = QV8Engine::getV4(v8engine);
- Scope scope(v4engine);
- ScopedObject o(scope, v4engine->newObject());
- ScopedString s(scope);
- for (int ii = 0; ii < d->roleNames.keys().count(); ++ii) {
- Property *p = o->insertMember((s = v4engine->newIdentifier(d->roleNames[Qt::UserRole + ii + 1])), PropertyAttributes());
- p->value = v8engine->fromVariant(data(index(idx, 0), Qt::UserRole + ii + 1));
- }
-
- return QQmlV4Handle(o);
-}
-
-QQmlV4Handle QQuickFontListModel::pointSizes()
-{
- QQmlEngine *engine = qmlContext(this)->engine();
- QV8Engine *v8engine = QQmlEnginePrivate::getV8Engine(engine);
- ExecutionEngine *v4engine = QV8Engine::getV4(v8engine);
- Scope scope(v4engine);
-
- QList<int> pss = QFontDatabase::standardSizes();
- int size = pss.size();
-
- Scoped<QV4::ArrayObject> a(scope, v4engine->newArrayObject());
- a->arrayReserve(size);
- a->arrayDataLen = size;
- for (int i = 0; i < size; ++i)
- a->arrayData[i].value = Primitive::fromInt32(pss.at(i));
- a->setArrayLengthUnchecked(size);
-
- return QQmlV4Handle(ScopedValue(scope, a.asReturnedValue()));
-}
-
-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
deleted file mode 100644
index 3e2e7f7132..0000000000
--- a/src/imports/dialogs-private/qquickfontlistmodel_p.h
+++ /dev/null
@@ -1,125 +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 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/qabstractitemmodel.h>
-#include <QtGui/qpa/qplatformdialoghelper.h>
-#include <QtQml/qqmlparserstatus.h>
-#include <private/qv8engine_p.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 QQmlV4Handle get(int index) const;
- Q_INVOKABLE QQmlV4Handle 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
deleted file mode 100644
index f2b4ff8b8f..0000000000
--- a/src/imports/dialogs-private/qquickwritingsystemlistmodel.cpp
+++ /dev/null
@@ -1,176 +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 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/qqmlcontext.h>
-#include <private/qqmlengine_p.h>
-#include <private/qv8engine_p.h>
-#include <private/qv4value_p.h>
-#include <private/qv4engine_p.h>
-#include <private/qv4object_p.h>
-
-QT_BEGIN_NAMESPACE
-
-using namespace QV4;
-
-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;
-}
-
-QQmlV4Handle QQuickWritingSystemListModel::get(int idx) const
-{
- Q_D(const QQuickWritingSystemListModel);
-
- if (idx < 0 || idx >= count())
- return QQmlV4Handle(Encode::undefined());
-
- QQmlEngine *engine = qmlContext(this)->engine();
- QV8Engine *v8engine = QQmlEnginePrivate::getV8Engine(engine);
- ExecutionEngine *v4engine = QV8Engine::getV4(v8engine);
- Scope scope(v4engine);
- ScopedObject o(scope, v4engine->newObject());
- ScopedString s(scope);
- for (int ii = 0; ii < d->roleNames.keys().count(); ++ii) {
- Property *p = o->insertMember((s = v4engine->newIdentifier(d->roleNames[Qt::UserRole + ii + 1])), PropertyAttributes());
- p->value = v8engine->fromVariant(data(index(idx, 0), Qt::UserRole + ii + 1));
- }
-
- return QQmlV4Handle(o);
-}
-
-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
deleted file mode 100644
index 31058bbf78..0000000000
--- a/src/imports/dialogs-private/qquickwritingsystemlistmodel_p.h
+++ /dev/null
@@ -1,100 +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 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/qabstractitemmodel.h>
-#include <QtQml/qqmlparserstatus.h>
-#include <private/qv8engine_p.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 QQmlV4Handle 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
deleted file mode 100644
index 4913e332d7..0000000000
--- a/src/imports/dialogs/DefaultColorDialog.qml
+++ /dev/null
@@ -1,362 +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 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.0
-import "qml"
-
-AbstractColorDialog {
- id: root
- property bool __valueSet: true // guard to prevent binding loops
- function __setControlsFromColor() {
- __valueSet = false
- 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
- }
- onCurrentColorChanged: __setControlsFromColor()
- onSelectionAccepted: root.color = root.currentColor
-
- Rectangle {
- id: content
- property int maxSize: 0.9 * Math.min(Screen.desktopAvailableWidth, Screen.desktopAvailableHeight)
- implicitHeight: Math.min(maxSize, Screen.pixelDensity * (usePaletteMap ? 100 : 50))
- implicitWidth: usePaletteMap ? implicitHeight - bottomMinHeight : implicitHeight * 1.5
- color: palette.window
- focus: root.visible
- property real bottomMinHeight: sliders.height + buttonRow.height + outerSpacing * 3
- property real spacing: 8
- property real outerSpacing: 12
- property bool usePaletteMap: true
-
- Keys.onPressed: {
- event.accepted = true
- switch (event.key) {
- case Qt.Key_Return:
- case Qt.Key_Select:
- accept()
- break
- case Qt.Key_Escape:
- case Qt.Key_Back:
- reject()
- break
- case Qt.Key_C:
- if (event.modifiers & Qt.ControlModifier)
- colorField.copyAll()
- break
- case Qt.Key_V:
- if (event.modifiers & Qt.ControlModifier) {
- colorField.paste()
- root.currentColor = colorField.text
- }
- break
- default:
- // do nothing
- event.accepted = false
- break
- }
- }
-
- // set the preferred width based on height, to avoid "letterboxing" the paletteMap
- onHeightChanged: implicitHeight = Math.max((usePaletteMap ? 480 : bottomMinHeight), height)
-
- SystemPalette { id: palette }
-
- Item {
- id: paletteFrame
- visible: content.usePaletteMap
- anchors {
- top: parent.top
- left: parent.left
- right: parent.right
- margins: content.outerSpacing
- }
- height: Math.min(content.height - content.bottomMinHeight, content.width - content.outerSpacing * 2)
-
- Image {
- id: paletteMap
- x: (parent.width - width) / 2
- width: height
- onWidthChanged: root.__setControlsFromColor()
- height: parent.height
- source: "images/checkers.png"
- fillMode: Image.Tile
-
- // note we smoothscale the shader from a smaller version to improve performance
- ShaderEffect {
- id: map
- width: 64
- height: 64
- opacity: alphaSlider.value
- scale: paletteMap.width / width;
- layer.enabled: true
- layer.smooth: true
- anchors.centerIn: parent
- property real hue: hueSlider.value
-
- fragmentShader: "
- varying mediump vec2 qt_TexCoord0;
- uniform highp float qt_Opacity;
- uniform highp float hue;
-
- highp float hueToIntensity(highp float v1, highp float v2, highp float h) {
- h = fract(h);
- if (h < 1.0 / 6.0)
- return v1 + (v2 - v1) * 6.0 * h;
- else if (h < 1.0 / 2.0)
- return v2;
- else if (h < 2.0 / 3.0)
- return v1 + (v2 - v1) * 6.0 * (2.0 / 3.0 - h);
-
- return v1;
- }
-
- highp vec3 HSLtoRGB(highp vec3 color) {
- highp float h = color.x;
- highp float l = color.z;
- highp float s = color.y;
-
- if (s < 1.0 / 256.0)
- return vec3(l, l, l);
-
- highp float v1;
- highp float v2;
- if (l < 0.5)
- v2 = l * (1.0 + s);
- else
- v2 = (l + s) - (s * l);
-
- v1 = 2.0 * l - v2;
-
- highp float d = 1.0 / 3.0;
- highp float r = hueToIntensity(v1, v2, h + d);
- highp float g = hueToIntensity(v1, v2, h);
- highp float b = hueToIntensity(v1, v2, h - d);
- return vec3(r, g, b);
- }
-
- void main() {
- lowp vec4 c = vec4(1.0);
- c.rgb = HSLtoRGB(vec3(hue, 1.0 - qt_TexCoord0.t, qt_TexCoord0.s));
- gl_FragColor = c * qt_Opacity;
- }
- "
- }
-
- MouseArea {
- id: mapMouseArea
- anchors.fill: parent
- onPositionChanged: {
- if (pressed && containsMouse) {
- var xx = Math.max(0, Math.min(mouse.x, parent.width))
- var yy = Math.max(0, Math.min(mouse.y, parent.height))
- saturationSlider.value = 1.0 - yy / parent.height
- lightnessSlider.value = xx / parent.width
- // TODO if we constrain the movement here, can avoid the containsMouse test
- crosshairs.x = mouse.x - crosshairs.radius
- crosshairs.y = mouse.y - crosshairs.radius
- }
- }
- onPressed: positionChanged(mouse)
- }
-
- Image {
- id: crosshairs
- property int radius: width / 2 // truncated to int
- source: "images/crosshairs.png"
- }
-
- BorderImage {
- anchors.fill: parent
- anchors.margins: -1
- anchors.leftMargin: -2
- source: "images/sunken_frame.png"
- border.left: 8
- border.right: 8
- border.top: 8
- border.bottom: 8
- }
- }
- }
-
- Column {
- id: sliders
- anchors {
- top: paletteFrame.bottom
- left: parent.left
- right: parent.right
- margins: content.outerSpacing
- }
- spacing: content.spacing
-
- ColorSlider {
- id: hueSlider
- value: 0.5
- onValueChanged: if (__valueSet) root.currentColor = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
- text: qsTr("Hue")
- trackDelegate: Rectangle {
- rotation: -90
- transformOrigin: Item.TopLeft
- gradient: Gradient {
- GradientStop {position: 0.000; color: Qt.rgba(1, 0, 0, 1)}
- GradientStop {position: 0.167; color: Qt.rgba(1, 1, 0, 1)}
- GradientStop {position: 0.333; color: Qt.rgba(0, 1, 0, 1)}
- GradientStop {position: 0.500; color: Qt.rgba(0, 1, 1, 1)}
- GradientStop {position: 0.667; color: Qt.rgba(0, 0, 1, 1)}
- GradientStop {position: 0.833; color: Qt.rgba(1, 0, 1, 1)}
- GradientStop {position: 1.000; color: Qt.rgba(1, 0, 0, 1)}
- }
- }
- }
-
- ColorSlider {
- id: saturationSlider
- visible: !content.usePaletteMap
- value: 0.5
- onValueChanged: if (__valueSet) root.currentColor = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
- text: qsTr("Saturation")
- trackDelegate: Rectangle {
- rotation: -90
- transformOrigin: Item.TopLeft
- gradient: Gradient {
- GradientStop { position: 0; color: Qt.hsla(hueSlider.value, 0.0, lightnessSlider.value, 1.0) }
- GradientStop { position: 1; color: Qt.hsla(hueSlider.value, 1.0, lightnessSlider.value, 1.0) }
- }
- }
- }
-
- ColorSlider {
- id: lightnessSlider
- visible: !content.usePaletteMap
- value: 0.5
- onValueChanged: if (__valueSet) root.currentColor = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
- text: qsTr("Luminosity")
- trackDelegate: Rectangle {
- rotation: -90
- transformOrigin: Item.TopLeft
- gradient: Gradient {
- GradientStop { position: 0; color: "black" }
- GradientStop { position: 0.5; color: Qt.hsla(hueSlider.value, saturationSlider.value, 0.5, 1.0) }
- GradientStop { position: 1; color: "white" }
- }
- }
- }
-
- ColorSlider {
- id: alphaSlider
- minimum: 0.0
- maximum: 1.0
- value: 1.0
- onValueChanged: if (__valueSet) root.currentColor = Qt.hsla(hueSlider.value, saturationSlider.value, lightnessSlider.value, alphaSlider.value)
- text: qsTr("Alpha")
- visible: root.showAlphaChannel
- trackDelegate: Item {
- rotation: -90
- transformOrigin: Item.TopLeft
- Image {
- anchors {fill: parent}
- source: "images/checkers.png"
- fillMode: Image.TileVertically
- }
- Rectangle {
- anchors.fill: parent
- gradient: Gradient {
- GradientStop { position: 0; color: "transparent" }
- GradientStop { position: 1; color: Qt.hsla(hueSlider.value,
- saturationSlider.value,
- lightnessSlider.value, 1.0) }
- } }
- }
- }
- }
-
- Item {
- id: buttonRow
- height: Math.max(buttonsOnly.height, copyIcon.height)
- width: parent.width
- anchors {
- left: parent.left
- right: parent.right
- bottom: content.bottom
- margins: content.outerSpacing
- }
- Row {
- spacing: content.spacing
- height: parent.height
- TextField {
- id: colorField
- text: root.currentColor.toString()
- anchors.verticalCenter: parent.verticalCenter
- onAccepted: root.currentColor = text
- Component.onCompleted: width = implicitWidth + 10
- }
- Image {
- id: copyIcon
- anchors.verticalCenter: parent.verticalCenter
- source: "images/copy.png"
- MouseArea {
- anchors.fill: parent
- onClicked: colorField.copyAll()
- }
- }
- }
- Row {
- id: buttonsOnly
- spacing: content.spacing
- anchors.right: parent.right
- Button {
- id: cancelButton
- text: "Cancel"
- onClicked: root.reject()
- }
- Button {
- id: okButton
- text: "OK"
- onClicked: root.accept()
- }
- }
- }
- }
-}
diff --git a/src/imports/dialogs/DefaultFileDialog.qml b/src/imports/dialogs/DefaultFileDialog.qml
deleted file mode 100644
index 627a719f60..0000000000
--- a/src/imports/dialogs/DefaultFileDialog.qml
+++ /dev/null
@@ -1,394 +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 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.Dialogs 1.0
-import QtQuick.Window 2.1
-import Qt.labs.folderlistmodel 2.0
-import "qml"
-
-AbstractFileDialog {
- id: root
- onVisibleChanged: {
- if (visible) {
- __selectedIndices = []
- __lastClickedIdx = -1
- currentPathField.visible = false
- }
- }
- onFolderChanged: {
- var str = new String(folder)
- if (str.indexOf("qrc:") === 0)
- folder = "file:" + str.slice(4)
- if (view.model.folder != folder)
- view.model.folder = folder
- }
-
- property real __textX: titleBar.height
- property SystemPalette __palette
- property var __selectedIndices: []
- property int __lastClickedIdx: -1
-
- function __dirDown(path) {
- view.model.folder = "file://" + path
- __lastClickedIdx = -1
- __selectedIndices = []
- }
- function __dirUp() {
- if (view.model.parentFolder == "")
- view.model.folder = "file:///"
- else
- view.model.folder = view.model.parentFolder
- __lastClickedIdx = -1
- __selectedIndices = []
- }
- function __up(extend) {
- if (view.currentIndex > 0)
- --view.currentIndex
- else
- view.currentIndex = 0
- if (extend) {
- if (__selectedIndices.indexOf(view.currentIndex) < 0) {
- var selCopy = __selectedIndices
- selCopy.push(view.currentIndex)
- __selectedIndices = selCopy
- }
- } else
- __selectedIndices = [view.currentIndex]
- }
- function __down(extend) {
- if (view.currentIndex < view.model.count - 1)
- ++view.currentIndex
- else
- view.currentIndex = view.model.count - 1
- if (extend) {
- if (__selectedIndices.indexOf(view.currentIndex) < 0) {
- var selCopy = __selectedIndices
- selCopy.push(view.currentIndex)
- __selectedIndices = selCopy
- }
- } else
- __selectedIndices = [view.currentIndex]
- }
- function __acceptSelection() {
- clearSelection()
- if (selectFolder && __selectedIndices.length == 0)
- addSelection(folder)
- else if (__selectedIndices.length > 0) {
- __selectedIndices.map(function(idx) {
- if (view.model.isFolder(idx)) {
- if (selectFolder)
- addSelection(view.model.get(idx, "fileURL"))
- } else {
- if (!selectFolder)
- addSelection(view.model.get(idx, "fileURL"))
- }
- })
- } else {
- addSelection(pathToUrl(currentPathField.text))
- }
- accept()
- }
-
- Rectangle {
- id: content
- property int maxSize: Math.min(Screen.desktopAvailableWidth, Screen.desktopAvailableHeight)
- // TODO: QTBUG-29817 geometry from AbstractFileDialog
- implicitWidth: Math.min(maxSize, Screen.pixelDensity * 100)
- implicitHeight: Math.min(maxSize, Screen.pixelDensity * 80)
- color: __palette.window
- focus: root.visible && !currentPathField.visible
- property real spacing: 6
- property real outerSpacing: 12
- SystemPalette { id: __palette }
-
- Component {
- id: folderDelegate
- Rectangle {
- id: wrapper
- function launch() {
- if (view.model.isFolder(index)) {
- __dirDown(filePath)
- } else {
- root.__acceptSelection()
- }
- }
- width: content.width
- height: nameText.implicitHeight * 1.5
- color: "transparent"
- Rectangle {
- id: itemHighlight
- visible: root.__selectedIndices.indexOf(index) >= 0
- anchors.fill: parent
- color: __palette.highlight
- }
- Image {
- id: icon
- source: "images/folder.png"
- height: wrapper.height - y * 2; width: height
- x: (root.__textX - width) / 2
- y: 2
- visible: view.model.isFolder(index)
- }
- Text {
- id: nameText
- anchors.fill: parent; verticalAlignment: Text.AlignVCenter
- text: fileName
- anchors.leftMargin: root.__textX
- color: itemHighlight.visible ? __palette.highlightedText : __palette.windowText
- elide: Text.ElideRight
- }
- MouseArea {
- id: mouseRegion
- anchors.fill: parent
- onDoubleClicked: {
- __selectedIndices = [index]
- root.__lastClickedIdx = index
- launch()
- }
- onClicked: {
- view.currentIndex = index
- if (mouse.modifiers & Qt.ControlModifier && root.selectMultiple) {
- // modifying the contents of __selectedIndices doesn't notify,
- // so we have to re-assign the variable
- var selCopy = __selectedIndices
- var existingIdx = selCopy.indexOf(index)
- if (existingIdx >= 0)
- selCopy.splice(existingIdx, 1)
- else
- selCopy.push(index)
- __selectedIndices = selCopy
- } else if (mouse.modifiers & Qt.ShiftModifier && root.selectMultiple) {
- if (root.__lastClickedIdx >= 0) {
- var sel = []
- if (index > __lastClickedIdx) {
- for (var i = root.__lastClickedIdx; i <= index; i++)
- sel.push(i)
- } else {
- for (var i = root.__lastClickedIdx; i >= index; i--)
- sel.push(i)
- }
- __selectedIndices = sel
- }
- } else {
- __selectedIndices = [index]
- root.__lastClickedIdx = index
- }
- }
- }
- }
- }
-
- Keys.onPressed: {
- event.accepted = true
- switch (event.key) {
- case Qt.Key_Up:
- root.__up(event.modifiers & Qt.ShiftModifier && root.selectMultiple)
- break
- case Qt.Key_Down:
- root.__down(event.modifiers & Qt.ShiftModifier && root.selectMultiple)
- break
- case Qt.Key_Left:
- root.__dirUp()
- break
- case Qt.Key_Return:
- case Qt.Key_Select:
- case Qt.Key_Right:
- if (view.currentItem)
- view.currentItem.launch()
- else
- root.__acceptSelection()
- break
- case Qt.Key_Back:
- case Qt.Key_Escape:
- reject()
- break
- case Qt.Key_C:
- if (event.modifiers & Qt.ControlModifier)
- currentPathField.copyAll()
- break
- case Qt.Key_V:
- if (event.modifiers & Qt.ControlModifier) {
- currentPathField.visible = true
- currentPathField.paste()
- }
- break
- default:
- // do nothing
- event.accepted = false
- break
- }
- }
-
- ListView {
- id: view
- anchors.top: titleBar.bottom
- anchors.bottom: bottomBar.top
- clip: true
- x: 0
- width: parent.width
- model: FolderListModel {
- onFolderChanged: {
- root.folder = folder
- currentPathField.text = root.urlToPath(view.model.folder)
- }
- }
- delegate: folderDelegate
- highlight: Rectangle {
- color: "transparent"
- border.color: Qt.darker(__palette.window, 1.3)
- }
- highlightMoveDuration: 0
- highlightMoveVelocity: -1
- }
-
- MouseArea {
- anchors.fill: view
- enabled: currentPathField.visible
- onClicked: currentPathField.visible = false
- }
-
-
- Item {
- id: titleBar
- width: parent.width
- height: currentPathField.height * 1.5
- Rectangle {
- anchors.fill: parent
- color: Qt.darker(__palette.window, 1.1)
- border.color: Qt.darker(__palette.window, 1.3)
- }
- Rectangle {
- id: upButton
- width: root.__textX
- height: titleBar.height
- color: "transparent"
-
- Image {
- id: upButtonImage
- anchors.centerIn: parent; source: "images/up.png"
- }
- MouseArea { id: upRegion; anchors.centerIn: parent
- width: 56
- height: parent.height
- onClicked: if (view.model.parentFolder !== "") __dirUp()
- }
- states: [
- State {
- name: "pressed"
- when: upRegion.pressed
- PropertyChanges { target: upButton; color: __palette.highlight }
- }
- ]
- }
- Text {
- id: currentPathText
- anchors.left: parent.left; anchors.right: parent.right; anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: __textX; anchors.rightMargin: content.spacing
- text: root.urlToPath(view.model.folder)
- color: __palette.text
- elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
- MouseArea {
- anchors.fill: parent
- onClicked: currentPathField.visible = true
- }
- }
- TextField {
- id: currentPathField
- anchors.left: parent.left; anchors.right: parent.right; anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: __textX; anchors.rightMargin: content.spacing
- visible: false
- focus: visible
- onAccepted: {
- root.clearSelection()
- if (root.addSelection(root.pathToUrl(text)))
- root.accept()
- else
- view.model.folder = root.pathFolder(text)
- }
- onDownPressed: currentPathField.visible = false
- onBackPressed: reject()
- onEscapePressed: reject()
- }
- }
- Rectangle {
- id: bottomBar
- width: parent.width
- height: buttonRow.height + buttonRow.spacing * 2
- anchors.bottom: parent.bottom
- color: Qt.darker(__palette.window, 1.1)
- border.color: Qt.darker(__palette.window, 1.3)
-
- Row {
- id: buttonRow
- anchors.right: parent.right
- anchors.rightMargin: spacing
- anchors.verticalCenter: parent.verticalCenter
- spacing: content.spacing
- TextField {
- id: filterField
- text: root.selectedNameFilter
- visible: !selectFolder
- width: bottomBar.width - cancelButton.width - okButton.width - parent.spacing * 5
- anchors.verticalCenter: parent.verticalCenter
- onAccepted: {
- root.selectNameFilter(text)
- view.model.nameFilters = text
- }
- }
- Button {
- id: cancelButton
- text: "Cancel"
- onClicked: root.reject()
- }
- Button {
- id: okButton
- text: "OK"
- onClicked: {
- if (view.model.isFolder(view.currentIndex) && !selectFolder)
- __dirDown(view.model.get(view.currentIndex, "filePath"))
- else
- root.__acceptSelection()
- }
- }
- }
- }
- }
-}
diff --git a/src/imports/dialogs/DefaultFontDialog.qml b/src/imports/dialogs/DefaultFontDialog.qml
deleted file mode 100644
index 29feed342f..0000000000
--- a/src/imports/dialogs/DefaultFontDialog.qml
+++ /dev/null
@@ -1,483 +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 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
- implicitWidth: Math.min(Screen.desktopAvailableWidth, implicitHeight * 1.2)
- implicitHeight: Math.min(Screen.desktopAvailableHeight, settingsBottom.implicitHeight * 3)
- color: palette.window
- focus: root.visible
- property real spacing: 6
- property real outerSpacing: 12
- property real listMargins: 4
- property real delegateHeightMultiplier: 1.5
- property real extraWidth: width > 400 ? width - 400 : 0
- property real extraHeight: height > initialHeight ? height - initialHeight : 0
- property real initialHeight: -1
- onHeightChanged: if (visible && initialHeight < 0) initialHeight = height
-
- 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
-
- onFontChanged: externalFont = font
-
- onExternalFontChanged: {
- if (content.font != content.externalFont) {
- font = externalFont
- wsListView.reset()
- fontListView.reset()
- weightListView.reset()
- }
- }
-
- Keys.onPressed: {
- event.accepted = true
- switch (event.key) {
- case Qt.Key_Return:
- case Qt.Key_Select:
- root.font = content.font
- root.accept()
- break
- case Qt.Key_Escape:
- case Qt.Key_Back:
- reject()
- break
- default:
- // do nothing
- event.accepted = false
- break
- }
- }
-
- SystemPalette { id: palette }
-
- Column {
- id: contentColumn
- anchors.fill: parent
- anchors.margins: content.outerSpacing
- spacing: content.outerSpacing
-
- Grid {
- id: settingsTop
- columns: 3
- spacing: content.spacing
- width: parent.width
- height: parent.height - buttonRow.height - settingsBottom.height - parent.spacing * 2
- property real columnHeight: height - writingSystemLabel.height - spacing
-
- Text { id: writingSystemLabel; text: qsTr("Writing System"); font.bold: true }
- Text { id: fontNameLabel; text: qsTr("Font"); font.bold: true }
- Text { id: sizeLabel; text: qsTr("Size"); font.bold: true }
- Rectangle {
- id: wsColumn
- radius: 3
- color: palette.window
- border.color: content.borderColor
- implicitWidth: Math.max(writingSystemLabel.implicitWidth, 100) + content.extraWidth / 5
- height: parent.columnHeight
- clip: true
- ListView {
- id: wsListView
- anchors.fill: parent
- anchors.margins: content.listMargins
- anchors.topMargin: 2
- highlightMoveDuration: 0
- onHeightChanged: positionViewAtIndex(currentIndex, ListView.Contain)
- 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 * content.delegateHeightMultiplier
- Text {
- id: wsText
- text: name
- width: parent.width
- elide: Text.ElideRight
- color: index === wsListView.currentIndex ? palette.highlightedText : palette.windowText
- anchors.verticalCenter: parent.verticalCenter
- }
- 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, parent.width - wsColumn.implicitWidth - pointSizesColumn.implicitWidth - parent.spacing * 2)
- height: parent.columnHeight
- clip: true
- ListView {
- id: fontListView
- anchors.fill: parent
- anchors.margins: content.listMargins
- anchors.topMargin: 2
- highlightMoveDuration: 0
- onHeightChanged: positionViewAtIndex(currentIndex, ListView.Contain)
- 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 * content.delegateHeightMultiplier
- Text {
- id: fontText
- text: family
- width: parent.width
- elide: Text.ElideRight
- color: index === fontListView.currentIndex ? palette.highlightedText : palette.windowText
- anchors.verticalCenter: parent.verticalCenter
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- fontListView.currentIndex = index
- content.font.family = fontModel.get(fontListView.currentIndex).family
- }
- }
- }
- }
- }
- Rectangle {
- id: pointSizesColumn
- radius: 3
- color: palette.window
- border.color: content.borderColor
- implicitWidth:sizeLabel.implicitWidth * 2
- height: parent.columnHeight
- clip: true
- ListView {
- id: pointSizesListView
- anchors.fill: parent
- anchors.margins: content.listMargins
- anchors.topMargin: 2
- highlightMoveDuration: 0
- onHeightChanged: positionViewAtIndex(currentIndex, ListView.Contain)
- model: content.pointSizes
- highlight: Rectangle {
- color: palette.highlight
- x: 2 - pointSizesListView.anchors.margins
- width: pointSizesListView.parent.width - 4
- }
- delegate: Item {
- width: parent.width
- height: pointSizesText.height * content.delegateHeightMultiplier
- Text {
- id: pointSizesText
- text: content.pointSizes[index]
- width: parent.width
- elide: Text.ElideRight
- color: index === pointSizesListView.currentIndex ? palette.highlightedText : palette.windowText
- anchors.verticalCenter: parent.verticalCenter
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- pointSizesListView.currentIndex = index
- content.font.pointSize = content.pointSizes[pointSizesListView.currentIndex]
- }
- }
- }
- }
- }
- }
-
- Grid {
- id: settingsBottom
- columns: 3
- spacing: content.spacing
- width: parent.width
- height: initialHeight + content.extraHeight / 4
- property real initialHeight
- property real secondRowHeight: height - weightLabel.height - spacing
- Component.onCompleted: initialHeight = implicitHeight
-
- Text { id: weightLabel; text: qsTr("Weight"); font.bold: true }
- Text { id: optionsLabel; text: qsTr("Style"); font.bold: true }
- Text { id: sampleLabel; text: qsTr("Sample"); font.bold: true }
- Rectangle {
- id: weightColumn
- radius: 3
- color: palette.window
- border.color: content.borderColor
- implicitWidth: optionsColumn.implicitWidth
- implicitHeight: optionsColumn.implicitHeight
- height: parent.secondRowHeight
- clip: true
- ListView {
- id: weightListView
- anchors.fill: parent
- anchors.margins: content.listMargins
- anchors.topMargin: 2
- highlightMoveDuration: 0
- onHeightChanged: positionViewAtIndex(currentIndex, ListView.Contain)
- 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 * content.delegateHeightMultiplier
- Text {
- id: weightText
- text: name
- width: parent.width
- elide: Text.ElideRight
- color: index === weightListView.currentIndex ? palette.highlightedText : palette.windowText
- anchors.verticalCenter: parent.verticalCenter
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- weightListView.currentIndex = index
- content.font.weight = weightModel.get(weightListView.currentIndex).weight
- }
- }
- }
- }
- }
- Column {
- id: optionsColumn
- spacing: 4
- 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 {
- clip: true
- implicitWidth: sample.implicitWidth + parent.spacing
- implicitHeight: optionsColumn.implicitHeight
- width: parent.width - weightColumn.width - optionsColumn.width - parent.spacing * 2
- height: parent.secondRowHeight
- 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
- Row {
- id: buttonsOnly
- spacing: content.spacing
- anchors.right: parent.right
- Button {
- text: qsTr("Cancel")
- onClicked: root.reject()
- }
- Button {
- text: qsTr("OK")
- onClicked: {
- root.font = content.font
- root.accept()
- }
- }
- }
- }
- }
- }
-}
-
diff --git a/src/imports/dialogs/DefaultMessageDialog.qml b/src/imports/dialogs/DefaultMessageDialog.qml
deleted file mode 100644
index ba29469b5e..0000000000
--- a/src/imports/dialogs/DefaultMessageDialog.qml
+++ /dev/null
@@ -1,330 +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 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: 6
- property real outerSpacing: 12
- property real buttonsRowImplicitWidth: Screen.pixelDensity * 50
- implicitHeight: contentColumn.implicitHeight + outerSpacing * 2
- onImplicitHeightChanged: root.height = implicitHeight
- implicitWidth: Math.min(Screen.desktopAvailableWidth * 0.9, Math.max(
- mainText.implicitWidth, buttonsRowImplicitWidth) + outerSpacing * 2);
- onImplicitWidthChanged: root.width = implicitWidth
- color: palette.window
- focus: root.visible
- Keys.onPressed: {
- event.accepted = true
- if (event.modifiers === Qt.ControlModifier)
- switch (event.key) {
- case Qt.Key_A:
- detailedText.selectAll()
- break
- case Qt.Key_C:
- detailedText.copy()
- break
- } else switch (event.key) {
- case Qt.Key_Escape:
- case Qt.Key_Back:
- reject()
- break
- case Qt.Key_Enter:
- case Qt.Key_Return:
- accept()
- 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
- }
- }
-
-
- Flow {
- id: buttons
- spacing: content.spacing
- layoutDirection: Qt.RightToLeft
- width: parent.width + content.outerSpacing
- x: -content.outerSpacing
- Button {
- id: okButton
- text: "OK"
- onClicked: root.click(StandardButton.Ok)
- visible: root.standardButtons & StandardButton.Ok
- }
- Button {
- id: openButton
- text: "Open"
- onClicked: root.click(StandardButton.Open)
- visible: root.standardButtons & StandardButton.Open
- }
- Button {
- id: saveButton
- text: "Save"
- onClicked: root.click(StandardButton.Save)
- visible: root.standardButtons & StandardButton.Save
- }
- Button {
- id: saveAllButton
- text: "Save All"
- onClicked: root.click(StandardButton.SaveAll)
- visible: root.standardButtons & StandardButton.SaveAll
- }
- Button {
- id: retryButton
- text: "Retry"
- onClicked: root.click(StandardButton.Retry)
- visible: root.standardButtons & StandardButton.Retry
- }
- Button {
- id: ignoreButton
- text: "Ignore"
- onClicked: root.click(StandardButton.Ignore)
- visible: root.standardButtons & StandardButton.Ignore
- }
- Button {
- id: applyButton
- text: "Apply"
- onClicked: root.click(StandardButton.Apply)
- visible: root.standardButtons & StandardButton.Apply
- }
- Button {
- id: yesButton
- text: "Yes"
- onClicked: root.click(StandardButton.Yes)
- visible: root.standardButtons & StandardButton.Yes
- }
- Button {
- id: yesAllButton
- text: "Yes to All"
- onClicked: root.click(StandardButton.YesToAll)
- visible: root.standardButtons & StandardButton.YesToAll
- }
- Button {
- id: noButton
- text: "No"
- onClicked: root.click(StandardButton.No)
- visible: root.standardButtons & StandardButton.No
- }
- Button {
- id: noAllButton
- text: "No to All"
- onClicked: root.click(StandardButton.NoToAll)
- visible: root.standardButtons & StandardButton.NoToAll
- }
- Button {
- id: discardButton
- text: "Discard"
- onClicked: root.click(StandardButton.Discard)
- visible: root.standardButtons & StandardButton.Discard
- }
- Button {
- id: resetButton
- text: "Reset"
- onClicked: root.click(StandardButton.Reset)
- visible: root.standardButtons & StandardButton.Reset
- }
- Button {
- id: restoreDefaultsButton
- text: "Restore Defaults"
- onClicked: root.click(StandardButton.RestoreDefaults)
- visible: root.standardButtons & StandardButton.RestoreDefaults
- }
- Button {
- id: cancelButton
- text: "Cancel"
- onClicked: root.click(StandardButton.Cancel)
- visible: root.standardButtons & StandardButton.Cancel
- }
- Button {
- id: abortButton
- text: "Abort"
- onClicked: root.click(StandardButton.Abort)
- visible: root.standardButtons & StandardButton.Abort
- }
- Button {
- id: closeButton
- text: "Close"
- onClicked: root.click(StandardButton.Close)
- visible: root.standardButtons & StandardButton.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(StandardButton.Help)
- visible: root.standardButtons & StandardButton.Help
- }
- onVisibleChildrenChanged: calculateImplicitWidth()
- }
- }
-
- 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"
- }
- }
- ]
- }
- function calculateImplicitWidth() {
- if (buttons.visibleChildren.length < 2)
- return;
- var calcWidth = 0;
- for (var i = 0; i < buttons.visibleChildren.length; ++i)
- calcWidth += Math.max(100, buttons.visibleChildren[i].implicitWidth) + content.spacing
- content.buttonsRowImplicitWidth = content.outerSpacing + calcWidth
- }
- Component.onCompleted: calculateImplicitWidth()
-}
diff --git a/src/imports/dialogs/WidgetColorDialog.qml b/src/imports/dialogs/WidgetColorDialog.qml
deleted file mode 100644
index ed7c7ab77a..0000000000
--- a/src/imports/dialogs/WidgetColorDialog.qml
+++ /dev/null
@@ -1,44 +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 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.0
-
-QtColorDialog { }
diff --git a/src/imports/dialogs/WidgetFileDialog.qml b/src/imports/dialogs/WidgetFileDialog.qml
deleted file mode 100644
index c8f59d20a7..0000000000
--- a/src/imports/dialogs/WidgetFileDialog.qml
+++ /dev/null
@@ -1,44 +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 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.0
-
-QtFileDialog { }
diff --git a/src/imports/dialogs/WidgetFontDialog.qml b/src/imports/dialogs/WidgetFontDialog.qml
deleted file mode 100644
index 69f98b28a2..0000000000
--- a/src/imports/dialogs/WidgetFontDialog.qml
+++ /dev/null
@@ -1,44 +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 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
deleted file mode 100644
index 8bc3eccfd7..0000000000
--- a/src/imports/dialogs/WidgetMessageDialog.qml
+++ /dev/null
@@ -1,44 +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 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
deleted file mode 100644
index 1abad55883..0000000000
--- a/src/imports/dialogs/dialogs.pro
+++ /dev/null
@@ -1,97 +0,0 @@
-CXX_MODULE = qml
-TARGET = dialogplugin
-TARGETPATH = QtQuick/Dialogs
-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 \
- qquickdialogassets_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
-
-DIALOGS_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 \
- images/sunken_frame.png \
- images/window_border.png \
- images/folder.png \
- images/up.png
-
-QT += quick-private gui gui-private core core-private qml
-
-# Create the resource file
-GENERATED_RESOURCE_FILE = $$OUT_PWD/dialogs.qrc
-
-RESOURCE_CONTENT = \
- "<RCC>" \
- "<qresource prefix=\"/QtQuick/Dialogs\">"
-
-for(resourcefile, DIALOGS_QML_FILES) {
- resourcefileabsolutepath = $$absolute_path($$resourcefile)
- relativepath_in = $$relative_path($$resourcefileabsolutepath, $$_PRO_FILE_PWD_)
- relativepath_out = $$relative_path($$resourcefileabsolutepath, $$OUT_PWD)
- RESOURCE_CONTENT += "<file alias=\"$$relativepath_in\">$$relativepath_out</file>"
-}
-
-RESOURCE_CONTENT += \
- "</qresource>" \
- "</RCC>"
-
-write_file($$GENERATED_RESOURCE_FILE, RESOURCE_CONTENT)|error("Aborting.")
-
-RESOURCES += $$GENERATED_RESOURCE_FILE
-
-# In case of a debug build, deploy the QML files too
-CONFIG(debug, debug|release): QML_FILES += $$DIALOGS_QML_FILES
-
-load(qml_plugin)
diff --git a/src/imports/dialogs/doc/images/critical.png b/src/imports/dialogs/doc/images/critical.png
deleted file mode 100644
index dc9c5aebf4..0000000000
--- a/src/imports/dialogs/doc/images/critical.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/doc/images/information.png b/src/imports/dialogs/doc/images/information.png
deleted file mode 100644
index 0a2eb87d10..0000000000
--- a/src/imports/dialogs/doc/images/information.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/doc/images/question.png b/src/imports/dialogs/doc/images/question.png
deleted file mode 100644
index 2dd92fd791..0000000000
--- a/src/imports/dialogs/doc/images/question.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/doc/images/replacefile.png b/src/imports/dialogs/doc/images/replacefile.png
deleted file mode 100644
index d1479fa944..0000000000
--- a/src/imports/dialogs/doc/images/replacefile.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/doc/images/warning.png b/src/imports/dialogs/doc/images/warning.png
deleted file mode 100644
index cba78f6bea..0000000000
--- a/src/imports/dialogs/doc/images/warning.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/doc/qtquickdialogs.qdocconf b/src/imports/dialogs/doc/qtquickdialogs.qdocconf
deleted file mode 100644
index 1bad67790f..0000000000
--- a/src/imports/dialogs/doc/qtquickdialogs.qdocconf
+++ /dev/null
@@ -1,41 +0,0 @@
-include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
-
-project = QtQuickDialogs
-description = Qt Quick Dialogs Reference Documentation
-url = http://qt-project.org/doc/qt-$QT_VER
-version = $QT_VERSION
-
-qhp.projects = QtQuickDialogs
-
-qhp.QtQuickDialogs.file = qtquickdialogs.qhp
-qhp.QtQuickDialogs.namespace = org.qt-project.qtquickdialogs.$QT_VERSION_TAG
-qhp.QtQuickDialogs.virtualFolder = qtquickdialogs
-qhp.QtQuickDialogs.indexTitle = Qt Quick Dialogs
-qhp.QtQuickDialogs.indexRoot =
-
-qhp.QtQuickDialogs.filterAttributes = qtquickdialogs $QT_VERSION qtrefdoc
-qhp.QtQuickDialogs.customFilters.Qt.name = QtQuickDialogs $QT_VERSION
-qhp.QtQuickDialogs.customFilters.Qt.filterAttributes = qtquickdialogs $QT_VERSION
-
-qhp.QtQuickDialogs.subprojects = qtquickdialogsqmltypes
-qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.title = QML Types
-qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.indexTitle = Qt Quick Dialogs QML Types
-qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.selectors = fake:qmlclass
-qhp.QtQuickDialogs.subprojects.qtquickdialogsqmltypes.sortPages = true
-
-depends = qtqml qtquick qtgui qtwidgets qtdoc
-
-exampledirs += ../../../../examples/quick/dialogs
-
-examplesinstallpath = quick/dialogs
-
-headerdirs += ..
-
-sourcedirs += ..
-
-imagedirs += images
-
-excludedirs += ../qml
-
-navigation.landingpage = "Qt Quick Dialogs"
-navigation.qmltypespage = "Qt Quick Dialogs QML Types"
diff --git a/src/imports/dialogs/doc/src/qtquickdialogs-examples.qdoc b/src/imports/dialogs/doc/src/qtquickdialogs-examples.qdoc
deleted file mode 100644
index ee277f48dc..0000000000
--- a/src/imports/dialogs/doc/src/qtquickdialogs-examples.qdoc
+++ /dev/null
@@ -1,36 +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 documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** 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 Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \group qtquickdialog_examples
- \ingroup qtquickexamples
- \title Qt Quick Examples - Dialogs
- \brief A Collection of examples for \l{Qt Quick Dialogs}, written in QML.
-
- These examples show how to use the \l{Qt Quick Dialogs}.
-*/
-
diff --git a/src/imports/dialogs/doc/src/qtquickdialogs-index.qdoc b/src/imports/dialogs/doc/src/qtquickdialogs-index.qdoc
deleted file mode 100644
index 5a1223b04d..0000000000
--- a/src/imports/dialogs/doc/src/qtquickdialogs-index.qdoc
+++ /dev/null
@@ -1,58 +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 documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** 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 Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \group dialogs
- \title Dialogs
-*/
-
-/*!
- \page qtquickdialogs-index.html
- \title Qt Quick Dialogs
-
- \brief Qt Quick Dialogs submodule
-
- The module is new in Qt 5.1.
-
- \section1 Dialogs
-
- \annotatedlist dialogs
-
- \section1 Related information
-
- \section2 Examples
- \list
- \li \l{Qt Quick Examples - Dialogs}{Dialogs Examples}
- \endlist
-
- \section2 Reference
- \list
- \li \l{Qt Quick Dialogs QML Types}{QML Types}
- \endlist
-
-*/
-
diff --git a/src/imports/dialogs/images/checkers.png b/src/imports/dialogs/images/checkers.png
deleted file mode 100644
index 458d33de9d..0000000000
--- a/src/imports/dialogs/images/checkers.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/checkmark.png b/src/imports/dialogs/images/checkmark.png
deleted file mode 100644
index 821aafccdd..0000000000
--- a/src/imports/dialogs/images/checkmark.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/copy.png b/src/imports/dialogs/images/copy.png
deleted file mode 100644
index 2aeb28288f..0000000000
--- a/src/imports/dialogs/images/copy.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/critical.png b/src/imports/dialogs/images/critical.png
deleted file mode 100644
index dc9c5aebf4..0000000000
--- a/src/imports/dialogs/images/critical.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/crosshairs.png b/src/imports/dialogs/images/crosshairs.png
deleted file mode 100644
index 9a61946eca..0000000000
--- a/src/imports/dialogs/images/crosshairs.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/folder.png b/src/imports/dialogs/images/folder.png
deleted file mode 100644
index e53e2ad464..0000000000
--- a/src/imports/dialogs/images/folder.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/information.png b/src/imports/dialogs/images/information.png
deleted file mode 100644
index 0a2eb87d10..0000000000
--- a/src/imports/dialogs/images/information.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/question.png b/src/imports/dialogs/images/question.png
deleted file mode 100644
index 2dd92fd791..0000000000
--- a/src/imports/dialogs/images/question.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/slider_handle.png b/src/imports/dialogs/images/slider_handle.png
deleted file mode 100644
index e3b9654392..0000000000
--- a/src/imports/dialogs/images/slider_handle.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/sunken_frame.png b/src/imports/dialogs/images/sunken_frame.png
deleted file mode 100644
index 178c3092d2..0000000000
--- a/src/imports/dialogs/images/sunken_frame.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/up.png b/src/imports/dialogs/images/up.png
deleted file mode 100644
index b05f8025d0..0000000000
--- a/src/imports/dialogs/images/up.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/warning.png b/src/imports/dialogs/images/warning.png
deleted file mode 100644
index cba78f6bea..0000000000
--- a/src/imports/dialogs/images/warning.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/images/window_border.png b/src/imports/dialogs/images/window_border.png
deleted file mode 100644
index 431af8545d..0000000000
--- a/src/imports/dialogs/images/window_border.png
+++ /dev/null
Binary files differ
diff --git a/src/imports/dialogs/plugin.cpp b/src/imports/dialogs/plugin.cpp
deleted file mode 100644
index 70e12093b6..0000000000
--- a/src/imports/dialogs/plugin.cpp
+++ /dev/null
@@ -1,214 +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 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 <QtQml/qqml.h>
-#include <QtQml/qqmlextensionplugin.h>
-#include "qquickmessagedialog_p.h"
-#include "qquickabstractmessagedialog_p.h"
-#include "qquickdialogassets_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>
-
-//#define PURE_QML_ONLY
-//#define DEBUG_REGISTRATION
-
-static void initResources()
-{
- Q_INIT_RESOURCE(dialogs);
-}
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmlmodule QtQuick.Dialogs 1.1
- \title Qt Quick Dialogs QML Types
- \ingroup qmlmodules
- \brief Provides QML types for standard file, color picker and message dialogs
-
- This QML module contains types for creating and interacting with system dialogs.
-
- To use the types in this module, import the module with the following line:
-
- \code
- import QtQuick.Dialogs 1.1
- \endcode
-*/
-
-class QtQuick2DialogsPlugin : public QQmlExtensionPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
-
-public:
- QtQuick2DialogsPlugin() : QQmlExtensionPlugin(), m_useResources(true) { }
-
- virtual void initializeEngine(QQmlEngine *engine, const char * uri) {
-#ifdef DEBUG_REGISTRATION
- qDebug() << Q_FUNC_INFO << uri << m_decorationComponentUrl;
-#else
- Q_UNUSED(uri)
-#endif
- QQuickAbstractDialog::m_decorationComponent =
- new QQmlComponent(engine, m_decorationComponentUrl, QQmlComponent::Asynchronous);
- }
-
- virtual void registerTypes(const char *uri) {
- initResources();
-
-#ifdef DEBUG_REGISTRATION
- qDebug() << Q_FUNC_INFO << uri;
-#endif
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Dialogs"));
- bool hasTopLevelWindows = QGuiApplicationPrivate::platformIntegration()->
- hasCapability(QPlatformIntegration::MultipleWindows);
- QDir qmlDir(baseUrl().toLocalFile());
- QDir widgetsDir(baseUrl().toLocalFile());
- // TODO: find the directory by searching rather than assuming a relative path
- widgetsDir.cd("../PrivateWidgets");
-
- // If at least one file was actually installed, then use installed qml files instead of resources.
- // This makes debugging and incremental development easier, whereas the "normal" installation
- // uses resources to save space and cut down on the number of files to deploy.
- if (qmlDir.exists(QString("DefaultFileDialog.qml")))
- m_useResources = false;
- m_decorationComponentUrl = m_useResources ?
- QUrl("qrc:/QtQuick/Dialogs/qml/DefaultWindowDecoration.qml") :
- QUrl::fromLocalFile(qmlDir.filePath(QString("qml/DefaultWindowDecoration.qml")));
-
- // Prefer the QPA dialog helpers if the platform supports them.
- // Else if there is a QWidget-based implementation, check whether it's
- // possible to instantiate it from Qt Quick.
- // Otherwise fall back to a pure-QML implementation.
-
- // MessageDialog
- qmlRegisterUncreatableType<QQuickStandardButton>(uri, 1, 1, "StandardButton",
- QLatin1String("Do not create objects of type StandardButton"));
- qmlRegisterUncreatableType<QQuickStandardIcon>(uri, 1, 1, "StandardIcon",
- QLatin1String("Do not create objects of type StandardIcon"));
-#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))
- qmlRegisterType<QQuickPlatformFileDialog>(uri, 1, 0, "FileDialog");
- else
-#endif
- registerWidgetOrQmlImplementation<QQuickFileDialog>(widgetsDir, qmlDir, "FileDialog", uri, hasTopLevelWindows, 1, 0);
-
- // ColorDialog
-#ifndef PURE_QML_ONLY
- if (QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::ColorDialog))
- qmlRegisterType<QQuickPlatformColorDialog>(uri, 1, 0, "ColorDialog");
- 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:
- template <class WrapperType>
- void registerWidgetOrQmlImplementation(QDir widgetsDir, QDir qmlDir,
- const char *qmlName, const char *uri, bool hasTopLevelWindows, int versionMajor, int versionMinor) {
- // qDebug() << "QtQuick2DialogsPlugin::registerWidgetOrQmlImplementation" << uri << qmlName << ": QML in" << qmlDir.absolutePath()
- // << "using resources?" << m_useResources << "; widgets in" << widgetsDir.absolutePath();
- bool needQmlImplementation = true;
-
-#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") &&
- QCoreApplication::instance()->inherits("QApplication")) {
- QUrl dialogQmlPath = m_useResources ?
- QUrl(QString("qrc:/QtQuick/Dialogs/Widget%1.qml").arg(qmlName)) :
- QUrl::fromLocalFile(qmlDir.filePath(QString("Widget%1.qml").arg(qmlName)));
- if (qmlRegisterType(dialogQmlPath, uri, versionMajor, versionMinor, qmlName) >= 0) {
- needQmlImplementation = false;
-#ifdef DEBUG_REGISTRATION
- qDebug() << " registering" << qmlName << " as " << dialogQmlPath << "success?" << !needQmlImplementation;
-#endif
- }
- }
-#endif
- if (needQmlImplementation) {
- QByteArray abstractTypeName = QByteArray("Abstract") + qmlName;
- qmlRegisterType<WrapperType>(uri, versionMajor, versionMinor, abstractTypeName); // implementation wrapper
- QUrl dialogQmlPath = m_useResources ?
- QUrl(QString("qrc:/QtQuick/Dialogs/Default%1.qml").arg(qmlName)) :
- QUrl::fromLocalFile(qmlDir.filePath(QString("Default%1.qml").arg(qmlName)));
-#ifdef DEBUG_REGISTRATION
- qDebug() << " registering" << qmlName << " as " << dialogQmlPath << "success?" <<
-#endif
- qmlRegisterType(dialogQmlPath, uri, versionMajor, versionMinor, qmlName);
- }
- }
-
- QUrl m_decorationComponentUrl;
- bool m_useResources;
-};
-
-QT_END_NAMESPACE
-
-#include "plugin.moc"
diff --git a/src/imports/dialogs/plugins.qmltypes b/src/imports/dialogs/plugins.qmltypes
deleted file mode 100644
index d5db4b93bd..0000000000
--- a/src/imports/dialogs/plugins.qmltypes
+++ /dev/null
@@ -1,654 +0,0 @@
-import QtQuick.tooling 1.1
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -omit-prefix=__ QtQuick.Dialogs 1.1'
-
-Module {
- Component {
- name: "QQuickAbstractColorDialog"
- 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"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setModality"
- Parameter { name: "m"; type: "Qt::WindowModality" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "t"; type: "string" }
- }
- Method {
- name: "setColor"
- Parameter { name: "arg"; type: "QColor" }
- }
- Method {
- name: "setCurrentColor"
- Parameter { name: "currentColor"; type: "QColor" }
- }
- Method {
- name: "setShowAlphaChannel"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickAbstractDialog"
- prototype: "QObject"
- Property { name: "visible"; type: "bool" }
- Property { name: "modality"; type: "Qt::WindowModality" }
- Property { name: "title"; type: "string" }
- Property { name: "isWindow"; type: "bool"; isReadonly: true }
- Property { name: "x"; type: "int" }
- Property { name: "y"; type: "int" }
- Property { name: "width"; type: "int" }
- Property { name: "height"; type: "int" }
- Signal { name: "visibilityChanged" }
- Signal { name: "geometryChanged" }
- Signal { name: "accepted" }
- 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"
- prototype: "QQuickAbstractDialog"
- Property { name: "selectExisting"; type: "bool" }
- Property { name: "selectMultiple"; type: "bool" }
- Property { name: "selectFolder"; type: "bool" }
- Property { name: "folder"; type: "QUrl" }
- Property { name: "nameFilters"; type: "QStringList" }
- Property { name: "selectedNameFilter"; type: "string" }
- Property { name: "fileUrl"; type: "QUrl"; isReadonly: true }
- Property { name: "fileUrls"; type: "QList<QUrl>"; isReadonly: true }
- Signal { name: "filterSelected" }
- Signal { name: "fileModeChanged" }
- Signal { name: "selectionAccepted" }
- Method {
- name: "setVisible"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "t"; type: "string" }
- }
- Method {
- name: "setSelectExisting"
- Parameter { name: "s"; type: "bool" }
- }
- Method {
- name: "setSelectMultiple"
- Parameter { name: "s"; type: "bool" }
- }
- Method {
- name: "setSelectFolder"
- Parameter { name: "s"; type: "bool" }
- }
- Method {
- name: "setFolder"
- Parameter { name: "f"; type: "QUrl" }
- }
- Method {
- name: "setNameFilters"
- Parameter { name: "f"; type: "QStringList" }
- }
- Method {
- name: "selectNameFilter"
- Parameter { name: "f"; type: "string" }
- }
- }
- Component {
- name: "QQuickAbstractFontDialog"
- prototype: "QQuickAbstractDialog"
- Property { name: "scalableFonts"; type: "bool" }
- Property { name: "nonScalableFonts"; type: "bool" }
- Property { name: "monospacedFonts"; type: "bool" }
- Property { name: "proportionalFonts"; type: "bool" }
- Property { name: "font"; type: "QFont" }
- Signal { name: "selectionAccepted" }
- Method {
- name: "setVisible"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setModality"
- Parameter { name: "m"; type: "Qt::WindowModality" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "t"; type: "string" }
- }
- Method {
- name: "setFont"
- Parameter { name: "arg"; type: "QFont" }
- }
- Method {
- name: "setScalableFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setNonScalableFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setMonospacedFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setProportionalFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickAbstractMessageDialog"
- prototype: "QQuickAbstractDialog"
- Enum {
- name: "Icon"
- values: {
- "NoIcon": 0,
- "Information": 1,
- "Warning": 2,
- "Critical": 3,
- "Question": 4
- }
- }
- Enum {
- name: "StandardButton"
- values: {
- "NoButton": 0,
- "Ok": 1024,
- "Save": 2048,
- "SaveAll": 4096,
- "Open": 8192,
- "Yes": 16384,
- "YesToAll": 32768,
- "No": 65536,
- "NoToAll": 131072,
- "Abort": 262144,
- "Retry": 524288,
- "Ignore": 1048576,
- "Close": 2097152,
- "Cancel": 4194304,
- "Discard": 8388608,
- "Help": 16777216,
- "Apply": 33554432,
- "Reset": 67108864,
- "RestoreDefaults": 134217728
- }
- }
- Enum {
- name: "StandardButtons"
- values: {
- "NoButton": 0,
- "Ok": 1024,
- "Save": 2048,
- "SaveAll": 4096,
- "Open": 8192,
- "Yes": 16384,
- "YesToAll": 32768,
- "No": 65536,
- "NoToAll": 131072,
- "Abort": 262144,
- "Retry": 524288,
- "Ignore": 1048576,
- "Close": 2097152,
- "Cancel": 4194304,
- "Discard": 8388608,
- "Help": 16777216,
- "Apply": 33554432,
- "Reset": 67108864,
- "RestoreDefaults": 134217728
- }
- }
- Property { name: "text"; type: "string" }
- Property { name: "informativeText"; type: "string" }
- Property { name: "detailedText"; type: "string" }
- Property { name: "icon"; type: "Icon" }
- Property { name: "standardIconSource"; type: "QUrl"; isReadonly: true }
- Property { name: "standardButtons"; type: "StandardButtons" }
- Property { name: "clickedButton"; type: "StandardButton"; isReadonly: true }
- Signal { name: "buttonClicked" }
- Signal { name: "discard" }
- Signal { name: "help" }
- Signal { name: "yes" }
- Signal { name: "no" }
- Signal { name: "apply" }
- Signal { name: "reset" }
- Method {
- name: "setVisible"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setText"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setInformativeText"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setDetailedText"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setIcon"
- Parameter { name: "icon"; type: "Icon" }
- }
- Method {
- name: "setStandardButtons"
- Parameter { name: "buttons"; type: "StandardButtons" }
- }
- Method {
- name: "click"
- Parameter { name: "button"; type: "QMessageDialogOptions::StandardButton" }
- Parameter { type: "QMessageDialogOptions::ButtonRole" }
- }
- Method {
- name: "click"
- Parameter { name: "button"; type: "QQuickAbstractMessageDialog::StandardButton" }
- }
- }
- Component {
- name: "QQuickColorDialog"
- defaultProperty: "implementation"
- prototype: "QQuickAbstractColorDialog"
- exports: ["QtQuick.Dialogs/AbstractColorDialog 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "implementation"; type: "QObject"; isPointer: true }
- }
- Component {
- name: "QQuickFileDialog"
- defaultProperty: "implementation"
- prototype: "QQuickAbstractFileDialog"
- exports: ["QtQuick.Dialogs/AbstractFileDialog 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "implementation"; type: "QObject"; isPointer: true }
- Method { name: "clearSelection" }
- Method {
- name: "addSelection"
- type: "bool"
- Parameter { name: "path"; type: "QUrl" }
- }
- }
- Component {
- name: "QQuickFontDialog"
- defaultProperty: "implementation"
- prototype: "QQuickAbstractFontDialog"
- exports: ["QtQuick.Dialogs/AbstractFontDialog 1.1"]
- exportMetaObjectRevisions: [0]
- Property { name: "implementation"; type: "QObject"; isPointer: true }
- }
- Component {
- name: "QQuickMessageDialog"
- defaultProperty: "implementation"
- prototype: "QQuickAbstractMessageDialog"
- exports: ["QtQuick.Dialogs/AbstractMessageDialog 1.1"]
- exportMetaObjectRevisions: [0]
- Property { name: "implementation"; type: "QObject"; isPointer: true }
- }
- Component {
- name: "QQuickStandardButton"
- exports: ["QtQuick.Dialogs/StandardButton 1.1"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickStandardIcon"
- exports: ["QtQuick.Dialogs/StandardIcon 1.1"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- prototype: "QObject"
- name: "QtQuick.Dialogs/ColorDialog"
- exports: ["QtQuick.Dialogs/ColorDialog 1.0"]
- exportMetaObjectRevisions: [0]
- defaultProperty: "implementation"
- 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"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setModality"
- Parameter { name: "m"; type: "Qt::WindowModality" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "t"; type: "string" }
- }
- Method {
- name: "setColor"
- Parameter { name: "arg"; type: "QColor" }
- }
- Method {
- name: "setCurrentColor"
- Parameter { name: "currentColor"; type: "QColor" }
- }
- Method {
- name: "setShowAlphaChannel"
- Parameter { name: "arg"; type: "bool" }
- }
- Property { name: "visible"; type: "bool" }
- Property { name: "modality"; type: "Qt::WindowModality" }
- Property { name: "title"; type: "string" }
- Property { name: "isWindow"; type: "bool"; isReadonly: true }
- Property { name: "x"; type: "int" }
- Property { name: "y"; type: "int" }
- Property { name: "width"; type: "int" }
- Property { name: "height"; type: "int" }
- Signal { name: "visibilityChanged" }
- Signal { name: "geometryChanged" }
- Signal { name: "accepted" }
- 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" }
- }
- Property { name: "implementation"; type: "QObject"; isPointer: true }
- }
- Component {
- prototype: "QObject"
- name: "QtQuick.Dialogs/FileDialog"
- exports: ["QtQuick.Dialogs/FileDialog 1.0"]
- exportMetaObjectRevisions: [0]
- defaultProperty: "implementation"
- Property { name: "visible"; type: "bool" }
- Property { name: "modality"; type: "Qt::WindowModality" }
- Property { name: "title"; type: "string" }
- Property { name: "isWindow"; type: "bool"; isReadonly: true }
- Property { name: "x"; type: "int" }
- Property { name: "y"; type: "int" }
- Property { name: "width"; type: "int" }
- Property { name: "height"; type: "int" }
- Signal { name: "visibilityChanged" }
- Signal { name: "geometryChanged" }
- Signal { name: "accepted" }
- 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" }
- }
- Property { name: "selectExisting"; type: "bool" }
- Property { name: "selectMultiple"; type: "bool" }
- Property { name: "selectFolder"; type: "bool" }
- Property { name: "folder"; type: "QUrl" }
- Property { name: "nameFilters"; type: "QStringList" }
- Property { name: "selectedNameFilter"; type: "string" }
- Property { name: "fileUrl"; type: "QUrl"; isReadonly: true }
- Property { name: "fileUrls"; type: "QList<QUrl>"; isReadonly: true }
- Signal { name: "filterSelected" }
- Signal { name: "fileModeChanged" }
- Signal { name: "selectionAccepted" }
- Method {
- name: "setVisible"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "t"; type: "string" }
- }
- Method {
- name: "setSelectExisting"
- Parameter { name: "s"; type: "bool" }
- }
- Method {
- name: "setSelectMultiple"
- Parameter { name: "s"; type: "bool" }
- }
- Method {
- name: "setSelectFolder"
- Parameter { name: "s"; type: "bool" }
- }
- Method {
- name: "setFolder"
- Parameter { name: "f"; type: "QUrl" }
- }
- Method {
- name: "setNameFilters"
- Parameter { name: "f"; type: "QStringList" }
- }
- Method {
- name: "selectNameFilter"
- Parameter { name: "f"; type: "string" }
- }
- Property { name: "implementation"; type: "QObject"; isPointer: true }
- Method { name: "clearSelection" }
- Method {
- name: "addSelection"
- type: "bool"
- Parameter { name: "path"; type: "QUrl" }
- }
- }
- Component {
- prototype: "QObject"
- name: "QtQuick.Dialogs/FontDialog"
- exports: ["QtQuick.Dialogs/FontDialog 1.1"]
- exportMetaObjectRevisions: [1]
- defaultProperty: "implementation"
- Property { name: "font"; type: "QFont" }
- Property { name: "visible"; type: "bool" }
- Property { name: "modality"; type: "Qt::WindowModality" }
- Property { name: "title"; type: "string" }
- Property { name: "isWindow"; type: "bool"; isReadonly: true }
- Property { name: "x"; type: "int" }
- Property { name: "y"; type: "int" }
- Property { name: "width"; type: "int" }
- Property { name: "height"; type: "int" }
- Signal { name: "visibilityChanged" }
- Signal { name: "geometryChanged" }
- Signal { name: "accepted" }
- 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" }
- }
- Property { name: "scalableFonts"; type: "bool" }
- Property { name: "nonScalableFonts"; type: "bool" }
- Property { name: "monospacedFonts"; type: "bool" }
- Property { name: "proportionalFonts"; type: "bool" }
- Property { name: "font"; type: "QFont" }
- Signal { name: "selectionAccepted" }
- Method {
- name: "setVisible"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setModality"
- Parameter { name: "m"; type: "Qt::WindowModality" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "t"; type: "string" }
- }
- Method {
- name: "setFont"
- Parameter { name: "arg"; type: "QFont" }
- }
- Method {
- name: "setScalableFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setNonScalableFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setMonospacedFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setProportionalFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Property { name: "implementation"; type: "QObject"; isPointer: true }
- }
- Component {
- prototype: "QObject"
- name: "QtQuick.Dialogs/MessageDialog"
- exports: ["QtQuick.Dialogs/MessageDialog 1.1"]
- exportMetaObjectRevisions: [1]
- defaultProperty: "implementation"
- Method { name: "calculateImplicitWidth"; type: "QVariant" }
- Property { name: "visible"; type: "bool" }
- Property { name: "modality"; type: "Qt::WindowModality" }
- Property { name: "title"; type: "string" }
- Property { name: "isWindow"; type: "bool"; isReadonly: true }
- Property { name: "x"; type: "int" }
- Property { name: "y"; type: "int" }
- Property { name: "width"; type: "int" }
- Property { name: "height"; type: "int" }
- Signal { name: "visibilityChanged" }
- Signal { name: "geometryChanged" }
- Signal { name: "accepted" }
- 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" }
- }
- Property { name: "text"; type: "string" }
- Property { name: "informativeText"; type: "string" }
- Property { name: "detailedText"; type: "string" }
- Property { name: "icon"; type: "Icon" }
- Property { name: "standardIconSource"; type: "QUrl"; isReadonly: true }
- Property { name: "standardButtons"; type: "StandardButtons" }
- Property { name: "clickedButton"; type: "StandardButton"; isReadonly: true }
- Signal { name: "buttonClicked" }
- Signal { name: "discard" }
- Signal { name: "help" }
- Signal { name: "yes" }
- Signal { name: "no" }
- Signal { name: "apply" }
- Signal { name: "reset" }
- Method {
- name: "setVisible"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setText"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setInformativeText"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setDetailedText"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setIcon"
- Parameter { name: "icon"; type: "Icon" }
- }
- Method {
- name: "setStandardButtons"
- Parameter { name: "buttons"; type: "StandardButtons" }
- }
- Method {
- name: "click"
- Parameter { name: "button"; type: "QMessageDialogOptions::StandardButton" }
- Parameter { type: "QMessageDialogOptions::ButtonRole" }
- }
- Method {
- name: "click"
- Parameter { name: "button"; type: "QQuickAbstractMessageDialog::StandardButton" }
- }
- Property { name: "implementation"; type: "QObject"; isPointer: true }
- }
-}
diff --git a/src/imports/dialogs/qml/Button.qml b/src/imports/dialogs/qml/Button.qml
deleted file mode 100644
index f48264d5ff..0000000000
--- a/src/imports/dialogs/qml/Button.qml
+++ /dev/null
@@ -1,86 +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 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
-
-Item {
- id: container
-
- property alias text: buttonLabel.text
- property alias label: buttonLabel
- signal clicked
- property alias containsMouse: mouseArea.containsMouse
- property alias pressed: mouseArea.pressed
- implicitHeight: Math.max(Screen.pixelDensity * 7, buttonLabel.implicitHeight * 1.2)
- implicitWidth: visible ? Math.max(Screen.pixelDensity * 11, buttonLabel.implicitWidth * 1.3) : 0
- height: implicitHeight
- width: implicitWidth
-
- SystemPalette { id: palette }
-
- Rectangle {
- id: frame
- anchors.fill: parent
- color: palette.button
- 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) }
- }
- antialiasing: true
- radius: height / 6
- border.color: Qt.darker(palette.button, 1.5)
- border.width: 1
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- onClicked: container.clicked()
- hoverEnabled: true
- }
-
- Text {
- id: buttonLabel
- text: container.text
- color: palette.buttonText
- anchors.centerIn: parent
- }
-}
diff --git a/src/imports/dialogs/qml/CheckBox.qml b/src/imports/dialogs/qml/CheckBox.qml
deleted file mode 100644
index 32b0e6ff70..0000000000
--- a/src/imports/dialogs/qml/CheckBox.qml
+++ /dev/null
@@ -1,96 +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 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/ColorSlider.qml b/src/imports/dialogs/qml/ColorSlider.qml
deleted file mode 100755
index 8fc9717380..0000000000
--- a/src/imports/dialogs/qml/ColorSlider.qml
+++ /dev/null
@@ -1,138 +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 Qt Graphical Effects module.
-**
-** $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: colorSlider
-
- property real value: 1
- property real maximum: 1
- property real minimum: 0
- property string text: ""
- property bool pressed: mouseArea.pressed
- property bool integer: false
- property Component trackDelegate
- property string handleSource: "../images/slider_handle.png"
-
- width: parent.width
- height: handle.height + textText.implicitHeight
-
- function updatePos() {
- if (maximum > minimum) {
- var pos = (track.width - 10) * (value - minimum) / (maximum - minimum) + 5;
- return Math.min(Math.max(pos, 5), track.width - 5) - 10;
- } else {
- return 5;
- }
- }
-
- SystemPalette { id: palette }
-
- Column {
- id: column
- width: parent.width
- spacing: 12
- Text {
- id: textText
- anchors.horizontalCenter: parent.horizontalCenter
- text: colorSlider.text
- anchors.left: parent.left
- color: palette.windowText
- }
-
- Item {
- id: track
- height: 8
- anchors.left: parent.left
- anchors.right: parent.right
-
- Loader {
- sourceComponent: trackDelegate
- width: parent.height
- height: parent.width
- y: width
- }
-
- BorderImage {
- source: "../images/sunken_frame.png"
- border.left: 8
- border.right: 8
- border.top:8
- border.bottom: 8
- anchors.fill: track
- anchors.margins: -1
- anchors.topMargin: -2
- anchors.leftMargin: -2
- }
-
- Image {
- id: handle
- anchors.verticalCenter: parent.verticalCenter
- smooth: true
- source: "../images/slider_handle.png"
- x: updatePos() - 8
- z: 1
- }
-
- MouseArea {
- id: mouseArea
- anchors {left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter}
- height: handle.height
- width: handle.width
- preventStealing: true
-
- onPressed: {
- var handleX = Math.max(0, Math.min(mouseX, mouseArea.width))
- var realValue = (maximum - minimum) * handleX / mouseArea.width + minimum;
- value = colorSlider.integer ? Math.round(realValue) : realValue;
- }
-
- onPositionChanged: {
- if (pressed) {
- var handleX = Math.max(0, Math.min(mouseX, mouseArea.width))
- var realValue = (maximum - minimum) * handleX / mouseArea.width + minimum;
- value = colorSlider.integer ? Math.round(realValue) : realValue;
- }
- }
- }
- }
- }
-}
diff --git a/src/imports/dialogs/qml/DefaultWindowDecoration.qml b/src/imports/dialogs/qml/DefaultWindowDecoration.qml
deleted file mode 100644
index ec930101d2..0000000000
--- a/src/imports/dialogs/qml/DefaultWindowDecoration.qml
+++ /dev/null
@@ -1,71 +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 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
-
-Rectangle {
- color: "#80000000"
- anchors.fill: parent
- z: 1000000
- property alias content: borderImage.content
- property bool dismissOnOuterClick: true
- signal dismissed
- MouseArea {
- anchors.fill: parent
- enabled: dismissOnOuterClick
- onClicked: dismissed()
- BorderImage {
- id: borderImage
- property Item content
-
- MouseArea { anchors.fill: parent }
-
- width: content ? content.width + 15 : 0
- height: content ? content.height + 15 : 0
- onWidthChanged: content.x = 5
- onHeightChanged: content.y = 5
- border { left: 10; top: 10; right: 10; bottom: 10 }
- clip: true
- source: "../images/window_border.png"
- anchors.centerIn: parent
- onContentChanged: if (content) content.parent = borderImage
- }
- }
-}
diff --git a/src/imports/dialogs/qml/EdgeFade.qml b/src/imports/dialogs/qml/EdgeFade.qml
deleted file mode 100644
index 376aa151e6..0000000000
--- a/src/imports/dialogs/qml/EdgeFade.qml
+++ /dev/null
@@ -1,63 +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 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/TextField.qml b/src/imports/dialogs/qml/TextField.qml
deleted file mode 100644
index e67155086c..0000000000
--- a/src/imports/dialogs/qml/TextField.qml
+++ /dev/null
@@ -1,89 +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 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
- signal backPressed
- signal escapePressed
- implicitWidth: textInput.implicitWidth + rect.radius * 2
- implicitHeight: textInput.implicitHeight
-
- function copyAll() {
- textInput.selectAll()
- textInput.copy()
- }
-
- function paste() {
- textInput.selectAll()
- textInput.paste()
- }
-
- 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()
- Keys.onBackPressed: root.backPressed()
- Keys.onEscapePressed: root.escapePressed()
- }
-}
diff --git a/src/imports/dialogs/qml/qmldir b/src/imports/dialogs/qml/qmldir
deleted file mode 100644
index 9d273b1c4b..0000000000
--- a/src/imports/dialogs/qml/qmldir
+++ /dev/null
@@ -1,5 +0,0 @@
-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/qmldir b/src/imports/dialogs/qmldir
deleted file mode 100644
index b4ae1a059c..0000000000
--- a/src/imports/dialogs/qmldir
+++ /dev/null
@@ -1,4 +0,0 @@
-module QtQuick.Dialogs
-plugin dialogplugin
-classname QtQuick2DialogsPlugin
-typeinfo plugins.qmltypes
diff --git a/src/imports/dialogs/qquickabstractcolordialog.cpp b/src/imports/dialogs/qquickabstractcolordialog.cpp
deleted file mode 100644
index 1931bde905..0000000000
--- a/src/imports/dialogs/qquickabstractcolordialog.cpp
+++ /dev/null
@@ -1,134 +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 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 "qquickabstractcolordialog_p.h"
-#include "qquickitem.h"
-
-#include <private/qguiapplication_p.h>
-#include <QWindow>
-#include <QQuickWindow>
-
-QT_BEGIN_NAMESPACE
-
-QQuickAbstractColorDialog::QQuickAbstractColorDialog(QObject *parent)
- : QQuickAbstractDialog(parent)
- , m_dlgHelper(0)
- , m_options(QSharedPointer<QColorDialogOptions>(new QColorDialogOptions()))
-{
- // 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()));
-}
-
-QQuickAbstractColorDialog::~QQuickAbstractColorDialog()
-{
-}
-
-void QQuickAbstractColorDialog::setVisible(bool v)
-{
- if (helper() && v) {
- m_dlgHelper->setOptions(m_options);
- // Due to the fact that QColorDialogOptions doesn't have currentColor...
- m_dlgHelper->setCurrentColor(m_color);
- }
- QQuickAbstractDialog::setVisible(v);
- // QTBUG-35206
-#if defined(Q_OS_WIN)
- if (m_dialogWindow)
- m_dialogWindow->setWidth(m_dialogWindow->width() + 1);
-#endif
-}
-
-void QQuickAbstractColorDialog::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 QQuickAbstractColorDialog::title() const
-{
- return m_options->windowTitle();
-}
-
-bool QQuickAbstractColorDialog::showAlphaChannel() const
-{
- return m_options->testOption(QColorDialogOptions::ShowAlphaChannel);
-}
-
-void QQuickAbstractColorDialog::setTitle(const QString &t)
-{
- if (m_options->windowTitle() == t) return;
- m_options->setWindowTitle(t);
- emit titleChanged();
-}
-
-void QQuickAbstractColorDialog::setColor(QColor arg)
-{
- if (m_dlgHelper)
- m_dlgHelper->setCurrentColor(arg);
- // m_options->setCustomColor or setStandardColor don't make sense here
- if (m_color != 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)
-{
- m_options->setOption(QColorDialogOptions::ShowAlphaChannel, arg);
- emit showAlphaChannelChanged();
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickabstractcolordialog_p.h b/src/imports/dialogs/qquickabstractcolordialog_p.h
deleted file mode 100644
index ad2c7ce1ed..0000000000
--- a/src/imports/dialogs/qquickabstractcolordialog_p.h
+++ /dev/null
@@ -1,113 +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 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 QQUICKABSTRACTCOLORDIALOG_P_H
-#define QQUICKABSTRACTCOLORDIALOG_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 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(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);
- virtual ~QQuickAbstractColorDialog();
-
- virtual QString title() const;
- bool showAlphaChannel() const;
- QColor color() const { return m_color; }
- 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)
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKABSTRACTCOLORDIALOG_P_H
diff --git a/src/imports/dialogs/qquickabstractdialog.cpp b/src/imports/dialogs/qquickabstractdialog.cpp
deleted file mode 100644
index 9bb2388741..0000000000
--- a/src/imports/dialogs/qquickabstractdialog.cpp
+++ /dev/null
@@ -1,337 +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 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 "qquickabstractdialog_p.h"
-#include "qquickitem.h"
-
-#include <private/qguiapplication_p.h>
-#include <QWindow>
-#include <QQmlComponent>
-#include <QQuickWindow>
-#include <qpa/qplatformintegration.h>
-
-QT_BEGIN_NAMESPACE
-
-QQmlComponent *QQuickAbstractDialog::m_decorationComponent(0);
-
-QQuickAbstractDialog::QQuickAbstractDialog(QObject *parent)
- : QObject(parent)
- , m_parentWindow(0)
- , m_visible(false)
- , m_modality(Qt::WindowModal)
- , m_qmlImplementation(0)
- , m_dialogWindow(0)
- , m_contentItem(0)
- , m_windowDecoration(0)
- , m_hasNativeWindows(QGuiApplicationPrivate::platformIntegration()->
- hasCapability(QPlatformIntegration::MultipleWindows) &&
- QGuiApplicationPrivate::platformIntegration()->
- hasCapability(QPlatformIntegration::WindowManagement))
- , m_hasAspiredPosition(false)
-{
-}
-
-QQuickAbstractDialog::~QQuickAbstractDialog()
-{
-}
-
-void QQuickAbstractDialog::setVisible(bool v)
-{
- if (m_visible == v) return;
- m_visible = v;
- if (helper()) {
- if (v) {
- Qt::WindowFlags flags = Qt::Dialog;
- if (!title().isEmpty())
- flags |= Qt::WindowTitleHint;
- m_visible = helper()->show(flags, m_modality, parentWindow());
- } else {
- helper()->hide();
- }
- } else {
- // For a pure QML implementation, there is no helper.
- // But m_implementation is probably either an Item or a Window at this point.
- if (!m_dialogWindow) {
- m_dialogWindow = qobject_cast<QWindow *>(m_qmlImplementation);
- if (!m_dialogWindow) {
- m_contentItem = qobject_cast<QQuickItem *>(m_qmlImplementation);
- if (m_contentItem) {
- if (m_hasNativeWindows)
- m_dialogWindow = m_contentItem->window();
- // An Item-based dialog implementation doesn't come with a window, so
- // we have to instantiate one iff the platform allows it.
- if (!m_dialogWindow && m_hasNativeWindows) {
- QQuickWindow *win = new QQuickWindow;
- ((QObject *)win)->setParent(this); // memory management only
- m_dialogWindow = win;
- m_contentItem->setParentItem(win->contentItem());
- m_dialogWindow->setMinimumSize(QSize(m_contentItem->implicitWidth(), m_contentItem->implicitHeight()));
- connect(win, SIGNAL(widthChanged(int)), this, SLOT(windowGeometryChanged()));
- connect(win, SIGNAL(heightChanged(int)), this, SLOT(windowGeometryChanged()));
- }
-
- QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
-
- // If the platform does not support multiple windows, but the dialog is
- // implemented as an Item, then try to decorate it as a fake window and make it visible.
- if (parentItem && !m_dialogWindow && !m_windowDecoration) {
- if (m_decorationComponent) {
- if (m_decorationComponent->isLoading())
- connect(m_decorationComponent, SIGNAL(statusChanged(QQmlComponent::Status)),
- this, SLOT(decorationLoaded()));
- else
- decorationLoaded();
- }
- // Window decoration wasn't possible, so just reparent it into the scene
- else {
- m_contentItem->setParentItem(parentItem);
- m_contentItem->setZ(10000);
- }
- }
- }
- }
- 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);
- } else if (m_dialogWindow) {
- if (v) {
- m_dialogWindow->setTransientParent(parentWindow());
- m_dialogWindow->setTitle(title());
- m_dialogWindow->setModality(m_modality);
- }
- m_dialogWindow->setVisible(v);
- }
- }
-
- emit visibilityChanged();
-}
-
-void QQuickAbstractDialog::decorationLoaded()
-{
- bool ok = false;
- QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
- while (parentItem->parentItem() && !parentItem->parentItem()->inherits("QQuickRootItem"))
- parentItem = parentItem->parentItem();
- if (m_decorationComponent->isError()) {
- qWarning() << m_decorationComponent->errors();
- } else {
- QObject *decoration = m_decorationComponent->create();
- m_windowDecoration = qobject_cast<QQuickItem *>(decoration);
- if (m_windowDecoration) {
- m_windowDecoration->setParentItem(parentItem);
- // Give the window decoration its content to manage
- QVariant contentVariant;
- contentVariant.setValue<QQuickItem*>(m_contentItem);
- m_windowDecoration->setProperty("content", contentVariant);
- connect(m_windowDecoration, SIGNAL(dismissed()), this, SLOT(reject()));
- ok = true;
- } else {
- qWarning() << m_decorationComponent->url() <<
- "cannot be used as a window decoration because it's not an Item";
- delete m_windowDecoration;
- delete m_decorationComponent;
- m_decorationComponent = 0;
- }
- }
- // Window decoration wasn't possible, so just reparent it into the scene
- if (!ok) {
- m_contentItem->setParentItem(parentItem);
- m_contentItem->setZ(10000);
- }
-}
-
-void QQuickAbstractDialog::setModality(Qt::WindowModality m)
-{
- if (m_modality == m) return;
- m_modality = m;
- emit modalityChanged();
-}
-
-void QQuickAbstractDialog::accept()
-{
- setVisible(false);
- emit accepted();
-}
-
-void QQuickAbstractDialog::reject()
-{
- setVisible(false);
- emit rejected();
-}
-
-void QQuickAbstractDialog::visibleChanged(bool v)
-{
- m_visible = v;
- emit visibilityChanged();
-}
-
-void QQuickAbstractDialog::windowGeometryChanged()
-{
- QQuickItem *content = qobject_cast<QQuickItem*>(m_qmlImplementation);
- if (m_dialogWindow && content) {
- content->setWidth(m_dialogWindow->width());
- content->setHeight(m_dialogWindow->height());
- }
-}
-
-QQuickWindow *QQuickAbstractDialog::parentWindow()
-{
- QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
- if (parentItem)
- m_parentWindow = parentItem->window();
- return m_parentWindow;
-}
-
-void QQuickAbstractDialog::setQmlImplementation(QObject *obj)
-{
- m_qmlImplementation = obj;
- if (m_dialogWindow) {
- disconnect(this, SLOT(visibleChanged(bool)));
- // Can't necessarily delete because m_dialogWindow might have been provided by the QML.
- m_dialogWindow = 0;
- }
-}
-
-int QQuickAbstractDialog::x() const
-{
- if (m_dialogWindow)
- return m_dialogWindow->x();
- return m_sizeAspiration.x();
-}
-
-int QQuickAbstractDialog::y() const
-{
- if (m_dialogWindow)
- return m_dialogWindow->y();
- return m_sizeAspiration.y();
-}
-
-int QQuickAbstractDialog::width() const
-{
- if (m_dialogWindow)
- return m_dialogWindow->width();
- return m_sizeAspiration.width();
-}
-
-int QQuickAbstractDialog::height() const
-{
- if (m_dialogWindow)
- return m_dialogWindow->height();
- return m_sizeAspiration.height();
-}
-
-void QQuickAbstractDialog::setX(int arg)
-{
- m_hasAspiredPosition = true;
- m_sizeAspiration.setX(arg);
- if (helper()) {
- // TODO
- } else if (m_dialogWindow) {
- 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) {
- 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) {
- 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) {
- if (sender() != m_dialogWindow)
- m_dialogWindow->setHeight(arg);
- } else if (m_contentItem) {
- m_contentItem->setHeight(arg);
- }
- emit geometryChanged();
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickabstractdialog_p.h b/src/imports/dialogs/qquickabstractdialog_p.h
deleted file mode 100644
index 8ffa166c5b..0000000000
--- a/src/imports/dialogs/qquickabstractdialog_p.h
+++ /dev/null
@@ -1,145 +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 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 QQUICKABSTRACTDIALOG_P_H
-#define QQUICKABSTRACTDIALOG_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>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickAbstractDialog : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibilityChanged)
- Q_PROPERTY(Qt::WindowModality modality READ modality WRITE setModality NOTIFY modalityChanged)
- Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
- Q_PROPERTY(bool isWindow READ isWindow CONSTANT)
- Q_PROPERTY(int x READ x WRITE setX NOTIFY geometryChanged)
- Q_PROPERTY(int y READ y WRITE setY NOTIFY geometryChanged)
- Q_PROPERTY(int width READ width WRITE setWidth NOTIFY geometryChanged)
- Q_PROPERTY(int height READ height WRITE setHeight NOTIFY geometryChanged)
-
-public:
- QQuickAbstractDialog(QObject *parent = 0);
- virtual ~QQuickAbstractDialog();
-
- bool isVisible() const { return m_visible; }
- Qt::WindowModality modality() const { return m_modality; }
- virtual QString title() const = 0;
- QObject* qmlImplementation() { return m_qmlImplementation; }
-
- int x() const;
- int y() const;
- int width() const;
- int height() const;
-
- virtual void setVisible(bool v);
- virtual void setModality(Qt::WindowModality m);
- virtual void setTitle(const QString &t) = 0;
- void setQmlImplementation(QObject* obj);
- bool isWindow() const { return m_hasNativeWindows; }
-
-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();
- void geometryChanged();
- void modalityChanged();
- void titleChanged();
- void accepted();
- void rejected();
-
-protected Q_SLOTS:
- void decorationLoaded();
- virtual void accept();
- virtual void reject();
- void visibleChanged(bool v);
- void windowGeometryChanged();
-
-protected:
- virtual QPlatformDialogHelper *helper() = 0;
- QQuickWindow *parentWindow();
-
-protected:
- QQuickWindow *m_parentWindow;
- bool m_visible;
- Qt::WindowModality m_modality;
-
-protected: // variables for pure-QML implementations only
- QObject *m_qmlImplementation;
- QWindow *m_dialogWindow;
- QQuickItem *m_contentItem;
- QQuickItem *m_windowDecoration;
- bool m_hasNativeWindows;
- QRect m_sizeAspiration;
- bool m_hasAspiredPosition;
-
- static QQmlComponent *m_decorationComponent;
-
- friend class QtQuick2DialogsPlugin;
-
- Q_DISABLE_COPY(QQuickAbstractDialog)
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKABSTRACTDIALOG_P_H
diff --git a/src/imports/dialogs/qquickabstractfiledialog.cpp b/src/imports/dialogs/qquickabstractfiledialog.cpp
deleted file mode 100644
index 0cac801311..0000000000
--- a/src/imports/dialogs/qquickabstractfiledialog.cpp
+++ /dev/null
@@ -1,194 +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 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 "qquickabstractfiledialog_p.h"
-#include "qquickitem.h"
-
-#include <private/qguiapplication_p.h>
-#include <QWindow>
-#include <QQuickWindow>
-
-QT_BEGIN_NAMESPACE
-
-QQuickAbstractFileDialog::QQuickAbstractFileDialog(QObject *parent)
- : QQuickAbstractDialog(parent)
- , m_dlgHelper(0)
- , m_options(QSharedPointer<QFileDialogOptions>(new QFileDialogOptions()))
- , m_selectExisting(true)
- , m_selectMultiple(false)
- , m_selectFolder(false)
-{
- updateModes();
- connect(this, SIGNAL(accepted()), this, SIGNAL(selectionAccepted()));
-}
-
-QQuickAbstractFileDialog::~QQuickAbstractFileDialog()
-{
-}
-
-void QQuickAbstractFileDialog::setVisible(bool v)
-{
- if (helper() && v) {
- m_dlgHelper->setOptions(m_options);
- m_dlgHelper->setFilter();
- emit filterSelected();
- }
- QQuickAbstractDialog::setVisible(v);
-}
-
-QString QQuickAbstractFileDialog::title() const
-{
- return m_options->windowTitle();
-}
-
-void QQuickAbstractFileDialog::setTitle(const QString &t)
-{
- if (m_options->windowTitle() == t) return;
- m_options->setWindowTitle(t);
- emit titleChanged();
-}
-
-void QQuickAbstractFileDialog::setSelectExisting(bool selectExisting)
-{
- if (selectExisting == m_selectExisting) return;
- m_selectExisting = selectExisting;
- updateModes();
-}
-
-void QQuickAbstractFileDialog::setSelectMultiple(bool selectMultiple)
-{
- if (selectMultiple == m_selectMultiple) return;
- m_selectMultiple = selectMultiple;
- updateModes();
-}
-
-void QQuickAbstractFileDialog::setSelectFolder(bool selectFolder)
-{
- if (selectFolder == m_selectFolder) return;
- m_selectFolder = selectFolder;
- updateModes();
-}
-
-QUrl QQuickAbstractFileDialog::folder()
-{
- if (m_dlgHelper && !m_dlgHelper->directory().isEmpty())
- return m_dlgHelper->directory();
- return m_options->initialDirectory();
-}
-
-void QQuickAbstractFileDialog::setFolder(const QUrl &f)
-{
- if (m_dlgHelper)
- m_dlgHelper->setDirectory(f);
- m_options->setInitialDirectory(f);
- emit folderChanged();
-}
-
-void QQuickAbstractFileDialog::setNameFilters(const QStringList &f)
-{
- m_options->setNameFilters(f);
- if (f.isEmpty())
- selectNameFilter(QString());
- else if (!f.contains(selectedNameFilter()))
- selectNameFilter(f.first());
- emit nameFiltersChanged();
-}
-
-QString QQuickAbstractFileDialog::selectedNameFilter()
-{
- QString ret;
- if (m_dlgHelper)
- ret = m_dlgHelper->selectedNameFilter();
- if (ret.isEmpty())
- return m_options->initiallySelectedNameFilter();
- return ret;
-}
-
-void QQuickAbstractFileDialog::selectNameFilter(const QString &f)
-{
- // This should work whether the dialog is currently being shown already, or ahead of time.
- m_options->setInitiallySelectedNameFilter(f);
- if (m_dlgHelper)
- m_dlgHelper->selectNameFilter(f);
- emit filterSelected();
-}
-
-QUrl QQuickAbstractFileDialog::fileUrl()
-{
- QList<QUrl> urls = fileUrls();
- return (urls.count() == 1) ? urls[0] : QUrl();
-}
-
-QList<QUrl> QQuickAbstractFileDialog::fileUrls()
-{
- if (m_dlgHelper)
- return m_dlgHelper->selectedFiles();
- return QList<QUrl>();
-}
-
-void QQuickAbstractFileDialog::updateModes()
-{
- // The 4 possible modes are AnyFile, ExistingFile, Directory, ExistingFiles
- // Assume AnyFile until we find a reason to the contrary
- QFileDialogOptions::FileMode mode = QFileDialogOptions::AnyFile;
-
- if (m_selectFolder) {
- mode = QFileDialogOptions::Directory;
- m_options->setOption(QFileDialogOptions::ShowDirsOnly);
- m_selectMultiple = false;
- m_selectExisting = true;
- setNameFilters(QStringList());
- } else if (m_selectExisting) {
- mode = m_selectMultiple ?
- QFileDialogOptions::ExistingFiles : QFileDialogOptions::ExistingFile;
- m_options->setOption(QFileDialogOptions::ShowDirsOnly, false);
- } else if (m_selectMultiple) {
- m_selectExisting = true;
- }
- if (!m_selectExisting)
- m_selectMultiple = false;
- m_options->setFileMode(mode);
- m_options->setAcceptMode(m_selectExisting ?
- QFileDialogOptions::AcceptOpen : QFileDialogOptions::AcceptSave);
- emit fileModeChanged();
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickabstractfiledialog_p.h b/src/imports/dialogs/qquickabstractfiledialog_p.h
deleted file mode 100644
index 5ce48e8055..0000000000
--- a/src/imports/dialogs/qquickabstractfiledialog_p.h
+++ /dev/null
@@ -1,122 +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 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 QQUICKABSTRACTFILEDIALOG_P_H
-#define QQUICKABSTRACTFILEDIALOG_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 QQuickAbstractFileDialog : public QQuickAbstractDialog
-{
- Q_OBJECT
- Q_PROPERTY(bool selectExisting READ selectExisting WRITE setSelectExisting NOTIFY fileModeChanged)
- Q_PROPERTY(bool selectMultiple READ selectMultiple WRITE setSelectMultiple NOTIFY fileModeChanged)
- Q_PROPERTY(bool selectFolder READ selectFolder WRITE setSelectFolder NOTIFY fileModeChanged)
- Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged)
- Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY nameFiltersChanged)
- Q_PROPERTY(QString selectedNameFilter READ selectedNameFilter WRITE selectNameFilter NOTIFY filterSelected)
- Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY selectionAccepted)
- Q_PROPERTY(QList<QUrl> fileUrls READ fileUrls NOTIFY selectionAccepted)
-
-public:
- QQuickAbstractFileDialog(QObject *parent = 0);
- virtual ~QQuickAbstractFileDialog();
-
- virtual QString title() const;
- bool selectExisting() const { return m_selectExisting; }
- bool selectMultiple() const { return m_selectMultiple; }
- bool selectFolder() const { return m_selectFolder; }
- QUrl folder();
- QStringList nameFilters() const { return m_options->nameFilters(); }
- QString selectedNameFilter();
- QUrl fileUrl();
- virtual QList<QUrl> fileUrls();
-
-public Q_SLOTS:
- void setVisible(bool v);
- void setTitle(const QString &t);
- void setSelectExisting(bool s);
- void setSelectMultiple(bool s);
- void setSelectFolder(bool s);
- void setFolder(const QUrl &f);
- void setNameFilters(const QStringList &f);
- void selectNameFilter(const QString &f);
-
-Q_SIGNALS:
- void folderChanged();
- void nameFiltersChanged();
- void filterSelected();
- void fileModeChanged();
- void selectionAccepted();
-
-protected:
- void updateModes();
-
-protected:
- QPlatformFileDialogHelper *m_dlgHelper;
- QSharedPointer<QFileDialogOptions> m_options;
- bool m_selectExisting;
- bool m_selectMultiple;
- bool m_selectFolder;
-
- Q_DISABLE_COPY(QQuickAbstractFileDialog)
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKABSTRACTFILEDIALOG_P_H
diff --git a/src/imports/dialogs/qquickabstractfontdialog.cpp b/src/imports/dialogs/qquickabstractfontdialog.cpp
deleted file mode 100644
index 29dd15e8cc..0000000000
--- a/src/imports/dialogs/qquickabstractfontdialog.cpp
+++ /dev/null
@@ -1,150 +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 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
deleted file mode 100644
index 858a0d3eac..0000000000
--- a/src/imports/dialogs/qquickabstractfontdialog_p.h
+++ /dev/null
@@ -1,113 +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 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
deleted file mode 100644
index a44464962a..0000000000
--- a/src/imports/dialogs/qquickabstractmessagedialog.cpp
+++ /dev/null
@@ -1,179 +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 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"
-#include <QtGui/qpa/qplatformdialoghelper.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(QMessageDialogOptions::StandardButton button, QMessageDialogOptions::ButtonRole role)
-{
- setVisible(false);
- m_clickedButton = static_cast<StandardButton>(button);
- emit buttonClicked();
- switch (role) {
- case QMessageDialogOptions::AcceptRole:
- emit accept();
- break;
- case QMessageDialogOptions::RejectRole:
- emit reject();
- break;
- case QMessageDialogOptions::DestructiveRole:
- emit discard();
- break;
- case QMessageDialogOptions::HelpRole:
- emit help();
- break;
- case QMessageDialogOptions::YesRole:
- emit yes();
- break;
- case QMessageDialogOptions::NoRole:
- emit no();
- break;
- case QMessageDialogOptions::ApplyRole:
- emit apply();
- break;
- case QMessageDialogOptions::ResetRole:
- emit reset();
- break;
- default:
- qWarning("unhandled MessageDialog button %d with role %d", button, role);
- }
-}
-
-void QQuickAbstractMessageDialog::click(QQuickAbstractMessageDialog::StandardButton button)
-{
- click(static_cast<QMessageDialogOptions::StandardButton>(button),
- static_cast<QMessageDialogOptions::ButtonRole>(
- QMessageDialogOptions::buttonRole(static_cast<QMessageDialogOptions::StandardButton>(button))));
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickabstractmessagedialog_p.h b/src/imports/dialogs/qquickabstractmessagedialog_p.h
deleted file mode 100644
index f2427bb2e0..0000000000
--- a/src/imports/dialogs/qquickabstractmessagedialog_p.h
+++ /dev/null
@@ -1,165 +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 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(QMessageDialogOptions::StandardButton button, QMessageDialogOptions::ButtonRole);
- void click(QQuickAbstractMessageDialog::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/qquickcolordialog.cpp b/src/imports/dialogs/qquickcolordialog.cpp
deleted file mode 100644
index d0e0e11b07..0000000000
--- a/src/imports/dialogs/qquickcolordialog.cpp
+++ /dev/null
@@ -1,119 +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 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 "qquickcolordialog_p.h"
-#include <QQuickItem>
-#include <private/qguiapplication_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype AbstractColorDialog
- \instantiates QQuickColorDialog
- \inqmlmodule QtQuick.Dialogs 1
- \ingroup qtquick-visual
- \brief API wrapper for QML file dialog implementations
- \since 5.1
- \internal
-
- AbstractColorDialog provides only the API for implementing a color 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::AbstractColorDialog::accepted
-
- This signal is emitted by \l accept().
-*/
-
-/*!
- \qmlsignal QtQuick::Dialogs::AbstractColorDialog::rejected
-
- This signal is emitted by \l reject().
-*/
-
-/*!
- \class QQuickColorDialog
- \inmodule QtQuick.Dialogs
- \internal
-
- The QQuickColorDialog class is a concrete subclass of
- \l QQuickAbstractColorDialog, 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.1
-*/
-
-/*!
- Constructs a file dialog wrapper with parent window \a parent.
-*/
-QQuickColorDialog::QQuickColorDialog(QObject *parent)
- : QQuickAbstractColorDialog(parent)
-{
-}
-
-
-/*!
- Destroys the file dialog wrapper.
-*/
-QQuickColorDialog::~QQuickColorDialog()
-{
-}
-
-/*!
- \qmlproperty bool AbstractColorDialog::visible
-
- This property holds whether the dialog is visible. By default this is false.
-*/
-
-/*!
- \qmlproperty QObject AbstractColorDialog::implementation
-
- The QML object which implements the actual file dialog. Should be either a
- \l Window or an \l Item.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickcolordialog_p.h b/src/imports/dialogs/qquickcolordialog_p.h
deleted file mode 100644
index ff6953fc0f..0000000000
--- a/src/imports/dialogs/qquickcolordialog_p.h
+++ /dev/null
@@ -1,80 +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 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 QQUICKCOLORDIALOG_P_H
-#define QQUICKCOLORDIALOG_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 "qquickabstractcolordialog_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QQuickColorDialog : public QQuickAbstractColorDialog
-{
- Q_OBJECT
- Q_PROPERTY(QObject* implementation READ qmlImplementation WRITE setQmlImplementation DESIGNABLE false)
- Q_CLASSINFO("DefaultProperty", "implementation") // AbstractColorDialog in QML can have only one child
-
-public:
- explicit QQuickColorDialog(QObject *parent = 0);
- ~QQuickColorDialog();
-
-protected:
- virtual QPlatformColorDialogHelper *helper() { return 0; }
-
- Q_DISABLE_COPY(QQuickColorDialog)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickColorDialog *)
-
-#endif // QQUICKCOLORDIALOG_P_H
diff --git a/src/imports/dialogs/qquickfiledialog.cpp b/src/imports/dialogs/qquickfiledialog.cpp
deleted file mode 100644
index 2ee4afc5d2..0000000000
--- a/src/imports/dialogs/qquickfiledialog.cpp
+++ /dev/null
@@ -1,172 +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 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 "qquickfiledialog_p.h"
-#include <QQuickItem>
-#include <private/qguiapplication_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype AbstractFileDialog
- \instantiates QQuickFileDialog
- \inqmlmodule QtQuick.Dialogs 1
- \ingroup qtquick-visual
- \brief API wrapper for QML file dialog implementations
- \since 5.1
- \internal
-
- AbstractFileDialog provides only the API for implementing a file 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::AbstractFileDialog::accepted
-
- This signal is emitted by \l accept().
-*/
-
-/*!
- \qmlsignal QtQuick::Dialogs::AbstractFileDialog::rejected
-
- This signal is emitted by \l reject().
-*/
-
-/*!
- \class QQuickFileDialog
- \inmodule QtQuick.Dialogs
- \internal
-
- The QQuickFileDialog class is a concrete subclass of
- \l QQuickAbstractFileDialog, 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.1
-*/
-
-/*!
- Constructs a file dialog wrapper with parent window \a parent.
-*/
-QQuickFileDialog::QQuickFileDialog(QObject *parent)
- : QQuickAbstractFileDialog(parent)
-{
-}
-
-
-/*!
- Destroys the file dialog wrapper.
-*/
-QQuickFileDialog::~QQuickFileDialog()
-{
-}
-
-QList<QUrl> QQuickFileDialog::fileUrls()
-{
- return m_selections;
-}
-
-/*!
- \qmlproperty bool AbstractFileDialog::visible
-
- This property holds whether the dialog is visible. By default this is false.
-*/
-
-/*!
- \qmlproperty bool AbstractFileDialog::fileUrls
-
- A list of files to be populated as the user chooses.
-*/
-
-/*!
- \brief Clears \l fileUrls
-*/
-void QQuickFileDialog::clearSelection()
-{
- m_selections.clear();
-}
-
-/*!
- \brief Adds one file to \l fileUrls
-
- \l path should be given as an absolute file:// path URL.
- Returns true on success, false if the given path is
- not valid given the current property settings.
-*/
-bool QQuickFileDialog::addSelection(const QUrl &path)
-{
- QFileInfo info(path.toLocalFile());
- if (info.exists() && ((info.isDir() && m_selectFolder) || !info.isDir())) {
- if (m_selectFolder)
- m_selections.append(pathFolder(path.toLocalFile()));
- else
- m_selections.append(path);
- return true;
- }
- return false;
-}
-
-/*!
- \brief get a file's directory as a URL
-
- If \a path points to a directory, just convert it to a URL.
- If \a path points to a file, convert the file's directory to a URL.
-*/
-QUrl QQuickFileDialog::pathFolder(const QString &path)
-{
- QFileInfo info(path);
- if (info.exists() && info.isDir())
- return QUrl::fromLocalFile(path);
- return QUrl::fromLocalFile(QFileInfo(path).absolutePath());
-}
-
-/*!
- \qmlproperty QObject AbstractFileDialog::implementation
-
- The QML object which implements the actual file dialog. Should be either a
- \l Window or an \l Item.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickfiledialog_p.h b/src/imports/dialogs/qquickfiledialog_p.h
deleted file mode 100644
index a4c7939fda..0000000000
--- a/src/imports/dialogs/qquickfiledialog_p.h
+++ /dev/null
@@ -1,93 +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 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 QQUICKFILEDIALOG_P_H
-#define QQUICKFILEDIALOG_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 "qquickabstractfiledialog_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QQuickFileDialog : public QQuickAbstractFileDialog
-{
- Q_OBJECT
- Q_PROPERTY(QObject* implementation READ qmlImplementation WRITE setQmlImplementation DESIGNABLE false)
- Q_CLASSINFO("DefaultProperty", "implementation") // AbstractFileDialog in QML can have only one child
-
-public:
- explicit QQuickFileDialog(QObject *parent = 0);
- ~QQuickFileDialog();
- virtual QList<QUrl> fileUrls();
-
-Q_SIGNALS:
-
-public Q_SLOTS:
- void clearSelection();
- bool addSelection(const QUrl &path);
-
-protected:
- virtual QPlatformFileDialogHelper *helper() { return 0; }
- Q_INVOKABLE QString urlToPath(const QUrl &url) { return url.toLocalFile(); }
- Q_INVOKABLE QUrl pathToUrl(const QString &path) { return QUrl::fromLocalFile(path); }
- Q_INVOKABLE QUrl pathFolder(const QString &path);
-
-private:
- QList<QUrl> m_selections;
-
- Q_DISABLE_COPY(QQuickFileDialog)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickFileDialog *)
-
-#endif // QQUICKFILEDIALOG_P_H
diff --git a/src/imports/dialogs/qquickfontdialog.cpp b/src/imports/dialogs/qquickfontdialog.cpp
deleted file mode 100644
index 2f3c6d83bb..0000000000
--- a/src/imports/dialogs/qquickfontdialog.cpp
+++ /dev/null
@@ -1,120 +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 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
deleted file mode 100644
index a8e2d82e6f..0000000000
--- a/src/imports/dialogs/qquickfontdialog_p.h
+++ /dev/null
@@ -1,80 +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 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/qquickmessagedialog.cpp b/src/imports/dialogs/qquickmessagedialog.cpp
deleted file mode 100644
index 5346aeeda8..0000000000
--- a/src/imports/dialogs/qquickmessagedialog.cpp
+++ /dev/null
@@ -1,133 +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 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)
-{
-}
-
-
-/*!
- 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::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
deleted file mode 100644
index 99c59ecca1..0000000000
--- a/src/imports/dialogs/qquickmessagedialog_p.h
+++ /dev/null
@@ -1,85 +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 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();
-
-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
deleted file mode 100644
index 11ddbfe6c7..0000000000
--- a/src/imports/dialogs/qquickplatformcolordialog.cpp
+++ /dev/null
@@ -1,254 +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 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 "qquickplatformcolordialog_p.h"
-#include "qquickitem.h"
-
-#include <private/qguiapplication_p.h>
-#include <QWindow>
-#include <QQuickView>
-#include <QQuickWindow>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype ColorDialog
- \instantiates QQuickPlatformColorDialog
- \inqmlmodule QtQuick.Dialogs 1
- \ingroup dialogs
- \brief Dialog component for choosing a color.
- \since 5.1
-
- ColorDialog allows the user to select a color. 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 color dialog and exit after the user
- chooses a color:
-
- \qml
- import QtQuick 2.1
- import QtQuick.Dialogs 1.0
-
- ColorDialog {
- id: colorDialog
- title: "Please choose a color"
- onAccepted: {
- console.log("You chose: " + colorDialog.color)
- Qt.quit()
- }
- onRejected: {
- console.log("Canceled")
- Qt.quit()
- }
- Component.onCompleted: visible = true
- }
- \endqml
-
- A ColorDialog 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 ColorDialog will be a platform color dialog if
- possible. If that isn't possible, then it will try to instantiate a
- \l QColorDialog. If that also isn't possible, then it will fall back to a QML
- implementation, DefaultColorDialog.qml. In that case you can customize the
- appearance by editing this file. DefaultColorDialog.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::ColorDialog::accepted
-
- This handler is called when the user has finished using the
- dialog. You can then inspect the \l color property to get the selection.
-
- Example:
-
- \qml
- ColorDialog {
- onAccepted: { console.log("Selected color: " + color) }
- }
- \endqml
-*/
-
-/*!
- \qmlsignal QtQuick::Dialogs::ColorDialog::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 QQuickPlatformColorDialog
- \inmodule QtQuick.Dialogs
- \internal
-
- \brief The QQuickPlatformColorDialog class provides a color dialog
-
- The dialog is implemented via the QPlatformColorDialogHelper when possible;
- otherwise it falls back to a QColorDialog or a QML implementation.
-
- \since 5.1
-*/
-
-/*!
- Constructs a color dialog with parent window \a parent.
-*/
-QQuickPlatformColorDialog::QQuickPlatformColorDialog(QObject *parent) :
- QQuickAbstractColorDialog(parent)
-{
-}
-
-/*!
- Destroys the color dialog.
-*/
-QQuickPlatformColorDialog::~QQuickPlatformColorDialog()
-{
- if (m_dlgHelper)
- m_dlgHelper->hide();
- delete m_dlgHelper;
-}
-
-QPlatformColorDialogHelper *QQuickPlatformColorDialog::helper()
-{
- QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
- if (parentItem)
- m_parentWindow = parentItem->window();
-
- if ( !m_dlgHelper && QGuiApplicationPrivate::platformTheme()->
- usePlatformNativeDialog(QPlatformTheme::ColorDialog) ) {
- m_dlgHelper = static_cast<QPlatformColorDialogHelper *>(QGuiApplicationPrivate::platformTheme()
- ->createPlatformDialogHelper(QPlatformTheme::ColorDialog));
- 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(currentColorChanged(QColor)), this, SLOT(setCurrentColor(QColor)));
- connect(m_dlgHelper, SIGNAL(colorSelected(QColor)), this, SLOT(setColor(QColor)));
- }
-
- return m_dlgHelper;
-}
-
-/*!
- \qmlproperty bool ColorDialog::visible
-
- This property holds whether the dialog is visible. By default this is
- false.
-
- \sa modality
-*/
-
-/*!
- \qmlproperty Qt::WindowModality ColorDialog::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 NonModal.
-
- 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.
-
- On MacOS the color dialog is only allowed to be non-modal.
-*/
-
-/*!
- \qmlmethod void ColorDialog::open()
-
- Shows the dialog to the user. It is equivalent to setting \l visible to
- true.
-*/
-
-/*!
- \qmlmethod void ColorDialog::close()
-
- Closes the dialog.
-*/
-
-/*!
- \qmlproperty string ColorDialog::title
-
- The title of the dialog window.
-*/
-
-/*!
- \qmlproperty bool ColorDialog::showAlphaChannel
-
- Whether the dialog will provide a means of changing the opacity.
-
- By default, this property is true. This property must be set to the desired
- value before opening the dialog. Usually the alpha channel is represented
- by an additional slider control.
-*/
-
-/*!
- \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/qquickplatformcolordialog_p.h b/src/imports/dialogs/qquickplatformcolordialog_p.h
deleted file mode 100644
index 55d301da8b..0000000000
--- a/src/imports/dialogs/qquickplatformcolordialog_p.h
+++ /dev/null
@@ -1,78 +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 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 QQUICKPLATFORMCOLORDIALOG_P_H
-#define QQUICKPLATFORMCOLORDIALOG_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 "qquickabstractcolordialog_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPlatformColorDialog : public QQuickAbstractColorDialog
-{
- Q_OBJECT
-
-public:
- QQuickPlatformColorDialog(QObject *parent = 0);
- virtual ~QQuickPlatformColorDialog();
-
-protected:
- QPlatformColorDialogHelper *helper();
-
- Q_DISABLE_COPY(QQuickPlatformColorDialog)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickPlatformColorDialog *)
-
-#endif // QQUICKPLATFORMCOLORDIALOG_P_H
diff --git a/src/imports/dialogs/qquickplatformfiledialog.cpp b/src/imports/dialogs/qquickplatformfiledialog.cpp
deleted file mode 100644
index 066aabe336..0000000000
--- a/src/imports/dialogs/qquickplatformfiledialog.cpp
+++ /dev/null
@@ -1,314 +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 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 "qquickplatformfiledialog_p.h"
-#include "qquickitem.h"
-
-#include <private/qguiapplication_p.h>
-#include <QWindow>
-#include <QQuickView>
-#include <QQuickWindow>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype FileDialog
- \instantiates QQuickPlatformFileDialog
- \inqmlmodule QtQuick.Dialogs 1
- \ingroup dialogs
- \brief Dialog component for choosing files from a local filesystem.
- \since 5.1
-
- FileDialog provides a basic file chooser: it allows the user to select
- existing files and/or directories, or create new filenames. 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 file dialog and exit after the user
- chooses a file:
-
- \qml
- import QtQuick 2.1
- import QtQuick.Dialogs 1.0
-
- FileDialog {
- id: fileDialog
- title: "Please choose a file"
- onAccepted: {
- console.log("You chose: " + fileDialog.fileUrls)
- Qt.quit()
- }
- onRejected: {
- console.log("Canceled")
- Qt.quit()
- }
- Component.onCompleted: visible = true
- }
- \endqml
-
- A FileDialog 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 FileDialog will be a platform file dialog if
- possible. If that isn't possible, then it will try to instantiate a
- \l QFileDialog. If that also isn't possible, then it will fall back to a QML
- implementation, DefaultFileDialog.qml. In that case you can customize the
- appearance by editing this file. DefaultFileDialog.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::FileDialog::accepted
-
- This handler is called when the user has finished using the
- dialog. You can then inspect the \l fileUrl or \l fileUrls properties to
- get the selection.
-
- Example:
-
- \qml
- FileDialog {
- onAccepted: { console.log("Selected file: " + fileUrl) }
- }
- \endqml
-*/
-
-/*!
- \qmlsignal QtQuick::Dialogs::FileDialog::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 QQuickPlatformFileDialog
- \inmodule QtQuick.Dialogs
- \internal
-
- \brief The QQuickPlatformFileDialog class provides a file dialog
-
- The dialog is implemented via the QPlatformFileDialogHelper when possible;
- otherwise it falls back to a QFileDialog or a QML implementation.
-
- \since 5.1
-*/
-
-/*!
- Constructs a file dialog with parent window \a parent.
-*/
-QQuickPlatformFileDialog::QQuickPlatformFileDialog(QObject *parent) :
- QQuickAbstractFileDialog(parent)
-{
-}
-
-/*!
- Destroys the file dialog.
-*/
-QQuickPlatformFileDialog::~QQuickPlatformFileDialog()
-{
- if (m_dlgHelper)
- m_dlgHelper->hide();
- delete m_dlgHelper;
-}
-
-QPlatformFileDialogHelper *QQuickPlatformFileDialog::helper()
-{
- QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
- if (parentItem)
- m_parentWindow = parentItem->window();
-
- if ( !m_dlgHelper && QGuiApplicationPrivate::platformTheme()->
- usePlatformNativeDialog(QPlatformTheme::FileDialog) ) {
- m_dlgHelper = static_cast<QPlatformFileDialogHelper *>(QGuiApplicationPrivate::platformTheme()
- ->createPlatformDialogHelper(QPlatformTheme::FileDialog));
- if (!m_dlgHelper)
- return m_dlgHelper;
- connect(m_dlgHelper, SIGNAL(directoryEntered(QUrl)), this, SIGNAL(folderChanged()));
- connect(m_dlgHelper, SIGNAL(filterSelected(QString)), this, SIGNAL(filterSelected()));
- connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
- connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
- }
-
- return m_dlgHelper;
-}
-
-/*!
- \qmlproperty bool FileDialog::visible
-
- This property holds whether the dialog is visible. By default this is
- false.
-
- \sa modality
-*/
-
-/*!
- \qmlproperty Qt::WindowModality FileDialog::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. You probably need to write an onAccepted handler
- to actually load or save the chosen file.
-*/
-
-/*!
- \qmlmethod void FileDialog::open()
-
- Shows the dialog to the user. It is equivalent to setting \l visible to
- true.
-*/
-
-/*!
- \qmlmethod void FileDialog::close()
-
- Closes the dialog.
-*/
-
-/*!
- \qmlproperty string FileDialog::title
-
- The title of the dialog window.
-*/
-
-/*!
- \qmlproperty bool FileDialog::selectExisting
-
- Whether only existing files or directories can be selected.
-
- By default, this property is true. This property must be set to the desired
- value before opening the dialog. Setting this property to false implies
- that the dialog is for naming a file to which to save something, or naming
- a folder to be created; therefore \l selectMultiple must be false.
-*/
-
-/*!
- \qmlproperty bool FileDialog::selectMultiple
-
- Whether more than one filename can be selected.
-
- By default, this property is false. This property must be set to the
- desired value before opening the dialog. Setting this property to true
- implies that \l selectExisting must be true.
-*/
-
-/*!
- \qmlproperty bool FileDialog::selectFolder
-
- Whether the selected item should be a folder.
-
- By default, this property is false. This property must be set to the
- desired value before opening the dialog. Setting this property to true
- implies that \l selectMultiple must be false and \l selectExisting must be
- true.
-*/
-
-/*!
- \qmlproperty url FileDialog::folder
-
- The path to the currently selected folder. Setting this property before
- invoking open() will cause the file browser to be initially positioned on
- the specified folder.
-
- The value of this property is also updated after the dialog is closed.
-
- By default, this property is false.
-*/
-
-/*!
- \qmlproperty list<string> FileDialog::nameFilters
-
- A list of strings to be used as file name filters. Each string can be a
- space-separated list of filters; filters may include the ? and * wildcards.
- The list of filters can also be enclosed in parentheses and a textual
- description of the filter can be provided.
-
- For example:
-
- \qml
- FileDialog {
- nameFilters: [ "Image files (*.jpg *.png)", "All files (*)" ]
- }
- \endqml
-
- \note Directories are not excluded by filters.
- \sa selectedNameFilter
-*/
-
-/*!
- \qmlproperty string FileDialog::selectedNameFilter
-
- Which of the \l nameFilters is currently selected.
-
- This property can be set before the dialog is visible, to set the default
- name filter, and can also be set while the dialog is visible to set the
- current name filter. It is also updated when the user selects a different
- filter.
-*/
-
-/*!
- \qmlproperty url FileDialog::fileUrl
-
- The path of the file which was selected by the user.
-
- \note This property is set only if exactly one file was selected. In all
- other cases, it will be empty.
-
- \sa fileUrls
-*/
-
-/*!
- \qmlproperty list<url> FileDialog::fileUrls
-
- The list of file paths which were selected by the user.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickplatformfiledialog_p.h b/src/imports/dialogs/qquickplatformfiledialog_p.h
deleted file mode 100644
index 5431836271..0000000000
--- a/src/imports/dialogs/qquickplatformfiledialog_p.h
+++ /dev/null
@@ -1,78 +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 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 QQUICKPLATFORMFILEDIALOG_P_H
-#define QQUICKPLATFORMFILEDIALOG_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 "qquickabstractfiledialog_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPlatformFileDialog : public QQuickAbstractFileDialog
-{
- Q_OBJECT
-
-public:
- QQuickPlatformFileDialog(QObject *parent = 0);
- virtual ~QQuickPlatformFileDialog();
-
-protected:
- QPlatformFileDialogHelper *helper();
-
- Q_DISABLE_COPY(QQuickPlatformFileDialog)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickPlatformFileDialog *)
-
-#endif // QQUICKPLATFORMFILEDIALOG_P_H
diff --git a/src/imports/dialogs/qquickplatformfontdialog.cpp b/src/imports/dialogs/qquickplatformfontdialog.cpp
deleted file mode 100644
index 46ad5eb8df..0000000000
--- a/src/imports/dialogs/qquickplatformfontdialog.cpp
+++ /dev/null
@@ -1,252 +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 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
- \ingroup dialogs
- \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/qquickplatformmessagedialog.cpp b/src/imports/dialogs/qquickplatformmessagedialog.cpp
deleted file mode 100644
index 65114100d2..0000000000
--- a/src/imports/dialogs/qquickplatformmessagedialog.cpp
+++ /dev/null
@@ -1,398 +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 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 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 \c 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
-
- There are several possible handlers depending on which \l standardButtons
- the dialog has and the \l {QMessageBox::ButtonRole} {ButtonRole} of each.
- For example, the \l {rejected} {onRejected} handler will be called if the
- user presses a \gui Cancel, \gui Close or \gui Abort button.
-
- 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, \c DefaultMessageDialog.qml. In that case you can customize
- the appearance by editing this file. \c DefaultMessageDialog.qml contains a
- \l 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 \l Window if possible, or simply
- reparented on top of the main window if there can only be one window.
-*/
-
-/*!
- \qmlsignal MessageDialog::accepted()
-
- This handler is called when the user has pressed any button which has the
- \l {QMessageBox::AcceptRole} {AcceptRole}: \gui OK, \gui Open, \gui Save,
- \gui {Save All}, \gui Retry or \gui Ignore.
-*/
-
-/*!
- \qmlsignal MessageDialog::rejected()
-
- This handler is called when the user has dismissed the dialog, by closing
- the dialog window, by pressing a \gui Cancel, \gui Close or \gui Abort
- button on the dialog, or by pressing the back button or the escape key.
-*/
-
-/*!
- \qmlsignal MessageDialog::discard()
-
- This handler is called when the user has pressed the \gui Discard button.
-*/
-
-/*!
- \qmlsignal MessageDialog::help()
-
- This handler is called when the user has pressed the \gui Help button.
- Depending on platform, the dialog may not be automatically dismissed
- because the help that your application provides may need to be relevant to
- the text shown in this dialog in order to assist the user in making a
- decision. However on other platforms it's not possible to show a dialog and
- a help window at the same time. If you want to be sure that the dialog will
- close, you can set \l visible to \c false in your handler.
-*/
-
-/*!
- \qmlsignal MessageDialog::yes()
-
- This handler is called when the user has pressed any button which has
- the \l {QMessageBox::YesRole} {YesRole}: \gui Yes or \gui {Yes to All}.
-*/
-
-/*!
- \qmlsignal MessageDialog::no()
-
- This handler is called when the user has pressed any button which has
- the \l {QMessageBox::NoRole} {NoRole}: \gui No or \gui {No to All}.
-*/
-
-/*!
- \qmlsignal MessageDialog::apply()
-
- This handler is called when the user has pressed the \gui Apply button.
-*/
-
-/*!
- \qmlsignal MessageDialog::reset()
-
- This handler is called when the user has pressed any button which has
- the \l {QMessageBox::ResetRole} {ResetRole}: \gui Reset or \gui {Restore Defaults}.
-*/
-
-/*!
- \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;
- // accept() shouldn't be emitted. reject() happens only if the dialog is
- // dismissed by closing the window rather than by one of its button widgets.
- connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
- connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
- connect(m_dlgHelper, SIGNAL(clicked(QMessageDialogOptions::StandardButton, QMessageDialogOptions::ButtonRole)),
- this, SLOT(click(QMessageDialogOptions::StandardButton, QMessageDialogOptions::ButtonRole)));
- }
-
- return m_dlgHelper;
-}
-
-/*!
- \qmlproperty bool MessageDialog::visible
-
- This property holds whether the dialog is visible. By default this is
- \c 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 until the dialog is dismissed.
-*/
-
-/*!
- \qmlmethod void MessageDialog::open()
-
- Shows the dialog to the user. It is equivalent to setting \l visible to
- \c true.
-*/
-
-/*!
- \qmlmethod void MessageDialog::close()
-
- Closes the dialog.
-*/
-
-/*!
- \qmlproperty string MessageDialog::title
-
- The title of the dialog window.
-*/
-
-/*!
- \qmlproperty string MessageDialog::text
-
- The primary text to be displayed.
-*/
-
-/*!
- \qmlproperty string MessageDialog::informativeText
-
- The informative text that provides a fuller description for the message.
-
- Informative text can be used to supplement the \c text to give more
- information to the user. Depending on the platform, it may appear in a
- smaller font below the text, or simply appended to the text.
-
- \sa {MessageDialog::text}{text}
-*/
-
-/*!
- \qmlproperty string MessageDialog::detailedText
-
- The text to be displayed in the details area, which is hidden by default.
- The user will then be able to press the \gui {Show Details...} button to
- make it visible.
-
- \sa {MessageDialog::text}{text}
-*/
-
-/*!
- \enum QQuickStandardIcon::Icon
-
- This enum specifies a standard icon to be used on a dialog.
-*/
-
-/*!
- \qmlproperty QQuickStandardIcon::Icon MessageDialog::icon
-
- The icon of the message box can be specified with one of these values:
-
- \table
- \row
- \li no icon
- \li \l StandardIcon.NoIcon
- \li For an unadorned text alert.
- \row
- \li \inlineimage ../images/question.png "Question icon"
- \li \l StandardIcon.Question
- \li For asking a question during normal operations.
- \row
- \li \image information.png
- \li \l StandardIcon.Information
- \li For reporting information about normal operations.
- \row
- \li \image warning.png
- \li \l StandardIcon.Warning
- \li For reporting non-critical errors.
- \row
- \li \image critical.png
- \li \l StandardIcon.Critical
- \li For reporting critical errors.
- \endtable
-
- The default is \c StandardIcon.NoIcon.
-
- The enum values are the same as in \l QMessageBox::Icon.
-*/
-
-// TODO after QTBUG-35019 is fixed: fix links to this module's enums
-// rather than linking to those in QMessageBox
-/*!
- \enum QQuickStandardButton::StandardButton
-
- This enum specifies a button with a standard label to be used on a dialog.
-*/
-
-/*!
- \qmlproperty StandardButtons MessageDialog::standardButtons
-
- The MessageDialog has a row of buttons along the bottom, each of which has
- a \l {QMessageBox::ButtonRole} {ButtonRole} that determines which signal
- will be emitted when the button is pressed. You can also find out which
- specific button was pressed after the fact via the \l clickedButton
- property. You can control which buttons are available by setting
- standardButtons to a bitwise-or combination of the following flags:
-
- \table
- \row \li StandardButton.Ok \li An \gui OK button defined with the \l {QMessageBox::AcceptRole} {AcceptRole}.
- \row \li StandardButton.Open \li An \gui Open button defined with the \l {QMessageBox::AcceptRole} {AcceptRole}.
- \row \li StandardButton.Save \li A \gui Save button defined with the \l {QMessageBox::AcceptRole} {AcceptRole}.
- \row \li StandardButton.Cancel \li A \gui Cancel button defined with the \l {QMessageBox::RejectRole} {RejectRole}.
- \row \li StandardButton.Close \li A \gui Close button defined with the \l {QMessageBox::RejectRole} {RejectRole}.
- \row \li StandardButton.Discard \li A \gui Discard or \gui {Don't Save} button, depending on the platform,
- defined with the \l {QMessageBox::DestructiveRole} {DestructiveRole}.
- \row \li StandardButton.Apply \li An \gui Apply button defined with the \l {QMessageBox::ApplyRole} {ApplyRole}.
- \row \li StandardButton.Reset \li A \gui Reset button defined with the \l {QMessageBox::ResetRole} {ResetRole}.
- \row \li StandardButton.RestoreDefaults \li A \gui {Restore Defaults} button defined with the \l {QMessageBox::ResetRole} {ResetRole}.
- \row \li StandardButton.Help \li A \gui Help button defined with the \l {QMessageBox::HelpRole} {HelpRole}.
- \row \li StandardButton.SaveAll \li A \gui {Save All} button defined with the \l {QMessageBox::AcceptRole} {AcceptRole}.
- \row \li StandardButton.Yes \li A \gui Yes button defined with the \l {QMessageBox::YesRole} {YesRole}.
- \row \li StandardButton.YesToAll \li A \gui {Yes to All} button defined with the \l {QMessageBox::YesRole} {YesRole}.
- \row \li StandardButton.No \li A \gui No button defined with the \l {QMessageBox::NoRole} {NoRole}.
- \row \li StandardButton.NoToAll \li A \gui {No to All} button defined with the \l {QMessageBox::NoRole} {NoRole}.
- \row \li StandardButton.Abort \li An \gui Abort button defined with the \l {QMessageBox::RejectRole} {RejectRole}.
- \row \li StandardButton.Retry \li A \gui Retry button defined with the \l {QMessageBox::AcceptRole} {AcceptRole}.
- \row \li StandardButton.Ignore \li An \gui Ignore button defined with the \l {QMessageBox::AcceptRole} {AcceptRole}.
- \endtable
-
- For example the following dialog will ask a question with 5 possible answers:
-
- \qml
- import QtQuick 2.2
- import QtQuick.Dialogs 1.1
-
- MessageDialog {
- title: "Overwrite?"
- icon: StandardIcon.Question
- text: "file.txt already exists. Replace?"
- detailedText: "To replace a file means that its existing contents will be lost. " +
- "The file that you are copying now will be copied over it instead."
- standardButtons: StandardButton.Yes | StandardButton.YesToAll |
- StandardButton.No | StandardButton.NoToAll | StandardButton.Abort
- Component.onCompleted: visible = true
- onYes: console.log("copied")
- onNo: console.log("didn't copy")
- onRejected: console.log("aborted")
- }
- \endqml
-
- \image replacefile.png
-
- The default is \c StandardButton.Ok.
-
- The enum values are the same as in \l QMessageBox::StandardButtons.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickplatformmessagedialog_p.h b/src/imports/dialogs/qquickplatformmessagedialog_p.h
deleted file mode 100644
index 61f055bb38..0000000000
--- a/src/imports/dialogs/qquickplatformmessagedialog_p.h
+++ /dev/null
@@ -1,78 +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 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/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
index f425eaa220..5ed38db3d7 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
@@ -96,10 +96,10 @@ void QQuickFolderListModelPrivate::init()
{
Q_Q(QQuickFolderListModel);
qRegisterMetaType<QList<FileProperty> >("QList<FileProperty>");
- q->connect(&fileInfoThread, SIGNAL(directoryChanged(QString, QList<FileProperty>)),
- q, SLOT(_q_directoryChanged(QString, QList<FileProperty>)));
- q->connect(&fileInfoThread, SIGNAL(directoryUpdated(QString, QList<FileProperty>, int, int)),
- q, SLOT(_q_directoryUpdated(QString, QList<FileProperty>, int, int)));
+ q->connect(&fileInfoThread, SIGNAL(directoryChanged(QString,QList<FileProperty>)),
+ q, SLOT(_q_directoryChanged(QString,QList<FileProperty>)));
+ q->connect(&fileInfoThread, SIGNAL(directoryUpdated(QString,QList<FileProperty>,int,int)),
+ q, SLOT(_q_directoryUpdated(QString,QList<FileProperty>,int,int)));
q->connect(&fileInfoThread, SIGNAL(sortFinished(QList<FileProperty>)),
q, SLOT(_q_sortFinished(QList<FileProperty>)));
q->connect(q, SIGNAL(rowCountChanged()), q, SIGNAL(countChanged()));
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index 3f15755211..f1d262a6c3 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -11,11 +11,7 @@ qtHaveModule(quick) {
qtquick2 \
particles \
window \
- dialogs-private \
- dialogs \
testlib
}
qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel
-
-qtHaveModule(quick):qtHaveModule(widgets): SUBDIRS += widgets
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 48693dbbf3..7a7649c6f1 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -101,14 +101,14 @@ V8_DEFINE_EXTENSION(QQmlSqlDatabaseData, databaseData)
class QQmlSqlDatabaseWrapper : public Object
{
- Q_MANAGED
+ V4_OBJECT
public:
enum Type { Database, Query, Rows };
QQmlSqlDatabaseWrapper(QV8Engine *e)
: Object(QV8Engine::getV4(e)), type(Database), inTransaction(false), readonly(false), forwardOnly(false)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
~QQmlSqlDatabaseWrapper() {
@@ -131,7 +131,8 @@ public:
bool forwardOnly; // type == Rows
};
-DEFINE_MANAGED_VTABLE(QQmlSqlDatabaseWrapper);
+DEFINE_REF(QQmlSqlDatabaseWrapper, Object);
+DEFINE_OBJECT_VTABLE(QQmlSqlDatabaseWrapper);
static ReturnedValue qmlsqldatabase_version(CallContext *ctx)
{
@@ -206,7 +207,7 @@ static QString qmlsqldatabase_databaseFile(const QString& connectionName, QV8Eng
return qmlsqldatabase_databasesPath(engine) + QDir::separator() + connectionName;
}
-static ReturnedValue qmlsqldatabase_rows_index(QV4::Referenced<QQmlSqlDatabaseWrapper> r, ExecutionEngine *v4, quint32 index, bool *hasProperty = 0)
+static ReturnedValue qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapperRef r, ExecutionEngine *v4, quint32 index, bool *hasProperty = 0)
{
Scope scope(v4);
QV8Engine *v8 = v4->v8Engine;
@@ -281,7 +282,7 @@ static ReturnedValue qmlsqldatabase_executeSql(CallContext *ctx)
ScopedValue values(scope, ctx->callData->args[1]);
if (values->asArrayObject()) {
ScopedArrayObject array(scope, values);
- quint32 size = array->arrayLength();
+ quint32 size = array->getLength();
QV4::ScopedValue v(scope);
for (quint32 ii = 0; ii < size; ++ii)
query.bindValue(ii, engine->toVariant((v = array->getIndexed(ii)), -1));
diff --git a/src/imports/settings/qqmlsettings.cpp b/src/imports/settings/qqmlsettings.cpp
index 011a39f20c..128eb9ed38 100644
--- a/src/imports/settings/qqmlsettings.cpp
+++ b/src/imports/settings/qqmlsettings.cpp
@@ -273,6 +273,9 @@ QSettings *QQmlSettingsPrivate::instance() const
void QQmlSettingsPrivate::init()
{
if (!initialized) {
+#ifdef SETTINGS_DEBUG
+ qDebug() << "QQmlSettings: stored at" << instance()->fileName();
+#endif
load();
initialized = true;
}
diff --git a/src/imports/widgets/plugins.qmltypes b/src/imports/widgets/plugins.qmltypes
deleted file mode 100644
index a67443c5b7..0000000000
--- a/src/imports/widgets/plugins.qmltypes
+++ /dev/null
@@ -1,302 +0,0 @@
-import QtQuick.tooling 1.1
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.PrivateWidgets 1.1'
-
-Module {
- Component {
- name: "QQuickAbstractColorDialog"
- 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"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setModality"
- Parameter { name: "m"; type: "Qt::WindowModality" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "t"; type: "string" }
- }
- Method {
- name: "setColor"
- Parameter { name: "arg"; type: "QColor" }
- }
- Method {
- name: "setCurrentColor"
- Parameter { name: "currentColor"; type: "QColor" }
- }
- Method {
- name: "setShowAlphaChannel"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickAbstractDialog"
- prototype: "QObject"
- Property { name: "visible"; type: "bool" }
- Property { name: "modality"; type: "Qt::WindowModality" }
- Property { name: "title"; type: "string" }
- Property { name: "isWindow"; type: "bool"; isReadonly: true }
- Property { name: "x"; type: "int" }
- Property { name: "y"; type: "int" }
- Property { name: "width"; type: "int" }
- Property { name: "height"; type: "int" }
- Signal { name: "visibilityChanged" }
- Signal { name: "geometryChanged" }
- Signal { name: "accepted" }
- 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"
- prototype: "QQuickAbstractDialog"
- Property { name: "selectExisting"; type: "bool" }
- Property { name: "selectMultiple"; type: "bool" }
- Property { name: "selectFolder"; type: "bool" }
- Property { name: "folder"; type: "QUrl" }
- Property { name: "nameFilters"; type: "QStringList" }
- Property { name: "selectedNameFilter"; type: "string" }
- Property { name: "fileUrl"; type: "QUrl"; isReadonly: true }
- Property { name: "fileUrls"; type: "QList<QUrl>"; isReadonly: true }
- Signal { name: "filterSelected" }
- Signal { name: "fileModeChanged" }
- Signal { name: "selectionAccepted" }
- Method {
- name: "setVisible"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "t"; type: "string" }
- }
- Method {
- name: "setSelectExisting"
- Parameter { name: "s"; type: "bool" }
- }
- Method {
- name: "setSelectMultiple"
- Parameter { name: "s"; type: "bool" }
- }
- Method {
- name: "setSelectFolder"
- Parameter { name: "s"; type: "bool" }
- }
- Method {
- name: "setFolder"
- Parameter { name: "f"; type: "QUrl" }
- }
- Method {
- name: "setNameFilters"
- Parameter { name: "f"; type: "QStringList" }
- }
- Method {
- name: "selectNameFilter"
- Parameter { name: "f"; type: "string" }
- }
- }
- Component {
- name: "QQuickAbstractFontDialog"
- prototype: "QQuickAbstractDialog"
- Property { name: "scalableFonts"; type: "bool" }
- Property { name: "nonScalableFonts"; type: "bool" }
- Property { name: "monospacedFonts"; type: "bool" }
- Property { name: "proportionalFonts"; type: "bool" }
- Property { name: "font"; type: "QFont" }
- Signal { name: "selectionAccepted" }
- Method {
- name: "setVisible"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setModality"
- Parameter { name: "m"; type: "Qt::WindowModality" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "t"; type: "string" }
- }
- Method {
- name: "setFont"
- Parameter { name: "arg"; type: "QFont" }
- }
- Method {
- name: "setScalableFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setNonScalableFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setMonospacedFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- Method {
- name: "setProportionalFonts"
- Parameter { name: "arg"; type: "bool" }
- }
- }
- Component {
- name: "QQuickAbstractMessageDialog"
- prototype: "QQuickAbstractDialog"
- exports: ["QtQuick.PrivateWidgets/QtMessageDialog 1.1"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Icon"
- values: {
- "NoIcon": 0,
- "Information": 1,
- "Warning": 2,
- "Critical": 3,
- "Question": 4
- }
- }
- Enum {
- name: "StandardButton"
- values: {
- "NoButton": 0,
- "Ok": 1024,
- "Save": 2048,
- "SaveAll": 4096,
- "Open": 8192,
- "Yes": 16384,
- "YesToAll": 32768,
- "No": 65536,
- "NoToAll": 131072,
- "Abort": 262144,
- "Retry": 524288,
- "Ignore": 1048576,
- "Close": 2097152,
- "Cancel": 4194304,
- "Discard": 8388608,
- "Help": 16777216,
- "Apply": 33554432,
- "Reset": 67108864,
- "RestoreDefaults": 134217728
- }
- }
- Enum {
- name: "StandardButtons"
- values: {
- "NoButton": 0,
- "Ok": 1024,
- "Save": 2048,
- "SaveAll": 4096,
- "Open": 8192,
- "Yes": 16384,
- "YesToAll": 32768,
- "No": 65536,
- "NoToAll": 131072,
- "Abort": 262144,
- "Retry": 524288,
- "Ignore": 1048576,
- "Close": 2097152,
- "Cancel": 4194304,
- "Discard": 8388608,
- "Help": 16777216,
- "Apply": 33554432,
- "Reset": 67108864,
- "RestoreDefaults": 134217728
- }
- }
- Property { name: "text"; type: "string" }
- Property { name: "informativeText"; type: "string" }
- Property { name: "detailedText"; type: "string" }
- Property { name: "icon"; type: "Icon" }
- Property { name: "standardIconSource"; type: "QUrl"; isReadonly: true }
- Property { name: "standardButtons"; type: "StandardButtons" }
- Property { name: "clickedButton"; type: "StandardButton"; isReadonly: true }
- Signal { name: "buttonClicked" }
- Signal { name: "discard" }
- Signal { name: "help" }
- Signal { name: "yes" }
- Signal { name: "no" }
- Signal { name: "apply" }
- Signal { name: "reset" }
- Method {
- name: "setVisible"
- Parameter { name: "v"; type: "bool" }
- }
- Method {
- name: "setTitle"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setText"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setInformativeText"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setDetailedText"
- Parameter { name: "arg"; type: "string" }
- }
- Method {
- name: "setIcon"
- Parameter { name: "icon"; type: "Icon" }
- }
- Method {
- name: "setStandardButtons"
- Parameter { name: "buttons"; type: "StandardButtons" }
- }
- Method {
- name: "click"
- Parameter { name: "button"; type: "QMessageDialogOptions::StandardButton" }
- Parameter { type: "QMessageDialogOptions::ButtonRole" }
- }
- Method {
- name: "click"
- Parameter { name: "button"; type: "QQuickAbstractMessageDialog::StandardButton" }
- }
- }
- Component {
- name: "QQuickQColorDialog"
- prototype: "QQuickAbstractColorDialog"
- exports: ["QtQuick.PrivateWidgets/QtColorDialog 1.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickQFileDialog"
- prototype: "QQuickAbstractFileDialog"
- exports: ["QtQuick.PrivateWidgets/QtFileDialog 1.0"]
- exportMetaObjectRevisions: [0]
- }
- Component {
- name: "QQuickQFontDialog"
- prototype: "QQuickAbstractFontDialog"
- exports: ["QtQuick.PrivateWidgets/QtFontDialog 1.1"]
- exportMetaObjectRevisions: [0]
- }
-}
diff --git a/src/imports/widgets/qmessageboxhelper_p.h b/src/imports/widgets/qmessageboxhelper_p.h
deleted file mode 100644
index 4f1070f97d..0000000000
--- a/src/imports/widgets/qmessageboxhelper_p.h
+++ /dev/null
@@ -1,107 +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$
-**
-****************************************************************************/
-
-#ifndef QMESSAGEBOXHELPER_P_H
-#define QMESSAGEBOXHELPER_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 <QMessageBox>
-#include "../dialogs/qquickabstractmessagedialog_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QMessageBoxHelper : public QPlatformMessageDialogHelper
-{
- Q_OBJECT
-public:
- QMessageBoxHelper() {
- connect(&m_dialog, SIGNAL(accepted()), this, SIGNAL(accept()));
- connect(&m_dialog, SIGNAL(rejected()), this, SIGNAL(reject()));
- connect(&m_dialog, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*)));
- }
-
- 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;
-
-public Q_SLOTS:
- void buttonClicked(QAbstractButton* button) {
- emit clicked(static_cast<QMessageDialogOptions::StandardButton>(m_dialog.standardButton(button)),
- static_cast<QMessageDialogOptions::ButtonRole>(m_dialog.buttonRole(button)));
- }
-};
-
-QT_END_NAMESPACE
-
-#endif // QMESSAGEBOXHELPER_P_H
diff --git a/src/imports/widgets/qmldir b/src/imports/widgets/qmldir
deleted file mode 100644
index da63c98e61..0000000000
--- a/src/imports/widgets/qmldir
+++ /dev/null
@@ -1,4 +0,0 @@
-module QtQuick.PrivateWidgets
-plugin widgetsplugin
-classname QtQuick2PrivateWidgetsPlugin
-typeinfo plugins.qmltypes
diff --git a/src/imports/widgets/qquickqcolordialog.cpp b/src/imports/widgets/qquickqcolordialog.cpp
deleted file mode 100644
index ee27d147e7..0000000000
--- a/src/imports/widgets/qquickqcolordialog.cpp
+++ /dev/null
@@ -1,175 +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 "qquickqcolordialog_p.h"
-#include "qquickitem.h"
-
-#include <private/qguiapplication_p.h>
-#include <private/qqmlcontext_p.h>
-#include <QWindow>
-#include <QQuickWindow>
-#include <QColorDialog>
-
-QT_BEGIN_NAMESPACE
-
-class QColorDialogHelper : public QPlatformColorDialogHelper
-{
-public:
- QColorDialogHelper() :
- QPlatformColorDialogHelper()
- {
- connect(&m_dialog, SIGNAL(currentColorChanged(const QColor&)), this, SIGNAL(currentColorChanged(const QColor&)));
- connect(&m_dialog, SIGNAL(colorSelected(const QColor&)), this, SIGNAL(colorSelected(const QColor&)));
- connect(&m_dialog, SIGNAL(accepted()), this, SIGNAL(accept()));
- connect(&m_dialog, SIGNAL(rejected()), this, SIGNAL(reject()));
- }
-
- virtual void setCurrentColor(const QColor &c) { m_dialog.setCurrentColor(c); }
- virtual QColor currentColor() const { return m_dialog.currentColor(); }
-
- 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(QPlatformColorDialogHelper::options()->windowTitle());
- m_dialog.setOptions((QColorDialog::ColorDialogOptions)((int)(QPlatformColorDialogHelper::options()->options())));
- m_dialog.show();
- return m_dialog.isVisible();
- }
-
- virtual void hide() { m_dialog.hide(); }
-
-private:
- QColorDialog m_dialog;
-};
-
-/*!
- \qmltype QtColorDialog
- \instantiates QQuickQColorDialog
- \inqmlmodule QtQuick.PrivateWidgets 1
- \ingroup qtquick-visual
- \brief Dialog component for choosing a color.
- \since 5.1
- \internal
-
- QtColorDialog provides a means to instantiate and manage a QColorDialog.
- It is not recommended to be used directly; it is an implementation
- detail of \l ColorDialog 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.0
- \endcode
-*/
-
-/*!
- \qmlsignal QtQuick::Dialogs::ColorDialog::accepted
-
- The \a accepted signal is emitted when the user has finished using the
- dialog. You can then inspect the \a color property to get the selection.
-
- Example:
-
- \qml
- ColorDialog {
- onAccepted: { console.log("Selected color: " + color) }
- }
- \endqml
-*/
-
-/*!
- \qmlsignal QtQuick::Dialogs::ColorDialog::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 QQuickQColorDialog
- \inmodule QtQuick.PrivateWidgets
- \internal
-
- \brief The QQuickQColorDialog class is a wrapper for a QColorDialog.
-
- \since 5.1
-*/
-
-/*!
- Constructs a file dialog with parent window \a parent.
-*/
-QQuickQColorDialog::QQuickQColorDialog(QObject *parent)
- : QQuickAbstractColorDialog(parent)
-{
-}
-
-/*!
- Destroys the file dialog.
-*/
-QQuickQColorDialog::~QQuickQColorDialog()
-{
- if (m_dlgHelper)
- m_dlgHelper->hide();
- delete m_dlgHelper;
-}
-
-QPlatformColorDialogHelper *QQuickQColorDialog::helper()
-{
- QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
- if (parentItem)
- m_parentWindow = parentItem->window();
-
- if (!m_dlgHelper) {
- m_dlgHelper = new QColorDialogHelper();
- 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()));
- }
-
- return m_dlgHelper;
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/widgets/qquickqfiledialog.cpp b/src/imports/widgets/qquickqfiledialog.cpp
deleted file mode 100644
index 403577fabe..0000000000
--- a/src/imports/widgets/qquickqfiledialog.cpp
+++ /dev/null
@@ -1,215 +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 "qquickqfiledialog_p.h"
-#include "qquickitem.h"
-
-#include <private/qguiapplication_p.h>
-#include <private/qqmlcontext_p.h>
-#include <QWindow>
-#include <QQuickWindow>
-#include <QFileDialog>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmltype QtFileDialog
- \instantiates QQuickQFileDialog
- \inqmlmodule QtQuick.PrivateWidgets 1
- \ingroup qtquick-visual
- \brief Dialog component for choosing files from a local filesystem.
- \since 5.1
- \internal
-
- QtFileDialog provides a means to instantiate and manage a QFileDialog.
- It is not recommended to be used directly; it is an implementation
- detail of \l FileDialog 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.0
- \endcode
-*/
-
-/*!
- \qmlsignal QtQuick::Dialogs::FileDialog::accepted
-
- The \a accepted signal is emitted when the user has finished using the
- dialog. You can then inspect the \a fileUrl or \a fileUrls properties to
- get the selection.
-
- Example:
-
- \qml
- FileDialog {
- onAccepted: { console.log("Selected file: " + fileUrl) }
- }
- \endqml
-*/
-
-/*!
- \qmlsignal QtQuick::Dialogs::FileDialog::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 QQuickQFileDialog
- \inmodule QtQuick.PrivateWidgets
- \internal
-
- \brief The QQuickQFileDialog class is a wrapper for a QFileDialog.
-
- \since 5.1
-*/
-
-/*!
- Constructs a file dialog with parent window \a parent.
-*/
-QQuickQFileDialog::QQuickQFileDialog(QObject *parent)
- : QQuickAbstractFileDialog(parent)
-{
-}
-
-/*!
- Destroys the file dialog.
-*/
-QQuickQFileDialog::~QQuickQFileDialog()
-{
- if (m_dlgHelper)
- m_dlgHelper->hide();
- delete m_dlgHelper;
-}
-
-QPlatformFileDialogHelper *QQuickQFileDialog::helper()
-{
- QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
- if (parentItem)
- m_parentWindow = parentItem->window();
-
- if (!m_dlgHelper) {
- m_dlgHelper = new QFileDialogHelper();
- connect(m_dlgHelper, SIGNAL(directoryEntered(const QUrl &)), this, SIGNAL(folderChanged()));
- connect(m_dlgHelper, SIGNAL(filterSelected(const QString &)), this, SIGNAL(filterSelected()));
- connect(m_dlgHelper, SIGNAL(accept()), this, SLOT(accept()));
- connect(m_dlgHelper, SIGNAL(reject()), this, SLOT(reject()));
- }
-
- return m_dlgHelper;
-}
-
-QFileDialogHelper::QFileDialogHelper() :
- QPlatformFileDialogHelper()
-{
- connect(&m_dialog, SIGNAL(currentChanged(const QString&)), this, SLOT(currentChanged(const QString&)));
- connect(&m_dialog, SIGNAL(directoryEntered(const QString&)), this, SLOT(directoryEntered(const QString&)));
- connect(&m_dialog, SIGNAL(fileSelected(const QString&)), this, SLOT(fileSelected(const QString&)));
- connect(&m_dialog, SIGNAL(filesSelected(const QStringList&)), this, SLOT(filesSelected(const QStringList&)));
- connect(&m_dialog, SIGNAL(filterSelected(const QString&)), this, SIGNAL(filterSelected(const QString&)));
- connect(&m_dialog, SIGNAL(accepted()), this, SIGNAL(accept()));
- connect(&m_dialog, SIGNAL(rejected()), this, SIGNAL(reject()));
-}
-
-QList<QUrl> QFileDialogHelper::selectedFiles() const
-{
- return m_dialog.selectedUrls();
-}
-
-void QFileDialogHelper::setFilter() {
- m_dialog.setWindowTitle(QPlatformFileDialogHelper::options()->windowTitle());
- if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::LookIn))
- m_dialog.setLabelText(m_dialog.LookIn, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::LookIn));
- if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::FileName))
- m_dialog.setLabelText(m_dialog.FileName, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::FileName));
- if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::FileType))
- m_dialog.setLabelText(m_dialog.FileType, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::FileType));
- if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::Accept))
- m_dialog.setLabelText(m_dialog.Accept, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::Accept));
- if (QPlatformFileDialogHelper::options()->isLabelExplicitlySet(QFileDialogOptions::Reject))
- m_dialog.setLabelText(m_dialog.Reject, QPlatformFileDialogHelper::options()->labelText(QFileDialogOptions::Reject));
- m_dialog.setFilter(QPlatformFileDialogHelper::options()->filter());
- m_dialog.setNameFilters(QPlatformFileDialogHelper::options()->nameFilters());
- m_dialog.selectNameFilter(QPlatformFileDialogHelper::options()->initiallySelectedNameFilter());
- m_dialog.setFileMode(QFileDialog::FileMode(QPlatformFileDialogHelper::options()->fileMode()));
- m_dialog.setOptions((QFileDialog::Options)((int)(QPlatformFileDialogHelper::options()->options())));
- m_dialog.setAcceptMode(QFileDialog::AcceptMode(QPlatformFileDialogHelper::options()->acceptMode()));
-
- const QUrl initialDirectory = QPlatformFileDialogHelper::options()->initialDirectory();
- if (initialDirectory.isValid() && initialDirectory.isLocalFile())
- m_dialog.setDirectory(initialDirectory.toLocalFile());
-}
-
-bool QFileDialogHelper::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.show();
- return m_dialog.isVisible();
-}
-
-void QFileDialogHelper::currentChanged(const QString& path)
-{
- emit QPlatformFileDialogHelper::currentChanged(QUrl::fromLocalFile(path));
-}
-
-void QFileDialogHelper::directoryEntered(const QString& path)
-{
- emit QPlatformFileDialogHelper::directoryEntered(QUrl::fromLocalFile(path));
-}
-
-void QFileDialogHelper::fileSelected(const QString& path)
-{
- emit QPlatformFileDialogHelper::fileSelected(QUrl::fromLocalFile(path));
-}
-
-void QFileDialogHelper::filesSelected(const QStringList& paths)
-{
- QList<QUrl> pathUrls;
- foreach (const QString &path, paths)
- pathUrls << QUrl::fromLocalFile(path);
- emit QPlatformFileDialogHelper::filesSelected(pathUrls);
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/widgets/qquickqfiledialog_p.h b/src/imports/widgets/qquickqfiledialog_p.h
deleted file mode 100644
index 2bd364eba0..0000000000
--- a/src/imports/widgets/qquickqfiledialog_p.h
+++ /dev/null
@@ -1,107 +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$
-**
-****************************************************************************/
-
-#ifndef QQUICKQFILEDIALOG_P_H
-#define QQUICKQFILEDIALOG_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 <QFileDialog>
-#include "../dialogs/qquickabstractfiledialog_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QQuickQFileDialog : public QQuickAbstractFileDialog
-{
- Q_OBJECT
-
-public:
- QQuickQFileDialog(QObject *parent = 0);
- virtual ~QQuickQFileDialog();
-
-protected:
- QPlatformFileDialogHelper *helper();
-
- Q_DISABLE_COPY(QQuickQFileDialog)
-};
-
-class QFileDialogHelper : public QPlatformFileDialogHelper
-{
- Q_OBJECT
-public:
- QFileDialogHelper();
-
- bool defaultNameFilterDisables() const Q_DECL_OVERRIDE { return true; }
- void setDirectory(const QUrl &dir) Q_DECL_OVERRIDE { m_dialog.setDirectoryUrl(dir); }
- QUrl directory() const Q_DECL_OVERRIDE { return m_dialog.directoryUrl(); }
- void selectFile(const QUrl &f) Q_DECL_OVERRIDE { m_dialog.selectUrl(f); }
- QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
- void setFilter() Q_DECL_OVERRIDE;
- void selectNameFilter(const QString &f) Q_DECL_OVERRIDE { m_dialog.selectNameFilter(f); }
- QString selectedNameFilter() const Q_DECL_OVERRIDE { return m_dialog.selectedNameFilter(); }
- void exec() Q_DECL_OVERRIDE { m_dialog.exec(); }
- bool show(Qt::WindowFlags f, Qt::WindowModality m, QWindow *parent) Q_DECL_OVERRIDE;
- void hide() Q_DECL_OVERRIDE { m_dialog.hide(); }
-
-private Q_SLOTS:
- void currentChanged(const QString& path);
- void directoryEntered(const QString& path);
- void fileSelected(const QString& path);
- void filesSelected(const QStringList& paths);
-
-private:
- QFileDialog m_dialog;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickQFileDialog *)
-
-#endif // QQUICKQFILEDIALOG_P_H
diff --git a/src/imports/widgets/qquickqfontdialog.cpp b/src/imports/widgets/qquickqfontdialog.cpp
deleted file mode 100644
index 6d637e1ddb..0000000000
--- a/src/imports/widgets/qquickqfontdialog.cpp
+++ /dev/null
@@ -1,178 +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 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
deleted file mode 100644
index 6efd15995b..0000000000
--- a/src/imports/widgets/qquickqfontdialog_p.h
+++ /dev/null
@@ -1,78 +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 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
deleted file mode 100644
index 1b92efc5ef..0000000000
--- a/src/imports/widgets/qquickqmessagebox.cpp
+++ /dev/null
@@ -1,144 +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 "qquickqmessagebox_p.h"
-#include "qmessageboxhelper_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
-
-/*!
- \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;
-}
-
-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;
- // accept() shouldn't be emitted. reject() happens only if the dialog is
- // dismissed by closing the window rather than by one of its button widgets.
- connect(helper, SIGNAL(accept()), this, SLOT(accept()));
- connect(helper, SIGNAL(reject()), this, SLOT(reject()));
- connect(helper, SIGNAL(clicked(QMessageDialogOptions::StandardButton, QMessageDialogOptions::ButtonRole)),
- this, SLOT(click(QMessageDialogOptions::StandardButton, QMessageDialogOptions::ButtonRole)));
- }
-
- return QQuickAbstractMessageDialog::m_dlgHelper;
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro
deleted file mode 100644
index 5320838082..0000000000
--- a/src/imports/widgets/widgets.pro
+++ /dev/null
@@ -1,32 +0,0 @@
-CXX_MODULE = qml
-TARGET = widgetsplugin
-TARGETPATH = QtQuick/PrivateWidgets
-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 \
- qmessageboxhelper_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
-
-load(qml_plugin)
diff --git a/src/imports/widgets/widgetsplugin.cpp b/src/imports/widgets/widgetsplugin.cpp
deleted file mode 100644
index 05c3a5e86c..0000000000
--- a/src/imports/widgets/widgetsplugin.cpp
+++ /dev/null
@@ -1,89 +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 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 "qquickqmessagebox_p.h"
-#include "qquickqfiledialog_p.h"
-#include "qquickqcolordialog_p.h"
-#include "qquickqfontdialog_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmlmodule QtQuick.PrivateWidgets 1
- \title QWidget QML Types
- \ingroup qmlmodules
- \brief Provides QML types for certain QWidgets
- \internal
-
- This QML module contains types which should not be depended upon in Qt Quick
- applications, but are available if the Widgets module is linked. It is
- recommended to load components from this module conditionally, if at all,
- and to provide fallback implementations in case they fail to load.
-
- \code
- import QtQuick.PrivateWidgets 1.1
- \endcode
-
- \since 5.1
-*/
-
-class QtQuick2PrivateWidgetsPlugin : 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.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");
- }
-};
-
-QT_END_NAMESPACE
-
-#include "widgetsplugin.moc"
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
index 97dc3aba1f..0b9be3105b 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
@@ -44,7 +44,7 @@
#include <qqmlcontext.h>
#include <private/qqmlengine_p.h>
#include <private/qv8engine_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4engine_p.h>
#include <private/qv4object_p.h>
@@ -925,10 +925,12 @@ QQmlV4Handle QQuickXmlListModel::get(int index) const
ExecutionEngine *v4engine = QV8Engine::getV4(v8engine);
Scope scope(v4engine);
Scoped<Object> o(scope, v4engine->newObject());
+ ScopedString name(scope);
+ ScopedValue value(scope);
for (int ii = 0; ii < d->roleObjects.count(); ++ii) {
- ScopedString name(scope, v4engine->newIdentifier(d->roleObjects[ii]->name()));
- Property *p = o->insertMember(name, PropertyAttributes());
- p->value = v8engine->fromVariant(d->data.value(ii).value(index));
+ name = v4engine->newIdentifier(d->roleObjects[ii]->name());
+ value = v8engine->fromVariant(d->data.value(ii).value(index));
+ o->insertMember(name, value);
}
return QQmlV4Handle(o);
diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp
index d0e9a392d4..1d7b7abd9c 100644
--- a/src/particles/qquickv4particledata.cpp
+++ b/src/particles/qquickv4particledata.cpp
@@ -273,11 +273,11 @@ QT_BEGIN_NAMESPACE
//### Particle data handles are not locked to within certain scopes like QQuickContext2D, but there's no way to reload either...
struct QV4ParticleData : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
QV4ParticleData(QV4::ExecutionEngine *engine, QQuickParticleData *datum)
: Object(engine)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
this->datum = datum;
}
@@ -287,7 +287,7 @@ struct QV4ParticleData : public QV4::Object
{ that->as<QV4ParticleData>()->~QV4ParticleData(); }
};
-DEFINE_MANAGED_VTABLE(QV4ParticleData);
+DEFINE_OBJECT_VTABLE(QV4ParticleData);
class QV8ParticleDataDeletable : public QV8Engine::Deletable
{
diff --git a/src/particles/qquickv4particledata_p.h b/src/particles/qquickv4particledata_p.h
index b3614f94ff..10e9ecacc5 100644
--- a/src/particles/qquickv4particledata_p.h
+++ b/src/particles/qquickv4particledata_p.h
@@ -44,7 +44,7 @@
#include <private/qv8engine_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/quick/qaccessiblequickitem.cpp b/src/plugins/accessible/quick/qaccessiblequickitem.cpp
index 3521d4f98e..4b68574149 100644
--- a/src/plugins/accessible/quick/qaccessiblequickitem.cpp
+++ b/src/plugins/accessible/quick/qaccessiblequickitem.cpp
@@ -152,52 +152,24 @@ QList<QQuickItem *> QAccessibleQuickItem::childItems() const
QAccessible::State QAccessibleQuickItem::state() const
{
- QAccessible::State state;
+ QQuickAccessibleAttached *attached = QQuickAccessibleAttached::attachedProperties(item());
+ if (!attached)
+ return QAccessible::State();
- if (item()->hasActiveFocus()) {
- state.focusable = true;
- state.focused = true;
- }
-
- if (item()->activeFocusOnTab())
- state.focusable = true;
+ QAccessible::State st = attached->state();
if (!item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
- state.invisible = true;
+ st.invisible = true;
- QAccessible::Role r = role();
- switch (r) {
- case QAccessible::Button: {
- state.focusable = true;
- QVariant checkable = item()->property("checkable");
- if (!checkable.toBool())
- break;
- // fall through
- }
- case QAccessible::CheckBox:
- case QAccessible::RadioButton: {
- state.focusable = true;
- state.checkable = true;
- state.checked = item()->property("checked").toBool();
- break;
- }
- case QAccessible::MenuItem:
- case QAccessible::PageTab:
- case QAccessible::EditableText:
- case QAccessible::SpinBox:
- case QAccessible::Terminal:
- case QAccessible::ScrollBar:
- state.focusable = true;
- break;
- case QAccessible::ComboBox:
- state.focusable = true;
- state.editable = item()->property("editable").toBool();
- break;
- default:
- break;
- }
+ if (item()->activeFocusOnTab())
+ st.focusable = true;
+ if (item()->hasActiveFocus())
+ st.focused = true;
+
+ if (role() == QAccessible::ComboBox)
+ st.editable = item()->property("editable").toBool();
- return state;
+ return st;
}
QAccessible::Role QAccessibleQuickItem::role() const
diff --git a/src/plugins/accessible/shared/qqmlaccessible.cpp b/src/plugins/accessible/shared/qqmlaccessible.cpp
index d08f9bdb2c..ecf4e56acf 100644
--- a/src/plugins/accessible/shared/qqmlaccessible.cpp
+++ b/src/plugins/accessible/shared/qqmlaccessible.cpp
@@ -185,7 +185,7 @@ void QQmlAccessible::doAction(const QString &actionName)
// use the "stepSize" property on the item
if (QAccessibleValueInterface *valueIface = valueInterface()) {
QVariant valueV = valueIface->currentValue();
- qreal newValue = valueV.toInt();
+ qreal newValue = valueV.toReal();
QVariant stepSizeV = object()->property("stepSize");
qreal stepSize = stepSizeV.isValid() ? stepSizeV.toReal() : qreal(1.0);
diff --git a/src/plugins/qmltooling/shared/qpacketprotocol.cpp b/src/plugins/qmltooling/shared/qpacketprotocol.cpp
index 0792dadfe3..7de5a7648e 100644
--- a/src/plugins/qmltooling/shared/qpacketprotocol.cpp
+++ b/src/plugins/qmltooling/shared/qpacketprotocol.cpp
@@ -237,7 +237,7 @@ QPacketProtocol::~QPacketProtocol()
/*!
Returns the maximum packet size allowed. By default this is
2,147,483,647 bytes.
-
+
If a packet claiming to be larger than the maximum packet size is received,
the QPacketProtocol::invalidPacket() signal is emitted.
diff --git a/src/qml/compiler/compiler.pri b/src/qml/compiler/compiler.pri
index df4f5e8dc3..b2569f9111 100644
--- a/src/qml/compiler/compiler.pri
+++ b/src/qml/compiler/compiler.pri
@@ -15,7 +15,8 @@ HEADERS += \
$$PWD/qv4ssa_p.h \
$$PWD/qv4regalloc_p.h \
$$PWD/qqmlcodegenerator_p.h \
- $$PWD/qv4isel_masm_p.h
+ $$PWD/qv4isel_masm_p.h \
+ $$PWD/qqmltypecompiler_p.h
SOURCES += \
$$PWD/qv4compileddata.cpp \
@@ -28,6 +29,7 @@ SOURCES += \
$$PWD/qv4ssa.cpp \
$$PWD/qv4regalloc.cpp \
$$PWD/qqmlcodegenerator.cpp \
- $$PWD/qv4isel_masm.cpp
+ $$PWD/qv4isel_masm.cpp \
+ $$PWD/qqmltypecompiler.cpp
include(../../3rdparty/masm/masm.pri)
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 13b23fde68..f933465100 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -54,6 +54,8 @@
QT_USE_NAMESPACE
+static const quint32 emptyStringIndex = 0;
+
DEFINE_BOOL_CONFIG_OPTION(lookupHints, QML_LOOKUP_HINTS);
using namespace QtQml;
@@ -64,6 +66,22 @@ using namespace QtQml;
return false; \
}
+void QmlObject::init(MemoryPool *pool, int typeNameIndex, int id, const AST::SourceLocation &loc)
+{
+ inheritedTypeNameIndex = typeNameIndex;
+
+ location.line = loc.startLine;
+ location.column = loc.startColumn;
+
+ idIndex = id;
+ indexOfDefaultProperty = -1;
+ properties = pool->New<PoolList<QmlProperty> >();
+ qmlSignals = pool->New<PoolList<Signal> >();
+ bindings = pool->New<PoolList<Binding> >();
+ functions = pool->New<PoolList<Function> >();
+ declarationsOverride = 0;
+}
+
void QmlObject::dump(DebugStream &out)
{
out << inheritedTypeNameIndex << " {" << endl;
@@ -73,6 +91,95 @@ void QmlObject::dump(DebugStream &out)
out << "}" << endl;
}
+QString QmlObject::sanityCheckFunctionNames(const QList<CompiledFunctionOrExpression> &allFunctions, const QSet<QString> &illegalNames, AST::SourceLocation *errorLocation)
+{
+ QSet<int> functionNames;
+ for (Function *f = functions->first; f; f = f->next) {
+ AST::FunctionDeclaration *function = AST::cast<AST::FunctionDeclaration*>(allFunctions.at(f->index).node);
+ Q_ASSERT(function);
+ *errorLocation = function->identifierToken;
+ QString name = function->name.toString();
+ if (functionNames.contains(f->nameIndex))
+ return tr("Duplicate method name");
+ functionNames.insert(f->nameIndex);
+ if (signalNames.contains(f->nameIndex))
+ return tr("Duplicate method name");
+
+ if (name.at(0).isUpper())
+ return tr("Method names cannot begin with an upper case letter");
+ if (illegalNames.contains(name))
+ return tr("Illegal method name");
+ }
+ return QString(); // no error
+}
+
+QString QmlObject::appendSignal(Signal *signal)
+{
+ QmlObject *target = declarationsOverride;
+ if (!target)
+ target = this;
+ if (target->signalNames.contains(signal->nameIndex))
+ return tr("Duplicate signal name");
+ target->signalNames.insert(signal->nameIndex);
+ target->qmlSignals->append(signal);
+ return QString(); // no error
+}
+
+QString QmlObject::appendProperty(QmlProperty *prop, const QString &propertyName, bool isDefaultProperty, const AST::SourceLocation &defaultToken, AST::SourceLocation *errorLocation)
+{
+ QmlObject *target = declarationsOverride;
+ if (!target)
+ target = this;
+
+ if (target->propertyNames.contains(prop->nameIndex))
+ return tr("Duplicate property name");
+
+ if (propertyName.constData()->isUpper())
+ return tr("Property names cannot begin with an upper case letter");
+
+ target->propertyNames.insert(prop->nameIndex);
+
+ const int index = target->properties->append(prop);
+ if (isDefaultProperty) {
+ if (target->indexOfDefaultProperty != -1) {
+ *errorLocation = defaultToken;
+ return tr("Duplicate default property");
+ }
+ target->indexOfDefaultProperty = index;
+ }
+ return QString(); // no error
+}
+
+void QmlObject::appendFunction(Function *f)
+{
+ QmlObject *target = declarationsOverride;
+ if (!target)
+ target = this;
+ target->functions->append(f);
+}
+
+QString QmlObject::appendBinding(Binding *b, bool isListBinding)
+{
+ const bool bindingToDefaultProperty = (b->propertyNameIndex == 0);
+ if (!isListBinding && !bindingToDefaultProperty
+ && b->type != QV4::CompiledData::Binding::Type_GroupProperty
+ && b->type != QV4::CompiledData::Binding::Type_AttachedProperty
+ && !(b->flags & QV4::CompiledData::Binding::IsOnAssignment)) {
+ if (bindingNames.contains(b->propertyNameIndex))
+ return tr("Property value set multiple times");
+ bindingNames.insert(b->propertyNameIndex);
+ }
+ if (isListBinding) {
+ bindings->append(b);
+ } else if (bindingToDefaultProperty) {
+ Binding *insertionPoint = bindings->findSortedInsertionPoint<QV4::CompiledData::Location, QV4::CompiledData::Binding, &QV4::CompiledData::Binding::location>(b);
+ bindings->insertAfter(insertionPoint, b);
+ } else {
+ bindings->prepend(b);
+ }
+ return QString(); // no error
+}
+
QStringList Signal::parameterStringList(const QStringList &stringPool) const
{
QStringList result;
@@ -82,8 +189,10 @@ QStringList Signal::parameterStringList(const QStringList &stringPool) const
return result;
}
-QQmlCodeGenerator::QQmlCodeGenerator()
- : _object(0)
+QQmlCodeGenerator::QQmlCodeGenerator(const QSet<QString> &illegalNames)
+ : illegalNames(illegalNames)
+ , _object(0)
+ , _propertyDeclaration(0)
, jsGenerator(0)
{
}
@@ -132,7 +241,7 @@ bool QQmlCodeGenerator::generateFromQml(const QString &code, const QUrl &url, co
this->pool = output->jsParserEngine.pool();
this->jsGenerator = &output->jsGenerator;
- emptyStringIndex = registerString(QString());
+ Q_ASSERT(registerString(QString()) == emptyStringIndex);
sourceCode = code;
@@ -205,7 +314,7 @@ bool QQmlCodeGenerator::visit(AST::UiObjectDefinition *node)
int idx = defineQMLObject(node);
appendBinding(node->qualifiedTypeNameId->identifierToken, emptyStringIndex, idx);
} else {
- int idx = defineQMLObject(/*qualfied type name id*/0, node->initializer);
+ int idx = defineQMLObject(/*qualfied type name id*/0, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, /*declarations should go here*/_object);
appendBinding(node->qualifiedTypeNameId, idx);
}
return false;
@@ -213,8 +322,8 @@ bool QQmlCodeGenerator::visit(AST::UiObjectDefinition *node)
bool QQmlCodeGenerator::visit(AST::UiObjectBinding *node)
{
- int idx = defineQMLObject(node->qualifiedTypeNameId, node->initializer);
- appendBinding(node->qualifiedId, idx);
+ int idx = defineQMLObject(node->qualifiedTypeNameId, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer);
+ appendBinding(node->qualifiedId, idx, node->hasOnToken);
return false;
}
@@ -277,63 +386,31 @@ void QQmlCodeGenerator::accept(AST::Node *node)
AST::Node::acceptChild(node, this);
}
-bool QQmlCodeGenerator::sanityCheckFunctionNames()
-{
- QSet<QString> functionNames;
- for (Function *f = _object->functions->first; f; f = f->next) {
- AST::FunctionDeclaration *function = AST::cast<AST::FunctionDeclaration*>(_functions.at(f->index).node);
- Q_ASSERT(function);
- QString name = function->name.toString();
- if (functionNames.contains(name))
- COMPILE_EXCEPTION(function->identifierToken, tr("Duplicate method name"));
- functionNames.insert(name);
- if (_signalNames.contains(name))
- COMPILE_EXCEPTION(function->identifierToken, tr("Duplicate method name"));
-
- if (name.at(0).isUpper())
- COMPILE_EXCEPTION(function->identifierToken, tr("Method names cannot begin with an upper case letter"));
-#if 0 // ###
- if (enginePrivate->v8engine()->illegalNames().contains(currSlot.name.toString()))
- COMPILE_EXCEPTION(&currSlot, tr("Illegal method name"));
-#endif
- }
- return true;
-}
-
-int QQmlCodeGenerator::defineQMLObject(AST::UiQualifiedId *qualifiedTypeNameId, AST::UiObjectInitializer *initializer)
+int QQmlCodeGenerator::defineQMLObject(AST::UiQualifiedId *qualifiedTypeNameId, const AST::SourceLocation &location, AST::UiObjectInitializer *initializer, QmlObject *declarationsOverride)
{
QmlObject *obj = New<QmlObject>();
_objects.append(obj);
const int objectIndex = _objects.size() - 1;
qSwap(_object, obj);
- _object->inheritedTypeNameIndex = registerString(asString(qualifiedTypeNameId));
+ _object->init(pool, registerString(asString(qualifiedTypeNameId)), emptyStringIndex, location);
+ _object->declarationsOverride = declarationsOverride;
- AST::SourceLocation loc;
- if (qualifiedTypeNameId)
- loc = qualifiedTypeNameId->firstSourceLocation();
- _object->location.line = loc.startLine;
- _object->location.column = loc.startColumn;
-
- _object->idIndex = emptyStringIndex;
- _object->indexOfDefaultProperty = -1;
- _object->properties = New<PoolList<QmlProperty> >();
- _object->qmlSignals = New<PoolList<Signal> >();
- _object->bindings = New<PoolList<Binding> >();
- _object->functions = New<PoolList<Function> >();
-
- QSet<QString> propertyNames;
- qSwap(_propertyNames, propertyNames);
- QSet<QString> signalNames;
- qSwap(_signalNames, signalNames);
+ // A new object is also a boundary for property declarations.
+ QmlProperty *declaration = 0;
+ qSwap(_propertyDeclaration, declaration);
accept(initializer);
- sanityCheckFunctionNames();
+ qSwap(_propertyDeclaration, declaration);
- qSwap(_propertyNames, propertyNames);
- qSwap(_signalNames, signalNames);
qSwap(_object, obj);
+
+ AST::SourceLocation loc;
+ QString error = obj->sanityCheckFunctionNames(_functions, illegalNames, &loc);
+ if (!error.isEmpty())
+ recordError(loc, error);
+
return objectIndex;
}
@@ -522,7 +599,7 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node)
QString signalName = node->name.toString();
signal->nameIndex = registerString(signalName);
- AST::SourceLocation loc = node->firstSourceLocation();
+ AST::SourceLocation loc = node->typeToken;
signal->location.line = loc.startLine;
signal->location.column = loc.startColumn;
@@ -582,19 +659,17 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node)
p = p->next;
}
- if (_signalNames.contains(signalName))
- COMPILE_EXCEPTION(node->identifierToken, tr("Duplicate signal name"));
- _signalNames.insert(signalName);
-
if (signalName.at(0).isUpper())
COMPILE_EXCEPTION(node->identifierToken, tr("Signal names cannot begin with an upper case letter"));
-#if 0 // ### cannot access identifier table from separate thread
- if (enginePrivate->v8engine()->illegalNames().contains(currSig.name.toString()))
- COMPILE_EXCEPTION(&currSig, tr("Illegal signal name"));
-#endif
+ if (illegalNames.contains(signalName))
+ COMPILE_EXCEPTION(node->identifierToken, tr("Illegal signal name"));
- _object->qmlSignals->append(signal);
+ QString error = _object->appendSignal(signal);
+ if (!error.isEmpty()) {
+ recordError(node->identifierToken, error);
+ return false;
+ }
} else {
const QStringRef &memberType = node->memberType;
const QStringRef &name = node->name;
@@ -662,7 +737,8 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node)
else
property->customTypeNameIndex = emptyStringIndex;
- property->nameIndex = registerString(name.toString());
+ const QString propName = name.toString();
+ property->nameIndex = registerString(propName);
AST::SourceLocation loc = node->firstSourceLocation();
property->location.line = loc.startLine;
@@ -710,25 +786,38 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node)
propertyValue += alias.at(2);
}
property->aliasPropertyValueIndex = registerString(propertyValue);
- } else if (node->statement)
- appendBinding(node->identifierToken, property->nameIndex, node->statement);
+ } else if (node->statement) {
+ qSwap(_propertyDeclaration, property);
+ appendBinding(node->identifierToken, _propertyDeclaration->nameIndex, node->statement);
+ qSwap(_propertyDeclaration, property);
+ }
- _object->properties->append(property);
+ AST::SourceLocation errorLocation;
+ QString error;
- if (node->isDefaultMember) {
- if (_object->indexOfDefaultProperty != -1) {
- QQmlError error;
- error.setDescription(QCoreApplication::translate("QQmlParser","Duplicate default property"));
- error.setLine(node->defaultToken.startLine);
- error.setColumn(node->defaultToken.startColumn);
- errors << error;
- return false;
- }
- _object->indexOfDefaultProperty = _object->properties->count - 1;
+ if (illegalNames.contains(propName))
+ error = tr("Illegal property name");
+ else
+ error = _object->appendProperty(property, propName, node->isDefaultMember, node->defaultToken, &errorLocation);
+
+ if (!error.isEmpty()) {
+ if (errorLocation.startLine == 0)
+ errorLocation = node->identifierToken;
+
+ QQmlError qmlError;
+ qmlError.setDescription(error);
+ qmlError.setLine(errorLocation.startLine);
+ qmlError.setColumn(errorLocation.startColumn);
+ errors << qmlError;
+ return false;
}
- // process QML-like initializers (e.g. property Object o: Object {})
- AST::Node::accept(node->binding, this);
+ if (node->binding) {
+ qSwap(_propertyDeclaration, property);
+ // process QML-like initializers (e.g. property Object o: Object {})
+ AST::Node::accept(node->binding, this);
+ qSwap(_propertyDeclaration, property);
+ }
}
return false;
@@ -739,8 +828,13 @@ bool QQmlCodeGenerator::visit(AST::UiSourceElement *node)
if (AST::FunctionDeclaration *funDecl = AST::cast<AST::FunctionDeclaration *>(node->sourceElement)) {
_functions << funDecl;
Function *f = New<Function>();
+ f->functionDeclaration = funDecl;
+ AST::SourceLocation loc = funDecl->identifierToken;
+ f->location.line = loc.startLine;
+ f->location.column = loc.startColumn;
f->index = _functions.size() - 1;
- _object->functions->append(f);
+ f->nameIndex = registerString(funDecl->name.toString());
+ _object->appendFunction(f);
} else {
QQmlError error;
error.setDescription(QCoreApplication::translate("QQmlParser","JavaScript declaration outside Script element"));
@@ -798,7 +892,12 @@ QStringRef QQmlCodeGenerator::textRefAt(const AST::SourceLocation &first, const
void QQmlCodeGenerator::setBindingValue(QV4::CompiledData::Binding *binding, AST::Statement *statement)
{
+ AST::SourceLocation loc = statement->firstSourceLocation();
+ binding->valueLocation.line = loc.startLine;
+ binding->valueLocation.column = loc.startColumn;
binding->type = QV4::CompiledData::Binding::Type_Invalid;
+ if (_propertyDeclaration && (_propertyDeclaration->flags & QV4::CompiledData::Property::IsReadOnly))
+ binding->flags |= QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration;
if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement *>(statement)) {
AST::ExpressionNode *expr = stmt->expression;
@@ -844,23 +943,20 @@ void QQmlCodeGenerator::appendBinding(AST::UiQualifiedId *name, AST::Statement *
qSwap(_object, object);
}
-void QQmlCodeGenerator::appendBinding(AST::UiQualifiedId *name, int objectIndex)
+void QQmlCodeGenerator::appendBinding(AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment)
{
QmlObject *object = 0;
if (!resolveQualifiedId(&name, &object))
return;
qSwap(_object, object);
- appendBinding(name->identifierToken, registerString(name->name.toString()), objectIndex);
+ appendBinding(name->identifierToken, registerString(name->name.toString()), objectIndex, /*isListItem*/false, isOnAssignment);
qSwap(_object, object);
}
-void QQmlCodeGenerator::appendBinding(const AST::SourceLocation &nameLocation, int propertyNameIndex, AST::Statement *value)
+void QQmlCodeGenerator::appendBinding(const AST::SourceLocation &nameLocation, quint32 propertyNameIndex, AST::Statement *value)
{
- if (!sanityCheckPropertyName(nameLocation, propertyNameIndex))
- return;
-
if (stringAt(propertyNameIndex) == QStringLiteral("id")) {
- setId(value);
+ setId(nameLocation, value);
return;
}
@@ -870,14 +966,14 @@ void QQmlCodeGenerator::appendBinding(const AST::SourceLocation &nameLocation, i
binding->location.column = nameLocation.startColumn;
binding->flags = 0;
setBindingValue(binding, value);
- _object->bindings->append(binding);
+ QString error = bindingsTarget()->appendBinding(binding, /*isListBinding*/false);
+ if (!error.isEmpty()) {
+ recordError(nameLocation, error);
+ }
}
-void QQmlCodeGenerator::appendBinding(const AST::SourceLocation &nameLocation, int propertyNameIndex, int objectIndex, bool isListItem)
+void QQmlCodeGenerator::appendBinding(const AST::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem, bool isOnAssignment)
{
- if (!sanityCheckPropertyName(nameLocation, propertyNameIndex, isListItem))
- return;
-
if (stringAt(propertyNameIndex) == QStringLiteral("id")) {
recordError(nameLocation, tr("Invalid component id specification"));
return;
@@ -887,26 +983,55 @@ void QQmlCodeGenerator::appendBinding(const AST::SourceLocation &nameLocation, i
binding->propertyNameIndex = propertyNameIndex;
binding->location.line = nameLocation.startLine;
binding->location.column = nameLocation.startColumn;
+
+ const QmlObject *obj = _objects.at(objectIndex);
+ binding->valueLocation = obj->location;
+
binding->flags = 0;
- binding->type = QV4::CompiledData::Binding::Type_Object;
+
+ if (_propertyDeclaration && (_propertyDeclaration->flags & QV4::CompiledData::Property::IsReadOnly))
+ binding->flags |= QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration;
+
+ // No type name on the initializer means it must be a group property
+ if (_objects.at(objectIndex)->inheritedTypeNameIndex == emptyStringIndex)
+ binding->type = QV4::CompiledData::Binding::Type_GroupProperty;
+ else
+ binding->type = QV4::CompiledData::Binding::Type_Object;
+
+ if (isOnAssignment)
+ binding->flags |= QV4::CompiledData::Binding::IsOnAssignment;
+ if (isListItem)
+ binding->flags |= QV4::CompiledData::Binding::IsListItem;
+
binding->value.objectIndex = objectIndex;
- _object->bindings->append(binding);
+ QString error = bindingsTarget()->appendBinding(binding, isListItem);
+ if (!error.isEmpty()) {
+ recordError(nameLocation, error);
+ }
+}
+
+QmlObject *QQmlCodeGenerator::bindingsTarget() const
+{
+ if (_propertyDeclaration && _object->declarationsOverride)
+ return _object->declarationsOverride;
+ return _object;
}
-bool QQmlCodeGenerator::setId(AST::Statement *value)
+bool QQmlCodeGenerator::setId(const AST::SourceLocation &idLocation, AST::Statement *value)
{
AST::SourceLocation loc = value->firstSourceLocation();
QStringRef str;
AST::Node *node = value;
if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement *>(node)) {
- if (AST::StringLiteral *lit = AST::cast<AST::StringLiteral *>(stmt->expression))
+ if (AST::StringLiteral *lit = AST::cast<AST::StringLiteral *>(stmt->expression)) {
str = lit->value;
- else
+ node = 0;
+ } else
node = stmt->expression;
}
- if (str.isEmpty())
+ if (node && str.isEmpty())
str = asStringRef(node);
if (str.isEmpty())
@@ -926,12 +1051,14 @@ bool QQmlCodeGenerator::setId(AST::Statement *value)
COMPILE_EXCEPTION(loc, tr( "IDs must contain only letters, numbers, and underscores"));
}
-#if 0 // ###
- if (enginePrivate->v8engine()->illegalNames().contains(str))
- COMPILE_EXCEPTION(v, tr( "ID illegally masks global JavaScript property"));
-#endif
+ QString idQString(str.toString());
+ if (illegalNames.contains(idQString))
+ COMPILE_EXCEPTION(loc, tr( "ID illegally masks global JavaScript property"));
- _object->idIndex = registerString(str.toString());
+ if (_object->idIndex != emptyStringIndex)
+ COMPILE_EXCEPTION(idLocation, tr("Property value set multiple times"));
+
+ _object->idIndex = registerString(idQString);
_object->locationOfIdProperty.line = loc.startLine;
_object->locationOfIdProperty.column = loc.startColumn;
@@ -940,61 +1067,57 @@ bool QQmlCodeGenerator::setId(AST::Statement *value)
bool QQmlCodeGenerator::resolveQualifiedId(AST::UiQualifiedId **nameToResolve, QmlObject **object)
{
- AST::UiQualifiedId *name = *nameToResolve;
+ AST::UiQualifiedId *qualifiedIdElement = *nameToResolve;
+
+ if (qualifiedIdElement->name == QStringLiteral("id") && qualifiedIdElement->next)
+ COMPILE_EXCEPTION(qualifiedIdElement->identifierToken, tr( "Invalid use of id property"));
+
+ // If it's a namespace, prepend the qualifier and we'll resolve it later to the correct type.
+ QString currentName = qualifiedIdElement->name.toString();
+ if (qualifiedIdElement->next) {
+ foreach (QV4::CompiledData::Import* import, _imports)
+ if (import->qualifierIndex != emptyStringIndex
+ && stringAt(import->qualifierIndex) == currentName) {
+ qualifiedIdElement = qualifiedIdElement->next;
+ currentName += QLatin1Char('.');
+ currentName += qualifiedIdElement->name;
+
+ if (!qualifiedIdElement->name.unicode()->isUpper())
+ COMPILE_EXCEPTION(qualifiedIdElement->firstSourceLocation(), tr("Expected type name"));
- if (name->name == QStringLiteral("id") && name->next)
- COMPILE_EXCEPTION(name->identifierToken, tr( "Invalid use of id property"));
+ break;
+ }
+ }
*object = _object;
- while (name->next) {
+ while (qualifiedIdElement->next) {
Binding *binding = New<Binding>();
- binding->propertyNameIndex = registerString(name->name.toString());
- binding->location.line = name->identifierToken.startLine;
- binding->location.column = name->identifierToken.startColumn;
+ binding->propertyNameIndex = registerString(currentName);
+ binding->location.line = qualifiedIdElement->identifierToken.startLine;
+ binding->location.column = qualifiedIdElement->identifierToken.startColumn;
+ binding->valueLocation.line = binding->valueLocation.column = 0;
binding->flags = 0;
- if (name->name.unicode()->isUpper())
+ if (qualifiedIdElement->name.unicode()->isUpper())
binding->type = QV4::CompiledData::Binding::Type_AttachedProperty;
else
binding->type = QV4::CompiledData::Binding::Type_GroupProperty;
- int objIndex = defineQMLObject(0, 0);
+ int objIndex = defineQMLObject(0, AST::SourceLocation(), 0, 0);
binding->value.objectIndex = objIndex;
- (*object)->bindings->append(binding);
+ QString error = (*object)->appendBinding(binding, /*isListBinding*/false);
+ if (!error.isEmpty()) {
+ recordError(qualifiedIdElement->identifierToken, error);
+ return false;
+ }
*object = _objects[objIndex];
- name = name->next;
- }
- *nameToResolve = name;
- return true;
-}
-
-bool QQmlCodeGenerator::sanityCheckPropertyName(const AST::SourceLocation &nameLocation, int nameIndex, bool isListItem)
-{
- const QString &name = jsGenerator->strings.at(nameIndex);
- if (name.isEmpty())
- return true;
-
- // List items are implement by multiple bindings to the same name, so allow duplicates.
- if (!isListItem) {
- if (_propertyNames.contains(name))
- COMPILE_EXCEPTION(nameLocation, tr("Duplicate property name"));
-
- _propertyNames.insert(name);
+ qualifiedIdElement = qualifiedIdElement->next;
+ if (qualifiedIdElement)
+ currentName = qualifiedIdElement->name.toString();
}
-
- if (name.at(0).isUpper())
- COMPILE_EXCEPTION(nameLocation, tr("Property names cannot begin with an upper case letter"));
-
-#if 0 // ### how to check against illegalNames when in separate thread?
- if (enginePrivate->v8engine()->illegalNames().contains(prop.name.toString())) {
- COMPILE_EXCEPTION_LOCATION(prop.nameLocation.line,
- prop.nameLocation.column,
- tr("Illegal property name"));
- }
-#endif
-
+ *nameToResolve = qualifiedIdElement;
return true;
}
@@ -1011,20 +1134,21 @@ void QQmlCodeGenerator::recordError(const AST::SourceLocation &location, const Q
void QQmlCodeGenerator::collectTypeReferences()
{
foreach (QmlObject *obj, _objects) {
- if (!stringAt(obj->inheritedTypeNameIndex).isEmpty())
- _typeReferences.add(obj->inheritedTypeNameIndex, obj->location);
-
- for (QmlProperty *prop = obj->properties->first; prop; prop = prop->next) {
- if (prop->type >= QV4::CompiledData::Property::Custom)
- _typeReferences.add(prop->customTypeNameIndex, prop->location);
+ if (obj->inheritedTypeNameIndex != emptyStringIndex) {
+ QV4::CompiledData::TypeReference &r = _typeReferences.add(obj->inheritedTypeNameIndex, obj->location);
+ r.needsCreation = true;
}
- for (Signal *sig = obj->qmlSignals->first; sig; sig = sig->next)
- for (SignalParameter *param = sig->parameters->first; param; param = param->next)
- if (!stringAt(param->customTypeNameIndex).isEmpty())
- _typeReferences.add(param->customTypeNameIndex, param->location);
+ for (const QmlProperty *prop = obj->firstProperty(); prop; prop = prop->next) {
+ if (prop->type >= QV4::CompiledData::Property::Custom) {
+ // ### FIXME: We could report the more accurate location here by using prop->location, but the old
+ // compiler can't and the tests expect it to be the object location right now.
+ QV4::CompiledData::TypeReference &r = _typeReferences.add(prop->customTypeNameIndex, obj->location);
+ r.needsCreation = true;
+ }
+ }
- for (Binding *binding = obj->bindings->first; binding; binding = binding->next) {
+ for (const Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty)
_typeReferences.add(binding->propertyNameIndex, binding->location);
}
@@ -1082,10 +1206,10 @@ QV4::CompiledData::QmlUnit *QmlUnitGenerator::generate(ParsedQML &output, const
int objectsSize = 0;
foreach (QmlObject *o, output.objects) {
objectOffsets.insert(o, unitSize + importSize + objectOffsetTableSize + objectsSize);
- objectsSize += QV4::CompiledData::Object::calculateSizeExcludingSignals(o->functions->count, o->properties->count, o->qmlSignals->count, o->bindings->count);
+ objectsSize += QV4::CompiledData::Object::calculateSizeExcludingSignals(o->functionCount(), o->propertyCount(), o->signalCount(), o->bindingCount());
int signalTableSize = 0;
- for (Signal *s = o->qmlSignals->first; s; s = s->next)
+ for (const Signal *s = o->firstSignal(); s; s = s->next)
signalTableSize += QV4::CompiledData::Signal::calculateSize(s->parameters->count);
objectsSize += signalTableSize;
@@ -1128,46 +1252,45 @@ QV4::CompiledData::QmlUnit *QmlUnitGenerator::generate(ParsedQML &output, const
quint32 nextOffset = sizeof(QV4::CompiledData::Object);
- objectToWrite->nFunctions = o->functions->count;
+ objectToWrite->nFunctions = o->functionCount();
objectToWrite->offsetToFunctions = nextOffset;
nextOffset += objectToWrite->nFunctions * sizeof(quint32);
- objectToWrite->nProperties = o->properties->count;
+ objectToWrite->nProperties = o->propertyCount();
objectToWrite->offsetToProperties = nextOffset;
nextOffset += objectToWrite->nProperties * sizeof(QV4::CompiledData::Property);
- objectToWrite->nSignals = o->qmlSignals->count;
+ objectToWrite->nSignals = o->signalCount();
objectToWrite->offsetToSignals = nextOffset;
nextOffset += objectToWrite->nSignals * sizeof(quint32);
- objectToWrite->nBindings = o->bindings->count;
+ objectToWrite->nBindings = o->bindingCount();
objectToWrite->offsetToBindings = nextOffset;
nextOffset += objectToWrite->nBindings * sizeof(QV4::CompiledData::Binding);
quint32 *functionsTable = reinterpret_cast<quint32*>(objectPtr + objectToWrite->offsetToFunctions);
- for (Function *f = o->functions->first; f; f = f->next)
+ for (const Function *f = o->firstFunction(); f; f = f->next)
*functionsTable++ = runtimeFunctionIndices[f->index];
char *propertiesPtr = objectPtr + objectToWrite->offsetToProperties;
- for (QmlProperty *p = o->properties->first; p; p = p->next) {
+ for (const QmlProperty *p = o->firstProperty(); p; p = p->next) {
QV4::CompiledData::Property *propertyToWrite = reinterpret_cast<QV4::CompiledData::Property*>(propertiesPtr);
*propertyToWrite = *p;
propertiesPtr += sizeof(QV4::CompiledData::Property);
}
char *bindingPtr = objectPtr + objectToWrite->offsetToBindings;
- for (Binding *b = o->bindings->first; b; b = b->next) {
- QV4::CompiledData::Binding *bindingToWrite = reinterpret_cast<QV4::CompiledData::Binding*>(bindingPtr);
- *bindingToWrite = *b;
- if (b->type == QV4::CompiledData::Binding::Type_Script)
- bindingToWrite->value.compiledScriptIndex = runtimeFunctionIndices[b->value.compiledScriptIndex];
- bindingPtr += sizeof(QV4::CompiledData::Binding);
- }
+ bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isValueBindingNoAlias);
+ bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isSignalHandler);
+ bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isAttachedProperty);
+ bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isGroupProperty);
+ bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isValueBindingToAlias);
+ Q_ASSERT((bindingPtr - objectToWrite->offsetToBindings - objectPtr) / sizeof(QV4::CompiledData::Binding) == unsigned(o->bindingCount()));
quint32 *signalOffsetTable = reinterpret_cast<quint32*>(objectPtr + objectToWrite->offsetToSignals);
quint32 signalTableSize = 0;
char *signalPtr = objectPtr + nextOffset;
- for (Signal *s = o->qmlSignals->first; s; s = s->next) {
+ for (const Signal *s = o->firstSignal(); s; s = s->next) {
*signalOffsetTable++ = signalPtr - objectPtr;
QV4::CompiledData::Signal *signalToWrite = reinterpret_cast<QV4::CompiledData::Signal*>(signalPtr);
@@ -1184,7 +1307,7 @@ QV4::CompiledData::QmlUnit *QmlUnitGenerator::generate(ParsedQML &output, const
signalPtr += size;
}
- objectPtr += QV4::CompiledData::Object::calculateSizeExcludingSignals(o->functions->count, o->properties->count, o->qmlSignals->count, o->bindings->count);
+ objectPtr += QV4::CompiledData::Object::calculateSizeExcludingSignals(o->functionCount(), o->propertyCount(), o->signalCount(), o->bindingCount());
objectPtr += signalTableSize;
}
@@ -1199,6 +1322,20 @@ QV4::CompiledData::QmlUnit *QmlUnitGenerator::generate(ParsedQML &output, const
return qmlUnit;
}
+char *QmlUnitGenerator::writeBindings(char *bindingPtr, QmlObject *o, const QVector<int> &runtimeFunctionIndices, BindingFilter filter) const
+{
+ for (const Binding *b = o->firstBinding(); b; b = b->next) {
+ if (!(b->*(filter))())
+ continue;
+ QV4::CompiledData::Binding *bindingToWrite = reinterpret_cast<QV4::CompiledData::Binding*>(bindingPtr);
+ *bindingToWrite = *b;
+ if (b->type == QV4::CompiledData::Binding::Type_Script)
+ bindingToWrite->value.compiledScriptIndex = runtimeFunctionIndices[b->value.compiledScriptIndex];
+ bindingPtr += sizeof(QV4::CompiledData::Binding);
+ }
+ return bindingPtr;
+}
+
int QmlUnitGenerator::getStringId(const QString &str) const
{
return jsUnitGenerator->getStringId(str);
@@ -1620,16 +1757,24 @@ SignalHandlerConverter::SignalHandlerConverter(QQmlEnginePrivate *enginePrivate,
: enginePrivate(enginePrivate)
, parsedQML(parsedQML)
, unit(unit)
+ , illegalNames(QV8Engine::get(QQmlEnginePrivate::get(enginePrivate))->illegalNames())
{
}
bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclarations()
{
- foreach (QmlObject *obj, parsedQML->objects) {
+ for (int objectIndex = 0; objectIndex < parsedQML->objects.count(); ++objectIndex) {
+ QmlObject * const obj = parsedQML->objects.at(objectIndex);
QString elementName = stringAt(obj->inheritedTypeNameIndex);
if (elementName.isEmpty())
continue;
- QQmlPropertyCache *cache = unit->resolvedTypes[obj->inheritedTypeNameIndex].createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
+ QQmlCompiledData::TypeReference *tr = unit->resolvedTypes.value(obj->inheritedTypeNameIndex);
+ QQmlCustomParser *customParser = (tr && tr->type) ? tr->type->customParser() : 0;
+ if (customParser && !(customParser->flags() & QQmlCustomParser::AcceptsSignalHandlers))
+ continue;
+ QQmlPropertyCache *cache = unit->propertyCaches.value(objectIndex);
+ if (!cache)
+ continue;
if (!convertSignalHandlerExpressionsToFunctionDeclarations(obj, elementName, cache))
return false;
}
@@ -1641,12 +1786,13 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
// map from signal name defined in qml itself to list of parameters
QHash<QString, QStringList> customSignals;
- for (Binding *binding = obj->bindings->first; binding; binding = binding->next) {
+ for (Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
QString propertyName = stringAt(binding->propertyNameIndex);
// Attached property?
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
QmlObject *attachedObj = parsedQML->objects[binding->value.objectIndex];
- QQmlType *type = unit->resolvedTypes.value(binding->propertyNameIndex).type;
+ QQmlCompiledData::TypeReference *typeRef = unit->resolvedTypes.value(binding->propertyNameIndex);
+ QQmlType *type = typeRef ? typeRef->type : 0;
const QMetaObject *attachedType = type ? type->attachedPropertiesType() : 0;
if (!attachedType)
COMPILE_EXCEPTION(binding->location, tr("Non-existent attached object"));
@@ -1659,10 +1805,6 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
if (!QQmlCodeGenerator::isSignalPropertyName(propertyName))
continue;
- if (binding->type != QV4::CompiledData::Binding::Type_Script) {
- COMPILE_EXCEPTION(binding->location, tr("Incorrectly specified signal assignment"));
- }
-
PropertyResolver resolver(propertyCache);
Q_ASSERT(propertyName.startsWith(QStringLiteral("on")));
@@ -1683,8 +1825,22 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
QQmlPropertyData *signal = resolver.signal(propertyName, &notInRevision);
if (signal) {
int sigIndex = propertyCache->methodIndexToSignalIndex(signal->coreIndex);
- foreach (const QByteArray &param, propertyCache->signalParameterNames(sigIndex))
- parameters << QString::fromUtf8(param);
+ sigIndex = propertyCache->originalClone(sigIndex);
+
+ bool unnamedParameter = false;
+
+ QList<QByteArray> parameterNames = propertyCache->signalParameterNames(sigIndex);
+ for (int i = 0; i < parameterNames.count(); ++i) {
+ const QString param = QString::fromUtf8(parameterNames.at(i));
+ if (param.isEmpty())
+ unnamedParameter = true;
+ else if (unnamedParameter) {
+ COMPILE_EXCEPTION(binding->location, tr("Signal uses unnamed parameter followed by named parameter."));
+ } else if (illegalNames.contains(param)) {
+ COMPILE_EXCEPTION(binding->location, tr("Signal parameter \"%1\" hides global variable.").arg(param));
+ }
+ parameters += param;
+ }
} else {
if (notInRevision) {
// Try assinging it as a property later
@@ -1693,7 +1849,8 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
const QString &originalPropertyName = stringAt(binding->propertyNameIndex);
- const QQmlType *type = unit->resolvedTypes.value(obj->inheritedTypeNameIndex).type;
+ QQmlCompiledData::TypeReference *typeRef = unit->resolvedTypes.value(obj->inheritedTypeNameIndex);
+ const QQmlType *type = typeRef ? typeRef->type : 0;
if (type) {
COMPILE_EXCEPTION(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(originalPropertyName).arg(type->module()).arg(type->majorVersion()).arg(type->minorVersion()));
} else {
@@ -1705,12 +1862,12 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
// build cache if necessary
if (customSignals.isEmpty()) {
- for (Signal *signal = obj->qmlSignals->first; signal; signal = signal->next) {
+ for (const Signal *signal = obj->firstSignal(); signal; signal = signal->next) {
const QString &signalName = stringAt(signal->nameIndex);
customSignals.insert(signalName, signal->parameterStringList(parsedQML->jsGenerator.strings));
}
- for (QmlProperty *property = obj->properties->first; property; property = property->next) {
+ for (const QmlProperty *property = obj->firstProperty(); property; property = property->next) {
const QString propName = stringAt(property->nameIndex);
customSignals.insert(propName, QStringList());
}
@@ -1731,6 +1888,18 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
parameters = entry.value();
}
+ binding->propertyNameIndex = parsedQML->jsGenerator.registerString(propertyName);
+
+ // Binding object to signal means connect the signal to the object's default method.
+ if (binding->type == QV4::CompiledData::Binding::Type_Object) {
+ binding->flags |= QV4::CompiledData::Binding::IsSignalHandlerObject;
+ continue;
+ }
+
+ if (binding->type != QV4::CompiledData::Binding::Type_Script) {
+ COMPILE_EXCEPTION(binding->location, tr("Incorrectly specified signal assignment"));
+ }
+
QQmlJS::Engine &jsEngine = parsedQML->jsParserEngine;
QQmlJS::MemoryPool *pool = jsEngine.pool();
@@ -1758,7 +1927,6 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
parsedQML->functions[binding->value.compiledScriptIndex] = functionDeclaration;
binding->flags |= QV4::CompiledData::Binding::IsSignalHandlerExpression;
- binding->propertyNameIndex = parsedQML->jsGenerator.registerString(propertyName);
}
return true;
}
@@ -1773,11 +1941,11 @@ void SignalHandlerConverter::recordError(const QV4::CompiledData::Location &loca
errors << error;
}
-QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRevision)
+QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRevision, QObject *object, QQmlContextData *context)
{
if (notInRevision) *notInRevision = false;
- QQmlPropertyData *d = cache->property(name, 0, 0);
+ QQmlPropertyData *d = cache->property(name, object, context);
// Find the first property
while (d && d->isFunction())
@@ -1792,11 +1960,11 @@ QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRev
}
-QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevision)
+QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevision, QObject *object, QQmlContextData *context)
{
if (notInRevision) *notInRevision = false;
- QQmlPropertyData *d = cache->property(name, 0, 0);
+ QQmlPropertyData *d = cache->property(name, object, context);
if (notInRevision) *notInRevision = false;
while (d && !(d->isFunction()))
@@ -1812,7 +1980,7 @@ QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevis
if (name.endsWith(QStringLiteral("Changed"))) {
QString propName = name.mid(0, name.length() - static_cast<int>(strlen("Changed")));
- d = property(propName, notInRevision);
+ d = property(propName, notInRevision, object, context);
if (d)
return cache->signal(d->notifyIndex);
}
diff --git a/src/qml/compiler/qqmlcodegenerator_p.h b/src/qml/compiler/qqmlcodegenerator_p.h
index 0a0e4f2d5b..7c09b8bfa2 100644
--- a/src/qml/compiler/qqmlcodegenerator_p.h
+++ b/src/qml/compiler/qqmlcodegenerator_p.h
@@ -93,15 +93,49 @@ struct PoolList
T *last;
int count;
- void append(T *item) {
+ int append(T *item) {
item->next = 0;
if (last)
last->next = item;
else
first = item;
last = item;
+ return count++;
+ }
+
+ void prepend(T *item) {
+ item->next = first;
+ first = item;
+ if (!last)
+ last = first;
++count;
}
+
+ template <typename Sortable, typename Base, Sortable Base::*sortMember>
+ T *findSortedInsertionPoint(T *item) const
+ {
+ T *insertPos = 0;
+
+ for (T *it = first; it; it = it->next) {
+ if (!(it->*sortMember < item->*sortMember))
+ break;
+ insertPos = it;
+ }
+
+ return insertPos;
+ }
+
+ void insertAfter(T *insertionPoint, T *item) {
+ if (!insertionPoint) {
+ prepend(item);
+ } else if (insertionPoint == last) {
+ append(item);
+ } else {
+ item->next = insertionPoint->next;
+ insertionPoint->next = item;
+ ++count;
+ }
+ }
};
struct QmlObject;
@@ -135,25 +169,73 @@ struct Binding : public QV4::CompiledData::Binding
struct Function
{
+ AST::FunctionDeclaration *functionDeclaration;
+ QV4::CompiledData::Location location;
+ int nameIndex;
int index; // index in parsedQML::functions
Function *next;
};
+struct CompiledFunctionOrExpression
+{
+ CompiledFunctionOrExpression()
+ : node(0)
+ , disableAcceleratedLookups(false)
+ {}
+ CompiledFunctionOrExpression(AST::Node *n)
+ : node(n)
+ , disableAcceleratedLookups(false)
+ {}
+ AST::Node *node; // FunctionDeclaration, Statement or Expression
+ QString name;
+ bool disableAcceleratedLookups;
+};
+
struct QmlObject
{
- int inheritedTypeNameIndex;
- int idIndex;
+ Q_DECLARE_TR_FUNCTIONS(QmlObject)
+public:
+ quint32 inheritedTypeNameIndex;
+ quint32 idIndex;
int indexOfDefaultProperty;
QV4::CompiledData::Location location;
QV4::CompiledData::Location locationOfIdProperty;
+ const QmlProperty *firstProperty() const { return properties->first; }
+ int propertyCount() const { return properties->count; }
+ const Signal *firstSignal() const { return qmlSignals->first; }
+ int signalCount() const { return qmlSignals->count; }
+ Binding *firstBinding() const { return bindings->first; }
+ int bindingCount() const { return bindings->count; }
+ const Function *firstFunction() const { return functions->first; }
+ int functionCount() const { return functions->count; }
+
+ // If set, then declarations for this object (and init bindings for these) should go into the
+ // specified object. Used for declarations inside group properties.
+ QmlObject *declarationsOverride;
+
+ void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int id, const AST::SourceLocation &location = AST::SourceLocation());
+
+ void dump(DebugStream &out);
+
+ QString sanityCheckFunctionNames(const QList<CompiledFunctionOrExpression> &allFunctions, const QSet<QString> &illegalNames, AST::SourceLocation *errorLocation);
+
+ QString appendSignal(Signal *signal);
+ QString appendProperty(QmlProperty *prop, const QString &propertyName, bool isDefaultProperty, const AST::SourceLocation &defaultToken, AST::SourceLocation *errorLocation);
+ void appendFunction(Function *f);
+
+ QString appendBinding(Binding *b, bool isListBinding);
+
+private:
PoolList<QmlProperty> *properties;
PoolList<Signal> *qmlSignals;
PoolList<Binding> *bindings;
PoolList<Function> *functions;
- void dump(DebugStream &out);
+ QSet<int> propertyNames;
+ QSet<int> bindingNames;
+ QSet<int> signalNames;
};
struct Pragma
@@ -166,20 +248,6 @@ struct Pragma
QV4::CompiledData::Location location;
};
-struct CompiledFunctionOrExpression
-{
- CompiledFunctionOrExpression()
- : disableAcceleratedLookups(false)
- {}
- CompiledFunctionOrExpression(AST::Node *n)
- : node(n)
- , disableAcceleratedLookups(false)
- {}
- AST::Node *node; // FunctionDeclaration, Statement or Expression
- QString name;
- bool disableAcceleratedLookups;
-};
-
struct ParsedQML
{
ParsedQML(bool debugMode)
@@ -207,7 +275,7 @@ struct Q_QML_EXPORT QQmlCodeGenerator : public AST::Visitor
{
Q_DECLARE_TR_FUNCTIONS(QQmlCodeGenerator)
public:
- QQmlCodeGenerator();
+ QQmlCodeGenerator(const QSet<QString> &illegalNames);
bool generateFromQml(const QString &code, const QUrl &url, const QString &urlString, ParsedQML *output);
static bool isSignalPropertyName(const QString &name);
@@ -234,9 +302,9 @@ public:
void accept(AST::Node *node);
// returns index in _objects
- int defineQMLObject(AST::UiQualifiedId *qualifiedTypeNameId, AST::UiObjectInitializer *initializer);
- int defineQMLObject(AST::UiObjectDefinition *node)
- { return defineQMLObject(node->qualifiedTypeNameId, node->initializer); }
+ int defineQMLObject(AST::UiQualifiedId *qualifiedTypeNameId, const AST::SourceLocation &location, AST::UiObjectInitializer *initializer, QmlObject *declarationsOverride = 0);
+ int defineQMLObject(AST::UiObjectDefinition *node, QmlObject *declarationsOverride = 0)
+ { return defineQMLObject(node->qualifiedTypeNameId, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, declarationsOverride); }
static QString asString(AST::UiQualifiedId *node);
QStringRef asStringRef(AST::Node *node);
@@ -253,26 +321,26 @@ public:
void setBindingValue(QV4::CompiledData::Binding *binding, AST::Statement *statement);
void appendBinding(AST::UiQualifiedId *name, AST::Statement *value);
- void appendBinding(AST::UiQualifiedId *name, int objectIndex);
- void appendBinding(const AST::SourceLocation &nameLocation, int propertyNameIndex, AST::Statement *value);
- void appendBinding(const AST::SourceLocation &nameLocation, int propertyNameIndex, int objectIndex, bool isListItem = false);
+ void appendBinding(AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment = false);
+ void appendBinding(const AST::SourceLocation &nameLocation, quint32 propertyNameIndex, AST::Statement *value);
+ void appendBinding(const AST::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem = false, bool isOnAssignment = false);
+
+ QmlObject *bindingsTarget() const;
- bool setId(AST::Statement *value);
+ bool setId(const AST::SourceLocation &idLocation, AST::Statement *value);
// resolves qualified name (font.pixelSize for example) and returns the last name along
// with the object any right-hand-side of a binding should apply to.
bool resolveQualifiedId(AST::UiQualifiedId **nameToResolve, QmlObject **object);
- bool sanityCheckPropertyName(const AST::SourceLocation &nameLocation, int nameIndex, bool isListItem = false);
-
void recordError(const AST::SourceLocation &location, const QString &description);
void collectTypeReferences();
static QQmlScript::LocationSpan location(AST::SourceLocation start, AST::SourceLocation end);
- int registerString(const QString &str) const { return jsGenerator->registerString(str); }
- template <typename _Tp> _Tp *New() { return new (pool->allocate(sizeof(_Tp))) _Tp(); }
+ quint32 registerString(const QString &str) const { return jsGenerator->registerString(str); }
+ template <typename _Tp> _Tp *New() { return pool->New<_Tp>(); }
QString stringAt(int index) const { return jsGenerator->strings.at(index); }
@@ -280,6 +348,8 @@ public:
QList<QQmlError> errors;
+ QSet<QString> illegalNames;
+
QList<QV4::CompiledData::Import*> _imports;
QList<Pragma*> _pragmas;
QList<QmlObject*> _objects;
@@ -288,15 +358,12 @@ public:
QV4::CompiledData::TypeReferenceMap _typeReferences;
QmlObject *_object;
- QSet<QString> _propertyNames;
- QSet<QString> _signalNames;
+ QmlProperty *_propertyDeclaration;
QQmlJS::MemoryPool *pool;
QString sourceCode;
QUrl url;
QV4::Compiler::JSUnitGenerator *jsGenerator;
- int emptyStringIndex;
- bool sanityCheckFunctionNames();
};
struct Q_QML_EXPORT QmlUnitGenerator
@@ -309,6 +376,9 @@ struct Q_QML_EXPORT QmlUnitGenerator
QV4::CompiledData::QmlUnit *generate(ParsedQML &output, const QVector<int> &runtimeFunctionIndices);
private:
+ typedef bool (Binding::*BindingFilter)() const;
+ char *writeBindings(char *bindingPtr, QmlObject *o, const QVector<int> &runtimeFunctionIndices, BindingFilter filter) const;
+
int getStringId(const QString &str) const;
QV4::Compiler::JSUnitGenerator *jsUnitGenerator;
@@ -325,10 +395,10 @@ struct PropertyResolver
return cache->property(index);
}
- QQmlPropertyData *property(const QString &name, bool *notInRevision = 0);
+ QQmlPropertyData *property(const QString &name, bool *notInRevision = 0, QObject *object = 0, QQmlContextData *context = 0);
// This code must match the semantics of QQmlPropertyPrivate::findSignalByName
- QQmlPropertyData *signal(const QString &name, bool *notInRevision);
+ QQmlPropertyData *signal(const QString &name, bool *notInRevision, QObject *object = 0, QQmlContextData *context = 0);
QQmlPropertyCache *cache;
};
@@ -357,6 +427,7 @@ private:
QQmlEnginePrivate *enginePrivate;
ParsedQML *parsedQML;
QQmlCompiledData *unit;
+ const QSet<QString> &illegalNames;
};
struct Q_QML_EXPORT JSCodeGen : public QQmlJS::Codegen
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
new file mode 100644
index 0000000000..dae57fe6f4
--- /dev/null
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -0,0 +1,1908 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** 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 "qqmltypecompiler_p.h"
+
+#include <private/qqmlcompiler_p.h>
+#include <private/qqmlobjectcreator_p.h>
+#include <private/qqmlcustomparser_p.h>
+#include <private/qqmlvmemetaobject_p.h>
+#include <private/qqmlcomponent_p.h>
+#include <private/qqmlstringconverters_p.h>
+
+#define COMPILE_EXCEPTION(token, desc) \
+ { \
+ recordError((token)->location, desc); \
+ return false; \
+ }
+
+QT_BEGIN_NAMESPACE
+
+QQmlTypeCompiler::QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlCompiledData *compiledData, QQmlTypeData *typeData, QtQml::ParsedQML *parsedQML)
+ : engine(engine)
+ , compiledData(compiledData)
+ , typeData(typeData)
+ , parsedQML(parsedQML)
+{
+}
+
+bool QQmlTypeCompiler::compile()
+{
+ compiledData->importCache = new QQmlTypeNameCache;
+
+ foreach (const QString &ns, typeData->namespaces())
+ compiledData->importCache->add(ns);
+
+ // Add any Composite Singletons that were used to the import cache
+ foreach (const QQmlTypeData::TypeReference &singleton, typeData->compositeSingletons())
+ compiledData->importCache->add(singleton.type->qmlTypeName(), singleton.type->sourceUrl(), singleton.prefix);
+
+ typeData->imports().populateCache(compiledData->importCache);
+ compiledData->importCache->addref();
+
+ const QHash<int, QQmlTypeData::TypeReference> &resolvedTypes = typeData->resolvedTypeRefs();
+ for (QHash<int, QQmlTypeData::TypeReference>::ConstIterator resolvedType = resolvedTypes.constBegin(), end = resolvedTypes.constEnd();
+ resolvedType != end; ++resolvedType) {
+ QScopedPointer<QQmlCompiledData::TypeReference> ref(new QQmlCompiledData::TypeReference);
+ QQmlType *qmlType = resolvedType->type;
+ if (resolvedType->typeData) {
+ if (resolvedType->needsCreation && qmlType->isCompositeSingleton()) {
+ QQmlError error;
+ QString reason = tr("Composite Singleton Type %1 is not creatable.").arg(qmlType->qmlTypeName());
+ error.setDescription(reason);
+ error.setColumn(resolvedType->location.column);
+ error.setLine(resolvedType->location.line);
+ recordError(error);
+ return false;
+ }
+ ref->component = resolvedType->typeData->compiledData();
+ ref->component->addref();
+ } else if (qmlType) {
+ ref->type = qmlType;
+ Q_ASSERT(ref->type);
+
+ if (resolvedType->needsCreation && !ref->type->isCreatable()) {
+ QQmlError error;
+ QString reason = ref->type->noCreationReason();
+ if (reason.isEmpty())
+ reason = tr("Element is not creatable.");
+ error.setDescription(reason);
+ error.setColumn(resolvedType->location.column);
+ error.setLine(resolvedType->location.line);
+ recordError(error);
+ return false;
+ }
+
+ if (ref->type->containsRevisionedAttributes()) {
+ QQmlError cacheError;
+ ref->typePropertyCache = engine->cache(ref->type,
+ resolvedType->minorVersion,
+ cacheError);
+ if (!ref->typePropertyCache) {
+ cacheError.setColumn(resolvedType->location.column);
+ cacheError.setLine(resolvedType->location.line);
+ recordError(cacheError);
+ return false;
+ }
+ ref->typePropertyCache->addref();
+ }
+ }
+ ref->majorVersion = resolvedType->majorVersion;
+ ref->minorVersion = resolvedType->minorVersion;
+ compiledData->resolvedTypes.insert(resolvedType.key(), ref.take());
+ }
+
+ // Build property caches and VME meta object data
+
+ const int objectCount = parsedQML->objects.count();
+ compiledData->datas.reserve(objectCount);
+ compiledData->propertyCaches.reserve(objectCount);
+
+ {
+ QQmlPropertyCacheCreator propertyCacheBuilder(this);
+ if (!propertyCacheBuilder.buildMetaObjects())
+ return false;
+ }
+
+ {
+ SignalHandlerConverter converter(engine, parsedQML, compiledData);
+ if (!converter.convertSignalHandlerExpressionsToFunctionDeclarations()) {
+ errors << converter.errors;
+ return false;
+ }
+ }
+
+ {
+ QQmlEnumTypeResolver enumResolver(this);
+ if (!enumResolver.resolveEnumBindings())
+ return false;
+ }
+
+ {
+ QQmlAliasAnnotator annotator(this);
+ annotator.annotateBindingsToAliases();
+ }
+
+ // Collect imported scripts
+ const QList<QQmlTypeData::ScriptReference> &scripts = typeData->resolvedScripts();
+ compiledData->scripts.reserve(scripts.count());
+ for (int scriptIndex = 0; scriptIndex < scripts.count(); ++scriptIndex) {
+ const QQmlTypeData::ScriptReference &script = scripts.at(scriptIndex);
+
+ QString qualifier = script.qualifier;
+ QString enclosingNamespace;
+
+ const int lastDotIndex = qualifier.lastIndexOf(QLatin1Char('.'));
+ if (lastDotIndex != -1) {
+ enclosingNamespace = qualifier.left(lastDotIndex);
+ qualifier = qualifier.mid(lastDotIndex+1);
+ }
+
+ compiledData->importCache->add(qualifier, scriptIndex, enclosingNamespace);
+ QQmlScriptData *scriptData = script.script->scriptData();
+ scriptData->addref();
+ compiledData->scripts << scriptData;
+ }
+
+ // Resolve component boundaries and aliases
+
+ {
+ // Scan for components, determine their scopes and resolve aliases within the scope.
+ QQmlComponentAndAliasResolver resolver(this);
+ if (!resolver.resolve())
+ return false;
+ }
+
+ // Compile JS binding expressions and signal handlers
+
+ JSCodeGen jsCodeGen(typeData->finalUrlString(), parsedQML->code, &parsedQML->jsModule, &parsedQML->jsParserEngine, parsedQML->program, compiledData->importCache);
+ const QVector<int> runtimeFunctionIndices = jsCodeGen.generateJSCodeForFunctionsAndBindings(parsedQML->functions);
+ QList<QQmlError> jsErrors = jsCodeGen.errors();
+ if (!jsErrors.isEmpty()) {
+ errors << jsErrors;
+ return false;
+ }
+
+ QV4::ExecutionEngine *v4 = engine->v4engine();
+
+ QScopedPointer<QQmlJS::EvalInstructionSelection> isel(v4->iselFactory->create(engine, v4->executableAllocator, &parsedQML->jsModule, &parsedQML->jsGenerator));
+ isel->setUseFastLookups(false);
+ QV4::CompiledData::CompilationUnit *jsUnit = isel->compile(/*generated unit data*/false);
+
+ // Generate QML compiled type data structures
+
+ QmlUnitGenerator qmlGenerator;
+ QV4::CompiledData::QmlUnit *qmlUnit = qmlGenerator.generate(*parsedQML, runtimeFunctionIndices);
+
+ if (jsUnit) {
+ Q_ASSERT(!jsUnit->data);
+ jsUnit->ownsData = false;
+ jsUnit->data = &qmlUnit->header;
+ }
+
+ compiledData->compilationUnit = jsUnit;
+ if (compiledData->compilationUnit)
+ compiledData->compilationUnit->ref();
+ compiledData->qmlUnit = qmlUnit; // ownership transferred to m_compiledData
+
+ // Add to type registry of composites
+ if (compiledData->isCompositeType())
+ engine->registerInternalCompositeType(compiledData);
+ else {
+ const QV4::CompiledData::Object *obj = qmlUnit->objectAt(qmlUnit->indexOfRootObject);
+ QQmlCompiledData::TypeReference *typeRef = compiledData->resolvedTypes.value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
+ if (typeRef->component) {
+ compiledData->metaTypeId = typeRef->component->metaTypeId;
+ compiledData->listMetaTypeId = typeRef->component->listMetaTypeId;
+ } else {
+ compiledData->metaTypeId = typeRef->type->typeId();
+ compiledData->listMetaTypeId = typeRef->type->qListTypeId();
+ }
+ }
+
+ // Sanity check property bindings
+ QQmlPropertyValidator validator(this, runtimeFunctionIndices);
+ if (!validator.validate())
+ return false;
+
+ // Collect some data for instantiation later.
+ int bindingCount = 0;
+ int parserStatusCount = 0;
+ for (quint32 i = 0; i < qmlUnit->nObjects; ++i) {
+ const QV4::CompiledData::Object *obj = qmlUnit->objectAt(i);
+ bindingCount += obj->nBindings;
+ if (QQmlCompiledData::TypeReference *typeRef = compiledData->resolvedTypes.value(obj->inheritedTypeNameIndex)) {
+ if (QQmlType *qmlType = typeRef->type) {
+ if (qmlType->parserStatusCast() != -1)
+ ++parserStatusCount;
+ }
+ if (typeRef->component) {
+ bindingCount += typeRef->component->totalBindingsCount;
+ parserStatusCount += typeRef->component->totalParserStatusCount;
+ }
+ }
+ }
+
+ compiledData->totalBindingsCount = bindingCount;
+ compiledData->totalParserStatusCount = parserStatusCount;
+
+ return errors.isEmpty();
+}
+
+void QQmlTypeCompiler::recordError(const QQmlError &error)
+{
+ QQmlError e = error;
+ e.setUrl(compiledData->url);
+ errors << e;
+}
+
+QString QQmlTypeCompiler::stringAt(int idx) const
+{
+ return parsedQML->stringAt(idx);
+}
+
+int QQmlTypeCompiler::registerString(const QString &str)
+{
+ return parsedQML->jsGenerator.registerString(str);
+}
+
+const QV4::CompiledData::QmlUnit *QQmlTypeCompiler::qmlUnit() const
+{
+ return compiledData->qmlUnit;
+}
+
+const QQmlImports *QQmlTypeCompiler::imports() const
+{
+ return &typeData->imports();
+}
+
+QHash<int, QQmlCompiledData::TypeReference*> *QQmlTypeCompiler::resolvedTypes()
+{
+ return &compiledData->resolvedTypes;
+}
+
+QList<QmlObject *> *QQmlTypeCompiler::qmlObjects()
+{
+ return &parsedQML->objects;
+}
+
+int QQmlTypeCompiler::rootObjectIndex() const
+{
+ return parsedQML->indexOfRootObject;
+}
+
+void QQmlTypeCompiler::setPropertyCaches(const QVector<QQmlPropertyCache *> &caches)
+{
+ Q_ASSERT(compiledData->propertyCaches.isEmpty());
+ compiledData->propertyCaches = caches;
+ Q_ASSERT(caches.count() >= parsedQML->indexOfRootObject);
+ compiledData->rootPropertyCache = caches.at(parsedQML->indexOfRootObject);
+ compiledData->rootPropertyCache->addref();
+}
+
+const QVector<QQmlPropertyCache *> &QQmlTypeCompiler::propertyCaches() const
+{
+ return compiledData->propertyCaches;
+}
+
+void QQmlTypeCompiler::setVMEMetaObjects(const QVector<QByteArray> &metaObjects)
+{
+ Q_ASSERT(compiledData->datas.isEmpty());
+ compiledData->datas = metaObjects;
+}
+
+QVector<QByteArray> *QQmlTypeCompiler::vmeMetaObjects() const
+{
+ return &compiledData->datas;
+}
+
+QHash<int, int> *QQmlTypeCompiler::objectIndexToIdForRoot()
+{
+ return &compiledData->objectIndexToIdForRoot;
+}
+
+QHash<int, QHash<int, int> > *QQmlTypeCompiler::objectIndexToIdPerComponent()
+{
+ return &compiledData->objectIndexToIdPerComponent;
+}
+
+QHash<int, QByteArray> *QQmlTypeCompiler::customParserData()
+{
+ return &compiledData->customParserData;
+}
+
+MemoryPool *QQmlTypeCompiler::memoryPool()
+{
+ return parsedQML->jsParserEngine.pool();
+}
+
+const QList<CompiledFunctionOrExpression> &QQmlTypeCompiler::functions() const
+{
+ return parsedQML->functions;
+}
+
+void QQmlTypeCompiler::setCustomParserBindings(const QVector<int> &bindings)
+{
+ compiledData->customParserBindings = bindings;
+}
+
+QQmlCompilePass::QQmlCompilePass(QQmlTypeCompiler *typeCompiler)
+ : compiler(typeCompiler)
+{
+}
+
+void QQmlCompilePass::recordError(const QV4::CompiledData::Location &location, const QString &description)
+{
+ QQmlError error;
+ error.setLine(location.line);
+ error.setColumn(location.column);
+ error.setDescription(description);
+ compiler->recordError(error);
+}
+
+static QAtomicInt classIndexCounter(0);
+
+QQmlPropertyCacheCreator::QQmlPropertyCacheCreator(QQmlTypeCompiler *typeCompiler)
+ : QQmlCompilePass(typeCompiler)
+ , enginePrivate(typeCompiler->enginePrivate())
+ , qmlObjects(*typeCompiler->qmlObjects())
+ , imports(typeCompiler->imports())
+ , resolvedTypes(typeCompiler->resolvedTypes())
+{
+}
+
+QQmlPropertyCacheCreator::~QQmlPropertyCacheCreator()
+{
+ for (int i = 0; i < propertyCaches.count(); ++i)
+ if (QQmlPropertyCache *cache = propertyCaches.at(i))
+ cache->release();
+ propertyCaches.clear();
+}
+
+bool QQmlPropertyCacheCreator::buildMetaObjects()
+{
+ propertyCaches.resize(qmlObjects.count());
+ vmeMetaObjects.resize(qmlObjects.count());
+
+ if (!buildMetaObjectRecursively(compiler->rootObjectIndex(), /*referencing object*/-1, /*instantiating binding*/0))
+ return false;
+
+ compiler->setVMEMetaObjects(vmeMetaObjects);
+ compiler->setPropertyCaches(propertyCaches);
+ propertyCaches.clear();
+
+ return true;
+}
+
+bool QQmlPropertyCacheCreator::buildMetaObjectRecursively(int objectIndex, int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding)
+{
+ const QmlObject *obj = qmlObjects.at(objectIndex);
+
+ QQmlPropertyCache *baseTypeCache = 0;
+ QQmlPropertyData *instantiatingProperty = 0;
+ if (instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty) {
+ Q_ASSERT(referencingObjectIndex >= 0);
+ QQmlPropertyCache *parentCache = propertyCaches.at(referencingObjectIndex);
+ Q_ASSERT(parentCache);
+ Q_ASSERT(instantiatingBinding->propertyNameIndex != 0);
+
+ bool notInRevision = false;
+ instantiatingProperty = PropertyResolver(parentCache).property(stringAt(instantiatingBinding->propertyNameIndex), &notInRevision);
+ if (instantiatingProperty) {
+ if (instantiatingProperty->isQObject()) {
+ baseTypeCache = enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType);
+ Q_ASSERT(baseTypeCache);
+ } else if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(instantiatingProperty->propType)) {
+ baseTypeCache = enginePrivate->cache(vt->metaObject());
+ Q_ASSERT(baseTypeCache);
+ }
+ }
+ }
+
+ bool needVMEMetaObject = obj->propertyCount() != 0 || obj->signalCount() != 0 || obj->functionCount() != 0;
+ if (!needVMEMetaObject) {
+ for (const QtQml::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
+ if (binding->type == QV4::CompiledData::Binding::Type_Object && (binding->flags & QV4::CompiledData::Binding::IsOnAssignment)) {
+
+ // On assignments are implemented using value interceptors, which require a VME meta object.
+ needVMEMetaObject = true;
+
+ // If the on assignment is inside a group property, we need to distinguish between QObject based
+ // group properties and value type group properties. For the former the base type is derived from
+ // the property that references us, for the latter we only need a meta-object on the referencing object
+ // because interceptors can't go to the shared value type instances.
+ if (instantiatingProperty && QQmlValueTypeFactory::isValueType(instantiatingProperty->propType)) {
+ needVMEMetaObject = false;
+ if (!ensureMetaObject(referencingObjectIndex))
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ if (obj->inheritedTypeNameIndex != 0) {
+ QQmlCompiledData::TypeReference *typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
+ baseTypeCache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
+ Q_ASSERT(baseTypeCache);
+ }
+
+ if (needVMEMetaObject) {
+ if (!createMetaObject(objectIndex, obj, baseTypeCache))
+ return false;
+ } else if (baseTypeCache) {
+ propertyCaches[objectIndex] = baseTypeCache;
+ baseTypeCache->addref();
+ }
+
+ if (propertyCaches.at(objectIndex)) {
+ for (const QtQml::Binding *binding = obj->firstBinding(); binding; binding = binding->next)
+ if (binding->type == QV4::CompiledData::Binding::Type_Object || binding->type == QV4::CompiledData::Binding::Type_GroupProperty)
+ if (!buildMetaObjectRecursively(binding->value.objectIndex, objectIndex, binding))
+ return false;
+ }
+
+ return true;
+}
+
+bool QQmlPropertyCacheCreator::ensureMetaObject(int objectIndex)
+{
+ if (!vmeMetaObjects.at(objectIndex).isEmpty())
+ return true;
+ const QtQml::QmlObject *obj = qmlObjects.at(objectIndex);
+ QQmlCompiledData::TypeReference *typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
+ QQmlPropertyCache *baseTypeCache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
+ return createMetaObject(objectIndex, obj, baseTypeCache);
+}
+
+bool QQmlPropertyCacheCreator::createMetaObject(int objectIndex, const QtQml::QmlObject *obj, QQmlPropertyCache *baseTypeCache)
+{
+ QQmlPropertyCache *cache = baseTypeCache->copyAndReserve(QQmlEnginePrivate::get(enginePrivate),
+ obj->propertyCount(),
+ obj->functionCount() + obj->propertyCount() + obj->signalCount(),
+ obj->signalCount() + obj->propertyCount());
+ propertyCaches[objectIndex] = cache;
+
+ struct TypeData {
+ QV4::CompiledData::Property::Type dtype;
+ int metaType;
+ } builtinTypes[] = {
+ { QV4::CompiledData::Property::Var, qMetaTypeId<QJSValue>() },
+ { QV4::CompiledData::Property::Variant, QMetaType::QVariant },
+ { QV4::CompiledData::Property::Int, QMetaType::Int },
+ { QV4::CompiledData::Property::Bool, QMetaType::Bool },
+ { QV4::CompiledData::Property::Real, QMetaType::Double },
+ { QV4::CompiledData::Property::String, QMetaType::QString },
+ { QV4::CompiledData::Property::Url, QMetaType::QUrl },
+ { QV4::CompiledData::Property::Color, QMetaType::QColor },
+ { QV4::CompiledData::Property::Font, QMetaType::QFont },
+ { QV4::CompiledData::Property::Time, QMetaType::QTime },
+ { QV4::CompiledData::Property::Date, QMetaType::QDate },
+ { QV4::CompiledData::Property::DateTime, QMetaType::QDateTime },
+ { QV4::CompiledData::Property::Rect, QMetaType::QRectF },
+ { QV4::CompiledData::Property::Point, QMetaType::QPointF },
+ { QV4::CompiledData::Property::Size, QMetaType::QSizeF },
+ { QV4::CompiledData::Property::Vector2D, QMetaType::QVector2D },
+ { QV4::CompiledData::Property::Vector3D, QMetaType::QVector3D },
+ { QV4::CompiledData::Property::Vector4D, QMetaType::QVector4D },
+ { QV4::CompiledData::Property::Matrix4x4, QMetaType::QMatrix4x4 },
+ { QV4::CompiledData::Property::Quaternion, QMetaType::QQuaternion }
+ };
+ static const uint builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData);
+
+ QByteArray newClassName;
+
+ if (false /* ### compileState->root == obj && !compileState->nested*/) {
+#if 0 // ###
+ QString path = output->url.path();
+ int lastSlash = path.lastIndexOf(QLatin1Char('/'));
+ if (lastSlash > -1) {
+ QString nameBase = path.mid(lastSlash + 1, path.length()-lastSlash-5);
+ if (!nameBase.isEmpty() && nameBase.at(0).isUpper())
+ newClassName = nameBase.toUtf8() + "_QMLTYPE_" +
+ QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1));
+ }
+#endif
+ }
+ if (newClassName.isEmpty()) {
+ newClassName = QQmlMetaObject(baseTypeCache).className();
+ newClassName.append("_QML_");
+ newClassName.append(QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1)));
+ }
+
+ cache->_dynamicClassName = newClassName;
+
+ int aliasCount = 0;
+ int varPropCount = 0;
+
+ PropertyResolver resolver(baseTypeCache);
+
+ for (const QtQml::QmlProperty *p = obj->firstProperty(); p; p = p->next) {
+ if (p->type == QV4::CompiledData::Property::Alias)
+ aliasCount++;
+ else if (p->type == QV4::CompiledData::Property::Var)
+ varPropCount++;
+
+ // No point doing this for both the alias and non alias cases
+ bool notInRevision = false;
+ QQmlPropertyData *d = resolver.property(stringAt(p->nameIndex), &notInRevision);
+ if (d && d->isFinal())
+ COMPILE_EXCEPTION(p, tr("Cannot override FINAL property"));
+ }
+
+ typedef QQmlVMEMetaData VMD;
+
+ QByteArray &dynamicData = vmeMetaObjects[objectIndex] = QByteArray(sizeof(QQmlVMEMetaData)
+ + obj->propertyCount() * sizeof(VMD::PropertyData)
+ + obj->functionCount() * sizeof(VMD::MethodData)
+ + aliasCount * sizeof(VMD::AliasData), 0);
+
+ int effectivePropertyIndex = cache->propertyIndexCacheStart;
+ int effectiveMethodIndex = cache->methodIndexCacheStart;
+
+ // For property change signal override detection.
+ // We prepopulate a set of signal names which already exist in the object,
+ // and throw an error if there is a signal/method defined as an override.
+ QSet<QString> seenSignals;
+ seenSignals << QStringLiteral("destroyed") << QStringLiteral("parentChanged") << QStringLiteral("objectNameChanged");
+ QQmlPropertyCache *parentCache = cache;
+ while ((parentCache = parentCache->parent())) {
+ if (int pSigCount = parentCache->signalCount()) {
+ int pSigOffset = parentCache->signalOffset();
+ for (int i = pSigOffset; i < pSigCount; ++i) {
+ QQmlPropertyData *currPSig = parentCache->signal(i);
+ // XXX TODO: find a better way to get signal name from the property data :-/
+ for (QQmlPropertyCache::StringCache::ConstIterator iter = parentCache->stringCache.begin();
+ iter != parentCache->stringCache.end(); ++iter) {
+ if (currPSig == (*iter).second) {
+ seenSignals.insert(iter.key());
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // First set up notify signals for properties - first normal, then var, then alias
+ enum { NSS_Normal = 0, NSS_Var = 1, NSS_Alias = 2 };
+ for (int ii = NSS_Normal; ii <= NSS_Alias; ++ii) { // 0 == normal, 1 == var, 2 == alias
+
+ if (ii == NSS_Var && varPropCount == 0) continue;
+ else if (ii == NSS_Alias && aliasCount == 0) continue;
+
+ for (const QtQml::QmlProperty *p = obj->firstProperty(); p; p = p->next) {
+ if ((ii == NSS_Normal && (p->type == QV4::CompiledData::Property::Alias ||
+ p->type == QV4::CompiledData::Property::Var)) ||
+ ((ii == NSS_Var) && (p->type != QV4::CompiledData::Property::Var)) ||
+ ((ii == NSS_Alias) && (p->type != QV4::CompiledData::Property::Alias)))
+ continue;
+
+ quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction |
+ QQmlPropertyData::IsVMESignal;
+
+ QString changedSigName = stringAt(p->nameIndex) + QLatin1String("Changed");
+ seenSignals.insert(changedSigName);
+
+ cache->appendSignal(changedSigName, flags, effectiveMethodIndex++);
+ }
+ }
+
+ // Dynamic signals
+ for (const QtQml::Signal *s = obj->firstSignal(); s; s = s->next) {
+ const int paramCount = s->parameters->count;
+
+ QList<QByteArray> names;
+ QVarLengthArray<int, 10> paramTypes(paramCount?(paramCount + 1):0);
+
+ if (paramCount) {
+ paramTypes[0] = paramCount;
+
+ QtQml::SignalParameter *param = s->parameters->first;
+ for (int i = 0; i < paramCount; ++i, param = param->next) {
+ names.append(stringAt(param->nameIndex).toUtf8());
+ if (param->type < builtinTypeCount) {
+ // built-in type
+ paramTypes[i + 1] = builtinTypes[param->type].metaType;
+ } else {
+ // lazily resolved type
+ Q_ASSERT(param->type == QV4::CompiledData::Property::Custom);
+ const QString customTypeName = stringAt(param->customTypeNameIndex);
+ QQmlType *qmltype = 0;
+ if (!imports->resolveType(customTypeName, &qmltype, 0, 0, 0))
+ COMPILE_EXCEPTION(s, tr("Invalid signal parameter type: %1").arg(customTypeName));
+
+ if (qmltype->isComposite()) {
+ QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl());
+ Q_ASSERT(tdata);
+ Q_ASSERT(tdata->isComplete());
+
+ QQmlCompiledData *data = tdata->compiledData();
+
+ paramTypes[i + 1] = data->metaTypeId;
+
+ tdata->release();
+ } else {
+ paramTypes[i + 1] = qmltype->typeId();
+ }
+ }
+ }
+ }
+
+ ((QQmlVMEMetaData *)dynamicData.data())->signalCount++;
+
+ quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction |
+ QQmlPropertyData::IsVMESignal;
+ if (paramCount)
+ flags |= QQmlPropertyData::HasArguments;
+
+ QString signalName = stringAt(s->nameIndex);
+ if (seenSignals.contains(signalName))
+ COMPILE_EXCEPTION(s, tr("Duplicate signal name: invalid override of property change signal or superclass signal"));
+ seenSignals.insert(signalName);
+
+ cache->appendSignal(signalName, flags, effectiveMethodIndex++,
+ paramCount?paramTypes.constData():0, names);
+ }
+
+
+ // Dynamic slots
+ for (const QtQml::Function *s = obj->firstFunction(); s; s = s->next) {
+ AST::FunctionDeclaration *astFunction = s->functionDeclaration;
+
+ quint32 flags = QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMEFunction;
+
+ if (astFunction->formals)
+ flags |= QQmlPropertyData::HasArguments;
+
+ QString slotName = astFunction->name.toString();
+ if (seenSignals.contains(slotName))
+ COMPILE_EXCEPTION(s, tr("Duplicate method name: invalid override of property change signal or superclass signal"));
+ // Note: we don't append slotName to the seenSignals list, since we don't
+ // protect against overriding change signals or methods with properties.
+
+ QList<QByteArray> parameterNames;
+ AST::FormalParameterList *param = astFunction->formals;
+ while (param) {
+ parameterNames << param->name.toUtf8();
+ param = param->next;
+ }
+
+ cache->appendMethod(slotName, flags, effectiveMethodIndex++, parameterNames);
+ }
+
+
+ // Dynamic properties (except var and aliases)
+ int effectiveSignalIndex = cache->signalHandlerIndexCacheStart;
+ int propertyIdx = 0;
+ for (const QtQml::QmlProperty *p = obj->firstProperty(); p; p = p->next, ++propertyIdx) {
+
+ if (p->type == QV4::CompiledData::Property::Alias ||
+ p->type == QV4::CompiledData::Property::Var)
+ continue;
+
+ int propertyType = 0;
+ int vmePropertyType = 0;
+ quint32 propertyFlags = 0;
+
+ if (p->type < builtinTypeCount) {
+ propertyType = builtinTypes[p->type].metaType;
+ vmePropertyType = propertyType;
+
+ if (p->type == QV4::CompiledData::Property::Variant)
+ propertyFlags |= QQmlPropertyData::IsQVariant;
+ } else {
+ Q_ASSERT(p->type == QV4::CompiledData::Property::CustomList ||
+ p->type == QV4::CompiledData::Property::Custom);
+
+ QQmlType *qmltype = 0;
+ if (!imports->resolveType(stringAt(p->customTypeNameIndex), &qmltype, 0, 0, 0)) {
+ COMPILE_EXCEPTION(p, tr("Invalid property type"));
+ }
+
+ Q_ASSERT(qmltype);
+ if (qmltype->isComposite()) {
+ QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl());
+ Q_ASSERT(tdata);
+ Q_ASSERT(tdata->isComplete());
+
+ QQmlCompiledData *data = tdata->compiledData();
+
+ if (p->type == QV4::CompiledData::Property::Custom) {
+ propertyType = data->metaTypeId;
+ vmePropertyType = QMetaType::QObjectStar;
+ } else {
+ propertyType = data->listMetaTypeId;
+ vmePropertyType = qMetaTypeId<QQmlListProperty<QObject> >();
+ }
+
+ tdata->release();
+ } else {
+ if (p->type == QV4::CompiledData::Property::Custom) {
+ propertyType = qmltype->typeId();
+ vmePropertyType = QMetaType::QObjectStar;
+ } else {
+ propertyType = qmltype->qListTypeId();
+ vmePropertyType = qMetaTypeId<QQmlListProperty<QObject> >();
+ }
+ }
+
+ if (p->type == QV4::CompiledData::Property::Custom)
+ propertyFlags |= QQmlPropertyData::IsQObjectDerived;
+ else
+ propertyFlags |= QQmlPropertyData::IsQList;
+ }
+
+ if ((!p->flags & QV4::CompiledData::Property::IsReadOnly) && p->type != QV4::CompiledData::Property::CustomList)
+ propertyFlags |= QQmlPropertyData::IsWritable;
+
+
+ QString propertyName = stringAt(p->nameIndex);
+ if (propertyIdx == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName;
+ cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
+ propertyType, effectiveSignalIndex);
+
+ effectiveSignalIndex++;
+
+ VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
+ (vmd->propertyData() + vmd->propertyCount)->propertyType = vmePropertyType;
+ vmd->propertyCount++;
+ }
+
+ // Now do var properties
+ propertyIdx = 0;
+ for (const QtQml::QmlProperty *p = obj->firstProperty(); p; p = p->next, ++propertyIdx) {
+
+ if (p->type != QV4::CompiledData::Property::Var)
+ continue;
+
+ quint32 propertyFlags = QQmlPropertyData::IsVarProperty;
+ if (!p->flags & QV4::CompiledData::Property::IsReadOnly)
+ propertyFlags |= QQmlPropertyData::IsWritable;
+
+ VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
+ (vmd->propertyData() + vmd->propertyCount)->propertyType = QMetaType::QVariant;
+ vmd->propertyCount++;
+ ((QQmlVMEMetaData *)dynamicData.data())->varPropertyCount++;
+
+ QString propertyName = stringAt(p->nameIndex);
+ if (propertyIdx == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName;
+ cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
+ QMetaType::QVariant, effectiveSignalIndex);
+
+ effectiveSignalIndex++;
+ }
+
+ // Alias property count. Actual data is setup in buildDynamicMetaAliases
+ ((QQmlVMEMetaData *)dynamicData.data())->aliasCount = aliasCount;
+
+ // Dynamic slot data - comes after the property data
+ for (const QtQml::Function *s = obj->firstFunction(); s; s = s->next) {
+ AST::FunctionDeclaration *astFunction = s->functionDeclaration;
+ int formalsCount = 0;
+ AST::FormalParameterList *param = astFunction->formals;
+ while (param) {
+ formalsCount++;
+ param = param->next;
+ }
+
+ VMD::MethodData methodData = { /* runtimeFunctionIndex*/ 0, // ###
+ formalsCount,
+ /* s->location.start.line */0 }; // ###
+
+ VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
+ VMD::MethodData &md = *(vmd->methodData() + vmd->methodCount);
+ vmd->methodCount++;
+ md = methodData;
+ }
+
+ return true;
+}
+
+QQmlEnumTypeResolver::QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler)
+ : QQmlCompilePass(typeCompiler)
+ , qmlObjects(*typeCompiler->qmlObjects())
+ , propertyCaches(typeCompiler->propertyCaches())
+ , imports(typeCompiler->imports())
+ , resolvedTypes(typeCompiler->resolvedTypes())
+{
+}
+
+bool QQmlEnumTypeResolver::resolveEnumBindings()
+{
+ for (int i = 0; i < qmlObjects.count(); ++i) {
+ QQmlPropertyCache *propertyCache = propertyCaches.at(i);
+ if (!propertyCache)
+ continue;
+ const QmlObject *obj = qmlObjects.at(i);
+
+ PropertyResolver resolver(propertyCache);
+
+ for (QtQml::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
+ if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression
+ || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
+ continue;
+
+ if (binding->type != QV4::CompiledData::Binding::Type_Script)
+ continue;
+
+ const QString propertyName = stringAt(binding->propertyNameIndex);
+ bool notInRevision = false;
+ QQmlPropertyData *pd = resolver.property(propertyName, &notInRevision);
+ if (!pd)
+ continue;
+
+ if (!pd->isEnum() && pd->propType != QMetaType::Int)
+ continue;
+
+ if (!tryQualifiedEnumAssignment(obj, propertyCache, pd, binding))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+struct StaticQtMetaObject : public QObject
+{
+ static const QMetaObject *get()
+ { return &staticQtMetaObject; }
+};
+
+bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlObject *obj, const QQmlPropertyCache *propertyCache, const QQmlPropertyData *prop, Binding *binding)
+{
+ bool isIntProp = (prop->propType == QMetaType::Int) && !prop->isEnum();
+ if (!prop->isEnum() && !isIntProp)
+ return true;
+
+ if (!prop->isWritable() && !(binding->flags & QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration))
+ COMPILE_EXCEPTION(binding, tr("Invalid property assignment: \"%1\" is a read-only property").arg(stringAt(binding->propertyNameIndex)));
+
+ Q_ASSERT(binding->type = QV4::CompiledData::Binding::Type_Script);
+ QString string = stringAt(binding->stringIndex);
+ if (!string.at(0).isUpper())
+ return true;
+
+ int dot = string.indexOf(QLatin1Char('.'));
+ if (dot == -1 || dot == string.length()-1)
+ return true;
+
+ if (string.indexOf(QLatin1Char('.'), dot+1) != -1)
+ return true;
+
+ QHashedStringRef typeName(string.constData(), dot);
+ QString enumValue = string.mid(dot+1);
+
+ if (isIntProp) {
+ // Allow enum assignment to ints.
+ bool ok;
+ int enumval = evaluateEnum(typeName.toString(), enumValue.toUtf8(), &ok);
+ if (ok) {
+ binding->type = QV4::CompiledData::Binding::Type_Number;
+ binding->value.d = (double)enumval;
+ binding->flags |= QV4::CompiledData::Binding::IsResolvedEnum;
+ }
+ return true;
+ }
+ QQmlType *type = 0;
+ imports->resolveType(typeName, &type, 0, 0, 0);
+
+ if (!type && typeName != QLatin1String("Qt"))
+ return true;
+ if (type && type->isComposite()) //No enums on composite (or composite singleton) types
+ return true;
+
+ int value = 0;
+ bool ok = false;
+
+ QQmlCompiledData::TypeReference *tr = resolvedTypes->value(obj->inheritedTypeNameIndex);
+ if (type && tr && tr->type == type) {
+ QMetaProperty mprop = propertyCache->firstCppMetaObject()->property(prop->coreIndex);
+
+ // When these two match, we can short cut the search
+ if (mprop.isFlagType()) {
+ value = mprop.enumerator().keysToValue(enumValue.toUtf8().constData(), &ok);
+ } else {
+ value = mprop.enumerator().keyToValue(enumValue.toUtf8().constData(), &ok);
+ }
+ } else {
+ // Otherwise we have to search the whole type
+ if (type) {
+ value = type->enumValue(QHashedStringRef(enumValue), &ok);
+ } else {
+ QByteArray enumName = enumValue.toUtf8();
+ const QMetaObject *metaObject = StaticQtMetaObject::get();
+ for (int ii = metaObject->enumeratorCount() - 1; !ok && ii >= 0; --ii) {
+ QMetaEnum e = metaObject->enumerator(ii);
+ value = e.keyToValue(enumName.constData(), &ok);
+ }
+ }
+ }
+
+ if (!ok)
+ return true;
+
+ binding->type = QV4::CompiledData::Binding::Type_Number;
+ binding->value.d = (double)value;
+ binding->flags |= QV4::CompiledData::Binding::IsResolvedEnum;
+ return true;
+}
+
+int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &enumValue, bool *ok) const
+{
+ Q_ASSERT_X(ok, "QQmlEnumTypeResolver::evaluateEnum", "ok must not be a null pointer");
+ *ok = false;
+
+ if (scope != QLatin1String("Qt")) {
+ QQmlType *type = 0;
+ imports->resolveType(scope, &type, 0, 0, 0);
+ return type ? type->enumValue(QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1;
+ }
+
+ const QMetaObject *mo = StaticQtMetaObject::get();
+ int i = mo->enumeratorCount();
+ while (i--) {
+ int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
+ if (*ok)
+ return v;
+ }
+ return -1;
+}
+
+
+QQmlAliasAnnotator::QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler)
+ : QQmlCompilePass(typeCompiler)
+ , qmlObjects(*typeCompiler->qmlObjects())
+ , propertyCaches(typeCompiler->propertyCaches())
+{
+}
+
+void QQmlAliasAnnotator::annotateBindingsToAliases()
+{
+ for (int i = 0; i < qmlObjects.count(); ++i) {
+ QQmlPropertyCache *propertyCache = propertyCaches.at(i);
+ if (!propertyCache)
+ continue;
+
+ const QmlObject *obj = qmlObjects.at(i);
+
+ PropertyResolver resolver(propertyCache);
+ QQmlPropertyData *defaultProperty = obj->indexOfDefaultProperty != -1 ? propertyCache->parent()->defaultProperty() : propertyCache->defaultProperty();
+
+ for (QtQml::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
+ if (!binding->isValueBinding())
+ continue;
+ bool notInRevision = false;
+ QQmlPropertyData *pd = binding->propertyNameIndex != 0 ? resolver.property(stringAt(binding->propertyNameIndex), &notInRevision) : defaultProperty;
+ if (pd && pd->isAlias())
+ binding->flags |= QV4::CompiledData::Binding::IsBindingToAlias;
+ }
+ }
+}
+
+QQmlComponentAndAliasResolver::QQmlComponentAndAliasResolver(QQmlTypeCompiler *typeCompiler)
+ : QQmlCompilePass(typeCompiler)
+ , enginePrivate(typeCompiler->enginePrivate())
+ , pool(typeCompiler->memoryPool())
+ , qmlObjects(typeCompiler->qmlObjects())
+ , indexOfRootObject(typeCompiler->rootObjectIndex())
+ , _componentIndex(-1)
+ , _objectIndexToIdInScope(0)
+ , resolvedTypes(typeCompiler->resolvedTypes())
+ , propertyCaches(typeCompiler->propertyCaches())
+ , vmeMetaObjectData(typeCompiler->vmeMetaObjects())
+ , objectIndexToIdForRoot(typeCompiler->objectIndexToIdForRoot())
+ , objectIndexToIdPerComponent(typeCompiler->objectIndexToIdPerComponent())
+{
+}
+
+void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QtQml::QmlObject *obj, int objectIndex)
+{
+ QQmlPropertyCache *propertyCache = propertyCaches.value(objectIndex);
+ if (!propertyCache)
+ return;
+
+ PropertyResolver propertyResolver(propertyCache);
+
+ QQmlPropertyData *defaultProperty = obj->indexOfDefaultProperty != -1 ? propertyCache->parent()->defaultProperty() : propertyCache->defaultProperty();
+
+ for (QtQml::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
+ if (binding->type != QV4::CompiledData::Binding::Type_Object)
+ continue;
+ if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
+ continue;
+
+ const QtQml::QmlObject *targetObject = qmlObjects->at(binding->value.objectIndex);
+ QQmlCompiledData::TypeReference *tr = resolvedTypes->value(targetObject->inheritedTypeNameIndex);
+ Q_ASSERT(tr);
+ QQmlType *targetType = tr->type;
+ if (targetType && targetType->metaObject() == &QQmlComponent::staticMetaObject)
+ continue;
+
+ QQmlPropertyData *pd = 0;
+ if (binding->propertyNameIndex != 0) {
+ bool notInRevision = false;
+ pd = propertyResolver.property(stringAt(binding->propertyNameIndex), &notInRevision);
+ } else {
+ pd = defaultProperty;
+ }
+ if (!pd || !pd->isQObject())
+ continue;
+
+ QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType);
+ const QMetaObject *mo = pc->firstCppMetaObject();
+ while (mo) {
+ if (mo == &QQmlComponent::staticMetaObject)
+ break;
+ mo = mo->superClass();
+ }
+
+ if (!mo)
+ continue;
+
+ static QQmlType *componentType = QQmlMetaType::qmlType(&QQmlComponent::staticMetaObject);
+ Q_ASSERT(componentType);
+
+ QtQml::QmlObject *syntheticComponent = pool->New<QtQml::QmlObject>();
+ syntheticComponent->init(pool, compiler->registerString(QString::fromUtf8(componentType->typeName())), compiler->registerString(QString()));
+
+ if (!resolvedTypes->contains(syntheticComponent->inheritedTypeNameIndex)) {
+ QQmlCompiledData::TypeReference *typeRef = new QQmlCompiledData::TypeReference;
+ typeRef->type = componentType;
+ typeRef->majorVersion = componentType->majorVersion();
+ typeRef->minorVersion = componentType->minorVersion();
+ resolvedTypes->insert(syntheticComponent->inheritedTypeNameIndex, typeRef);
+ }
+
+ qmlObjects->append(syntheticComponent);
+ const int componentIndex = qmlObjects->count() - 1;
+
+ QtQml::Binding *syntheticBinding = pool->New<QtQml::Binding>();
+ *syntheticBinding = *binding;
+ syntheticBinding->type = QV4::CompiledData::Binding::Type_Object;
+ QString error = syntheticComponent->appendBinding(syntheticBinding, /*isListBinding*/false);
+ Q_ASSERT(error.isEmpty());
+ Q_UNUSED(error);
+
+ binding->value.objectIndex = componentIndex;
+
+ componentRoots.append(componentIndex);
+ componentBoundaries.append(syntheticBinding->value.objectIndex);
+ }
+}
+
+bool QQmlComponentAndAliasResolver::resolve()
+{
+ // Detect real Component {} objects as well as implicitly defined components, such as
+ // someItemDelegate: Item {}
+ // In the implicit case Item is surrounded by a synthetic Component {} because the property
+ // on the left hand side is of QQmlComponent type.
+ const int objCountWithoutSynthesizedComponents = qmlObjects->count();
+ for (int i = 0; i < objCountWithoutSynthesizedComponents; ++i) {
+ const QtQml::QmlObject *obj = qmlObjects->at(i);
+ if (obj->inheritedTypeNameIndex == 0)
+ continue;
+
+ QQmlCompiledData::TypeReference *tref = resolvedTypes->value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(tref);
+ if (!tref->type || tref->type->metaObject() != &QQmlComponent::staticMetaObject) {
+ findAndRegisterImplicitComponents(obj, i);
+ continue;
+ }
+
+ componentRoots.append(i);
+
+ if (obj->functionCount() > 0)
+ COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new functions."));
+ if (obj->propertyCount() > 0)
+ COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new properties."));
+ if (obj->signalCount() > 0)
+ COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new signals."));
+
+ if (obj->bindingCount() == 0)
+ COMPILE_EXCEPTION(obj, tr("Cannot create empty component specification"));
+
+ const QtQml::Binding *rootBinding = obj->firstBinding();
+ if (rootBinding->next || rootBinding->type != QV4::CompiledData::Binding::Type_Object)
+ COMPILE_EXCEPTION(rootBinding, tr("Component elements may not contain properties other than id"));
+
+ componentBoundaries.append(rootBinding->value.objectIndex);
+ }
+
+ std::sort(componentBoundaries.begin(), componentBoundaries.end());
+
+ for (int i = 0; i < componentRoots.count(); ++i) {
+ const QtQml::QmlObject *component = qmlObjects->at(componentRoots.at(i));
+ const QtQml::Binding *rootBinding = component->firstBinding();
+
+ _componentIndex = i;
+ _idToObjectIndex.clear();
+
+ _objectIndexToIdInScope = &(*objectIndexToIdPerComponent)[componentRoots.at(i)];
+
+ _objectsWithAliases.clear();
+
+ if (!collectIdsAndAliases(rootBinding->value.objectIndex))
+ return false;
+
+ if (!resolveAliases())
+ return false;
+ }
+
+ // Collect ids and aliases for root
+ _componentIndex = -1;
+ _idToObjectIndex.clear();
+ _objectIndexToIdInScope = objectIndexToIdForRoot;
+ _objectsWithAliases.clear();
+
+ collectIdsAndAliases(indexOfRootObject);
+
+ resolveAliases();
+
+ return true;
+}
+
+bool QQmlComponentAndAliasResolver::collectIdsAndAliases(int objectIndex)
+{
+ const QtQml::QmlObject *obj = qmlObjects->at(objectIndex);
+
+ if (obj->idIndex != 0) {
+ if (_idToObjectIndex.contains(obj->idIndex)) {
+ recordError(obj->locationOfIdProperty, tr("id is not unique"));
+ return false;
+ }
+ _idToObjectIndex.insert(obj->idIndex, objectIndex);
+ _objectIndexToIdInScope->insert(objectIndex, _objectIndexToIdInScope->count());
+ }
+
+ for (const QtQml::QmlProperty *property = obj->firstProperty(); property; property = property->next) {
+ if (property->type == QV4::CompiledData::Property::Alias) {
+ _objectsWithAliases.append(objectIndex);
+ break;
+ }
+ }
+
+ for (const QtQml::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
+ if (binding->type != QV4::CompiledData::Binding::Type_Object
+ && binding->type != QV4::CompiledData::Binding::Type_AttachedProperty
+ && binding->type != QV4::CompiledData::Binding::Type_GroupProperty)
+ continue;
+
+ // Stop at Component boundary
+ if (std::binary_search(componentBoundaries.constBegin(), componentBoundaries.constEnd(), binding->value.objectIndex))
+ continue;
+
+ if (!collectIdsAndAliases(binding->value.objectIndex))
+ return false;
+ }
+
+ return true;
+}
+
+bool QQmlComponentAndAliasResolver::resolveAliases()
+{
+ foreach (int objectIndex, _objectsWithAliases) {
+ const QtQml::QmlObject *obj = qmlObjects->at(objectIndex);
+
+ QQmlPropertyCache *propertyCache = propertyCaches.value(objectIndex);
+ Q_ASSERT(propertyCache);
+
+ int effectiveSignalIndex = propertyCache->signalHandlerIndexCacheStart + propertyCache->propertyIndexCache.count();
+ int effectivePropertyIndex = propertyCache->propertyIndexCacheStart + propertyCache->propertyIndexCache.count();
+ int effectiveAliasIndex = 0;
+
+ const QtQml::QmlProperty *p = obj->firstProperty();
+ for (int propertyIndex = 0; propertyIndex < obj->propertyCount(); ++propertyIndex, p = p->next) {
+ if (p->type != QV4::CompiledData::Property::Alias)
+ continue;
+
+ const int idIndex = p->aliasIdValueIndex;
+ const int targetObjectIndex = _idToObjectIndex.value(idIndex, -1);
+ if (targetObjectIndex == -1) {
+ recordError(p->aliasLocation, tr("Invalid alias reference. Unable to find id \"%1\"").arg(stringAt(idIndex)));
+ return false;
+ }
+ const int targetId = _objectIndexToIdInScope->value(targetObjectIndex, -1);
+ Q_ASSERT(targetId != -1);
+
+ const QString aliasPropertyValue = stringAt(p->aliasPropertyValueIndex);
+
+ QStringRef property;
+ QStringRef subProperty;
+
+ const int propertySeparator = aliasPropertyValue.indexOf(QLatin1Char('.'));
+ if (propertySeparator != -1) {
+ property = aliasPropertyValue.leftRef(propertySeparator);
+ subProperty = aliasPropertyValue.midRef(propertySeparator + 1);
+ } else
+ property = QStringRef(&aliasPropertyValue, 0, aliasPropertyValue.length());
+
+ int propIdx = -1;
+ int propType = 0;
+ int notifySignal = -1;
+ int flags = 0;
+ int type = 0;
+ bool writable = false;
+ bool resettable = false;
+
+ quint32 propertyFlags = QQmlPropertyData::IsAlias;
+
+ if (property.isEmpty()) {
+ const QtQml::QmlObject *targetObject = qmlObjects->at(targetObjectIndex);
+ QQmlCompiledData::TypeReference *typeRef = resolvedTypes->value(targetObject->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
+
+ if (typeRef->type)
+ type = typeRef->type->typeId();
+ else
+ type = typeRef->component->metaTypeId;
+
+ flags |= QML_ALIAS_FLAG_PTR;
+ propertyFlags |= QQmlPropertyData::IsQObjectDerived;
+ } else {
+ QQmlPropertyCache *targetCache = propertyCaches.value(targetObjectIndex);
+ Q_ASSERT(targetCache);
+ QtQml::PropertyResolver resolver(targetCache);
+
+ QQmlPropertyData *targetProperty = resolver.property(property.toString());
+ if (!targetProperty || targetProperty->coreIndex > 0x0000FFFF) {
+ recordError(p->aliasLocation, tr("Invalid alias location"));
+ return false;
+ }
+
+ propIdx = targetProperty->coreIndex;
+ type = targetProperty->propType;
+
+ writable = targetProperty->isWritable();
+ resettable = targetProperty->isResettable();
+ notifySignal = targetProperty->notifyIndex;
+
+ if (!subProperty.isEmpty()) {
+ QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type);
+ if (!valueType) {
+ recordError(p->aliasLocation, tr("Invalid alias location"));
+ return false;
+ }
+
+ propType = type;
+
+ int valueTypeIndex =
+ valueType->metaObject()->indexOfProperty(subProperty.toString().toUtf8().constData());
+ if (valueTypeIndex == -1) {
+ recordError(p->aliasLocation, tr("Invalid alias location"));
+ return false;
+ }
+ Q_ASSERT(valueTypeIndex <= 0x0000FFFF);
+
+ propIdx |= (valueTypeIndex << 16);
+ if (valueType->metaObject()->property(valueTypeIndex).isEnumType())
+ type = QVariant::Int;
+ else
+ type = valueType->metaObject()->property(valueTypeIndex).userType();
+
+ } else {
+ if (targetProperty->isEnum()) {
+ type = QVariant::Int;
+ } else {
+ // Copy type flags
+ propertyFlags |= targetProperty->getFlags() & QQmlPropertyData::PropTypeFlagMask;
+
+ if (targetProperty->isVarProperty())
+ propertyFlags |= QQmlPropertyData::IsQVariant;
+
+ if (targetProperty->isQObject())
+ flags |= QML_ALIAS_FLAG_PTR;
+ }
+ }
+ }
+
+ QQmlVMEMetaData::AliasData aliasData = { targetId, propIdx, propType, flags, notifySignal };
+
+ typedef QQmlVMEMetaData VMD;
+ QByteArray &dynamicData = (*vmeMetaObjectData)[objectIndex];
+ Q_ASSERT(!dynamicData.isEmpty());
+ VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
+ *(vmd->aliasData() + effectiveAliasIndex++) = aliasData;
+
+ Q_ASSERT(dynamicData.isDetached());
+
+ if (!(p->flags & QV4::CompiledData::Property::IsReadOnly) && writable)
+ propertyFlags |= QQmlPropertyData::IsWritable;
+ else
+ propertyFlags &= ~QQmlPropertyData::IsWritable;
+
+ if (resettable)
+ propertyFlags |= QQmlPropertyData::IsResettable;
+ else
+ propertyFlags &= ~QQmlPropertyData::IsResettable;
+
+ QString propertyName = stringAt(p->nameIndex);
+ if (propertyIndex == obj->indexOfDefaultProperty) propertyCache->_defaultPropertyName = propertyName;
+ propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
+ type, effectiveSignalIndex++);
+
+ }
+ }
+ return true;
+}
+
+
+QQmlPropertyValidator::QQmlPropertyValidator(QQmlTypeCompiler *typeCompiler, const QVector<int> &runtimeFunctionIndices)
+ : QQmlCompilePass(typeCompiler)
+ , enginePrivate(typeCompiler->enginePrivate())
+ , qmlUnit(typeCompiler->qmlUnit())
+ , resolvedTypes(*typeCompiler->resolvedTypes())
+ , propertyCaches(typeCompiler->propertyCaches())
+ , objectIndexToIdPerComponent(*typeCompiler->objectIndexToIdPerComponent())
+ , customParserData(typeCompiler->customParserData())
+ , runtimeFunctionIndices(runtimeFunctionIndices)
+{
+}
+
+bool QQmlPropertyValidator::validate()
+{
+ if (!validateObject(qmlUnit->indexOfRootObject, /*instantiatingBinding*/0))
+ return false;
+ compiler->setCustomParserBindings(customParserBindings);
+ return true;
+}
+
+const QQmlImports &QQmlPropertyValidator::imports() const
+{
+ return *compiler->imports();
+}
+
+AST::Node *QQmlPropertyValidator::astForBinding(int scriptIndex) const
+{
+ // ####
+ int reverseIndex = runtimeFunctionIndices.indexOf(scriptIndex);
+ if (reverseIndex == -1)
+ return 0;
+ return compiler->functions().value(reverseIndex).node;
+}
+
+QQmlBinding::Identifier QQmlPropertyValidator::bindingIdentifier(const QV4::CompiledData::Binding *binding, QQmlCustomParser *)
+{
+ int id = customParserBindings.count();
+ customParserBindings.append(binding->value.compiledScriptIndex);
+ return id;
+}
+
+bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding)
+{
+ const QV4::CompiledData::Object *obj = qmlUnit->objectAt(objectIndex);
+
+ if (isComponent(objectIndex)) {
+ Q_ASSERT(obj->nBindings == 1);
+ const QV4::CompiledData::Binding *componentBinding = obj->bindingTable();
+ Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object);
+ return validateObject(componentBinding->value.objectIndex, componentBinding);
+ }
+
+ QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex);
+ if (!propertyCache)
+ return true;
+
+ QQmlCustomParser *customParser = 0;
+ QQmlCompiledData::TypeReference *objectType = resolvedTypes.value(obj->inheritedTypeNameIndex);
+ if (objectType && objectType->type)
+ customParser = objectType->type->customParser();
+ QList<const QV4::CompiledData::Binding*> customBindings;
+
+ PropertyResolver propertyResolver(propertyCache);
+
+ QString defaultPropertyName;
+ QQmlPropertyData *defaultProperty = 0;
+ if (obj->indexOfDefaultProperty != -1) {
+ QQmlPropertyCache *cache = propertyCache->parent();
+ defaultPropertyName = cache->defaultPropertyName();
+ defaultProperty = cache->defaultProperty();
+ } else {
+ defaultPropertyName = propertyCache->defaultPropertyName();
+ defaultProperty = propertyCache->defaultProperty();
+ }
+
+ const QV4::CompiledData::Binding *binding = obj->bindingTable();
+ for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) {
+
+ if (customParser) {
+ if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
+ if (customParser->flags() & QQmlCustomParser::AcceptsAttachedProperties) {
+ customBindings << binding;
+ continue;
+ }
+ } else if ((binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression)
+ && !(customParser->flags() & QQmlCustomParser::AcceptsSignalHandlers)) {
+ customBindings << binding;
+ continue;
+ } else if (binding->type == QV4::CompiledData::Binding::Type_Object
+ || binding->type == QV4::CompiledData::Binding::Type_GroupProperty) {
+ customBindings << binding;
+ continue;
+ }
+ }
+
+ if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
+ if (!validateObject(binding->value.objectIndex, binding))
+ return false;
+ // Nothing further to check for attached properties.
+ if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty)
+ continue;
+ }
+
+ // Signal handlers were resolved and checked earlier in the signal handler conversion pass.
+ if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression
+ || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
+ continue;
+
+ QString name = stringAt(binding->propertyNameIndex);
+
+ bool bindingToDefaultProperty = false;
+
+ bool notInRevision = false;
+ QQmlPropertyData *pd = 0;
+ if (!name.isEmpty()) {
+ if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression
+ || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
+ pd = propertyResolver.signal(name, &notInRevision);
+ else
+ pd = propertyResolver.property(name, &notInRevision);
+
+ if (notInRevision) {
+ QString typeName = stringAt(obj->inheritedTypeNameIndex);
+ if (objectType && objectType->type) {
+ COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(objectType->type->module()).arg(objectType->majorVersion).arg(objectType->minorVersion));
+ } else {
+ COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(name));
+ }
+ }
+ } else {
+ if (instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty)
+ COMPILE_EXCEPTION(binding, tr("Cannot assign a value directly to a grouped property"));
+
+ pd = defaultProperty;
+ name = defaultPropertyName;
+ bindingToDefaultProperty = true;
+ }
+
+ if (pd) {
+ if (!pd->isWritable()
+ && !pd->isQList()
+ && binding->type != QV4::CompiledData::Binding::Type_GroupProperty
+ && !(binding->flags & QV4::CompiledData::Binding::InitializerForReadOnlyDeclaration)
+ ) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: \"%1\" is a read-only property").arg(name));
+ return false;
+ }
+
+ if (!pd->isQList() && (binding->flags & QV4::CompiledData::Binding::IsListItem)) {
+ QString error;
+ if (pd->propType == qMetaTypeId<QQmlScriptString>())
+ error = tr( "Cannot assign multiple values to a script property");
+ else
+ error = tr( "Cannot assign multiple values to a singular property");
+ recordError(binding->valueLocation, error);
+ return false;
+ }
+
+ if (binding->type < QV4::CompiledData::Binding::Type_Script) {
+ if (!validateLiteralBinding(propertyCache, pd, binding))
+ return false;
+ } else if (binding->type == QV4::CompiledData::Binding::Type_Object) {
+ if (!validateObjectBinding(pd, name, binding))
+ return false;
+ }
+ } else {
+ if (customParser) {
+ customBindings << binding;
+ continue;
+ }
+ if (bindingToDefaultProperty) {
+ COMPILE_EXCEPTION(binding, tr("Cannot assign to non-existent default property"));
+ } else {
+ COMPILE_EXCEPTION(binding, tr("Cannot assign to non-existent property \"%1\"").arg(name));
+ }
+ }
+ }
+
+ if (customParser && !customBindings.isEmpty()) {
+ customParser->clearErrors();
+ customParser->compiler = this;
+ QByteArray data = customParser->compile(qmlUnit, customBindings);
+ customParser->compiler = 0;
+ customParserData->insert(objectIndex, data);
+ const QList<QQmlError> parserErrors = customParser->errors();
+ if (!parserErrors.isEmpty()) {
+ foreach (QQmlError error, parserErrors)
+ compiler->recordError(error);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding)
+{
+ if (property->isEnum()) {
+ if (binding->flags & QV4::CompiledData::Binding::IsResolvedEnum)
+ return true;
+
+ QString value = binding->valueAsString(&qmlUnit->header);
+ QMetaProperty p = propertyCache->firstCppMetaObject()->property(property->coreIndex);
+ bool ok;
+ if (p.isFlagType()) {
+ p.enumerator().keysToValue(value.toUtf8().constData(), &ok);
+ } else
+ p.enumerator().keyToValue(value.toUtf8().constData(), &ok);
+
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: unknown enumeration"));
+ return false;
+ }
+ return true;
+ }
+
+ switch (property->propType) {
+ case QMetaType::QVariant:
+ break;
+ case QVariant::String: {
+ if (binding->type != QV4::CompiledData::Binding::Type_String) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: string expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::StringList: {
+ if (binding->type != QV4::CompiledData::Binding::Type_String) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: string or string list expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::ByteArray: {
+ if (binding->type != QV4::CompiledData::Binding::Type_String) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: byte array expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::Url: {
+ if (binding->type != QV4::CompiledData::Binding::Type_String) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: url expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::UInt: {
+ if (binding->type == QV4::CompiledData::Binding::Type_Number) {
+ double d = binding->valueAsNumber();
+ if (double(uint(d)) == d)
+ return true;
+ }
+ recordError(binding->valueLocation, tr("Invalid property assignment: unsigned int expected"));
+ return false;
+ }
+ break;
+ case QVariant::Int: {
+ if (binding->type == QV4::CompiledData::Binding::Type_Number) {
+ double d = binding->valueAsNumber();
+ if (double(int(d)) == d)
+ return true;
+ }
+ recordError(binding->valueLocation, tr("Invalid property assignment: int expected"));
+ return false;
+ }
+ break;
+ case QMetaType::Float: {
+ if (binding->type != QV4::CompiledData::Binding::Type_Number) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: number expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::Double: {
+ if (binding->type != QV4::CompiledData::Binding::Type_Number) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: number expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::Color: {
+ bool ok = false;
+ QQmlStringConverters::rgbaFromString(binding->valueAsString(&qmlUnit->header), &ok);
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: color expected"));
+ return false;
+ }
+ }
+ break;
+#ifndef QT_NO_DATESTRING
+ case QVariant::Date: {
+ bool ok = false;
+ QQmlStringConverters::dateFromString(binding->valueAsString(&qmlUnit->header), &ok);
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: date expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::Time: {
+ bool ok = false;
+ QQmlStringConverters::timeFromString(binding->valueAsString(&qmlUnit->header), &ok);
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: time expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::DateTime: {
+ bool ok = false;
+ QQmlStringConverters::dateTimeFromString(binding->valueAsString(&qmlUnit->header), &ok);
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: datetime expected"));
+ return false;
+ }
+ }
+ break;
+#endif // QT_NO_DATESTRING
+ case QVariant::Point: {
+ bool ok = false;
+ QQmlStringConverters::pointFFromString(binding->valueAsString(&qmlUnit->header), &ok).toPoint();
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: point expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::PointF: {
+ bool ok = false;
+ QQmlStringConverters::pointFFromString(binding->valueAsString(&qmlUnit->header), &ok);
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: point expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::Size: {
+ bool ok = false;
+ QQmlStringConverters::sizeFFromString(binding->valueAsString(&qmlUnit->header), &ok).toSize();
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: size expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::SizeF: {
+ bool ok = false;
+ QQmlStringConverters::sizeFFromString(binding->valueAsString(&qmlUnit->header), &ok);
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: size expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::Rect: {
+ bool ok = false;
+ QQmlStringConverters::rectFFromString(binding->valueAsString(&qmlUnit->header), &ok).toRect();
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: rect expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::RectF: {
+ bool ok = false;
+ QQmlStringConverters::rectFFromString(binding->valueAsString(&qmlUnit->header), &ok);
+ if (!ok) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: point expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::Bool: {
+ if (binding->type != QV4::CompiledData::Binding::Type_Boolean) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: boolean expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::Vector3D: {
+ struct {
+ float xp;
+ float yp;
+ float zy;
+ } vec;
+ if (!QQmlStringConverters::createFromString(QMetaType::QVector3D, binding->valueAsString(&qmlUnit->header), &vec, sizeof(vec))) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: 3D vector expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::Vector4D: {
+ struct {
+ float xp;
+ float yp;
+ float zy;
+ float wp;
+ } vec;
+ if (!QQmlStringConverters::createFromString(QMetaType::QVector4D, binding->valueAsString(&qmlUnit->header), &vec, sizeof(vec))) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: 4D vector expected"));
+ return false;
+ }
+ }
+ break;
+ case QVariant::RegExp:
+ recordError(binding->valueLocation, tr("Invalid property assignment: regular expression expected; use /pattern/ syntax"));
+ return false;
+ default: {
+ // generate single literal value assignment to a list property if required
+ if (property->propType == qMetaTypeId<QList<qreal> >()) {
+ if (binding->type != QV4::CompiledData::Binding::Type_Number) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: real or array of reals expected"));
+ return false;
+ }
+ break;
+ } else if (property->propType == qMetaTypeId<QList<int> >()) {
+ bool ok = (binding->type == QV4::CompiledData::Binding::Type_Number);
+ if (ok) {
+ double n = binding->valueAsNumber();
+ if (double(int(n)) != n)
+ ok = false;
+ }
+ if (!ok)
+ recordError(binding->valueLocation, tr("Invalid property assignment: int or array of ints expected"));
+ break;
+ } else if (property->propType == qMetaTypeId<QList<bool> >()) {
+ if (binding->type != QV4::CompiledData::Binding::Type_Boolean) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: bool or array of bools expected"));
+ return false;
+ }
+ break;
+ } else if (property->propType == qMetaTypeId<QList<QUrl> >()) {
+ if (binding->type != QV4::CompiledData::Binding::Type_String) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: url or array of urls expected"));
+ return false;
+ }
+ break;
+ } else if (property->propType == qMetaTypeId<QList<QString> >()) {
+ if (binding->type != QV4::CompiledData::Binding::Type_String) {
+ recordError(binding->valueLocation, tr("Invalid property assignment: string or array of strings expected"));
+ return false;
+ }
+ break;
+ } else if (property->propType == qMetaTypeId<QJSValue>()) {
+ break;
+ } else if (property->propType == qMetaTypeId<QQmlScriptString>()) {
+ break;
+ }
+
+ // otherwise, try a custom type assignment
+ QQmlMetaType::StringConverter converter = QQmlMetaType::customStringConverter(property->propType);
+ if (!converter) {
+ recordError(binding->location, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QMetaType::typeName(property->propType))));
+ return false;
+ }
+ }
+ break;
+ }
+ return true;
+}
+
+bool QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding)
+{
+ if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) {
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Object);
+
+ bool isValueSource = false;
+ bool isPropertyInterceptor = false;
+
+ QQmlType *qmlType = 0;
+ const QV4::CompiledData::Object *targetObject = qmlUnit->objectAt(binding->value.objectIndex);
+ QQmlCompiledData::TypeReference *typeRef = resolvedTypes.value(targetObject->inheritedTypeNameIndex);
+ if (typeRef) {
+ QQmlPropertyCache *cache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
+ const QMetaObject *mo = cache->firstCppMetaObject();
+ while (mo && !qmlType) {
+ qmlType = QQmlMetaType::qmlType(mo);
+ mo = mo->superClass();
+ }
+ Q_ASSERT(qmlType);
+ }
+
+ if (qmlType) {
+ isValueSource = qmlType->propertyValueSourceCast() != -1;
+ isPropertyInterceptor = qmlType->propertyValueInterceptorCast() != -1;
+ }
+
+ if (!isValueSource && !isPropertyInterceptor) {
+ recordError(binding->valueLocation, tr("\"%1\" cannot operate on \"%2\"").arg(stringAt(targetObject->inheritedTypeNameIndex)).arg(propertyName));
+ return false;
+ }
+
+ return true;
+ }
+ if (isComponent(binding->value.objectIndex))
+ return true;
+
+ if (QQmlMetaType::isInterface(property->propType)) {
+ // Can only check at instantiation time if the created sub-object successfully casts to the
+ // target interface.
+ return true;
+ } else if (property->propType == QMetaType::QVariant) {
+ // We can convert everything to QVariant :)
+ return true;
+ } else if (property->isQList()) {
+ // ### TODO: list error handling
+ return true;
+ } else if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject && property->isFunction()) {
+ return true;
+ } else if (QQmlValueTypeFactory::isValueType(property->propType)) {
+ recordError(binding->location, tr("Unexpected object assignment"));
+ return false;
+ } else {
+ // We want to raw metaObject here as the raw metaobject is the
+ // actual property type before we applied any extensions that might
+ // effect the properties on the type, but don't effect assignability
+ QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(property->propType);
+
+ // Will be true if the assgned type inherits propertyMetaObject
+ bool isAssignable = false;
+ // Determine isAssignable value
+ if (propertyMetaObject) {
+ QQmlPropertyCache *c = propertyCaches.value(binding->value.objectIndex);
+ while (c && !isAssignable) {
+ isAssignable |= c == propertyMetaObject;
+ c = c->parent();
+ }
+ }
+
+ if (!isAssignable) {
+ recordError(binding->valueLocation, tr("Cannot assign object to property"));
+ return false;
+ }
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
new file mode 100644
index 0000000000..2e97d13481
--- /dev/null
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** 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 QQMLTYPECOMPILER_P_H
+#define QQMLTYPECOMPILER_P_H
+
+#include <qglobal.h>
+#include <qqmlerror.h>
+#include <qhash.h>
+#include <private/qqmlcompiler_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlEnginePrivate;
+class QQmlCompiledData;
+class QQmlError;
+class QQmlTypeData;
+class QQmlImports;
+
+namespace QtQml {
+struct ParsedQML;
+}
+
+namespace QV4 {
+namespace CompiledData {
+struct QmlUnit;
+struct Location;
+}
+}
+
+struct QQmlTypeCompiler
+{
+ Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
+public:
+ QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlCompiledData *compiledData, QQmlTypeData *typeData, QtQml::ParsedQML *parsedQML);
+
+ bool compile();
+
+ QList<QQmlError> compilationErrors() const { return errors; }
+ void recordError(const QQmlError &error);
+
+ QString stringAt(int idx) const;
+ int registerString(const QString &str);
+
+ const QV4::CompiledData::QmlUnit *qmlUnit() const;
+
+ QQmlEnginePrivate *enginePrivate() const { return engine; }
+ const QQmlImports *imports() const;
+ QHash<int, QQmlCompiledData::TypeReference *> *resolvedTypes();
+ QList<QtQml::QmlObject*> *qmlObjects();
+ int rootObjectIndex() const;
+ void setPropertyCaches(const QVector<QQmlPropertyCache *> &caches);
+ const QVector<QQmlPropertyCache *> &propertyCaches() const;
+ void setVMEMetaObjects(const QVector<QByteArray> &metaObjects);
+ QVector<QByteArray> *vmeMetaObjects() const;
+ QHash<int, int> *objectIndexToIdForRoot();
+ QHash<int, QHash<int, int> > *objectIndexToIdPerComponent();
+ QHash<int, QByteArray> *customParserData();
+ QQmlJS::MemoryPool *memoryPool();
+ const QList<CompiledFunctionOrExpression> &functions() const;
+ void setCustomParserBindings(const QVector<int> &bindings);
+
+private:
+ QList<QQmlError> errors;
+ QQmlEnginePrivate *engine;
+ QQmlCompiledData *compiledData;
+ QQmlTypeData *typeData;
+ QtQml::ParsedQML *parsedQML;
+};
+
+struct QQmlCompilePass
+{
+ virtual ~QQmlCompilePass() {}
+
+ QQmlCompilePass(QQmlTypeCompiler *typeCompiler);
+
+ QString stringAt(int idx) const { return compiler->stringAt(idx); }
+protected:
+ void recordError(const QV4::CompiledData::Location &location, const QString &description);
+
+ QQmlTypeCompiler *compiler;
+};
+
+class QQmlPropertyCacheCreator : public QQmlCompilePass
+{
+ Q_DECLARE_TR_FUNCTIONS(QQmlPropertyCacheCreator)
+public:
+ QQmlPropertyCacheCreator(QQmlTypeCompiler *typeCompiler);
+ ~QQmlPropertyCacheCreator();
+
+ bool buildMetaObjects();
+protected:
+ bool buildMetaObjectRecursively(int objectIndex, int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding);
+ bool ensureMetaObject(int objectIndex);
+ bool createMetaObject(int objectIndex, const QtQml::QmlObject *obj, QQmlPropertyCache *baseTypeCache);
+
+ QQmlEnginePrivate *enginePrivate;
+ const QList<QtQml::QmlObject*> &qmlObjects;
+ const QQmlImports *imports;
+ QHash<int, QQmlCompiledData::TypeReference*> *resolvedTypes;
+ QVector<QByteArray> vmeMetaObjects;
+ QVector<QQmlPropertyCache*> propertyCaches;
+};
+
+// ### This will go away when the codegen resolves all enums to constant expressions
+// and we replace the constant expression with a literal binding instead of using
+// a script.
+class QQmlEnumTypeResolver : public QQmlCompilePass
+{
+ Q_DECLARE_TR_FUNCTIONS(QQmlEnumTypeResolver)
+public:
+ QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler);
+
+ bool resolveEnumBindings();
+
+private:
+ bool tryQualifiedEnumAssignment(const QmlObject *obj, const QQmlPropertyCache *propertyCache,
+ const QQmlPropertyData *prop,
+ QtQml::Binding *binding);
+ int evaluateEnum(const QString &scope, const QByteArray &enumValue, bool *ok) const;
+
+
+ const QList<QtQml::QmlObject*> &qmlObjects;
+ const QVector<QQmlPropertyCache *> propertyCaches;
+ const QQmlImports *imports;
+ QHash<int, QQmlCompiledData::TypeReference *> *resolvedTypes;
+};
+
+// Annotate properties bound to aliases with a flag
+class QQmlAliasAnnotator : public QQmlCompilePass
+{
+public:
+ QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler);
+
+ void annotateBindingsToAliases();
+private:
+ const QList<QtQml::QmlObject*> &qmlObjects;
+ const QVector<QQmlPropertyCache *> propertyCaches;
+};
+
+class QQmlComponentAndAliasResolver : public QQmlCompilePass
+{
+ Q_DECLARE_TR_FUNCTIONS(QQmlAnonymousComponentResolver)
+public:
+ QQmlComponentAndAliasResolver(QQmlTypeCompiler *typeCompiler);
+
+ bool resolve();
+
+protected:
+ void findAndRegisterImplicitComponents(const QtQml::QmlObject *obj, int objectIndex);
+ bool collectIdsAndAliases(int objectIndex);
+ bool resolveAliases();
+
+ QQmlEnginePrivate *enginePrivate;
+ QQmlJS::MemoryPool *pool;
+
+ QList<QtQml::QmlObject*> *qmlObjects;
+ const int indexOfRootObject;
+
+ // indices of the objects that are actually Component {}
+ QVector<int> componentRoots;
+ // indices of objects that are the beginning of a new component
+ // scope. This is sorted and used for binary search.
+ QVector<int> componentBoundaries;
+
+ int _componentIndex;
+ QHash<int, int> _idToObjectIndex;
+ QHash<int, int> *_objectIndexToIdInScope;
+ QList<int> _objectsWithAliases;
+
+ QHash<int, QQmlCompiledData::TypeReference*> *resolvedTypes;
+ const QVector<QQmlPropertyCache *> propertyCaches;
+ QVector<QByteArray> *vmeMetaObjectData;
+ QHash<int, int> *objectIndexToIdForRoot;
+ QHash<int, QHash<int, int> > *objectIndexToIdPerComponent;
+};
+
+class QQmlPropertyValidator : public QQmlCompilePass, public QQmlCustomParserCompilerBackend
+{
+ Q_DECLARE_TR_FUNCTIONS(QQmlPropertyValidator)
+public:
+ QQmlPropertyValidator(QQmlTypeCompiler *typeCompiler, const QVector<int> &runtimeFunctionIndices);
+
+ bool validate();
+
+ // Re-implemented for QQmlCustomParser
+ virtual const QQmlImports &imports() const;
+ virtual QQmlJS::AST::Node *astForBinding(int scriptIndex) const;
+ virtual QQmlBinding::Identifier bindingIdentifier(const QV4::CompiledData::Binding *binding, QQmlCustomParser *parser);
+
+private:
+ bool validateObject(int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding);
+ bool validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
+ bool validateObjectBinding(QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding);
+
+ bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); }
+
+ QQmlEnginePrivate *enginePrivate;
+ const QV4::CompiledData::QmlUnit *qmlUnit;
+ const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes;
+ const QVector<QQmlPropertyCache *> &propertyCaches;
+ const QHash<int, QHash<int, int> > objectIndexToIdPerComponent;
+ QHash<int, QByteArray> *customParserData;
+ QVector<int> customParserBindings;
+ const QVector<int> &runtimeFunctionIndices;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLTYPECOMPILER_P_H
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index ce0c7abf9e..aa8db06fd5 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -67,15 +67,15 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
assert(!runtimeStrings);
assert(data);
- runtimeStrings = (QV4::SafeString *)malloc(data->stringTableSize * sizeof(QV4::SafeString));
+ runtimeStrings = (QV4::StringValue *)malloc(data->stringTableSize * sizeof(QV4::StringValue));
// memset the strings to 0 in case a GC run happens while we're within the loop below
- memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::SafeString));
+ memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::StringValue));
for (uint i = 0; i < data->stringTableSize; ++i)
runtimeStrings[i] = engine->newIdentifier(data->stringAt(i));
- runtimeRegularExpressions = new QV4::SafeValue[data->regexpTableSize];
+ runtimeRegularExpressions = new QV4::Value[data->regexpTableSize];
// memset the regexps to 0 in case a GC run happens while we're within the loop below
- memset(runtimeRegularExpressions, 0, data->regexpTableSize * sizeof(QV4::SafeValue));
+ memset(runtimeRegularExpressions, 0, data->regexpTableSize * sizeof(QV4::Value));
for (uint i = 0; i < data->regexpTableSize; ++i) {
const CompiledData::RegExp *re = data->regexpAt(i);
int flags = 0;
@@ -95,18 +95,25 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
for (uint i = 0; i < data->lookupTableSize; ++i) {
QV4::Lookup *l = runtimeLookups + i;
- if (compiledLookups[i].type_and_flags == CompiledData::Lookup::Type_Getter)
+ Lookup::Type type = Lookup::Type(compiledLookups[i].type_and_flags);
+ if (type == CompiledData::Lookup::Type_Getter)
l->getter = QV4::Lookup::getterGeneric;
- else if (compiledLookups[i].type_and_flags == CompiledData::Lookup::Type_Setter)
+ else if (type == CompiledData::Lookup::Type_Setter)
l->setter = QV4::Lookup::setterGeneric;
- else if (compiledLookups[i].type_and_flags == CompiledData::Lookup::Type_GlobalGetter)
+ else if (type == CompiledData::Lookup::Type_GlobalGetter)
l->globalGetter = QV4::Lookup::globalGetterGeneric;
+ else if (type == CompiledData::Lookup::Type_IndexedGetter)
+ l->indexedGetter = QV4::Lookup::indexedGetterGeneric;
+ else if (type == CompiledData::Lookup::Type_IndexedSetter)
+ l->indexedSetter = QV4::Lookup::indexedSetterGeneric;
for (int j = 0; j < QV4::Lookup::Size; ++j)
l->classList[j] = 0;
l->level = -1;
l->index = UINT_MAX;
l->name = runtimeStrings[compiledLookups[i].nameIndex].asString();
+ if (type == CompiledData::Lookup::Type_IndexedGetter || type == CompiledData::Lookup::Type_IndexedSetter)
+ l->engine = engine;
}
}
@@ -193,6 +200,57 @@ QString Binding::valueAsString(const Unit *unit) const
return QString();
}
+//reverse of Lexer::singleEscape()
+static QString escapedString(const QString &string)
+{
+ QString tmp = QLatin1String("\"");
+ for (int i = 0; i < string.length(); ++i) {
+ const QChar &c = string.at(i);
+ switch (c.unicode()) {
+ case 0x08:
+ tmp += QLatin1String("\\b");
+ break;
+ case 0x09:
+ tmp += QLatin1String("\\t");
+ break;
+ case 0x0A:
+ tmp += QLatin1String("\\n");
+ break;
+ case 0x0B:
+ tmp += QLatin1String("\\v");
+ break;
+ case 0x0C:
+ tmp += QLatin1String("\\f");
+ break;
+ case 0x0D:
+ tmp += QLatin1String("\\r");
+ break;
+ case 0x22:
+ tmp += QLatin1String("\\\"");
+ break;
+ case 0x27:
+ tmp += QLatin1String("\\\'");
+ break;
+ case 0x5C:
+ tmp += QLatin1String("\\\\");
+ break;
+ default:
+ tmp += c;
+ break;
+ }
+ }
+ tmp += QLatin1Char('\"');
+ return tmp;
+}
+
+QString Binding::valueAsScriptString(const Unit *unit) const
+{
+ if (type == Type_String)
+ return escapedString(unit->stringAt(stringIndex));
+ else
+ return valueAsString(unit);
+}
+
}
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 90f27d5f57..94ea4bdc90 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -45,7 +45,7 @@
#include <QVector>
#include <QStringList>
#include <QHash>
-#include <private/qv4value_def_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4executableallocator_p.h>
QT_BEGIN_NAMESPACE
@@ -70,17 +70,32 @@ struct RegExp;
struct Location
{
- int line;
- int column;
+ qint32 line;
+ qint32 column;
+ inline bool operator<(const Location &other) const {
+ return line < other.line ||
+ (line == other.line && column < other.column);
+ }
+};
+
+struct TypeReference
+{
+ TypeReference(const Location &loc)
+ : location(loc)
+ , needsCreation(false)
+ {}
+ Location location; // first use
+ bool needsCreation; // whether the type needs to be creatable or not
};
// map from name index to location of first use
-struct TypeReferenceMap : QHash<int, Location>
+struct TypeReferenceMap : QHash<int, TypeReference>
{
- void add(int nameIndex, const Location &loc) {
- if (contains(nameIndex))
- return;
- insert(nameIndex, loc);
+ TypeReference &add(int nameIndex, const Location &loc) {
+ Iterator it = find(nameIndex);
+ if (it != end())
+ return *it;
+ return *insert(nameIndex, loc);
}
};
@@ -102,7 +117,9 @@ struct Lookup
enum Type {
Type_Getter = 0x0,
Type_Setter = 0x1,
- Type_GlobalGetter = 2
+ Type_GlobalGetter = 2,
+ Type_IndexedGetter = 3,
+ Type_IndexedSetter = 4
};
quint32 type_and_flags;
@@ -188,8 +205,8 @@ struct Unit
const RegExp *regexpAt(int index) const {
return reinterpret_cast<const RegExp*>(reinterpret_cast<const char *>(this) + offsetToRegexpTable + index * sizeof(RegExp));
}
- const QV4::SafeValue *constants() const {
- return reinterpret_cast<const QV4::SafeValue*>(reinterpret_cast<const char *>(this) + offsetToConstantTable);
+ const QV4::Value *constants() const {
+ return reinterpret_cast<const QV4::Value*>(reinterpret_cast<const char *>(this) + offsetToConstantTable);
}
const JSClassMember *jsClassAt(int idx, int *nMembers) const {
@@ -264,7 +281,7 @@ struct Function
// Qml data structures
-struct Binding
+struct Q_QML_EXPORT Binding
{
quint32 propertyNameIndex;
@@ -280,7 +297,13 @@ struct Binding
};
enum Flags {
- IsSignalHandlerExpression = 0x1
+ IsSignalHandlerExpression = 0x1,
+ IsSignalHandlerObject = 0x2,
+ IsOnAssignment = 0x4,
+ InitializerForReadOnlyDeclaration = 0x8,
+ IsResolvedEnum = 0x10,
+ IsListItem = 0x20,
+ IsBindingToAlias = 0x40
};
quint32 flags : 16;
@@ -294,8 +317,57 @@ struct Binding
quint32 stringIndex; // Set for Type_String and Type_Script (the latter because of script strings)
Location location;
+ Location valueLocation;
+
+ bool isValueBinding() const
+ {
+ if (type == Type_AttachedProperty
+ || type == Type_GroupProperty)
+ return false;
+ if (flags & IsSignalHandlerExpression
+ || flags & IsSignalHandlerObject)
+ return false;
+ return true;
+ }
+
+ bool isValueBindingNoAlias() const { return isValueBinding() && !(flags & IsBindingToAlias); }
+ bool isValueBindingToAlias() const { return isValueBinding() && (flags & IsBindingToAlias); }
+
+ bool isSignalHandler() const
+ {
+ if (flags & IsSignalHandlerExpression || flags & IsSignalHandlerObject) {
+ Q_ASSERT(!isValueBinding());
+ Q_ASSERT(!isAttachedProperty());
+ Q_ASSERT(!isGroupProperty());
+ return true;
+ }
+ return false;
+ }
+
+ bool isAttachedProperty() const
+ {
+ if (type == Type_AttachedProperty) {
+ Q_ASSERT(!isValueBinding());
+ Q_ASSERT(!isSignalHandler());
+ Q_ASSERT(!isGroupProperty());
+ return true;
+ }
+ return false;
+ }
+
+ bool isGroupProperty() const
+ {
+ if (type == Type_GroupProperty) {
+ Q_ASSERT(!isValueBinding());
+ Q_ASSERT(!isSignalHandler());
+ Q_ASSERT(!isAttachedProperty());
+ return true;
+ }
+ return false;
+ }
QString valueAsString(const Unit *unit) const;
+ QString valueAsScriptString(const Unit *unit) const;
double valueAsNumber() const
{
if (type == Type_Number)
@@ -369,7 +441,7 @@ struct Object
// it will be the name of the attached type.
quint32 inheritedTypeNameIndex;
quint32 idIndex;
- quint32 indexOfDefaultProperty;
+ qint32 indexOfDefaultProperty; // -1 means no default property declared in this object
quint32 nFunctions;
quint32 offsetToFunctions;
quint32 nProperties;
@@ -491,9 +563,9 @@ struct Q_QML_EXPORT CompilationUnit
QString fileName() const { return data->stringAt(data->sourceFileIndex); }
- QV4::SafeString *runtimeStrings; // Array
+ QV4::StringValue *runtimeStrings; // Array
QV4::Lookup *runtimeLookups;
- QV4::SafeValue *runtimeRegularExpressions;
+ QV4::Value *runtimeRegularExpressions;
QV4::InternalClass **runtimeClasses;
QVector<QV4::Function *> runtimeFunctions;
// QVector<QV4::Function *> runtimeFunctionsSortedByAddress;
@@ -516,6 +588,8 @@ protected:
}
+Q_DECLARE_TYPEINFO(QV4::CompiledData::JSClassMember, Q_PRIMITIVE_TYPE);
+
QT_END_NAMESPACE
#endif
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 9041b04837..bc47b815f2 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -53,6 +53,8 @@ QV4::Compiler::JSUnitGenerator::JSUnitGenerator(QQmlJS::V4IR::Module *module, in
if (headerSize == -1)
headerSize = sizeof(QV4::CompiledData::Unit);
this->headerSize = headerSize;
+ // Make sure the empty string always gets index 0
+ registerString(QString());
}
int QV4::Compiler::JSUnitGenerator::registerString(const QString &str)
@@ -72,6 +74,24 @@ int QV4::Compiler::JSUnitGenerator::getStringId(const QString &string) const
return stringToId.value(string);
}
+uint QV4::Compiler::JSUnitGenerator::registerIndexedGetterLookup()
+{
+ CompiledData::Lookup l;
+ l.type_and_flags = CompiledData::Lookup::Type_IndexedGetter;
+ l.nameIndex = 0;
+ lookups << l;
+ return lookups.size() - 1;
+}
+
+uint QV4::Compiler::JSUnitGenerator::registerIndexedSetterLookup()
+{
+ CompiledData::Lookup l;
+ l.type_and_flags = CompiledData::Lookup::Type_IndexedSetter;
+ l.nameIndex = 0;
+ lookups << l;
+ return lookups.size() - 1;
+}
+
uint QV4::Compiler::JSUnitGenerator::registerGetterLookup(const QString &name)
{
CompiledData::Lookup l;
@@ -81,6 +101,7 @@ uint QV4::Compiler::JSUnitGenerator::registerGetterLookup(const QString &name)
return lookups.size() - 1;
}
+
uint QV4::Compiler::JSUnitGenerator::registerSetterLookup(const QString &name)
{
CompiledData::Lookup l;
diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h
index 1596fcb622..6baefae7b7 100644
--- a/src/qml/compiler/qv4compiler_p.h
+++ b/src/qml/compiler/qv4compiler_p.h
@@ -70,6 +70,8 @@ struct Q_QML_EXPORT JSUnitGenerator {
uint registerGetterLookup(const QString &name);
uint registerSetterLookup(const QString &name);
uint registerGlobalGetterLookup(const QString &name);
+ uint registerIndexedGetterLookup();
+ uint registerIndexedSetterLookup();
int registerRegExp(QQmlJS::V4IR::RegExp *regexp);
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 5b5667abb4..e3e227796e 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -43,7 +43,7 @@
#define QV4INSTR_MOTH_P_H
#include <QtCore/qglobal.h>
-#include <private/qv4value_def_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4function_p.h>
#include <private/qv4runtime_p.h>
@@ -51,16 +51,20 @@ QT_BEGIN_NAMESPACE
#define FOR_EACH_MOTH_INSTR(F) \
F(Ret, ret) \
+ F(Debug, debug) \
F(LoadRuntimeString, loadRuntimeString) \
F(LoadRegExp, loadRegExp) \
F(LoadClosure, loadClosure) \
F(Move, move) \
+ F(MoveConst, moveConst) \
F(SwapTemps, swapTemps) \
F(LoadName, loadName) \
F(GetGlobalLookup, getGlobalLookup) \
F(StoreName, storeName) \
F(LoadElement, loadElement) \
+ F(LoadElementLookup, loadElementLookup) \
F(StoreElement, storeElement) \
+ F(StoreElementLookup, storeElementLookup) \
F(LoadProperty, loadProperty) \
F(GetLookup, getLookup) \
F(StoreProperty, storeProperty) \
@@ -103,7 +107,8 @@ QT_BEGIN_NAMESPACE
F(CreateActivationProperty, createActivationProperty) \
F(ConstructGlobalLookup, constructGlobalLookup) \
F(Jump, jump) \
- F(CJump, cjump) \
+ F(JumpEq, jumpEq) \
+ F(JumpNe, jumpNe) \
F(UNot, unot) \
F(UNotBool, unotBool) \
F(UPlus, uplus) \
@@ -117,15 +122,16 @@ QT_BEGIN_NAMESPACE
F(BitAnd, bitAnd) \
F(BitOr, bitOr) \
F(BitXor, bitXor) \
+ F(Shr, shr) \
+ F(Shl, shl) \
F(BitAndConst, bitAndConst) \
F(BitOrConst, bitOrConst) \
F(BitXorConst, bitXorConst) \
+ F(ShrConst, shrConst) \
+ F(ShlConst, shlConst) \
F(Mul, mul) \
F(Sub, sub) \
F(BinopContext, binopContext) \
- F(AddNumberParams, addNumberParams) \
- F(MulNumberParams, mulNumberParams) \
- F(SubNumberParams, subNumberParams) \
F(LoadThis, loadThis) \
F(LoadQmlIdArray, loadQmlIdArray) \
F(LoadQmlImportedScripts, loadQmlImportedScripts) \
@@ -140,11 +146,9 @@ QT_BEGIN_NAMESPACE
#define MOTH_INSTR_ALIGN_MASK (Q_ALIGNOF(QQmlJS::Moth::Instr) - 1)
#ifdef MOTH_THREADED_INTERPRETER
-# define MOTH_INSTR_HEADER void *code; \
- unsigned int breakPoint : 1;
+# define MOTH_INSTR_HEADER void *code;
#else
-# define MOTH_INSTR_HEADER quint8 instructionType; \
- unsigned int breakPoint : 1;
+# define MOTH_INSTR_HEADER quint32 instructionType;
#endif
#define MOTH_INSTR_ENUM(I, FMT) I,
@@ -231,7 +235,11 @@ union Instr
struct instr_ret {
MOTH_INSTR_HEADER
Param result;
- };
+ };
+ struct instr_debug {
+ MOTH_INSTR_HEADER
+ quint32 breakPoint;
+ };
struct instr_loadRuntimeString {
MOTH_INSTR_HEADER
int stringId;
@@ -247,6 +255,11 @@ union Instr
Param source;
Param result;
};
+ struct instr_moveConst {
+ MOTH_INSTR_HEADER
+ QV4::ReturnedValue source;
+ Param result;
+ };
struct instr_swapTemps {
MOTH_INSTR_HEADER
Param left;
@@ -322,12 +335,26 @@ union Instr
Param index;
Param result;
};
+ struct instr_loadElementLookup {
+ MOTH_INSTR_HEADER
+ uint lookup;
+ Param base;
+ Param index;
+ Param result;
+ };
struct instr_storeElement {
MOTH_INSTR_HEADER
Param base;
Param index;
Param source;
};
+ struct instr_storeElementLookup {
+ MOTH_INSTR_HEADER
+ uint lookup;
+ Param base;
+ Param index;
+ Param source;
+ };
struct instr_push {
MOTH_INSTR_HEADER
quint32 value;
@@ -525,13 +552,17 @@ union Instr
};
struct instr_jump {
MOTH_INSTR_HEADER
- ptrdiff_t offset;
+ ptrdiff_t offset;
+ };
+ struct instr_jumpEq {
+ MOTH_INSTR_HEADER
+ ptrdiff_t offset;
+ Param condition;
};
- struct instr_cjump {
+ struct instr_jumpNe {
MOTH_INSTR_HEADER
ptrdiff_t offset;
Param condition;
- bool invert;
};
struct instr_unot {
MOTH_INSTR_HEADER
@@ -604,57 +635,63 @@ union Instr
Param rhs;
Param result;
};
- struct instr_bitAndConst {
+ struct instr_shr {
MOTH_INSTR_HEADER
Param lhs;
- int rhs;
+ Param rhs;
Param result;
};
- struct instr_bitOrConst {
+ struct instr_shl {
+ MOTH_INSTR_HEADER
+ Param lhs;
+ Param rhs;
+ Param result;
+ };
+ struct instr_bitAndConst {
MOTH_INSTR_HEADER
Param lhs;
int rhs;
Param result;
};
- struct instr_bitXorConst {
+ struct instr_bitOrConst {
MOTH_INSTR_HEADER
Param lhs;
int rhs;
Param result;
};
- struct instr_mul {
+ struct instr_bitXorConst {
MOTH_INSTR_HEADER
Param lhs;
- Param rhs;
+ int rhs;
Param result;
};
- struct instr_sub {
+ struct instr_shrConst {
MOTH_INSTR_HEADER
Param lhs;
- Param rhs;
+ int rhs;
Param result;
};
- struct instr_binopContext {
+ struct instr_shlConst {
MOTH_INSTR_HEADER
- QV4::BinOpContext alu;
Param lhs;
- Param rhs;
+ int rhs;
Param result;
};
- struct instr_addNumberParams {
+ struct instr_mul {
MOTH_INSTR_HEADER
Param lhs;
Param rhs;
Param result;
};
- struct instr_mulNumberParams {
+ struct instr_sub {
MOTH_INSTR_HEADER
Param lhs;
Param rhs;
Param result;
};
- struct instr_subNumberParams {
+ struct instr_binopContext {
MOTH_INSTR_HEADER
+ QV4::BinOpContext alu;
Param lhs;
Param rhs;
Param result;
@@ -687,16 +724,20 @@ union Instr
instr_common common;
instr_ret ret;
+ instr_debug debug;
instr_loadRuntimeString loadRuntimeString;
instr_loadRegExp loadRegExp;
instr_move move;
+ instr_moveConst moveConst;
instr_swapTemps swapTemps;
instr_loadClosure loadClosure;
instr_loadName loadName;
instr_getGlobalLookup getGlobalLookup;
instr_storeName storeName;
instr_loadElement loadElement;
+ instr_loadElementLookup loadElementLookup;
instr_storeElement storeElement;
+ instr_storeElementLookup storeElementLookup;
instr_loadProperty loadProperty;
instr_getLookup getLookup;
instr_loadQObjectProperty loadQObjectProperty;
@@ -739,7 +780,8 @@ union Instr
instr_createActivationProperty createActivationProperty;
instr_constructGlobalLookup constructGlobalLookup;
instr_jump jump;
- instr_cjump cjump;
+ instr_jumpEq jumpEq;
+ instr_jumpNe jumpNe;
instr_unot unot;
instr_unotBool unotBool;
instr_uplus uplus;
@@ -753,15 +795,16 @@ union Instr
instr_bitAnd bitAnd;
instr_bitOr bitOr;
instr_bitXor bitXor;
+ instr_shr shr;
+ instr_shl shl;
instr_bitAndConst bitAndConst;
instr_bitOrConst bitOrConst;
instr_bitXorConst bitXorConst;
+ instr_shrConst shrConst;
+ instr_shlConst shlConst;
instr_mul mul;
instr_sub sub;
instr_binopContext binopContext;
- instr_addNumberParams addNumberParams;
- instr_mulNumberParams mulNumberParams;
- instr_subNumberParams subNumberParams;
instr_loadThis loadThis;
instr_loadQmlIdArray loadQmlIdArray;
instr_loadQmlImportedScripts loadQmlImportedScripts;
@@ -782,7 +825,7 @@ struct InstrMeta {
typedef Instr::instr_##FMT DataType; \
static const DataType &data(const Instr &instr) { return instr.FMT; } \
static void setData(Instr &instr, const DataType &v) { instr.FMT = v; } \
- };
+ };
FOR_EACH_MOTH_INSTR(MOTH_INSTR_META_TEMPLATE);
#undef MOTH_INSTR_META_TEMPLATE
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 0fcd770584..c89b108309 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -245,12 +245,12 @@ Assembler::Pointer Assembler::loadTempAddress(RegisterID baseReg, V4IR::Temp *t)
case V4IR::Temp::Formal:
case V4IR::Temp::ScopedFormal: {
loadPtr(Address(context, qOffsetOf(ExecutionContext, callData)), baseReg);
- offset = sizeof(CallData) + (t->index - 1) * sizeof(SafeValue);
+ offset = sizeof(CallData) + (t->index - 1) * sizeof(Value);
} break;
case V4IR::Temp::Local:
case V4IR::Temp::ScopedLocal: {
loadPtr(Address(context, qOffsetOf(CallContext, locals)), baseReg);
- offset = t->index * sizeof(SafeValue);
+ offset = t->index * sizeof(Value);
} break;
case V4IR::Temp::StackSlot: {
return stackSlotPointer(t);
@@ -266,7 +266,7 @@ Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &s
loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext, compilationUnit)), Assembler::ScratchRegister);
loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg);
const int id = _isel->registerString(string);
- return Pointer(reg, id * sizeof(QV4::SafeString));
+ return Pointer(reg, id * sizeof(QV4::StringValue));
}
void Assembler::loadStringRef(RegisterID reg, const QString &string)
@@ -274,7 +274,7 @@ void Assembler::loadStringRef(RegisterID reg, const QString &string)
loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext, compilationUnit)), reg);
loadPtr(Address(reg, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg);
const int id = _isel->registerString(string);
- addPtr(TrustedImmPtr(id * sizeof(QV4::SafeString)), reg);
+ addPtr(TrustedImmPtr(id * sizeof(QV4::StringValue)), reg);
}
template <typename Result, typename Source>
@@ -615,7 +615,7 @@ void InstructionSelection::run(int functionIndex)
const int locals = _as->stackLayout().calculateJSStackFrameSize();
_as->loadPtr(Address(Assembler::ContextRegister, qOffsetOf(ExecutionContext, engine)), Assembler::ScratchRegister);
_as->loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop)), Assembler::LocalsRegister);
- _as->addPtr(Assembler::TrustedImm32(sizeof(QV4::SafeValue)*locals), Assembler::LocalsRegister);
+ _as->addPtr(Assembler::TrustedImm32(sizeof(QV4::Value)*locals), Assembler::LocalsRegister);
_as->storePtr(Assembler::LocalsRegister, Address(Assembler::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop)));
int lastLine = -1;
@@ -1015,99 +1015,13 @@ void InstructionSelection::setQObjectProperty(V4IR::Expr *source, V4IR::Expr *ta
void InstructionSelection::getElement(V4IR::Expr *base, V4IR::Expr *index, V4IR::Temp *target)
{
-#if QT_POINTER_SIZE == 8
- V4IR::Temp *tbase = base->asTemp();
- V4IR::Temp *tindex = index->asTemp();
- if (tbase && tindex &&
- tbase->kind != V4IR::Temp::PhysicalRegister) {
- Assembler::Pointer addr = _as->loadTempAddress(Assembler::ReturnValueRegister, tbase);
- _as->load64(addr, Assembler::ScratchRegister);
- _as->move(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
- _as->urshift64(Assembler::TrustedImm32(QV4::Value::IsManaged_Shift), Assembler::ReturnValueRegister);
- Assembler::Jump notManaged = _as->branch64(Assembler::NotEqual, Assembler::ReturnValueRegister, Assembler::TrustedImm64(0));
- // check whether we have an object with a simple array
- Assembler::Address managedType(Assembler::ScratchRegister, qOffsetOf(QV4::Managed, flags));
- _as->load8(managedType, Assembler::ReturnValueRegister);
- _as->and32(Assembler::TrustedImm32(QV4::Managed::SimpleArray), Assembler::ReturnValueRegister);
- Assembler::Jump notSimple = _as->branch32(Assembler::Equal, Assembler::ReturnValueRegister, Assembler::TrustedImm32(0));
-
- bool needNegativeCheck = false;
- Assembler::Jump fallback, fallback2;
- if (tindex->kind == V4IR::Temp::PhysicalRegister) {
- if (tindex->type == V4IR::SInt32Type) {
- fallback = _as->branch32(Assembler::LessThan, (Assembler::RegisterID)tindex->index, Assembler::TrustedImm32(0));
- _as->move((Assembler::RegisterID) tindex->index, Assembler::ScratchRegister);
- needNegativeCheck = true;
- } else {
- // double, convert and check if it's a int
- fallback2 = _as->branchTruncateDoubleToUint32((Assembler::FPRegisterID) tindex->index, Assembler::ScratchRegister);
- _as->convertInt32ToDouble(Assembler::ScratchRegister, Assembler::FPGpr0);
- fallback = _as->branchDouble(Assembler::DoubleNotEqual, Assembler::FPGpr0, (Assembler::FPRegisterID) tindex->index);
- }
- } else {
- Assembler::Pointer indexAddr = _as->loadTempAddress(Assembler::ReturnValueRegister, tindex);
- _as->load64(indexAddr, Assembler::ScratchRegister);
- _as->move(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
- _as->urshift64(Assembler::TrustedImm32(QV4::Value::IsNumber_Shift), Assembler::ReturnValueRegister);
- Assembler::Jump isInteger = _as->branch64(Assembler::Equal, Assembler::ReturnValueRegister, Assembler::TrustedImm64(1));
-
- // other type, convert to double and check if it's a int
- // this check is ok to do even if the type is something else than a double, as
- // that would result in a NaN
- _as->move(Assembler::TrustedImm64(QV4::Value::NaNEncodeMask), Assembler::ReturnValueRegister);
- _as->xor64(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
- _as->move64ToDouble(Assembler::ReturnValueRegister, Assembler::FPGpr0);
- fallback2 = _as->branchTruncateDoubleToUint32(Assembler::FPGpr0, Assembler::ScratchRegister);
- _as->convertInt32ToDouble(Assembler::ScratchRegister, Assembler::FPGpr1);
- fallback = _as->branchDouble(Assembler::DoubleNotEqualOrUnordered, Assembler::FPGpr0, Assembler::FPGpr1);
-
- isInteger.link(_as);
- _as->or32(Assembler::TrustedImm32(0), Assembler::ScratchRegister);
- needNegativeCheck = true;
- }
-
- // get data, ScratchRegister holds index
- addr = _as->loadTempAddress(Assembler::ReturnValueRegister, tbase);
- _as->load64(addr, Assembler::ReturnValueRegister);
- Address arrayDataLen(Assembler::ReturnValueRegister, qOffsetOf(Object, arrayDataLen));
- Assembler::Jump outOfRange;
- if (needNegativeCheck)
- outOfRange = _as->branch32(Assembler::LessThan, Assembler::ScratchRegister, Assembler::TrustedImm32(0));
- Assembler::Jump outOfRange2 = _as->branch32(Assembler::GreaterThanOrEqual, Assembler::ScratchRegister, arrayDataLen);
- Address arrayData(Assembler::ReturnValueRegister, qOffsetOf(Object, arrayData));
- _as->load64(arrayData, Assembler::ReturnValueRegister);
- Q_ASSERT(sizeof(Property) == (1<<4));
- _as->lshift64(Assembler::TrustedImm32(4), Assembler::ScratchRegister);
- _as->add64(Assembler::ReturnValueRegister, Assembler::ScratchRegister);
- Address value(Assembler::ScratchRegister, qOffsetOf(Property, value));
- _as->load64(value, Assembler::ReturnValueRegister);
-
- // check that the value is not empty
- _as->move(Assembler::ReturnValueRegister, Assembler::ScratchRegister);
- _as->urshift64(Assembler::TrustedImm32(32), Assembler::ScratchRegister);
- Assembler::Jump emptyValue = _as->branch32(Assembler::Equal, Assembler::TrustedImm32(QV4::Value::Empty_Type), Assembler::ScratchRegister);
- _as->storeReturnValue(target);
-
- Assembler::Jump done = _as->jump();
-
- emptyValue.link(_as);
- if (outOfRange.isSet())
- outOfRange.link(_as);
- outOfRange2.link(_as);
- if (fallback.isSet())
- fallback.link(_as);
- if (fallback2.isSet())
- fallback2.link(_as);
- notSimple.link(_as);
- notManaged.link(_as);
-
- generateFunctionCall(target, __qmljs_get_element, Assembler::ContextRegister,
- Assembler::PointerToValue(base), Assembler::PointerToValue(index));
-
- done.link(_as);
+ if (useFastLookups) {
+ uint lookup = registerIndexedGetterLookup();
+ generateLookupCall(target, lookup, qOffsetOf(QV4::Lookup, indexedGetter),
+ Assembler::PointerToValue(base),
+ Assembler::PointerToValue(index));
return;
}
-#endif
generateFunctionCall(target, __qmljs_get_element, Assembler::ContextRegister,
Assembler::PointerToValue(base), Assembler::PointerToValue(index));
@@ -1115,6 +1029,13 @@ void InstructionSelection::getElement(V4IR::Expr *base, V4IR::Expr *index, V4IR:
void InstructionSelection::setElement(V4IR::Expr *source, V4IR::Expr *targetBase, V4IR::Expr *targetIndex)
{
+ if (useFastLookups) {
+ uint lookup = registerIndexedSetterLookup();
+ generateLookupCall(Assembler::Void, lookup, qOffsetOf(QV4::Lookup, indexedSetter),
+ Assembler::PointerToValue(targetBase), Assembler::PointerToValue(targetIndex),
+ Assembler::PointerToValue(source));
+ return;
+ }
generateFunctionCall(Assembler::Void, __qmljs_set_element, Assembler::ContextRegister,
Assembler::PointerToValue(targetBase), Assembler::PointerToValue(targetIndex),
Assembler::PointerToValue(source));
@@ -2010,7 +1931,7 @@ void InstructionSelection::visitRet(V4IR::Ret *s)
_as->exceptionReturnLabel = _as->label();
const int locals = _as->stackLayout().calculateJSStackFrameSize();
- _as->subPtr(Assembler::TrustedImm32(sizeof(QV4::SafeValue)*locals), Assembler::LocalsRegister);
+ _as->subPtr(Assembler::TrustedImm32(sizeof(QV4::Value)*locals), Assembler::LocalsRegister);
_as->loadPtr(Address(Assembler::ContextRegister, qOffsetOf(ExecutionContext, engine)), Assembler::ScratchRegister);
_as->storePtr(Assembler::LocalsRegister, Address(Assembler::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop)));
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index 7dfe6a820a..76fe6c6391 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -45,7 +45,7 @@
#include "qv4jsir_p.h"
#include "qv4isel_p.h"
#include "qv4isel_util_p.h"
-#include "private/qv4value_def_p.h"
+#include "private/qv4value_p.h"
#include "private/qv4lookup_p.h"
#include <QtCore/QHash>
@@ -351,7 +351,7 @@ public:
// space for the callee saved registers
int frameSize = RegisterSize * calleeSavedRegisterCount;
- frameSize += savedRegCount * sizeof(QV4::SafeValue); // these get written out as Values, not as native registers
+ frameSize += savedRegCount * sizeof(QV4::Value); // these get written out as Values, not as native registers
frameSize = WTF::roundUpToMultipleOf(StackAlignment, frameSize + stackSpaceAllocatedOtherwise);
frameSize -= stackSpaceAllocatedOtherwise;
@@ -361,8 +361,8 @@ public:
int calculateJSStackFrameSize() const
{
- const int locals = (localCount + sizeof(QV4::CallData)/sizeof(QV4::SafeValue) - 1 + maxOutgoingArgumentCount) + 1;
- int frameSize = locals * sizeof(QV4::SafeValue);
+ const int locals = (localCount + sizeof(QV4::CallData)/sizeof(QV4::Value) - 1 + maxOutgoingArgumentCount) + 1;
+ int frameSize = locals * sizeof(QV4::Value);
return frameSize;
}
@@ -372,7 +372,7 @@ public:
Q_ASSERT(idx < localCount);
Pointer addr = callDataAddress(0);
- addr.offset -= sizeof(QV4::SafeValue) * (idx + 1);
+ addr.offset -= sizeof(QV4::Value) * (idx + 1);
return addr;
}
@@ -384,11 +384,11 @@ public:
Q_ASSERT(argument < maxOutgoingArgumentCount);
const int index = maxOutgoingArgumentCount - argument;
- return Pointer(Assembler::LocalsRegister, sizeof(QV4::SafeValue) * (-index));
+ return Pointer(Assembler::LocalsRegister, sizeof(QV4::Value) * (-index));
}
Pointer callDataAddress(int offset = 0) const {
- return Pointer(Assembler::LocalsRegister, -(sizeof(QV4::CallData) + sizeof(QV4::SafeValue) * (maxOutgoingArgumentCount - 1)) + offset);
+ return Pointer(Assembler::LocalsRegister, -(sizeof(QV4::CallData) + sizeof(QV4::Value) * (maxOutgoingArgumentCount - 1)) + offset);
}
Address savedRegPointer(int offset) const
@@ -396,7 +396,7 @@ public:
Q_ASSERT(offset >= 0);
Q_ASSERT(offset < savedRegCount);
- const int off = offset * sizeof(QV4::SafeValue);
+ const int off = offset * sizeof(QV4::Value);
return Address(Assembler::StackFrameRegister, - calleeSavedRegisterSpace() - off);
}
@@ -657,7 +657,7 @@ public:
void storeUInt32ReturnValue(RegisterID dest)
{
- Pointer tmp(StackPointerRegister, -int(sizeof(QV4::SafeValue)));
+ Pointer tmp(StackPointerRegister, -int(sizeof(QV4::Value)));
storeReturnValue(tmp);
toUInt32Register(tmp, dest);
}
@@ -669,7 +669,7 @@ public:
xor64(ScratchRegister, ReturnValueRegister);
move64ToDouble(ReturnValueRegister, dest);
#else
- Pointer tmp(StackPointerRegister, -int(sizeof(QV4::SafeValue)));
+ Pointer tmp(StackPointerRegister, -int(sizeof(QV4::Value)));
storeReturnValue(tmp);
loadDouble(tmp, dest);
#endif
@@ -1584,8 +1584,8 @@ private:
int prepareVariableArguments(V4IR::ExprList* args);
int prepareCallData(V4IR::ExprList* args, V4IR::Expr *thisObject);
- template <typename Retval, typename Arg1, typename Arg2>
- void generateLookupCall(Retval retval, uint index, uint getterSetterOffset, Arg1 arg1, Arg2 arg2)
+ template <typename Retval, typename Arg1, typename Arg2, typename Arg3>
+ void generateLookupCall(Retval retval, uint index, uint getterSetterOffset, Arg1 arg1, Arg2 arg2, Arg3 arg3)
{
Assembler::RegisterID lookupRegister;
#if CPU(ARM)
@@ -1599,13 +1599,13 @@ private:
getterSetter.offset += getterSetterOffset;
_as->generateFunctionCallImp(retval, "lookup getter/setter",
- RelativeCall(getterSetter), lookupAddr, arg1, arg2);
+ RelativeCall(getterSetter), lookupAddr, arg1, arg2, arg3);
}
- template <typename Arg1>
- void generateLookupCall(uint index, uint getterSetterOffset, Arg1 arg1)
+ template <typename Retval, typename Arg1, typename Arg2>
+ void generateLookupCall(Retval retval, uint index, uint getterSetterOffset, Arg1 arg1, Arg2 arg2)
{
- generateLookupCall(index, getterSetterOffset, arg1, Assembler::VoidType());
+ generateLookupCall(retval, index, getterSetterOffset, arg1, arg2, Assembler::VoidType());
}
/// This is a temporary method, and will be removed when registers are fully supported.
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index bf9af178fe..130725f3ed 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -47,6 +47,7 @@
#include <private/qv4function_p.h>
#include <private/qv4regexpobject_p.h>
#include <private/qv4compileddata_p.h>
+#include <private/qqmlengine_p.h>
#undef USE_TYPE_INFO
@@ -150,6 +151,167 @@ inline bool isBoolType(V4IR::Expr *e)
return (e->type == V4IR::BoolType);
}
+/*
+ * stack slot allocation:
+ *
+ * foreach bb do
+ * foreach stmt do
+ * if the current statement is not a phi-node:
+ * purge ranges that end before the current statement
+ * check for life ranges to activate, and if they don't have a stackslot associated then allocate one
+ * renumber temps to stack
+ * for phi nodes: check if all temps (src+dst) are assigned stack slots and marked as allocated
+ * if it's a jump:
+ * foreach phi node in the successor:
+ * allocate slots for each temp (both sources and targets) if they don't have one allocated already
+ * insert moves before the jump
+ */
+class AllocateStackSlots: protected ConvertTemps
+{
+ const QVector<V4IR::LifeTimeInterval> _intervals;
+ QVector<const V4IR::LifeTimeInterval *> _unhandled;
+ QVector<const V4IR::LifeTimeInterval *> _live;
+ QBitArray _slotIsInUse;
+ V4IR::Function *_function;
+
+public:
+ AllocateStackSlots(const QVector<V4IR::LifeTimeInterval> &intervals)
+ : _intervals(intervals)
+ , _slotIsInUse(intervals.size(), false)
+ , _function(0)
+ {
+ _live.reserve(8);
+ _unhandled.reserve(_intervals.size());
+ for (int i = _intervals.size() - 1; i >= 0; --i)
+ _unhandled.append(&_intervals.at(i));
+ }
+
+ void forFunction(V4IR::Function *function)
+ {
+ V4IR::Optimizer::showMeTheCode(function);
+ _function = function;
+ toStackSlots(function);
+
+// QTextStream os(stdout, QIODevice::WriteOnly);
+// os << "Frame layout:" << endl;
+// foreach (int t, _stackSlotForTemp.keys()) {
+// os << "\t" << t << " -> " << _stackSlotForTemp[t] << endl;
+// }
+ }
+
+protected:
+ virtual int allocateFreeSlot()
+ {
+ for (int i = 0, ei = _slotIsInUse.size(); i != ei; ++i) {
+ if (!_slotIsInUse[i]) {
+ if (_nextUnusedStackSlot <= i) {
+ Q_ASSERT(_nextUnusedStackSlot == i);
+ _nextUnusedStackSlot = i + 1;
+ }
+ _slotIsInUse[i] = true;
+ return i;
+ }
+ }
+
+ Q_UNREACHABLE();
+ return -1;
+ }
+
+ virtual void process(V4IR::Stmt *s)
+ {
+ Q_ASSERT(s->id > 0);
+
+// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id);
+
+ if (V4IR::Phi *phi = s->asPhi()) {
+ visitPhi(phi);
+ } else {
+ // purge ranges no longer alive:
+ for (int i = 0; i < _live.size(); ) {
+ const V4IR::LifeTimeInterval *lti = _live.at(i);
+ if (lti->end() < s->id) {
+// qDebug() << "\t - moving temp" << lti->temp().index << "to handled, freeing slot" << _stackSlotForTemp[lti->temp().index];
+ _live.remove(i);
+ Q_ASSERT(_slotIsInUse[_stackSlotForTemp[lti->temp().index]]);
+ _slotIsInUse[_stackSlotForTemp[lti->temp().index]] = false;
+ continue;
+ } else {
+ ++i;
+ }
+ }
+
+ // active new ranges:
+ while (!_unhandled.isEmpty()) {
+ const V4IR::LifeTimeInterval *lti = _unhandled.last();
+ if (lti->start() > s->id)
+ break; // we're done
+ Q_ASSERT(!_stackSlotForTemp.contains(lti->temp().index));
+ _stackSlotForTemp[lti->temp().index] = allocateFreeSlot();
+// qDebug() << "\t - activating temp" << lti->temp().index << "on slot" << _stackSlotForTemp[lti->temp().index];
+ _live.append(lti);
+ _unhandled.removeLast();
+ }
+
+ s->accept(this);
+ }
+
+ if (V4IR::Jump *jump = s->asJump()) {
+ V4IR::MoveMapping moves;
+ foreach (V4IR::Stmt *succStmt, jump->target->statements) {
+ if (V4IR::Phi *phi = succStmt->asPhi()) {
+ forceActivation(*phi->targetTemp);
+ for (int i = 0, ei = phi->d->incoming.size(); i != ei; ++i) {
+ V4IR::Expr *e = phi->d->incoming[i];
+ if (V4IR::Temp *t = e->asTemp()) {
+ forceActivation(*t);
+ }
+ if (jump->target->in[i] == _currentBasicBlock)
+ moves.add(phi->d->incoming[i], phi->targetTemp);
+ }
+ } else {
+ break;
+ }
+ }
+ moves.order();
+ QList<V4IR::Move *> newMoves = moves.insertMoves(_currentBasicBlock, _function, true);
+ foreach (V4IR::Move *move, newMoves)
+ move->accept(this);
+ }
+ }
+
+ void forceActivation(const V4IR::Temp &t)
+ {
+ if (_stackSlotForTemp.contains(t.index))
+ return;
+
+ int i = _unhandled.size() - 1;
+ for (; i >= 0; --i) {
+ const V4IR::LifeTimeInterval *lti = _unhandled[i];
+ if (lti->temp() == t) {
+ _live.append(lti);
+ _unhandled.remove(i);
+ break;
+ }
+ }
+ Q_ASSERT(i >= 0); // check that we always found the entry
+
+ _stackSlotForTemp[t.index] = allocateFreeSlot();
+// qDebug() << "\t - force activating temp" << t.index << "on slot" << _stackSlotForTemp[t.index];
+ }
+
+ virtual void visitPhi(V4IR::Phi *phi)
+ {
+ Q_UNUSED(phi);
+#if !defined(QT_NO_DEBUG)
+ Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index));
+ Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]);
+ foreach (V4IR::Expr *e, phi->d->incoming) {
+ if (V4IR::Temp *t = e->asTemp())
+ Q_ASSERT(_stackSlotForTemp.contains(t->index));
+ }
+#endif // defined(QT_NO_DEBUG)
+ }
+};
} // anonymous namespace
InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, V4IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator)
@@ -194,10 +356,19 @@ void InstructionSelection::run(int functionIndex)
V4IR::Optimizer opt(_function);
opt.run(qmlEngine);
if (opt.isInSSA()) {
- opt.convertOutOfSSA();
+ static const bool doStackSlotAllocation =
+ qgetenv("QV4_NO_INTERPRETER_STACK_SLOT_ALLOCATION").isEmpty();
+
+ if (doStackSlotAllocation) {
+ AllocateStackSlots(opt.lifeRanges()).forFunction(_function);
+ } else {
+ opt.convertOutOfSSA();
+ ConvertTemps().toStackSlots(_function);
+ }
opt.showMeTheCode(_function);
+ } else {
+ ConvertTemps().toStackSlots(_function);
}
- ConvertTemps().toStackSlots(_function);
QSet<V4IR::Jump *> removableJumps = opt.calculateOptionalJumps();
qSwap(_removableJumps, removableJumps);
@@ -217,7 +388,13 @@ void InstructionSelection::run(int functionIndex)
QVector<uint> lineNumberMappings;
lineNumberMappings.reserve(_function->basicBlocks.size() * 2);
+ uint currentLine = -1;
for (int i = 0, ei = _function->basicBlocks.size(); i != ei; ++i) {
+ if (irModule->debugMode) {
+ Instruction::Debug debug;
+ debug.breakPoint = 0;
+ addInstruction(debug);
+ }
_block = _function->basicBlocks[i];
_nextBlock = (i < ei - 1) ? _function->basicBlocks[i + 1] : 0;
_addrs.insert(_block, _codeNext - _codeStart);
@@ -237,8 +414,15 @@ void InstructionSelection::run(int functionIndex)
foreach (V4IR::Stmt *s, _block->statements) {
_currentStatement = s;
- if (s->location.isValid())
+ if (s->location.isValid()) {
lineNumberMappings << _codeNext - _codeStart << s->location.startLine;
+ if (irModule->debugMode && s->location.startLine != currentLine) {
+ Instruction::Debug debug;
+ debug.breakPoint = 0;
+ addInstruction(debug);
+ currentLine = s->location.startLine;
+ }
+ }
s->accept(this);
}
@@ -323,7 +507,7 @@ void InstructionSelection::callSubscript(V4IR::Expr *base, V4IR::Expr *index, V4
void InstructionSelection::convertType(V4IR::Temp *source, V4IR::Temp *target)
{
// FIXME: do something more useful with this info
- if (target->type & V4IR::NumberType)
+ if (target->type & V4IR::NumberType && !(source->type & V4IR::NumberType))
unop(V4IR::OpUPlus, source, target);
else
copyValue(source, target);
@@ -428,8 +612,8 @@ void InstructionSelection::loadConst(V4IR::Const *sourceConst, V4IR::Temp *targe
{
assert(sourceConst);
- Instruction::Move move;
- move.source = getParam(sourceConst);
+ Instruction::MoveConst move;
+ move.source = convertToValue(sourceConst).asReturnedValue();
move.result = getResultParam(targetTemp);
addInstruction(move);
}
@@ -546,6 +730,15 @@ void InstructionSelection::getQObjectProperty(V4IR::Expr *base, int propertyInde
void InstructionSelection::getElement(V4IR::Expr *base, V4IR::Expr *index, V4IR::Temp *target)
{
+ if (useFastLookups) {
+ Instruction::LoadElementLookup load;
+ load.lookup = registerIndexedGetterLookup();
+ load.base = getParam(base);
+ load.index = getParam(index);
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ }
Instruction::LoadElement load;
load.base = getParam(base);
load.index = getParam(index);
@@ -556,6 +749,15 @@ void InstructionSelection::getElement(V4IR::Expr *base, V4IR::Expr *index, V4IR:
void InstructionSelection::setElement(V4IR::Expr *source, V4IR::Expr *targetBase,
V4IR::Expr *targetIndex)
{
+ if (useFastLookups) {
+ Instruction::StoreElementLookup store;
+ store.lookup = registerIndexedSetterLookup();
+ store.base = getParam(targetBase);
+ store.index = getParam(targetIndex);
+ store.source = getParam(source);
+ addInstruction(store);
+ return;
+ }
Instruction::StoreElement store;
store.base = getParam(targetBase);
store.index = getParam(targetIndex);
@@ -613,7 +815,8 @@ void InstructionSelection::unop(V4IR::AluOp oper, V4IR::Temp *sourceTemp, V4IR::
Instruction::Move move;
move.source = getParam(sourceTemp);
move.result = getResultParam(targetTemp);
- addInstruction(move);
+ if (move.source != move.result)
+ addInstruction(move);
return;
}
Instruction::UPlus uplus;
@@ -664,37 +867,6 @@ void InstructionSelection::binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR:
Param InstructionSelection::binopHelper(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource, V4IR::Temp *target)
{
- if (isNumberType(leftSource) && isNumberType(rightSource)) {
- switch (oper) {
- case V4IR::OpAdd: {
- Instruction::AddNumberParams instr;
- instr.lhs = getParam(leftSource);
- instr.rhs = getParam(rightSource);
- instr.result = getResultParam(target);
- addInstruction(instr);
- return instr.result;
- }
- case V4IR::OpMul: {
- Instruction::MulNumberParams instr;
- instr.lhs = getParam(leftSource);
- instr.rhs = getParam(rightSource);
- instr.result = getResultParam(target);
- addInstruction(instr);
- return instr.result;
- }
- case V4IR::OpSub: {
- Instruction::SubNumberParams instr;
- instr.lhs = getParam(leftSource);
- instr.rhs = getParam(rightSource);
- instr.result = getResultParam(target);
- addInstruction(instr);
- return instr.result;
- }
- default:
- break;
- }
- }
-
if (oper == V4IR::OpAdd) {
Instruction::Add add;
add.lhs = getParam(leftSource);
@@ -773,6 +945,38 @@ Param InstructionSelection::binopHelper(V4IR::AluOp oper, V4IR::Expr *leftSource
addInstruction(bitXor);
return bitXor.result;
}
+ if (oper == V4IR::OpRShift) {
+ if (V4IR::Const *c = rightSource->asConst()) {
+ Instruction::ShrConst shr;
+ shr.lhs = getParam(leftSource);
+ shr.rhs = convertToValue(c).Value::toInt32() & 0x1f;
+ shr.result = getResultParam(target);
+ addInstruction(shr);
+ return shr.result;
+ }
+ Instruction::Shr shr;
+ shr.lhs = getParam(leftSource);
+ shr.rhs = getParam(rightSource);
+ shr.result = getResultParam(target);
+ addInstruction(shr);
+ return shr.result;
+ }
+ if (oper == V4IR::OpLShift) {
+ if (V4IR::Const *c = rightSource->asConst()) {
+ Instruction::ShlConst shl;
+ shl.lhs = getParam(leftSource);
+ shl.rhs = convertToValue(c).Value::toInt32() & 0x1f;
+ shl.result = getResultParam(target);
+ addInstruction(shl);
+ return shl.result;
+ }
+ Instruction::Shl shl;
+ shl.lhs = getParam(leftSource);
+ shl.rhs = getParam(rightSource);
+ shl.result = getResultParam(target);
+ addInstruction(shl);
+ return shl.result;
+ }
if (oper == V4IR::OpInstanceof || oper == V4IR::OpIn || oper == V4IR::OpAdd) {
Instruction::BinopContext binop;
@@ -810,10 +1014,17 @@ void InstructionSelection::prepareCallArgs(V4IR::ExprList *e, quint32 &argc, qui
// We need to move all the temps into the function arg array
assert(argLocation >= 0);
while (e) {
- Instruction::Move move;
- move.source = getParam(e->expr);
- move.result = Param::createTemp(argLocation);
- addInstruction(move);
+ if (V4IR::Const *c = e->expr->asConst()) {
+ Instruction::MoveConst move;
+ move.source = convertToValue(c).asReturnedValue();
+ move.result = Param::createTemp(argLocation);
+ addInstruction(move);
+ } else {
+ Instruction::Move move;
+ move.source = getParam(e->expr);
+ move.result = Param::createTemp(argLocation);
+ addInstruction(move);
+ }
++argLocation;
++argc;
e = e->next;
@@ -846,16 +1057,16 @@ void InstructionSelection::visitCJump(V4IR::CJump *s)
Q_UNIMPLEMENTED();
}
- Instruction::CJump jump;
- jump.offset = 0;
- jump.condition = condition;
-
if (s->iftrue == _nextBlock) {
- jump.invert = true;
+ Instruction::JumpNe jump;
+ jump.offset = 0;
+ jump.condition = condition;
ptrdiff_t falseLoc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
_patches[s->iffalse].append(falseLoc);
} else {
- jump.invert = false;
+ Instruction::JumpEq jump;
+ jump.offset = 0;
+ jump.condition = condition;
ptrdiff_t trueLoc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
_patches[s->iftrue].append(trueLoc);
@@ -959,9 +1170,8 @@ void InstructionSelection::callBuiltinDeleteName(const QString &name, V4IR::Temp
void InstructionSelection::callBuiltinDeleteValue(V4IR::Temp *result)
{
- Instruction::Move move;
- int idx = jsUnitGenerator()->registerConstant(QV4::Encode(false));
- move.source = Param::createConstant(idx);
+ Instruction::MoveConst move;
+ move.source = QV4::Encode(false);
move.result = getResultParam(result);
addInstruction(move);
}
@@ -1082,10 +1292,17 @@ void InstructionSelection::callBuiltinDefineObjectLiteral(V4IR::Temp *result, V4
bool isData = it->expr->asConst()->value;
it = it->next;
- Instruction::Move move;
- move.source = getParam(it->expr);
- move.result = Param::createTemp(argLocation);
- addInstruction(move);
+ if (V4IR::Const *c = it->expr->asConst()) {
+ Instruction::MoveConst move;
+ move.source = convertToValue(c).asReturnedValue();
+ move.result = Param::createTemp(argLocation);
+ addInstruction(move);
+ } else {
+ Instruction::Move move;
+ move.source = getParam(it->expr);
+ move.result = Param::createTemp(argLocation);
+ addInstruction(move);
+ }
++argLocation;
if (!isData) {
@@ -1124,12 +1341,12 @@ void QQmlJS::Moth::InstructionSelection::callBuiltinConvertThisToObject()
ptrdiff_t InstructionSelection::addInstructionHelper(Instr::Type type, Instr &instr)
{
+
#ifdef MOTH_THREADED_INTERPRETER
instr.common.code = VME::instructionJumpTable()[static_cast<int>(type)];
#else
instr.common.instructionType = type;
#endif
- instr.common.breakPoint = 0;
int instructionSize = Instr::size(type);
if (_codeEnd - _codeNext < instructionSize) {
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
index d8a85ff249..b43868d186 100644
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ b/src/qml/compiler/qv4isel_moth_p.h
@@ -46,7 +46,7 @@
#include <private/qv4isel_p.h>
#include <private/qv4isel_util_p.h>
#include <private/qv4jsir_p.h>
-#include <private/qv4value_def_p.h>
+#include <private/qv4value_p.h>
#include "qv4instr_moth_p.h"
QT_BEGIN_NAMESPACE
@@ -160,7 +160,7 @@ private:
int scratchTempIndex() const { return _function->tempCount; }
int callDataStart() const { return scratchTempIndex() + 1; }
- int outgoingArgumentTempStart() const { return callDataStart() + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue); }
+ int outgoingArgumentTempStart() const { return callDataStart() + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value); }
int frameSize() const { return outgoingArgumentTempStart() + _function->maxNumberOfArguments; }
template <int Instr>
diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h
index 5ddafc07ab..57222672b9 100644
--- a/src/qml/compiler/qv4isel_p.h
+++ b/src/qml/compiler/qv4isel_p.h
@@ -72,6 +72,8 @@ public:
void setUseFastLookups(bool b) { useFastLookups = b; }
int registerString(const QString &str) { return jsGenerator->registerString(str); }
+ uint registerIndexedGetterLookup() { return jsGenerator->registerIndexedGetterLookup(); }
+ uint registerIndexedSetterLookup() { return jsGenerator->registerIndexedSetterLookup(); }
uint registerGetterLookup(const QString &name) { return jsGenerator->registerGetterLookup(name); }
uint registerSetterLookup(const QString &name) { return jsGenerator->registerSetterLookup(name); }
uint registerGlobalGetterLookup(const QString &name) { return jsGenerator->registerGlobalGetterLookup(name); }
diff --git a/src/qml/compiler/qv4isel_util_p.h b/src/qml/compiler/qv4isel_util_p.h
index 38ea682d3b..637746dce1 100644
--- a/src/qml/compiler/qv4isel_util_p.h
+++ b/src/qml/compiler/qv4isel_util_p.h
@@ -42,7 +42,7 @@
#ifndef QV4ISEL_UTIL_P_H
#define QV4ISEL_UTIL_P_H
-#include "private/qv4value_def_p.h"
+#include "private/qv4value_p.h"
#include "qv4jsir_p.h"
QT_BEGIN_NAMESPACE
@@ -97,38 +97,52 @@ inline QV4::Primitive convertToValue(V4IR::Const *c)
class ConvertTemps: protected V4IR::StmtVisitor, protected V4IR::ExprVisitor
{
- int _nextFreeStackSlot;
- QHash<V4IR::Temp, int> _stackSlotForTemp;
-
void renumber(V4IR::Temp *t)
{
if (t->kind != V4IR::Temp::VirtualRegister)
return;
- int stackSlot = _stackSlotForTemp.value(*t, -1);
+ int stackSlot = _stackSlotForTemp.value(t->index, -1);
if (stackSlot == -1) {
- stackSlot = _nextFreeStackSlot++;
- _stackSlotForTemp[*t] = stackSlot;
+ stackSlot = allocateFreeSlot();
+ _stackSlotForTemp[t->index] = stackSlot;
}
t->kind = V4IR::Temp::StackSlot;
t->index = stackSlot;
}
+protected:
+ int _nextUnusedStackSlot;
+ QHash<int, int> _stackSlotForTemp;
+ V4IR::BasicBlock *_currentBasicBlock;
+ virtual int allocateFreeSlot()
+ {
+ return _nextUnusedStackSlot++;
+ }
+
+ virtual void process(V4IR::Stmt *s)
+ {
+ s->accept(this);
+ }
+
public:
ConvertTemps()
- : _nextFreeStackSlot(0)
+ : _nextUnusedStackSlot(0)
+ , _currentBasicBlock(0)
{}
void toStackSlots(V4IR::Function *function)
{
_stackSlotForTemp.reserve(function->tempCount);
- foreach (V4IR::BasicBlock *bb, function->basicBlocks)
+ foreach (V4IR::BasicBlock *bb, function->basicBlocks) {
+ _currentBasicBlock = bb;
foreach (V4IR::Stmt *s, bb->statements)
- s->accept(this);
+ process(s);
+ }
- function->tempCount = _nextFreeStackSlot;
+ function->tempCount = _nextUnusedStackSlot;
}
protected:
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
index deb1af51b4..ea92bb468d 100644
--- a/src/qml/compiler/qv4jsir.cpp
+++ b/src/qml/compiler/qv4jsir.cpp
@@ -740,7 +740,7 @@ Temp *BasicBlock::LOCAL(unsigned index, unsigned scope)
}
Expr *BasicBlock::CONST(Type type, double value)
-{
+{
Const *e = function->New<Const>();
if (type == NumberType) {
int ival = (int)value;
@@ -769,7 +769,7 @@ Expr *BasicBlock::REGEXP(const QString *value, int flags)
}
Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column)
-{
+{
Name *e = function->New<Name>();
e->init(function->newString(id), line, column);
return e;
@@ -805,7 +805,7 @@ Expr *BasicBlock::CONVERT(Expr *expr, Type type)
}
Expr *BasicBlock::UNOP(AluOp op, Expr *expr)
-{
+{
Unop *e = function->New<Unop>();
e->init(op, expr);
return e;
@@ -819,7 +819,7 @@ Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
}
Expr *BasicBlock::CALL(Expr *base, ExprList *args)
-{
+{
Call *e = function->New<Call>();
e->init(base, args);
int argc = 0;
@@ -851,7 +851,7 @@ Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *prop
}
Stmt *BasicBlock::EXP(Expr *expr)
-{
+{
if (isTerminated())
return 0;
@@ -862,7 +862,7 @@ Stmt *BasicBlock::EXP(Expr *expr)
}
Stmt *BasicBlock::MOVE(Expr *target, Expr *source)
-{
+{
if (isTerminated())
return 0;
@@ -872,7 +872,7 @@ Stmt *BasicBlock::MOVE(Expr *target, Expr *source)
return s;
}
-Stmt *BasicBlock::JUMP(BasicBlock *target)
+Stmt *BasicBlock::JUMP(BasicBlock *target)
{
if (isTerminated())
return 0;
@@ -890,7 +890,7 @@ Stmt *BasicBlock::JUMP(BasicBlock *target)
return s;
}
-Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
+Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
{
if (isTerminated())
return 0;
diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp
index ea2338acad..cc9ce4fc96 100644
--- a/src/qml/compiler/qv4regalloc.cpp
+++ b/src/qml/compiler/qv4regalloc.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "qv4regalloc_p.h"
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <algorithm>
@@ -60,6 +60,9 @@ struct Use {
}
QT_BEGIN_NAMESPACE
+
+Q_DECLARE_TYPEINFO(Use, Q_MOVABLE_TYPE);
+
using namespace QQmlJS::V4IR;
namespace QQmlJS {
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 594c38d109..8f3e186cc7 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -3552,7 +3552,13 @@ private:
for (int i = bb->statements.size() - 1; i >= 0; --i) {
Stmt *s = bb->statements[i];
if (Phi *phi = s->asPhi()) {
- live.remove(*phi->targetTemp);
+ LiveRegs::iterator it = live.find(*phi->targetTemp);
+ if (it == live.end()) {
+ // a phi node target that is only defined, but never used
+ _intervals[*phi->targetTemp].setFrom(s);
+ } else {
+ live.erase(it);
+ }
continue;
}
collector.collect(s);
@@ -3991,15 +3997,21 @@ void MoveMapping::order()
qSwap(_moves, output);
}
-void MoveMapping::insertMoves(BasicBlock *bb, Function *function, bool atEnd) const
+QList<V4IR::Move *> MoveMapping::insertMoves(BasicBlock *bb, Function *function, bool atEnd) const
{
+ QList<V4IR::Move *> newMoves;
+ newMoves.reserve(_moves.size());
+
int insertionPoint = atEnd ? bb->statements.size() - 1 : 0;
foreach (const Move &m, _moves) {
V4IR::Move *move = function->New<V4IR::Move>();
- move->init(m.to, m.from);
+ move->init(clone(m.to, function), clone(m.from, function));
move->swap = m.needsSwap;
bb->statements.insert(insertionPoint++, move);
+ newMoves.append(move);
}
+
+ return newMoves;
}
void MoveMapping::dump() const
diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h
index 2ec81b9577..95bed40a27 100644
--- a/src/qml/compiler/qv4ssa_p.h
+++ b/src/qml/compiler/qv4ssa_p.h
@@ -188,7 +188,7 @@ class MoveMapping
public:
void add(Expr *from, Temp *to);
void order();
- void insertMoves(BasicBlock *bb, Function *function, bool atEnd) const;
+ QList<V4IR::Move *> insertMoves(BasicBlock *bb, Function *function, bool atEnd) const;
void dump() const;
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri
index c10f43c8c9..e9f1d6f5fe 100644
--- a/src/qml/debugger/debugger.pri
+++ b/src/qml/debugger/debugger.pri
@@ -3,10 +3,12 @@ SOURCES += \
$$PWD/qqmlprofilerservice.cpp \
$$PWD/qqmldebugserver.cpp \
$$PWD/qqmlinspectorservice.cpp \
- $$PWD/qv8profilerservice.cpp \
+ $$PWD/qv4profilerservice.cpp \
$$PWD/qqmlenginedebugservice.cpp \
$$PWD/qdebugmessageservice.cpp \
- $$PWD/qv4debugservice.cpp
+ $$PWD/qv4debugservice.cpp \
+ $$PWD/qqmlconfigurabledebugservice.cpp \
+ $$PWD/qqmlenginecontrolservice.cpp
HEADERS += \
$$PWD/qqmldebugservice_p.h \
@@ -17,8 +19,11 @@ HEADERS += \
$$PWD/qqmldebugstatesdelegate_p.h \
$$PWD/qqmlinspectorservice_p.h \
$$PWD/qqmlinspectorinterface_p.h \
- $$PWD/qv8profilerservice_p.h \
+ $$PWD/qv4profilerservice_p.h \
$$PWD/qqmlenginedebugservice_p.h \
$$PWD/qqmldebug.h \
$$PWD/qdebugmessageservice_p.h \
- $$PWD/qv4debugservice_p.h
+ $$PWD/qv4debugservice_p.h \
+ $$PWD/qqmlconfigurabledebugservice_p.h \
+ $$PWD/qqmlconfigurabledebugservice_p_p.h \
+ $$PWD/qqmlenginecontrolservice_p.h
diff --git a/src/imports/dialogs/qquickdialogassets_p.h b/src/qml/debugger/qqmlconfigurabledebugservice.cpp
index 406b68a66d..076e12b613 100644
--- a/src/imports/dialogs/qquickdialogassets_p.h
+++ b/src/qml/debugger/qqmlconfigurabledebugservice.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 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.
@@ -39,27 +39,58 @@
**
****************************************************************************/
-#ifndef QQUICKDIALOGASSETS_P_H
-#define QQUICKDIALOGASSETS_P_H
-
-#include <private/qtquickglobal_p.h>
-#include <QtGui/qpa/qplatformdialoghelper.h>
-#include "qquickabstractmessagedialog_p.h"
+#include "qqmlconfigurabledebugservice_p.h"
+#include "qqmlconfigurabledebugservice_p_p.h"
QT_BEGIN_NAMESPACE
-class QQuickStandardButton
+QQmlConfigurableDebugService::QQmlConfigurableDebugService(const QString &name, float version,
+ QObject *parent) :
+ QQmlDebugService((*new QQmlConfigurableDebugServicePrivate), name, version, parent) { init(); }
+
+QQmlConfigurableDebugService::QQmlConfigurableDebugService(QQmlDebugServicePrivate &dd,
+ const QString &name, float version,
+ QObject *parent) :
+ QQmlDebugService(dd, name, version, parent) { init(); }
+
+QMutex *QQmlConfigurableDebugService::configMutex()
{
- Q_GADGET
- Q_ENUMS(QQuickAbstractMessageDialog::StandardButton)
-};
+ Q_D(QQmlConfigurableDebugService);
+ return &d->configMutex;
+}
-class QQuickStandardIcon
+void QQmlConfigurableDebugService::init()
{
- Q_GADGET
- Q_ENUMS(QQuickAbstractMessageDialog::Icon)
-};
+ Q_D(QQmlConfigurableDebugService);
+ QMutexLocker lock(&d->configMutex);
+ // If we're not enabled or not blocking, don't wait for configuration
+ d->waitingForConfiguration = (registerService() == Enabled && blockingMode());
+}
-QT_END_NAMESPACE
+void QQmlConfigurableDebugService::stopWaiting()
+{
+ Q_D(QQmlConfigurableDebugService);
+ QMutexLocker lock(&d->configMutex);
+ d->waitingForConfiguration = false;
+ foreach (QQmlEngine *engine, d->waitingEngines)
+ emit attachedToEngine(engine);
+ d->waitingEngines.clear();
+}
-#endif // QQUICKDIALOGASSETS_P_H
+void QQmlConfigurableDebugService::stateChanged(QQmlDebugService::State newState)
+{
+ if (newState != Enabled)
+ stopWaiting();
+}
+
+void QQmlConfigurableDebugService::engineAboutToBeAdded(QQmlEngine *engine)
+{
+ Q_D(QQmlConfigurableDebugService);
+ QMutexLocker lock(&d->configMutex);
+ if (d->waitingForConfiguration)
+ d->waitingEngines.append(engine);
+ else
+ emit attachedToEngine(engine);
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/widgets/qquickqmessagebox_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
index be91f1d02b..92d18bea90 100644
--- a/src/imports/widgets/qquickqmessagebox_p.h
+++ b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 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.
@@ -39,8 +39,9 @@
**
****************************************************************************/
-#ifndef QQUICKQMESSAGEBOX_P_H
-#define QQUICKQMESSAGEBOX_P_H
+
+#ifndef QQMLCONFIGURABLEDEBUGSEVICE_H
+#define QQMLCONFIGURABLEDEBUGSEVICE_H
//
// W A R N I N G
@@ -53,25 +54,34 @@
// We mean it.
//
-#include "../dialogs/qquickabstractmessagedialog_p.h"
+#include "qqmldebugservice_p.h"
QT_BEGIN_NAMESPACE
-class QQuickQMessageBox : public QQuickAbstractMessageDialog
+class QMutex;
+class QQmlConfigurableDebugServicePrivate;
+class QQmlConfigurableDebugService : public QQmlDebugService
{
+ Q_OBJECT
public:
- QQuickQMessageBox(QObject *parent = 0);
- virtual ~QQuickQMessageBox();
+ QQmlConfigurableDebugService(const QString &name, float version, QObject *parent = 0);
protected:
- virtual QPlatformDialogHelper *helper();
+ QQmlConfigurableDebugService(QQmlDebugServicePrivate &dd, const QString &name, float version, QObject *parent = 0);
-protected:
- Q_DISABLE_COPY(QQuickQMessageBox)
+ QMutex *configMutex();
+ void stopWaiting();
+ void init();
+
+ void stateChanged(State);
+ void engineAboutToBeAdded(QQmlEngine *);
+
+ virtual ~QQmlConfigurableDebugService() {}
+private:
+ Q_DISABLE_COPY(QQmlConfigurableDebugService)
+ Q_DECLARE_PRIVATE(QQmlConfigurableDebugService)
};
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickQMessageBox *)
-
-#endif // QQUICKQMESSAGEBOX_P_H
+#endif // QQMLCONFIGURABLEDEBUGSEVICE_H
diff --git a/src/imports/widgets/qquickqcolordialog_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h
index 3fb0476299..0537933889 100644
--- a/src/imports/widgets/qquickqcolordialog_p.h
+++ b/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 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.
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QQUICKQCOLORDIALOG_P_H
-#define QQUICKQCOLORDIALOG_P_H
+#ifndef QQMLCONFIGURABLEDEBUGSERVICE_P_H
+#define QQMLCONFIGURABLEDEBUGSERVICE_P_H
//
// W A R N I N G
@@ -53,26 +53,26 @@
// We mean it.
//
-#include "../dialogs/qquickabstractcolordialog_p.h"
+#include "qqmldebugservice_p.h"
+#include "qqmldebugservice_p_p.h"
+
+#include <QMutex>
QT_BEGIN_NAMESPACE
-class QQuickQColorDialog : public QQuickAbstractColorDialog
-{
- Q_OBJECT
+class QQmlEngine;
+class QQmlConfigurableDebugServicePrivate : public QQmlDebugServicePrivate
+{
+ Q_DECLARE_PUBLIC(QQmlConfigurableDebugService)
public:
- QQuickQColorDialog(QObject *parent = 0);
- virtual ~QQuickQColorDialog();
+ QQmlConfigurableDebugServicePrivate() : configMutex(QMutex::Recursive) {}
-protected:
- QPlatformColorDialogHelper *helper();
-
- Q_DISABLE_COPY(QQuickQColorDialog)
+ QMutex configMutex;
+ QList<QQmlEngine *> waitingEngines;
+ bool waitingForConfiguration;
};
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickQColorDialog *)
-
-#endif // QQUICKQCOLORDIALOG_P_H
+#endif // QQMLCONFIGURABLEDEBUGSERVICE_P_H
diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp
index 0523762971..a2bf19dee7 100644
--- a/src/qml/debugger/qqmldebugserver.cpp
+++ b/src/qml/debugger/qqmldebugserver.cpp
@@ -42,6 +42,12 @@
#include "qqmldebugserver_p.h"
#include "qqmldebugservice_p.h"
#include "qqmldebugservice_p_p.h"
+#include "qqmlenginedebugservice_p.h"
+#include "qv4debugservice_p.h"
+#include "qv4profilerservice_p.h"
+#include "qdebugmessageservice_p.h"
+#include "qqmlprofilerservice_p.h"
+
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
@@ -56,6 +62,17 @@
QT_BEGIN_NAMESPACE
+// We can't friend the Q_GLOBAL_STATIC to have the constructor available so we need a little
+// workaround here. Using this wrapper we can also make QQmlEnginePrivate's cleanup() available to
+// qAddPostRoutine(). We can't do the cleanup in the destructor because we need a QApplication to
+// be available when stopping the plugins.
+struct QQmlDebugServerInstanceWrapper {
+ QQmlDebugServer m_instance;
+ void cleanup();
+};
+
+Q_GLOBAL_STATIC(QQmlDebugServerInstanceWrapper, debugServerInstance)
+
/*
QQmlDebug Protocol (Version 1):
@@ -93,6 +110,7 @@ public:
QQmlDebugServerPrivate();
void advertisePlugins();
+ void cleanup();
QQmlDebugServerConnection *loadConnectionPlugin(const QString &pluginName);
QQmlDebugServerConnection *connection;
@@ -102,6 +120,22 @@ public:
bool gotHello;
bool blockingMode;
+ class EngineCondition {
+ public:
+ EngineCondition() : numServices(0), condition(new QWaitCondition) {}
+
+ bool waitForServices(QReadWriteLock *locked, int numEngines);
+
+ void wake();
+ private:
+ int numServices;
+
+ // shared pointer to allow for QHash-inflicted copying.
+ QSharedPointer<QWaitCondition> condition;
+ };
+
+ QHash<QQmlEngine *, EngineCondition> engineConditions;
+
QMutex helloMutex;
QWaitCondition helloCondition;
QQmlDebugServerThread *thread;
@@ -115,6 +149,9 @@ private:
void _q_sendMessages(const QList<QByteArray> &messages);
};
+void QQmlDebugServerInstanceWrapper::cleanup()
+{ m_instance.d_func()->cleanup(); }
+
class QQmlDebugServerThread : public QThread
{
public:
@@ -174,6 +211,35 @@ void QQmlDebugServerPrivate::advertisePlugins()
QMetaObject::invokeMethod(q, "_q_sendMessages", Qt::QueuedConnection, Q_ARG(QList<QByteArray>, QList<QByteArray>() << message));
}
+void QQmlDebugServerPrivate::cleanup()
+{
+ Q_Q(QQmlDebugServer);
+ {
+ QReadLocker lock(&pluginsLock);
+ foreach (QQmlDebugService *service, plugins.values()) {
+ changeServiceStateCalls.ref();
+ QMetaObject::invokeMethod(q, "_q_changeServiceState", Qt::QueuedConnection,
+ Q_ARG(QString, service->name()),
+ Q_ARG(QQmlDebugService::State, QQmlDebugService::NotConnected));
+ }
+ }
+
+ // Wait for changeServiceState calls to finish
+ // (while running an event loop because some services
+ // might again use slots to execute stuff in the GUI thread)
+ QEventLoop loop;
+ while (!changeServiceStateCalls.testAndSetOrdered(0, 0))
+ loop.processEvents();
+
+ // Stop the thread while the application is still there.
+ if (thread) {
+ thread->exit();
+ thread->wait();
+ delete thread;
+ thread = 0;
+ }
+}
+
QQmlDebugServerConnection *QQmlDebugServerPrivate::loadConnectionPlugin(
const QString &pluginName)
{
@@ -222,11 +288,13 @@ QQmlDebugServerConnection *QQmlDebugServerPrivate::loadConnectionPlugin(
void QQmlDebugServerThread::run()
{
- QQmlDebugServer *server = QQmlDebugServer::instance();
+ QQmlDebugServerInstanceWrapper *wrapper = debugServerInstance();
+ Q_ASSERT_X(wrapper != 0, Q_FUNC_INFO, "There should always be a debug server available here.");
+ QQmlDebugServer *server = &wrapper->m_instance;
QQmlDebugServerConnection *connection
= server->d_func()->loadConnectionPlugin(m_pluginName);
if (connection) {
- connection->setServer(QQmlDebugServer::instance());
+ connection->setServer(server);
connection->setPortRange(m_portFrom, m_portTo, m_block, m_hostAddress);
} else {
QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp));
@@ -255,112 +323,107 @@ bool QQmlDebugServer::blockingMode() const
return d->blockingMode;
}
-static QQmlDebugServer *qQmlDebugServer = 0;
-
-
-static void cleanup()
+QQmlDebugServer *QQmlDebugServer::instance()
{
- delete qQmlDebugServer;
- qQmlDebugServer = 0;
+ QQmlDebugServerInstanceWrapper *wrapper = debugServerInstance();
+ if (wrapper && wrapper->m_instance.d_func()->thread) {
+ QQmlDebugServer *ret = &(wrapper->m_instance);
+ QQmlDebugServerPrivate *d = ret->d_func();
+ QMutexLocker locker(&d->helloMutex);
+ if (d->blockingMode && !d->gotHello)
+ d->helloCondition.wait(&d->helloMutex);
+ return ret;
+ } else {
+ return 0;
+ }
}
-QQmlDebugServer *QQmlDebugServer::instance()
+static void cleanup()
{
- static bool commandLineTested = false;
+ QQmlDebugServerInstanceWrapper *wrapper = debugServerInstance();
+ if (wrapper)
+ wrapper->cleanup();
+}
- if (!commandLineTested) {
- commandLineTested = true;
- QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp));
+QQmlDebugServer::QQmlDebugServer()
+ : QObject(*(new QQmlDebugServerPrivate))
+{
+ QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp));
#ifndef QT_QML_NO_DEBUGGER
- // ### remove port definition when protocol is changed
- int portFrom = 0;
- int portTo = 0;
- bool block = false;
- bool ok = false;
- QString hostAddress;
-
- // format: qmljsdebugger=port:<port_from>[,port_to],host:<ip address>][,block]
- if (!appD->qmljsDebugArgumentsString().isEmpty()) {
- if (!QQmlEnginePrivate::qml_debugging_enabled) {
- qWarning() << QString(QLatin1String(
- "QML Debugger: Ignoring \"-qmljsdebugger=%1\". "
- "Debugging has not been enabled.")).arg(
- appD->qmljsDebugArgumentsString());
- return 0;
- }
+ // ### remove port definition when protocol is changed
+ int portFrom = 0;
+ int portTo = 0;
+ bool block = false;
+ bool ok = false;
+ QString hostAddress;
+
+ // format: qmljsdebugger=port:<port_from>[,port_to],host:<ip address>][,block]
+ if (!appD->qmljsDebugArgumentsString().isEmpty()) {
+ if (!QQmlEnginePrivate::qml_debugging_enabled) {
+ qWarning() << QString(QLatin1String(
+ "QML Debugger: Ignoring \"-qmljsdebugger=%1\". "
+ "Debugging has not been enabled.")).arg(
+ appD->qmljsDebugArgumentsString());
+ return;
+ }
- QString pluginName;
- QStringList lstjsDebugArguments = appD->qmljsDebugArgumentsString()
- .split(QLatin1Char(','));
- QStringList::const_iterator argsItEnd = lstjsDebugArguments.end();
- QStringList::const_iterator argsIt = lstjsDebugArguments.begin();
- for (; argsIt != argsItEnd; ++argsIt) {
- const QString strArgument = *argsIt;
- if (strArgument.startsWith(QLatin1String("port:"))) {
- pluginName = QLatin1String("qmldbg_tcp");
- portFrom = strArgument.mid(5).toInt(&ok);
- portTo = portFrom;
- QStringList::const_iterator argsNext = argsIt + 1;
- if (argsNext == argsItEnd)
- break;
- const QString nextArgument = *argsNext;
- if (ok && nextArgument.contains(QRegExp(QStringLiteral("^\\s*\\d+\\s*$")))) {
- portTo = nextArgument.toInt(&ok);
- ++argsIt;
- }
- } else if (strArgument.startsWith(QLatin1String("host:"))) {
- hostAddress = strArgument.mid(5);
- } else if (strArgument == QLatin1String("block")) {
- block = true;
- } else {
- qWarning() << QString::fromLatin1("QML Debugger: Invalid argument '%1' "
- "detected. Ignoring the same.")
- .arg(strArgument);
+ QString pluginName;
+ QStringList lstjsDebugArguments = appD->qmljsDebugArgumentsString()
+ .split(QLatin1Char(','));
+ QStringList::const_iterator argsItEnd = lstjsDebugArguments.end();
+ QStringList::const_iterator argsIt = lstjsDebugArguments.begin();
+ for (; argsIt != argsItEnd; ++argsIt) {
+ const QString strArgument = *argsIt;
+ if (strArgument.startsWith(QLatin1String("port:"))) {
+ pluginName = QLatin1String("qmldbg_tcp");
+ portFrom = strArgument.mid(5).toInt(&ok);
+ portTo = portFrom;
+ QStringList::const_iterator argsNext = argsIt + 1;
+ if (argsNext == argsItEnd)
+ break;
+ const QString nextArgument = *argsNext;
+ if (ok && nextArgument.contains(QRegExp(QStringLiteral("^\\s*\\d+\\s*$")))) {
+ portTo = nextArgument.toInt(&ok);
+ ++argsIt;
}
+ } else if (strArgument.startsWith(QLatin1String("host:"))) {
+ hostAddress = strArgument.mid(5);
+ } else if (strArgument == QLatin1String("block")) {
+ block = true;
+ } else {
+ qWarning() << QString::fromLatin1("QML Debugger: Invalid argument '%1' "
+ "detected. Ignoring the same.")
+ .arg(strArgument);
}
+ }
- if (ok) {
- qQmlDebugServer = new QQmlDebugServer();
- QQmlDebugServerThread *thread = new QQmlDebugServerThread;
- qQmlDebugServer->d_func()->thread = thread;
- qQmlDebugServer->moveToThread(thread);
- thread->setPluginName(pluginName);
- thread->setPortRange(portFrom, portTo, block, hostAddress);
-
- QQmlDebugServerPrivate *d = qQmlDebugServer->d_func();
- d->blockingMode = block;
-
- QMutexLocker locker(&d->helloMutex);
- thread->start();
+ if (ok) {
+ qAddPostRoutine(cleanup);
+ Q_D(QQmlDebugServer);
+ d->thread = new QQmlDebugServerThread;
+ moveToThread(d->thread);
+ d->thread->setPluginName(pluginName);
+ d->thread->setPortRange(portFrom, portTo, block, hostAddress);
- if (d->blockingMode)
- d->helloCondition.wait(&d->helloMutex);
+ d->blockingMode = block;
+ d->thread->start();
- } else {
- qWarning() << QString(QLatin1String(
- "QML Debugger: Ignoring \"-qmljsdebugger=%1\". "
- "Format is qmljsdebugger=port:<port_from>[,port_to],host:"
- "<ip address>][,block]")).arg(appD->qmljsDebugArgumentsString());
- }
- }
-#else
- if (!appD->qmljsDebugArgumentsString().isEmpty()) {
+ } else {
qWarning() << QString(QLatin1String(
- "QML Debugger: Ignoring \"-qmljsdebugger=%1\". "
- "QtQml is not configured for debugging.")).arg(
- appD->qmljsDebugArgumentsString());
+ "QML Debugger: Ignoring \"-qmljsdebugger=%1\". "
+ "Format is qmljsdebugger=port:<port_from>[,port_to],host:"
+ "<ip address>][,block]")).arg(appD->qmljsDebugArgumentsString());
}
-#endif
}
-
- return qQmlDebugServer;
-}
-
-QQmlDebugServer::QQmlDebugServer()
- : QObject(*(new QQmlDebugServerPrivate))
-{
- qAddPostRoutine(cleanup);
+#else
+ if (!appD->qmljsDebugArgumentsString().isEmpty()) {
+ qWarning() << QString(QLatin1String(
+ "QML Debugger: Ignoring \"-qmljsdebugger=%1\". "
+ "QtQml is not configured for debugging.")).arg(
+ appD->qmljsDebugArgumentsString());
+ }
+#endif
}
// called from GUI thread!
@@ -368,28 +431,7 @@ QQmlDebugServer::~QQmlDebugServer()
{
Q_D(QQmlDebugServer);
- {
- QReadLocker lock(&d->pluginsLock);
- foreach (QQmlDebugService *service, d->plugins.values()) {
- d->changeServiceStateCalls.ref();
- QMetaObject::invokeMethod(this, "_q_changeServiceState", Qt::QueuedConnection,
- Q_ARG(QString, service->name()),
- Q_ARG(QQmlDebugService::State, QQmlDebugService::NotConnected));
- }
- }
-
- // Wait for changeServiceState calls to finish
- // (while running an event loop because some services
- // might again use slots to execute stuff in the GUI thread)
- QEventLoop loop;
- while (!d->changeServiceStateCalls.testAndSetOrdered(0, 0))
- loop.processEvents();
-
- if (d->thread) {
- d->thread->exit();
- d->thread->wait();
- delete d->thread;
- }
+ delete d->thread;
delete d->connection;
}
@@ -409,6 +451,7 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message)
int op = -1;
in >> op;
if (op == 0) {
+ QWriteLocker lock(&d->pluginsLock);
int version;
in >> version >> d->clientPlugins;
@@ -423,24 +466,22 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message)
// the plugins below start sending messages.
QByteArray helloAnswer;
- {
- QReadLocker readPluginsLock(&d->pluginsLock);
- QQmlDebugStream out(&helloAnswer, QIODevice::WriteOnly);
- QStringList pluginNames;
- QList<float> pluginVersions;
- foreach (QQmlDebugService *service, d->plugins.values()) {
- pluginNames << service->name();
- pluginVersions << service->version();
- }
-
- out << QString(QStringLiteral("QDeclarativeDebugClient")) << 0 << protocolVersion
- << pluginNames << pluginVersions << s_dataStreamVersion;
+ QQmlDebugStream out(&helloAnswer, QIODevice::WriteOnly);
+ QStringList pluginNames;
+ QList<float> pluginVersions;
+ foreach (QQmlDebugService *service, d->plugins.values()) {
+ pluginNames << service->name();
+ pluginVersions << service->version();
}
+
+ out << QString(QStringLiteral("QDeclarativeDebugClient")) << 0 << protocolVersion
+ << pluginNames << pluginVersions << s_dataStreamVersion;
+
d->connection->send(QList<QByteArray>() << helloAnswer);
+ QMutexLocker helloLock(&d->helloMutex);
d->gotHello = true;
- QReadLocker lock(&d->pluginsLock);
QHash<QString, QQmlDebugService*>::ConstIterator iter = d->plugins.constBegin();
for (; iter != d->plugins.constEnd(); ++iter) {
QQmlDebugService::State newState = QQmlDebugService::Unavailable;
@@ -450,16 +491,15 @@ void QQmlDebugServer::receiveMessage(const QByteArray &message)
d->_q_changeServiceState(iter.value()->name(), newState);
}
- QMutexLocker helloLock(&d->helloMutex);
d->helloCondition.wakeAll();
} else if (op == 1) {
+ QWriteLocker lock(&d->pluginsLock);
// Service Discovery
QStringList oldClientPlugins = d->clientPlugins;
in >> d->clientPlugins;
- QReadLocker lock(&d->pluginsLock);
QHash<QString, QQmlDebugService*>::ConstIterator iter = d->plugins.constBegin();
for (; iter != d->plugins.constEnd(); ++iter) {
const QString pluginName = iter.key();
@@ -507,7 +547,10 @@ void QQmlDebugServerPrivate::_q_changeServiceState(const QString &serviceName,
QQmlDebugService *service = 0;
{
- QReadLocker lock(&pluginsLock);
+ // Write lock here, because this can be called from receiveMessage which already has a write
+ // lock. We cannot downgrade it. We also don't want to give up the write lock and later get
+ // a read lock as that technique has great potential for deadlocks.
+ QWriteLocker lock(&pluginsLock);
service = plugins.value(serviceName);
}
@@ -543,27 +586,56 @@ QStringList QQmlDebugServer::serviceNames() const
return d->plugins.keys();
}
+void QQmlDebugServer::addEngine(QQmlEngine *engine)
+{
+ Q_D(QQmlDebugServer);
+ QWriteLocker lock(&d->pluginsLock);
+
+ foreach (QQmlDebugService *service, d->plugins)
+ service->engineAboutToBeAdded(engine);
+
+ d->engineConditions[engine].waitForServices(&d->pluginsLock, d->plugins.count());
+
+ foreach (QQmlDebugService *service, d->plugins)
+ service->engineAdded(engine);
+}
+
+void QQmlDebugServer::removeEngine(QQmlEngine *engine)
+{
+ Q_D(QQmlDebugServer);
+ QWriteLocker lock(&d->pluginsLock);
+
+ foreach (QQmlDebugService *service, d->plugins)
+ service->engineAboutToBeRemoved(engine);
+
+ d->engineConditions[engine].waitForServices(&d->pluginsLock, d->plugins.count());
+
+ foreach (QQmlDebugService *service, d->plugins)
+ service->engineRemoved(engine);
+}
+
bool QQmlDebugServer::addService(QQmlDebugService *service)
{
Q_D(QQmlDebugServer);
- // to be executed in GUI thread
- Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread());
+ // to be executed outside of debugger thread
+ Q_ASSERT(QThread::currentThread() != thread());
- {
- QWriteLocker lock(&d->pluginsLock);
- if (!service || d->plugins.contains(service->name()))
- return false;
- d->plugins.insert(service->name(), service);
- }
- {
- QReadLocker lock(&d->pluginsLock);
- d->advertisePlugins();
- QQmlDebugService::State newState = QQmlDebugService::Unavailable;
- if (d->clientPlugins.contains(service->name()))
- newState = QQmlDebugService::Enabled;
- service->d_func()->state = newState;
- }
+ connect(service, SIGNAL(attachedToEngine(QQmlEngine*)),
+ this, SLOT(wakeEngine(QQmlEngine*)), Qt::QueuedConnection);
+ connect(service, SIGNAL(detachedFromEngine(QQmlEngine*)),
+ this, SLOT(wakeEngine(QQmlEngine*)), Qt::QueuedConnection);
+
+
+ QWriteLocker lock(&d->pluginsLock);
+ if (!service || d->plugins.contains(service->name()))
+ return false;
+ d->plugins.insert(service->name(), service);
+ d->advertisePlugins();
+ QQmlDebugService::State newState = QQmlDebugService::Unavailable;
+ if (d->clientPlugins.contains(service->name()))
+ newState = QQmlDebugService::Enabled;
+ service->d_func()->state = newState;
return true;
}
@@ -571,24 +643,22 @@ bool QQmlDebugServer::removeService(QQmlDebugService *service)
{
Q_D(QQmlDebugServer);
- // to be executed in GUI thread
- Q_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread());
+ // to be executed outside of debugger thread
+ Q_ASSERT(QThread::currentThread() != thread());
- {
- QWriteLocker lock(&d->pluginsLock);
- QQmlDebugService::State newState = QQmlDebugService::NotConnected;
+ QWriteLocker lock(&d->pluginsLock);
+ QQmlDebugService::State newState = QQmlDebugService::NotConnected;
- d->changeServiceStateCalls.ref();
- QMetaObject::invokeMethod(this, "_q_changeServiceState", Qt::QueuedConnection,
- Q_ARG(QString, service->name()),
- Q_ARG(QQmlDebugService::State, newState));
+ d->changeServiceStateCalls.ref();
+ QMetaObject::invokeMethod(this, "_q_changeServiceState", Qt::QueuedConnection,
+ Q_ARG(QString, service->name()),
+ Q_ARG(QQmlDebugService::State, newState));
- if (!service || !d->plugins.contains(service->name()))
- return false;
- d->plugins.remove(service->name());
+ if (!service || !d->plugins.contains(service->name()))
+ return false;
+ d->plugins.remove(service->name());
- d->advertisePlugins();
- }
+ d->advertisePlugins();
return true;
}
@@ -608,6 +678,33 @@ void QQmlDebugServer::sendMessages(QQmlDebugService *service,
Q_ARG(QList<QByteArray>, prefixedMessages));
}
+void QQmlDebugServer::wakeEngine(QQmlEngine *engine)
+{
+ // to be executed in debugger thread
+ Q_ASSERT(QThread::currentThread() == thread());
+
+ Q_D(QQmlDebugServer);
+ QWriteLocker lock(&d->pluginsLock);
+ d->engineConditions[engine].wake();
+}
+
+bool QQmlDebugServerPrivate::EngineCondition::waitForServices(QReadWriteLock *locked, int num)
+{
+ // to be executed outside of debugger thread
+ Q_ASSERT(QThread::currentThread() != QQmlDebugServer::instance()->thread());
+
+ Q_ASSERT_X(numServices == 0, Q_FUNC_INFO, "Request to wait again before previous wait finished");
+ numServices = num;
+ return condition->wait(locked);
+}
+
+void QQmlDebugServerPrivate::EngineCondition::wake()
+{
+ if (--numServices == 0)
+ condition->wakeAll();
+ Q_ASSERT_X(numServices >=0, Q_FUNC_INFO, "Woken more often than #services.");
+}
+
QT_END_NAMESPACE
#include "moc_qqmldebugserver_p.cpp"
diff --git a/src/qml/debugger/qqmldebugserver_p.h b/src/qml/debugger/qqmldebugserver_p.h
index e285d7cfe7..0675faaef7 100644
--- a/src/qml/debugger/qqmldebugserver_p.h
+++ b/src/qml/debugger/qqmldebugserver_p.h
@@ -77,6 +77,8 @@ public:
QList<QQmlDebugService*> services() const;
QStringList serviceNames() const;
+ void addEngine(QQmlEngine *engine);
+ void removeEngine(QQmlEngine *engine);
bool addService(QQmlDebugService *service);
bool removeService(QQmlDebugService *service);
@@ -85,10 +87,14 @@ public:
void sendMessages(QQmlDebugService *service, const QList<QByteArray> &messages);
+private slots:
+ void wakeEngine(QQmlEngine *engine);
+
private:
friend class QQmlDebugService;
friend class QQmlDebugServicePrivate;
friend class QQmlDebugServerThread;
+ friend struct QQmlDebugServerInstanceWrapper;
QQmlDebugServer();
Q_PRIVATE_SLOT(d_func(), void _q_changeServiceState(const QString &serviceName,
QQmlDebugService::State state))
diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp
index d8fc2f2bb2..da62393d97 100644
--- a/src/qml/debugger/qqmldebugservice.cpp
+++ b/src/qml/debugger/qqmldebugservice.cpp
@@ -318,6 +318,24 @@ void QQmlDebugService::messageReceived(const QByteArray &)
{
}
+void QQmlDebugService::engineAboutToBeAdded(QQmlEngine *engine)
+{
+ emit attachedToEngine(engine);
+}
+
+void QQmlDebugService::engineAboutToBeRemoved(QQmlEngine *engine)
+{
+ emit detachedFromEngine(engine);
+}
+
+void QQmlDebugService::engineAdded(QQmlEngine *)
+{
+}
+
+void QQmlDebugService::engineRemoved(QQmlEngine *)
+{
+}
+
QQmlDebugStream::QQmlDebugStream()
: QDataStream()
{
diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h
index 71a116f6a5..5208b2dfa8 100644
--- a/src/qml/debugger/qqmldebugservice_p.h
+++ b/src/qml/debugger/qqmldebugservice_p.h
@@ -60,6 +60,7 @@
QT_BEGIN_NAMESPACE
+class QQmlEngine;
class QQmlDebugServicePrivate;
class Q_QML_PRIVATE_EXPORT QQmlDebugService : public QObject
@@ -103,6 +104,15 @@ protected:
virtual void stateChanged(State);
virtual void messageReceived(const QByteArray &);
+ virtual void engineAboutToBeAdded(QQmlEngine *);
+ virtual void engineAboutToBeRemoved(QQmlEngine *);
+ virtual void engineAdded(QQmlEngine *);
+ virtual void engineRemoved(QQmlEngine *);
+
+signals:
+ void attachedToEngine(QQmlEngine *);
+ void detachedFromEngine(QQmlEngine *);
+
private:
friend class QQmlDebugServer;
friend class QQmlDebugServerPrivate;
diff --git a/src/qml/debugger/qqmlenginecontrolservice.cpp b/src/qml/debugger/qqmlenginecontrolservice.cpp
new file mode 100644
index 0000000000..90815912ad
--- /dev/null
+++ b/src/qml/debugger/qqmlenginecontrolservice.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 <QQmlEngine>
+#include "qqmldebug.h"
+#include "qqmlenginecontrolservice_p.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC(QQmlEngineControlService, qmlEngineControlService)
+
+QQmlEngineControlService::QQmlEngineControlService() :
+ QQmlDebugService(QStringLiteral("EngineControl"), 1)
+{
+ QMutexLocker lock(&dataMutex);
+ registerService();
+}
+
+QQmlEngineControlService *QQmlEngineControlService::instance()
+{
+ return qmlEngineControlService();
+}
+
+void QQmlEngineControlService::messageReceived(const QByteArray &message)
+{
+ QMutexLocker lock(&dataMutex);
+ QQmlDebugStream d(message);
+ int command;
+ int engineId;
+ d >> command >> engineId;
+ QQmlEngine *engine = qobject_cast<QQmlEngine *>(objectForId(engineId));
+ if (command == StartWaitingEngine && startingEngines.contains(engine)) {
+ startingEngines.removeOne(engine);
+ emit attachedToEngine(engine);
+ } else if (command == StopWaitingEngine && stoppingEngines.contains(engine)) {
+ stoppingEngines.removeOne(engine);
+ emit detachedFromEngine(engine);
+ }
+}
+
+void QQmlEngineControlService::engineAboutToBeAdded(QQmlEngine *engine)
+{
+ QMutexLocker lock(&dataMutex);
+ if (state() == Enabled) {
+ Q_ASSERT(!stoppingEngines.contains(engine));
+ Q_ASSERT(!startingEngines.contains(engine));
+ startingEngines.append(engine);
+ sendMessage(EngineAboutToBeAdded, engine);
+ } else {
+ emit attachedToEngine(engine);
+ }
+}
+
+void QQmlEngineControlService::engineAboutToBeRemoved(QQmlEngine *engine)
+{
+ QMutexLocker lock(&dataMutex);
+ if (state() == Enabled) {
+ Q_ASSERT(!stoppingEngines.contains(engine));
+ Q_ASSERT(!startingEngines.contains(engine));
+ stoppingEngines.append(engine);
+ sendMessage(EngineAboutToBeRemoved, engine);
+ } else {
+ emit detachedFromEngine(engine);
+ }
+}
+
+void QQmlEngineControlService::engineAdded(QQmlEngine *engine)
+{
+ if (state() == Enabled) {
+ QMutexLocker lock(&dataMutex);
+ Q_ASSERT(!startingEngines.contains(engine));
+ Q_ASSERT(!stoppingEngines.contains(engine));
+ sendMessage(EngineAdded, engine);
+ }
+}
+
+void QQmlEngineControlService::engineRemoved(QQmlEngine *engine)
+{
+ if (state() == Enabled) {
+ QMutexLocker lock(&dataMutex);
+ Q_ASSERT(!startingEngines.contains(engine));
+ Q_ASSERT(!stoppingEngines.contains(engine));
+ sendMessage(EngineRemoved, engine);
+ }
+}
+
+void QQmlEngineControlService::sendMessage(QQmlEngineControlService::MessageType type, QQmlEngine *engine)
+{
+ QByteArray message;
+ QQmlDebugStream d(&message, QIODevice::WriteOnly);
+ d << type << idForObject(engine);
+ QQmlDebugService::sendMessage(message);
+}
+
+void QQmlEngineControlService::stateChanged(State)
+{
+ // We flush everything for any kind of state change, to avoid complicated timing issues.
+ QMutexLocker lock(&dataMutex);
+ foreach (QQmlEngine *engine, startingEngines)
+ emit attachedToEngine(engine);
+ startingEngines.clear();
+ foreach (QQmlEngine *engine, stoppingEngines)
+ emit detachedFromEngine(engine);
+ stoppingEngines.clear();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/dialogs/qquickplatformfontdialog_p.h b/src/qml/debugger/qqmlenginecontrolservice_p.h
index 743b24ad87..150d36d9cf 100644
--- a/src/imports/dialogs/qquickplatformfontdialog_p.h
+++ b/src/qml/debugger/qqmlenginecontrolservice_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 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.
+** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,8 +39,11 @@
**
****************************************************************************/
-#ifndef QQUICKPLATFORMFONTDIALOG_P_H
-#define QQUICKPLATFORMFONTDIALOG_P_H
+#ifndef QQMLENGINECONTROLSERVICE_H
+#define QQMLENGINECONTROLSERVICE_H
+
+#include <QMutex>
+#include "qqmldebugservice_p.h"
//
// W A R N I N G
@@ -53,26 +56,43 @@
// We mean it.
//
-#include "qquickabstractfontdialog_p.h"
-
QT_BEGIN_NAMESPACE
-class QQuickPlatformFontDialog : public QQuickAbstractFontDialog
+class QQmlEngineControlService : public QQmlDebugService
{
- Q_OBJECT
-
public:
- QQuickPlatformFontDialog(QObject *parent = 0);
- virtual ~QQuickPlatformFontDialog();
+ enum MessageType {
+ EngineAboutToBeAdded,
+ EngineAdded,
+ EngineAboutToBeRemoved,
+ EngineRemoved
+ };
+
+ enum CommandType {
+ StartWaitingEngine,
+ StopWaitingEngine
+ };
+
+ QQmlEngineControlService();
+
+ static QQmlEngineControlService *instance();
protected:
- QPlatformFontDialogHelper *helper();
+ QMutex dataMutex;
+ QList<QQmlEngine *> startingEngines;
+ QList<QQmlEngine *> stoppingEngines;
+
+ void messageReceived(const QByteArray &);
+ void engineAboutToBeAdded(QQmlEngine *);
+ void engineAboutToBeRemoved(QQmlEngine *);
+ void engineAdded(QQmlEngine *);
+ void engineRemoved(QQmlEngine *);
- Q_DISABLE_COPY(QQuickPlatformFontDialog)
+ void sendMessage(MessageType type, QQmlEngine *engine);
+
+ void stateChanged(State);
};
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickPlatformFontDialog *)
-
-#endif // QQUICKPLATFORMFONTDIALOG_P_H
+#endif // QQMLENGINECONTROLSERVICE_H
diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp
index 5f3db9fb65..2c6c1e22f5 100644
--- a/src/qml/debugger/qqmlenginedebugservice.cpp
+++ b/src/qml/debugger/qqmlenginedebugservice.cpp
@@ -83,7 +83,7 @@ QQmlEngineDebugService::~QQmlEngineDebugService()
delete m_statesDelegate;
}
-QDataStream &operator<<(QDataStream &ds,
+QDataStream &operator<<(QDataStream &ds,
const QQmlEngineDebugService::QQmlObjectData &data)
{
ds << data.url << data.lineNumber << data.columnNumber << data.idString
@@ -92,7 +92,7 @@ QDataStream &operator<<(QDataStream &ds,
return ds;
}
-QDataStream &operator>>(QDataStream &ds,
+QDataStream &operator>>(QDataStream &ds,
QQmlEngineDebugService::QQmlObjectData &data)
{
ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString
@@ -101,7 +101,7 @@ QDataStream &operator>>(QDataStream &ds,
return ds;
}
-QDataStream &operator<<(QDataStream &ds,
+QDataStream &operator<<(QDataStream &ds,
const QQmlEngineDebugService::QQmlObjectProperty &data)
{
ds << (int)data.type << data.name << data.value << data.valueTypeName
@@ -109,7 +109,7 @@ QDataStream &operator<<(QDataStream &ds,
return ds;
}
-QDataStream &operator>>(QDataStream &ds,
+QDataStream &operator>>(QDataStream &ds,
QQmlEngineDebugService::QQmlObjectProperty &data)
{
int type;
@@ -219,13 +219,13 @@ QVariant QQmlEngineDebugService::valueContents(const QVariant &value) const
return QString(QStringLiteral("<unknown value>"));
}
-void QQmlEngineDebugService::buildObjectDump(QDataStream &message,
+void QQmlEngineDebugService::buildObjectDump(QDataStream &message,
QObject *object, bool recur, bool dumpProperties)
{
message << objectData(object);
QObjectList children = object->children();
-
+
int childrenCount = children.count();
for (int ii = 0; ii < children.count(); ++ii) {
if (qobject_cast<QQmlContext*>(children[ii]))
@@ -759,20 +759,22 @@ void QQmlEngineDebugService::propertyChanged(int id, int objectId, const QMetaPr
sendMessage(reply);
}
-void QQmlEngineDebugService::addEngine(QQmlEngine *engine)
+void QQmlEngineDebugService::engineAboutToBeAdded(QQmlEngine *engine)
{
Q_ASSERT(engine);
Q_ASSERT(!m_engines.contains(engine));
m_engines.append(engine);
+ emit attachedToEngine(engine);
}
-void QQmlEngineDebugService::remEngine(QQmlEngine *engine)
+void QQmlEngineDebugService::engineAboutToBeRemoved(QQmlEngine *engine)
{
Q_ASSERT(engine);
Q_ASSERT(m_engines.contains(engine));
m_engines.removeAll(engine);
+ emit detachedFromEngine(engine);
}
void QQmlEngineDebugService::objectCreated(QQmlEngine *engine, QObject *object)
diff --git a/src/qml/debugger/qqmlenginedebugservice_p.h b/src/qml/debugger/qqmlenginedebugservice_p.h
index bbd6aac1b1..4809ee3ed5 100644
--- a/src/qml/debugger/qqmlenginedebugservice_p.h
+++ b/src/qml/debugger/qqmlenginedebugservice_p.h
@@ -96,8 +96,8 @@ public:
bool hasNotifySignal;
};
- void addEngine(QQmlEngine *);
- void remEngine(QQmlEngine *);
+ void engineAboutToBeAdded(QQmlEngine *);
+ void engineAboutToBeRemoved(QQmlEngine *);
void objectCreated(QQmlEngine *, QObject *);
void setStatesDelegate(QQmlDebugStatesDelegate *);
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp
index af2aea21ae..a9ef5ff6b1 100644
--- a/src/qml/debugger/qqmlprofilerservice.cpp
+++ b/src/qml/debugger/qqmlprofilerservice.cpp
@@ -47,97 +47,118 @@
#include <QtCore/qthread.h>
#include <QtCore/qcoreapplication.h>
-// this contains QUnifiedTimer
-#include <private/qabstractanimation_p.h>
-
QT_BEGIN_NAMESPACE
// instance will be set, unset in constructor. Allows static methods to be inlined.
-QQmlProfilerService *QQmlProfilerService::instance = 0;
+QQmlProfilerService *QQmlProfilerService::m_instance = 0;
Q_GLOBAL_STATIC(QQmlProfilerService, profilerInstance)
bool QQmlProfilerService::enabled = false;
-// convert to a QByteArray that can be sent to the debug client
+// convert to QByteArrays that can be sent to the debug client
// use of QDataStream can skew results
// (see tst_qqmldebugtrace::trace() benchmark)
-QByteArray QQmlProfilerData::toByteArray() const
+void QQmlProfilerData::toByteArrays(QList<QByteArray> &messages) const
{
QByteArray data;
- //### using QDataStream is relatively expensive
- QQmlDebugStream ds(&data, QIODevice::WriteOnly);
- ds << time << messageType << detailType;
- if (messageType == (int)QQmlProfilerService::RangeStart &&
- detailType == (int)QQmlProfilerService::Binding)
- ds << bindingType;
- if (messageType == (int)QQmlProfilerService::RangeData)
- ds << detailData;
- if (messageType == (int)QQmlProfilerService::RangeLocation)
- ds << detailData << line << column;
- if (messageType == (int)QQmlProfilerService::Event &&
- detailType == (int)QQmlProfilerService::AnimationFrame)
- ds << framerate << animationcount;
- if (messageType == (int)QQmlProfilerService::PixmapCacheEvent) {
- ds << detailData;
- switch (detailType) {
- case QQmlProfilerService::PixmapSizeKnown: ds << line << column; break;
- case QQmlProfilerService::PixmapReferenceCountChanged: ds << animationcount; break;
- case QQmlProfilerService::PixmapCacheCountChanged: ds << animationcount; break;
- default: break;
- }
- }
- if (messageType == (int)QQmlProfilerService::SceneGraphFrame) {
- switch (detailType) {
- // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime
- case QQmlProfilerService::SceneGraphRendererFrame: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break;
- // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime
- case QQmlProfilerService::SceneGraphAdaptationLayerFrame: ds << (int)subtime_1 << subtime_2 << subtime_3; break;
- // ContextFrame: compiling material time
- case QQmlProfilerService::SceneGraphContextFrame: ds << subtime_1; break;
- // RenderLoop: syncTime, renderTime, swapTime
- case QQmlProfilerService::SceneGraphRenderLoopFrame: ds << subtime_1 << subtime_2 << subtime_3; break;
- // TexturePrepare: bind, convert, swizzle, upload, mipmap
- case QQmlProfilerService::SceneGraphTexturePrepare: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4 << subtime_5; break;
- // TextureDeletion: deletionTime
- case QQmlProfilerService::SceneGraphTextureDeletion: ds << subtime_1; break;
- // PolishAndSync: polishTime, waitTime, syncTime, animationsTime,
- case QQmlProfilerService::SceneGraphPolishAndSync: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break;
- // WindowsRenderLoop: GL time, make current time, SceneGraph time
- case QQmlProfilerService::SceneGraphWindowsRenderShow: ds << subtime_1 << subtime_2 << subtime_3; break;
- // WindowsAnimations: update time
- case QQmlProfilerService::SceneGraphWindowsAnimations: ds << subtime_1; break;
- // WindowsRenderWindow: polish time
- case QQmlProfilerService::SceneGraphWindowsPolishFrame: ds << subtime_1; break;
- default:break;
+ Q_ASSERT_X(((messageType | detailType) & (1 << 31)) == 0, Q_FUNC_INFO, "You can use at most 31 message types and 31 detail types.");
+ for (uint decodedMessageType = 0; (messageType >> decodedMessageType) != 0; ++decodedMessageType) {
+ if ((messageType & (1 << decodedMessageType)) == 0)
+ continue;
+
+ for (uint decodedDetailType = 0; (detailType >> decodedDetailType) != 0; ++decodedDetailType) {
+ if ((detailType & (1 << decodedDetailType)) == 0)
+ continue;
+
+ //### using QDataStream is relatively expensive
+ QQmlDebugStream ds(&data, QIODevice::WriteOnly);
+ ds << time << decodedMessageType << decodedDetailType;
+
+ switch (decodedMessageType) {
+ case QQmlProfilerService::Event:
+ if (decodedDetailType == (int)QQmlProfilerService::AnimationFrame)
+ ds << framerate << count;
+ break;
+ case QQmlProfilerService::RangeStart:
+ if (decodedDetailType == (int)QQmlProfilerService::Binding)
+ ds << bindingType;
+ break;
+ case QQmlProfilerService::RangeData:
+ ds << detailString;
+ break;
+ case QQmlProfilerService::RangeLocation:
+ ds << (detailUrl.isEmpty() ? detailString : detailUrl.toString()) << x << y;
+ break;
+ case QQmlProfilerService::RangeEnd: break;
+ case QQmlProfilerService::PixmapCacheEvent:
+ ds << detailUrl.toString();
+ switch (decodedDetailType) {
+ case QQmlProfilerService::PixmapSizeKnown: ds << x << y; break;
+ case QQmlProfilerService::PixmapReferenceCountChanged: ds << count; break;
+ case QQmlProfilerService::PixmapCacheCountChanged: ds << count; break;
+ default: break;
+ }
+ break;
+ case QQmlProfilerService::SceneGraphFrame:
+ switch (decodedDetailType) {
+ // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime
+ case QQmlProfilerService::SceneGraphRendererFrame: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break;
+ // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime
+ case QQmlProfilerService::SceneGraphAdaptationLayerFrame: ds << (int)subtime_1 << subtime_2 << subtime_3; break;
+ // ContextFrame: compiling material time
+ case QQmlProfilerService::SceneGraphContextFrame: ds << subtime_1; break;
+ // RenderLoop: syncTime, renderTime, swapTime
+ case QQmlProfilerService::SceneGraphRenderLoopFrame: ds << subtime_1 << subtime_2 << subtime_3; break;
+ // TexturePrepare: bind, convert, swizzle, upload, mipmap
+ case QQmlProfilerService::SceneGraphTexturePrepare: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4 << subtime_5; break;
+ // TextureDeletion: deletionTime
+ case QQmlProfilerService::SceneGraphTextureDeletion: ds << subtime_1; break;
+ // PolishAndSync: polishTime, waitTime, syncTime, animationsTime,
+ case QQmlProfilerService::SceneGraphPolishAndSync: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break;
+ // WindowsRenderLoop: GL time, make current time, SceneGraph time
+ case QQmlProfilerService::SceneGraphWindowsRenderShow: ds << subtime_1 << subtime_2 << subtime_3; break;
+ // WindowsAnimations: update time
+ case QQmlProfilerService::SceneGraphWindowsAnimations: ds << subtime_1; break;
+ // WindowsRenderWindow: polish time; always comes packed after a RenderLoop
+ case QQmlProfilerService::SceneGraphWindowsPolishFrame: ds << subtime_4; break;
+ default:break;
+ }
+ break;
+ case QQmlProfilerService::Complete: break;
+ }
+ messages << data;
+ data.clear();
}
}
+}
- return data;
+void QQmlProfilerService::animationTimerCallback(qint64 delta)
+{
+ Q_QML_PROFILE(animationFrame(delta));
}
QQmlProfilerService::QQmlProfilerService()
- : QQmlDebugService(QStringLiteral("CanvasFrameRate"), 1)
+ : QQmlConfigurableDebugService(QStringLiteral("CanvasFrameRate"), 1)
{
m_timer.start();
- // don't execute stateAboutToBeChanged(), messageReceived() in parallel
- QMutexLocker lock(&m_initializeMutex);
-
- if (registerService() == Enabled) {
- QUnifiedTimer::instance()->registerProfilerCallback(&animationFrame);
- if (blockingMode())
- m_initializeCondition.wait(&m_initializeMutex);
- }
+ QMutexLocker lock(configMutex());
+ // TODO: This is problematic as the service could be enabled at a later point in time. In that
+ // case we might miss the callback registration.
+ if (state() == Enabled)
+ QUnifiedTimer::instance()->registerProfilerCallback(&animationTimerCallback);
}
QQmlProfilerService::~QQmlProfilerService()
{
- instance = 0;
+ enabled = false;
+ m_instance = 0;
}
-void QQmlProfilerService::initialize()
+QQmlProfilerService *QQmlProfilerService::instance()
{
// just make sure that the service is properly registered
- instance = profilerInstance();
+ m_instance = profilerInstance();
+ return m_instance;
}
bool QQmlProfilerService::startProfiling()
@@ -150,26 +171,6 @@ bool QQmlProfilerService::stopProfiling()
return profilerInstance()->stopProfilingImpl();
}
-void QQmlProfilerService::sendStartedProfilingMessage()
-{
- profilerInstance()->sendStartedProfilingMessageImpl();
-}
-
-void QQmlProfilerService::addEvent(EventType t)
-{
- profilerInstance()->addEventImpl(t);
-}
-
-void QQmlProfilerService::animationFrame(qint64 delta)
-{
- profilerInstance()->animationFrameImpl(delta);
-}
-
-void QQmlProfilerService::sceneGraphFrame(SceneGraphFrameType frameType, qint64 value1, qint64 value2, qint64 value3, qint64 value4, qint64 value5)
-{
- profilerInstance()->sceneGraphFrameImpl(frameType, value1, value2, value3, value4, value5);
-}
-
void QQmlProfilerService::sendProfilingData()
{
profilerInstance()->sendMessages();
@@ -177,193 +178,31 @@ void QQmlProfilerService::sendProfilingData()
bool QQmlProfilerService::startProfilingImpl()
{
- bool success = false;
- if (QQmlDebugService::isDebuggingEnabled() && !profilingEnabled()) {
- setProfilingEnabled(true);
- sendStartedProfilingMessageImpl();
- success = true;
+ if (QQmlDebugService::isDebuggingEnabled() && !enabled) {
+ enabled = true;
+ QList<QByteArray> messages;
+ QQmlProfilerData(m_timer.nsecsElapsed(), 1 << Event, 1 << StartTrace).toByteArrays(messages);
+ QQmlDebugService::sendMessages(messages);
+ return true;
+ } else {
+ return false;
}
- return success;
}
bool QQmlProfilerService::stopProfilingImpl()
{
- bool success = false;
- if (profilingEnabled()) {
- addEventImpl(EndTrace);
- setProfilingEnabled(false);
- success = true;
- }
- return success;
-}
-
-void QQmlProfilerService::sendStartedProfilingMessageImpl()
-{
- if (!QQmlDebugService::isDebuggingEnabled() || !enabled)
- return;
-
- QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)StartTrace,
- QString(), -1, -1, 0, 0, 0,
- 0, 0, 0, 0, 0};
- QQmlDebugService::sendMessage(ed.toByteArray());
-}
-
-void QQmlProfilerService::addEventImpl(EventType event)
-{
- if (!QQmlDebugService::isDebuggingEnabled() || !enabled)
- return;
-
- QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)event,
- QString(), -1, -1, 0, 0, 0,
- 0, 0, 0, 0, 0};
- processMessage(ed);
-}
-
-void QQmlProfilerService::startRange(RangeType range, BindingType bindingType)
-{
- if (!QQmlDebugService::isDebuggingEnabled() || !enabled)
- return;
-
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeStart, (int)range,
- QString(), -1, -1, 0, 0, (int)bindingType,
- 0, 0, 0, 0, 0};
- processMessage(rd);
-}
-
-void QQmlProfilerService::rangeData(RangeType range, const QString &rData)
-{
- if (!QQmlDebugService::isDebuggingEnabled() || !enabled)
- return;
-
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range,
- rData, -1, -1, 0, 0, 0,
- 0, 0, 0, 0, 0};
- processMessage(rd);
-}
-
-void QQmlProfilerService::rangeData(RangeType range, const QUrl &rData)
-{
- if (!QQmlDebugService::isDebuggingEnabled() || !enabled)
- return;
-
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range,
- rData.toString(), -1, -1, 0, 0, 0,
- 0, 0, 0, 0, 0};
- processMessage(rd);
-}
-
-void QQmlProfilerService::rangeLocation(RangeType range, const QString &fileName, int line, int column)
-{
- if (!QQmlDebugService::isDebuggingEnabled() || !enabled)
- return;
-
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range,
- fileName, line, column, 0, 0, 0,
- 0, 0, 0, 0, 0};
- processMessage(rd);
-}
-
-void QQmlProfilerService::rangeLocation(RangeType range, const QUrl &fileName, int line, int column)
-{
- if (!QQmlDebugService::isDebuggingEnabled() || !enabled)
- return;
-
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range,
- fileName.toString(), line, column, 0, 0, 0,
- 0, 0, 0, 0, 0};
- processMessage(rd);
-}
-
-void QQmlProfilerService::endRange(RangeType range)
-{
- if (!QQmlDebugService::isDebuggingEnabled() || !enabled)
- return;
-
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)RangeEnd, (int)range,
- QString(), -1, -1, 0, 0, 0,
- 0, 0, 0, 0, 0};
- processMessage(rd);
-}
-
-void QQmlProfilerService::pixmapEventImpl(PixmapEventType eventType, const QUrl &url)
-{
- // assuming enabled checked by caller
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)PixmapCacheEvent, (int)eventType,
- url.toString(), -1, -1, -1, -1, -1,
- 0, 0, 0, 0, 0};
- processMessage(rd);
-}
-
-void QQmlProfilerService::pixmapEventImpl(PixmapEventType eventType, const QUrl &url, int width, int height)
-{
- // assuming enabled checked by caller
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)PixmapCacheEvent, (int)eventType,
- url.toString(), width, height, -1, -1, -1,
- 0, 0, 0, 0, 0};
- processMessage(rd);
-}
-
-void QQmlProfilerService::pixmapEventImpl(PixmapEventType eventType, const QUrl &url, int count)
-{
- // assuming enabled checked by caller
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)PixmapCacheEvent, (int)eventType,
- url.toString(), -1, -1, -1, count, -1,
- 0, 0, 0, 0, 0};
- processMessage(rd);
-}
-
-void QQmlProfilerService::sceneGraphFrameImpl(SceneGraphFrameType frameType, qint64 value1, qint64 value2, qint64 value3, qint64 value4, qint64 value5)
-{
- if (!QQmlDebugService::isDebuggingEnabled() || !enabled)
- return;
-
- // because I already have some space to store ints in the struct, I'll use it to store the frame data
- // even though the field names do not match
- QQmlProfilerData rd = {m_timer.nsecsElapsed(), (int)SceneGraphFrame, (int)frameType, QString(),
- -1, -1, -1, -1, -1,
- value1, value2, value3, value4, value5};
- processMessage(rd);
-}
-
-void QQmlProfilerService::animationFrameImpl(qint64 delta)
-{
- Q_ASSERT(QQmlDebugService::isDebuggingEnabled());
- if (!enabled)
- return;
-
- int animCount = QUnifiedTimer::instance()->runningAnimationCount();
-
- if (animCount > 0 && delta > 0) {
- // trim fps to integer
- int fps = 1000 / delta;
- QQmlProfilerData ed = {m_timer.nsecsElapsed(), (int)Event, (int)AnimationFrame,
- QString(), -1, -1, fps, animCount, 0,
- 0, 0, 0, 0, 0};
- processMessage(ed);
+ if (enabled) {
+ enabled = false;
+ // We cannot use instance here as this is called from the debugger thread.
+ // It may be called before the QML engine (and the profiler) is ready.
+ processMessage(QQmlProfilerData(m_timer.nsecsElapsed(), 1 << Event, 1 << EndTrace));
+ return true;
+ } else {
+ return false;
}
}
/*
- Either send the message directly, or queue up
- a list of messages to send later (via sendMessages)
-*/
-void QQmlProfilerService::processMessage(const QQmlProfilerData &message)
-{
- QMutexLocker locker(&m_dataMutex);
- m_data.append(message);
-}
-
-bool QQmlProfilerService::profilingEnabled()
-{
- return enabled;
-}
-
-void QQmlProfilerService::setProfilingEnabled(bool enable)
-{
- enabled = enable;
-}
-
-/*
Send the messages queued up by processMessage
*/
void QQmlProfilerService::sendMessages()
@@ -372,7 +211,7 @@ void QQmlProfilerService::sendMessages()
QList<QByteArray> messages;
for (int i = 0; i < m_data.count(); ++i)
- messages << m_data.at(i).toByteArray();
+ m_data.at(i).toByteArrays(messages);
m_data.clear();
//indicate completion
@@ -386,27 +225,20 @@ void QQmlProfilerService::sendMessages()
void QQmlProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState)
{
- QMutexLocker lock(&m_initializeMutex);
+ QMutexLocker lock(configMutex());
if (state() == newState)
return;
- if (state() == Enabled
- && enabled) {
+ if (newState != Enabled && enabled) {
stopProfilingImpl();
sendMessages();
}
-
- if (state() != Enabled) {
- // wake up constructor in blocking mode
- // (we might got disabled before first message arrived)
- m_initializeCondition.wakeAll();
- }
}
void QQmlProfilerService::messageReceived(const QByteArray &message)
{
- QMutexLocker lock(&m_initializeMutex);
+ QMutexLocker lock(configMutex());
QByteArray rwData = message;
QQmlDebugStream stream(&rwData, QIODevice::ReadOnly);
@@ -421,158 +253,62 @@ void QQmlProfilerService::messageReceived(const QByteArray &message)
sendMessages();
}
- // wake up constructor in blocking mode
- m_initializeCondition.wakeAll();
-}
-
-/*!
- * \brief QQmlVmeProfiler::Data::clear Reset to defaults
- * Reset the profiling data to defaults.
- */
-void QQmlVmeProfiler::Data::clear()
-{
- url.clear();
- line = 0;
- column = 0;
- typeName.clear();
+ stopWaiting();
}
/*!
- * \brief QQmlVmeProfiler::start Start profiler without data
- * Clears the current range data, then stops the profiler previously running in the
- * foreground if any, then starts a new one.
+ * \fn void QQmlVmeProfiler::Data::clear()
+ * Resets the profiling data to defaults.
*/
-bool QQmlVmeProfiler::start()
-{
- if (QQmlProfilerService::enabled) {
- currentRange.clear();
- if (running)
- QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
- else
- running = true;
- QQmlProfilerService::instance->startRange(QQmlProfilerService::Creating);
- return true;
- }
- return false;
-}
/*!
- * \brief QQmlVmeProfiler::updateLocation Update current location information
- * \param url URL of file being executed
- * \param line line Curent line in file
- * \param column column Current column in file
- * Updates the current profiler's location information.
+ * \fn bool QQmlVmeProfiler::startBackground(const QString &typeName)
+ * If profiling is enabled clears the current range data, then stops the
+ * profiler previously running in the foreground if any, then starts a new one
+ * in the background, setting the given typeName. \a typeName is the type of
+ * object being created.
*/
-void QQmlVmeProfiler::updateLocation(const QUrl &url, int line, int column)
-{
- if (QQmlProfilerService::enabled && running) {
- currentRange.url = url;
- currentRange.line = line;
- currentRange.column = column;
- QQmlProfilerService::instance->rangeLocation(
- QQmlProfilerService::Creating, url, line, column);
- }
-}
/*!
- * \brief QQmlVmeProfiler::updateTypeName Update current type information
- * \param typeName Type of object being created
- * Updates the current profiler's type information.
+ * \fn bool QQmlVmeProfiler::start(const QString &typeName, const QUrl &url, int line, int column)
+ * If profiling is enabled clears the current range data, then stops the
+ * profiler previously running in the foreground if any, then starts a new one
+ * in the foreground, setting the given location. \a url is the URL of
+ * file being executed, \line line is the current line in in that file, and
+ * \a column is the current column in that file.
*/
-void QQmlVmeProfiler::updateTypeName(const QString &typeName)
-{
- if (QQmlProfilerService::enabled && running) {
- currentRange.typeName = typeName;
- QQmlProfilerService::instance->rangeData(QQmlProfilerService::Creating, typeName);
- }
-}
/*!
- * \brief QQmlVmeProfiler::pop Pops a paused profiler from the stack and restarts it
+ * \fn bool QQmlVmeProfiler::pop()
* Stops the currently running profiler, if any, then retrieves an old one from the stack
- * of paused profilers and starts that.
+ * of paused profilers and starts that if possible.
*/
-void QQmlVmeProfiler::pop()
-{
- if (QQmlProfilerService::enabled && ranges.count() > 0) {
- start();
- currentRange = ranges.pop();
- QQmlProfilerService::instance->rangeLocation(
- QQmlProfilerService::Creating, currentRange.url, currentRange.line, currentRange.column);
- QQmlProfilerService::instance->rangeData(QQmlProfilerService::Creating, currentRange.typeName);
- }
-}
/*!
- * \brief QQmlVmeProfiler::push Pushes the currently running profiler on the stack.
+ * \fn void QQmlVmeProfiler::push()
* Pushes the currently running profiler on the stack of paused profilers. Note: The profiler
* isn't paused here. That's a separate step. If it's never paused, but pop()'ed later that
* won't do any harm, though.
*/
-void QQmlVmeProfiler::push()
-{
- if (QQmlProfilerService::enabled && running)
- ranges.push(currentRange);
-}
/*!
- * \brief QQmlVmeProfiler::clear Stop all running profilers and clear all data.
+ * \fn void QQmlVmeProfiler::clear()
* Stops the currently running (foreground and background) profilers and removes all saved
* data about paused profilers.
*/
-void QQmlVmeProfiler::clear()
-{
- stop();
- ranges.clear();
- if (QQmlProfilerService::enabled) {
- for (int i = 0; i < backgroundRanges.count(); ++i) {
- QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
- }
- }
- backgroundRanges.clear();
- running = false;
-}
/*!
- * \brief QQmlVmeProfiler::stop Stop profiler running in the foreground, if any.
+ * \fn void QQmlVmeProfiler::stop()
+ * Stop profiler running in the foreground, if any.
*/
-void QQmlVmeProfiler::stop()
-{
- if (QQmlProfilerService::enabled && running) {
- QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
- currentRange.clear();
- running = false;
- }
-}
/*!
- * \brief QQmlVmeProfiler::background Push the current profiler to the background.
- * Push the profiler currently running in the foreground to the background so that it
- * won't be stopped by stop() or start(). There can be multiple profilers in the background.
- * You can retrieve them in reverse order by calling foreground().
+ * \fn bool QQmlVmeProfiler::foreground(const QUrl &url, int line, int column)
+ * Stops the profiler currently running in the foreground, if any and puts the
+ * next profiler from the background in its place if there are any profilers in
+ * the background. Additionally the rangeLocation is set. \a url is the URL of
+ * file being executed, \line line is the current line in in that file, and
+ * \a column is the current column in that file.
*/
-void QQmlVmeProfiler::background()
-{
- if (QQmlProfilerService::enabled && running) {
- backgroundRanges.push(currentRange);
- running = false;
- }
-}
-
-/*!
- * \brief QQmlVmeProfiler::foreground Retrieve a profiler from the background
- * Stop the profiler currently running in the foreground, if any and put the next profiler
- * from the background in its place.
- */
-bool QQmlVmeProfiler::foreground()
-{
- if (QQmlProfilerService::enabled && backgroundRanges.count() > 0) {
- stop();
- currentRange = backgroundRanges.pop();
- running = true;
- return true;
- }
- return false;
-}
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h
index 32b88e3ec3..b688141730 100644
--- a/src/qml/debugger/qqmlprofilerservice_p.h
+++ b/src/qml/debugger/qqmlprofilerservice_p.h
@@ -53,8 +53,10 @@
// We mean it.
//
-#include <private/qqmldebugservice_p.h>
+#include "qqmlconfigurabledebugservice_p.h"
#include <private/qqmlboundsignal_p.h>
+// this contains QUnifiedTimer
+#include <private/qabstractanimation_p.h>
#include <private/qv4function_p.h>
#include <QtCore/qelapsedtimer.h>
@@ -64,30 +66,95 @@
#include <QtCore/qstringbuilder.h>
#include <QtCore/qwaitcondition.h>
+#define Q_QML_PROFILE_IF_ENABLED(Code)\
+ if (QQmlProfilerService::enabled) {\
+ Code;\
+ } else\
+ (void)0
+
+#define Q_QML_PROFILE(Method)\
+ Q_QML_PROFILE_IF_ENABLED(QQmlProfilerService::Method)
+
+#define Q_QML_SG_PROFILE2(Type1, Type2, Params)\
+ Q_QML_PROFILE_IF_ENABLED((QQmlProfilerService::sceneGraphFrame<Type1, Type2> Params))
+
+#define Q_QML_SG_PROFILE1(Type, Params) Q_QML_SG_PROFILE2(Type, Type, Params)
QT_BEGIN_NAMESPACE
+// This struct is somewhat dangerous to use:
+// You can save values either with 32 or 64 bit precision. toByteArrays will
+// guess the precision from messageType. If you state the wrong messageType
+// you will get undefined results.
+// The messageType is itself a bit field. You can pack multiple messages into
+// one object, e.g. RangeStart and RangeLocation. Each one will be read
+// independently by toByteArrays. Thus you can only pack messages if their data
+// doesn't overlap. Again, it's up to you to figure that out.
struct Q_AUTOTEST_EXPORT QQmlProfilerData
{
+ QQmlProfilerData() {}
+
+ QQmlProfilerData(qint64 time, int messageType, int detailType, const QUrl &url,
+ int x = 0, int y = 0, int framerate = 0, int count = 0, int bindingType = 0) :
+ time(time), messageType(messageType), detailType(detailType), detailUrl(url),
+ x(x), y(y), framerate(framerate), count(count), bindingType(bindingType) {}
+
+ QQmlProfilerData(qint64 time, int messageType, int detailType, const QString &str,
+ int x = 0, int y = 0, int framerate = 0, int count = 0, int bindingType = 0) :
+ time(time), messageType(messageType), detailType(detailType),detailString(str),
+ x(x), y(y), framerate(framerate), count(count), bindingType(bindingType) {}
+
+ QQmlProfilerData(qint64 time, int messageType, int detailType, const QString &str,
+ const QUrl &url, int x = 0, int y = 0, int framerate = 0, int count = 0,
+ int bindingType = 0) :
+ time(time), messageType(messageType), detailType(detailType), detailString(str),
+ detailUrl(url), x(x), y(y), framerate(framerate), count(count), bindingType(bindingType) {}
+
+
+ QQmlProfilerData(qint64 time, int messageType, int detailType) :
+ time(time), messageType(messageType), detailType(detailType) {}
+
+ // Special ctor for scenegraph frames. Note that it's missing the QString/QUrl params.
+ // This is slightly ugly, but makes it easier to disambiguate between int and qint64 params.
+ QQmlProfilerData(qint64 time, int messageType, int detailType,
+ qint64 d1, qint64 d2, qint64 d3, qint64 d4, qint64 d5) :
+ time(time), messageType(messageType), detailType(detailType),
+ subtime_1(d1), subtime_2(d2), subtime_3(d3), subtime_4(d4), subtime_5(d5) {}
+
+
qint64 time;
- int messageType;
+ int messageType; //bit field of QQmlProfilerService::Message
int detailType;
- //###
- QString detailData; //used by RangeData and RangeLocation
- int line; //used by RangeLocation, also as "width" for pixmaps
- int column; //used by RangeLocation, also as "height" for pixmaps
- int framerate; //used by animation events
- int animationcount; //used by animation events, also as "cache/reference count" for pixmaps
- int bindingType;
-
- qint64 subtime_1;
- qint64 subtime_2;
- qint64 subtime_3;
- qint64 subtime_4;
- qint64 subtime_5;
-
- QByteArray toByteArray() const;
+ QString detailString; //used by RangeData and possibly by RangeLocation
+ QUrl detailUrl; //used by RangeLocation, overrides detailString
+
+ union {
+ qint64 subtime_1;
+ int x; //used by RangeLocation and for pixmaps
+ };
+
+ union {
+ qint64 subtime_2;
+ int y; //used by RangeLocation and for pixmaps
+ };
+
+ union {
+ qint64 subtime_3;
+ int framerate; //used by animation events
+ };
+
+ union {
+ qint64 subtime_4;
+ int count; //used by animation events and for pixmaps
+ };
+
+ union {
+ qint64 subtime_5;
+ int bindingType;
+ };
+
+ void toByteArrays(QList<QByteArray> &messages) const;
};
Q_DECLARE_TYPEINFO(QQmlProfilerData, Q_MOVABLE_TYPE);
@@ -96,7 +163,7 @@ class QUrl;
class QQmlEngine;
-class Q_QML_PRIVATE_EXPORT QQmlProfilerService : public QQmlDebugService
+class Q_QML_PRIVATE_EXPORT QQmlProfilerService : public QQmlConfigurableDebugService
{
public:
enum Message {
@@ -167,17 +234,62 @@ public:
MaximumSceneGraphFrameType
};
- static void initialize();
+ static QQmlProfilerService *instance();
static bool startProfiling();
static bool stopProfiling();
- static void sendStartedProfilingMessage();
- static bool profilingEnabled();
- static void addEvent(EventType);
- static void animationFrame(qint64);
+ template<EventType DetailType>
+ static void addEvent()
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(), 1 << Event,
+ 1 << DetailType));
+ }
+
+ static void animationFrame(qint64 delta)
+ {
+ int animCount = QUnifiedTimer::instance()->runningAnimationCount();
+
+ if (animCount > 0 && delta > 0) {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(), 1 << Event,
+ 1 << AnimationFrame, QString(), 0, 0,
+ 1000 / (int)delta /* trim fps to integer */,
+ animCount));
+ }
+ }
+
+ template<SceneGraphFrameType FrameType1, SceneGraphFrameType FrameType2>
+ static void sceneGraphFrame(qint64 value1, qint64 value2 = -1, qint64 value3 = -1,
+ qint64 value4 = -1, qint64 value5 = -1)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(), 1 << SceneGraphFrame,
+ 1 << FrameType1 | 1 << FrameType2,
+ value1, value2, value3, value4, value5));
+ }
+
+ template<PixmapEventType PixmapState>
+ static void pixmapStateChanged(const QUrl &url)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(), 1 << PixmapCacheEvent,
+ 1 << PixmapState, url));
+ }
+
+ static void pixmapLoadingFinished(const QUrl &url, const QSize &size)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(), 1 << PixmapCacheEvent,
+ (1 << PixmapLoadingFinished) | ((size.width() > 0 && size.height() > 0) ? (1 << PixmapSizeKnown) : 0),
+ url, size.width(), size.height()));
+ }
+
+ template<PixmapEventType CountType>
+ static void pixmapCountChanged(const QUrl &url, int count)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(), 1 << PixmapCacheEvent,
+ 1 << CountType, url, 0, 0, 0, count));
+ }
+
+ qint64 timestamp() {return m_timer.nsecsElapsed();}
- static void sceneGraphFrame(SceneGraphFrameType frameType, qint64 value1, qint64 value2 = -1, qint64 value3 = -1, qint64 value4 = -1, qint64 value5 = -1);
static void sendProfilingData();
QQmlProfilerService();
@@ -190,28 +302,69 @@ protected:
private:
bool startProfilingImpl();
bool stopProfilingImpl();
- void sendStartedProfilingMessageImpl();
- void addEventImpl(EventType);
- void animationFrameImpl(qint64);
- void startRange(RangeType, BindingType bindingType = QmlBinding);
- void rangeData(RangeType, const QString &);
- void rangeData(RangeType, const QUrl &);
- void rangeLocation(RangeType, const QString &, int, int);
- void rangeLocation(RangeType, const QUrl &, int, int);
- void endRange(RangeType);
+ static void startBinding(const QString &fileName, int line, int column, BindingType bindingType)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(),
+ (1 << RangeStart | 1 << RangeLocation),
+ 1 << Binding, fileName, line, column, 0, 0,
+ bindingType));
+ }
+
+ // Have toByteArrays() construct another RangeData event from the same QString later.
+ // This is somewhat pointless but important for backwards compatibility.
+ static void startCompiling(const QString &name)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(),
+ (1 << RangeStart | 1 << RangeLocation | 1 << RangeData), 1 << Compiling,
+ name, 1, 1, 0, 0, QmlBinding));
+ }
+
+ static void startHandlingSignal(const QString &fileName, int line, int column)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(),
+ (1 << RangeStart | 1 << RangeLocation),
+ 1 << HandlingSignal, fileName, line, column, 0, 0,
+ QmlBinding));
+ }
+
+ static void startCreating(const QString &typeName, const QUrl &fileName, int line, int column)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(),
+ (1 << RangeStart | 1 << RangeLocation | 1 << RangeData),
+ 1 << Creating, typeName, fileName, line, column,
+ 0, 0, QmlBinding));
+ }
- // overloading depending on parameters
- void pixmapEventImpl(PixmapEventType eventType, const QUrl &url);
- void pixmapEventImpl(PixmapEventType eventType, const QUrl &url, int width, int height);
- void pixmapEventImpl(PixmapEventType eventType, const QUrl &url, int count);
+ static void startCreating(const QString &typeName)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(),
+ (1 << RangeStart | 1 << RangeData), 1 << Creating,
+ typeName, 0, 0, 0, 0, QmlBinding));
+ }
- void sceneGraphFrameImpl(SceneGraphFrameType frameType, qint64 value1, qint64 value2, qint64 value3, qint64 value4, qint64 value5);
+ static void creatingLocation(const QUrl &fileName, int line, int column)
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(), 1 << RangeLocation,
+ 1 << Creating, fileName, line, column));
+ }
+ template<RangeType Range>
+ static void endRange()
+ {
+ m_instance->processMessage(QQmlProfilerData(m_instance->timestamp(), 1 << RangeEnd,
+ 1 << Range));
+ }
- void setProfilingEnabled(bool enable);
void sendMessages();
- void processMessage(const QQmlProfilerData &);
+
+ void processMessage(const QQmlProfilerData &message)
+ {
+ QMutexLocker locker(&m_dataMutex);
+ m_data.append(message);
+ }
+
+ static void animationTimerCallback(qint64 delta);
public:
static bool enabled;
@@ -219,16 +372,13 @@ private:
QElapsedTimer m_timer;
QVector<QQmlProfilerData> m_data;
QMutex m_dataMutex;
- QMutex m_initializeMutex;
- QWaitCondition m_initializeCondition;
- static QQmlProfilerService *instance;
+ static QQmlProfilerService *m_instance;
friend struct QQmlBindingProfiler;
friend struct QQmlHandlingSignalProfiler;
friend struct QQmlVmeProfiler;
friend struct QQmlCompilingProfiler;
- friend struct QQmlPixmapProfiler;
};
//
@@ -238,64 +388,53 @@ private:
struct QQmlBindingProfiler {
QQmlBindingProfiler(const QString &url, int line, int column, QQmlProfilerService::BindingType bindingType)
{
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::instance->startRange(QQmlProfilerService::Binding, bindingType);
- QQmlProfilerService::instance->rangeLocation(QQmlProfilerService::Binding, url, line, column);
- }
+ Q_QML_PROFILE(startBinding(url, line, column, bindingType));
}
~QQmlBindingProfiler()
{
- if (QQmlProfilerService::enabled)
- QQmlProfilerService::instance->endRange(QQmlProfilerService::Binding);
+ Q_QML_PROFILE(endRange<QQmlProfilerService::Binding>());
}
};
struct QQmlHandlingSignalProfiler {
QQmlHandlingSignalProfiler(QQmlBoundSignalExpression *expression)
{
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService *service = QQmlProfilerService::instance;
- service->startRange(QQmlProfilerService::HandlingSignal);
- if (expression->sourceFile().isEmpty()) {
- QV4::Function *function = expression->function();
- if (function) {
- service->rangeLocation(QQmlProfilerService::HandlingSignal,
- function->sourceFile(), function->compiledFunction->location.line,
- function->compiledFunction->location.column);
- }
+ Q_QML_PROFILE_IF_ENABLED({
+ QV4::Function *function;
+ if (expression->sourceFile().isEmpty() && (function = expression->function())) {
+ QQmlProfilerService::startHandlingSignal(
+ function->sourceFile(), function->compiledFunction->location.line,
+ function->compiledFunction->location.column);
+
} else {
- service->rangeLocation(QQmlProfilerService::HandlingSignal,
+ QQmlProfilerService::startHandlingSignal(
expression->sourceFile(), expression->lineNumber(),
expression->columnNumber());
}
- }
+ });
}
~QQmlHandlingSignalProfiler()
{
- if (QQmlProfilerService::enabled)
- QQmlProfilerService::instance->endRange(QQmlProfilerService::HandlingSignal);
+ Q_QML_PROFILE(endRange<QQmlProfilerService::HandlingSignal>());
}
};
struct QQmlCompilingProfiler {
QQmlCompilingProfiler(const QString &name)
{
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::instance->startRange(QQmlProfilerService::Compiling);
- QQmlProfilerService::instance->rangeLocation(QQmlProfilerService::Compiling, name, 1, 1);
- QQmlProfilerService::instance->rangeData(QQmlProfilerService::Compiling, name);
- }
+ Q_QML_PROFILE(startCompiling(name));
}
~QQmlCompilingProfiler()
{
- if (QQmlProfilerService::enabled)
- QQmlProfilerService::instance->endRange(QQmlProfilerService::Compiling);
+ Q_QML_PROFILE(endRange<QQmlProfilerService::Compiling>());
}
};
+#define Q_QML_VME_PROFILE(Method) Q_QML_PROFILE_IF_ENABLED(Method)
+
struct QQmlVmeProfiler {
public:
@@ -305,72 +444,94 @@ public:
int line;
int column;
QString typeName;
- void clear();
};
- QQmlVmeProfiler() :
- running(false)
- {}
+ QQmlVmeProfiler() : running(false) {}
- ~QQmlVmeProfiler()
+ void clear()
{
- if (QQmlProfilerService::enabled)
- clear();
+ ranges.clear();
+ if (running)
+ QQmlProfilerService::m_instance->endRange<QQmlProfilerService::Creating>();
+ for (int i = 0; i < backgroundRanges.count(); ++i) {
+ QQmlProfilerService::m_instance->endRange<QQmlProfilerService::Creating>();
+ }
+ backgroundRanges.clear();
+ running = false;
}
- void clear();
-
- bool start();
- void stop();
-
- void updateLocation(const QUrl &url, int line, int column);
- void updateTypeName(const QString &typeName);
-
- void pop();
- void push();
-
- void background();
- bool foreground();
-
-private:
+ void startBackground(const QString &typeName)
+ {
+ if (running) {
+ QQmlProfilerService::m_instance->endRange<QQmlProfilerService::Creating>();
+ running = false;
+ }
+ QQmlProfilerService::m_instance->startCreating(typeName);
+ backgroundRanges.push(typeName);
+ }
- Data currentRange;
- QStack<Data> ranges;
- QStack<Data> backgroundRanges;
- bool running;
-};
+ void start(const QString &typeName, const QUrl &url, int line, int column)
+ {
+ switchRange();
+ setCurrentRange(typeName, url, line, column);
+ QQmlProfilerService::m_instance->startCreating(typeName, url, line, column);
+ }
-struct QQmlPixmapProfiler {
- void startLoading(const QUrl &pixmapUrl) {
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapLoadingStarted, pixmapUrl);
+ void stop()
+ {
+ if (running) {
+ QQmlProfilerService::m_instance->endRange<QQmlProfilerService::Creating>();
+ running = false;
}
}
- void finishLoading(const QUrl &pixmapUrl) {
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapLoadingFinished, pixmapUrl);
+
+ void pop()
+ {
+ if (ranges.count() > 0) {
+ switchRange();
+ currentRange = ranges.pop();
+ QQmlProfilerService::m_instance->startCreating(currentRange.typeName, currentRange.url,
+ currentRange.line, currentRange.column);
}
}
- void errorLoading(const QUrl &pixmapUrl) {
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapLoadingError, pixmapUrl);
- }
+
+ void push()
+ {
+ if (running)
+ ranges.push(currentRange);
}
- void cacheCountChanged(const QUrl &pixmapUrl, int cacheCount) {
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapCacheCountChanged, pixmapUrl, cacheCount);
+
+ void foreground(const QUrl &url, int line, int column)
+ {
+ if (backgroundRanges.count() > 0) {
+ switchRange();
+ setCurrentRange(backgroundRanges.pop(), url, line, column);
+ QQmlProfilerService::m_instance->creatingLocation(url, line, column);
}
}
- void referenceCountChanged(const QUrl &pixmapUrl, int referenceCount) {
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapReferenceCountChanged, pixmapUrl, referenceCount);
- }
+
+private:
+
+ void switchRange()
+ {
+ if (running)
+ QQmlProfilerService::m_instance->endRange<QQmlProfilerService::Creating>();
+ else
+ running = true;
}
- void setSize(const QUrl &pixmapUrl, const QSize &size) {
- if (QQmlProfilerService::enabled && size.width() > 0) {
- QQmlProfilerService::instance->pixmapEventImpl(QQmlProfilerService::PixmapSizeKnown, pixmapUrl, size.width(), size.height());
- }
+
+ void setCurrentRange(const QString &typeName, const QUrl &url, int line, int column)
+ {
+ currentRange.typeName = typeName;
+ currentRange.url = url;
+ currentRange.line = line;
+ currentRange.column = column;
}
+
+ Data currentRange;
+ QStack<Data> ranges;
+ QStack<QString> backgroundRanges;
+ bool running;
};
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qv4debugservice.cpp b/src/qml/debugger/qv4debugservice.cpp
index 372a51e997..8e81d6e24e 100644
--- a/src/qml/debugger/qv4debugservice.cpp
+++ b/src/qml/debugger/qv4debugservice.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "qv4debugservice_p.h"
-#include "qqmldebugservice_p_p.h"
+#include "qqmlconfigurabledebugservice_p_p.h"
#include "qqmlengine.h"
#include "qv4debugging_p.h"
#include "qv4engine_p.h"
@@ -358,7 +358,7 @@ private:
QHash<QV4::Object *, int> objectRefs;
};
-class QV4DebugServicePrivate : public QQmlDebugServicePrivate
+class QV4DebugServicePrivate : public QQmlConfigurableDebugServicePrivate
{
Q_DECLARE_PUBLIC(QV4DebugService)
@@ -393,8 +393,6 @@ public:
void processCommand(const QByteArray &command, const QByteArray &data);
- QMutex initializeMutex;
- QWaitCondition initializeCondition;
QV4DebuggerAgent debuggerAgent;
QStringList breakOnSignals;
@@ -999,19 +997,9 @@ V8CommandHandler *QV4DebugServicePrivate::v8CommandHandler(const QString &comman
}
QV4DebugService::QV4DebugService(QObject *parent)
- : QQmlDebugService(*(new QV4DebugServicePrivate()),
+ : QQmlConfigurableDebugService(*(new QV4DebugServicePrivate()),
QStringLiteral("V8Debugger"), 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()
{
@@ -1022,10 +1010,10 @@ QV4DebugService *QV4DebugService::instance()
return v4ServiceInstance();
}
-void QV4DebugService::addEngine(const QQmlEngine *engine)
+void QV4DebugService::engineAboutToBeAdded(QQmlEngine *engine)
{
Q_D(QV4DebugService);
-
+ QMutexLocker lock(configMutex());
if (engine) {
QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
if (QQmlDebugServer *server = QQmlDebugServer::instance()) {
@@ -1039,11 +1027,13 @@ void QV4DebugService::addEngine(const QQmlEngine *engine)
}
}
}
+ QQmlConfigurableDebugService::engineAboutToBeAdded(engine);
}
-void QV4DebugService::removeEngine(const QQmlEngine *engine)
+void QV4DebugService::engineAboutToBeRemoved(QQmlEngine *engine)
{
Q_D(QV4DebugService);
+ QMutexLocker lock(configMutex());
if (engine){
const QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
if (ee) {
@@ -1059,6 +1049,7 @@ void QV4DebugService::removeEngine(const QQmlEngine *engine)
d->debuggerAgent.removeDebugger(debugger);
}
}
+ QQmlConfigurableDebugService::engineAboutToBeRemoved(engine);
}
void QV4DebugService::signalEmitted(const QString &signal)
@@ -1080,22 +1071,10 @@ void QV4DebugService::signalEmitted(const QString &signal)
}
}
-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);
+ QMutexLocker lock(configMutex());
QQmlDebugStream ms(message);
QByteArray header;
@@ -1111,7 +1090,7 @@ void QV4DebugService::messageReceived(const QByteArray &message)
if (type == V4_CONNECT) {
sendMessage(d->packMessage(type));
- d->initializeCondition.wakeAll();
+ stopWaiting();
} else if (type == V4_PAUSE) {
d->debuggerAgent.pauseAll();
sendSomethingToSomebody(type);
diff --git a/src/qml/debugger/qv4debugservice_p.h b/src/qml/debugger/qv4debugservice_p.h
index e35010bebf..d63d5fae1c 100644
--- a/src/qml/debugger/qv4debugservice_p.h
+++ b/src/qml/debugger/qv4debugservice_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include "qqmldebugservice_p.h"
+#include "qqmlconfigurabledebugservice_p.h"
QT_BEGIN_NAMESPACE
@@ -61,7 +61,7 @@ namespace QV4 { struct ExecutionEngine; }
class QQmlEngine;
class QV4DebugServicePrivate;
-class QV4DebugService : public QQmlDebugService
+class QV4DebugService : public QQmlConfigurableDebugService
{
Q_OBJECT
public:
@@ -69,13 +69,12 @@ public:
~QV4DebugService();
static QV4DebugService *instance();
- void addEngine(const QQmlEngine *engine);
- void removeEngine(const QQmlEngine *engine);
+ void engineAboutToBeAdded(QQmlEngine *engine);
+ void engineAboutToBeRemoved(QQmlEngine *engine);
void signalEmitted(const QString &signal);
protected:
- void stateChanged(State newState);
void messageReceived(const QByteArray &);
void sendSomethingToSomebody(const char *type, int magicNumber = 1);
diff --git a/src/qml/debugger/qv8profilerservice.cpp b/src/qml/debugger/qv4profilerservice.cpp
index 7b9331da66..d8f69aecd9 100644
--- a/src/qml/debugger/qv8profilerservice.cpp
+++ b/src/qml/debugger/qv4profilerservice.cpp
@@ -39,9 +39,8 @@
**
****************************************************************************/
-#include "qv8profilerservice_p.h"
-#include "qqmldebugservice_p_p.h"
-#include <private/qv8profiler_p.h>
+#include "qv4profilerservice_p.h"
+#include "qqmlconfigurabledebugservice_p_p.h"
#include <QtCore/QHash>
#include <QtCore/QMutex>
@@ -49,7 +48,7 @@
QT_BEGIN_NAMESPACE
-Q_GLOBAL_STATIC(QV8ProfilerService, v8ProfilerInstance)
+Q_GLOBAL_STATIC(QV4ProfilerService, v4ProfilerInstance)
#if 0
// ### FIXME: v4
@@ -63,7 +62,7 @@ public:
{
QByteArray data;
QQmlDebugStream ds(&data, QIODevice::WriteOnly);
- ds << QV8ProfilerService::V8SnapshotChunk << QByteArray(rawData, size);
+ ds << QV4ProfilerService::V4SnapshotChunk << QByteArray(rawData, size);
messages.append(data);
return kContinue;
}
@@ -72,7 +71,7 @@ public:
#endif
// convert to a QByteArray that can be sent to the debug client
-QByteArray QV8ProfilerData::toByteArray() const
+QByteArray QV4ProfilerData::toByteArray() const
{
QByteArray data;
//### using QDataStream is relatively expensive
@@ -82,12 +81,12 @@ QByteArray QV8ProfilerData::toByteArray() const
return data;
}
-class QV8ProfilerServicePrivate : public QQmlDebugServicePrivate
+class QV4ProfilerServicePrivate : public QQmlConfigurableDebugServicePrivate
{
- Q_DECLARE_PUBLIC(QV8ProfilerService)
+ Q_DECLARE_PUBLIC(QV4ProfilerService)
public:
- QV8ProfilerServicePrivate()
+ QV4ProfilerServicePrivate()
:initialized(false)
{
}
@@ -97,46 +96,30 @@ public:
// void printProfileTree(const v8::CpuProfileNode *node, int level = 0);
// void sendMessages();
- QList<QV8ProfilerData> m_data;
+ QList<QV4ProfilerData> m_data;
bool initialized;
- QMutex initializeMutex;
- QWaitCondition initializeCondition;
QList<QString> m_ongoing;
};
-QV8ProfilerService::QV8ProfilerService(QObject *parent)
- : QQmlDebugService(*(new QV8ProfilerServicePrivate()), QStringLiteral("V8Profiler"), 1, parent)
+QV4ProfilerService::QV4ProfilerService(QObject *parent)
+ : QQmlConfigurableDebugService(*(new QV4ProfilerServicePrivate()), QStringLiteral("V8Profiler"), 1, parent)
{
- Q_D(QV8ProfilerService);
-
- QMutexLocker lock(&d->initializeMutex);
-
- if (registerService() == Enabled
- && QQmlDebugService::blockingMode()) {
- // let's wait for first message ...
- d->initializeCondition.wait(&d->initializeMutex);
- }
}
-QV8ProfilerService::~QV8ProfilerService()
+QV4ProfilerService::~QV4ProfilerService()
{
}
-QV8ProfilerService *QV8ProfilerService::instance()
+QV4ProfilerService *QV4ProfilerService::instance()
{
- return v8ProfilerInstance();
+ return v4ProfilerInstance();
}
-void QV8ProfilerService::initialize()
+void QV4ProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState)
{
- // just make sure that the service is properly registered
- v8ProfilerInstance();
-}
-
-void QV8ProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState)
-{
- Q_D(QV8ProfilerService);
+ Q_D(QV4ProfilerService);
+ QMutexLocker lock(configMutex());
if (state() == newState)
return;
@@ -147,16 +130,12 @@ void QV8ProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState)
Q_ARG(QString, title));
}
QMetaObject::invokeMethod(this, "sendProfilingData", Qt::BlockingQueuedConnection);
- } else {
- // wake up constructor in blocking mode
- // (we might got disabled before first message arrived)
- d->initializeCondition.wakeAll();
}
}
-void QV8ProfilerService::messageReceived(const QByteArray &message)
+void QV4ProfilerService::messageReceived(const QByteArray &message)
{
- Q_D(QV8ProfilerService);
+ Q_D(QV4ProfilerService);
QQmlDebugStream ds(message);
QByteArray command;
@@ -164,7 +143,7 @@ void QV8ProfilerService::messageReceived(const QByteArray &message)
QByteArray title;
ds >> command >> option;
- QMutexLocker lock(&d->initializeMutex);
+ QMutexLocker lock(configMutex());
if (command == "V8PROFILER") {
ds >> title;
@@ -187,14 +166,14 @@ void QV8ProfilerService::messageReceived(const QByteArray &message)
}
// wake up constructor in blocking mode
- d->initializeCondition.wakeAll();
+ stopWaiting();
QQmlDebugService::messageReceived(message);
}
-void QV8ProfilerService::startProfiling(const QString &title)
+void QV4ProfilerService::startProfiling(const QString &title)
{
- Q_D(QV8ProfilerService);
+ Q_D(QV4ProfilerService);
// Start Profiling
if (d->m_ongoing.contains(title))
@@ -209,14 +188,14 @@ void QV8ProfilerService::startProfiling(const QString &title)
// indicate profiling started
QByteArray data;
QQmlDebugStream ds(&data, QIODevice::WriteOnly);
- ds << (int)QV8ProfilerService::V8Started;
+ ds << (int)QV4ProfilerService::V4Started;
sendMessage(data);
}
-void QV8ProfilerService::stopProfiling(const QString &title)
+void QV4ProfilerService::stopProfiling(const QString &title)
{
- Q_D(QV8ProfilerService);
+ Q_D(QV4ProfilerService);
// Stop profiling
if (!d->m_ongoing.contains(title))
@@ -237,7 +216,7 @@ void QV8ProfilerService::stopProfiling(const QString &title)
// indicate completion, even without data
QByteArray data;
QQmlDebugStream ds(&data, QIODevice::WriteOnly);
- ds << (int)QV8ProfilerService::V8Complete;
+ ds << (int)QV4ProfilerService::V4Complete;
sendMessage(data);
#if 0
@@ -245,22 +224,22 @@ void QV8ProfilerService::stopProfiling(const QString &title)
#endif
}
-void QV8ProfilerService::takeSnapshot()
+void QV4ProfilerService::takeSnapshot()
{
-// Q_D(QV8ProfilerService);
+// Q_D(QV4ProfilerService);
// ### FIXME: v4
// d->takeSnapshot(v8::HeapSnapshot::kFull);
}
-void QV8ProfilerService::deleteSnapshots()
+void QV4ProfilerService::deleteSnapshots()
{
// ### FIXME: v4
// v8::HeapProfiler::DeleteAllSnapshots();
}
-void QV8ProfilerService::sendProfilingData()
+void QV4ProfilerService::sendProfilingData()
{
-// Q_D(QV8ProfilerService);
+// Q_D(QV4ProfilerService);
// Send messages to client
// ### FIXME: v4
// d->sendMessages();
@@ -268,14 +247,14 @@ void QV8ProfilerService::sendProfilingData()
#if 0
// ### FIXME: v4
-void QV8ProfilerServicePrivate::printProfileTree(const v8::CpuProfileNode *node, int level)
+void QV4ProfilerServicePrivate::printProfileTree(const v8::CpuProfileNode *node, int level)
{
for (int index = 0 ; index < node->GetChildrenCount() ; index++) {
const v8::CpuProfileNode* childNode = node->GetChild(index);
QString scriptResourceName = QJSConverter::toString(childNode->GetScriptResourceName());
if (scriptResourceName.length() > 0) {
- QV8ProfilerData rd = {(int)QV8ProfilerService::V8Entry, scriptResourceName,
+ QV4ProfilerData rd = {(int)QV4ProfilerService::V4Entry, scriptResourceName,
QJSConverter::toString(childNode->GetFunctionName()),
childNode->GetLineNumber(), childNode->GetTotalTime(), childNode->GetSelfTime(), level};
m_data.append(rd);
@@ -288,9 +267,9 @@ void QV8ProfilerServicePrivate::printProfileTree(const v8::CpuProfileNode *node,
}
}
-void QV8ProfilerServicePrivate::takeSnapshot(v8::HeapSnapshot::Type snapshotType)
+void QV4ProfilerServicePrivate::takeSnapshot(v8::HeapSnapshot::Type snapshotType)
{
- Q_Q(QV8ProfilerService);
+ Q_Q(QV4ProfilerService);
v8::HandleScope scope;
v8::Handle<v8::String> title = v8::String::New("");
@@ -303,15 +282,15 @@ void QV8ProfilerServicePrivate::takeSnapshot(v8::HeapSnapshot::Type snapshotType
//indicate completion
QByteArray data;
QQmlDebugStream ds(&data, QIODevice::WriteOnly);
- ds << (int)QV8ProfilerService::V8SnapshotComplete;
+ ds << (int)QV4ProfilerService::V4SnapshotComplete;
messages.append(data);
q->sendMessages(messages);
}
-void QV8ProfilerServicePrivate::sendMessages()
+void QV4ProfilerServicePrivate::sendMessages()
{
- Q_Q(QV8ProfilerService);
+ Q_Q(QV4ProfilerService);
QList<QByteArray> messages;
for (int i = 0; i < m_data.count(); ++i)
@@ -321,7 +300,7 @@ void QV8ProfilerServicePrivate::sendMessages()
//indicate completion
QByteArray data;
QQmlDebugStream ds(&data, QIODevice::WriteOnly);
- ds << (int)QV8ProfilerService::V8Complete;
+ ds << (int)QV4ProfilerService::V4Complete;
messages.append(data);
q->sendMessages(messages);
diff --git a/src/qml/debugger/qv8profilerservice_p.h b/src/qml/debugger/qv4profilerservice_p.h
index 60dc70f4db..b1a58dae03 100644
--- a/src/qml/debugger/qv8profilerservice_p.h
+++ b/src/qml/debugger/qv4profilerservice_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QV8PROFILERSERVICE_P_H
-#define QV8PROFILERSERVICE_P_H
+#ifndef QV4PROFILERSERVICE_P_H
+#define QV4PROFILERSERVICE_P_H
//
// W A R N I N G
@@ -53,12 +53,12 @@
// We mean it.
//
-#include <private/qqmldebugservice_p.h>
+#include <private/qqmlconfigurabledebugservice_p.h>
QT_BEGIN_NAMESPACE
-struct Q_AUTOTEST_EXPORT QV8ProfilerData
+struct Q_AUTOTEST_EXPORT QV4ProfilerData
{
int messageType;
QString filename;
@@ -72,27 +72,26 @@ struct Q_AUTOTEST_EXPORT QV8ProfilerData
};
class QQmlEngine;
-class QV8ProfilerServicePrivate;
+class QV4ProfilerServicePrivate;
-class Q_AUTOTEST_EXPORT QV8ProfilerService : public QQmlDebugService
+class Q_AUTOTEST_EXPORT QV4ProfilerService : public QQmlConfigurableDebugService
{
Q_OBJECT
public:
enum MessageType {
- V8Entry,
- V8Complete,
- V8SnapshotChunk,
- V8SnapshotComplete,
- V8Started,
+ V4Entry,
+ V4Complete,
+ V4SnapshotChunk,
+ V4SnapshotComplete,
+ V4Started,
- V8MaximumMessage
+ V4MaximumMessage
};
- QV8ProfilerService(QObject *parent = 0);
- ~QV8ProfilerService();
+ QV4ProfilerService(QObject *parent = 0);
+ ~QV4ProfilerService();
- static QV8ProfilerService *instance();
- static void initialize();
+ static QV4ProfilerService *instance();
public Q_SLOTS:
void startProfiling(const QString &title);
@@ -107,10 +106,10 @@ protected:
void messageReceived(const QByteArray &);
private:
- Q_DISABLE_COPY(QV8ProfilerService)
- Q_DECLARE_PRIVATE(QV8ProfilerService)
+ Q_DISABLE_COPY(QV4ProfilerService)
+ Q_DECLARE_PRIVATE(QV4ProfilerService)
};
QT_END_NAMESPACE
-#endif // QV8PROFILERSERVICE_P_H
+#endif // QV4PROFILERSERVICE_P_H
diff --git a/src/qml/doc/snippets/delegatemodel/visualdatamodel_rootindex/view.qml b/src/qml/doc/snippets/delegatemodel/visualdatamodel_rootindex/view.qml
index 1e8cfade96..f46671e9a0 100644
--- a/src/qml/doc/snippets/delegatemodel/visualdatamodel_rootindex/view.qml
+++ b/src/qml/doc/snippets/delegatemodel/visualdatamodel_rootindex/view.qml
@@ -55,7 +55,7 @@ ListView {
MouseArea {
anchors.fill: parent
onClicked: {
- if (model.hasModelChildren)
+ if (model.hasModelChildren)
view.model.rootIndex = view.model.modelIndex(index)
}
}
diff --git a/src/qml/doc/snippets/qml/SelfDestroyingRect.qml b/src/qml/doc/snippets/qml/SelfDestroyingRect.qml
index b2e8c318f2..16a73c204d 100644
--- a/src/qml/doc/snippets/qml/SelfDestroyingRect.qml
+++ b/src/qml/doc/snippets/qml/SelfDestroyingRect.qml
@@ -45,9 +45,9 @@ Rectangle {
width: 80; height: 80
color: "red"
- NumberAnimation on opacity {
+ NumberAnimation on opacity {
to: 0
- duration: 1000
+ duration: 1000
onRunningChanged: {
if (!running) {
diff --git a/src/qml/doc/snippets/qml/createQmlObject.qml b/src/qml/doc/snippets/qml/createQmlObject.qml
index 7984261f0f..10f49f13c3 100644
--- a/src/qml/doc/snippets/qml/createQmlObject.qml
+++ b/src/qml/doc/snippets/qml/createQmlObject.qml
@@ -45,7 +45,7 @@ Rectangle {
width: 100
height: 100
-
+
function createIt() {
//![0]
var newObject = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: "red"; width: 20; height: 20}',
diff --git a/src/qml/doc/snippets/qml/listmodel/listmodel-nested.qml b/src/qml/doc/snippets/qml/listmodel/listmodel-nested.qml
index c9637712f6..3c836d81cf 100644
--- a/src/qml/doc/snippets/qml/listmodel/listmodel-nested.qml
+++ b/src/qml/doc/snippets/qml/listmodel/listmodel-nested.qml
@@ -86,7 +86,7 @@ Component {
Text { text: "Attributes:" }
Repeater {
model: attributes
- Text { text: description }
+ Text { text: description }
}
}
}
diff --git a/src/qml/doc/snippets/qml/qml-documents/inline-component.qml b/src/qml/doc/snippets/qml/qml-documents/inline-component.qml
index 5b600499c4..b8144c263f 100644
--- a/src/qml/doc/snippets/qml/qml-documents/inline-component.qml
+++ b/src/qml/doc/snippets/qml/qml-documents/inline-component.qml
@@ -42,7 +42,7 @@
import QtQuick 2.0
Rectangle {
- width: 240; height: 320;
+ width: 240; height: 320;
ListView {
anchors.fill: parent
@@ -52,6 +52,6 @@ Rectangle {
text: modelData.firstName + " " + modelData.lastName
}
}
- }
+ }
}
//! [document]
diff --git a/src/qml/doc/snippets/qml/qml-documents/inline-text-component.qml b/src/qml/doc/snippets/qml/qml-documents/inline-text-component.qml
index 44d67a7480..e731ce998f 100644
--- a/src/qml/doc/snippets/qml/qml-documents/inline-text-component.qml
+++ b/src/qml/doc/snippets/qml/qml-documents/inline-text-component.qml
@@ -42,7 +42,7 @@
import QtQuick 2.0
Rectangle {
- width: 240; height: 320;
+ width: 240; height: 320;
ListView {
anchors.fill: parent
@@ -50,6 +50,6 @@ Rectangle {
delegate: Text {
text: modelData.firstName + " " + modelData.lastName
}
- }
+ }
}
//! [document]
diff --git a/src/qml/doc/snippets/qml/qml-documents/non-trivial.qml b/src/qml/doc/snippets/qml/qml-documents/non-trivial.qml
index ccf4603b44..cedd09d3ce 100644
--- a/src/qml/doc/snippets/qml/qml-documents/non-trivial.qml
+++ b/src/qml/doc/snippets/qml/qml-documents/non-trivial.qml
@@ -42,7 +42,7 @@
import QtQuick 2.0
Rectangle {
- width: 240; height: 320;
+ width: 240; height: 320;
resources: [
Component {
@@ -57,6 +57,6 @@ Rectangle {
anchors.fill: parent
model: contactModel
delegate: contactDelegate
- }
+ }
}
//! [document]
diff --git a/src/qml/doc/snippets/qml/qml-documents/qmldocuments.qml b/src/qml/doc/snippets/qml/qml-documents/qmldocuments.qml
index 66322fdfd1..fd582db061 100644
--- a/src/qml/doc/snippets/qml/qml-documents/qmldocuments.qml
+++ b/src/qml/doc/snippets/qml/qml-documents/qmldocuments.qml
@@ -45,7 +45,7 @@ Rectangle {
property alias text: textItem.text
width: 100; height: 30
- border.width: 1
+ border.width: 1
radius: 5
antialiasing: true
diff --git a/src/qml/doc/snippets/qml/qtobject.qml b/src/qml/doc/snippets/qml/qtobject.qml
index 7d0957326e..6fdf7f74d3 100644
--- a/src/qml/doc/snippets/qml/qtobject.qml
+++ b/src/qml/doc/snippets/qml/qtobject.qml
@@ -41,7 +41,7 @@
import QtQuick 2.0
Item {
- QtObject {
+ QtObject {
id: attributes
property string name
property int size
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 4cc3796541..38a8e40cb2 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -45,7 +45,7 @@
#include "qjsengine.h"
#include "qjsvalue.h"
#include "qjsvalue_p.h"
-#include "qv4value_p.h"
+#include "qv4value_inl_p.h"
#include "qv4object_p.h"
#include "qv4functionobject_p.h"
#include "qv4dateobject_p.h"
@@ -1028,7 +1028,7 @@ bool QJSValue::hasProperty(const QString &name) const
return false;
ScopedString s(scope, engine->newIdentifier(name));
- return o->__hasProperty__(s);
+ return o->hasProperty(s);
}
/*!
@@ -1049,7 +1049,7 @@ bool QJSValue::hasOwnProperty(const QString &name) const
return false;
ScopedString s(scope, engine->newIdentifier(name));
- return o->__getOwnProperty__(s);
+ return o->hasOwnProperty(s);
}
/*!
diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h
index d8da664cc6..41856b1e98 100644
--- a/src/qml/jsapi/qjsvalue_p.h
+++ b/src/qml/jsapi/qjsvalue_p.h
@@ -55,7 +55,7 @@
#include <qjsvalue.h>
#include <private/qtqmlglobal_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4string_p.h>
#include <private/qv4engine_p.h>
#include <private/qv4object_p.h>
diff --git a/src/qml/jsapi/qjsvalueiterator.cpp b/src/qml/jsapi/qjsvalueiterator.cpp
index ed011ef691..e3358b29bd 100644
--- a/src/qml/jsapi/qjsvalueiterator.cpp
+++ b/src/qml/jsapi/qjsvalueiterator.cpp
@@ -109,7 +109,7 @@ QJSValueIterator::QJSValueIterator(const QJSValue& object)
QV4::Scope scope(v4);
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
it->it.flags = QV4::ObjectIterator::NoFlags;
- it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+ it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
}
/*!
@@ -150,6 +150,7 @@ bool QJSValueIterator::next()
return false;
d_ptr->currentName = d_ptr->nextName;
d_ptr->currentIndex = d_ptr->nextIndex;
+ d_ptr->currentProperty = d_ptr->nextProperty;
d_ptr->currentAttributes = d_ptr->nextAttributes;
QV4::ExecutionEngine *v4 = d_ptr->iterator.engine();
@@ -157,7 +158,7 @@ bool QJSValueIterator::next()
return false;
QV4::Scope scope(v4);
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
- it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+ it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
return !!d_ptr->nextName || d_ptr->nextIndex != UINT_MAX;
}
@@ -187,27 +188,19 @@ QString QJSValueIterator::name() const
*/
QJSValue QJSValueIterator::value() const
{
- if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
- return QJSValue();
-
QV4::ExecutionEngine *engine = d_ptr->iterator.engine();
if (!engine)
return QJSValue();
-
QV4::Scope scope(engine);
- QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
- QV4::ScopedObject o(scope, it->it.object);
+ QV4::ScopedObject obj(scope, QJSValuePrivate::get(d_ptr->value)->value);
+ if (!obj)
+ return QJSValue();
QV4::ExecutionContext *ctx = engine->currentContext();
- QV4::ScopedValue v(scope);
- if (!!d_ptr->currentName) {
- QV4::ScopedString n(scope, d_ptr->currentName);
- v = o->get(n);
- } else if (d_ptr->currentIndex != UINT_MAX) {
- v = o->getIndexed(d_ptr->currentIndex);
- } else {
+ if (!d_ptr->currentName && d_ptr->currentIndex == UINT_MAX)
return QJSValue();
- }
+
+ QV4::ScopedValue v(scope, obj->getValue(obj, &d_ptr->currentProperty, d_ptr->currentAttributes));
if (scope.hasException()) {
ctx->catchException();
return QJSValue();
@@ -240,7 +233,7 @@ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
d_ptr->iterator = v4->newForEachIteratorObject(v4->currentContext(), o)->asReturnedValue();
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
it->it.flags = QV4::ObjectIterator::NoFlags;
- it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+ it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes);
return *this;
}
diff --git a/src/qml/jsapi/qjsvalueiterator_p.h b/src/qml/jsapi/qjsvalueiterator_p.h
index b7a9b4a190..882c779c00 100644
--- a/src/qml/jsapi/qjsvalueiterator_p.h
+++ b/src/qml/jsapi/qjsvalueiterator_p.h
@@ -56,11 +56,13 @@ public:
QJSValue value;
QV4::PersistentValue iterator;
+ QV4::Property currentProperty;
QV4::PropertyAttributes currentAttributes;
- QV4::SafeString currentName;
+ QV4::StringValue currentName;
uint currentIndex;
+ QV4::Property nextProperty;
QV4::PropertyAttributes nextAttributes;
- QV4::SafeString nextName;
+ QV4::StringValue nextName;
uint nextIndex;
};
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index 94983f51e5..43eb61ac9a 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -6,6 +6,7 @@ SOURCES += \
$$PWD/qv4context.cpp \
$$PWD/qv4runtime.cpp \
$$PWD/qv4value.cpp \
+ $$PWD/qv4persistent.cpp \
$$PWD/qv4debugging.cpp \
$$PWD/qv4lookup.cpp \
$$PWD/qv4identifier.cpp \
@@ -14,6 +15,7 @@ SOURCES += \
$$PWD/qv4managed.cpp \
$$PWD/qv4internalclass.cpp \
$$PWD/qv4sparsearray.cpp \
+ $$PWD/qv4arraydata.cpp \
$$PWD/qv4arrayobject.cpp \
$$PWD/qv4argumentsobject.cpp \
$$PWD/qv4booleanobject.cpp \
@@ -48,8 +50,9 @@ HEADERS += \
$$PWD/qv4context_p.h \
$$PWD/qv4runtime_p.h \
$$PWD/qv4math_p.h \
+ $$PWD/qv4value_inl_p.h \
$$PWD/qv4value_p.h \
- $$PWD/qv4value_def_p.h \
+ $$PWD/qv4persistent_p.h \
$$PWD/qv4debugging_p.h \
$$PWD/qv4lookup_p.h \
$$PWD/qv4identifier_p.h \
@@ -58,6 +61,7 @@ HEADERS += \
$$PWD/qv4managed_p.h \
$$PWD/qv4internalclass_p.h \
$$PWD/qv4sparsearray_p.h \
+ $$PWD/qv4arraydata_p.h \
$$PWD/qv4arrayobject_p.h \
$$PWD/qv4argumentsobject_p.h \
$$PWD/qv4booleanobject_p.h \
diff --git a/src/qml/jsruntime/qv4alloca_p.h b/src/qml/jsruntime/qv4alloca_p.h
index e51c6dff00..a76c327b04 100644
--- a/src/qml/jsruntime/qv4alloca_p.h
+++ b/src/qml/jsruntime/qv4alloca_p.h
@@ -49,10 +49,8 @@
# ifndef __GNUC__
# define alloca _alloca
# endif
-#else
-#if !defined(__FreeBSD__) && !defined(__DragonFly__)
+#elif !defined(Q_OS_BSD4) || defined(Q_OS_DARWIN)
# include <alloca.h>
#endif
-#endif
#endif
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 629c255b48..5dedd59770 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -44,20 +44,19 @@
using namespace QV4;
-DEFINE_MANAGED_VTABLE(ArgumentsObject);
+DEFINE_OBJECT_VTABLE(ArgumentsObject);
ArgumentsObject::ArgumentsObject(CallContext *context)
: Object(context->strictMode ? context->engine->strictArgumentsObjectClass : context->engine->argumentsObjectClass)
, context(context)
, fullyCreated(false)
{
- type = Type_ArgumentsObject;
- flags &= ~SimpleArray;
-
ExecutionEngine *v4 = context->engine;
Scope scope(v4);
ScopedObject protectThis(scope, this);
+ setArrayType(ArrayData::Complex);
+
if (context->strictMode) {
Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee));
@@ -66,20 +65,18 @@ ArgumentsObject::ArgumentsObject(CallContext *context)
memberData[CallerPropertyIndex] = pd;
arrayReserve(context->callData->argc);
- for (int i = 0; i < context->callData->argc; ++i)
- arrayData[i].value = context->callData->args[i];
- arrayDataLen = context->callData->argc;
+ arrayPut(0, context->callData->args, context->callData->argc);
fullyCreated = true;
} else {
+ hasAccessorProperty = 1;
Q_ASSERT(CalleePropertyIndex == internalClass->find(context->engine->id_callee));
memberData[CalleePropertyIndex].value = context->function->asReturnedValue();
- isNonStrictArgumentsObject = true;
}
Q_ASSERT(LengthPropertyIndex == internalClass->find(context->engine->id_length));
Property *lp = memberData + ArrayObject::LengthPropertyIndex;
lp->value = Primitive::fromInt32(context->realArgumentCount);
- Q_ASSERT(internalClass->vtable == &static_vtbl);
+ Q_ASSERT(internalClass->vtable == staticVTable());
}
void ArgumentsObject::destroy(Managed *that)
@@ -94,19 +91,15 @@ void ArgumentsObject::fullyCreate()
uint numAccessors = qMin((int)context->function->formalParameterCount, context->realArgumentCount);
uint argCount = qMin(context->realArgumentCount, context->callData->argc);
- arrayReserve(argCount);
- ensureArrayAttributes();
+ ArrayData::realloc(this, ArrayData::Sparse, 0, argCount, true);
context->engine->requireArgumentsAccessors(numAccessors);
for (uint i = 0; i < (uint)numAccessors; ++i) {
mappedArguments.append(context->callData->args[i]);
- arrayData[i] = context->engine->argumentsAccessors.at(i);
- arrayAttributes[i] = Attr_Accessor;
- }
- for (uint i = numAccessors; i < argCount; ++i) {
- arrayData[i] = Property::fromValue(context->callData->args[i]);
- arrayAttributes[i] = Attr_Data;
+ arraySet(i, context->engine->argumentsAccessors.at(i), Attr_Accessor);
}
- arrayDataLen = argCount;
+ arrayPut(numAccessors, context->callData->args + numAccessors, argCount - numAccessors);
+ for (uint i = numAccessors; i < argCount; ++i)
+ setArrayAttributes(i, Attr_Data);
fullyCreated = true;
}
@@ -116,27 +109,25 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
fullyCreate();
Scope scope(ctx);
- uint pidx = propertyIndexFromArrayIndex(index);
- Property *pd = arrayData + pidx;
+ Property *pd = arrayData->getProperty(index);
Property map;
PropertyAttributes mapAttrs;
bool isMapped = false;
if (pd && index < (uint)mappedArguments.size())
- isMapped = arrayAttributes && arrayAttributes[pidx].isAccessor() && pd->getter() == context->engine->argumentsAccessors.at(index).getter();
+ isMapped = arrayData->attributes(index).isAccessor() && pd->getter() == context->engine->argumentsAccessors.at(index).getter();
if (isMapped) {
map = *pd;
- mapAttrs = arrayAttributes[pidx];
- arrayAttributes[pidx] = Attr_Data;
+ mapAttrs = arrayData->attributes(index);
+ setArrayAttributes(index, Attr_Data);
+ pd = arrayData->getProperty(index);
pd->value = mappedArguments.at(index);
}
- isNonStrictArgumentsObject = false;
bool strict = ctx->strictMode;
ctx->strictMode = false;
- bool result = Object::__defineOwnProperty__(ctx, index, desc, attrs);
+ bool result = Object::defineOwnProperty2(ctx, index, desc, attrs);
ctx->strictMode = strict;
- isNonStrictArgumentsObject = true;
if (isMapped && attrs.isData()) {
ScopedCallData callData(scope, 1);
@@ -145,8 +136,9 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
map.setter()->call(callData);
if (attrs.isWritable()) {
+ setArrayAttributes(index, mapAttrs);
+ pd = arrayData->getProperty(index);
*pd = map;
- arrayAttributes[pidx] = mapAttrs;
}
}
@@ -206,7 +198,7 @@ PropertyAttributes ArgumentsObject::queryIndexed(const Managed *m, uint index)
return Attr_Accessor;
}
-DEFINE_MANAGED_VTABLE(ArgumentsGetterFunction);
+DEFINE_OBJECT_VTABLE(ArgumentsGetterFunction);
ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
{
@@ -221,7 +213,7 @@ ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
return o->context->argument(g->index);
}
-DEFINE_MANAGED_VTABLE(ArgumentsSetterFunction);
+DEFINE_OBJECT_VTABLE(ArgumentsSetterFunction);
ReturnedValue ArgumentsSetterFunction::call(Managed *setter, CallData *callData)
{
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index d306fae92b..b50c4f081d 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -50,12 +50,12 @@ namespace QV4 {
struct ArgumentsGetterFunction: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
uint index;
ArgumentsGetterFunction(ExecutionContext *scope, uint index)
: FunctionObject(scope), index(index) {
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
static ReturnedValue call(Managed *that, CallData *d);
@@ -63,12 +63,12 @@ struct ArgumentsGetterFunction: FunctionObject
struct ArgumentsSetterFunction: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
uint index;
ArgumentsSetterFunction(ExecutionContext *scope, uint index)
: FunctionObject(scope), index(index) {
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
static ReturnedValue call(Managed *that, CallData *callData);
@@ -76,13 +76,18 @@ struct ArgumentsSetterFunction: FunctionObject
struct ArgumentsObject: Object {
- Q_MANAGED
+ V4_OBJECT
+ Q_MANAGED_TYPE(ArgumentsObject)
CallContext *context;
bool fullyCreated;
- QVector<SafeValue> mappedArguments;
+ QVector<Value> mappedArguments;
ArgumentsObject(CallContext *context);
~ArgumentsObject() {}
+ static bool isNonStrictArgumentsObject(Managed *m) {
+ return m->internalClass->vtable->type == Type_ArgumentsObject &&
+ !static_cast<ArgumentsObject *>(m)->context->strictMode;
+ }
enum {
LengthPropertyIndex = 0,
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
new file mode 100644
index 0000000000..44727cba17
--- /dev/null
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -0,0 +1,771 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "qv4arraydata_p.h"
+#include "qv4object_p.h"
+#include "qv4functionobject_p.h"
+#include "qv4mm_p.h"
+
+using namespace QV4;
+
+const ArrayVTable SimpleArrayData::static_vtbl =
+{
+ DEFINE_MANAGED_VTABLE_INT(SimpleArrayData),
+ SimpleArrayData::Simple,
+ SimpleArrayData::reallocate,
+ SimpleArrayData::get,
+ SimpleArrayData::put,
+ SimpleArrayData::putArray,
+ SimpleArrayData::del,
+ SimpleArrayData::setAttribute,
+ SimpleArrayData::attribute,
+ SimpleArrayData::push_front,
+ SimpleArrayData::pop_front,
+ SimpleArrayData::truncate,
+ SimpleArrayData::length
+};
+
+const ArrayVTable SparseArrayData::static_vtbl =
+{
+ DEFINE_MANAGED_VTABLE_INT(SparseArrayData),
+ ArrayData::Sparse,
+ SparseArrayData::reallocate,
+ SparseArrayData::get,
+ SparseArrayData::put,
+ SparseArrayData::putArray,
+ SparseArrayData::del,
+ SparseArrayData::setAttribute,
+ SparseArrayData::attribute,
+ SparseArrayData::push_front,
+ SparseArrayData::pop_front,
+ SparseArrayData::truncate,
+ SparseArrayData::length
+};
+
+
+void ArrayData::realloc(Object *o, Type newType, uint offset, uint alloc, bool enforceAttributes)
+{
+ ArrayData *d = o->arrayData;
+
+ uint oldAlloc = 0;
+ uint toCopy = 0;
+ if (alloc < 8)
+ alloc = 8;
+
+ if (d) {
+ bool hasAttrs = d->attrs;
+ enforceAttributes |= hasAttrs;
+
+ if (!offset && alloc <= d->alloc && newType == d->type && hasAttrs == enforceAttributes)
+ return;
+
+ oldAlloc = d->alloc;
+ if (d->type < Sparse) {
+ offset = qMax(offset, static_cast<SimpleArrayData *>(d)->offset);
+ toCopy = static_cast<SimpleArrayData *>(d)->len;
+ } else {
+ Q_ASSERT(!offset);
+ toCopy = d->alloc;
+ newType = Sparse;
+ }
+ }
+ if (enforceAttributes && newType == Simple)
+ newType = Complex;
+
+ alloc = qMax(alloc, 2*oldAlloc) + offset;
+ size_t size = alloc*sizeof(Value);
+ if (enforceAttributes)
+ size += alloc*sizeof(PropertyAttributes);
+
+ if (newType < Sparse) {
+ size += sizeof(SimpleArrayData);
+ SimpleArrayData *newData = static_cast<SimpleArrayData *>(o->engine()->memoryManager->allocManaged(size));
+ new (newData) SimpleArrayData(o->engine());
+ newData->alloc = alloc - offset;
+ newData->type = newType;
+ newData->data = reinterpret_cast<Value *>(newData + 1) + offset;
+ newData->attrs = enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->data + alloc) + offset : 0;
+ newData->offset = offset;
+ newData->len = d ? static_cast<SimpleArrayData *>(d)->len : 0;
+ o->arrayData = newData;
+ } else {
+ size += sizeof(SparseArrayData);
+ SparseArrayData *newData = static_cast<SparseArrayData *>(o->engine()->memoryManager->allocManaged(size));
+ new (newData) SparseArrayData(o->engine());
+ newData->alloc = alloc;
+ newData->type = newType;
+ newData->data = reinterpret_cast<Value *>(newData + 1);
+ newData->attrs = enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->data + alloc) : 0;
+ o->arrayData = newData;
+ }
+
+ if (d) {
+ memcpy(o->arrayData->data, d->data, sizeof(Value)*toCopy);
+ if (enforceAttributes) {
+ if (d->attrs)
+ memcpy(o->arrayData->attrs, d->attrs, sizeof(PropertyAttributes)*toCopy);
+ else
+ for (uint i = 0; i < toCopy; ++i)
+ o->arrayData->attrs[i] = Attr_Data;
+ }
+ }
+
+ if (newType != Sparse)
+ return;
+
+ SparseArrayData *newData = static_cast<SparseArrayData *>(o->arrayData);
+ if (d && d->type == Sparse) {
+ SparseArrayData *old = static_cast<SparseArrayData *>(d);
+ newData->sparse = old->sparse;
+ old->sparse = 0;
+ newData->freeList = old->freeList;
+ return;
+ }
+
+ newData->sparse = new SparseArray;
+ uint *lastFree = &newData->freeList;
+ for (uint i = 0; i < toCopy; ++i) {
+ if (!newData->data[i].isEmpty()) {
+ SparseArrayNode *n = newData->sparse->insert(i);
+ n->value = i;
+ } else {
+ *lastFree = i;
+ newData->data[i].tag = Value::Empty_Type;
+ lastFree = &newData->data[i].uint_32;
+ }
+ }
+ for (uint i = toCopy; i < newData->alloc; ++i) {
+ *lastFree = i;
+ newData->data[i].tag = Value::Empty_Type;
+ lastFree = &newData->data[i].uint_32;
+ }
+ *lastFree = newData->alloc;
+
+ // ### Could explicitly free the old data
+}
+
+
+void SimpleArrayData::getHeadRoom(Object *o)
+{
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
+ Q_ASSERT(dd);
+ Q_ASSERT(!dd->offset);
+ uint offset = qMax(dd->len >> 2, (uint)16);
+ realloc(o, Simple, offset, 0, false);
+}
+
+ArrayData *SimpleArrayData::reallocate(Object *o, uint n, bool enforceAttributes)
+{
+ realloc(o, Simple, 0, n, enforceAttributes);
+ return o->arrayData;
+}
+
+void ArrayData::ensureAttributes(Object *o)
+{
+ if (o->arrayData && o->arrayData->attrs)
+ return;
+
+ ArrayData::realloc(o, Simple, 0, 0, true);
+}
+
+
+void SimpleArrayData::destroy(Managed *)
+{
+}
+
+void SimpleArrayData::markObjects(Managed *d, ExecutionEngine *e)
+{
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
+ uint l = dd->len;
+ for (uint i = 0; i < l; ++i)
+ dd->data[i].mark(e);
+}
+
+ReturnedValue SimpleArrayData::get(const ArrayData *d, uint index)
+{
+ const SimpleArrayData *dd = static_cast<const SimpleArrayData *>(d);
+ if (index >= dd->len)
+ return Primitive::emptyValue().asReturnedValue();
+ return dd->data[index].asReturnedValue();
+}
+
+bool SimpleArrayData::put(Object *o, uint index, ValueRef value)
+{
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
+ Q_ASSERT(index >= dd->len || !dd->attrs || !dd->attrs[index].isAccessor());
+ // ### honour attributes
+ dd->data[index] = value;
+ if (index >= dd->len) {
+ if (dd->attrs)
+ dd->attrs[index] = Attr_Data;
+ dd->len = index + 1;
+ }
+ return true;
+}
+
+bool SimpleArrayData::del(Object *o, uint index)
+{
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
+ if (index >= dd->len)
+ return true;
+
+ if (!dd->attrs || dd->attrs[index].isConfigurable()) {
+ dd->data[index] = Primitive::emptyValue();
+ if (dd->attrs)
+ dd->attrs[index] = Attr_Data;
+ return true;
+ }
+ if (dd->data[index].isEmpty())
+ return true;
+ return false;
+}
+
+void SimpleArrayData::setAttribute(Object *o, uint index, PropertyAttributes attrs)
+{
+ o->arrayData->attrs[index] = attrs;
+}
+
+PropertyAttributes SimpleArrayData::attribute(const ArrayData *d, uint index)
+{
+ return d->attrs[index];
+}
+
+void SimpleArrayData::push_front(Object *o, Value *values, uint n)
+{
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
+ Q_ASSERT(!dd->attrs);
+ for (int i = n - 1; i >= 0; --i) {
+ if (!dd->offset) {
+ getHeadRoom(o);
+ dd = static_cast<SimpleArrayData *>(o->arrayData);
+ }
+
+
+ --dd->offset;
+ --dd->data;
+ ++dd->len;
+ ++dd->alloc;
+ *dd->data = values[i].asReturnedValue();
+ }
+
+}
+
+ReturnedValue SimpleArrayData::pop_front(Object *o)
+{
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
+ Q_ASSERT(!dd->attrs);
+ if (!dd->len)
+ return Encode::undefined();
+
+ ReturnedValue v = dd->data[0].isEmpty() ? Encode::undefined() : dd->data[0].asReturnedValue();
+ ++dd->offset;
+ ++dd->data;
+ --dd->len;
+ --dd->alloc;
+ return v;
+}
+
+uint SimpleArrayData::truncate(Object *o, uint newLen)
+{
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
+ if (dd->len < newLen)
+ return newLen;
+
+ if (dd->attrs) {
+ Value *it = dd->data + dd->len;
+ const Value *begin = dd->data + newLen;
+ while (--it >= begin) {
+ if (!it->isEmpty() && !dd->attrs[it - dd->data].isConfigurable()) {
+ newLen = it - dd->data + 1;
+ break;
+ }
+ *it = Primitive::emptyValue();
+ }
+ }
+ dd->len = newLen;
+ return newLen;
+}
+
+uint SimpleArrayData::length(const ArrayData *d)
+{
+ return static_cast<const SimpleArrayData *>(d)->len;
+}
+
+bool SimpleArrayData::putArray(Object *o, uint index, Value *values, uint n)
+{
+ SimpleArrayData *dd = static_cast<SimpleArrayData *>(o->arrayData);
+ if (index + n > dd->alloc) {
+ reallocate(o, index + n + 1, false);
+ dd = static_cast<SimpleArrayData *>(o->arrayData);
+ }
+ for (uint i = dd->len; i < index; ++i)
+ dd->data[i] = Primitive::emptyValue();
+ for (uint i = 0; i < n; ++i)
+ dd->data[index + i] = values[i];
+ dd->len = qMax(dd->len, index + n);
+ return true;
+}
+
+void SparseArrayData::free(ArrayData *d, uint idx)
+{
+ Q_ASSERT(d && d->type == ArrayData::Sparse);
+ SparseArrayData *dd = static_cast<SparseArrayData *>(d);
+ Value *v = dd->data + idx;
+ if (dd->attrs && dd->attrs[idx].isAccessor()) {
+ // double slot, free both. Order is important, so we have a double slot for allocation again afterwards.
+ v[1].tag = Value::Empty_Type;
+ v[1].uint_32 = dd->freeList;
+ v[0].tag = Value::Empty_Type;
+ v[0].uint_32 = idx + 1;
+ } else {
+ v->tag = Value::Empty_Type;
+ v->uint_32 = dd->freeList;
+ }
+ dd->freeList = idx;
+ if (dd->attrs)
+ dd->attrs[idx].clear();
+}
+
+
+void SparseArrayData::destroy(Managed *d)
+{
+ SparseArrayData *dd = static_cast<SparseArrayData *>(d);
+ delete dd->sparse;
+}
+
+void SparseArrayData::markObjects(Managed *d, ExecutionEngine *e)
+{
+ SparseArrayData *dd = static_cast<SparseArrayData *>(d);
+ uint l = dd->alloc;
+ for (uint i = 0; i < l; ++i)
+ dd->data[i].mark(e);
+}
+
+ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttributes)
+{
+ realloc(o, Sparse, 0, n, enforceAttributes);
+ return o->arrayData;
+}
+
+// double slots are required for accessor properties
+uint SparseArrayData::allocate(Object *o, bool doubleSlot)
+{
+ Q_ASSERT(o->arrayData->type == ArrayData::Sparse);
+ SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData);
+ if (doubleSlot) {
+ uint *last = &dd->freeList;
+ while (1) {
+ if (*last + 1 >= dd->alloc) {
+ reallocate(o, o->arrayData->alloc + 2, true);
+ dd = static_cast<SparseArrayData *>(o->arrayData);
+ last = &dd->freeList;
+ }
+
+ if (dd->data[*last].uint_32 == (*last + 1)) {
+ // found two slots in a row
+ uint idx = *last;
+ *last = dd->data[*last + 1].uint_32;
+ o->arrayData->attrs[idx] = Attr_Accessor;
+ return idx;
+ }
+ last = &dd->data[*last].uint_32;
+ }
+ } else {
+ if (dd->alloc == dd->freeList) {
+ reallocate(o, o->arrayData->alloc + 2, false);
+ dd = static_cast<SparseArrayData *>(o->arrayData);
+ }
+ uint idx = dd->freeList;
+ dd->freeList = dd->data[idx].uint_32;
+ if (dd->attrs)
+ dd->attrs[idx] = Attr_Data;
+ return idx;
+ }
+}
+
+ReturnedValue SparseArrayData::get(const ArrayData *d, uint index)
+{
+ SparseArrayNode *n = static_cast<const SparseArrayData *>(d)->sparse->findNode(index);
+ if (!n)
+ return Primitive::emptyValue().asReturnedValue();
+ return d->data[n->value].asReturnedValue();
+}
+
+bool SparseArrayData::put(Object *o, uint index, ValueRef value)
+{
+ if (value->isEmpty())
+ return true;
+
+ SparseArrayNode *n = static_cast<SparseArrayData *>(o->arrayData)->sparse->insert(index);
+ Q_ASSERT(n->value == UINT_MAX || !o->arrayData->attrs || !o->arrayData->attrs[n->value].isAccessor());
+ if (n->value == UINT_MAX)
+ n->value = allocate(o);
+ o->arrayData->data[n->value] = value;
+ if (o->arrayData->attrs)
+ o->arrayData->attrs[n->value] = Attr_Data;
+ return true;
+}
+
+bool SparseArrayData::del(Object *o, uint index)
+{
+ SparseArrayData *dd = static_cast<SparseArrayData *>(o->arrayData);
+ SparseArrayNode *n = dd->sparse->findNode(index);
+ if (!n)
+ return true;
+
+ uint pidx = n->value;
+ Q_ASSERT(!dd->data[pidx].isEmpty());
+
+ bool isAccessor = false;
+ if (dd->attrs) {
+ if (!dd->attrs[pidx].isConfigurable())
+ return false;
+
+ isAccessor = dd->attrs[pidx].isAccessor();
+ dd->attrs[pidx] = Attr_Data;
+ }
+
+ if (isAccessor) {
+ // free up both indices
+ dd->data[pidx + 1].tag = Value::Undefined_Type;
+ dd->data[pidx + 1].uint_32 = static_cast<SparseArrayData *>(dd)->freeList;
+ dd->data[pidx].tag = Value::Undefined_Type;
+ dd->data[pidx].uint_32 = pidx + 1;
+ } else {
+ dd->data[pidx].tag = Value::Undefined_Type;
+ dd->data[pidx].uint_32 = static_cast<SparseArrayData *>(dd)->freeList;
+ }
+
+ dd->freeList = pidx;
+ dd->sparse->erase(n);
+ return true;
+}
+
+void SparseArrayData::setAttribute(Object *o, uint index, PropertyAttributes attrs)
+{
+ SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData);
+ SparseArrayNode *n = d->sparse->insert(index);
+ if (n->value == UINT_MAX) {
+ n->value = allocate(o, attrs.isAccessor());
+ d = static_cast<SparseArrayData *>(o->arrayData);
+ }
+ else if (attrs.isAccessor() != d->attrs[n->value].isAccessor()) {
+ // need to convert the slot
+ free(d, n->value);
+ n->value = allocate(o, attrs.isAccessor());
+ }
+ o->arrayData->attrs[n->value] = attrs;
+}
+
+PropertyAttributes SparseArrayData::attribute(const ArrayData *d, uint index)
+{
+ SparseArrayNode *n = static_cast<const SparseArrayData *>(d)->sparse->insert(index);
+ if (!n)
+ return PropertyAttributes();
+ return d->attrs[n->value];
+}
+
+void SparseArrayData::push_front(Object *o, Value *values, uint n)
+{
+ Q_ASSERT(!o->arrayData->attrs);
+ for (int i = n - 1; i >= 0; --i) {
+ uint idx = allocate(o);
+ o->arrayData->data[idx] = values[i];
+ static_cast<SparseArrayData *>(o->arrayData)->sparse->push_front(idx);
+ }
+}
+
+ReturnedValue SparseArrayData::pop_front(Object *o)
+{
+ Q_ASSERT(!o->arrayData->attrs);
+ uint idx = static_cast<SparseArrayData *>(o->arrayData)->sparse->pop_front();
+ ReturnedValue v;
+ if (idx != UINT_MAX) {
+ v = o->arrayData->data[idx].asReturnedValue();
+ free(o->arrayData, idx);
+ } else {
+ v = Encode::undefined();
+ }
+ return v;
+}
+
+uint SparseArrayData::truncate(Object *o, uint newLen)
+{
+ SparseArrayData *d = static_cast<SparseArrayData *>(o->arrayData);
+ SparseArrayNode *begin = d->sparse->lowerBound(newLen);
+ if (begin != d->sparse->end()) {
+ SparseArrayNode *it = d->sparse->end()->previousNode();
+ while (1) {
+ if (d->attrs) {
+ if (!d->attrs[it->value].isConfigurable()) {
+ newLen = it->key() + 1;
+ break;
+ }
+ }
+ free(d, it->value);
+ bool brk = (it == begin);
+ SparseArrayNode *prev = it->previousNode();
+ static_cast<SparseArrayData *>(d)->sparse->erase(it);
+ if (brk)
+ break;
+ it = prev;
+ }
+ }
+ return newLen;
+}
+
+uint SparseArrayData::length(const ArrayData *d)
+{
+ const SparseArrayData *dd = static_cast<const SparseArrayData *>(d);
+ if (!dd->sparse)
+ return 0;
+ SparseArrayNode *n = dd->sparse->end();
+ n = n->previousNode();
+ return n ? n->key() + 1 : 0;
+}
+
+bool SparseArrayData::putArray(Object *o, uint index, Value *values, uint n)
+{
+ for (uint i = 0; i < n; ++i)
+ put(o, index + i, values[i]);
+ return true;
+}
+
+
+uint ArrayData::append(Object *obj, const ArrayObject *otherObj, uint n)
+{
+ Q_ASSERT(!obj->arrayData->hasAttributes());
+
+ if (!n)
+ return obj->getLength();
+
+ const ArrayData *other = otherObj->arrayData;
+
+ if (other->isSparse())
+ obj->initSparseArray();
+
+ uint oldSize = obj->getLength();
+
+ if (other->isSparse()) {
+ if (otherObj->hasAccessorProperty && other->hasAttributes()) {
+ Scope scope(obj->engine());
+ ScopedValue v(scope);
+ for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other)->sparse->begin();
+ it != static_cast<const SparseArrayData *>(other)->sparse->end(); it = it->nextNode()) {
+ v = otherObj->getValue(reinterpret_cast<Property *>(other->data + it->value), other->attrs[it->value]);
+ obj->arraySet(oldSize + it->key(), v);
+ }
+ } else {
+ for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other)->sparse->begin();
+ it != static_cast<const SparseArrayData *>(other)->sparse->end(); it = it->nextNode())
+ obj->arraySet(oldSize + it->key(), other->data[it->value]);
+ }
+ } else {
+ obj->arrayPut(oldSize, other->data, n);
+ }
+
+ return oldSize + n;
+}
+
+Property *ArrayData::insert(Object *o, uint index, bool isAccessor)
+{
+ if (!isAccessor && o->arrayData->type != ArrayData::Sparse) {
+ SimpleArrayData *d = static_cast<SimpleArrayData *>(o->arrayData);
+ if (index < 0x1000 || index < d->len + (d->len >> 2)) {
+ if (index >= o->arrayData->alloc) {
+ o->arrayReserve(index + 1);
+ d = static_cast<SimpleArrayData *>(o->arrayData);
+ }
+ if (index >= d->len) {
+ // mark possible hole in the array
+ for (uint i = d->len; i < index; ++i)
+ d->data[i] = Primitive::emptyValue();
+ d->len = index + 1;
+ }
+ return reinterpret_cast<Property *>(o->arrayData->data + index);
+ }
+ }
+
+ o->initSparseArray();
+ SparseArrayNode *n = static_cast<SparseArrayData *>(o->arrayData)->sparse->insert(index);
+ if (n->value == UINT_MAX)
+ n->value = SparseArrayData::allocate(o, isAccessor);
+ return reinterpret_cast<Property *>(o->arrayData->data + n->value);
+}
+
+
+class ArrayElementLessThan
+{
+public:
+ inline ArrayElementLessThan(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn)
+ : m_context(context), thisObject(thisObject), m_comparefn(comparefn) {}
+
+ bool operator()(const Value &v1, const Value &v2) const;
+
+private:
+ ExecutionContext *m_context;
+ ObjectRef thisObject;
+ const ValueRef m_comparefn;
+};
+
+
+bool ArrayElementLessThan::operator()(const Value &v1, const Value &v2) const
+{
+ Scope scope(m_context);
+
+ if (v1.isUndefined() || v1.isEmpty())
+ return false;
+ if (v2.isUndefined() || v2.isEmpty())
+ return true;
+ ScopedObject o(scope, m_comparefn);
+ if (o) {
+ Scope scope(o->engine());
+ ScopedValue result(scope);
+ ScopedCallData callData(scope, 2);
+ callData->thisObject = Primitive::undefinedValue();
+ callData->args[0] = v1;
+ callData->args[1] = v2;
+ result = __qmljs_call_value(m_context, m_comparefn, callData);
+
+ return result->toNumber() < 0;
+ }
+ ScopedString p1s(scope, v1.toString(m_context));
+ ScopedString p2s(scope, v2.toString(m_context));
+ return p1s->toQString() < p2s->toQString();
+}
+
+void ArrayData::sort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint len)
+{
+ if (!len)
+ return;
+
+ if (!thisObject->arrayData->length())
+ return;
+
+ if (!(comparefn->isUndefined() || comparefn->asObject())) {
+ context->throwTypeError();
+ return;
+ }
+
+ // The spec says the sorting goes through a series of get,put and delete operations.
+ // this implies that the attributes don't get sorted around.
+
+ if (thisObject->arrayData->type == ArrayData::Sparse) {
+ // since we sort anyway, we can simply iterate over the entries in the sparse
+ // array and append them one by one to a regular one.
+ SparseArrayData *sparse = static_cast<SparseArrayData *>(thisObject->arrayData);
+
+ if (!sparse->sparse->nEntries())
+ return;
+
+ thisObject->arrayData = 0;
+ ArrayData::realloc(thisObject, ArrayData::Simple, 0, sparse->sparse->nEntries(), sparse->attrs ? true : false);
+ SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData);
+
+ SparseArrayNode *n = sparse->sparse->begin();
+ uint i = 0;
+ if (sparse->attrs) {
+ while (n != sparse->sparse->end()) {
+ if (n->value >= len)
+ break;
+
+ PropertyAttributes a = sparse->attrs ? sparse->attrs[n->value] : Attr_Data;
+ d->data[i] = thisObject->getValue(reinterpret_cast<Property *>(sparse->data + n->value), a);
+ d->attrs[i] = a.isAccessor() ? Attr_Data : a;
+
+ n = n->nextNode();
+ ++i;
+ }
+ } else {
+ while (n != sparse->sparse->end()) {
+ if (n->value >= len)
+ break;
+ d->data[i] = sparse->data[n->value];
+ n = n->nextNode();
+ ++i;
+ }
+ }
+ d->len = i;
+ if (len > i)
+ len = i;
+ if (n != sparse->sparse->end()) {
+ // have some entries outside the sort range that we need to ignore when sorting
+ thisObject->initSparseArray();
+ while (n != sparse->sparse->end()) {
+ PropertyAttributes a = sparse->attrs ? sparse->attrs[n->value] : Attr_Data;
+ thisObject->arraySet(n->value, *reinterpret_cast<Property *>(sparse->data + n->value), a);
+
+ n = n->nextNode();
+ }
+
+ }
+ // ### explicitly delete sparse
+ } else {
+ SimpleArrayData *d = static_cast<SimpleArrayData *>(thisObject->arrayData);
+ if (len > d->len)
+ len = d->len;
+
+ // sort empty values to the end
+ for (uint i = 0; i < len; i++) {
+ if (thisObject->arrayData->data[i].isEmpty()) {
+ while (--len > i)
+ if (!thisObject->arrayData->data[len].isEmpty())
+ break;
+ Q_ASSERT(!thisObject->arrayData->attrs || !thisObject->arrayData->attrs[len].isAccessor());
+ thisObject->arrayData->data[i] = thisObject->arrayData->data[len];
+ thisObject->arrayData->data[len] = Primitive::emptyValue();
+ }
+ }
+
+ if (!len)
+ return;
+ }
+
+
+ ArrayElementLessThan lessThan(context, thisObject, comparefn);
+
+ Value *begin = thisObject->arrayData->data;
+ std::sort(begin, begin + len, lessThan);
+
+#ifdef CHECK_SPARSE_ARRAYS
+ thisObject->initSparseArray();
+#endif
+
+}
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
new file mode 100644
index 0000000000..f127c75fb0
--- /dev/null
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 QV4ARRAYDATA_H
+#define QV4ARRAYDATA_H
+
+#include "qv4global_p.h"
+#include "qv4managed_p.h"
+#include "qv4property_p.h"
+#include "qv4sparsearray_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+#define V4_ARRAYDATA \
+ public: \
+ Q_MANAGED_CHECK \
+ static const QV4::ArrayVTable static_vtbl; \
+ static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
+ template <typename T> \
+ QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+
+struct ArrayData;
+
+struct ArrayVTable
+{
+ ManagedVTable managedVTable;
+ uint type;
+ ArrayData *(*reallocate)(Object *o, uint n, bool enforceAttributes);
+ ReturnedValue (*get)(const ArrayData *d, uint index);
+ bool (*put)(Object *o, uint index, ValueRef value);
+ bool (*putArray)(Object *o, uint index, Value *values, uint n);
+ bool (*del)(Object *o, uint index);
+ void (*setAttribute)(Object *o, uint index, PropertyAttributes attrs);
+ PropertyAttributes (*attribute)(const ArrayData *d, uint index);
+ void (*push_front)(Object *o, Value *values, uint n);
+ ReturnedValue (*pop_front)(Object *o);
+ uint (*truncate)(Object *o, uint newLen);
+ uint (*length)(const ArrayData *d);
+};
+
+
+struct Q_QML_EXPORT ArrayData : public Managed
+{
+ ArrayData(InternalClass *ic)
+ : Managed(ic)
+ {
+ }
+
+ enum Type {
+ Simple = 0,
+ Complex = 1,
+ Sparse = 2,
+ Custom = 3
+ };
+
+ uint alloc;
+ Type type;
+ PropertyAttributes *attrs;
+ Value *data;
+
+ const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass->vtable); }
+ bool isSparse() const { return this && type == Sparse; }
+
+ uint length() const {
+ if (!this)
+ return 0;
+ return vtable()->length(this);
+ }
+
+ bool hasAttributes() const {
+ return this && attrs;
+ }
+ PropertyAttributes attributes(int i) const {
+ Q_ASSERT(this);
+ return attrs ? vtable()->attribute(this, i) : Attr_Data;
+ }
+
+ bool isEmpty(uint i) const {
+ if (!this)
+ return true;
+ return (vtable()->get(this, i) == Primitive::emptyValue().asReturnedValue());
+ }
+
+ ReturnedValue get(uint i) const {
+ if (!this)
+ return Primitive::emptyValue().asReturnedValue();
+ return vtable()->get(this, i);
+ }
+ inline Property *getProperty(uint index) const;
+
+ static void ensureAttributes(Object *o);
+ static void realloc(Object *o, Type newType, uint offset, uint alloc, bool enforceAttributes);
+
+ static void sort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint dataLen);
+ static uint append(Object *obj, const ArrayObject *otherObj, uint n);
+ static Property *insert(Object *o, uint index, bool isAccessor = false);
+};
+
+struct Q_QML_EXPORT SimpleArrayData : public ArrayData
+{
+ V4_ARRAYDATA
+
+ SimpleArrayData(ExecutionEngine *engine)
+ : ArrayData(engine->emptyClass)
+ { setVTable(staticVTable()); }
+
+ uint len;
+ uint offset;
+
+ static void getHeadRoom(Object *o);
+ static ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
+
+ static void destroy(Managed *d);
+ static void markObjects(Managed *d, ExecutionEngine *e);
+
+ static ReturnedValue get(const ArrayData *d, uint index);
+ static bool put(Object *o, uint index, ValueRef value);
+ static bool putArray(Object *o, uint index, Value *values, uint n);
+ static bool del(Object *o, uint index);
+ static void setAttribute(Object *o, uint index, PropertyAttributes attrs);
+ static PropertyAttributes attribute(const ArrayData *d, uint index);
+ static void push_front(Object *o, Value *values, uint n);
+ static ReturnedValue pop_front(Object *o);
+ static uint truncate(Object *o, uint newLen);
+ static uint length(const ArrayData *d);
+};
+
+struct Q_QML_EXPORT SparseArrayData : public ArrayData
+{
+ V4_ARRAYDATA
+
+ SparseArrayData(ExecutionEngine *engine)
+ : ArrayData(engine->emptyClass)
+ { setVTable(staticVTable()); }
+
+ uint freeList;
+ SparseArray *sparse;
+
+ static uint allocate(Object *o, bool doubleSlot = false);
+ static void free(ArrayData *d, uint idx);
+
+ static void destroy(Managed *d);
+ static void markObjects(Managed *d, ExecutionEngine *e);
+
+ static ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
+ static ReturnedValue get(const ArrayData *d, uint index);
+ static bool put(Object *o, uint index, ValueRef value);
+ static bool putArray(Object *o, uint index, Value *values, uint n);
+ static bool del(Object *o, uint index);
+ static void setAttribute(Object *o, uint index, PropertyAttributes attrs);
+ static PropertyAttributes attribute(const ArrayData *d, uint index);
+ static void push_front(Object *o, Value *values, uint n);
+ static ReturnedValue pop_front(Object *o);
+ static uint truncate(Object *o, uint newLen);
+ static uint length(const ArrayData *d);
+};
+
+
+inline Property *ArrayData::getProperty(uint index) const
+{
+ if (!this)
+ return 0;
+ if (type != Sparse) {
+ const SimpleArrayData *that = static_cast<const SimpleArrayData *>(this);
+ if (index >= that->len || data[index].isEmpty())
+ return 0;
+ return reinterpret_cast<Property *>(data + index);
+ } else {
+ SparseArrayNode *n = static_cast<const SparseArrayData *>(this)->sparse->findNode(index);
+ if (!n)
+ return 0;
+ return reinterpret_cast<Property *>(data + n->value);
+ }
+}
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index d4829e587e..efe1dff19c 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -46,12 +46,12 @@
using namespace QV4;
-DEFINE_MANAGED_VTABLE(ArrayCtor);
+DEFINE_OBJECT_VTABLE(ArrayCtor);
ArrayCtor::ArrayCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("Array"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData)
@@ -72,9 +72,7 @@ ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData)
} else {
len = callData->argc;
a->arrayReserve(len);
- for (unsigned int i = 0; i < len; ++i)
- a->arrayData[i].value = callData->args[i];
- a->arrayDataLen = len;
+ a->arrayPut(0, callData->args, len);
}
a->setArrayLengthUnchecked(len);
@@ -122,15 +120,6 @@ void ArrayPrototype::init(ExecutionEngine *engine, ObjectRef ctor)
defineDefaultProperty(QStringLiteral("reduceRight"), method_reduceRight, 1);
}
-uint ArrayPrototype::getLength(ExecutionContext *ctx, ObjectRef o)
-{
- if (o->isArrayObject())
- return o->arrayLength();
- Scope scope(ctx);
- ScopedValue v(scope, o->get(ctx->engine->id_length));
- return v->toUInt32();
-}
-
ReturnedValue ArrayPrototype::method_isArray(CallContext *ctx)
{
bool isArray = ctx->callData->argc && ctx->callData->args[0].asArrayObject();
@@ -180,15 +169,17 @@ ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
eltAsObj = ctx->callData->args[i];
elt = ctx->callData->args[i];
if (elt) {
- result->arrayConcat(elt.getPointer());
+ uint n = elt->getLength();
+ uint newLen = ArrayData::append(result.getPointer(), elt.getPointer(), n);
+ result->setArrayLengthUnchecked(newLen);
} else if (eltAsObj && eltAsObj->isListType()) {
- const uint startIndex = getLength(ctx, result);
- for (int i = 0, len = getLength(ctx, eltAsObj); i < len; ++i) {
+ const uint startIndex = result->getLength();
+ for (int i = 0, len = eltAsObj->getLength(); i < len; ++i) {
entry = eltAsObj->getIndexed(i);
result->putIndexed(startIndex + i, entry);
}
} else {
- result->arraySet(getLength(ctx, result), ctx->callData->args[i]);
+ result->arraySet(result->getLength(), ctx->callData->args[i]);
}
}
@@ -218,7 +209,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
// ### FIXME
if (ArrayObject *a = self->asArrayObject()) {
ScopedValue e(scope);
- for (uint i = 0; i < a->arrayLength(); ++i) {
+ for (uint i = 0; i < a->getLength(); ++i) {
if (i)
R += r4;
@@ -260,7 +251,7 @@ ReturnedValue ArrayPrototype::method_pop(CallContext *ctx)
ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
if (!len) {
if (!instance->isArrayObject())
@@ -288,7 +279,10 @@ ReturnedValue ArrayPrototype::method_push(CallContext *ctx)
ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+
+ instance->arrayCreate();
+
+ uint len = instance->getLength();
if (len + ctx->callData->argc < len) {
// ughh...
@@ -308,21 +302,11 @@ ReturnedValue ArrayPrototype::method_push(CallContext *ctx)
return Encode(newLen);
}
- if (!instance->protoHasArray() && instance->arrayDataLen <= len && (instance->flags & SimpleArray)) {
- for (int i = 0; i < ctx->callData->argc; ++i) {
- if (!instance->sparseArray) {
- if (len >= instance->arrayAlloc)
- instance->arrayReserve(len + 1);
- instance->arrayData[len].value = ctx->callData->args[i];
- if (instance->arrayAttributes)
- instance->arrayAttributes[len] = Attr_Data;
- instance->arrayDataLen = len + 1;
- } else {
- uint j = instance->allocArrayValue(ctx->callData->args[i]);
- instance->sparseArray->push_back(j, len);
- }
- ++len;
- }
+ if (!ctx->callData->argc) {
+ ;
+ } else if (!instance->protoHasArray() && instance->arrayData->length() <= len && instance->arrayType() == ArrayData::Simple) {
+ instance->arrayData->vtable()->putArray(instance.getPointer(), len, ctx->callData->args, ctx->callData->argc);
+ len = instance->arrayData->length();
} else {
for (int i = 0; i < ctx->callData->argc; ++i)
instance->putIndexed(len + i, ctx->callData->args[i]);
@@ -342,7 +326,7 @@ ReturnedValue ArrayPrototype::method_reverse(CallContext *ctx)
ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
- uint length = getLength(ctx, instance);
+ uint length = instance->getLength();
int lo = 0, hi = length - 1;
@@ -374,7 +358,10 @@ ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+
+ instance->arrayCreate();
+
+ uint len = instance->getLength();
if (!len) {
if (!instance->isArrayObject())
@@ -382,28 +369,14 @@ ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
return Encode::undefined();
}
- Property *front = 0;
- uint pidx = instance->propertyIndexFromArrayIndex(0);
- if (pidx < UINT_MAX && !instance->arrayData[pidx].value.isEmpty())
- front = instance->arrayData + pidx;
-
- ScopedValue result(scope, front ? instance->getValue(front, instance->arrayAttributes ? instance->arrayAttributes[pidx] : Attr_Data) : Encode::undefined());
+ ScopedValue result(scope);
- if (!instance->protoHasArray() && instance->arrayDataLen <= len) {
- if (!instance->sparseArray) {
- if (instance->arrayDataLen) {
- ++instance->arrayOffset;
- ++instance->arrayData;
- --instance->arrayDataLen;
- --instance->arrayAlloc;
- if (instance->arrayAttributes)
- ++instance->arrayAttributes;
- }
- } else {
- uint idx = instance->sparseArray->pop_front();
- instance->freeArrayValue(idx);
- }
+ if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len) {
+ result = instance->arrayData->vtable()->pop_front(instance.getPointer());
} else {
+ result = instance->getIndexed(0);
+ if (scope.hasException())
+ return Encode::undefined();
ScopedValue v(scope);
// do it the slow way
for (uint k = 1; k < len; ++k) {
@@ -415,6 +388,8 @@ ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
instance->putIndexed(k - 1, v);
else
instance->deleteIndexedProperty(k - 1);
+ if (scope.hasException())
+ return Encode::undefined();
}
instance->deleteIndexedProperty(len - 1);
if (scope.hasException())
@@ -436,7 +411,7 @@ ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
return Encode::undefined();
Scoped<ArrayObject> result(scope, ctx->engine->newArrayObject());
- uint len = getLength(ctx, o);
+ uint len = o->getLength();
double s = ScopedValue(scope, ctx->argument(0))->toInteger();
uint start;
if (s < 0)
@@ -477,10 +452,10 @@ ReturnedValue ArrayPrototype::method_sort(CallContext *ctx)
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
ScopedValue comparefn(scope, ctx->argument(0));
- instance->arraySort(ctx, instance, comparefn, len);
+ ArrayData::sort(ctx, instance, comparefn, len);
return ctx->callData->thisObject.asReturnedValue();
}
@@ -490,7 +465,7 @@ ReturnedValue ArrayPrototype::method_splice(CallContext *ctx)
ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
Scoped<ArrayObject> newArray(scope, ctx->engine->newArrayObject());
@@ -504,17 +479,19 @@ ReturnedValue ArrayPrototype::method_splice(CallContext *ctx)
uint deleteCount = (uint)qMin(qMax(ScopedValue(scope, ctx->argument(1))->toInteger(), 0.), (double)(len - start));
newArray->arrayReserve(deleteCount);
+ ScopedValue v(scope);
for (uint i = 0; i < deleteCount; ++i) {
- newArray->arrayData[i].value = instance->getIndexed(start + i);
+ bool exists;
+ v = instance->getIndexed(start + i, &exists);
if (scope.hasException())
return Encode::undefined();
- newArray->arrayDataLen = i + 1;
+ if (exists)
+ newArray->arrayPut(i, v);
}
newArray->setArrayLengthUnchecked(deleteCount);
uint itemCount = ctx->callData->argc < 2 ? 0 : ctx->callData->argc - 2;
- ScopedValue v(scope);
if (itemCount < deleteCount) {
for (uint k = start; k < len - deleteCount; ++k) {
bool exists;
@@ -568,32 +545,15 @@ ReturnedValue ArrayPrototype::method_unshift(CallContext *ctx)
ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
- ScopedValue v(scope);
- if (!instance->protoHasArray() && instance->arrayDataLen <= len) {
- for (int i = ctx->callData->argc - 1; i >= 0; --i) {
- v = ctx->argument(i);
-
- if (!instance->sparseArray) {
- if (!instance->arrayOffset)
- instance->getArrayHeadRoom();
-
- --instance->arrayOffset;
- --instance->arrayData;
- ++instance->arrayDataLen;
- ++instance->arrayAlloc;
- if (instance->arrayAttributes) {
- --instance->arrayAttributes;
- *instance->arrayAttributes = Attr_Data;
- }
- instance->arrayData->value = v.asReturnedValue();
- } else {
- uint idx = instance->allocArrayValue(v);
- instance->sparseArray->push_front(idx);
- }
- }
+ instance->arrayCreate();
+
+ uint len = instance->getLength();
+
+ if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len) {
+ instance->arrayData->vtable()->push_front(instance.getPointer(), ctx->callData->args, ctx->callData->argc);
} else {
+ ScopedValue v(scope);
for (uint k = len; k > 0; --k) {
bool exists;
v = instance->getIndexed(k - 1, &exists);
@@ -622,7 +582,7 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
if (!len)
return Encode(-1);
@@ -651,7 +611,39 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
return Encode(-1);
}
- return instance->arrayIndexOf(searchValue, fromIndex, len, ctx, instance.getPointer());
+ ScopedValue value(scope);
+
+ if (instance->hasAccessorProperty || (instance->arrayType() >= ArrayData::Sparse) || instance->protoHasArray()) {
+ // lets be safe and slow
+ for (uint i = fromIndex; i < len; ++i) {
+ bool exists;
+ value = instance->getIndexed(i, &exists);
+ if (scope.hasException())
+ return Encode::undefined();
+ if (exists && __qmljs_strict_equal(value, searchValue))
+ return Encode(i);
+ }
+ } else if (!instance->arrayData) {
+ return Encode(-1);
+ } else {
+ Q_ASSERT(instance->arrayType() == ArrayData::Simple || instance->arrayType() == ArrayData::Complex);
+ if (len > instance->arrayData->length())
+ len = instance->arrayData->length();
+ Value *val = instance->arrayData->data;
+ Value *end = val + len;
+ val += fromIndex;
+ while (val < end) {
+ if (!val->isEmpty()) {
+ value = *val;
+ if (scope.hasException())
+ return Encode::undefined();
+ if (__qmljs_strict_equal(value, searchValue))
+ return Encode((uint)(val - instance->arrayData->data));
+ }
+ ++val;
+ }
+ }
+ return Encode(-1);
}
ReturnedValue ArrayPrototype::method_lastIndexOf(CallContext *ctx)
@@ -661,7 +653,7 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(CallContext *ctx)
ScopedObject instance(scope, ctx->callData->thisObject.toObject(ctx));
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
if (!len)
return Encode(-1);
@@ -707,7 +699,7 @@ ReturnedValue ArrayPrototype::method_every(CallContext *ctx)
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
@@ -741,7 +733,7 @@ ReturnedValue ArrayPrototype::method_some(CallContext *ctx)
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
@@ -775,7 +767,7 @@ ReturnedValue ArrayPrototype::method_forEach(CallContext *ctx)
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
@@ -806,7 +798,7 @@ ReturnedValue ArrayPrototype::method_map(CallContext *ctx)
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
@@ -843,7 +835,7 @@ ReturnedValue ArrayPrototype::method_filter(CallContext *ctx)
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
@@ -884,7 +876,7 @@ ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
@@ -934,7 +926,7 @@ ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
if (!instance)
return Encode::undefined();
- uint len = getLength(ctx, instance);
+ uint len = instance->getLength();
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index 7e809f9064..e7f8ba711f 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -51,7 +51,7 @@ namespace QV4 {
struct ArrayCtor: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
ArrayCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *m, CallData *callData);
@@ -64,8 +64,6 @@ struct ArrayPrototype: ArrayObject
void init(ExecutionEngine *engine, ObjectRef ctor);
- static uint getLength(ExecutionContext *ctx, ObjectRef o);
-
static ReturnedValue method_isArray(CallContext *ctx);
static ReturnedValue method_toString(CallContext *ctx);
static ReturnedValue method_toLocaleString(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index f8edfb7850..662ec64efb 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -43,13 +43,13 @@
using namespace QV4;
-DEFINE_MANAGED_VTABLE(BooleanCtor);
-DEFINE_MANAGED_VTABLE(BooleanObject);
+DEFINE_OBJECT_VTABLE(BooleanCtor);
+DEFINE_OBJECT_VTABLE(BooleanObject);
BooleanCtor::BooleanCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("Boolean"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue BooleanCtor::construct(Managed *m, CallData *callData)
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index 8d6adc0fb2..617f7f6b01 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -51,7 +51,7 @@ namespace QV4 {
struct BooleanCtor: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
BooleanCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *, CallData *callData);
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 8c6d75d1de..cec42e87aa 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -51,27 +51,7 @@
using namespace QV4;
-const ManagedVTable ExecutionContext::static_vtbl =
-{
- call,
- construct,
- markObjects,
- destroy,
- 0 /*collectDeletables*/,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- isEqualTo,
- 0,
- "ExecutionContext",
-};
+DEFINE_MANAGED_VTABLE(ExecutionContext);
CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData)
{
@@ -91,13 +71,13 @@ CallContext *ExecutionContext::newCallContext(FunctionObject *function, CallData
c->lookups = c->compilationUnit->runtimeLookups;
}
- c->locals = (SafeValue *)((quintptr(c + 1) + 7) & ~7);
+ c->locals = (Value *)((quintptr(c + 1) + 7) & ~7);
if (function->varCount)
std::fill(c->locals, c->locals + function->varCount, Primitive::undefinedValue());
c->callData = reinterpret_cast<CallData *>(c->locals + function->varCount);
- ::memcpy(c->callData, callData, sizeof(CallData) + (callData->argc - 1) * sizeof(SafeValue));
+ ::memcpy(c->callData, callData, sizeof(CallData) + (callData->argc - 1) * sizeof(Value));
if (callData->argc < static_cast<int>(function->formalParameterCount))
std::fill(c->callData->args + c->callData->argc, c->callData->args + function->formalParameterCount, Primitive::undefinedValue());
c->callData->argc = qMax((uint)callData->argc, function->formalParameterCount);
@@ -144,7 +124,7 @@ void ExecutionContext::createMutableBinding(const StringRef name, bool deletable
ctx = ctx->outer;
}
- if (activation->__hasProperty__(name))
+ if (activation->hasProperty(name))
return;
Property desc = Property::fromValue(Primitive::undefinedValue());
PropertyAttributes attrs(Attr_Data);
@@ -234,7 +214,7 @@ CallContext::CallContext(ExecutionEngine *engine, ObjectRef qml, FunctionObject
lookups = compilationUnit->runtimeLookups;
}
- locals = (SafeValue *)(this + 1);
+ locals = (Value *)(this + 1);
if (function->varCount)
std::fill(locals, locals + function->varCount, Primitive::undefinedValue());
}
@@ -248,7 +228,7 @@ bool ExecutionContext::deleteProperty(const StringRef name)
if (ctx->type == Type_WithContext) {
hasWith = true;
WithContext *w = static_cast<WithContext *>(ctx);
- if (w->withObject->__hasProperty__(name))
+ if (w->withObject->hasProperty(name))
return w->withObject->deleteProperty(name);
} else if (ctx->type == Type_CatchContext) {
CatchContext *c = static_cast<CatchContext *>(ctx);
@@ -263,11 +243,11 @@ bool ExecutionContext::deleteProperty(const StringRef name)
// ### throw in strict mode?
return false;
}
- if (c->activation && c->activation->__hasProperty__(name))
+ if (c->activation && c->activation->hasProperty(name))
return c->activation->deleteProperty(name);
} else if (ctx->type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(ctx);
- if (g->global->__hasProperty__(name))
+ if (g->global->hasProperty(name))
return g->global->deleteProperty(name);
}
}
@@ -320,7 +300,7 @@ void ExecutionContext::setProperty(const StringRef name, const ValueRef value)
for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) {
if (ctx->type == Type_WithContext) {
ScopedObject w(scope, static_cast<WithContext *>(ctx)->withObject);
- if (w->__hasProperty__(name)) {
+ if (w->hasProperty(name)) {
w->put(name, value);
return;
}
@@ -349,16 +329,9 @@ void ExecutionContext::setProperty(const StringRef name, const ValueRef value)
}
if (activation) {
- if (ctx->type == Type_QmlContext) {
+ if (ctx->type == Type_QmlContext || activation->hasOwnProperty(name)) {
activation->put(name, value);
return;
- } else {
- PropertyAttributes attrs;
- Property *p = activation->__getOwnProperty__(name, &attrs);
- if (p) {
- activation->putValue(p, attrs, value);
- return;
- }
}
}
}
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 9f905df15c..f9511d98e3 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -42,7 +42,7 @@
#define QMLJS_ENVIRONMENT_H
#include "qv4global_p.h"
-#include "qv4value_def_p.h"
+#include "qv4scopedvalue_p.h"
#include "qv4managed_p.h"
#include "qv4engine_p.h"
@@ -69,7 +69,11 @@ struct WithContext;
struct Q_QML_EXPORT ExecutionContext : public Managed
{
- Q_MANAGED
+ V4_MANAGED
+ Q_MANAGED_TYPE(ExecutionContext)
+ enum {
+ IsExecutionContext = true
+ };
enum ContextType {
Type_GlobalContext = 0x1,
@@ -170,13 +174,17 @@ struct CallContext : public ExecutionContext
FunctionObject *function;
int realArgumentCount;
- SafeValue *locals;
+ Value *locals;
Object *activation;
inline ReturnedValue argument(int i);
bool needsOwnArguments() const;
};
+inline ReturnedValue CallContext::argument(int i) {
+ return i < callData->argc ? callData->args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
+}
+
struct GlobalContext : public ExecutionContext
{
GlobalContext(ExecutionEngine *engine);
@@ -188,8 +196,8 @@ struct CatchContext : public ExecutionContext
{
CatchContext(ExecutionEngine *engine, const StringRef exceptionVarName, const ValueRef exceptionValue);
- SafeString exceptionVarName;
- SafeValue exceptionValue;
+ StringValue exceptionVarName;
+ Value exceptionValue;
};
struct WithContext : public ExecutionContext
@@ -239,6 +247,15 @@ struct ExecutionContextSaver
}
};
+inline Scope::Scope(ExecutionContext *ctx)
+ : engine(ctx->engine)
+#ifndef QT_NO_DEBUG
+ , size(0)
+#endif
+{
+ mark = engine->jsStackTop;
+}
+
/* Function *f, int argc */
#define requiredMemoryForExecutionContect(f, argc) \
((sizeof(CallContext) + 7) & ~7) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount)) + sizeof(CallData)
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 5d0c8ccf8e..a9ef29618c 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -641,13 +641,12 @@ static double getLocalTZA()
#endif
}
-DEFINE_MANAGED_VTABLE(DateObject);
+DEFINE_OBJECT_VTABLE(DateObject);
DateObject::DateObject(ExecutionEngine *engine, const QDateTime &date)
: Object(engine->dateClass)
{
- setVTable(&static_vtbl);
- type = Type_DateObject;
+ setVTable(staticVTable());
value.setDouble(date.isValid() ? date.toMSecsSinceEpoch() : qSNaN());
}
@@ -656,12 +655,12 @@ QDateTime DateObject::toQDateTime() const
return ToDateTime(value.asDouble(), Qt::LocalTime);
}
-DEFINE_MANAGED_VTABLE(DateCtor);
+DEFINE_OBJECT_VTABLE(DateCtor);
DateCtor::DateCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("Date"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue DateCtor::construct(Managed *m, CallData *callData)
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 9c451dd251..c52e8c3ee1 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -52,10 +52,10 @@ class QDateTime;
namespace QV4 {
struct DateObject: Object {
- Q_MANAGED
- SafeValue value;
+ V4_OBJECT
+ Q_MANAGED_TYPE(DateObject)
+ Value value;
DateObject(ExecutionEngine *engine, const ValueRef date): Object(engine->dateClass) {
- type = Type_DateObject;
value = date;
}
DateObject(ExecutionEngine *engine, const QDateTime &value);
@@ -64,15 +64,14 @@ struct DateObject: Object {
protected:
DateObject(InternalClass *ic): Object(ic) {
- setVTable(&static_vtbl);
- type = Type_DateObject;
+ Q_ASSERT(internalClass->vtable == staticVTable());
value = Primitive::fromDouble(qSNaN());
}
};
struct DateCtor: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
DateCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *, CallData *callData);
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index 4170b6817f..9ab1622fee 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -179,7 +179,7 @@ void Debugger::resume(Speed speed)
return;
if (!m_returnedValue.isUndefined())
- m_returnedValue = Primitive::undefinedValue();
+ m_returnedValue = Encode::undefined();
clearTemporaryBreakPoints();
if (speed == StepOver)
@@ -648,15 +648,15 @@ void Debugger::applyPendingBreakPoints()
void Debugger::setBreakOnInstruction(Function *function, qptrdiff codeOffset, bool onoff)
{
uchar *codePtr = const_cast<uchar *>(function->codeData) + codeOffset;
- QQmlJS::Moth::Instr *instruction = reinterpret_cast<QQmlJS::Moth::Instr*>(codePtr);
- instruction->common.breakPoint = onoff;
+ QQmlJS::Moth::Instr::instr_debug *debug = reinterpret_cast<QQmlJS::Moth::Instr::instr_debug *>(codePtr);
+ debug->breakPoint = onoff;
}
bool Debugger::hasBreakOnInstruction(Function *function, qptrdiff codeOffset)
{
uchar *codePtr = const_cast<uchar *>(function->codeData) + codeOffset;
- QQmlJS::Moth::Instr *instruction = reinterpret_cast<QQmlJS::Moth::Instr*>(codePtr);
- return instruction->common.breakPoint;
+ QQmlJS::Moth::Instr::instr_debug *debug = reinterpret_cast<QQmlJS::Moth::Instr::instr_debug *>(codePtr);
+ return debug->breakPoint;
}
bool Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr)
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index dc5a60b341..16bacbfafd 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include <qv4engine_p.h>
#include <qv4context_p.h>
-#include <qv4value_p.h>
+#include <qv4value_inl_p.h>
#include <qv4object_p.h>
#include <qv4objectproto_p.h>
#include <qv4objectiterator_p.h>
@@ -157,10 +157,10 @@ quintptr getStackLimit()
ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
- : memoryManager(new QV4::MemoryManager)
+ : current(0)
+ , memoryManager(new QV4::MemoryManager)
, executableAllocator(new QV4::ExecutableAllocator)
, regExpAllocator(new QV4::ExecutableAllocator)
- , current(0)
, bumperPointerAllocator(new WTF::BumpPointerAllocator)
, jsStack(new WTF::PageAllocation)
, debugger(0)
@@ -197,11 +197,11 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
// we allow it to grow to 2 times JSStackLimit, as we can overshoot due to garbage collection
// and ScopedValues allocated outside of JIT'ed methods.
*jsStack = WTF::PageAllocation::allocate(2*JSStackLimit, WTF::OSAllocator::JSVMStackPages, true);
- jsStackBase = (SafeValue *)jsStack->base();
+ jsStackBase = (Value *)jsStack->base();
jsStackTop = jsStackBase;
// set up stack limits
- jsStackLimit = jsStackBase + JSStackLimit/sizeof(SafeValue);
+ jsStackLimit = jsStackBase + JSStackLimit/sizeof(Value);
cStackLimit = getStackLimit();
Scope scope(this);
@@ -209,9 +209,9 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
identifierTable = new IdentifierTable(this);
emptyClass = new (classPool.allocate(sizeof(InternalClass))) InternalClass(this);
- executionContextClass = emptyClass->changeVTable(&ExecutionContext::static_vtbl);
- stringClass = emptyClass->changeVTable(&String::static_vtbl);
- regExpValueClass = emptyClass->changeVTable(&RegExp::static_vtbl);
+ executionContextClass = InternalClass::create(this, ExecutionContext::staticVTable(), 0);
+ stringClass = InternalClass::create(this, String::staticVTable(), 0);
+ regExpValueClass = InternalClass::create(this, RegExp::staticVTable(), 0);
id_undefined = newIdentifier(QStringLiteral("undefined"));
id_null = newIdentifier(QStringLiteral("null"));
@@ -244,69 +244,69 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
id_toString = newIdentifier(QStringLiteral("toString"));
id_valueOf = newIdentifier(QStringLiteral("valueOf"));
- ObjectPrototype *objectPrototype = new (memoryManager) ObjectPrototype(emptyClass->changeVTable(&ObjectPrototype::static_vtbl));
- objectClass = InternalClass::create(this, &Object::static_vtbl, objectPrototype);
- Q_ASSERT(objectClass->vtable == &Object::static_vtbl);
+ ObjectPrototype *objectPrototype = new (memoryManager) ObjectPrototype(InternalClass::create(this, ObjectPrototype::staticVTable(), 0));
+ objectClass = InternalClass::create(this, Object::staticVTable(), objectPrototype);
+ Q_ASSERT(objectClass->vtable == Object::staticVTable());
- arrayClass = InternalClass::create(this, &ArrayObject::static_vtbl, objectPrototype);
+ arrayClass = InternalClass::create(this, ArrayObject::staticVTable(), objectPrototype);
arrayClass = arrayClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable);
ArrayPrototype *arrayPrototype = new (memoryManager) ArrayPrototype(arrayClass);
arrayClass = arrayClass->changePrototype(arrayPrototype);
- InternalClass *argsClass = InternalClass::create(this, &ArgumentsObject::static_vtbl, objectPrototype);
+ InternalClass *argsClass = InternalClass::create(this, ArgumentsObject::staticVTable(), objectPrototype);
argsClass = argsClass->addMember(id_length, Attr_NotEnumerable);
argumentsObjectClass = argsClass->addMember(id_callee, Attr_Data|Attr_NotEnumerable);
strictArgumentsObjectClass = argsClass->addMember(id_callee, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
strictArgumentsObjectClass = strictArgumentsObjectClass->addMember(id_caller, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
- Q_ASSERT(argumentsObjectClass->vtable == &ArgumentsObject::static_vtbl);
- Q_ASSERT(strictArgumentsObjectClass->vtable == &ArgumentsObject::static_vtbl);
+ Q_ASSERT(argumentsObjectClass->vtable == ArgumentsObject::staticVTable());
+ Q_ASSERT(strictArgumentsObjectClass->vtable == ArgumentsObject::staticVTable());
initRootContext();
- StringPrototype *stringPrototype = new (memoryManager) StringPrototype(objectClass);
- stringObjectClass = InternalClass::create(this, &String::static_vtbl, stringPrototype);
+ StringPrototype *stringPrototype = new (memoryManager) StringPrototype(InternalClass::create(this, StringPrototype::staticVTable(), objectPrototype));
+ stringObjectClass = InternalClass::create(this, String::staticVTable(), stringPrototype);
- NumberPrototype *numberPrototype = new (memoryManager) NumberPrototype(objectClass);
- numberClass = InternalClass::create(this, &NumberObject::static_vtbl, numberPrototype);
+ NumberPrototype *numberPrototype = new (memoryManager) NumberPrototype(InternalClass::create(this, NumberPrototype::staticVTable(), objectPrototype));
+ numberClass = InternalClass::create(this, NumberObject::staticVTable(), numberPrototype);
- BooleanPrototype *booleanPrototype = new (memoryManager) BooleanPrototype(objectClass);
- booleanClass = InternalClass::create(this, &BooleanObject::static_vtbl, booleanPrototype);
+ BooleanPrototype *booleanPrototype = new (memoryManager) BooleanPrototype(InternalClass::create(this, BooleanPrototype::staticVTable(), objectPrototype));
+ booleanClass = InternalClass::create(this, BooleanObject::staticVTable(), booleanPrototype);
- DatePrototype *datePrototype = new (memoryManager) DatePrototype(objectClass);
- dateClass = InternalClass::create(this, &DateObject::static_vtbl, datePrototype);
+ DatePrototype *datePrototype = new (memoryManager) DatePrototype(InternalClass::create(this, DatePrototype::staticVTable(), objectPrototype));
+ dateClass = InternalClass::create(this, DateObject::staticVTable(), datePrototype);
- FunctionPrototype *functionPrototype = new (memoryManager) FunctionPrototype(InternalClass::create(this, &FunctionPrototype::static_vtbl, objectPrototype));
- functionClass = InternalClass::create(this, &FunctionObject::static_vtbl, functionPrototype);
+ FunctionPrototype *functionPrototype = new (memoryManager) FunctionPrototype(InternalClass::create(this, FunctionPrototype::staticVTable(), objectPrototype));
+ functionClass = InternalClass::create(this, FunctionObject::staticVTable(), functionPrototype);
uint index;
functionWithProtoClass = functionClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index);
Q_ASSERT(index == FunctionObject::Index_Prototype);
protoClass = objectClass->addMember(id_constructor, Attr_NotEnumerable, &index);
Q_ASSERT(index == FunctionObject::Index_ProtoConstructor);
- RegExpPrototype *regExpPrototype = new (memoryManager) RegExpPrototype(objectClass);
- regExpClass = InternalClass::create(this, &RegExpObject::static_vtbl, regExpPrototype);
+ RegExpPrototype *regExpPrototype = new (memoryManager) RegExpPrototype(InternalClass::create(this, RegExpPrototype::staticVTable(), objectPrototype));
+ regExpClass = InternalClass::create(this, RegExpObject::staticVTable(), regExpPrototype);
regExpExecArrayClass = arrayClass->addMember(id_index, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayIndex);
regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayInput);
- ErrorPrototype *errorPrototype = new (memoryManager) ErrorPrototype(objectClass);
- errorClass = InternalClass::create(this, &ErrorObject::static_vtbl, errorPrototype);
+ ErrorPrototype *errorPrototype = new (memoryManager) ErrorPrototype(InternalClass::create(this, ErrorObject::staticVTable(), objectPrototype));
+ errorClass = InternalClass::create(this, ErrorObject::staticVTable(), errorPrototype);
EvalErrorPrototype *evalErrorPrototype = new (memoryManager) EvalErrorPrototype(errorClass);
- evalErrorClass = InternalClass::create(this, &EvalErrorObject::static_vtbl, evalErrorPrototype);
+ evalErrorClass = InternalClass::create(this, EvalErrorObject::staticVTable(), evalErrorPrototype);
RangeErrorPrototype *rangeErrorPrototype = new (memoryManager) RangeErrorPrototype(errorClass);
- rangeErrorClass = InternalClass::create(this, &RangeErrorObject::static_vtbl, rangeErrorPrototype);
+ rangeErrorClass = InternalClass::create(this, RangeErrorObject::staticVTable(), rangeErrorPrototype);
ReferenceErrorPrototype *referenceErrorPrototype = new (memoryManager) ReferenceErrorPrototype(errorClass);
- referenceErrorClass = InternalClass::create(this, &ReferenceErrorObject::static_vtbl, referenceErrorPrototype);
+ referenceErrorClass = InternalClass::create(this, ReferenceErrorObject::staticVTable(), referenceErrorPrototype);
SyntaxErrorPrototype *syntaxErrorPrototype = new (memoryManager) SyntaxErrorPrototype(errorClass);
- syntaxErrorClass = InternalClass::create(this, &SyntaxErrorObject::static_vtbl, syntaxErrorPrototype);
+ syntaxErrorClass = InternalClass::create(this, SyntaxErrorObject::staticVTable(), syntaxErrorPrototype);
TypeErrorPrototype *typeErrorPrototype = new (memoryManager) TypeErrorPrototype(errorClass);
- typeErrorClass = InternalClass::create(this, &TypeErrorObject::static_vtbl, typeErrorPrototype);
+ typeErrorClass = InternalClass::create(this, TypeErrorObject::staticVTable(), typeErrorPrototype);
URIErrorPrototype *uRIErrorPrototype = new (memoryManager) URIErrorPrototype(errorClass);
- uriErrorClass = InternalClass::create(this, &URIErrorObject::static_vtbl, uRIErrorPrototype);
+ uriErrorClass = InternalClass::create(this, URIErrorObject::staticVTable(), uRIErrorPrototype);
- VariantPrototype *variantPrototype = new (memoryManager) VariantPrototype(InternalClass::create(this, &VariantPrototype::static_vtbl, objectPrototype));
- variantClass = InternalClass::create(this, &VariantObject::static_vtbl, variantPrototype);
+ VariantPrototype *variantPrototype = new (memoryManager) VariantPrototype(InternalClass::create(this, VariantPrototype::staticVTable(), objectPrototype));
+ variantClass = InternalClass::create(this, VariantObject::staticVTable(), variantPrototype);
Q_ASSERT(variantClass->prototype == variantPrototype);
Q_ASSERT(variantPrototype->internalClass->prototype == objectPrototype);
@@ -371,8 +371,8 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
globalObject->defineDefaultProperty(QStringLiteral("TypeError"), typeErrorCtor);
globalObject->defineDefaultProperty(QStringLiteral("URIError"), uRIErrorCtor);
ScopedObject o(scope);
- globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = new (memoryManager) MathObject(this)));
- globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = new (memoryManager) JsonObject(this)));
+ globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = new (memoryManager) MathObject(QV4::InternalClass::create(this, MathObject::staticVTable(), objectPrototype))));
+ globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = new (memoryManager) JsonObject(QV4::InternalClass::create(this, JsonObject::staticVTable(), objectPrototype))));
globalObject->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue());
globalObject->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN()));
@@ -457,7 +457,7 @@ Returned<FunctionObject> *ExecutionEngine::newBuiltinFunction(ExecutionContext *
return f->asReturned<FunctionObject>();
}
-Returned<BoundFunction> *ExecutionEngine::newBoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<SafeValue> &boundArgs)
+Returned<BoundFunction> *ExecutionEngine::newBoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<Value> &boundArgs)
{
Q_ASSERT(target);
@@ -511,6 +511,8 @@ Returned<ArrayObject> *ExecutionEngine::newArrayObject(int count)
ArrayObject *object = new (memoryManager) ArrayObject(this);
if (count) {
+ Scope scope(this);
+ ScopedValue protectArray(scope, object);
if (count < 0x1000)
object->arrayReserve(count);
object->setArrayLengthUnchecked(count);
@@ -558,7 +560,7 @@ Returned<RegExpObject> *ExecutionEngine::newRegExpObject(const QString &pattern,
return newRegExpObject(re, global);
}
-Returned<RegExpObject> *ExecutionEngine::newRegExpObject(Referenced<RegExp> re, bool global)
+Returned<RegExpObject> *ExecutionEngine::newRegExpObject(RegExpRef re, bool global)
{
RegExpObject *object = new (memoryManager) RegExpObject(this, re, global);
return object->asReturned<RegExpObject>();
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index ecb5f2b4d5..63c57b8478 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -121,11 +121,6 @@ struct ExecutionContextSaver;
struct Q_QML_EXPORT ExecutionEngine
{
- MemoryManager *memoryManager;
- ExecutableAllocator *executableAllocator;
- ExecutableAllocator *regExpAllocator;
- QScopedPointer<QQmlJS::EvalISelFactory> iselFactory;
-
private:
friend struct ExecutionContextSaver;
friend struct ExecutionContext;
@@ -133,20 +128,27 @@ private:
public:
ExecutionContext *currentContext() const { return current; }
+ Value *jsStackTop;
+ quint32 hasException;
GlobalContext *rootContext;
- SafeValue *jsStackTop;
- SafeValue *jsStackLimit;
+ MemoryManager *memoryManager;
+ ExecutableAllocator *executableAllocator;
+ ExecutableAllocator *regExpAllocator;
+ QScopedPointer<QQmlJS::EvalISelFactory> iselFactory;
+
+
+ Value *jsStackLimit;
quintptr cStackLimit;
WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine.
enum { JSStackLimit = 4*1024*1024 };
WTF::PageAllocation *jsStack;
- SafeValue *jsStackBase;
+ Value *jsStackBase;
- SafeValue *stackPush(uint nValues) {
- SafeValue *ptr = jsStackTop;
+ Value *stackPush(uint nValues) {
+ Value *ptr = jsStackTop;
jsStackTop = ptr + nValues;
return ptr;
}
@@ -174,22 +176,22 @@ public:
QV8Engine *v8Engine;
- SafeValue objectCtor;
- SafeValue stringCtor;
- SafeValue numberCtor;
- SafeValue booleanCtor;
- SafeValue arrayCtor;
- SafeValue functionCtor;
- SafeValue dateCtor;
- SafeValue regExpCtor;
- SafeValue errorCtor;
- SafeValue evalErrorCtor;
- SafeValue rangeErrorCtor;
- SafeValue referenceErrorCtor;
- SafeValue syntaxErrorCtor;
- SafeValue typeErrorCtor;
- SafeValue uRIErrorCtor;
- SafeValue sequencePrototype;
+ Value objectCtor;
+ Value stringCtor;
+ Value numberCtor;
+ Value booleanCtor;
+ Value arrayCtor;
+ Value functionCtor;
+ Value dateCtor;
+ Value regExpCtor;
+ Value errorCtor;
+ Value evalErrorCtor;
+ Value rangeErrorCtor;
+ Value referenceErrorCtor;
+ Value syntaxErrorCtor;
+ Value typeErrorCtor;
+ Value uRIErrorCtor;
+ Value sequencePrototype;
QQmlJS::MemoryPool classPool;
InternalClass *emptyClass;
@@ -228,36 +230,36 @@ public:
QVector<Property> argumentsAccessors;
- SafeString id_undefined;
- SafeString id_null;
- SafeString id_true;
- SafeString id_false;
- SafeString id_boolean;
- SafeString id_number;
- SafeString id_string;
- SafeString id_object;
- SafeString id_function;
- SafeString id_length;
- SafeString id_prototype;
- SafeString id_constructor;
- SafeString id_arguments;
- SafeString id_caller;
- SafeString id_callee;
- SafeString id_this;
- SafeString id___proto__;
- SafeString id_enumerable;
- SafeString id_configurable;
- SafeString id_writable;
- SafeString id_value;
- SafeString id_get;
- SafeString id_set;
- SafeString id_eval;
- SafeString id_uintMax;
- SafeString id_name;
- SafeString id_index;
- SafeString id_input;
- SafeString id_toString;
- SafeString id_valueOf;
+ StringValue id_undefined;
+ StringValue id_null;
+ StringValue id_true;
+ StringValue id_false;
+ StringValue id_boolean;
+ StringValue id_number;
+ StringValue id_string;
+ StringValue id_object;
+ StringValue id_function;
+ StringValue id_length;
+ StringValue id_prototype;
+ StringValue id_constructor;
+ StringValue id_arguments;
+ StringValue id_caller;
+ StringValue id_callee;
+ StringValue id_this;
+ StringValue id___proto__;
+ StringValue id_enumerable;
+ StringValue id_configurable;
+ StringValue id_writable;
+ StringValue id_value;
+ StringValue id_get;
+ StringValue id_set;
+ StringValue id_eval;
+ StringValue id_uintMax;
+ StringValue id_name;
+ StringValue id_index;
+ StringValue id_input;
+ StringValue id_toString;
+ StringValue id_valueOf;
QSet<CompiledData::CompilationUnit*> compilationUnits;
QMap<quintptr, QV4::Function*> allFunctions;
@@ -295,7 +297,7 @@ public:
ExecutionContext *popContext();
Returned<FunctionObject> *newBuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(CallContext *));
- Returned<BoundFunction> *newBoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<SafeValue> &boundArgs);
+ Returned<BoundFunction> *newBoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<Value> &boundArgs);
Returned<Object> *newObject();
Returned<Object> *newObject(InternalClass *internalClass);
@@ -315,7 +317,7 @@ public:
Returned<DateObject> *newDateObject(const QDateTime &dt);
Returned<RegExpObject> *newRegExpObject(const QString &pattern, int flags);
- Returned<RegExpObject> *newRegExpObject(Referenced<RegExp> re, bool global);
+ Returned<RegExpObject> *newRegExpObject(RegExpRef re, bool global);
Returned<RegExpObject> *newRegExpObject(const QRegExp &re);
Returned<Object> *newErrorObject(const ValueRef value);
@@ -352,8 +354,7 @@ public:
bool recheckCStackLimits();
// Exception handling
- SafeValue exceptionValue;
- quint32 hasException;
+ Value exceptionValue;
StackTrace exceptionStackTrace;
ReturnedValue throwException(const ValueRef value);
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index cf5c06dd41..29615e8ec2 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -76,8 +76,6 @@ ErrorObject::ErrorObject(InternalClass *ic)
: Object(ic)
, stack(0)
{
- type = Type_ErrorObject;
-
Scope scope(engine());
ScopedValue protectThis(scope, this);
@@ -89,7 +87,6 @@ ErrorObject::ErrorObject(InternalClass *ic, const ValueRef message, ErrorType t)
: Object(ic)
, stack(0)
{
- type = Type_ErrorObject;
subtype = t;
Scope scope(engine());
@@ -113,7 +110,6 @@ ErrorObject::ErrorObject(InternalClass *ic, const QString &message, ErrorObject:
: Object(ic)
, stack(0)
{
- type = Type_ErrorObject;
subtype = t;
Scope scope(engine());
@@ -137,7 +133,6 @@ ErrorObject::ErrorObject(InternalClass *ic, const QString &message, const QStrin
: Object(ic)
, stack(0)
{
- type = Type_ErrorObject;
subtype = t;
Scope scope(engine());
@@ -196,9 +191,9 @@ void ErrorObject::markObjects(Managed *that, ExecutionEngine *e)
Object::markObjects(that, e);
}
-DEFINE_MANAGED_VTABLE(ErrorObject);
+DEFINE_OBJECT_VTABLE(ErrorObject);
-DEFINE_MANAGED_VTABLE(SyntaxErrorObject);
+DEFINE_OBJECT_VTABLE(SyntaxErrorObject);
SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const ValueRef msg)
: ErrorObject(engine->syntaxErrorClass, msg, SyntaxError)
@@ -255,24 +250,24 @@ URIErrorObject::URIErrorObject(ExecutionEngine *engine, const ValueRef message)
{
}
-DEFINE_MANAGED_VTABLE(ErrorCtor);
-DEFINE_MANAGED_VTABLE(EvalErrorCtor);
-DEFINE_MANAGED_VTABLE(RangeErrorCtor);
-DEFINE_MANAGED_VTABLE(ReferenceErrorCtor);
-DEFINE_MANAGED_VTABLE(SyntaxErrorCtor);
-DEFINE_MANAGED_VTABLE(TypeErrorCtor);
-DEFINE_MANAGED_VTABLE(URIErrorCtor);
+DEFINE_OBJECT_VTABLE(ErrorCtor);
+DEFINE_OBJECT_VTABLE(EvalErrorCtor);
+DEFINE_OBJECT_VTABLE(RangeErrorCtor);
+DEFINE_OBJECT_VTABLE(ReferenceErrorCtor);
+DEFINE_OBJECT_VTABLE(SyntaxErrorCtor);
+DEFINE_OBJECT_VTABLE(TypeErrorCtor);
+DEFINE_OBJECT_VTABLE(URIErrorCtor);
ErrorCtor::ErrorCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("Error"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ErrorCtor::ErrorCtor(ExecutionContext *scope, const QString &name)
: FunctionObject(scope, name)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue ErrorCtor::construct(Managed *m, CallData *callData)
@@ -284,13 +279,13 @@ ReturnedValue ErrorCtor::construct(Managed *m, CallData *callData)
ReturnedValue ErrorCtor::call(Managed *that, CallData *callData)
{
- return that->construct(callData);
+ return static_cast<Object *>(that)->construct(callData);
}
EvalErrorCtor::EvalErrorCtor(ExecutionContext *scope)
: ErrorCtor(scope, QStringLiteral("EvalError"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData)
@@ -303,7 +298,7 @@ ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData)
RangeErrorCtor::RangeErrorCtor(ExecutionContext *scope)
: ErrorCtor(scope, QStringLiteral("RangeError"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData)
@@ -316,7 +311,7 @@ ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData)
ReferenceErrorCtor::ReferenceErrorCtor(ExecutionContext *scope)
: ErrorCtor(scope, QStringLiteral("ReferenceError"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData)
@@ -329,7 +324,7 @@ ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData)
SyntaxErrorCtor::SyntaxErrorCtor(ExecutionContext *scope)
: ErrorCtor(scope, QStringLiteral("SyntaxError"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData)
@@ -342,7 +337,7 @@ ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData)
TypeErrorCtor::TypeErrorCtor(ExecutionContext *scope)
: ErrorCtor(scope, QStringLiteral("TypeError"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData)
@@ -355,7 +350,7 @@ ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData)
URIErrorCtor::URIErrorCtor(ExecutionContext *scope)
: ErrorCtor(scope, QStringLiteral("URIError"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue URIErrorCtor::construct(Managed *m, CallData *callData)
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index def776d3b6..c44cc5cdb2 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -51,7 +51,11 @@ namespace QV4 {
struct SyntaxErrorObject;
struct ErrorObject: Object {
- Q_MANAGED
+ V4_OBJECT
+ Q_MANAGED_TYPE(ErrorObject)
+ enum {
+ IsErrorObject = true
+ };
enum ErrorType {
Error,
@@ -99,7 +103,7 @@ struct ReferenceErrorObject: ErrorObject {
};
struct SyntaxErrorObject: ErrorObject {
- Q_MANAGED
+ V4_OBJECT
SyntaxErrorObject(ExecutionEngine *engine, const ValueRef msg);
SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber);
};
@@ -115,7 +119,7 @@ struct URIErrorObject: ErrorObject {
struct ErrorCtor: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
ErrorCtor(ExecutionContext *scope);
ErrorCtor(ExecutionContext *scope, const QString &name);
@@ -125,7 +129,7 @@ struct ErrorCtor: FunctionObject
struct EvalErrorCtor: ErrorCtor
{
- Q_MANAGED
+ V4_OBJECT
EvalErrorCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *m, CallData *callData);
@@ -133,7 +137,7 @@ struct EvalErrorCtor: ErrorCtor
struct RangeErrorCtor: ErrorCtor
{
- Q_MANAGED
+ V4_OBJECT
RangeErrorCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *m, CallData *callData);
@@ -141,7 +145,7 @@ struct RangeErrorCtor: ErrorCtor
struct ReferenceErrorCtor: ErrorCtor
{
- Q_MANAGED
+ V4_OBJECT
ReferenceErrorCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *m, CallData *callData);
@@ -149,7 +153,7 @@ struct ReferenceErrorCtor: ErrorCtor
struct SyntaxErrorCtor: ErrorCtor
{
- Q_MANAGED
+ V4_OBJECT
SyntaxErrorCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *m, CallData *callData);
@@ -157,7 +161,7 @@ struct SyntaxErrorCtor: ErrorCtor
struct TypeErrorCtor: ErrorCtor
{
- Q_MANAGED
+ V4_OBJECT
TypeErrorCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *m, CallData *callData);
@@ -165,7 +169,7 @@ struct TypeErrorCtor: ErrorCtor
struct URIErrorCtor: ErrorCtor
{
- Q_MANAGED
+ V4_OBJECT
URIErrorCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *m, CallData *callData);
@@ -184,37 +188,37 @@ struct ErrorPrototype: ErrorObject
struct EvalErrorPrototype: ErrorObject
{
- EvalErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); }
+ EvalErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
};
struct RangeErrorPrototype: ErrorObject
{
- RangeErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); }
+ RangeErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
};
struct ReferenceErrorPrototype: ErrorObject
{
- ReferenceErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); }
+ ReferenceErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
};
struct SyntaxErrorPrototype: ErrorObject
{
- SyntaxErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); }
+ SyntaxErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
};
struct TypeErrorPrototype: ErrorObject
{
- TypeErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); }
+ TypeErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
};
struct URIErrorPrototype: ErrorObject
{
- URIErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(&static_vtbl); }
+ URIErrorPrototype(InternalClass *ic): ErrorObject(ic) { setVTable(staticVTable()); }
void init(ExecutionEngine *engine, ObjectRef ctor) { ErrorPrototype::init(engine, ctor, this); }
};
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 0e90e213c4..811b445f9e 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -42,7 +42,7 @@
#include "qv4function_p.h"
#include "qv4managed_p.h"
#include "qv4string_p.h"
-#include "qv4value_p.h"
+#include "qv4value_inl_p.h"
#include "qv4engine_p.h"
#include "qv4lookup_p.h"
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 8d07853b45..377b45bfa3 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -47,7 +47,7 @@
#include <QtCore/QByteArray>
#include <QtCore/qurl.h>
-#include "qv4value_def_p.h"
+#include "qv4value_p.h"
#include <private/qv4compileddata_p.h>
#include <private/qv4engine_p.h>
@@ -81,7 +81,7 @@ struct InternalClass;
struct Lookup;
struct Function {
- SafeString name;
+ StringValue name;
const CompiledData::Function *compiledFunction;
CompiledData::CompilationUnit *compilationUnit;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index ce81282aa3..a3e47c42ca 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -71,7 +71,7 @@
using namespace QV4;
-DEFINE_MANAGED_VTABLE(FunctionObject);
+DEFINE_OBJECT_VTABLE(FunctionObject);
FunctionObject::FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto)
: Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass)
@@ -112,7 +112,6 @@ FunctionObject::FunctionObject(InternalClass *ic)
{
name = ic->engine->id_undefined;
- type = Type_FunctionObject;
needsActivation = false;
strictMode = false;
}
@@ -130,7 +129,6 @@ void FunctionObject::init(const StringRef n, bool createProto)
Scope s(internalClass->engine);
ScopedValue protectThis(s, this);
- type = Type_FunctionObject;
needsActivation = true;
strictMode = false;
@@ -224,19 +222,19 @@ InternalClass *FunctionObject::internalClassForConstructor()
Scope scope(internalClass->engine);
ScopedObject p(scope, proto);
if (p)
- classForConstructor = InternalClass::create(scope.engine, &Object::static_vtbl, p.getPointer());
+ classForConstructor = InternalClass::create(scope.engine, Object::staticVTable(), p.getPointer());
else
classForConstructor = scope.engine->objectClass;
return classForConstructor;
}
-DEFINE_MANAGED_VTABLE(FunctionCtor);
+DEFINE_OBJECT_VTABLE(FunctionCtor);
FunctionCtor::FunctionCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("Function"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
// 15.3.2
@@ -342,19 +340,19 @@ ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
if (!arg->isNullOrUndefined())
return ctx->throwTypeError();
} else {
- len = ArrayPrototype::getLength(ctx, arr);
+ len = arr->getLength();
}
ScopedCallData callData(scope, len);
if (len) {
- if (!(arr->flags & SimpleArray) || arr->protoHasArray() || arr->hasAccessorProperty) {
+ if (arr->arrayType() != ArrayData::Simple || arr->protoHasArray() || arr->hasAccessorProperty) {
for (quint32 i = 0; i < len; ++i)
callData->args[i] = arr->getIndexed(i);
} else {
- int alen = qMin(len, arr->arrayDataLen);
- for (int i = 0; i < alen; ++i)
- callData->args[i] = arr->arrayData[i].value;
+ int alen = qMin(len, arr->arrayData->length());
+ if (alen)
+ memcpy(callData->args, arr->arrayData->data, alen*sizeof(Value));
for (quint32 i = alen; i < len; ++i)
callData->args[i] = Primitive::undefinedValue();
}
@@ -389,19 +387,19 @@ ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
return ctx->throwTypeError();
ScopedValue boundThis(scope, ctx->argument(0));
- QVector<SafeValue> boundArgs;
+ QVector<Value> boundArgs;
for (int i = 1; i < ctx->callData->argc; ++i)
boundArgs += ctx->callData->args[i];
return ctx->engine->newBoundFunction(ctx->engine->rootContext, target, boundThis, boundArgs)->asReturnedValue();
}
-DEFINE_MANAGED_VTABLE(ScriptFunction);
+DEFINE_OBJECT_VTABLE(ScriptFunction);
ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
: FunctionObject(scope, function->name, true)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
Scope s(scope);
ScopedValue protectThis(s, this);
@@ -426,8 +424,8 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
if (scope->strictMode) {
Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
- *insertMember(scope->engine->id_caller, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd;
- *insertMember(scope->engine->id_arguments, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd;
+ insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
+ insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
}
@@ -478,12 +476,12 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
return f->function->code(ctx, f->function->codeData);
}
-DEFINE_MANAGED_VTABLE(SimpleScriptFunction);
+DEFINE_OBJECT_VTABLE(SimpleScriptFunction);
SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *function)
: FunctionObject(scope, function->name, true)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
Scope s(scope);
ScopedValue protectThis(s, this);
@@ -508,8 +506,8 @@ SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *fu
if (scope->strictMode) {
Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
- *insertMember(scope->engine->id_caller, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd;
- *insertMember(scope->engine->id_arguments, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd;
+ insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
+ insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
}
@@ -589,13 +587,13 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
-DEFINE_MANAGED_VTABLE(BuiltinFunction);
+DEFINE_OBJECT_VTABLE(BuiltinFunction);
BuiltinFunction::BuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(CallContext *))
: FunctionObject(scope, name)
, code(code)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue BuiltinFunction::construct(Managed *f, CallData *)
@@ -641,16 +639,16 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
return f->code(&ctx, f->index);
}
-DEFINE_MANAGED_VTABLE(IndexedBuiltinFunction);
+DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
-DEFINE_MANAGED_VTABLE(BoundFunction);
+DEFINE_OBJECT_VTABLE(BoundFunction);
-BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<SafeValue> &boundArgs)
+BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<Value> &boundArgs)
: FunctionObject(scope, QStringLiteral("__bound function__"))
, target(target)
, boundArgs(boundArgs)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
subtype = FunctionObject::BoundFunction;
this->boundThis = boundThis;
@@ -667,8 +665,8 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObjectRef target,
ExecutionEngine *v4 = scope->engine;
Property pd = Property::fromAccessor(v4->thrower, v4->thrower);
- *insertMember(scope->engine->id_arguments, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd;
- *insertMember(scope->engine->id_caller, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable) = pd;
+ insertMember(scope->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
+ insertMember(scope->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
void BoundFunction::destroy(Managed *that)
@@ -685,8 +683,8 @@ ReturnedValue BoundFunction::call(Managed *that, CallData *dd)
ScopedCallData callData(scope, f->boundArgs.size() + dd->argc);
callData->thisObject = f->boundThis;
- memcpy(callData->args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(SafeValue));
- memcpy(callData->args + f->boundArgs.size(), dd->args, dd->argc*sizeof(SafeValue));
+ 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);
}
@@ -698,8 +696,8 @@ ReturnedValue BoundFunction::construct(Managed *that, CallData *dd)
return Encode::undefined();
ScopedCallData callData(scope, f->boundArgs.size() + dd->argc);
- memcpy(callData->args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(SafeValue));
- memcpy(callData->args + f->boundArgs.size(), dd->args, dd->argc*sizeof(SafeValue));
+ 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 96534cb68c..af4ec024d5 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -93,7 +93,11 @@ struct InternalClass;
struct Lookup;
struct Q_QML_EXPORT FunctionObject: Object {
- Q_MANAGED
+ V4_OBJECT
+ Q_MANAGED_TYPE(FunctionObject)
+ enum {
+ IsFunctionObject = true
+ };
// Used with Managed::subType
enum FunctionType {
RegularFunction = 0,
@@ -107,7 +111,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
};
ExecutionContext *scope;
- SafeString name;
+ StringValue name;
unsigned int formalParameterCount;
unsigned int varCount;
Function *function;
@@ -124,14 +128,10 @@ struct Q_QML_EXPORT FunctionObject: Object {
ReturnedValue newInstance();
+ using Object::construct;
+ using Object::call;
static ReturnedValue construct(Managed *that, CallData *);
static ReturnedValue call(Managed *that, CallData *d);
- inline ReturnedValue construct(CallData *callData) {
- return internalClass->vtable->construct(this, callData);
- }
- inline ReturnedValue call(CallData *callData) {
- return internalClass->vtable->call(this, callData);
- }
static FunctionObject *cast(const Value &v) {
return v.asFunctionObject();
@@ -155,9 +155,11 @@ inline FunctionObject *value_cast(const Value &v) {
return v.asFunctionObject();
}
+DEFINE_REF(FunctionObject, Object);
+
struct FunctionCtor: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
FunctionCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *that, CallData *callData);
@@ -176,7 +178,7 @@ struct FunctionPrototype: FunctionObject
};
struct BuiltinFunction: FunctionObject {
- Q_MANAGED
+ V4_OBJECT
ReturnedValue (*code)(CallContext *);
BuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(CallContext *));
@@ -187,7 +189,7 @@ struct BuiltinFunction: FunctionObject {
struct IndexedBuiltinFunction: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
ReturnedValue (*code)(CallContext *ctx, uint index);
uint index;
@@ -197,7 +199,7 @@ struct IndexedBuiltinFunction: FunctionObject
, code(code)
, index(index)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
static ReturnedValue construct(Managed *m, CallData *)
@@ -210,7 +212,7 @@ struct IndexedBuiltinFunction: FunctionObject
struct ScriptFunction: FunctionObject {
- Q_MANAGED
+ V4_OBJECT
ScriptFunction(ExecutionContext *scope, Function *function);
static ReturnedValue construct(Managed *, CallData *callData);
@@ -218,7 +220,7 @@ struct ScriptFunction: FunctionObject {
};
struct SimpleScriptFunction: FunctionObject {
- Q_MANAGED
+ V4_OBJECT
SimpleScriptFunction(ExecutionContext *scope, Function *function);
static ReturnedValue construct(Managed *, CallData *callData);
@@ -226,12 +228,12 @@ struct SimpleScriptFunction: FunctionObject {
};
struct BoundFunction: FunctionObject {
- Q_MANAGED
+ V4_OBJECT
FunctionObject *target;
- SafeValue boundThis;
- QVector<SafeValue> boundArgs;
+ Value boundThis;
+ QVector<Value> boundArgs;
- BoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<SafeValue> &boundArgs);
+ BoundFunction(ExecutionContext *scope, FunctionObjectRef target, const ValueRef boundThis, const QVector<Value> &boundArgs);
~BoundFunction() {}
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 1d465df0c0..746513cc2f 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -156,12 +156,16 @@ template<typename T> struct Returned;
typedef Returned<String> ReturnedString;
typedef Returned<Object> ReturnedObject;
typedef Returned<FunctionObject> ReturnedFunctionObject;
-template<typename T> struct Referenced;
-typedef Referenced<Managed> ManagedRef;
-typedef Referenced<String> StringRef;
-typedef Referenced<Object> ObjectRef;
-typedef Referenced<ArrayObject> ArrayObjectRef;
-typedef Referenced<FunctionObject> FunctionObjectRef;
+struct ManagedRef;
+struct StringRef;
+struct ObjectRef;
+struct ArrayObjectRef;
+struct FunctionObjectRef;
+struct RegExpRef;
+
+struct PersistentValuePrivate;
+class PersistentValue;
+class WeakValue;
namespace Global {
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index fa8af8ed5d..76a8b0c25c 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -41,7 +41,7 @@
#include "qv4globalobject_p.h"
#include "qv4mm_p.h"
-#include "qv4value_p.h"
+#include "qv4value_inl_p.h"
#include "qv4context_p.h"
#include "qv4function_p.h"
#include "qv4debugging_p.h"
@@ -344,12 +344,12 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok)
return QString();
}
-DEFINE_MANAGED_VTABLE(EvalFunction);
+DEFINE_OBJECT_VTABLE(EvalFunction);
EvalFunction::EvalFunction(ExecutionContext *scope)
: FunctionObject(scope, scope->engine->id_eval)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
defineReadonlyProperty(scope->engine->id_length, Primitive::fromInt32(1));
}
diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h
index bf529a465d..63823acc19 100644
--- a/src/qml/jsruntime/qv4globalobject_p.h
+++ b/src/qml/jsruntime/qv4globalobject_p.h
@@ -50,12 +50,12 @@ namespace QV4 {
struct Q_QML_EXPORT EvalFunction : FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
EvalFunction(ExecutionContext *scope);
ReturnedValue evalCall(CallData *callData, bool directCall);
- using Managed::construct;
+ using Object::construct;
static ReturnedValue call(Managed *that, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index d0e0e9413b..7642db1e9b 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -131,8 +131,8 @@ void QV4Include::finished()
QVariant redirect = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
m_url = m_url.resolved(redirect.toUrl());
- delete m_reply;
-
+ delete m_reply;
+
QNetworkRequest request;
request.setUrl(m_url);
@@ -209,7 +209,7 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
callbackFunction);
result = i->result();
- } else {
+ } else {
QFile f(localFile);
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index c4c72f3a83..d1cadb3aa5 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -58,7 +58,7 @@
#include <private/qqmlcontext_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4context_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 29ede3d104..761a180722 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -183,6 +183,8 @@ InternalClass *InternalClass::changeMember(String *string, PropertyAttributes da
InternalClass *InternalClass::create(ExecutionEngine *engine, const ManagedVTable *vtable, Object *proto)
{
InternalClass *c = engine->emptyClass->changeVTable(vtable);
+ if (!proto)
+ return c;
return c->changePrototype(proto);
}
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 6633435668..20927ab8e7 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -66,6 +66,8 @@ static int indent = 0;
#endif
+DEFINE_OBJECT_VTABLE(JsonObject);
+
class JsonParser
{
public:
@@ -288,8 +290,7 @@ bool JsonParser::parseMember(ObjectRef o)
if (idx < UINT_MAX) {
o->putIndexed(idx, val);
} else {
- Property *p = o->insertMember(s, Attr_Data);
- p->value = val.asReturnedValue();
+ o->insertMember(s, val);
}
END;
@@ -337,7 +338,7 @@ ReturnedValue JsonParser::parseArray()
}
}
- DEBUG << "size =" << array->arrayLength();
+ DEBUG << "size =" << array->getLength();
END;
--nestingLevel;
@@ -853,7 +854,7 @@ QString Stringify::JA(ArrayObjectRef a)
indent += gap;
QStringList partial;
- uint len = a->arrayLength();
+ uint len = a->getLength();
ScopedValue v(scope);
for (uint i = 0; i < len; ++i) {
bool exists;
@@ -884,12 +885,10 @@ QString Stringify::JA(ArrayObjectRef a)
}
-JsonObject::JsonObject(ExecutionEngine *engine)
- : Object(engine)
+JsonObject::JsonObject(InternalClass *ic)
+ : Object(ic)
{
- type = Type_JSONObject;
-
- Scope scope(engine);
+ Scope scope(ic->engine);
ScopedObject protectThis(scope, this);
defineDefaultProperty(QStringLiteral("parse"), method_parse, 2);
@@ -925,7 +924,7 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
if (o) {
stringify.replacerFunction = o->asFunctionObject();
if (o->isArrayObject()) {
- uint arrayLen = o->arrayLength();
+ uint arrayLen = o->getLength();
ScopedValue v(scope);
for (uint i = 0; i < arrayLen; ++i) {
v = o->getIndexed(i);
@@ -1057,10 +1056,9 @@ QV4::ReturnedValue JsonObject::fromJsonArray(ExecutionEngine *engine, const QJso
int size = array.size();
Scoped<ArrayObject> a(scope, engine->newArrayObject());
a->arrayReserve(size);
- for (int i = 0; i < size; i++) {
- a->arrayData[i].value = fromJsonValue(engine, array.at(i));
- a->arrayDataLen = i + 1;
- }
+ ScopedValue v(scope);
+ for (int i = 0; i < size; i++)
+ a->arrayPut(i, (v = fromJsonValue(engine, array.at(i))));
a->setArrayLengthUnchecked(size);
return a.asReturnedValue();
}
@@ -1083,7 +1081,7 @@ QJsonArray JsonObject::toJsonArray(ArrayObjectRef a, V4ObjectSet &visitedObjects
visitedObjects.insert(a);
ScopedValue v(scope);
- quint32 length = a->arrayLength();
+ quint32 length = a->getLength();
for (quint32 i = 0; i < length; ++i) {
v = a->getIndexed(i);
if (v->asFunctionObject())
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index 3bcbdeadbf..34a4f4dd4b 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -51,10 +51,12 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct JsonObject : Object {
+ Q_MANAGED_TYPE(JsonObject)
+ V4_OBJECT
private:
typedef QSet<QV4::Object *> V4ObjectSet;
public:
- JsonObject(ExecutionEngine *engine);
+ JsonObject(InternalClass *ic);
static ReturnedValue method_parse(CallContext *ctx);
static ReturnedValue method_stringify(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index a870cdac61..4a75272843 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -46,8 +46,40 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-Property *Lookup::lookup(Object *obj, PropertyAttributes *attrs)
+
+ReturnedValue Lookup::lookup(ValueRef thisObject, Object *obj, PropertyAttributes *attrs)
+{
+ int i = 0;
+ while (i < Size && obj) {
+ classList[i] = obj->internalClass;
+
+ index = obj->internalClass->find(name);
+ if (index != UINT_MAX) {
+ level = i;
+ *attrs = obj->internalClass->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData[index].value.asReturnedValue() : obj->getValue(thisObject, obj->memberData + index, *attrs);
+ }
+
+ obj = obj->prototype();
+ ++i;
+ }
+ level = Size;
+
+ while (obj) {
+ index = obj->internalClass->find(name);
+ if (index != UINT_MAX) {
+ *attrs = obj->internalClass->propertyData.at(index);
+ return !attrs->isAccessor() ? obj->memberData[index].value.asReturnedValue() : obj->getValue(thisObject, obj->memberData + index, *attrs);
+ }
+
+ obj = obj->prototype();
+ }
+ return Primitive::emptyValue().asReturnedValue();
+}
+
+ReturnedValue Lookup::lookup(Object *obj, PropertyAttributes *attrs)
{
+ Object *thisObject = obj;
int i = 0;
while (i < Size && obj) {
classList[i] = obj->internalClass;
@@ -56,7 +88,7 @@ Property *Lookup::lookup(Object *obj, PropertyAttributes *attrs)
if (index != UINT_MAX) {
level = i;
*attrs = obj->internalClass->propertyData.at(index);
- return obj->memberData + index;
+ return !attrs->isAccessor() ? obj->memberData[index].value.asReturnedValue() : thisObject->getValue(obj->memberData + index, *attrs);
}
obj = obj->prototype();
@@ -68,14 +100,142 @@ Property *Lookup::lookup(Object *obj, PropertyAttributes *attrs)
index = obj->internalClass->find(name);
if (index != UINT_MAX) {
*attrs = obj->internalClass->propertyData.at(index);
- return obj->memberData + index;
+ return !attrs->isAccessor() ? obj->memberData[index].value.asReturnedValue() : thisObject->getValue(obj->memberData + index, *attrs);
}
obj = obj->prototype();
}
- return 0;
+ return Primitive::emptyValue().asReturnedValue();
+}
+
+ReturnedValue Lookup::indexedGetterGeneric(Lookup *l, const ValueRef object, const ValueRef index)
+{
+ if (object->isObject() && index->asArrayIndex() < UINT_MAX) {
+ l->indexedGetter = indexedGetterObjectInt;
+ return indexedGetterObjectInt(l, object, index);
+ }
+ return indexedGetterFallback(l, object, index);
+}
+
+ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const ValueRef object, const ValueRef index)
+{
+ Q_UNUSED(l);
+ ExecutionContext *ctx = l->engine->currentContext();
+ Scope scope(ctx);
+ uint idx = index->asArrayIndex();
+
+ Scoped<Object> o(scope, object);
+ if (!o) {
+ if (idx < UINT_MAX) {
+ if (String *str = object->asString()) {
+ if (idx >= (uint)str->toQString().length()) {
+ return Encode::undefined();
+ }
+ const QString s = str->toQString().mid(idx, 1);
+ return scope.engine->newString(s)->asReturnedValue();
+ }
+ }
+
+ if (object->isNullOrUndefined()) {
+ QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index->toQStringNoThrow()).arg(object->toQStringNoThrow());
+ return ctx->throwTypeError(message);
+ }
+
+ o = __qmljs_convert_to_object(ctx, object);
+ if (!o) // type error
+ return Encode::undefined();
+ }
+
+ if (idx < UINT_MAX) {
+ if (!o->arrayData->hasAttributes()) {
+ ScopedValue v(scope, o->arrayData->get(idx));
+ if (!v->isEmpty())
+ return v->asReturnedValue();
+ }
+
+ return o->getIndexed(idx);
+ }
+
+ ScopedString name(scope, index->toString(ctx));
+ if (scope.hasException())
+ return Encode::undefined();
+ return o->get(name);
+
+}
+
+
+ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const ValueRef object, const ValueRef index)
+{
+ uint idx = index->asArrayIndex();
+ if (idx == UINT_MAX || !object->isObject())
+ return indexedGetterGeneric(l, object, index);
+
+ Object *o = object->objectValue();
+ if (o->arrayData && o->arrayData->type == ArrayData::Simple) {
+ if (idx < static_cast<SimpleArrayData *>(o->arrayData)->len)
+ if (!o->arrayData->data[idx].isEmpty())
+ return o->arrayData->data[idx].asReturnedValue();
+ }
+
+ return indexedGetterFallback(l, object, index);
+}
+
+void Lookup::indexedSetterGeneric(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v)
+{
+ if (object->isObject()) {
+ Object *o = object->objectValue();
+ if (o->arrayData && o->arrayData->type == ArrayData::Simple && index->asArrayIndex() < UINT_MAX) {
+ l->indexedSetter = indexedSetterObjectInt;
+ indexedSetterObjectInt(l, object, index, v);
+ return;
+ }
+ }
+ indexedSetterFallback(l, object, index, v);
+}
+
+void Lookup::indexedSetterFallback(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef value)
+{
+ ExecutionContext *ctx = l->engine->currentContext();
+ Scope scope(ctx);
+ ScopedObject o(scope, object->toObject(ctx));
+ if (scope.engine->hasException)
+ return;
+
+ uint idx = index->asArrayIndex();
+ if (idx < UINT_MAX) {
+ if (o->arrayData && o->arrayData->type == ArrayData::Simple) {
+ SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData);
+ if (s && idx < s->len && !s->data[idx].isEmpty()) {
+ s->data[idx] = value;
+ return;
+ }
+ }
+ o->putIndexed(idx, value);
+ return;
+ }
+
+ ScopedString name(scope, index->toString(ctx));
+ o->put(name, value);
}
+void Lookup::indexedSetterObjectInt(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v)
+{
+ uint idx = index->asArrayIndex();
+ if (idx == UINT_MAX || !object->isObject()) {
+ indexedSetterGeneric(l, object, index, v);
+ return;
+ }
+
+ Object *o = object->objectValue();
+ if (o->arrayData && o->arrayData->type == ArrayData::Simple) {
+ SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData);
+ if (idx < s->len && !s->data[idx].isEmpty()) {
+ s->data[idx] = v;
+ return;
+ }
+ }
+ indexedSetterFallback(l, object, index, v);
+}
ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object)
{
@@ -106,8 +266,8 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object)
}
PropertyAttributes attrs;
- Property *p = l->lookup(proto, &attrs);
- if (p) {
+ ReturnedValue v = l->lookup(object, proto, &attrs);
+ if (v != Primitive::emptyValue().asReturnedValue()) {
l->type = object->type();
l->proto = proto;
if (attrs.isData()) {
@@ -115,13 +275,13 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object)
l->getter = Lookup::primitiveGetter0;
else if (l->level == 1)
l->getter = Lookup::primitiveGetter1;
- return p->value.asReturnedValue();
+ return v;
} else {
if (l->level == 0)
l->getter = Lookup::primitiveGetterAccessor0;
else if (l->level == 1)
l->getter = Lookup::primitiveGetterAccessor1;
- return proto->getValue(object, p, attrs);
+ return v;
}
}
@@ -316,13 +476,22 @@ ReturnedValue Lookup::stringLengthGetter(Lookup *l, const ValueRef object)
return getterGeneric(l, object);
}
+ReturnedValue Lookup::arrayLengthGetter(Lookup *l, const ValueRef object)
+{
+ if (ArrayObject *a = object->asArrayObject())
+ return a->memberData[ArrayObject::LengthPropertyIndex].value.asReturnedValue();
+
+ l->getter = getterGeneric;
+ return getterGeneric(l, object);
+}
+
ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx)
{
Object *o = ctx->engine->globalObject;
PropertyAttributes attrs;
- Property *p = l->lookup(o, &attrs);
- if (p) {
+ ReturnedValue v = l->lookup(o, &attrs);
+ if (v != Primitive::emptyValue().asReturnedValue()) {
if (attrs.isData()) {
if (l->level == 0)
l->globalGetter = globalGetter0;
@@ -330,7 +499,7 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx)
l->globalGetter = globalGetter1;
else if (l->level == 2)
l->globalGetter = globalGetter2;
- return p->value.asReturnedValue();
+ return v;
} else {
if (l->level == 0)
l->globalGetter = globalGetterAccessor0;
@@ -338,7 +507,7 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx)
l->globalGetter = globalGetterAccessor1;
else if (l->level == 2)
l->globalGetter = globalGetterAccessor2;
- return o->getValue(p, attrs);
+ return v;
}
}
Scope scope(ctx);
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index 9966d36604..7f107bf8eb 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -55,11 +55,14 @@ namespace QV4 {
struct Lookup {
enum { Size = 4 };
union {
+ ReturnedValue (*indexedGetter)(Lookup *l, const ValueRef object, const ValueRef index);
+ void (*indexedSetter)(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v);
ReturnedValue (*getter)(Lookup *l, const ValueRef object);
ReturnedValue (*globalGetter)(Lookup *l, ExecutionContext *ctx);
void (*setter)(Lookup *l, const ValueRef object, const ValueRef v);
};
union {
+ ExecutionEngine *engine;
InternalClass *classList[Size];
struct {
void *dummy0;
@@ -72,6 +75,14 @@ struct Lookup {
uint index;
String *name;
+ static ReturnedValue indexedGetterGeneric(Lookup *l, const ValueRef object, const ValueRef index);
+ static ReturnedValue indexedGetterFallback(Lookup *l, const ValueRef object, const ValueRef index);
+ static ReturnedValue indexedGetterObjectInt(Lookup *l, const ValueRef object, const ValueRef index);
+
+ static void indexedSetterGeneric(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v);
+ static void indexedSetterFallback(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef value);
+ static void indexedSetterObjectInt(Lookup *l, const ValueRef object, const ValueRef index, const ValueRef v);
+
static ReturnedValue getterGeneric(Lookup *l, const ValueRef object);
static ReturnedValue getter0(Lookup *l, const ValueRef object);
static ReturnedValue getter1(Lookup *l, const ValueRef object);
@@ -85,6 +96,7 @@ struct Lookup {
static ReturnedValue primitiveGetterAccessor0(Lookup *l, const ValueRef object);
static ReturnedValue primitiveGetterAccessor1(Lookup *l, const ValueRef object);
static ReturnedValue stringLengthGetter(Lookup *l, const ValueRef object);
+ static ReturnedValue arrayLengthGetter(Lookup *l, const ValueRef object);
static ReturnedValue globalGetterGeneric(Lookup *l, ExecutionContext *ctx);
static ReturnedValue globalGetter0(Lookup *l, ExecutionContext *ctx);
@@ -100,7 +112,8 @@ struct Lookup {
static void setterInsert1(Lookup *l, const ValueRef object, const ValueRef value);
static void setterInsert2(Lookup *l, const ValueRef object, const ValueRef value);
- Property *lookup(Object *obj, PropertyAttributes *attrs);
+ ReturnedValue lookup(ValueRef thisObject, Object *obj, PropertyAttributes *attrs);
+ ReturnedValue lookup(Object *obj, PropertyAttributes *attrs);
};
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index fef7489110..1f4030a4ed 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -47,24 +47,18 @@ using namespace QV4;
const ManagedVTable Managed::static_vtbl =
{
- call,
- construct,
- 0 /*markObjects*/,
- destroy,
- 0 /*collectDeletables*/,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- isEqualTo,
+ Managed::IsExecutionContext,
+ Managed::IsString,
+ Managed::IsObject,
+ Managed::IsFunctionObject,
+ Managed::IsErrorObject,
+ Managed::IsArrayData,
0,
+ Managed::MyType,
"Managed",
+ destroy,
+ 0 /*markObjects*/,
+ isEqualTo
};
@@ -101,7 +95,7 @@ ExecutionEngine *Managed::engine() const
QString Managed::className() const
{
const char *s = 0;
- switch (Type(type)) {
+ switch (Type(internalClass->vtable->type)) {
case Type_Invalid:
case Type_String:
return QString();
@@ -157,18 +151,23 @@ QString Managed::className() const
case Type_ArgumentsObject:
s = "Arguments";
break;
- case Type_JSONObject:
+ case Type_JsonObject:
s = "JSON";
break;
case Type_MathObject:
s = "Math";
break;
+
+ case Type_ExecutionContext:
+ s = "__ExecutionContext";
+ break;
case Type_ForeachIteratorObject:
s = "__ForeachIterator";
break;
case Type_RegExp:
- s = "RegExp";
+ s = "__RegExp";
break;
+
case Type_QmlSequence:
s = "QmlSequence";
break;
@@ -182,67 +181,7 @@ void Managed::setVTable(const ManagedVTable *vt)
internalClass = internalClass->changeVTable(vt);
}
-ReturnedValue Managed::construct(Managed *m, CallData *)
-{
- return m->engine()->currentContext()->throwTypeError();
-}
-
-ReturnedValue Managed::call(Managed *m, CallData *)
-{
- return m->engine()->currentContext()->throwTypeError();
-}
-
-ReturnedValue Managed::getLookup(Managed *m, Lookup *)
-{
- return m->engine()->currentContext()->throwTypeError();
-}
-
-void Managed::setLookup(Managed *m, Lookup *, const ValueRef)
-{
- m->engine()->currentContext()->throwTypeError();
-}
-
bool Managed::isEqualTo(Managed *, Managed *)
{
return false;
}
-
-ReturnedValue Managed::get(const StringRef name, bool *hasProperty)
-{
- return internalClass->vtable->get(this, name, hasProperty);
-}
-
-ReturnedValue Managed::getIndexed(uint index, bool *hasProperty)
-{
- return internalClass->vtable->getIndexed(this, index, hasProperty);
-}
-
-void Managed::put(const StringRef name, const ValueRef value)
-{
- internalClass->vtable->put(this, name, value);
-}
-
-void Managed::setLookup(Lookup *l, const ValueRef v)
-{
- internalClass->vtable->setLookup(this, l, v);
-}
-
-void Managed::putIndexed(uint index, const ValueRef value)
-{
- internalClass->vtable->putIndexed(this, index, value);
-}
-
-PropertyAttributes Managed::query(StringRef name) const
-{
- return internalClass->vtable->query(this, name);
-}
-
-bool Managed::deleteProperty(const StringRef name)
-{
- return internalClass->vtable->deleteProperty(this, name);
-}
-
-Property *Managed::advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes)
-{
- return internalClass->vtable->advanceIterator(this, it, name, index, attributes);
-}
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index e10409f397..8c6f2daf9b 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -45,7 +45,7 @@
#include <QtCore/QVector>
#include <QtCore/QDebug>
#include "qv4global_p.h"
-#include "qv4value_def_p.h"
+#include "qv4value_p.h"
#include "qv4internalclass_p.h"
QT_BEGIN_NAMESPACE
@@ -53,8 +53,8 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
#define Q_MANAGED_CHECK \
- template <typename T> inline void qt_check_for_QMANAGED_macro(const T &_q_argument) const \
- { int i = qYouForgotTheQ_MANAGED_Macro(this, &_q_argument); i = i + 1; }
+ template <typename T> inline void qt_check_for_QMANAGED_macro(const T *_q_argument) const \
+ { int i = qYouForgotTheQ_MANAGED_Macro(this, _q_argument); i = i + 1; }
template <typename T>
inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; }
@@ -62,13 +62,25 @@ inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; }
template <typename T1, typename T2>
inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
-#define Q_MANAGED \
+#define V4_MANAGED \
public: \
Q_MANAGED_CHECK \
static const QV4::ManagedVTable static_vtbl; \
+ static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl; } \
template <typename T> \
QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+#define V4_OBJECT \
+ public: \
+ Q_MANAGED_CHECK \
+ static const QV4::ObjectVTable static_vtbl; \
+ static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
+ template <typename T> \
+ QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+
+#define Q_MANAGED_TYPE(type) \
+ public: \
+ enum { MyType = Type_##type };
struct GCDeletable
{
@@ -80,10 +92,25 @@ struct GCDeletable
struct ManagedVTable
{
+ uint isExecutionContext : 1;
+ uint isString : 1;
+ uint isObject : 1;
+ uint isFunctionObject : 1;
+ uint isErrorObject : 1;
+ uint isArrayData : 1;
+ uint unused : 18;
+ uint type : 8;
+ const char *className;
+ void (*destroy)(Managed *);
+ void (*markObjects)(Managed *, ExecutionEngine *e);
+ bool (*isEqualTo)(Managed *m, Managed *other);
+};
+
+struct ObjectVTable
+{
+ ManagedVTable managedVTable;
ReturnedValue (*call)(Managed *, CallData *data);
ReturnedValue (*construct)(Managed *, CallData *data);
- void (*markObjects)(Managed *, ExecutionEngine *e);
- void (*destroy)(Managed *);
void (*collectDeletables)(Managed *, GCDeletable **deletable);
ReturnedValue (*get)(Managed *, const StringRef name, bool *hasProperty);
ReturnedValue (*getIndexed)(Managed *, uint index, bool *hasProperty);
@@ -95,18 +122,58 @@ struct ManagedVTable
bool (*deleteIndexedProperty)(Managed *m, uint index);
ReturnedValue (*getLookup)(Managed *m, Lookup *l);
void (*setLookup)(Managed *m, Lookup *l, const ValueRef v);
- bool (*isEqualTo)(Managed *m, Managed *other);
- Property *(*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
- const char *className;
+ uint (*getLength)(const Managed *m);
+ void (*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
};
+#define DEFINE_MANAGED_VTABLE_INT(classname) \
+{ \
+ classname::IsExecutionContext, \
+ classname::IsString, \
+ classname::IsObject, \
+ classname::IsFunctionObject, \
+ classname::IsErrorObject, \
+ classname::IsArrayData, \
+ 0, \
+ classname::MyType, \
+ #classname, \
+ destroy, \
+ markObjects, \
+ isEqualTo \
+}
+
+
#define DEFINE_MANAGED_VTABLE(classname) \
-const QV4::ManagedVTable classname::static_vtbl = \
+const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname)
+
+
+#define DEFINE_OBJECT_VTABLE(classname) \
+const QV4::ObjectVTable classname::static_vtbl = \
+{ \
+ DEFINE_MANAGED_VTABLE_INT(classname), \
+ call, \
+ construct, \
+ 0, \
+ get, \
+ getIndexed, \
+ put, \
+ putIndexed, \
+ query, \
+ queryIndexed, \
+ deleteProperty, \
+ deleteIndexedProperty, \
+ getLookup, \
+ setLookup, \
+ getLength, \
+ advanceIterator \
+}
+
+#define DEFINE_MANAGED_VTABLE_WITH_NAME(classname, name) \
+const QV4::ObjectVTable classname::static_vtbl = \
{ \
+ DEFINE_MANAGED_VTABLE_INT(name), \
call, \
construct, \
- markObjects, \
- destroy, \
0, \
get, \
getIndexed, \
@@ -118,18 +185,16 @@ const QV4::ManagedVTable classname::static_vtbl = \
deleteIndexedProperty, \
getLookup, \
setLookup, \
- isEqualTo, \
- advanceIterator, \
- #classname \
+ getLength, \
+ advanceIterator \
}
#define DEFINE_MANAGED_VTABLE_WITH_DELETABLES(classname) \
-const QV4::ManagedVTable classname::static_vtbl = \
+const QV4::ObjectVTable classname::static_vtbl = \
{ \
+ DEFINE_MANAGED_VTABLE_INT(classname), \
call, \
construct, \
- markObjects, \
- destroy, \
collectDeletables, \
get, \
getIndexed, \
@@ -141,14 +206,21 @@ const QV4::ManagedVTable classname::static_vtbl = \
deleteIndexedProperty, \
getLookup, \
setLookup, \
- isEqualTo, \
- advanceIterator, \
- #classname \
+ getLength, \
+ advanceIterator \
}
struct Q_QML_EXPORT Managed
{
- Q_MANAGED
+ V4_MANAGED
+ enum {
+ IsExecutionContext = false,
+ IsString = false,
+ IsObject = false,
+ IsFunctionObject = false,
+ IsErrorObject = false,
+ IsArrayData = false
+ };
private:
void *operator new(size_t);
Managed(const Managed &other);
@@ -158,7 +230,7 @@ protected:
Managed(InternalClass *internal)
: internalClass(internal), _data(0)
{
- Q_ASSERT(!internalClass || internalClass->vtable);
+ Q_ASSERT(internalClass && internalClass->vtable);
inUse = 1; extensible = 1;
}
@@ -183,13 +255,16 @@ public:
Type_RegExpObject,
Type_ErrorObject,
Type_ArgumentsObject,
- Type_JSONObject,
+ Type_JsonObject,
Type_MathObject,
+
+ Type_ExecutionContext,
Type_ForeachIteratorObject,
Type_RegExp,
Type_QmlSequence
};
+ Q_MANAGED_TYPE(Invalid)
ExecutionEngine *engine() const;
@@ -199,9 +274,9 @@ public:
if (!this || !internalClass)
return 0;
#if !defined(QT_NO_QOBJECT_CHECK)
- static_cast<T *>(this)->qt_check_for_QMANAGED_macro(*static_cast<T *>(this));
+ static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(this));
#endif
- return internalClass->vtable == &T::static_vtbl ? static_cast<T *>(this) : 0;
+ return internalClass->vtable == T::staticVTable() ? static_cast<T *>(this) : 0;
}
template <typename T>
const T *as() const {
@@ -209,26 +284,26 @@ public:
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)));
+ static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(const_cast<Managed *>(this)));
#endif
- return internalClass->vtable == &T::static_vtbl ? static_cast<const T *>(this) : 0;
+ return internalClass->vtable == T::staticVTable() ? static_cast<const T *>(this) : 0;
}
- String *asString() { return type == Type_String ? reinterpret_cast<String *>(this) : 0; }
- Object *asObject() { return type != Type_String ? reinterpret_cast<Object *>(this) : 0; }
- 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; }
- NumberObject *asNumberObject() { return type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
- StringObject *asStringObject() { return type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
- DateObject *asDateObject() { return type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
- ErrorObject *asErrorObject() { return type == Type_ErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
- ArgumentsObject *asArgumentsObject() { return type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
+ String *asString() { return internalClass->vtable->isString ? reinterpret_cast<String *>(this) : 0; }
+ Object *asObject() { return internalClass->vtable->isObject ? reinterpret_cast<Object *>(this) : 0; }
+ ArrayObject *asArrayObject() { return internalClass->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
+ FunctionObject *asFunctionObject() { return internalClass->vtable->isFunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
+ BooleanObject *asBooleanObject() { return internalClass->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
+ NumberObject *asNumberObject() { return internalClass->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
+ StringObject *asStringObject() { return internalClass->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
+ DateObject *asDateObject() { return internalClass->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
+ ErrorObject *asErrorObject() { return internalClass->vtable->isErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
+ ArgumentsObject *asArgumentsObject() { return internalClass->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
- bool isListType() const { return type == Type_QmlSequence; }
+ bool isListType() const { return internalClass->vtable->type == Type_QmlSequence; }
- bool isArrayObject() const { return type == Type_ArrayObject; }
- bool isStringObject() const { return type == Type_StringObject; }
+ bool isArrayObject() const { return internalClass->vtable->type == Type_ArrayObject; }
+ bool isStringObject() const { return internalClass->vtable->type == Type_StringObject; }
QString className() const;
@@ -244,61 +319,31 @@ public:
void setVTable(const ManagedVTable *vt);
- ReturnedValue construct(CallData *d);
- ReturnedValue call(CallData *d);
- ReturnedValue get(const StringRef name, bool *hasProperty = 0);
- ReturnedValue getIndexed(uint index, bool *hasProperty = 0);
- void put(const StringRef name, const ValueRef value);
- void putIndexed(uint index, const ValueRef value);
- PropertyAttributes query(StringRef name) const;
- PropertyAttributes queryIndexed(uint index) const
- { return internalClass->vtable->queryIndexed(this, index); }
-
- bool deleteProperty(const StringRef name);
- bool deleteIndexedProperty(uint index)
- { return internalClass->vtable->deleteIndexedProperty(this, index); }
- ReturnedValue getLookup(Lookup *l)
- { return internalClass->vtable->getLookup(this, l); }
- void setLookup(Lookup *l, const ValueRef v);
-
bool isEqualTo(Managed *other)
{ return internalClass->vtable->isEqualTo(this, other); }
- Property *advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
static void destroy(Managed *that) { that->_data = 0; }
- 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 ValueRef v);
static bool isEqualTo(Managed *m, Managed *other);
- uint internalType() const {
- return type;
- }
-
ReturnedValue asReturnedValue() { return Value::fromManaged(this).asReturnedValue(); }
InternalClass *internalClass;
- enum {
- SimpleArray = 1
- };
-
union {
uint _data;
struct {
uchar markBit : 1;
uchar inUse : 1;
uchar extensible : 1; // used by Object
- uchar isNonStrictArgumentsObject : 1;
+ uchar _unused : 1;
uchar needsActivation : 1; // used by FunctionObject
uchar strictMode : 1; // used by FunctionObject
uchar bindingKeyFlag : 1;
uchar hasAccessorProperty : 1;
- uchar type;
+ uchar _type;
mutable uchar subtype;
- uchar flags;
+ uchar _flags;
};
};
@@ -308,6 +353,7 @@ private:
friend struct ObjectIterator;
};
+
template<>
inline Managed *value_cast(const Value &v) {
return v.asManaged();
@@ -336,12 +382,67 @@ inline FunctionObject *managed_cast(Managed *m)
}
-inline ReturnedValue Managed::construct(CallData *d) {
- return internalClass->vtable->construct(this, d);
-}
-inline ReturnedValue Managed::call(CallData *d) {
- return internalClass->vtable->call(this, d);
-}
+Value *extractValuePointer(const ScopedValue &);
+template<typename T>
+Value *extractValuePointer(const Scoped<T> &);
+
+#define DEFINE_REF_METHODS(Class, Base) \
+ Class##Ref(const QV4::ScopedValue &v) \
+ { QV4::Value *val = extractValuePointer(v); ptr = QV4::value_cast<Class>(*val) ? val : 0; } \
+ Class##Ref(const QV4::Scoped<Class> &v) { ptr = extractValuePointer(v); } \
+ Class##Ref(QV4::TypedValue<Class> &v) { ptr = &v; } \
+ Class##Ref(QV4::Value &v) { ptr = QV4::value_cast<Class>(v) ? &v : 0; } \
+ Class##Ref &operator=(Class *t) { \
+ if (sizeof(void *) == 4) \
+ ptr->tag = QV4::Value::Managed_Type; \
+ ptr->m = t; \
+ return *this; \
+ } \
+ Class##Ref &operator=(QV4::Returned<Class> *t) { \
+ if (sizeof(void *) == 4) \
+ ptr->tag = QV4::Value::Managed_Type; \
+ ptr->m = t->getPointer(); \
+ return *this; \
+ } \
+ operator const Class *() const { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
+ const Class *operator->() const { return static_cast<Class*>(ptr->managed()); } \
+ operator Class *() { return ptr ? static_cast<Class*>(ptr->managed()) : 0; } \
+ Class *operator->() { return static_cast<Class*>(ptr->managed()); } \
+ Class *getPointer() const { return static_cast<Class *>(ptr->managed()); } \
+ operator QV4::Returned<Class> *() const { return ptr ? QV4::Returned<Class>::create(getPointer()) : 0; } \
+ static Class##Ref null() { Class##Ref c; c.ptr = 0; return c; } \
+protected: \
+ Class##Ref() {} \
+public: \
+
+#define DEFINE_REF(Class, Base) \
+struct Class##Ref : public Base##Ref \
+{ DEFINE_REF_METHODS(Class, Base) } \
+
+
+struct ManagedRef {
+ // Important: Do NOT add a copy constructor to this class or any derived class
+ // adding a copy constructor actually changes the calling convention, ie.
+ // is not even binary compatible. Adding it would break assumptions made
+ // in the jit'ed code.
+ DEFINE_REF_METHODS(Managed, Managed);
+
+ bool operator==(const ManagedRef &other) {
+ if (ptr == other.ptr)
+ return true;
+ return ptr && other.ptr && ptr->m == other.ptr->m;
+ }
+ bool operator!=(const ManagedRef &other) {
+ return !operator==(other);
+ }
+ bool operator!() const { return !ptr || !ptr->managed(); }
+
+ bool isNull() const { return !ptr; }
+ ReturnedValue asReturnedValue() const { return ptr ? ptr->val : Primitive::undefinedValue().asReturnedValue(); }
+
+public:
+ Value *ptr;
+};
}
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index 5a7af1f041..16d76e6914 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -51,14 +51,14 @@
using namespace QV4;
+DEFINE_OBJECT_VTABLE(MathObject);
+
static const double qt_PI = 2.0 * ::asin(1.0);
-MathObject::MathObject(ExecutionEngine *engine)
- : Object(engine)
+MathObject::MathObject(InternalClass *ic)
+ : Object(ic)
{
- type = Type_MathObject;
-
- Scope scope(engine);
+ Scope scope(ic->engine);
ScopedObject protectThis(scope, this);
defineReadonlyProperty(QStringLiteral("E"), Primitive::fromDouble(::exp(1.0)));
diff --git a/src/qml/jsruntime/qv4mathobject_p.h b/src/qml/jsruntime/qv4mathobject_p.h
index 6fe3db3950..18a80c2ba0 100644
--- a/src/qml/jsruntime/qv4mathobject_p.h
+++ b/src/qml/jsruntime/qv4mathobject_p.h
@@ -49,7 +49,9 @@ namespace QV4 {
struct MathObject: Object
{
- MathObject(ExecutionEngine *engine);
+ V4_OBJECT
+ Q_MANAGED_TYPE(MathObject)
+ MathObject(InternalClass *ic);
static ReturnedValue method_abs(CallContext *context);
static ReturnedValue method_acos(CallContext *context);
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index 1d6347b335..7bb41f1eec 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -288,6 +288,7 @@ Managed *MemoryManager::alloc(std::size_t size)
if (size >= MemoryManager::Data::MaxItemSize) {
// we use malloc for this
MemoryManager::Data::LargeItem *item = static_cast<MemoryManager::Data::LargeItem *>(malloc(size + sizeof(MemoryManager::Data::LargeItem)));
+ memset(item, 0, size + sizeof(MemoryManager::Data::LargeItem));
item->next = m_d->largeItems;
m_d->largeItems = item;
return item->managed();
@@ -354,7 +355,7 @@ Managed *MemoryManager::alloc(std::size_t size)
void MemoryManager::mark()
{
- SafeValue *markBase = m_d->engine->jsStackTop;
+ Value *markBase = m_d->engine->jsStackTop;
m_d->engine->markObjects();
@@ -529,10 +530,12 @@ void MemoryManager::sweep(char *chunkStart, std::size_t chunkSize, size_t size,
#ifdef V4_USE_VALGRIND
VALGRIND_ENABLE_ERROR_REPORTING;
#endif
- if (m->internalClass->vtable->collectDeletables)
- m->internalClass->vtable->collectDeletables(m, deletable);
+ Object *o = m->asObject();
+ if (o && o->vtable()->collectDeletables)
+ o->vtable()->collectDeletables(m, deletable);
m->internalClass->vtable->destroy(m);
+ memset(m, 0, size);
m->setNextFree(*f);
#ifdef V4_USE_VALGRIND
VALGRIND_DISABLE_ERROR_REPORTING;
@@ -695,8 +698,8 @@ void MemoryManager::collectFromStack() const
void MemoryManager::collectFromJSStack() const
{
- SafeValue *v = engine()->jsStackBase;
- SafeValue *top = engine()->jsStackTop;
+ Value *v = engine()->jsStackBase;
+ Value *top = engine()->jsStackTop;
while (v < top) {
Managed *m = v->asManaged();
if (m && m->inUse)
diff --git a/src/qml/jsruntime/qv4mm_p.h b/src/qml/jsruntime/qv4mm_p.h
index 7d28319536..a8fd585332 100644
--- a/src/qml/jsruntime/qv4mm_p.h
+++ b/src/qml/jsruntime/qv4mm_p.h
@@ -44,7 +44,7 @@
#include "qv4global_p.h"
#include "qv4context_p.h"
-#include "qv4value_p.h"
+#include "qv4value_inl_p.h"
#include <QScopedPointer>
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index a363a06242..decbcab7a0 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -48,13 +48,13 @@
using namespace QV4;
-DEFINE_MANAGED_VTABLE(NumberCtor);
-DEFINE_MANAGED_VTABLE(NumberObject);
+DEFINE_OBJECT_VTABLE(NumberCtor);
+DEFINE_OBJECT_VTABLE(NumberObject);
NumberCtor::NumberCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("Number"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue NumberCtor::construct(Managed *m, CallData *callData)
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index 1ca3a71249..ccabcf6727 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -51,7 +51,7 @@ namespace QV4 {
struct NumberCtor: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
NumberCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *that, CallData *callData);
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 106525d412..de84747221 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -67,42 +67,30 @@
using namespace QV4;
-DEFINE_MANAGED_VTABLE(Object);
+DEFINE_OBJECT_VTABLE(Object);
Object::Object(ExecutionEngine *engine)
: Managed(engine->objectClass)
, memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
- , arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayAttributes(0), arrayData(0), sparseArray(0)
{
- type = Type_Object;
- flags = SimpleArray;
- memset(memberData, 0, sizeof(Property)*memberDataAlloc);
}
Object::Object(InternalClass *ic)
: Managed(ic)
, memberDataAlloc(InlinePropertySize), memberData(inlineProperties)
- , arrayOffset(0), arrayDataLen(0), arrayAlloc(0), arrayAttributes(0), arrayData(0), sparseArray(0)
{
Q_ASSERT(internalClass->vtable && internalClass->vtable != &Managed::static_vtbl);
- type = Type_Object;
- flags = SimpleArray;
if (internalClass->size >= memberDataAlloc) {
memberDataAlloc = internalClass->size;
memberData = new Property[memberDataAlloc];
}
- memset(memberData, 0, sizeof(Property)*memberDataAlloc);
}
Object::~Object()
{
if (memberData != inlineProperties)
delete [] memberData;
- delete [] (arrayData - (sparseArray ? 0 : arrayOffset));
- if (arrayAttributes)
- delete [] (arrayAttributes - (sparseArray ? 0 : arrayOffset));
- delete sparseArray;
_data = 0;
}
@@ -150,12 +138,12 @@ void Object::putValue(Property *pd, PropertyAttributes attrs, const ValueRef val
return;
if (attrs.isAccessor()) {
- if (pd->set) {
- Scope scope(pd->set->engine());
+ if (FunctionObject *set = pd->setter()) {
+ Scope scope(set->engine());
ScopedCallData callData(scope, 1);
callData->args[0] = *value;
callData->thisObject = this;
- pd->set->call(callData);
+ set->call(callData);
return;
}
goto reject;
@@ -172,12 +160,6 @@ void Object::putValue(Property *pd, PropertyAttributes attrs, const ValueRef val
engine()->currentContext()->throwTypeError();
}
-void Object::defineDefaultProperty(const StringRef name, ValueRef value)
-{
- Property *pd = insertMember(name, Attr_Data|Attr_NotEnumerable);
- pd->value = *value;
-}
-
void Object::defineDefaultProperty(const QString &name, ValueRef value)
{
ExecutionEngine *e = engine();
@@ -216,12 +198,11 @@ void Object::defineAccessorProperty(const QString &name, ReturnedValue (*getter)
void Object::defineAccessorProperty(const StringRef name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *))
{
ExecutionEngine *v4 = engine();
- Property *p = insertMember(name, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
-
- if (getter)
- p->setGetter(v4->newBuiltinFunction(v4->rootContext, name, getter)->getPointer());
- if (setter)
- p->setSetter(v4->newBuiltinFunction(v4->rootContext, name, setter)->getPointer());
+ QV4::Scope scope(v4);
+ ScopedProperty p(scope);
+ p->setGetter(getter ? v4->newBuiltinFunction(v4->rootContext, name, getter)->getPointer() : 0);
+ p->setSetter(setter ? v4->newBuiltinFunction(v4->rootContext, name, setter)->getPointer() : 0);
+ insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
void Object::defineReadonlyProperty(const QString &name, ValueRef value)
@@ -234,8 +215,7 @@ void Object::defineReadonlyProperty(const QString &name, ValueRef value)
void Object::defineReadonlyProperty(const StringRef name, ValueRef value)
{
- Property *pd = insertMember(name, Attr_ReadOnly);
- pd->value = *value;
+ insertMember(name, value, Attr_ReadOnly);
}
void Object::markObjects(Managed *that, ExecutionEngine *e)
@@ -248,33 +228,13 @@ void Object::markObjects(Managed *that, ExecutionEngine *e)
} else {
for (uint i = 0; i < o->internalClass->size; ++i) {
const Property &pd = o->memberData[i];
- if (o->internalClass->propertyData[i].isAccessor()) {
- if (pd.getter())
- pd.getter()->mark(e);
- if (pd.setter())
- pd.setter()->mark(e);
- } else {
- pd.value.mark(e);
- }
- }
- }
- if (o->flags & SimpleArray) {
- for (uint i = 0; i < o->arrayDataLen; ++i)
- o->arrayData[i].value.mark(e);
- return;
- } else {
- for (uint i = 0; i < o->arrayDataLen; ++i) {
- const Property &pd = o->arrayData[i];
- if (o->arrayAttributes && o->arrayAttributes[i].isAccessor()) {
- if (pd.getter())
- pd.getter()->mark(e);
- if (pd.setter())
- pd.setter()->mark(e);
- } else {
- pd.value.mark(e);
- }
+ pd.value.mark(e);
+ if (o->internalClass->propertyData[i].isAccessor())
+ pd.set.mark(e);
}
}
+ if (o->arrayData)
+ o->arrayData->mark(e);
}
void Object::ensureMemberIndex(uint idx)
@@ -290,7 +250,7 @@ void Object::ensureMemberIndex(uint idx)
}
}
-Property *Object::insertMember(const StringRef s, PropertyAttributes attributes)
+void Object::insertMember(const StringRef s, const Property &p, PropertyAttributes attributes)
{
uint idx;
internalClass = internalClass->addMember(s.getPointer(), attributes, &idx);
@@ -300,7 +260,7 @@ Property *Object::insertMember(const StringRef s, PropertyAttributes attributes)
ensureMemberIndex(idx);
- return memberData + idx;
+ memberData[idx] = p;
}
// Section 8.12.1
@@ -324,14 +284,11 @@ Property *Object::__getOwnProperty__(const StringRef name, PropertyAttributes *a
Property *Object::__getOwnProperty__(uint index, PropertyAttributes *attrs)
{
- uint pidx = propertyIndexFromArrayIndex(index);
- if (pidx < UINT_MAX) {
- Property *p = arrayData + pidx;
- if (!p->value.isEmpty() && !(arrayAttributes && arrayAttributes[pidx].isGeneric())) {
- if (attrs)
- *attrs = arrayAttributes ? arrayAttributes[pidx] : PropertyAttributes(Attr_Data);
- return p;
- }
+ Property *p = arrayData->getProperty(index);
+ if (p) {
+ if (attrs)
+ *attrs = arrayData->attributes(index);
+ return p;
}
if (isStringObject()) {
if (attrs)
@@ -349,7 +306,7 @@ Property *Object::__getPropertyDescriptor__(const StringRef name, PropertyAttrib
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
- return __getPropertyDescriptor__(idx);
+ return __getPropertyDescriptor__(idx, attrs);
const Object *o = this;
@@ -372,14 +329,11 @@ Property *Object::__getPropertyDescriptor__(uint index, PropertyAttributes *attr
{
const Object *o = this;
while (o) {
- uint pidx = o->propertyIndexFromArrayIndex(index);
- if (pidx < UINT_MAX) {
- Property *p = o->arrayData + pidx;
- if (!p->value.isEmpty()) {
- if (attrs)
- *attrs = o->arrayAttributes ? o->arrayAttributes[pidx] : PropertyAttributes(Attr_Data);
- return p;
- }
+ Property *p = o->arrayData->getProperty(index);
+ if (p) {
+ if (attrs)
+ *attrs = o->arrayData->attributes(index);
+ return p;
}
if (o->isStringObject()) {
Property *p = static_cast<const StringObject *>(o)->getIndex(index);
@@ -396,36 +350,73 @@ Property *Object::__getPropertyDescriptor__(uint index, PropertyAttributes *attr
return 0;
}
-bool Object::__hasProperty__(const StringRef name) const
+bool Object::hasProperty(const StringRef name) const
{
- if (__getPropertyDescriptor__(name))
- return true;
+ uint idx = name->asArrayIndex();
+ if (idx != UINT_MAX)
+ return hasProperty(idx);
const Object *o = this;
while (o) {
- if (!o->query(name).isEmpty())
+ if (o->hasOwnProperty(name))
return true;
+
o = o->prototype();
}
return false;
}
-bool Object::__hasProperty__(uint index) const
+bool Object::hasProperty(uint index) const
{
- if (__getPropertyDescriptor__(index))
- return true;
-
const Object *o = this;
while (o) {
- if (!o->queryIndexed(index).isEmpty())
- return true;
+ if (o->hasOwnProperty(index))
+ return true;
+
o = o->prototype();
}
return false;
}
+bool Object::hasOwnProperty(const StringRef name) const
+{
+ uint idx = name->asArrayIndex();
+ if (idx != UINT_MAX)
+ return hasOwnProperty(idx);
+
+ if (internalClass->find(name) < UINT_MAX)
+ return true;
+ if (!query(name).isEmpty())
+ return true;
+ return false;
+}
+
+bool Object::hasOwnProperty(uint index) const
+{
+ if (!arrayData->isEmpty(index))
+ return true;
+ if (isStringObject()) {
+ String *s = static_cast<const StringObject *>(this)->value.asString();
+ if (index < (uint)s->length())
+ return true;
+ }
+ if (!queryIndexed(index).isEmpty())
+ return true;
+ return false;
+}
+
+ReturnedValue Object::construct(Managed *m, CallData *)
+{
+ return m->engine()->currentContext()->throwTypeError();
+}
+
+ReturnedValue Object::call(Managed *m, CallData *)
+{
+ return m->engine()->currentContext()->throwTypeError();
+}
+
ReturnedValue Object::get(Managed *m, const StringRef name, bool *hasProperty)
{
return static_cast<Object *>(m)->internalGet(name, hasProperty);
@@ -463,17 +454,13 @@ PropertyAttributes Object::query(const Managed *m, StringRef name)
PropertyAttributes Object::queryIndexed(const Managed *m, uint index)
{
const Object *o = static_cast<const Object *>(m);
- uint pidx = o->propertyIndexFromArrayIndex(index);
- if (pidx < UINT_MAX) {
- if (o->arrayAttributes)
- return o->arrayAttributes[pidx];
- if (!o->arrayData[pidx].value.isEmpty())
- return Attr_Data;
- }
+ if (o->arrayData->get(index) != Primitive::emptyValue().asReturnedValue())
+ return o->arrayData->attributes(index);
+
if (o->isStringObject()) {
- Property *p = static_cast<const StringObject *>(o)->getIndex(index);
- if (p)
- return Attr_Data;
+ String *s = static_cast<const StringObject *>(o)->value.asString();
+ if (index < (uint)s->length())
+ return (Attr_NotWritable|Attr_NotConfigurable);
}
return Attr_Invalid;
}
@@ -492,8 +479,8 @@ ReturnedValue Object::getLookup(Managed *m, Lookup *l)
{
Object *o = static_cast<Object *>(m);
PropertyAttributes attrs;
- Property *p = l->lookup(o, &attrs);
- if (p) {
+ ReturnedValue v = l->lookup(o, &attrs);
+ if (v != Primitive::emptyValue().asReturnedValue()) {
if (attrs.isData()) {
if (l->level == 0)
l->getter = Lookup::getter0;
@@ -501,7 +488,7 @@ ReturnedValue Object::getLookup(Managed *m, Lookup *l)
l->getter = Lookup::getter1;
else if (l->level == 2)
l->getter = Lookup::getter2;
- return p->value.asReturnedValue();
+ return v;
} else {
if (l->level == 0)
l->getter = Lookup::getterAccessor0;
@@ -509,7 +496,7 @@ ReturnedValue Object::getLookup(Managed *m, Lookup *l)
l->getter = Lookup::getterAccessor1;
else if (l->level == 2)
l->getter = Lookup::getterAccessor2;
- return o->getValue(p, attrs);
+ return v;
}
}
return Encode::undefined();
@@ -564,46 +551,47 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value)
l->setter = Lookup::setterInsert2;
}
-Property *Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
+void Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *pd, PropertyAttributes *attrs)
{
Object *o = static_cast<Object *>(m);
name = (String *)0;
*index = UINT_MAX;
- if (!it->arrayIndex)
- it->arrayNode = o->sparseArrayBegin();
-
- // sparse arrays
- if (it->arrayNode) {
- while (it->arrayNode != o->sparseArrayEnd()) {
- int k = it->arrayNode->key();
- uint pidx = it->arrayNode->value;
- Property *p = o->arrayData + pidx;
- it->arrayNode = it->arrayNode->nextNode();
- PropertyAttributes a = o->arrayAttributes ? o->arrayAttributes[pidx] : PropertyAttributes(Attr_Data);
- if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
- it->arrayIndex = k + 1;
- *index = k;
- if (attrs)
+ if (o->arrayData) {
+ if (!it->arrayIndex)
+ it->arrayNode = o->sparseBegin();
+
+ // sparse arrays
+ if (it->arrayNode) {
+ while (it->arrayNode != o->sparseEnd()) {
+ int k = it->arrayNode->key();
+ uint pidx = it->arrayNode->value;
+ Property *p = reinterpret_cast<Property *>(o->arrayData->data + pidx);
+ it->arrayNode = it->arrayNode->nextNode();
+ PropertyAttributes a = o->arrayData->attributes(k);
+ if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
+ it->arrayIndex = k + 1;
+ *index = k;
*attrs = a;
- return p;
+ *pd = *p;
+ return;
+ }
}
+ it->arrayNode = 0;
+ it->arrayIndex = UINT_MAX;
}
- it->arrayNode = 0;
- it->arrayIndex = UINT_MAX;
- }
- // dense arrays
- while (it->arrayIndex < o->arrayDataLen) {
- uint pidx = o->propertyIndexFromArrayIndex(it->arrayIndex);
- Property *p = o->arrayData + pidx;
- PropertyAttributes a = o->arrayAttributes ? o->arrayAttributes[pidx] : PropertyAttributes(Attr_Data);
- ++it->arrayIndex;
- if (!p->value.isEmpty()
- && (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable())) {
- *index = it->arrayIndex - 1;
- if (attrs)
+ // dense arrays
+ while (it->arrayIndex < o->arrayData->length()) {
+ Value *val = o->arrayData->data + it->arrayIndex;
+ PropertyAttributes a = o->arrayData->attributes(it->arrayIndex);
+ ++it->arrayIndex;
+ if (!val->isEmpty()
+ && (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable())) {
+ *index = it->arrayIndex - 1;
*attrs = a;
- return p;
+ pd->value = *val;
+ return;
+ }
}
}
@@ -616,13 +604,13 @@ Property *Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name
++it->memberIndex;
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
name = n;
- if (attrs)
- *attrs = a;
- return p;
+ *attrs = a;
+ *pd = *p;
+ return;
}
}
- return 0;
+ *attrs = PropertyAttributes();
}
// Section 8.12.3
@@ -654,17 +642,14 @@ ReturnedValue Object::internalGet(const StringRef name, bool *hasProperty)
ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty)
{
Property *pd = 0;
- PropertyAttributes attrs = Attr_Data;
+ PropertyAttributes attrs;
Object *o = this;
while (o) {
- uint pidx = o->propertyIndexFromArrayIndex(index);
- if (pidx < UINT_MAX) {
- if (!o->arrayData[pidx].value.isEmpty()) {
- pd = o->arrayData + pidx;
- if (o->arrayAttributes)
- attrs = o->arrayAttributes[pidx];
- break;
- }
+ Property *p = o->arrayData->getProperty(index);
+ if (p) {
+ pd = p;
+ attrs = o->arrayData->attributes(index);
+ break;
}
if (o->isStringObject()) {
pd = static_cast<StringObject *>(o)->getIndex(index);
@@ -761,11 +746,8 @@ void Object::internalPut(const StringRef name, const ValueRef value)
return;
}
- {
- Property *p = insertMember(name, Attr_Data);
- p->value = *value;
- return;
- }
+ insertMember(name, value);
+ return;
reject:
if (engine()->currentContext()->strictMode) {
@@ -781,14 +763,11 @@ void Object::internalPutIndexed(uint index, const ValueRef value)
if (internalClass->engine->hasException)
return;
- Property *pd = 0;
PropertyAttributes attrs;
- uint pidx = propertyIndexFromArrayIndex(index);
- if (pidx < UINT_MAX && !arrayData[pidx].value.isEmpty()) {
- pd = arrayData + pidx;
- attrs = arrayAttributes ? arrayAttributes[pidx] : PropertyAttributes(Attr_Data);
- }
+ Property *pd = arrayData->getProperty(index);
+ if (pd)
+ attrs = arrayData->attributes(index);
if (!pd && isStringObject()) {
pd = static_cast<StringObject *>(this)->getIndex(index);
@@ -879,22 +858,8 @@ bool Object::internalDeleteIndexedProperty(uint index)
if (internalClass->engine->hasException)
return false;
- uint pidx = propertyIndexFromArrayIndex(index);
- if (pidx == UINT_MAX)
- return true;
- if (arrayData[pidx].value.isEmpty())
- return true;
-
- if (!arrayAttributes || arrayAttributes[pidx].isConfigurable()) {
- arrayData[pidx].value = Primitive::emptyValue();
- if (arrayAttributes)
- arrayAttributes[pidx].clear();
- if (sparseArray) {
- arrayData[pidx].value.int_32 = arrayFreeList;
- arrayFreeList = pidx;
- }
+ if (!arrayData || arrayData->vtable()->del(this, index))
return true;
- }
if (engine()->currentContext()->strictMode)
engine()->currentContext()->throwTypeError();
@@ -913,6 +878,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name,
Scope scope(ctx);
Property *current;
PropertyAttributes *cattrs;
+ uint memberIndex;
if (isArrayObject() && name->equals(ctx->engine->id_length)) {
assert(ArrayObject::LengthPropertyIndex == internalClass->find(ctx->engine->id_length));
@@ -943,24 +909,22 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, const StringRef name,
}
// Clause 1
- {
- uint member = internalClass->find(name.getPointer());
- current = (member < UINT_MAX) ? memberData + member : 0;
- cattrs = internalClass->propertyData.constData() + member;
- }
+ memberIndex = internalClass->find(name.getPointer());
+ current = (memberIndex < UINT_MAX) ? memberData + memberIndex : 0;
+ cattrs = internalClass->propertyData.constData() + memberIndex;
if (!current) {
// clause 3
if (!extensible)
goto reject;
// clause 4
- Property *pd = insertMember(name, attrs);
- *pd = p;
- pd->fullyPopulated(&attrs);
+ Property pd = p;
+ pd.fullyPopulated(&attrs);
+ insertMember(name, pd, attrs);
return true;
}
- return __defineOwnProperty__(ctx, current, name, p, attrs);
+ return __defineOwnProperty__(ctx, memberIndex, name, p, attrs);
reject:
if (ctx->strictMode)
ctx->throwTypeError();
@@ -969,20 +933,27 @@ reject:
bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs)
{
- Property *current = 0;
-
// 15.4.5.1, 4b
- if (isArrayObject() && index >= arrayLength() && !internalClass->propertyData[ArrayObject::LengthPropertyIndex].isWritable())
+ if (isArrayObject() && index >= getLength() && !internalClass->propertyData[ArrayObject::LengthPropertyIndex].isWritable())
goto reject;
- if (isNonStrictArgumentsObject)
+ if (ArgumentsObject::isNonStrictArgumentsObject(this))
return static_cast<ArgumentsObject *>(this)->defineOwnProperty(ctx, index, p, attrs);
+ return defineOwnProperty2(ctx, index, p, attrs);
+reject:
+ if (ctx->strictMode)
+ ctx->throwTypeError();
+ return false;
+}
+
+bool Object::defineOwnProperty2(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs)
+{
+ Property *current = 0;
+
// Clause 1
{
- uint pidx = propertyIndexFromArrayIndex(index);
- if (pidx < UINT_MAX && !arrayData[pidx].value.isEmpty())
- current = arrayData + pidx;
+ current = arrayData->getProperty(index);
if (!current && isStringObject())
current = static_cast<StringObject *>(this)->getIndex(index);
}
@@ -992,30 +963,40 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Prop
if (!extensible)
goto reject;
// clause 4
- Property *pd = arrayInsert(index, attrs);
- *pd = p;
- pd->fullyPopulated(&attrs);
+ Property pp(p);
+ pp.fullyPopulated(&attrs);
+ if (attrs == Attr_Data) {
+ Scope scope(ctx);
+ ScopedValue v(scope, pp.value);
+ arraySet(index, v);
+ } else {
+ arraySet(index, pp, attrs);
+ }
return true;
}
- return __defineOwnProperty__(ctx, current, StringRef::null(), p, attrs);
+ return __defineOwnProperty__(ctx, index, StringRef::null(), p, attrs);
reject:
if (ctx->strictMode)
ctx->throwTypeError();
return false;
}
-bool Object::__defineOwnProperty__(ExecutionContext *ctx, Property *current, const StringRef member, const Property &p, PropertyAttributes attrs)
+bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const StringRef member, const Property &p, PropertyAttributes attrs)
{
// clause 5
if (attrs.isEmpty())
return true;
- PropertyAttributes cattrs = Attr_Data;
- if (!member.isNull())
- cattrs = internalClass->propertyData[current - memberData];
- else if (arrayAttributes)
- cattrs = arrayAttributes[current - arrayData];
+ Property *current;
+ PropertyAttributes cattrs;
+ if (!member.isNull()) {
+ current = memberData + index;
+ cattrs = internalClass->propertyData[index];
+ } else {
+ current = arrayData->getProperty(index);
+ cattrs = arrayData->attributes(index);
+ }
// clause 6
if (p.isSubset(attrs, *current, cattrs))
@@ -1042,12 +1023,23 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, Property *current, con
// 9b
cattrs.setType(PropertyAttributes::Accessor);
cattrs.clearWritable();
+ if (member.isNull()) {
+ // need to convert the array and the slot
+ initSparseArray();
+ setArrayAttributes(index, cattrs);
+ current = arrayData->getProperty(index);
+ }
current->setGetter(0);
current->setSetter(0);
} else {
// 9c
cattrs.setType(PropertyAttributes::Data);
cattrs.setWritable(false);
+ if (member.isNull()) {
+ // need to convert the array and the slot
+ setArrayAttributes(index, cattrs);
+ current = arrayData->getProperty(index);
+ }
current->value = Primitive::undefinedValue();
}
} else if (cattrs.isData() && attrs.isData()) { // clause 10
@@ -1056,11 +1048,11 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, Property *current, con
goto reject;
}
} else { // clause 10
- assert(cattrs.isAccessor() && attrs.isAccessor());
+ Q_ASSERT(cattrs.isAccessor() && attrs.isAccessor());
if (!cattrs.isConfigurable()) {
- if (p.getter() && !(current->getter() == p.getter() || (!current->getter() && (quintptr)p.getter() == 0x1)))
+ if (!p.value.isEmpty() && current->value.val != p.value.val)
goto reject;
- if (p.setter() && !(current->setter() == p.setter() || (!current->setter() && (quintptr)p.setter() == 0x1)))
+ if (!p.set.isEmpty() && current->set.val != p.set.val)
goto reject;
}
}
@@ -1071,12 +1063,9 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, Property *current, con
if (!member.isNull()) {
internalClass = internalClass->changeMember(member.getPointer(), cattrs);
} else {
- if (cattrs != Attr_Data)
- ensureArrayAttributes();
- if (arrayAttributes)
- arrayAttributes[current - arrayData] = cattrs;
+ setArrayAttributes(index, cattrs);
}
- if (attrs.isAccessor())
+ if (cattrs.isAccessor())
hasAccessorProperty = 1;
return true;
reject:
@@ -1100,323 +1089,83 @@ void Object::copyArrayData(Object *other)
Scope scope(engine());
if (other->protoHasArray() || other->hasAccessorProperty) {
- uint len = other->arrayLength();
+ uint len = other->getLength();
Q_ASSERT(len);
ScopedValue v(scope);
for (uint i = 0; i < len; ++i) {
arraySet(i, (v = other->getIndexed(i)));
}
- } else {
- arrayReserve(other->arrayDataLen);
- arrayDataLen = other->arrayDataLen;
- memcpy(arrayData, other->arrayData, arrayDataLen*sizeof(Property));
- }
-
- arrayOffset = 0;
-
- if (other->sparseArray) {
- flags &= ~SimpleArray;
- sparseArray = new SparseArray(*other->sparseArray);
- arrayFreeList = other->arrayFreeList;
- }
-
- setArrayLengthUnchecked(other->arrayLength());
-}
-
-
-ReturnedValue Object::arrayIndexOf(const ValueRef v, uint fromIndex, uint endIndex, ExecutionContext *ctx, Object *o)
-{
- Q_UNUSED(ctx);
-
- Scope scope(engine());
- ScopedValue value(scope);
-
- if (!(o->flags & SimpleArray) || o->protoHasArray()) {
- // lets be safe and slow
- for (uint i = fromIndex; i < endIndex; ++i) {
- bool exists;
- value = o->getIndexed(i, &exists);
- if (scope.hasException())
- return Encode::undefined();
- if (exists && __qmljs_strict_equal(value, v))
- 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 (scope.hasException())
- return Encode::undefined();
- if (__qmljs_strict_equal(value, v))
- return Encode(n->key());
- }
- } else {
- if (endIndex > arrayDataLen)
- endIndex = arrayDataLen;
- Property *pd = arrayData;
- Property *end = pd + endIndex;
- pd += fromIndex;
- while (pd < end) {
- if (!pd->value.isEmpty()) {
- value = o->getValue(pd, arrayAttributes ? arrayAttributes[pd - arrayData] : Attr_Data);
- if (scope.hasException())
- return Encode::undefined();
- if (__qmljs_strict_equal(value, v))
- return Encode((uint)(pd - arrayData));
- }
- ++pd;
- }
- }
- return Encode(-1);
-}
-
-void Object::arrayConcat(const ArrayObject *other)
-{
- int newLen = arrayDataLen + other->arrayLength();
- if (other->sparseArray)
- initSparse();
- // ### copy attributes as well!
- if (sparseArray) {
- if (other->sparseArray) {
- for (const SparseArrayNode *it = other->sparseArray->begin(); it != other->sparseArray->end(); it = it->nextNode())
- arraySet(arrayDataLen + it->key(), other->arrayData + it->value);
- } else {
- int oldSize = arrayDataLen;
- arrayReserve(oldSize + other->arrayLength());
- memcpy(arrayData + oldSize, other->arrayData, other->arrayLength()*sizeof(Property));
- if (arrayAttributes)
- std::fill(arrayAttributes + oldSize, arrayAttributes + oldSize + other->arrayLength(), PropertyAttributes(Attr_Data));
- for (uint i = 0; i < other->arrayLength(); ++i) {
- SparseArrayNode *n = sparseArray->insert(arrayDataLen + i);
- n->value = oldSize + i;
- }
+ } else if (!other->arrayData) {
+ ;
+ } else if (other->hasAccessorProperty && other->arrayData->attrs && other->arrayData->isSparse()){
+ // do it the slow way
+ ScopedValue v(scope);
+ for (const SparseArrayNode *it = static_cast<const SparseArrayData *>(other->arrayData)->sparse->begin();
+ it != static_cast<const SparseArrayData *>(other->arrayData)->sparse->end(); it = it->nextNode()) {
+ v = other->getValue(reinterpret_cast<Property *>(other->arrayData->data + it->value), other->arrayData->attrs[it->value]);
+ arraySet(it->key(), v);
}
} else {
- uint oldSize = arrayLength();
- arrayReserve(oldSize + other->arrayDataLen);
- if (oldSize > arrayDataLen) {
- for (uint i = arrayDataLen; i < oldSize; ++i)
- arrayData[i].value = Primitive::emptyValue();
- }
- if (other->arrayAttributes) {
- for (uint i = 0; i < other->arrayDataLen; ++i) {
- bool exists;
- arrayData[oldSize + i].value = const_cast<ArrayObject *>(other)->getIndexed(i, &exists);
- arrayDataLen = oldSize + i + 1;
- if (arrayAttributes)
- arrayAttributes[oldSize + i] = Attr_Data;
- if (!exists)
- arrayData[oldSize + i].value = Primitive::emptyValue();
- }
+ Q_ASSERT(!arrayData && other->arrayData);
+ ArrayData::realloc(this, other->arrayData->type, 0, other->arrayData->alloc, other->arrayData->attrs);
+ if (other->arrayType() == ArrayData::Sparse) {
+ SparseArrayData *od = static_cast<SparseArrayData *>(other->arrayData);
+ SparseArrayData *dd = static_cast<SparseArrayData *>(arrayData);
+ dd->sparse = new SparseArray(*od->sparse);
+ dd->freeList = od->freeList;
} else {
- arrayDataLen = oldSize + other->arrayDataLen;
- memcpy(arrayData + oldSize, other->arrayData, other->arrayDataLen*sizeof(Property));
- if (arrayAttributes)
- std::fill(arrayAttributes + oldSize, arrayAttributes + oldSize + other->arrayDataLen, PropertyAttributes(Attr_Data));
+ SimpleArrayData *d = static_cast<SimpleArrayData *>(arrayData);
+ d->len = static_cast<SimpleArrayData *>(other->arrayData)->len;
+ d->offset = 0;
}
+ memcpy(arrayData->data, other->arrayData->data, arrayData->alloc*sizeof(Value));
}
- setArrayLengthUnchecked(newLen);
+ setArrayLengthUnchecked(other->getLength());
}
-void Object::arraySort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint len)
+uint Object::getLength(const Managed *m)
{
- if (!arrayDataLen)
- return;
-
- if (sparseArray) {
- context->throwUnimplemented(QStringLiteral("Object::sort unimplemented for sparse arrays"));
- return;
- }
-
- if (len > arrayDataLen)
- len = arrayDataLen;
-
- // The spec says the sorting goes through a series of get,put and delete operations.
- // this implies that the attributes don't get sorted around.
- // behavior of accessor properties is implementation defined. We simply turn them all
- // into data properties and then sort. This is in line with the sentence above.
- if (arrayAttributes) {
- for (uint i = 0; i < len; i++) {
- if ((arrayAttributes && arrayAttributes[i].isGeneric()) || arrayData[i].value.isEmpty()) {
- while (--len > i)
- if (!((arrayAttributes && arrayAttributes[len].isGeneric())|| arrayData[len].value.isEmpty()))
- break;
- arrayData[i].value = getValue(arrayData + len, arrayAttributes[len]);
- arrayData[len].value = Primitive::emptyValue();
- if (arrayAttributes) {
- arrayAttributes[i] = Attr_Data;
- arrayAttributes[len].clear();
- }
- } else if (arrayAttributes[i].isAccessor()) {
- arrayData[i].value = getValue(arrayData + i, arrayAttributes[i]);
- arrayAttributes[i] = Attr_Data;
- }
- }
- }
-
- if (!(comparefn->isUndefined() || comparefn->asObject())) {
- context->throwTypeError();
- return;
- }
-
- ArrayElementLessThan lessThan(context, thisObject, comparefn);
-
- if (!len)
- return;
- Property *begin = arrayData;
- std::sort(begin, begin + len, lessThan);
-}
-
-
-void Object::initSparse()
-{
- if (!sparseArray) {
- flags &= ~SimpleArray;
- sparseArray = new SparseArray;
- for (uint i = 0; i < arrayDataLen; ++i) {
- if (!((arrayAttributes && arrayAttributes[i].isGeneric()) || arrayData[i].value.isEmpty())) {
- SparseArrayNode *n = sparseArray->insert(i);
- n->value = i + arrayOffset;
- }
- }
-
- uint off = arrayOffset;
- if (!arrayOffset) {
- arrayFreeList = arrayDataLen;
- } else {
- arrayFreeList = 0;
- arrayData -= off;
- arrayAlloc += off;
- int o = off;
- for (int i = 0; i < o - 1; ++i) {
- arrayData[i].value = Primitive::fromInt32(i + 1);
- }
- arrayData[o - 1].value = Primitive::fromInt32(arrayDataLen + off);
- }
- for (uint i = arrayDataLen + off; i < arrayAlloc; ++i) {
- arrayData[i].value = Primitive::fromInt32(i + 1);
- }
- }
-}
-
-void Object::arrayReserve(uint n)
-{
- if (n < 8)
- n = 8;
- if (n >= arrayAlloc) {
- uint off;
- if (sparseArray) {
- assert(arrayFreeList == arrayAlloc);
- // ### FIXME
- arrayDataLen = arrayAlloc;
- off = 0;
- } else {
- off = arrayOffset;
- }
- arrayAlloc = qMax(n, 2*arrayAlloc);
- Property *newArrayData = new Property[arrayAlloc + off];
- if (arrayData) {
- memcpy(newArrayData + off, arrayData, sizeof(Property)*arrayDataLen);
- delete [] (arrayData - off);
- }
- arrayData = newArrayData + off;
- if (sparseArray) {
- for (uint i = arrayFreeList; i < arrayAlloc; ++i) {
- arrayData[i].value = Primitive::emptyValue();
- arrayData[i].value = Primitive::fromInt32(i + 1);
- }
- }
-
- if (arrayAttributes) {
- PropertyAttributes *newAttrs = new PropertyAttributes[arrayAlloc];
- memcpy(newAttrs, arrayAttributes, sizeof(PropertyAttributes)*arrayDataLen);
- delete [] (arrayAttributes - off);
-
- arrayAttributes = newAttrs;
- if (sparseArray) {
- for (uint i = arrayFreeList; i < arrayAlloc; ++i)
- arrayAttributes[i] = Attr_Invalid;
- }
- }
- }
+ Scope scope(m->engine());
+ ScopedValue v(scope, static_cast<Object *>(const_cast<Managed *>(m))->get(scope.engine->id_length));
+ return v->toUInt32();
}
-void Object::ensureArrayAttributes()
+bool Object::setArrayLength(uint newLen)
{
- if (arrayAttributes)
- return;
-
- flags &= ~SimpleArray;
- uint off = sparseArray ? 0 : arrayOffset;
- arrayAttributes = new PropertyAttributes[arrayAlloc + off];
- arrayAttributes += off;
- for (uint i = 0; i < arrayDataLen; ++i)
- arrayAttributes[i] = Attr_Data;
- for (uint i = arrayDataLen; i < arrayAlloc; ++i)
- arrayAttributes[i] = Attr_Invalid;
-}
-
-
-bool Object::setArrayLength(uint newLen) {
- assert(isArrayObject());
+ Q_ASSERT(isArrayObject());
const Property *lengthProperty = memberData + ArrayObject::LengthPropertyIndex;
if (lengthProperty && !internalClass->propertyData[ArrayObject::LengthPropertyIndex].isWritable())
return false;
- uint oldLen = arrayLength();
+ uint oldLen = getLength();
bool ok = true;
if (newLen < oldLen) {
- if (sparseArray) {
- SparseArrayNode *begin = sparseArray->lowerBound(newLen);
- if (begin != sparseArray->end()) {
- SparseArrayNode *it = sparseArray->end()->previousNode();
- while (1) {
- Property &pd = arrayData[it->value];
- if (arrayAttributes) {
- if (!arrayAttributes[it->value].isConfigurable()) {
- ok = false;
- newLen = it->key() + 1;
- break;
- } else {
- arrayAttributes[it->value].clear();
- }
- }
- pd.value.tag = Value::Empty_Type;
- pd.value.int_32 = arrayFreeList;
- arrayFreeList = it->value;
- bool brk = (it == begin);
- SparseArrayNode *prev = it->previousNode();
- sparseArray->erase(it);
- if (brk)
- break;
- it = prev;
- }
- }
+ if (!arrayData) {
+ Q_ASSERT(!newLen);
} else {
- Property *it = arrayData + arrayDataLen;
- const Property *begin = arrayData + newLen;
- while (--it >= begin) {
- if (arrayAttributes) {
- if (!arrayAttributes[it - arrayData].isEmpty() && !arrayAttributes[it - arrayData].isConfigurable()) {
- ok = false;
- newLen = it - arrayData + 1;
- break;
- } else {
- arrayAttributes[it - arrayData].clear();
- }
- it->value = Primitive::emptyValue();
- }
- }
- arrayDataLen = newLen;
+ uint l = arrayData->vtable()->truncate(this, newLen);
+ if (l != newLen)
+ ok = false;
+ newLen = l;
}
} else {
if (newLen >= 0x100000)
- initSparse();
+ initSparseArray();
}
setArrayLengthUnchecked(newLen);
return ok;
}
-DEFINE_MANAGED_VTABLE(ArrayObject);
+void Object::initSparseArray()
+{
+ if (arrayType() == ArrayData::Sparse)
+ return;
+
+ ArrayData::realloc(this, ArrayData::Sparse, 0, 0, false);
+}
+
+
+DEFINE_OBJECT_VTABLE(ArrayObject);
ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
: Object(engine->arrayClass)
@@ -1431,10 +1180,9 @@ ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
// elements converted to JS Strings.
int len = list.count();
arrayReserve(len);
- for (int ii = 0; ii < len; ++ii) {
- arrayData[ii].value = Encode(engine->newString(list.at(ii)));
- arrayDataLen = ii + 1;
- }
+ ScopedValue v(scope);
+ for (int ii = 0; ii < len; ++ii)
+ arrayPut(ii, (v = engine->newString(list.at(ii))));
setArrayLengthUnchecked(len);
}
@@ -1442,10 +1190,28 @@ void ArrayObject::init(ExecutionEngine *engine)
{
Q_UNUSED(engine);
- type = Type_ArrayObject;
memberData[LengthPropertyIndex].value = Primitive::fromInt32(0);
}
+ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l)
+{
+ if (l->name->equals(m->engine()->id_length)) {
+ // special case, as the property is on the object itself
+ l->getter = Lookup::arrayLengthGetter;
+ ArrayObject *a = static_cast<ArrayObject *>(m);
+ return a->memberData[ArrayObject::LengthPropertyIndex].value.asReturnedValue();
+ }
+ return Object::getLookup(m, l);
+}
+
+uint ArrayObject::getLength(const Managed *m)
+{
+ const ArrayObject *a = static_cast<const ArrayObject *>(m);
+ if (a->memberData[ArrayObject::LengthPropertyIndex].value.isInteger())
+ return a->memberData[ArrayObject::LengthPropertyIndex].value.integerValue();
+ return Primitive::toUInt32(a->memberData[ArrayObject::LengthPropertyIndex].value.doubleValue());
+}
+
QStringList ArrayObject::toQStringList() const
{
QStringList result;
@@ -1454,7 +1220,7 @@ QStringList ArrayObject::toQStringList() const
Scope scope(engine);
ScopedValue v(scope);
- uint32_t length = arrayLength();
+ uint32_t length = getLength();
for (uint32_t i = 0; i < length; ++i) {
v = const_cast<ArrayObject *>(this)->getIndexed(i);
result.append(v->toQStringNoThrow());
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 23f2f682fd..e3361ae160 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -49,7 +49,7 @@
#include "qv4managed_p.h"
#include "qv4property_p.h"
#include "qv4internalclass_p.h"
-#include "qv4sparsearray_p.h"
+#include "qv4arraydata_p.h"
#include <QtCore/QString>
#include <QtCore/QHash>
@@ -100,20 +100,17 @@ struct SyntaxErrorPrototype;
struct TypeErrorPrototype;
struct URIErrorPrototype;
+
struct Q_QML_EXPORT Object: Managed {
- Q_MANAGED
+ V4_OBJECT
+ Q_MANAGED_TYPE(Object)
+ enum {
+ IsObject = true
+ };
uint memberDataAlloc;
Property *memberData;
- union {
- uint arrayFreeList;
- uint arrayOffset;
- };
- uint arrayDataLen;
- uint arrayAlloc;
- PropertyAttributes *arrayAttributes;
- Property *arrayData;
- SparseArray *sparseArray;
+ ArrayData *arrayData;
enum {
InlinePropertySize = 4
@@ -124,6 +121,7 @@ struct Q_QML_EXPORT Object: Managed {
Object(InternalClass *internalClass);
~Object();
+ const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(internalClass->vtable); }
Object *prototype() const { return internalClass->prototype; }
bool setPrototype(Object *proto);
@@ -133,13 +131,17 @@ struct Q_QML_EXPORT Object: Managed {
Property *__getPropertyDescriptor__(const StringRef name, PropertyAttributes *attrs = 0) const;
Property *__getPropertyDescriptor__(uint index, PropertyAttributes *attrs = 0) const;
- bool __hasProperty__(const StringRef name) const;
- bool __hasProperty__(uint index) const;
+ bool hasProperty(const StringRef name) const;
+ bool hasProperty(uint index) const;
- bool __defineOwnProperty__(ExecutionContext *ctx, Property *current, const StringRef member, const Property &p, PropertyAttributes attrs);
+ bool hasOwnProperty(const StringRef name) const;
+ bool hasOwnProperty(uint index) const;
+
+ bool __defineOwnProperty__(ExecutionContext *ctx, uint index, const StringRef member, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, const StringRef name, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionContext *ctx, const QString &name, const Property &p, PropertyAttributes attrs);
+ bool defineOwnProperty2(ExecutionContext *ctx, uint index, const Property &p, PropertyAttributes attrs);
//
// helpers
@@ -156,7 +158,9 @@ struct Q_QML_EXPORT Object: Managed {
void putValue(Property *pd, PropertyAttributes attrs, const ValueRef value);
/* The spec default: Writable: true, Enumerable: false, Configurable: true */
- void defineDefaultProperty(const StringRef name, ValueRef value);
+ void defineDefaultProperty(const StringRef name, ValueRef value) {
+ insertMember(name, value, Attr_Data|Attr_NotEnumerable);
+ }
void defineDefaultProperty(const QString &name, ValueRef value);
void defineDefaultProperty(const QString &name, ReturnedValue (*code)(CallContext *), int argumentCount = 0);
void defineDefaultProperty(const StringRef name, ReturnedValue (*code)(CallContext *), int argumentCount = 0);
@@ -166,113 +170,73 @@ struct Q_QML_EXPORT Object: Managed {
void defineReadonlyProperty(const QString &name, ValueRef value);
void defineReadonlyProperty(const StringRef name, ValueRef value);
- Property *insertMember(const StringRef s, PropertyAttributes attributes);
+ void insertMember(const StringRef s, const ValueRef v, PropertyAttributes attributes = Attr_Data) {
+ insertMember(s, Property::fromValue(*v), attributes);
+ }
+ void insertMember(const StringRef s, const Property &p, PropertyAttributes attributes);
inline ExecutionEngine *engine() const { return internalClass->engine; }
// Array handling
- uint allocArrayValue() {
- uint idx = arrayFreeList;
- if (arrayAlloc <= arrayFreeList)
- arrayReserve(arrayAlloc + 1);
- arrayFreeList = arrayData[arrayFreeList].value.uint_32;
- if (arrayAttributes)
- arrayAttributes[idx].setType(PropertyAttributes::Data);
- return idx;
- }
-
- uint allocArrayValue(const ValueRef v) {
- uint idx = allocArrayValue();
- Property *pd = &arrayData[idx];
- pd->value = *v;
- return idx;
- }
- void freeArrayValue(int idx) {
- Property &pd = arrayData[idx];
- pd.value.tag = Value::Empty_Type;
- pd.value.int_32 = arrayFreeList;
- arrayFreeList = idx;
- if (arrayAttributes)
- arrayAttributes[idx].clear();
- }
-
- void getArrayHeadRoom() {
- assert(!sparseArray && !arrayOffset);
- arrayOffset = qMax(arrayDataLen >> 2, (uint)16);
- Property *newArray = new Property[arrayOffset + arrayAlloc];
- memcpy(newArray + arrayOffset, arrayData, arrayDataLen*sizeof(Property));
- delete [] arrayData;
- arrayData = newArray + arrayOffset;
- if (arrayAttributes) {
- PropertyAttributes *newAttrs = new PropertyAttributes[arrayOffset + arrayAlloc];
- memcpy(newAttrs + arrayOffset, arrayAttributes, arrayDataLen*sizeof(PropertyAttributes));
- delete [] arrayAttributes;
- arrayAttributes = newAttrs + arrayOffset;
- }
- }
-
public:
void copyArrayData(Object *other);
- void initSparse();
- uint arrayLength() const;
bool setArrayLength(uint newLen);
-
void setArrayLengthUnchecked(uint l);
- Property *arrayInsert(uint index, PropertyAttributes attributes = Attr_Data);
-
- void arraySet(uint index, const Property *pd);
+ void arraySet(uint index, const Property &p, PropertyAttributes attributes = Attr_Data);
void arraySet(uint index, ValueRef value);
- uint propertyIndexFromArrayIndex(uint index) const
- {
- if (!sparseArray) {
- if (index >= arrayDataLen)
- return UINT_MAX;
- return index;
- } else {
- SparseArrayNode *n = sparseArray->findNode(index);
- if (!n)
- return UINT_MAX;
- return n->value;
- }
+ bool arrayPut(uint index, ValueRef value) {
+ return arrayData->vtable()->put(this, index, value);
}
-
- Property *arrayAt(uint index) const {
- uint pidx = propertyIndexFromArrayIndex(index);
- if (pidx == UINT_MAX)
- return 0;
- return arrayData + pidx;
+ bool arrayPut(uint index, Value *values, uint n) {
+ return arrayData->vtable()->putArray(this, index, values, n);
}
-
- Property *nonSparseArrayAt(uint index) const {
- if (sparseArray)
- return 0;
- if (index >= arrayDataLen)
- return 0;
- return arrayData + index;
+ void setArrayAttributes(uint i, PropertyAttributes a) {
+ Q_ASSERT(arrayData);
+ if (arrayData->attrs || a != Attr_Data) {
+ ArrayData::ensureAttributes(this);
+ a.resolve();
+ arrayData->vtable()->setAttribute(this, i, a);
+ }
}
void push_back(const ValueRef v);
- SparseArrayNode *sparseArrayBegin() { return sparseArray ? sparseArray->begin() : 0; }
- SparseArrayNode *sparseArrayEnd() { return sparseArray ? sparseArray->end() : 0; }
+ ArrayData::Type arrayType() const {
+ return arrayData ? arrayData->type : ArrayData::Simple;
+ }
+ // ### remove me
+ void setArrayType(ArrayData::Type t) {
+ Q_ASSERT(t != ArrayData::Simple && t != ArrayData::Sparse);
+ arrayCreate();
+ arrayData->type = t;
+ }
+
+ inline void arrayReserve(uint n) {
+ ArrayData::realloc(this, ArrayData::Simple, 0, n, false);
+ }
- void arrayConcat(const ArrayObject *other);
- void arraySort(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn, uint arrayDataLen);
- ReturnedValue arrayIndexOf(const ValueRef v, uint fromIndex, uint arrayDataLen, ExecutionContext *ctx, Object *o);
+ void arrayCreate() {
+ if (!arrayData)
+ ArrayData::realloc(this, ArrayData::Simple, 0, 0, false);
+#ifdef CHECK_SPARSE_ARRAYS
+ initSparseArray();
+#endif
+ }
- void arrayReserve(uint n);
- void ensureArrayAttributes();
+ void initSparseArray();
+ SparseArrayNode *sparseBegin() { return arrayType() == ArrayData::Sparse ? static_cast<SparseArrayData *>(arrayData)->sparse->begin() : 0; }
+ SparseArrayNode *sparseEnd() { return arrayType() == ArrayData::Sparse ? static_cast<SparseArrayData *>(arrayData)->sparse->end() : 0; }
inline bool protoHasArray() {
Scope scope(engine());
Scoped<Object> p(scope, this);
while ((p = p->prototype()))
- if (p->arrayDataLen)
+ if (p->arrayData)
return true;
return false;
@@ -280,27 +244,38 @@ public:
void ensureMemberIndex(uint idx);
inline ReturnedValue get(const StringRef name, bool *hasProperty = 0)
- { return internalClass->vtable->get(this, name, hasProperty); }
+ { return vtable()->get(this, name, hasProperty); }
inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0)
- { return internalClass->vtable->getIndexed(this, idx, hasProperty); }
+ { return vtable()->getIndexed(this, idx, hasProperty); }
inline void put(const StringRef name, const ValueRef v)
- { internalClass->vtable->put(this, name, v); }
+ { vtable()->put(this, name, v); }
inline void putIndexed(uint idx, const ValueRef v)
- { internalClass->vtable->putIndexed(this, idx, v); }
- using Managed::get;
- using Managed::getIndexed;
- using Managed::put;
- using Managed::putIndexed;
- using Managed::query;
- using Managed::queryIndexed;
- using Managed::deleteProperty;
- using Managed::deleteIndexedProperty;
- using Managed::getLookup;
- using Managed::setLookup;
- using Managed::advanceIterator;
+ { vtable()->putIndexed(this, idx, v); }
+ PropertyAttributes query(StringRef name) const
+ { return vtable()->query(this, name); }
+ PropertyAttributes queryIndexed(uint index) const
+ { return vtable()->queryIndexed(this, index); }
+ bool deleteProperty(const StringRef name)
+ { return vtable()->deleteProperty(this, name); }
+ bool deleteIndexedProperty(uint index)
+ { return vtable()->deleteIndexedProperty(this, index); }
+ ReturnedValue getLookup(Lookup *l)
+ { return vtable()->getLookup(this, l); }
+ void setLookup(Lookup *l, const ValueRef v)
+ { vtable()->setLookup(this, l, v); }
+ void advanceIterator(ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes)
+ { vtable()->advanceIterator(this, it, name, index, p, attributes); }
+ uint getLength() const { return vtable()->getLength(this); }
+
+ inline ReturnedValue construct(CallData *d)
+ { return vtable()->construct(this, d); }
+ inline ReturnedValue call(CallData *d)
+ { return vtable()->call(this, d); }
protected:
static void destroy(Managed *that);
static void markObjects(Managed *that, ExecutionEngine *e);
+ static ReturnedValue construct(Managed *m, CallData *);
+ static ReturnedValue call(Managed *m, CallData *);
static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, const StringRef name, const ValueRef value);
@@ -311,8 +286,8 @@ protected:
static bool deleteIndexedProperty(Managed *m, uint index);
static ReturnedValue getLookup(Managed *m, Lookup *l);
static void setLookup(Managed *m, Lookup *l, const ValueRef v);
- static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
-
+ static void advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
+ static uint getLength(const Managed *m);
private:
ReturnedValue internalGet(const StringRef name, bool *hasProperty);
@@ -327,41 +302,40 @@ private:
};
struct BooleanObject: Object {
- Q_MANAGED
- SafeValue value;
+ V4_OBJECT
+ Q_MANAGED_TYPE(BooleanObject)
+ Value value;
BooleanObject(ExecutionEngine *engine, const ValueRef val)
: Object(engine->booleanClass) {
- type = Type_BooleanObject;
value = val;
}
protected:
BooleanObject(InternalClass *ic)
: Object(ic) {
- setVTable(&static_vtbl);
- type = Type_BooleanObject;
+ Q_ASSERT(internalClass->vtable == staticVTable());
value = Encode(false);
}
};
struct NumberObject: Object {
- Q_MANAGED
- SafeValue value;
+ V4_OBJECT
+ Q_MANAGED_TYPE(NumberObject)
+ Value value;
NumberObject(ExecutionEngine *engine, const ValueRef val)
: Object(engine->numberClass) {
- type = Type_NumberObject;
value = val;
}
protected:
NumberObject(InternalClass *ic)
: Object(ic) {
- setVTable(&static_vtbl);
- type = Type_NumberObject;
+ Q_ASSERT(internalClass->vtable == staticVTable());
value = Encode((int)0);
}
};
struct ArrayObject: Object {
- Q_MANAGED
+ V4_OBJECT
+ Q_MANAGED_TYPE(ArrayObject)
enum {
LengthPropertyIndex = 0
};
@@ -372,19 +346,13 @@ struct ArrayObject: Object {
void init(ExecutionEngine *engine);
+ static ReturnedValue getLookup(Managed *m, Lookup *l);
+ using Object::getLength;
+ static uint getLength(const Managed *m);
+
QStringList toQStringList() const;
};
-inline uint Object::arrayLength() const
-{
- if (isArrayObject()) {
- if (memberData[ArrayObject::LengthPropertyIndex].value.isInteger())
- return memberData[ArrayObject::LengthPropertyIndex].value.integerValue();
- return Primitive::toUInt32(memberData[ArrayObject::LengthPropertyIndex].value.doubleValue());
- }
- return 0;
-}
-
inline void Object::setArrayLengthUnchecked(uint l)
{
if (isArrayObject()) {
@@ -396,64 +364,46 @@ inline void Object::setArrayLengthUnchecked(uint l)
inline void Object::push_back(const ValueRef v)
{
- uint idx = arrayLength();
- if (!sparseArray) {
- if (idx >= arrayAlloc)
- arrayReserve(idx + 1);
- arrayData[idx].value = *v;
- arrayDataLen = idx + 1;
- } else {
- uint idx = allocArrayValue(v);
- sparseArray->push_back(idx, arrayLength());
- }
+ arrayCreate();
+
+ uint idx = getLength();
+ arrayReserve(idx + 1);
+ arrayPut(idx, v);
setArrayLengthUnchecked(idx + 1);
}
-inline Property *Object::arrayInsert(uint index, PropertyAttributes attributes) {
- if (attributes.isAccessor())
+inline void Object::arraySet(uint index, const Property &p, PropertyAttributes attributes)
+{
+ // ### Clean up
+ arrayCreate();
+ if (attributes.isAccessor()) {
hasAccessorProperty = 1;
-
- Property *pd;
- if (!sparseArray && (index < 0x1000 || index < arrayDataLen + (arrayDataLen >> 2))) {
- if (index >= arrayAlloc)
- arrayReserve(index + 1);
- if (index >= arrayDataLen) {
- // mark possible hole in the array
- for (uint i = arrayDataLen; i < index; ++i) {
- arrayData[i].value = Primitive::emptyValue();
- if (arrayAttributes)
- arrayAttributes[i].clear();
- }
- arrayDataLen = index + 1;
- }
- pd = arrayData + index;
+ initSparseArray();
+ } else if (index > 0x1000 && index > 2*arrayData->alloc) {
+ initSparseArray();
} else {
- initSparse();
- SparseArrayNode *n = sparseArray->insert(index);
- if (n->value == UINT_MAX)
- n->value = allocArrayValue();
- pd = arrayData + n->value;
+ arrayData->vtable()->reallocate(this, index + 1, false);
}
- if (index >= arrayLength())
+ setArrayAttributes(index, attributes);
+ Property *pd = ArrayData::insert(this, index, attributes.isAccessor());
+ pd->value = p.value;
+ if (attributes.isAccessor())
+ pd->set = p.set;
+ if (isArrayObject() && index >= getLength())
setArrayLengthUnchecked(index + 1);
- if (arrayAttributes || attributes != Attr_Data) {
- if (!arrayAttributes)
- ensureArrayAttributes();
- attributes.resolve();
- arrayAttributes[pd - arrayData] = attributes;
- }
- return pd;
}
-inline void Object::arraySet(uint index, ValueRef value)
-{
- Property *pd = arrayInsert(index);
- pd->value = *value;
-}
-inline void Object::arraySet(uint index, const Property *pd)
+inline void Object::arraySet(uint index, ValueRef value)
{
- *arrayInsert(index) = *pd;
+ arrayCreate();
+ if (index > 0x1000 && index > 2*arrayData->alloc) {
+ initSparseArray();
+ }
+ Property *pd = ArrayData::insert(this, index);
+ pd->value = value ? *value : Primitive::undefinedValue();
+ if (isArrayObject() && index >= getLength())
+ setArrayLengthUnchecked(index + 1);
}
template<>
@@ -467,11 +417,28 @@ inline ArrayObject *value_cast(const Value &v) {
}
template<>
-inline ReturnedValue value_convert<Object>(ExecutionContext *ctx, const Value &v)
+inline ReturnedValue value_convert<Object>(ExecutionEngine *e, const Value &v)
{
- return v.toObject(ctx)->asReturnedValue();
+ return v.toObject(e->currentContext())->asReturnedValue();
}
+struct ObjectRef : public ManagedRef
+{
+ DEFINE_REF_METHODS(Object, Managed)
+
+ static ObjectRef fromValuePointer(Value *s) {
+ ObjectRef r;
+ r.ptr = s;
+ if (sizeof(void *) == 8)
+ r.ptr->val = 0;
+ else
+ *r.ptr = Value::fromManaged(0);
+ return r;
+ }
+};
+
+DEFINE_REF(ArrayObject, Object);
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index 04fa504991..e5f693c323 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -46,27 +46,26 @@
using namespace QV4;
-ObjectIterator::ObjectIterator(SafeObject *scratch1, SafeObject *scratch2, const ObjectRef o, uint flags)
- : object(*scratch1)
- , current(*scratch2)
+ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, const ObjectRef o, uint flags)
+ : object(ObjectRef::fromValuePointer(scratch1))
+ , current(ObjectRef::fromValuePointer(scratch2))
, arrayNode(0)
, arrayIndex(0)
, memberIndex(0)
, flags(flags)
{
- object = o;
- current = o;
- tmpDynamicProperty.value = Primitive::undefinedValue();
+ object = o.getPointer();
+ current = o.getPointer();
- if (object && object->isNonStrictArgumentsObject) {
+ if (!!object && object->asArgumentsObject()) {
Scope scope(object->engine());
Scoped<ArgumentsObject> (scope, object->asReturnedValue())->fullyCreate();
}
}
ObjectIterator::ObjectIterator(Scope &scope, const ObjectRef o, uint flags)
- : object(*static_cast<SafeObject *>(scope.alloc(1)))
- , current(*static_cast<SafeObject *>(scope.alloc(1)))
+ : object(ObjectRef::fromValuePointer(scope.alloc(1)))
+ , current(ObjectRef::fromValuePointer(scope.alloc(1)))
, arrayNode(0)
, arrayIndex(0)
, memberIndex(0)
@@ -74,40 +73,47 @@ ObjectIterator::ObjectIterator(Scope &scope, const ObjectRef o, uint flags)
{
object = o;
current = o;
- tmpDynamicProperty.value = Primitive::undefinedValue();
- if (object && object->isNonStrictArgumentsObject) {
+ if (!!object && object->asArgumentsObject()) {
Scope scope(object->engine());
Scoped<ArgumentsObject> (scope, object->asReturnedValue())->fullyCreate();
}
}
-Property *ObjectIterator::next(StringRef name, uint *index, PropertyAttributes *attrs)
+void ObjectIterator::next(StringRef name, uint *index, Property *pd, PropertyAttributes *attrs)
{
name = (String *)0;
*index = UINT_MAX;
- if (!object)
- return 0;
- Property *p = 0;
+ if (!object) {
+ *attrs = PropertyAttributes();
+ return;
+ }
+
while (1) {
if (!current)
break;
- while ((p = current->advanceIterator(this, name, index, attrs))) {
+ while (1) {
+ current->advanceIterator(this, name, index, pd, attrs);
+ if (attrs->isEmpty())
+ break;
// check the property is not already defined earlier in the proto chain
if (current != object) {
- Property *pp;
- if (name) {
- pp = object->__getPropertyDescriptor__(name);
- } else {
- assert (*index != UINT_MAX);
- pp = object->__getPropertyDescriptor__(*index);
+ Object *o = object;
+ bool shadowed = false;
+ while (o != current) {
+ if ((!!name && o->hasOwnProperty(name)) ||
+ (*index != UINT_MAX && o->hasOwnProperty(*index))) {
+ shadowed = true;
+ break;
+ }
+ o = o->prototype();
}
- if (pp != p)
+ if (shadowed)
continue;
}
- return p;
+ return;
}
if (flags & WithProtoChain)
@@ -118,7 +124,7 @@ Property *ObjectIterator::next(StringRef name, uint *index, PropertyAttributes *
arrayIndex = 0;
memberIndex = 0;
}
- return 0;
+ *attrs = PropertyAttributes();
}
ReturnedValue ObjectIterator::nextPropertyName(ValueRef value)
@@ -127,14 +133,15 @@ ReturnedValue ObjectIterator::nextPropertyName(ValueRef value)
return Encode::null();
PropertyAttributes attrs;
+ Property p;
uint index;
Scope scope(object->engine());
ScopedString name(scope);
- Property *p = next(name, &index, &attrs);
- if (!p)
+ next(name, &index, &p, &attrs);
+ if (attrs.isEmpty())
return Encode::null();
- value = object->getValue(p, attrs);
+ value = object->getValue(&p, attrs);
if (!!name)
return name->asReturnedValue();
@@ -148,14 +155,15 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString(ValueRef value)
return Encode::null();
PropertyAttributes attrs;
+ Property p;
uint index;
Scope scope(object->engine());
ScopedString name(scope);
- Property *p = next(name, &index, &attrs);
- if (!p)
+ next(name, &index, &p, &attrs);
+ if (attrs.isEmpty())
return Encode::null();
- value = object->getValue(p, attrs);
+ value = object->getValue(&p, attrs);
if (!!name)
return name->asReturnedValue();
@@ -169,11 +177,12 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
return Encode::null();
PropertyAttributes attrs;
+ Property p;
uint index;
Scope scope(object->engine());
ScopedString name(scope);
- Property *p = next(name, &index, &attrs);
- if (!p)
+ next(name, &index, &p, &attrs);
+ if (attrs.isEmpty())
return Encode::null();
if (!!name)
@@ -183,7 +192,7 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
}
-DEFINE_MANAGED_VTABLE(ForEachIteratorObject);
+DEFINE_OBJECT_VTABLE(ForEachIteratorObject);
void ForEachIteratorObject::markObjects(Managed *that, ExecutionEngine *e)
{
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index 6c333b328c..c87f284288 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -74,23 +74,22 @@ struct Q_QML_EXPORT ObjectIterator
uint memberIndex;
uint flags;
- Property tmpDynamicProperty;
-
- ObjectIterator(SafeObject *scratch1, SafeObject *scratch2, const ObjectRef o, uint flags);
+ ObjectIterator(Value *scratch1, Value *scratch2, const ObjectRef o, uint flags);
ObjectIterator(Scope &scope, const ObjectRef o, uint flags);
- Property *next(StringRef name, uint *index, PropertyAttributes *attributes = 0);
+ void next(StringRef name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
ReturnedValue nextPropertyName(ValueRef value);
ReturnedValue nextPropertyNameAsString(ValueRef value);
ReturnedValue nextPropertyNameAsString();
};
struct ForEachIteratorObject: Object {
- Q_MANAGED
+ V4_OBJECT
+ Q_MANAGED_TYPE(ForeachIteratorObject)
ObjectIterator it;
ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
- : Object(ctx->engine), it(workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
- setVTable(&static_vtbl);
- type = Type_ForeachIteratorObject;
+ : Object(ctx->engine), it(workArea, workArea + 1,
+ o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
+ setVTable(staticVTable());
}
ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }
@@ -98,7 +97,7 @@ struct ForEachIteratorObject: Object {
protected:
static void markObjects(Managed *that, ExecutionEngine *e);
- SafeObject workArea[2];
+ Value workArea[2];
};
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 7ca790b970..51d6b8d414 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -72,12 +72,12 @@
using namespace QV4;
-DEFINE_MANAGED_VTABLE(ObjectCtor);
+DEFINE_OBJECT_VTABLE(ObjectCtor);
ObjectCtor::ObjectCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("Object"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData)
@@ -105,9 +105,9 @@ ReturnedValue ObjectCtor::call(Managed *m, CallData *callData)
void ObjectPrototype::init(ExecutionEngine *v4, ObjectRef ctor)
{
Scope scope(v4);
- ScopedObject o(scope);
+ ScopedObject o(scope, this);
- ctor->defineReadonlyProperty(v4->id_prototype, (o = this));
+ ctor->defineReadonlyProperty(v4->id_prototype, o);
ctor->defineReadonlyProperty(v4->id_length, Primitive::fromInt32(1));
ctor->defineDefaultProperty(QStringLiteral("getPrototypeOf"), method_getPrototypeOf, 1);
ctor->defineDefaultProperty(QStringLiteral("getOwnPropertyDescriptor"), method_getOwnPropertyDescriptor, 2);
@@ -134,9 +134,9 @@ void ObjectPrototype::init(ExecutionEngine *v4, ObjectRef ctor)
defineDefaultProperty(QStringLiteral("__defineSetter__"), method_defineSetter, 2);
Scoped<String> id_proto(scope, v4->id___proto__);
- Property *p = insertMember(StringRef(v4->id___proto__), Attr_Accessor|Attr_NotEnumerable);
- p->setGetter(v4->newBuiltinFunction(v4->rootContext, id_proto, method_get_proto)->getPointer());
- p->setSetter(v4->newBuiltinFunction(v4->rootContext, id_proto, method_set_proto)->getPointer());
+ Property p = Property::fromAccessor(v4->newBuiltinFunction(v4->rootContext, id_proto, method_get_proto)->getPointer(),
+ v4->newBuiltinFunction(v4->rootContext, id_proto, method_set_proto)->getPointer());
+ insertMember(StringRef(v4->id___proto__), p, Attr_Accessor|Attr_NotEnumerable);
}
ReturnedValue ObjectPrototype::method_getPrototypeOf(CallContext *ctx)
@@ -157,7 +157,7 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(CallContext *ctx)
if (!O)
return ctx->throwTypeError();
- if (O->isNonStrictArgumentsObject)
+ if (ArgumentsObject::isNonStrictArgumentsObject(O.getPointer()))
Scoped<ArgumentsObject>(scope, O)->fullyCreate();
ScopedValue v(scope, ctx->argument(1));
@@ -239,12 +239,13 @@ ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
while (1) {
uint index;
PropertyAttributes attrs;
- Property *pd = it.next(name, &index, &attrs);
- if (!pd)
+ Property pd;
+ it.next(name, &index, &pd, &attrs);
+ if (attrs.isEmpty())
break;
Property n;
PropertyAttributes nattrs;
- val = o->getValue(pd, attrs);
+ val = o->getValue(&pd, attrs);
toPropertyDescriptor(ctx, val, &n, &nattrs);
if (scope.engine->hasException)
return Encode::undefined();
@@ -271,10 +272,12 @@ ReturnedValue ObjectPrototype::method_seal(CallContext *ctx)
o->internalClass = o->internalClass->sealed();
- o->ensureArrayAttributes();
- for (uint i = 0; i < o->arrayDataLen; ++i) {
- if (!(o->arrayAttributes[i].isGeneric() || o->arrayData[i].value.isEmpty()))
- o->arrayAttributes[i].setConfigurable(false);
+ if (o->arrayData) {
+ ArrayData::ensureAttributes(o.getPointer());
+ for (uint i = 0; i < o->arrayData->alloc; ++i) {
+ if (!o->arrayData->isEmpty(i))
+ o->arrayData->attrs[i].setConfigurable(false);
+ }
}
return o.asReturnedValue();
@@ -287,19 +290,21 @@ ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx)
if (!o)
return ctx->throwTypeError();
- if (o->isNonStrictArgumentsObject)
+ if (ArgumentsObject::isNonStrictArgumentsObject(o.getPointer()))
Scoped<ArgumentsObject>(scope, o)->fullyCreate();
o->extensible = false;
o->internalClass = o->internalClass->frozen();
- o->ensureArrayAttributes();
- for (uint i = 0; i < o->arrayDataLen; ++i) {
- if (!(o->arrayAttributes[i].isGeneric() || o->arrayData[i].value.isEmpty()))
- o->arrayAttributes[i].setConfigurable(false);
- if (o->arrayAttributes[i].isData())
- o->arrayAttributes[i].setWritable(false);
+ if (o->arrayData) {
+ ArrayData::ensureAttributes(o.getPointer());
+ for (uint i = 0; i < o->arrayData->alloc; ++i) {
+ if (!o->arrayData->isEmpty(i))
+ o->arrayData->attrs[i].setConfigurable(false);
+ if (o->arrayData->attrs[i].isData())
+ o->arrayData->attrs[i].setWritable(false);
+ }
}
return o.asReturnedValue();
}
@@ -328,15 +333,16 @@ ReturnedValue ObjectPrototype::method_isSealed(CallContext *ctx)
if (o->internalClass != o->internalClass->sealed())
return Encode(false);
- if (!o->arrayDataLen)
+ if (!o->arrayData || !o->arrayData->length())
return Encode(true);
- if (!o->arrayAttributes)
+ if (o->arrayData->length() && !o->arrayData->attrs)
return Encode(false);
- for (uint i = 0; i < o->arrayDataLen; ++i) {
- if (!(o->arrayAttributes[i].isGeneric() || o->arrayData[i].value.isEmpty()))
- if (o->arrayAttributes[i].isConfigurable())
+ for (uint i = 0; i < o->arrayData->alloc; ++i) {
+ // ### Fix for sparse arrays
+ if (!o->arrayData->isEmpty(i))
+ if (o->arrayData->attributes(i).isConfigurable())
return Encode(false);
}
@@ -356,15 +362,16 @@ ReturnedValue ObjectPrototype::method_isFrozen(CallContext *ctx)
if (o->internalClass != o->internalClass->frozen())
return Encode(false);
- if (!o->arrayDataLen)
+ if (!o->arrayData->length())
return Encode(true);
- if (!o->arrayAttributes)
+ if (o->arrayData->length() && !o->arrayData->attrs)
return Encode(false);
- for (uint i = 0; i < o->arrayDataLen; ++i) {
- if (!(o->arrayAttributes[i].isGeneric() || o->arrayData[i].value.isEmpty()))
- if (o->arrayAttributes[i].isConfigurable() || o->arrayAttributes[i].isWritable())
+ for (uint i = 0; i < o->arrayData->alloc; ++i) {
+ // ### Fix for sparse arrays
+ if (!o->arrayData->isEmpty(i))
+ if (o->arrayData->attributes(i).isConfigurable() || o->arrayData->attributes(i).isWritable())
return Encode(false);
}
@@ -448,7 +455,7 @@ ReturnedValue ObjectPrototype::method_hasOwnProperty(CallContext *ctx)
Scoped<Object> O(scope, ctx->callData->thisObject, Scoped<Object>::Convert);
if (scope.engine->hasException)
return Encode::undefined();
- bool r = O->__getOwnProperty__(P) != 0;
+ bool r = O->hasOwnProperty(P);
if (!r)
r = !O->query(P).isEmpty();
return Encode(r);
@@ -494,14 +501,14 @@ ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx)
return ctx->throwTypeError();
Scope scope(ctx);
- Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
-
Scoped<FunctionObject> f(scope, ctx->argument(1));
if (!f)
return ctx->throwTypeError();
+ Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
Scoped<Object> o(scope, ctx->callData->thisObject);
if (!o) {
if (!ctx->callData->thisObject.isUndefined())
@@ -509,7 +516,9 @@ ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx)
o = ctx->engine->globalObject;
}
- Property pd = Property::fromAccessor(f.getPointer(), 0);
+ Property pd;
+ pd.value = f;
+ pd.set = Primitive::emptyValue();
o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
return Encode::undefined();
}
@@ -520,14 +529,14 @@ ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx)
return ctx->throwTypeError();
Scope scope(ctx);
- Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
-
Scoped<FunctionObject> f(scope, ctx->argument(1));
if (!f)
return ctx->throwTypeError();
+ Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
Scoped<Object> o(scope, ctx->callData->thisObject);
if (!o) {
if (!ctx->callData->thisObject.isUndefined())
@@ -535,7 +544,9 @@ ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx)
o = ctx->engine->globalObject;
}
- Property pd = Property::fromAccessor(0, f.getPointer());
+ Property pd;
+ pd.value = Primitive::emptyValue();
+ pd.set = f;
o->__defineOwnProperty__(ctx, prop, pd, Attr_Accessor);
return Encode::undefined();
}
@@ -586,23 +597,21 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
}
attrs->clear();
- desc->setGetter(0);
- desc->setSetter(0);
+ desc->value = Primitive::emptyValue();
+ desc->set = Primitive::emptyValue();
ScopedValue tmp(scope);
- if (o->__hasProperty__(ctx->engine->id_enumerable))
+ if (o->hasProperty(ctx->engine->id_enumerable))
attrs->setEnumerable((tmp = o->get(ctx->engine->id_enumerable))->toBoolean());
- if (o->__hasProperty__(ctx->engine->id_configurable))
+ if (o->hasProperty(ctx->engine->id_configurable))
attrs->setConfigurable((tmp = o->get(ctx->engine->id_configurable))->toBoolean());
- if (o->__hasProperty__(ctx->engine->id_get)) {
+ if (o->hasProperty(ctx->engine->id_get)) {
ScopedValue get(scope, o->get(ctx->engine->id_get));
FunctionObject *f = get->asFunctionObject();
- if (f) {
- desc->setGetter(f);
- } else if (get->isUndefined()) {
- desc->setGetter((FunctionObject *)0x1);
+ if (f || get->isUndefined()) {
+ desc->value = get;
} else {
ctx->throwTypeError();
return;
@@ -610,13 +619,11 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
attrs->setType(PropertyAttributes::Accessor);
}
- if (o->__hasProperty__(ctx->engine->id_set)) {
+ if (o->hasProperty(ctx->engine->id_set)) {
ScopedValue set(scope, o->get(ctx->engine->id_set));
FunctionObject *f = set->asFunctionObject();
- if (f) {
- desc->setSetter(f);
- } else if (set->isUndefined()) {
- desc->setSetter((FunctionObject *)0x1);
+ if (f || set->isUndefined()) {
+ desc->set = set;
} else {
ctx->throwTypeError();
return;
@@ -624,7 +631,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
attrs->setType(PropertyAttributes::Accessor);
}
- if (o->__hasProperty__(ctx->engine->id_writable)) {
+ if (o->hasProperty(ctx->engine->id_writable)) {
if (attrs->isAccessor()) {
ctx->throwTypeError();
return;
@@ -634,7 +641,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
desc->value = Primitive::undefinedValue();
}
- if (o->__hasProperty__(ctx->engine->id_value)) {
+ if (o->hasProperty(ctx->engine->id_value)) {
if (attrs->isAccessor()) {
ctx->throwTypeError();
return;
diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h
index 0bd8072db8..2b9974be06 100644
--- a/src/qml/jsruntime/qv4objectproto_p.h
+++ b/src/qml/jsruntime/qv4objectproto_p.h
@@ -51,7 +51,7 @@ namespace QV4 {
struct ObjectCtor: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
ObjectCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *that, CallData *callData);
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp
new file mode 100644
index 0000000000..72e3651757
--- /dev/null
+++ b/src/qml/jsruntime/qv4persistent.cpp
@@ -0,0 +1,255 @@
+/****************************************************************************
+**
+** 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 "qv4persistent_p.h"
+#include "qv4mm_p.h"
+
+using namespace QV4;
+
+PersistentValue::PersistentValue(const ValueRef val)
+ : d(new PersistentValuePrivate(val.asReturnedValue()))
+{
+}
+
+PersistentValue::PersistentValue(ReturnedValue val)
+ : d(new PersistentValuePrivate(val))
+{
+}
+
+PersistentValue::PersistentValue(const PersistentValue &other)
+ : d(other.d)
+{
+ if (d)
+ d->ref();
+}
+
+PersistentValue &PersistentValue::operator=(const PersistentValue &other)
+{
+ if (d == other.d)
+ return *this;
+
+ // the memory manager cleans up those with a refcount of 0
+
+ if (d)
+ d->deref();
+ d = other.d;
+ if (d)
+ d->ref();
+
+ return *this;
+}
+
+PersistentValue &PersistentValue::operator =(const ValueRef other)
+{
+ if (!d) {
+ d = new PersistentValuePrivate(other.asReturnedValue());
+ return *this;
+ }
+ d = d->detach(other.asReturnedValue());
+ return *this;
+}
+
+PersistentValue &PersistentValue::operator =(ReturnedValue other)
+{
+ if (!d) {
+ d = new PersistentValuePrivate(other);
+ return *this;
+ }
+ d = d->detach(other);
+ return *this;
+}
+
+PersistentValue::~PersistentValue()
+{
+ if (d)
+ d->deref();
+}
+
+WeakValue::WeakValue(const ValueRef val)
+ : d(new PersistentValuePrivate(val.asReturnedValue(), /*engine*/0, /*weak*/true))
+{
+}
+
+WeakValue::WeakValue(const WeakValue &other)
+ : d(other.d)
+{
+ if (d)
+ d->ref();
+}
+
+WeakValue::WeakValue(ReturnedValue val)
+ : d(new PersistentValuePrivate(val, /*engine*/0, /*weak*/true))
+{
+}
+
+WeakValue &WeakValue::operator=(const WeakValue &other)
+{
+ if (d == other.d)
+ return *this;
+
+ // the memory manager cleans up those with a refcount of 0
+
+ if (d)
+ d->deref();
+ d = other.d;
+ if (d)
+ d->ref();
+
+ return *this;
+}
+
+WeakValue &WeakValue::operator =(const ValueRef other)
+{
+ if (!d) {
+ d = new PersistentValuePrivate(other.asReturnedValue(), /*engine*/0, /*weak*/true);
+ return *this;
+ }
+ d = d->detach(other.asReturnedValue(), /*weak*/true);
+ return *this;
+}
+
+WeakValue &WeakValue::operator =(const ReturnedValue &other)
+{
+ if (!d) {
+ d = new PersistentValuePrivate(other, /*engine*/0, /*weak*/true);
+ return *this;
+ }
+ d = d->detach(other, /*weak*/true);
+ return *this;
+}
+
+
+WeakValue::~WeakValue()
+{
+ if (d)
+ d->deref();
+}
+
+void WeakValue::markOnce(ExecutionEngine *e)
+{
+ if (!d)
+ return;
+ d->value.mark(e);
+}
+
+PersistentValuePrivate::PersistentValuePrivate(ReturnedValue v, ExecutionEngine *e, bool weak)
+ : refcount(1)
+ , weak(weak)
+ , engine(e)
+ , prev(0)
+ , next(0)
+{
+ value.val = v;
+ init();
+}
+
+void PersistentValuePrivate::init()
+{
+ if (!engine) {
+ Managed *m = value.asManaged();
+ if (!m)
+ return;
+
+ engine = m->engine();
+ }
+ if (engine && !prev) {
+ PersistentValuePrivate **listRoot = weak ? &engine->memoryManager->m_weakValues : &engine->memoryManager->m_persistentValues;
+
+ prev = listRoot;
+ next = *listRoot;
+ *prev = this;
+ if (next)
+ next->prev = &this->next;
+ }
+}
+
+PersistentValuePrivate::~PersistentValuePrivate()
+{
+}
+
+void PersistentValuePrivate::removeFromList()
+{
+ if (prev) {
+ if (next)
+ next->prev = prev;
+ *prev = next;
+ next = 0;
+ prev = 0;
+ }
+}
+
+void PersistentValuePrivate::deref()
+{
+ // if engine is not 0, they are registered with the memory manager
+ // and will get cleaned up in the next gc run
+ if (!--refcount) {
+ removeFromList();
+ delete this;
+ }
+}
+
+PersistentValuePrivate *PersistentValuePrivate::detach(const QV4::ReturnedValue val, bool weak)
+{
+ if (refcount == 1) {
+ value.val = val;
+
+ Managed *m = value.asManaged();
+ if (!prev) {
+ if (m) {
+ ExecutionEngine *engine = m->engine();
+ if (engine) {
+ PersistentValuePrivate **listRoot = weak ? &engine->memoryManager->m_weakValues : &engine->memoryManager->m_persistentValues;
+ prev = listRoot;
+ next = *listRoot;
+ *prev = this;
+ if (next)
+ next->prev = &this->next;
+ }
+ }
+ } else if (!m)
+ removeFromList();
+
+ return this;
+ }
+ --refcount;
+ return new PersistentValuePrivate(val, engine, weak);
+}
+
diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h
new file mode 100644
index 0000000000..21f37f3d96
--- /dev/null
+++ b/src/qml/jsruntime/qv4persistent_p.h
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 QV4PERSISTENT_H
+#define QV4PERSISTENT_H
+
+#include "qv4value_inl_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+struct Q_QML_PRIVATE_EXPORT PersistentValuePrivate
+{
+ PersistentValuePrivate(ReturnedValue v, ExecutionEngine *engine = 0, bool weak = false);
+ virtual ~PersistentValuePrivate();
+ Value value;
+ uint refcount;
+ bool weak;
+ QV4::ExecutionEngine *engine;
+ PersistentValuePrivate **prev;
+ PersistentValuePrivate *next;
+
+ void init();
+ void removeFromList();
+ void ref() { ++refcount; }
+ void deref();
+ PersistentValuePrivate *detach(const ReturnedValue value, bool weak = false);
+
+ bool checkEngine(QV4::ExecutionEngine *otherEngine) {
+ if (!engine) {
+ Q_ASSERT(!value.isObject());
+ engine = otherEngine;
+ }
+ return (engine == otherEngine);
+ }
+};
+
+class Q_QML_EXPORT PersistentValue
+{
+public:
+ PersistentValue() : d(0) {}
+ PersistentValue(const PersistentValue &other);
+ PersistentValue &operator=(const PersistentValue &other);
+
+ PersistentValue(const ValueRef val);
+ PersistentValue(ReturnedValue val);
+ template<typename T>
+ PersistentValue(Returned<T> *obj);
+ PersistentValue(const ManagedRef obj);
+ PersistentValue &operator=(const ValueRef other);
+ PersistentValue &operator=(const ScopedValue &other);
+ PersistentValue &operator =(ReturnedValue other);
+ template<typename T>
+ PersistentValue &operator=(Returned<T> *obj);
+ PersistentValue &operator=(const ManagedRef obj);
+ ~PersistentValue();
+
+ ReturnedValue value() const {
+ return (d ? d->value.asReturnedValue() : Primitive::undefinedValue().asReturnedValue());
+ }
+
+ ExecutionEngine *engine() {
+ if (!d)
+ return 0;
+ if (d->engine)
+ return d->engine;
+ Managed *m = d->value.asManaged();
+ return m ? m->engine() : 0;
+ }
+
+ bool isUndefined() const { return !d || d->value.isUndefined(); }
+ bool isNullOrUndefined() const { return !d || d->value.isNullOrUndefined(); }
+ void clear() {
+ *this = PersistentValue();
+ }
+
+private:
+ friend struct ValueRef;
+ PersistentValuePrivate *d;
+};
+
+class Q_QML_EXPORT WeakValue
+{
+public:
+ WeakValue() : d(0) {}
+ WeakValue(const ValueRef val);
+ WeakValue(const WeakValue &other);
+ WeakValue(ReturnedValue val);
+ template<typename T>
+ WeakValue(Returned<T> *obj);
+ WeakValue &operator=(const WeakValue &other);
+ WeakValue &operator=(const ValueRef other);
+ WeakValue &operator =(const ReturnedValue &other);
+ template<typename T>
+ WeakValue &operator=(Returned<T> *obj);
+
+ ~WeakValue();
+
+ ReturnedValue value() const {
+ return (d ? d->value.asReturnedValue() : Primitive::undefinedValue().asReturnedValue());
+ }
+
+ ExecutionEngine *engine() {
+ if (!d)
+ return 0;
+ if (d->engine)
+ return d->engine;
+ Managed *m = d->value.asManaged();
+ return m ? m->engine() : 0;
+ }
+
+ bool isUndefined() const { return !d || d->value.isUndefined(); }
+ bool isNullOrUndefined() const { return !d || d->value.isNullOrUndefined(); }
+ void clear() {
+ *this = WeakValue();
+ }
+
+ void markOnce(ExecutionEngine *e);
+
+private:
+ friend struct ValueRef;
+ PersistentValuePrivate *d;
+};
+
+} // namespace QV4
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h
index 9763de5adf..aceb6022f8 100644
--- a/src/qml/jsruntime/qv4property_p.h
+++ b/src/qml/jsruntime/qv4property_p.h
@@ -42,7 +42,7 @@
#define QV4PROPERTYDESCRIPTOR_H
#include "qv4global_p.h"
-#include "qv4value_p.h"
+#include "qv4value_inl_p.h"
#include "qv4internalclass_p.h"
QT_BEGIN_NAMESPACE
@@ -52,13 +52,8 @@ namespace QV4 {
struct FunctionObject;
struct Property {
- union {
- Value value;
- struct {
- FunctionObject *get;
- FunctionObject *set;
- };
- };
+ Value value;
+ Value set;
// Section 8.10
inline void fullyPopulated(PropertyAttributes *attrs) {
@@ -67,10 +62,10 @@ struct Property {
}
if (attrs->type() == PropertyAttributes::Accessor) {
attrs->clearWritable();
- if (get == (FunctionObject *)0x1)
- get = 0;
- if (set == (FunctionObject *)0x1)
- set = 0;
+ if (value.isEmpty())
+ value = Primitive::undefinedValue();
+ if (set.isEmpty())
+ set = Primitive::undefinedValue();
}
attrs->resolve();
}
@@ -82,8 +77,8 @@ struct Property {
}
static inline Property fromAccessor(FunctionObject *getter, FunctionObject *setter) {
Property pd;
- pd.get = getter;
- pd.set = setter;
+ pd.value = Primitive::fromManaged(reinterpret_cast<Managed *>(getter));
+ pd.set = Primitive::fromManaged(reinterpret_cast<Managed *>(setter));
return pd;
}
@@ -96,10 +91,10 @@ struct Property {
inline bool isSubset(const PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs) const;
inline void merge(PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs);
- inline FunctionObject *getter() const { return get; }
- inline FunctionObject *setter() const { return set; }
- inline void setGetter(FunctionObject *g) { get = g; }
- inline void setSetter(FunctionObject *s) { set = s; }
+ inline FunctionObject *getter() const { return reinterpret_cast<FunctionObject *>(value.asManaged()); }
+ inline FunctionObject *setter() const { return reinterpret_cast<FunctionObject *>(set.asManaged()); }
+ inline void setGetter(FunctionObject *g) { value = Primitive::fromManaged(reinterpret_cast<Managed *>(g)); }
+ inline void setSetter(FunctionObject *s) { set = Primitive::fromManaged(reinterpret_cast<Managed *>(s)); }
};
inline bool Property::isSubset(const PropertyAttributes &attrs, const Property &other, PropertyAttributes otherAttrs) const
@@ -115,9 +110,9 @@ inline bool Property::isSubset(const PropertyAttributes &attrs, const Property &
if (attrs.type() == PropertyAttributes::Data && !value.sameValue(other.value))
return false;
if (attrs.type() == PropertyAttributes::Accessor) {
- if (get != other.get)
+ if (value.asManaged() != other.value.asManaged())
return false;
- if (set != other.set)
+ if (set.asManaged() != other.set.asManaged())
return false;
}
return true;
@@ -133,10 +128,10 @@ inline void Property::merge(PropertyAttributes &attrs, const Property &other, Pr
attrs.setWritable(otherAttrs.isWritable());
if (otherAttrs.type() == PropertyAttributes::Accessor) {
attrs.setType(PropertyAttributes::Accessor);
- if (other.get)
- get = (other.get == (FunctionObject *)0x1) ? 0 : other.get;
- if (other.set)
- set = (other.set == (FunctionObject *)0x1) ? 0 : other.set;
+ if (!other.value.isEmpty())
+ value = other.value;
+ if (!other.set.isEmpty())
+ set = other.set;
} else if (otherAttrs.type() == PropertyAttributes::Data){
attrs.setType(PropertyAttributes::Data);
value = other.value;
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index e40875dff3..7f4ac22377 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -241,7 +241,7 @@ QObjectWrapper::QObjectWrapper(ExecutionEngine *engine, QObject *object)
: Object(engine)
, m_object(object)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
Scope scope(engine);
ScopedObject protectThis(scope, this);
@@ -695,42 +695,39 @@ PropertyAttributes QObjectWrapper::query(const Managed *m, StringRef name)
QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(engine);
QQmlPropertyData local;
if (that->findProperty(engine, qmlContext, name, IgnoreRevision, &local)
- || name->equals(const_cast<SafeString &>(that->m_destroy)) || name->equals(engine->id_toString))
+ || name->equals(const_cast<StringValue &>(that->m_destroy)) || name->equals(engine->id_toString))
return QV4::Attr_Data;
else
return QV4::Object::query(m, name);
}
-Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes)
+void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes)
{
name = (String *)0;
*index = UINT_MAX;
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
- if (!that->m_object)
- return QV4::Object::advanceIterator(m, it, name, index, attributes);
-
- const QMetaObject *mo = that->m_object->metaObject();
- const int propertyCount = mo->propertyCount();
- if (it->arrayIndex < static_cast<uint>(propertyCount)) {
- name = that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name()));
- ++it->arrayIndex;
- if (attributes)
+ if (that->m_object) {
+ const QMetaObject *mo = that->m_object->metaObject();
+ const int propertyCount = mo->propertyCount();
+ if (it->arrayIndex < static_cast<uint>(propertyCount)) {
+ name = that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name()));
+ ++it->arrayIndex;
*attributes = QV4::Attr_Data;
- it->tmpDynamicProperty.value = that->get(name);
- return &it->tmpDynamicProperty;
- }
- const int methodCount = mo->methodCount();
- if (it->arrayIndex < static_cast<uint>(propertyCount + methodCount)) {
- name = that->engine()->newString(QString::fromUtf8(mo->method(it->arrayIndex - propertyCount).name()));
- ++it->arrayIndex;
- if (attributes)
+ p->value = that->get(name);
+ return;
+ }
+ const int methodCount = mo->methodCount();
+ if (it->arrayIndex < static_cast<uint>(propertyCount + methodCount)) {
+ name = that->engine()->newString(QString::fromUtf8(mo->method(it->arrayIndex - propertyCount).name()));
+ ++it->arrayIndex;
*attributes = QV4::Attr_Data;
- it->tmpDynamicProperty.value = that->get(name);
- return &it->tmpDynamicProperty;
+ p->value = that->get(name);
+ return;
+ }
}
- return QV4::Object::advanceIterator(m, it, name, index, attributes);
+ QV4::Object::advanceIterator(m, it, name, index, p, attributes);
}
namespace QV4 {
@@ -1120,7 +1117,7 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType,
return args[0].toValue(engine);
} else if (returnType != QMetaType::Void) {
-
+
CallArgument arg;
arg.initAsType(returnType);
@@ -1140,7 +1137,7 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType,
}
/*!
- Returns the match score for converting \a actual to be of type \a conversionType. A
+ Returns the match score for converting \a actual to be of type \a conversionType. A
zero score means "perfect match" whereas a higher score is worse.
The conversion table is copied out of the \l QScript::callQtMethod() function.
@@ -1314,7 +1311,7 @@ static const QQmlPropertyData * RelatedMethod(QObject *object,
QMetaMethod method = mo->method(current->overrideIndex);
dummy.load(method);
-
+
// Look for overloaded methods
QByteArray methodName = method.name();
for (int ii = current->overrideIndex - 1; ii >= methodOffset; --ii) {
@@ -1348,7 +1345,7 @@ static QV4::ReturnedValue CallPrecise(QObject *object, const QQmlPropertyData &d
int *args = 0;
QVarLengthArray<int, 9> dummy;
- args = QQmlPropertyCache::methodParameterTypes(object, data.coreIndex, dummy,
+ args = QQmlPropertyCache::methodParameterTypes(object, data.coreIndex, dummy,
&unknownTypeError);
if (!args) {
@@ -1374,13 +1371,13 @@ static QV4::ReturnedValue CallPrecise(QObject *object, const QQmlPropertyData &d
/*!
Resolve the overloaded method to call. The algorithm works conceptually like this:
1. Resolve the set of overloads it is *possible* to call.
- Impossible overloads include those that have too many parameters or have parameters
- of unknown type.
- 2. Filter the set of overloads to only contain those with the closest number of
+ Impossible overloads include those that have too many parameters or have parameters
+ of unknown type.
+ 2. Filter the set of overloads to only contain those with the closest number of
parameters.
For example, if we are called with 3 parameters and there are 2 overloads that
take 2 parameters and one that takes 3, eliminate the 2 parameter overloads.
- 3. Find the best remaining overload based on its match score.
+ 3. Find the best remaining overload based on its match score.
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.
*/
@@ -1431,7 +1428,7 @@ static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData
continue; // We already have a better option
int methodMatchScore = 0;
- for (int ii = 0; ii < methodArgumentCount; ++ii)
+ for (int ii = 0; ii < methodArgumentCount; ++ii)
methodMatchScore += MatchScore((v = callArgs->args[ii]), methodArgTypes[ii]);
if (bestParameterScore > methodParameterScore || bestMatchScore > methodMatchScore) {
@@ -1453,7 +1450,7 @@ static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData
QString error = QLatin1String("Unable to determine callable overload. Candidates are:");
const QQmlPropertyData *candidate = &data;
while (candidate) {
- error += QLatin1String("\n ") +
+ error += QLatin1String("\n ") +
QString::fromUtf8(object->metaObject()->method(candidate->coreIndex).methodSignature().constData());
candidate = RelatedMethod(object, candidate, dummy);
}
@@ -1488,7 +1485,7 @@ void CallArgument::cleanup()
jsonObjectPtr->~QJsonObject();
} else if (type == QMetaType::QJsonValue) {
jsonValuePtr->~QJsonValue();
- }
+ }
}
void *CallArgument::dataPtr()
@@ -1595,7 +1592,7 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, const QV4::ValueRe
if (array) {
Scoped<QV4::QObjectWrapper> qobjectWrapper(scope);
- uint32_t length = array->arrayLength();
+ uint32_t length = array->getLength();
for (uint32_t ii = 0; ii < length; ++ii) {
QObject *o = 0;
qobjectWrapper = array->getIndexed(ii);
@@ -1692,10 +1689,9 @@ QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine)
QList<QObject *> &list = *qlistPtr;
QV4::Scoped<ArrayObject> array(scope, v4->newArrayObject());
array->arrayReserve(list.count());
- for (int ii = 0; ii < list.count(); ++ii) {
- array->arrayData[ii].value = QV4::QObjectWrapper::wrap(v4, list.at(ii));
- array->arrayDataLen = ii + 1;
- }
+ QV4::ScopedValue v(scope);
+ for (int ii = 0; ii < list.count(); ++ii)
+ array->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(v4, list.at(ii))));
array->setArrayLengthUnchecked(list.count());
return array.asReturnedValue();
} else if (type == qMetaTypeId<QQmlV4Handle>()) {
@@ -1709,7 +1705,8 @@ QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine)
} else if (type == -1 || type == qMetaTypeId<QVariant>()) {
QVariant value = *qvariantPtr;
QV4::ScopedValue rv(scope, engine->fromVariant(value));
- if (QV4::Referenced<QObjectWrapper> qobjectWrapper = rv->asRef<QV4::QObjectWrapper>()) {
+ QV4::QObjectWrapperRef qobjectWrapper = rv;
+ if (!!qobjectWrapper) {
if (QObject *object = qobjectWrapper->object())
QQmlData::get(object, true)->setImplicitDestructible();
}
@@ -1729,7 +1726,7 @@ QObjectMethod::QObjectMethod(ExecutionContext *scope, QObject *object, int index
, m_object(object)
, m_index(index)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
subtype = WrappedQtMethod;
m_qmlGlobal = qmlGlobal;
}
@@ -1843,17 +1840,17 @@ ReturnedValue QObjectMethod::callInternal(CallData *callData)
}
}
-DEFINE_MANAGED_VTABLE(QObjectMethod);
+DEFINE_OBJECT_VTABLE(QObjectMethod);
QmlSignalHandler::QmlSignalHandler(ExecutionEngine *engine, QObject *object, int signalIndex)
: Object(engine)
, m_object(object)
, m_signalIndex(signalIndex)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
-DEFINE_MANAGED_VTABLE(QmlSignalHandler);
+DEFINE_OBJECT_VTABLE(QmlSignalHandler);
void MultiplyWrappedQObjectMap::insert(QObject *key, Object *value)
{
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 07de1933c5..ca38c5b0dc 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -62,7 +62,7 @@
#include <private/qqmlpropertycache_p.h>
#include <private/qintrusivelist_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4functionobject_p.h>
QT_BEGIN_NAMESPACE
@@ -77,7 +77,7 @@ struct QObjectSlotDispatcher;
struct Q_QML_EXPORT QObjectWrapper : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
enum RevisionMode { IgnoreRevision, CheckRevision };
@@ -111,12 +111,12 @@ private:
QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
QPointer<QObject> m_object;
- SafeString m_destroy;
+ StringValue m_destroy;
static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
static void put(Managed *m, const StringRef name, const ValueRef value);
static PropertyAttributes query(const Managed *, StringRef name);
- static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
+ static void advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
static void markObjects(Managed *that, QV4::ExecutionEngine *e);
static void collectDeletables(Managed *m, GCDeletable **deletable);
static void destroy(Managed *that)
@@ -130,7 +130,7 @@ private:
struct QObjectMethod : public QV4::FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
enum { DestroyMethod = -1, ToStringMethod = -2 };
@@ -161,7 +161,7 @@ private:
struct QmlSignalHandler : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
QmlSignalHandler(ExecutionEngine *engine, QObject *object, int signalIndex);
@@ -200,6 +200,8 @@ private Q_SLOTS:
void removeDestroyedObject(QObject*);
};
+DEFINE_REF(QObjectWrapper, Object);
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index 41ff9f9741..e5490cffd1 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -99,8 +99,6 @@ RegExp::RegExp(ExecutionEngine* engine, const QString &pattern, bool ignoreCase,
, m_ignoreCase(ignoreCase)
, m_multiLine(multiline)
{
- type = Type_RegExpObject;
-
if (!engine)
return;
const char* error = 0;
@@ -136,71 +134,3 @@ void RegExp::markObjects(Managed *that, ExecutionEngine *e)
Q_UNUSED(that);
Q_UNUSED(e);
}
-
-ReturnedValue RegExp::get(Managed *, const StringRef, bool *)
-{
- return Encode::undefined();
-}
-
-ReturnedValue RegExp::getIndexed(Managed *m, uint index, bool *hasProperty)
-{
- Q_UNUSED(m);
- Q_UNUSED(index);
- Q_UNUSED(hasProperty);
-
- return Encode::undefined();
-}
-
-void RegExp::put(Managed *m, const StringRef name, const ValueRef value)
-{
- Q_UNUSED(m);
- Q_UNUSED(name);
- Q_UNUSED(value);
-}
-
-void RegExp::putIndexed(Managed *m, uint index, const ValueRef value)
-{
- Q_UNUSED(m);
- Q_UNUSED(index);
- Q_UNUSED(value);
-}
-
-PropertyAttributes RegExp::query(const Managed *m, StringRef name)
-{
- Q_UNUSED(m);
- Q_UNUSED(name);
-
- return Attr_Invalid;
-}
-
-PropertyAttributes RegExp::queryIndexed(const Managed *m, uint index)
-{
- Q_UNUSED(m);
- Q_UNUSED(index);
-
- return Attr_Invalid;
-}
-
-bool RegExp::deleteProperty(Managed *, const StringRef)
-{
- return false;
-}
-
-bool RegExp::deleteIndexedProperty(Managed *m, uint index)
-{
- Q_UNUSED(m);
- Q_UNUSED(index);
-
- return false;
-}
-
-Property *RegExp::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes)
-{
- Q_UNUSED(m);
- Q_UNUSED(it);
- Q_UNUSED(name);
- Q_UNUSED(index);
- Q_UNUSED(attributes);
-
- return 0;
-}
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index 9041ff2ef4..1bcc2c6f5a 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -93,7 +93,8 @@ public:
class RegExp : public Managed
{
- Q_MANAGED
+ V4_MANAGED
+ Q_MANAGED_TYPE(RegExp)
public:
static RegExp* create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false);
~RegExp();
@@ -111,15 +112,6 @@ public:
protected:
static void destroy(Managed *that);
static void markObjects(Managed *that, QV4::ExecutionEngine *e);
- static ReturnedValue get(Managed *, const StringRef, bool *);
- static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
- static void put(Managed *m, const StringRef name, const ValueRef value);
- static void putIndexed(Managed *m, uint index, const ValueRef value);
- static PropertyAttributes query(const Managed *m, StringRef name);
- static PropertyAttributes queryIndexed(const Managed *m, uint index);
- static bool deleteProperty(Managed *, const StringRef);
- static bool deleteIndexedProperty(Managed *m, uint index);
- static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
private:
friend class RegExpCache;
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 0ebad2f781..74c8a2d35e 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -69,17 +69,18 @@ Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyn
using namespace QV4;
-DEFINE_MANAGED_VTABLE(RegExpObject);
+DEFINE_OBJECT_VTABLE(RegExpObject);
RegExpObject::RegExpObject(InternalClass *ic)
: Object(ic)
, value(RegExp::create(ic->engine, QString(), false, false))
, global(false)
{
+ Q_ASSERT(internalClass->vtable == staticVTable());
init(ic->engine);
}
-RegExpObject::RegExpObject(ExecutionEngine *engine, Referenced<RegExp> value, bool global)
+RegExpObject::RegExpObject(ExecutionEngine *engine, RegExpRef value, bool global)
: Object(engine->regExpClass)
, value(value)
, global(global)
@@ -142,15 +143,14 @@ RegExpObject::RegExpObject(ExecutionEngine *engine, const QRegExp &re)
void RegExpObject::init(ExecutionEngine *engine)
{
- setVTable(&static_vtbl);
- type = Type_RegExpObject;
+ setVTable(staticVTable());
Scope scope(engine);
ScopedObject protectThis(scope, this);
ScopedString lastIndex(scope, engine->newIdentifier(QStringLiteral("lastIndex")));
- Property *lastIndexProperty = insertMember(lastIndex, Attr_NotEnumerable|Attr_NotConfigurable);
- lastIndexProperty->value = Primitive::fromInt32(0);
+ ScopedValue v(scope, Primitive::fromInt32(0));
+ insertMember(lastIndex, v, Attr_NotEnumerable|Attr_NotConfigurable);
if (!this->value)
return;
@@ -162,7 +162,6 @@ void RegExpObject::init(ExecutionEngine *engine)
p.replace('/', QLatin1String("\\/"));
}
- ScopedValue v(scope);
defineReadonlyProperty(QStringLiteral("source"), (v = engine->newString(p)));
defineReadonlyProperty(QStringLiteral("global"), Primitive::fromBoolean(global));
defineReadonlyProperty(QStringLiteral("ignoreCase"), Primitive::fromBoolean(this->value->ignoreCase()));
@@ -232,12 +231,12 @@ uint RegExpObject::flags() const
return f;
}
-DEFINE_MANAGED_VTABLE(RegExpCtor);
+DEFINE_OBJECT_VTABLE(RegExpCtor);
RegExpCtor::RegExpCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("RegExp"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
clearLastMatch();
}
@@ -387,11 +386,12 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
Scoped<ArrayObject> array(scope, ctx->engine->newArrayObject(ctx->engine->regExpExecArrayClass));
int len = r->value->captureCount();
array->arrayReserve(len);
+ ScopedValue v(scope);
for (int i = 0; i < len; ++i) {
int start = matchOffsets[i * 2];
int end = matchOffsets[i * 2 + 1];
- array->arrayData[i].value = (start != -1 && end != -1) ? ctx->engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
- array->arrayDataLen = i + 1;
+ v = (start != -1 && end != -1) ? ctx->engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
+ array->arrayPut(i, v);
}
array->setArrayLengthUnchecked(len);
array->memberData[Index_ArrayIndex].value = Primitive::fromInt32(result);
@@ -433,7 +433,7 @@ ReturnedValue RegExpPrototype::method_compile(CallContext *ctx)
return ctx->throwTypeError();
ScopedCallData callData(scope, ctx->callData->argc);
- memcpy(callData->args, ctx->callData->args, ctx->callData->argc*sizeof(SafeValue));
+ memcpy(callData->args, ctx->callData->args, ctx->callData->argc*sizeof(Value));
Scoped<RegExpObject> re(scope, ctx->engine->regExpCtor.asFunctionObject()->construct(callData));
@@ -457,7 +457,7 @@ ReturnedValue RegExpPrototype::method_get_lastParen(CallContext *ctx)
{
Scope scope(ctx);
ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->engine->regExpCtor.objectValue())->lastMatch);
- ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(lastMatch->arrayLength() - 1) : Encode::undefined());
+ ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined());
if (result->isUndefined())
return ctx->engine->newString(QString())->asReturnedValue();
return result.asReturnedValue();
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index f112ad804d..1b408749d3 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -66,7 +66,8 @@ namespace QV4 {
class RegExp;
struct RegExpObject: Object {
- Q_MANAGED
+ V4_OBJECT
+ Q_MANAGED_TYPE(RegExpObject)
// needs to be compatible with the flags in qv4jsir_p.h
enum Flags {
RegExp_Global = 0x01,
@@ -83,7 +84,7 @@ struct RegExpObject: Object {
Property *lastIndexProperty(ExecutionContext *ctx);
bool global;
- RegExpObject(ExecutionEngine *engine, Referenced<RegExp> value, bool global);
+ RegExpObject(ExecutionEngine *engine, RegExpRef value, bool global);
RegExpObject(ExecutionEngine *engine, const QRegExp &re);
~RegExpObject() {}
@@ -100,14 +101,15 @@ protected:
static void markObjects(Managed *that, ExecutionEngine *e);
};
+DEFINE_REF(RegExp, Object);
struct RegExpCtor: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
RegExpCtor(ExecutionContext *scope);
- SafeValue lastMatch;
- SafeString lastInput;
+ Value lastMatch;
+ StringValue lastInput;
int lastMatchStart;
int lastMatchEnd;
void clearLastMatch();
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 011607f0ba..a3cae3382d 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -338,7 +338,7 @@ QV4::ReturnedValue __qmljs_in(ExecutionContext *ctx, const ValueRef left, const
ScopedString s(scope, left->toString(ctx));
if (scope.hasException())
return Encode::undefined();
- bool r = right->objectValue()->__hasProperty__(s);
+ bool r = right->objectValue()->hasProperty(s);
return Encode(r);
}
@@ -383,8 +383,8 @@ ReturnedValue __qmljs_object_default_value(Object *object, int typeHint)
if (engine->hasException)
return Encode::undefined();
- SafeString *meth1 = &engine->id_toString;
- SafeString *meth2 = &engine->id_valueOf;
+ StringValue *meth1 = &engine->id_toString;
+ StringValue *meth2 = &engine->id_valueOf;
if (typeHint == NUMBER_HINT)
qSwap(meth1, meth2);
@@ -589,12 +589,10 @@ ReturnedValue __qmljs_get_element(ExecutionContext *ctx, const ValueRef object,
}
if (idx < UINT_MAX) {
- uint pidx = o->propertyIndexFromArrayIndex(idx);
- if (pidx < UINT_MAX) {
- if (!o->arrayAttributes || o->arrayAttributes[pidx].isData()) {
- if (!o->arrayData[pidx].value.isEmpty())
- return o->arrayData[pidx].value.asReturnedValue();
- }
+ if (!o->arrayData->hasAttributes()) {
+ ScopedValue v(scope, o->arrayData->get(idx));
+ if (!v->isEmpty())
+ return v->asReturnedValue();
}
return o->getIndexed(idx);
@@ -615,32 +613,10 @@ void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const Val
uint idx = index->asArrayIndex();
if (idx < UINT_MAX) {
- uint pidx = o->propertyIndexFromArrayIndex(idx);
- if (pidx < UINT_MAX) {
- if (o->arrayAttributes && !o->arrayAttributes[pidx].isEmpty() && !o->arrayAttributes[pidx].isWritable()) {
- if (ctx->strictMode)
- ctx->throwTypeError();
- return;
- }
-
- Property *p = o->arrayData + pidx;
- if (!o->arrayAttributes || o->arrayAttributes[pidx].isData()) {
- p->value = *value;
- return;
- }
-
- if (o->arrayAttributes[pidx].isAccessor()) {
- FunctionObject *setter = p->setter();
- if (!setter) {
- if (ctx->strictMode)
- ctx->throwTypeError();
- return;
- }
-
- ScopedCallData callData(scope, 1);
- callData->thisObject = o;
- callData->args[0] = *value;
- setter->call(callData);
+ if (o->arrayType() == ArrayData::Simple) {
+ SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData);
+ if (s && idx < s->len && !s->data[idx].isEmpty()) {
+ s->data[idx] = value;
return;
}
}
@@ -918,12 +894,12 @@ ReturnedValue __qmljs_call_property(ExecutionContext *context, const StringRef n
ReturnedValue __qmljs_call_property_lookup(ExecutionContext *context, uint index, CallDataRef callData)
{
Lookup *l = context->lookups + index;
- SafeValue v;
+ Value v;
v = l->getter(l, callData->thisObject);
- if (!v.isManaged())
+ if (!v.isObject())
return context->throwTypeError();
- return v.managed()->call(callData);
+ return v.objectValue()->call(callData);
}
ReturnedValue __qmljs_call_element(ExecutionContext *context, const ValueRef index, CallDataRef callData)
@@ -945,10 +921,10 @@ ReturnedValue __qmljs_call_element(ExecutionContext *context, const ValueRef ind
ReturnedValue __qmljs_call_value(ExecutionContext *context, const ValueRef func, CallDataRef callData)
{
- if (!func->isManaged())
+ if (!func->isObject())
return context->throwTypeError();
- return func->managed()->call(callData);
+ return func->objectValue()->call(callData);
}
@@ -1006,12 +982,12 @@ ReturnedValue __qmljs_construct_property(ExecutionContext *context, const String
ReturnedValue __qmljs_construct_property_lookup(ExecutionContext *context, uint index, CallDataRef callData)
{
Lookup *l = context->lookups + index;
- SafeValue v;
+ Value v;
v = l->getter(l, callData->thisObject);
- if (!v.isManaged())
+ if (!v.isObject())
return context->throwTypeError();
- return v.managed()->construct(callData);
+ return v.objectValue()->construct(callData);
}
@@ -1118,8 +1094,12 @@ void __qmljs_builtin_define_property(ExecutionContext *ctx, const ValueRef objec
assert(o);
uint idx = name->asArrayIndex();
- Property *pd = (idx != UINT_MAX) ? o->arrayInsert(idx) : o->insertMember(name, Attr_Data);
- pd->value = val ? *val : Primitive::undefinedValue();
+ if (idx != UINT_MAX) {
+ o->arraySet(idx, val);
+ } else {
+ ScopedValue v(scope, val ? *val : Primitive::undefinedValue());
+ o->insertMember(name, v);
+ }
}
ReturnedValue __qmljs_builtin_define_array(ExecutionContext *ctx, Value *values, uint length)
@@ -1127,16 +1107,9 @@ ReturnedValue __qmljs_builtin_define_array(ExecutionContext *ctx, Value *values,
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
- a->arrayReserve(length);
if (length) {
- a->arrayDataLen = length;
- Property *pd = a->arrayData;
- for (uint i = 0; i < length; ++i) {
- pd->value = values[i];
- ++pd;
- }
+ a->arrayReserve(length);
+ a->arrayPut(0, values, length);
a->setArrayLengthUnchecked(length);
}
return a.asReturnedValue();
@@ -1149,9 +1122,14 @@ void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const ValueRef
Q_ASSERT(!!o);
uint idx = name->asArrayIndex();
- Property *pd = (idx != UINT_MAX) ? o->arrayInsert(idx, Attr_Accessor) : o->insertMember(name, Attr_Accessor);
- pd->setGetter(getter ? getter->asFunctionObject() : 0);
- pd->setSetter(setter ? setter->asFunctionObject() : 0);
+ Property pd;
+ pd.value = getter;
+ pd.set = setter;
+ if (idx != UINT_MAX) {
+ o->arraySet(idx, pd, Attr_Accessor);
+ } else {
+ o->insertMember(name, pd, Attr_Accessor);
+ }
}
ReturnedValue __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, const QV4::Value *args, int classId)
@@ -1164,9 +1142,9 @@ ReturnedValue __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx,
if (klass->propertyData[i].isData())
o->memberData[i].value = *args++;
else {
- o->memberData[i].setGetter(args->asFunctionObject());
+ o->memberData[i].value = *args;
args++;
- o->memberData[i].setSetter(args->asFunctionObject());
+ o->memberData[i].set = *args;
args++;
}
}
@@ -1330,7 +1308,7 @@ QV4::ReturnedValue __qmljs_get_qml_singleton(QV4::NoThrowContext *ctx, const QV4
void __qmljs_builtin_convert_this_to_object(ExecutionContext *ctx)
{
- SafeValue *t = &ctx->callData->thisObject;
+ Value *t = &ctx->callData->thisObject;
if (t->isObject())
return;
if (t->isNullOrUndefined()) {
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 9524b2459c..3c2824ee23 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -42,9 +42,10 @@
#define QMLJS_RUNTIME_H
#include "qv4global_p.h"
-#include "qv4value_p.h"
+#include "qv4value_inl_p.h"
#include "qv4math_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4context_p.h"
#include <QtCore/QString>
#include <QtCore/qnumeric.h>
@@ -141,7 +142,7 @@ QV4::ExecutionContext *__qmljs_builtin_pop_scope(QV4::ExecutionContext *ctx);
ReturnedValue __qmljs_builtin_unwind_exception(ExecutionContext *ctx);
void __qmljs_builtin_declare_var(QV4::ExecutionContext *ctx, bool deletable, const QV4::StringRef name);
void __qmljs_builtin_define_property(QV4::ExecutionContext *ctx, const QV4::ValueRef object, const QV4::StringRef name, QV4::ValueRef val);
-QV4::ReturnedValue __qmljs_builtin_define_array(QV4::ExecutionContext *ctx, QV4::Value *values, uint length);
+QV4::ReturnedValue __qmljs_builtin_define_array(QV4::ExecutionContext *ctx, Value *values, uint length);
void __qmljs_builtin_define_getter_setter(QV4::ExecutionContext *ctx, const QV4::ValueRef object, const QV4::StringRef name, const QV4::ValueRef getter, const QV4::ValueRef setter);
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);
@@ -305,12 +306,7 @@ inline QV4::ReturnedValue __qmljs_compl(const QV4::ValueRef value)
{
TRACE1(value);
- int n;
- if (value->integerCompatible())
- n = value->int_32;
- else
- n = value->toInt32();
-
+ int n = value->toInt32();
return Encode((int)~n);
}
@@ -327,9 +323,6 @@ inline ReturnedValue __qmljs_bit_or(const QV4::ValueRef left, const QV4::ValueRe
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right))
- return Encode(left->integerValue() | right->integerValue());
-
int lval = left->toInt32();
int rval = right->toInt32();
return Encode(lval | rval);
@@ -339,9 +332,6 @@ inline ReturnedValue __qmljs_bit_xor(const QV4::ValueRef left, const QV4::ValueR
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right))
- return Encode(left->integerValue() ^ right->integerValue());
-
int lval = left->toInt32();
int rval = right->toInt32();
return Encode(lval ^ rval);
@@ -351,9 +341,6 @@ inline ReturnedValue __qmljs_bit_and(const QV4::ValueRef left, const QV4::ValueR
{
TRACE2(left, right);
- if (QV4::Value::integerCompatible(*left, *right))
- return Encode(left->integerValue() & right->integerValue());
-
int lval = left->toInt32();
int rval = right->toInt32();
return Encode(lval & rval);
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 2c71a36a3d..5d471ab4fb 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -41,8 +41,9 @@
#ifndef QV4SCOPEDVALUE_P_H
#define QV4SCOPEDVALUE_P_H
-#include "qv4context_p.h"
-#include "qv4value_def_p.h"
+#include "qv4engine_p.h"
+#include "qv4value_p.h"
+#include "qv4persistent_p.h"
QT_BEGIN_NAMESPACE
@@ -54,15 +55,7 @@ namespace QV4 {
struct ScopedValue;
struct Scope {
- explicit Scope(ExecutionContext *ctx)
- : engine(ctx->engine)
-#ifndef QT_NO_DEBUG
- , size(0)
-#endif
- {
- mark = engine->jsStackTop;
- }
-
+ inline explicit Scope(ExecutionContext *ctx);
explicit Scope(ExecutionEngine *e)
: engine(e)
#ifndef QT_NO_DEBUG
@@ -75,13 +68,13 @@ struct Scope {
~Scope() {
#ifndef QT_NO_DEBUG
Q_ASSERT(engine->jsStackTop >= mark);
- memset(mark, 0, (engine->jsStackTop - mark)*sizeof(SafeValue));
+ memset(mark, 0, (engine->jsStackTop - mark)*sizeof(Value));
#endif
engine->jsStackTop = mark;
}
- SafeValue *alloc(int nValues) {
- SafeValue *ptr = engine->jsStackTop;
+ Value *alloc(int nValues) {
+ Value *ptr = engine->jsStackTop;
engine->jsStackTop += nValues;
#ifndef QT_NO_DEBUG
size += nValues;
@@ -94,7 +87,7 @@ struct Scope {
}
ExecutionEngine *engine;
- SafeValue *mark;
+ Value *mark;
#ifndef QT_NO_DEBUG
mutable int size;
#endif
@@ -178,17 +171,17 @@ struct ScopedValue
return *this;
}
- SafeValue *operator->() {
+ Value *operator->() {
return ptr;
}
- const SafeValue *operator->() const {
+ const Value *operator->() const {
return ptr;
}
ReturnedValue asReturnedValue() const { return ptr->val; }
- SafeValue *ptr;
+ Value *ptr;
};
template<typename T>
@@ -234,7 +227,7 @@ struct Scoped
Scoped(const Scope &scope, const Value &v, _Convert)
{
ptr = scope.engine->jsStackTop++;
- ptr->val = value_convert<T>(scope.engine->currentContext(), v);
+ ptr->val = value_convert<T>(scope.engine, v);
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -281,7 +274,7 @@ struct Scoped
Scoped(const Scope &scope, const ReturnedValue &v, _Convert)
{
ptr = scope.engine->jsStackTop++;
- ptr->val = value_convert<T>(scope.engine->currentContext(), QV4::Value::fromReturnedValue(v));
+ ptr->val = value_convert<T>(scope.engine, QV4::Value::fromReturnedValue(v));
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -339,7 +332,7 @@ struct Scoped
#endif
}
- SafeValue *ptr;
+ Value *ptr;
};
struct CallData
@@ -356,14 +349,14 @@ struct CallData
return i < argc ? args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
}
- SafeValue thisObject;
- SafeValue args[1];
+ Value thisObject;
+ Value args[1];
};
struct ScopedCallData {
ScopedCallData(Scope &scope, int argc)
{
- int size = qMax(argc, (int)QV4::Global::ReservedArgumentCount) + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue);
+ int size = qMax(argc, (int)QV4::Global::ReservedArgumentCount) + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value);
ptr = reinterpret_cast<CallData *>(scope.engine->stackPush(size));
ptr->tag = QV4::Value::Integer_Type;
ptr->argc = argc;
@@ -385,141 +378,10 @@ struct ScopedCallData {
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)
- : ptr(&p->value) {}
- ValueRef(SafeValue &v) { ptr = &v; }
- // Important: Do NOT add a copy constructor to this class
- // adding a copy constructor actually changes the calling convention, ie.
- // is not even binary compatible. Adding it would break assumptions made
- // in the jit'ed code.
- ValueRef &operator=(const ScopedValue &o)
- { *ptr = *o.ptr; return *this; }
- ValueRef &operator=(const ValueRef &o)
- { *ptr = *o.ptr; return *this; }
- ValueRef &operator=(const Value &v)
- { *ptr = v; return *this; }
- ValueRef &operator=(const ReturnedValue &v) {
- ptr->val = v;
- return *this;
- }
- template <typename T>
- ValueRef &operator=(Returned<T> *v) {
- ptr->val = v->asReturnedValue();
- return *this;
- }
-
- operator const Value *() const {
- return ptr;
- }
- const Value *operator->() const {
- return ptr;
- }
-
- operator Value *() {
- return ptr;
- }
- SafeValue *operator->() {
- return ptr;
- }
-
- static ValueRef fromRawValue(Value *v) {
- return ValueRef(v);
- }
- 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 = reinterpret_cast<SafeValue *>(v); }
-private:
- SafeValue *ptr;
-};
-
-
-template<typename T>
-struct Referenced {
- // Important: Do NOT add a copy constructor to this class
- // adding a copy constructor actually changes the calling convention, ie.
- // is not even binary compatible. Adding it would break assumptions made
- // in the jit'ed code.
- Referenced(const Scoped<T> &v)
- : ptr(v.ptr) {}
- Referenced(Safe<T> &v) { ptr = &v; }
- Referenced(SafeValue &v) {
- ptr = value_cast<T>(v) ? &v : 0;
- }
-
- Referenced &operator=(const Referenced &o)
- { *ptr = *o.ptr; return *this; }
- Referenced &operator=(T *t)
- {
-#if QT_POINTER_SIZE == 4
- ptr->tag = Value::Managed_Type;
-#endif
- ptr->m = t;
- return *this;
- }
- Referenced &operator=(Returned<T> *t) {
-#if QT_POINTER_SIZE == 4
- ptr->tag = Value::Managed_Type;
-#endif
- ptr->m = t->getPointer();
- return *this;
- }
-
- operator const T *() const {
- return ptr ? static_cast<T*>(ptr->managed()) : 0;
- }
- const T *operator->() const {
- return static_cast<T*>(ptr->managed());
- }
-
- operator T *() {
- return ptr ? static_cast<T*>(ptr->managed()) : 0;
- }
- T *operator->() {
- return static_cast<T*>(ptr->managed());
- }
-
- T *getPointer() const {
- return static_cast<T *>(ptr->managed());
- }
- ReturnedValue asReturnedValue() const { return ptr ? ptr->val : Primitive::undefinedValue().asReturnedValue(); }
- operator Returned<T> *() const { return ptr ? Returned<T>::create(getPointer()) : 0; }
-
- bool operator==(const Referenced<T> &other) {
- if (ptr == other.ptr)
- return true;
- return ptr && other.ptr && ptr->m == other.ptr->m;
- }
- bool operator!=(const Referenced<T> &other) {
- if (ptr == other.ptr)
- return false;
- return !ptr || ptr->m != other.ptr->m;
- }
- bool operator!() const { return !ptr || !ptr->managed(); }
-
- static Referenced null() { return Referenced(Null); }
- bool isNull() const { return !ptr; }
-private:
- enum _Null { Null };
- Referenced(_Null) { ptr = 0; }
- SafeValue *ptr;
-};
-typedef Referenced<String> StringRef;
-typedef Referenced<Object> ObjectRef;
-typedef Referenced<FunctionObject> FunctionObjectRef;
+struct StringRef;
+struct ObjectRef;
+struct FunctionObjectRef;
template<typename T>
inline Scoped<T>::Scoped(const Scope &scope, const ValueRef &v)
@@ -569,51 +431,6 @@ private:
CallData *ptr;
};
-struct Encode {
- static ReturnedValue undefined() {
- return quint64(Value::Undefined_Type) << Value::Tag_Shift;
- }
- static ReturnedValue null() {
- return quint64(Value::_Null_Type) << Value::Tag_Shift;
- }
-
- Encode(bool b) {
- val = (quint64(Value::_Boolean_Type) << Value::Tag_Shift) | (uint)b;
- }
- Encode(double d) {
- Value v;
- v.setDouble(d);
- val = v.val;
- }
- Encode(int i) {
- val = (quint64(Value::_Integer_Type) << Value::Tag_Shift) | (uint)i;
- }
- Encode(uint i) {
- if (i <= INT_MAX) {
- val = (quint64(Value::_Integer_Type) << Value::Tag_Shift) | i;
- } else {
- Value v;
- v.setDouble(i);
- val = v.val;
- }
- }
- Encode(ReturnedValue v) {
- val = v;
- }
-
- template<typename T>
- Encode(Returned<T> *t) {
- val = t->getPointer()->asReturnedValue();
- }
-
- operator ReturnedValue() const {
- return val;
- }
- quint64 val;
-private:
- Encode(void *);
-};
-
template <typename T>
inline Value &Value::operator=(Returned<T> *t)
@@ -622,81 +439,68 @@ inline Value &Value::operator=(Returned<T> *t)
return *this;
}
-inline SafeValue &SafeValue::operator =(const ScopedValue &v)
+inline Value &Value::operator =(const ScopedValue &v)
{
val = v.ptr->val;
return *this;
}
template<typename T>
-inline SafeValue &SafeValue::operator=(Returned<T> *t)
-{
- val = t->getPointer()->asReturnedValue();
- return *this;
-}
-
-template<typename T>
-inline SafeValue &SafeValue::operator=(const Scoped<T> &t)
+inline Value &Value::operator=(const Scoped<T> &t)
{
val = t.ptr->val;
return *this;
}
-inline SafeValue &SafeValue::operator=(const ValueRef v)
+inline Value &Value::operator=(const ValueRef v)
{
val = v.asReturnedValue();
return *this;
}
template<typename T>
-inline Returned<T> *SafeValue::as()
+inline Returned<T> *Value::as()
{
return Returned<T>::create(value_cast<T>(*this));
}
-template<typename T> inline
-Referenced<T> SafeValue::asRef()
-{
- return Referenced<T>(*this);
-}
-
template<typename T>
-inline Safe<T> &Safe<T>::operator =(T *t)
+inline TypedValue<T> &TypedValue<T>::operator =(T *t)
{
val = t->asReturnedValue();
return *this;
}
template<typename T>
-inline Safe<T> &Safe<T>::operator =(const Scoped<T> &v)
+inline TypedValue<T> &TypedValue<T>::operator =(const Scoped<T> &v)
{
val = v.ptr->val;
return *this;
}
template<typename T>
-inline Safe<T> &Safe<T>::operator=(Returned<T> *t)
+inline TypedValue<T> &TypedValue<T>::operator=(Returned<T> *t)
{
val = t->getPointer()->asReturnedValue();
return *this;
}
-template<typename T>
-inline Safe<T> &Safe<T>::operator =(const Referenced<T> &v)
-{
- val = v.asReturnedValue();
- return *this;
-}
+//template<typename T>
+//inline TypedValue<T> &TypedValue<T>::operator =(const ManagedRef<T> &v)
+//{
+// val = v.asReturnedValue();
+// return *this;
+//}
template<typename T>
-inline Safe<T> &Safe<T>::operator=(const Safe<T> &t)
+inline TypedValue<T> &TypedValue<T>::operator=(const TypedValue<T> &t)
{
val = t.val;
return *this;
}
template<typename T>
-inline Returned<T> * Safe<T>::ret() const
+inline Returned<T> * TypedValue<T>::ret() const
{
return Returned<T>::create(static_cast<T *>(managed()));
}
@@ -713,9 +517,8 @@ PersistentValue::PersistentValue(Returned<T> *obj)
{
}
-template<typename T>
-inline PersistentValue::PersistentValue(const Referenced<T> obj)
- : d(new PersistentValuePrivate(*obj.ptr))
+inline PersistentValue::PersistentValue(const ManagedRef obj)
+ : d(new PersistentValuePrivate(obj.asReturnedValue()))
{
}
@@ -725,12 +528,15 @@ inline PersistentValue &PersistentValue::operator=(Returned<T> *obj)
return operator=(QV4::Value::fromManaged(obj->getPointer()).asReturnedValue());
}
-template<typename T>
-inline PersistentValue &PersistentValue::operator=(const Referenced<T> obj)
+inline PersistentValue &PersistentValue::operator=(const ManagedRef obj)
{
- return operator=(*obj.ptr);
+ return operator=(obj.asReturnedValue());
}
+inline PersistentValue &PersistentValue::operator=(const ScopedValue &other)
+{
+ return operator=(other.asReturnedValue());
+}
template<typename T>
inline WeakValue::WeakValue(Returned<T> *obj)
@@ -744,10 +550,53 @@ inline WeakValue &WeakValue::operator=(Returned<T> *obj)
return operator=(QV4::Value::fromManaged(obj->getPointer()).asReturnedValue());
}
-inline ReturnedValue CallContext::argument(int i) {
- return i < callData->argc ? callData->args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
+inline ValueRef::ValueRef(const ScopedValue &v)
+ : ptr(v.ptr)
+{}
+
+template <typename T>
+inline ValueRef::ValueRef(const Scoped<T> &v)
+ : ptr(v.ptr)
+{}
+
+inline ValueRef::ValueRef(const PersistentValue &v)
+ : ptr(&v.d->value)
+{}
+
+inline ValueRef::ValueRef(PersistentValuePrivate *p)
+ : ptr(&p->value)
+{}
+
+inline ValueRef &ValueRef::operator=(const ScopedValue &o)
+{
+ *ptr = *o.ptr;
+ return *this;
+}
+
+
+inline Value *extractValuePointer(const ScopedValue &v)
+{
+ return v.ptr;
}
+template<typename T>
+Value *extractValuePointer(const Scoped<T> &v)
+{
+ return v.ptr;
+}
+
+struct ScopedProperty
+{
+ ScopedProperty(Scope &scope)
+ {
+ property = reinterpret_cast<Property*>(scope.alloc(sizeof(Property) / sizeof(Value)));
+ }
+
+ Property *operator->() { return property; }
+ operator const Property &() { return *property; }
+
+ Property *property;
+};
}
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 4fd0569627..7d94195304 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -67,7 +67,7 @@ QmlBindingWrapper::QmlBindingWrapper(ExecutionContext *scope, Function *f, Objec
{
Q_ASSERT(scope->inUse);
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
function = f;
function->compilationUnit->ref();
needsActivation = function->needsActivation();
@@ -88,7 +88,7 @@ QmlBindingWrapper::QmlBindingWrapper(ExecutionContext *scope, ObjectRef qml)
{
Q_ASSERT(scope->inUse);
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
function = 0;
needsActivation = false;
@@ -129,18 +129,18 @@ void QmlBindingWrapper::markObjects(Managed *m, ExecutionEngine *e)
wrapper->qmlContext->mark(e);
}
-DEFINE_MANAGED_VTABLE(QmlBindingWrapper);
+DEFINE_OBJECT_VTABLE(QmlBindingWrapper);
struct CompilationUnitHolder : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
CompilationUnitHolder(ExecutionEngine *engine, CompiledData::CompilationUnit *unit)
: Object(engine)
, unit(unit)
{
unit->ref();
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
~CompilationUnitHolder()
{
@@ -155,7 +155,7 @@ struct CompilationUnitHolder : public QV4::Object
QV4::CompiledData::CompilationUnit *unit;
};
-DEFINE_MANAGED_VTABLE(CompilationUnitHolder);
+DEFINE_OBJECT_VTABLE(CompilationUnitHolder);
Script::Script(ExecutionEngine *v4, ObjectRef qml, CompiledData::CompilationUnit *compilationUnit)
: line(0), column(0), scope(v4->rootContext), strictMode(false), inheritContext(true), parsed(false)
@@ -168,7 +168,7 @@ Script::Script(ExecutionEngine *v4, ObjectRef qml, CompiledData::CompilationUnit
Q_ASSERT(vmFunction);
Scope valueScope(v4);
ScopedValue holder(valueScope, new (v4->memoryManager) CompilationUnitHolder(v4, compilationUnit));
- compilationUnitHolder = holder;
+ compilationUnitHolder = holder.asReturnedValue();
} else
vmFunction = 0;
}
@@ -236,7 +236,7 @@ void Script::parse()
QV4::CompiledData::CompilationUnit *compilationUnit = isel->compile();
vmFunction = compilationUnit->linkToEngine(v4);
ScopedValue holder(valueScope, new (v4->memoryManager) CompilationUnitHolder(v4, compilationUnit));
- compilationUnitHolder = holder;
+ compilationUnitHolder = holder.asReturnedValue();
}
if (!vmFunction) {
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index 8e11eddb8f..8afdb6126f 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -54,7 +54,7 @@ namespace QV4 {
struct ExecutionContext;
struct QmlBindingWrapper : FunctionObject {
- Q_MANAGED
+ V4_OBJECT
QmlBindingWrapper(ExecutionContext *scope, Function *f, ObjectRef qml);
// Constructor for QML functions and signal handlers, resulting binding wrapper is not callable!
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 8b0e31cb71..a82dcffbca 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -165,34 +165,33 @@ template <> bool convertValueToElement(const ValueRef value)
template <typename Container>
class QQmlSequence : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
+ Q_MANAGED_TYPE(QmlSequence)
public:
QQmlSequence(QV4::ExecutionEngine *engine, const Container &container)
- : QV4::Object(InternalClass::create(engine, &static_vtbl, engine->sequencePrototype.asObject()))
+ : QV4::Object(InternalClass::create(engine, staticVTable(), engine->sequencePrototype.asObject()))
, m_container(container)
, m_object(0)
, m_propertyIndex(-1)
, m_isReference(false)
{
- type = Type_QmlSequence;
- flags &= ~SimpleArray;
QV4::Scope scope(engine);
QV4::ScopedObject protectThis(scope, this);
Q_UNUSED(protectThis);
+ setArrayType(ArrayData::Custom);
init();
}
QQmlSequence(QV4::ExecutionEngine *engine, QObject *object, int propertyIndex)
- : QV4::Object(InternalClass::create(engine, &static_vtbl, engine->sequencePrototype.asObject()))
+ : QV4::Object(InternalClass::create(engine, staticVTable(), engine->sequencePrototype.asObject()))
, m_object(object)
, m_propertyIndex(propertyIndex)
, m_isReference(true)
{
- type = Type_QmlSequence;
- flags &= ~SimpleArray;
QV4::Scope scope(engine);
QV4::ScopedObject protectThis(scope, this);
Q_UNUSED(protectThis);
+ setArrayType(ArrayData::Custom);
loadReference();
init();
}
@@ -287,26 +286,27 @@ public:
return (signedIdx < m_container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
}
- Property *containerAdvanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
+ void containerAdvanceIterator(ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attrs)
{
name = (String *)0;
*index = UINT_MAX;
if (m_isReference) {
- if (!m_object)
- return QV4::Object::advanceIterator(this, it, name, index, attrs);
+ if (!m_object) {
+ QV4::Object::advanceIterator(this, it, name, index, p, attrs);
+ return;
+ }
loadReference();
}
if (it->arrayIndex < static_cast<uint>(m_container.count())) {
- if (attrs)
- *attrs = QV4::Attr_Data;
*index = it->arrayIndex;
++it->arrayIndex;
- it->tmpDynamicProperty.value = convertElementToValue(engine(), m_container.at(*index));
- return &it->tmpDynamicProperty;
+ *attrs = QV4::Attr_Data;
+ p->value = convertElementToValue(engine(), m_container.at(*index));
+ return;
}
- return QV4::Object::advanceIterator(this, it, name, index, attrs);
+ QV4::Object::advanceIterator(this, it, name, index, p, attrs);
}
bool containerDeleteIndexedProperty(uint index)
@@ -469,7 +469,7 @@ public:
{
QV4::Scope scope(array->engine());
Container result;
- quint32 length = array->arrayLength();
+ quint32 length = array->getLength();
QV4::ScopedValue v(scope);
for (quint32 i = 0; i < length; ++i)
result << convertValueToElement<typename Container::value_type>((v = array->getIndexed(i)));
@@ -510,8 +510,8 @@ private:
{ return static_cast<QQmlSequence<Container> *>(that)->containerDeleteIndexedProperty(index); }
static bool isEqualTo(Managed *that, Managed *other)
{ return static_cast<QQmlSequence<Container> *>(that)->containerIsEqualTo(other); }
- static Property *advanceIterator(Managed *that, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
- { return static_cast<QQmlSequence<Container> *>(that)->containerAdvanceIterator(it, name, index, attrs); }
+ static void advanceIterator(Managed *that, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attrs)
+ { return static_cast<QQmlSequence<Container> *>(that)->containerAdvanceIterator(it, name, index, p, attrs); }
static void destroy(Managed *that)
{
@@ -521,22 +521,22 @@ private:
typedef QQmlSequence<QStringList> QQmlQStringList;
template<>
-DEFINE_MANAGED_VTABLE(QQmlQStringList);
+DEFINE_OBJECT_VTABLE(QQmlQStringList);
typedef QQmlSequence<QList<QString> > QQmlStringList;
template<>
-DEFINE_MANAGED_VTABLE(QQmlStringList);
+DEFINE_OBJECT_VTABLE(QQmlStringList);
typedef QQmlSequence<QList<int> > QQmlIntList;
template<>
-DEFINE_MANAGED_VTABLE(QQmlIntList);
+DEFINE_OBJECT_VTABLE(QQmlIntList);
typedef QQmlSequence<QList<QUrl> > QQmlUrlList;
template<>
-DEFINE_MANAGED_VTABLE(QQmlUrlList);
+DEFINE_OBJECT_VTABLE(QQmlUrlList);
typedef QQmlSequence<QList<bool> > QQmlBoolList;
template<>
-DEFINE_MANAGED_VTABLE(QQmlBoolList);
+DEFINE_OBJECT_VTABLE(QQmlBoolList);
typedef QQmlSequence<QList<qreal> > QQmlRealList;
template<>
-DEFINE_MANAGED_VTABLE(QQmlRealList);
+DEFINE_OBJECT_VTABLE(QQmlRealList);
#define REGISTER_QML_SEQUENCE_METATYPE(unused, unused2, SequenceType, unused3) qRegisterMetaType<SequenceType>(#SequenceType);
SequencePrototype::SequencePrototype(InternalClass *ic)
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index 54a96863df..4a5e82b688 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -56,7 +56,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
-#include "qv4value_p.h"
+#include "qv4value_inl_p.h"
#include "qv4object_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp
index ee325db4c2..3d754389a2 100644
--- a/src/qml/jsruntime/qv4serialize.cpp
+++ b/src/qml/jsruntime/qv4serialize.cpp
@@ -45,7 +45,7 @@
#include <private/qqmllistmodel_p.h>
#include <private/qqmllistmodelworkeragent_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4dateobject_p.h>
#include <private/qv4regexpobject_p.h>
#include <private/qv4sequenceobject_p.h>
@@ -55,13 +55,13 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-// We allow the following JavaScript types to be passed between the main and
+// We allow the following JavaScript types to be passed between the main and
// the secondary thread:
// + undefined
// + null
// + Boolean
// + String
-// + Function
+// + Function
// + Array
// + "Simple" Objects
// + Number
@@ -143,7 +143,7 @@ static inline void *popPtr(const char *&data)
return rv;
}
-// XXX TODO: Check that worker script is exception safe in the case of
+// XXX TODO: Check that worker script is exception safe in the case of
// serialization/deserialization failures
#define ALIGN(size) (((size) + 3) & ~3)
@@ -171,7 +171,7 @@ void Serialize::serialize(QByteArray &data, const QV4::ValueRef v, QV8Engine *en
reserve(data, utf16size + sizeof(quint32));
push(data, valueheader(WorkerString, length));
-
+
int offset = data.size();
data.resize(data.size() + utf16size);
char *buffer = data.data() + offset;
@@ -183,7 +183,7 @@ void Serialize::serialize(QByteArray &data, const QV4::ValueRef v, QV8Engine *en
push(data, valueheader(WorkerUndefined));
} else if (v->asArrayObject()) {
QV4::ScopedArrayObject array(scope, v);
- uint32_t length = array->arrayLength();
+ uint32_t length = array->getLength();
if (length > 0xFFFFFF) {
push(data, valueheader(WorkerUndefined));
return;
@@ -266,7 +266,7 @@ void Serialize::serialize(QByteArray &data, const QV4::ValueRef v, QV8Engine *en
// regular object
QV4::ScopedValue val(scope, *v);
QV4::ScopedArrayObject properties(scope, QV4::ObjectPrototype::getOwnPropertyNames(v4, val));
- quint32 length = properties->arrayLength();
+ quint32 length = properties->getLength();
if (length > 0xFFFFFF) {
push(data, valueheader(WorkerUndefined));
return;
@@ -390,8 +390,7 @@ ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine)
array->arrayReserve(seqLength);
for (quint32 ii = 0; ii < seqLength; ++ii) {
value = deserialize(data, engine);
- array->arrayData[ii].value = value.asReturnedValue();
- array->arrayDataLen = ii + 1;
+ array->arrayPut(ii, value);
}
array->setArrayLengthUnchecked(seqLength);
QVariant seqVariant = QV4::SequencePrototype::toVariant(array, sequenceType, &succeeded);
diff --git a/src/qml/jsruntime/qv4serialize_p.h b/src/qml/jsruntime/qv4serialize_p.h
index a9f40e43cd..5ab8ae9258 100644
--- a/src/qml/jsruntime/qv4serialize_p.h
+++ b/src/qml/jsruntime/qv4serialize_p.h
@@ -54,7 +54,7 @@
//
#include <QtCore/qbytearray.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4sparsearray.cpp b/src/qml/jsruntime/qv4sparsearray.cpp
index 3ee89d5b53..ffd1adf98b 100644
--- a/src/qml/jsruntime/qv4sparsearray.cpp
+++ b/src/qml/jsruntime/qv4sparsearray.cpp
@@ -53,32 +53,6 @@
using namespace QV4;
-bool ArrayElementLessThan::operator()(const Property &p1, const Property &p2) const
-{
- Scope scope(m_context);
-
- if (p1.value.isUndefined() || p1.value.isEmpty())
- return false;
- if (p2.value.isUndefined() || p2.value.isEmpty())
- return true;
- ScopedObject o(scope, m_comparefn);
- if (o) {
- Scope scope(o->engine());
- ScopedValue result(scope);
- ScopedCallData callData(scope, 2);
- callData->thisObject = Primitive::undefinedValue();
- callData->args[0] = p1.value;
- callData->args[1] = p2.value;
- result = __qmljs_call_value(m_context, m_comparefn, callData);
-
- return result->toNumber() < 0;
- }
- ScopedString p1s(scope, p1.value.toString(m_context));
- ScopedString p2s(scope, p2.value.toString(m_context));
- return p1s->toQString() < p2s->toQString();
-}
-
-
const SparseArrayNode *SparseArrayNode::nextNode() const
{
const SparseArrayNode *n = this;
@@ -245,51 +219,51 @@ void SparseArray::deleteNode(SparseArrayNode *z)
else
mostLeftNode = y->parent();
}
- } else {
- if (y->right == 0) {
+ } else if (y->right == 0) {
x = y->left;
- } else {
- y = y->right;
- while (y->left != 0)
- y = y->left;
- x = y->right;
- }
+ } else {
+ y = y->right;
+ while (y->left != 0)
+ y = y->left;
+ x = y->right;
}
if (y != z) {
- z->left->setParent(y);
- y->left = z->left;
+ // move y into the position of z
+ // adjust size_left so the keys are ok.
+ z->size_left += y->size_left;
+ SparseArrayNode *n = y->parent();
+ while (n != z) {
+ n->size_left -= y->size_left;
+ n = n->parent();
+ }
+ y->size_left = 0;
+ z->value = y->value;
+
if (y != z->right) {
x_parent = y->parent();
- if (x)
- x->setParent(y->parent());
y->parent()->left = x;
- y->right = z->right;
- z->right->setParent(y);
} else {
- x_parent = y;
+ x_parent = z;
+ z->right = x;
}
- if (root == z)
- root = y;
- else if (z->parent()->left == z)
- z->parent()->left = y;
- else
- z->parent()->right = y;
- y->setParent(z->parent());
- // Swap the colors
- SparseArrayNode::Color c = y->color();
- y->setColor(z->color());
- z->setColor(c);
- y = z;
+ if (x)
+ x->setParent(x_parent);
} else {
x_parent = y->parent();
if (x)
x->setParent(y->parent());
- if (root == z)
+ if (root == y)
root = x;
- else if (z->parent()->left == z)
- z->parent()->left = x;
- else
- z->parent()->right = x;
+ else if (y->parent()->left == y) {
+ y->parent()->left = x;
+ if (x)
+ x->size_left += y->size_left;
+ } else {
+ y->parent()->right = x;
+ if (x)
+ x->size_left += y->size_left;
+ }
+ y->size_left = 0;
}
if (y->color() != SparseArrayNode::Red) {
while (x != root && (x == 0 || x->color() == SparseArrayNode::Black)) {
diff --git a/src/qml/jsruntime/qv4sparsearray_p.h b/src/qml/jsruntime/qv4sparsearray_p.h
index 4746498963..0bcbc805f3 100644
--- a/src/qml/jsruntime/qv4sparsearray_p.h
+++ b/src/qml/jsruntime/qv4sparsearray_p.h
@@ -39,16 +39,17 @@
**
****************************************************************************/
-#ifndef QV4ARRAY_H
-#define QV4ARRAY_H
+#ifndef QV4SPARSEARRAY_H
+#define QV4SPARSEARRAY_H
#include "qv4global_p.h"
#include <QtCore/qmap.h>
-#include "qv4value_p.h"
+#include "qv4value_inl_p.h"
#include "qv4scopedvalue_p.h"
#include "qv4property_p.h"
#include <assert.h>
+//#define Q_MAP_DEBUG
#ifdef Q_MAP_DEBUG
#include <QtCore/qdebug.h>
#endif
@@ -61,21 +62,6 @@ namespace QV4 {
struct SparseArray;
-class ArrayElementLessThan
-{
-public:
- inline ArrayElementLessThan(ExecutionContext *context, ObjectRef thisObject, const ValueRef comparefn)
- : m_context(context), thisObject(thisObject), m_comparefn(comparefn) {}
-
- bool operator()(const Property &v1, const Property &v2) const;
-
-private:
- ExecutionContext *m_context;
- ObjectRef thisObject;
- const ValueRef m_comparefn;
-};
-
-
struct SparseArrayNode
{
quintptr p;
@@ -182,6 +168,8 @@ public:
SparseArrayNode *findNode(uint akey) const;
+ uint nEntries() const { return numEntries; }
+
uint pop_front();
void push_front(uint at);
uint pop_back(uint len);
@@ -208,7 +196,7 @@ public:
typedef qptrdiff difference_type;
typedef int size_type;
-#ifdef Q_MAP_DEBUG
+#ifndef QT_NO_DEBUG
void dump() const;
#endif
};
@@ -281,23 +269,22 @@ inline void SparseArray::push_back(uint index, uint len)
n->value = index;
}
-#ifdef Q_MAP_DEBUG
-
-void SparseArray::dump() const
+#ifndef QT_NO_DEBUG
+inline void SparseArray::dump() const
{
- const_iterator it = begin();
+ const SparseArrayNode *it = begin();
qDebug() << "map dump:";
while (it != end()) {
- const SparseArrayNode *n = it.i;
+ const SparseArrayNode *n = it;
int depth = 0;
while (n && n != root()) {
++depth;
n = n->parent();
}
QByteArray space(4*depth, ' ');
- qDebug() << space << (it.i->color() == SparseArrayNode::Red ? "Red " : "Black") << it.i << it.i->left << it.i->right
- << it.key() << it.value();
- ++it;
+ qDebug() << space << (it->color() == SparseArrayNode::Red ? "Red " : "Black") << it << it->size_left << it->left << it->right
+ << it->key() << it->value;
+ it = it->nextNode();
}
qDebug() << "---------";
}
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index e5633eb06f..3d0328dfcf 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -101,12 +101,11 @@ static uint toArrayIndex(const char *ch, const char *end, bool *ok)
}
-const ManagedVTable String::static_vtbl =
+const ObjectVTable String::static_vtbl =
{
- call,
- construct,
- markObjects,
- destroy,
+ DEFINE_MANAGED_VTABLE_INT(String),
+ 0,
+ 0,
0 /*collectDeletables*/,
get,
getIndexed,
@@ -118,9 +117,8 @@ const ManagedVTable String::static_vtbl =
deleteIndexedProperty,
0 /*getLookup*/,
0 /*setLookup*/,
- isEqualTo,
+ 0,
0 /*advanceIterator*/,
- "String",
};
void String::destroy(Managed *that)
@@ -233,10 +231,9 @@ bool String::isEqualTo(Managed *t, Managed *o)
if (t == o)
return true;
- if (o->type != Type_String)
+ if (!o->internalClass->vtable->isString)
return false;
- Q_ASSERT(t->type == Type_String);
String *that = static_cast<String *>(t);
String *other = static_cast<String *>(o);
if (that->hashValue() != other->hashValue())
@@ -257,7 +254,6 @@ String::String(ExecutionEngine *engine, const QString &text)
{
_text->ref.ref();
len = _text->size;
- type = Type_String;
subtype = StringType_Unknown;
}
@@ -267,7 +263,6 @@ String::String(ExecutionEngine *engine, String *l, String *r)
, stringHash(UINT_MAX), largestSubLength(qMax(l->largestSubLength, r->largestSubLength))
, len(l->len + r->len)
{
- type = Type_String;
subtype = StringType_Unknown;
if (!l->largestSubLength && l->len > largestSubLength)
@@ -418,3 +413,8 @@ uint String::toArrayIndex(const QString &str)
bool ok;
return ::toArrayIndex(str.constData(), str.constData() + str.length(), &ok);
}
+
+uint String::getLength(const Managed *m)
+{
+ return static_cast<const String *>(m)->length();
+}
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 64e15b04c2..ade64d1352 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -52,7 +52,13 @@ struct ExecutionEngine;
struct Identifier;
struct Q_QML_EXPORT String : public Managed {
- Q_MANAGED
+ // ### FIXME: Should this be a V4_OBJECT
+ V4_OBJECT
+ Q_MANAGED_TYPE(String)
+ enum {
+ IsString = true
+ };
+
enum StringType {
StringType_Unknown,
StringType_Regular,
@@ -60,10 +66,6 @@ struct Q_QML_EXPORT String : public Managed {
StringType_ArrayIndex
};
- String()
- : Managed(0), _text(QStringData::sharedNull()), identifier(0)
- , stringHash(UINT_MAX), largestSubLength(0), len(0)
- { type = Type_String; subtype = StringType_Unknown; }
String(ExecutionEngine *engine, const QString &text);
String(ExecutionEngine *engine, String *l, String *n);
~String() {
@@ -86,6 +88,7 @@ struct Q_QML_EXPORT String : public Managed {
return toQString() == other->toQString();
}
+
inline bool compare(const String *other) {
return toQString() < other->toQString();
}
@@ -167,6 +170,7 @@ protected:
static bool deleteProperty(Managed *, const StringRef);
static bool deleteIndexedProperty(Managed *m, uint index);
static bool isEqualTo(Managed *that, Managed *o);
+ static uint getLength(const Managed *m);
private:
QChar *recursiveAppend(QChar *ch) const;
@@ -178,11 +182,13 @@ inline String *value_cast(const Value &v) {
}
template<>
-inline ReturnedValue value_convert<String>(ExecutionContext *ctx, const Value &v)
+inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
{
- return v.toString(ctx)->asReturnedValue();
+ return v.toString(e)->asReturnedValue();
}
+DEFINE_REF(String, Managed);
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index d468fb6b83..07cdf31a03 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -75,13 +75,12 @@
using namespace QV4;
-DEFINE_MANAGED_VTABLE(StringObject);
+DEFINE_OBJECT_VTABLE(StringObject);
StringObject::StringObject(InternalClass *ic)
: Object(ic)
{
- setVTable(&static_vtbl);
- type = Type_StringObject;
+ Q_ASSERT(internalClass->vtable == staticVTable());
Scope scope(engine());
ScopedObject protectThis(scope, this);
@@ -96,8 +95,7 @@ StringObject::StringObject(InternalClass *ic)
StringObject::StringObject(ExecutionEngine *engine, const ValueRef val)
: Object(engine->stringObjectClass)
{
- setVTable(&static_vtbl);
- type = Type_StringObject;
+ setVTable(staticVTable());
Scope scope(engine);
ScopedObject protectThis(scope, this);
@@ -137,26 +135,32 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index)
return true;
}
-Property *StringObject::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
+void StringObject::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attrs)
{
name = (String *)0;
StringObject *s = static_cast<StringObject *>(m);
uint slen = s->value.stringValue()->toQString().length();
- if (it->arrayIndex < slen) {
+ if (it->arrayIndex <= slen) {
while (it->arrayIndex < slen) {
*index = it->arrayIndex;
++it->arrayIndex;
- if (attrs)
- *attrs = s->arrayAttributes ? s->arrayAttributes[it->arrayIndex] : PropertyAttributes(Attr_NotWritable|Attr_NotConfigurable);
- return s->__getOwnProperty__(*index);
+ PropertyAttributes a;
+ Property *pd = s->__getOwnProperty__(*index, &a);
+ if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
+ *attrs = a;
+ *p = *pd;
+ return;
+ }
+ }
+ if (s->arrayData) {
+ it->arrayNode = s->sparseBegin();
+ // iterate until we're past the end of the string
+ while (it->arrayNode && it->arrayNode->key() < slen)
+ it->arrayNode = it->arrayNode->nextNode();
}
- it->arrayNode = s->sparseArrayBegin();
- // iterate until we're past the end of the string
- while (it->arrayNode && it->arrayNode->key() < slen)
- it->arrayNode = it->arrayNode->nextNode();
}
- return Object::advanceIterator(m, it, name, index, attrs);
+ return Object::advanceIterator(m, it, name, index, p, attrs);
}
void StringObject::markObjects(Managed *that, ExecutionEngine *e)
@@ -167,12 +171,12 @@ void StringObject::markObjects(Managed *that, ExecutionEngine *e)
Object::markObjects(that, e);
}
-DEFINE_MANAGED_VTABLE(StringCtor);
+DEFINE_OBJECT_VTABLE(StringCtor);
StringCtor::StringCtor(ExecutionContext *scope)
: FunctionObject(scope, QStringLiteral("String"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue StringCtor::construct(Managed *m, CallData *callData)
@@ -694,18 +698,18 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
array->push_back((s = ctx->engine->newString(text.mid(offset, matchOffsets[0] - offset))));
offset = qMax(offset + 1, matchOffsets[1]);
- if (array->arrayLength() >= limit)
+ if (array->getLength() >= limit)
break;
for (int i = 1; i < re->value->captureCount(); ++i) {
uint start = matchOffsets[i * 2];
uint end = matchOffsets[i * 2 + 1];
array->push_back((s = ctx->engine->newString(text.mid(start, end - start))));
- if (array->arrayLength() >= limit)
+ if (array->getLength() >= limit)
break;
}
}
- if (array->arrayLength() < limit)
+ if (array->getLength() < limit)
array->push_back((s = ctx->engine->newString(text.mid(offset))));
} else {
QString separator = separatorValue->toString(ctx)->toQString();
@@ -720,10 +724,10 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
while ((end = text.indexOf(separator, start)) != -1) {
array->push_back((s = ctx->engine->newString(text.mid(start, end - start))));
start = end + separator.size();
- if (array->arrayLength() >= limit)
+ if (array->getLength() >= limit)
break;
}
- if (array->arrayLength() < limit && start != -1)
+ if (array->getLength() < limit && start != -1)
array->push_back((s = ctx->engine->newString(text.mid(start))));
}
return array.asReturnedValue();
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index e8e46b85e7..c38fd5b75f 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -50,9 +50,10 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct StringObject: Object {
- Q_MANAGED
+ V4_OBJECT
+ Q_MANAGED_TYPE(StringObject)
- SafeValue value;
+ Value value;
mutable Property tmpProperty;
StringObject(ExecutionEngine *engine, const ValueRef value);
@@ -62,13 +63,13 @@ struct StringObject: Object {
protected:
StringObject(InternalClass *ic);
- static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs);
+ static void advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attrs);
static void markObjects(Managed *that, ExecutionEngine *e);
};
struct StringCtor: FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
StringCtor(ExecutionContext *scope);
static ReturnedValue construct(Managed *m, CallData *callData);
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index 30f7e8cdb0..c91084caee 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -262,6 +262,11 @@ double Primitive::toInteger(double number)
return std::signbit(number) ? -v : v;
}
+String *Value::toString(ExecutionEngine *e) const
+{
+ return toString(e->currentContext());
+}
+
String *Value::toString(ExecutionContext *ctx) const
{
if (isString())
@@ -276,213 +281,3 @@ Object *Value::toObject(ExecutionContext *ctx) const
return __qmljs_convert_to_object(ctx, ValueRef::fromRawValue(this))->getPointer();
}
-
-PersistentValue::PersistentValue(const ValueRef val)
- : d(new PersistentValuePrivate(val.asReturnedValue()))
-{
-}
-
-PersistentValue::PersistentValue(ReturnedValue val)
- : d(new PersistentValuePrivate(val))
-{
-}
-
-PersistentValue::PersistentValue(const PersistentValue &other)
- : d(other.d)
-{
- if (d)
- d->ref();
-}
-
-PersistentValue &PersistentValue::operator=(const PersistentValue &other)
-{
- if (d == other.d)
- return *this;
-
- // the memory manager cleans up those with a refcount of 0
-
- if (d)
- d->deref();
- d = other.d;
- if (d)
- d->ref();
-
- return *this;
-}
-
-PersistentValue &PersistentValue::operator =(const ValueRef other)
-{
- if (!d) {
- d = new PersistentValuePrivate(other.asReturnedValue());
- return *this;
- }
- d = d->detach(other.asReturnedValue());
- return *this;
-}
-
-PersistentValue &PersistentValue::operator =(ReturnedValue other)
-{
- if (!d) {
- d = new PersistentValuePrivate(other);
- return *this;
- }
- d = d->detach(other);
- return *this;
-}
-
-PersistentValue::~PersistentValue()
-{
- if (d)
- d->deref();
-}
-
-WeakValue::WeakValue(const ValueRef val)
- : d(new PersistentValuePrivate(val.asReturnedValue(), /*engine*/0, /*weak*/true))
-{
-}
-
-WeakValue::WeakValue(const WeakValue &other)
- : d(other.d)
-{
- if (d)
- d->ref();
-}
-
-WeakValue::WeakValue(ReturnedValue val)
- : d(new PersistentValuePrivate(val, /*engine*/0, /*weak*/true))
-{
-}
-
-WeakValue &WeakValue::operator=(const WeakValue &other)
-{
- if (d == other.d)
- return *this;
-
- // the memory manager cleans up those with a refcount of 0
-
- if (d)
- d->deref();
- d = other.d;
- if (d)
- d->ref();
-
- return *this;
-}
-
-WeakValue &WeakValue::operator =(const ValueRef other)
-{
- if (!d) {
- d = new PersistentValuePrivate(other.asReturnedValue(), /*engine*/0, /*weak*/true);
- return *this;
- }
- d = d->detach(other.asReturnedValue(), /*weak*/true);
- return *this;
-}
-
-WeakValue &WeakValue::operator =(const ReturnedValue &other)
-{
- if (!d) {
- d = new PersistentValuePrivate(other, /*engine*/0, /*weak*/true);
- return *this;
- }
- d = d->detach(other, /*weak*/true);
- return *this;
-}
-
-
-WeakValue::~WeakValue()
-{
- if (d)
- d->deref();
-}
-
-void WeakValue::markOnce(ExecutionEngine *e)
-{
- if (!d)
- return;
- d->value.mark(e);
-}
-
-PersistentValuePrivate::PersistentValuePrivate(ReturnedValue v, ExecutionEngine *e, bool weak)
- : refcount(1)
- , weak(weak)
- , engine(e)
- , prev(0)
- , next(0)
-{
- value.val = v;
- init();
-}
-
-void PersistentValuePrivate::init()
-{
- if (!engine) {
- Managed *m = value.asManaged();
- if (!m)
- return;
-
- engine = m->engine();
- }
- if (engine && !prev) {
- PersistentValuePrivate **listRoot = weak ? &engine->memoryManager->m_weakValues : &engine->memoryManager->m_persistentValues;
-
- prev = listRoot;
- next = *listRoot;
- *prev = this;
- if (next)
- next->prev = &this->next;
- }
-}
-
-PersistentValuePrivate::~PersistentValuePrivate()
-{
-}
-
-void PersistentValuePrivate::removeFromList()
-{
- if (prev) {
- if (next)
- next->prev = prev;
- *prev = next;
- next = 0;
- prev = 0;
- }
-}
-
-void PersistentValuePrivate::deref()
-{
- // if engine is not 0, they are registered with the memory manager
- // and will get cleaned up in the next gc run
- if (!--refcount) {
- removeFromList();
- delete this;
- }
-}
-
-PersistentValuePrivate *PersistentValuePrivate::detach(const QV4::ReturnedValue val, bool weak)
-{
- if (refcount == 1) {
- value.val = val;
-
- Managed *m = value.asManaged();
- if (!prev) {
- if (m) {
- ExecutionEngine *engine = m->engine();
- if (engine) {
- PersistentValuePrivate **listRoot = weak ? &engine->memoryManager->m_weakValues : &engine->memoryManager->m_persistentValues;
- prev = listRoot;
- next = *listRoot;
- *prev = this;
- if (next)
- next->prev = &this->next;
- }
- }
- } else if (!m)
- removeFromList();
-
- return this;
- }
- --refcount;
- return new PersistentValuePrivate(val, engine, weak);
-}
-
diff --git a/src/qml/jsruntime/qv4value_def_p.h b/src/qml/jsruntime/qv4value_def_p.h
deleted file mode 100644
index cf351c125a..0000000000
--- a/src/qml/jsruntime/qv4value_def_p.h
+++ /dev/null
@@ -1,476 +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$
-**
-****************************************************************************/
-#ifndef QV4VALUE_DEF_P_H
-#define QV4VALUE_DEF_P_H
-
-#include <QtCore/QString>
-#include "qv4global_p.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-
-typedef uint Bool;
-
-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;
-};
-
-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;
-#endif
- union {
- uint uint_32;
- int int_32;
-#if QT_POINTER_SIZE == 4
- Managed *m;
- Object *o;
- String *s;
-#endif
- };
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- uint tag;
-#endif
- };
- };
-
-#if QT_POINTER_SIZE == 4
- enum Masks {
- NaN_Mask = 0x7ff80000,
- NotDouble_Mask = 0x7ffc0000,
- Type_Mask = 0xffff8000,
- Immediate_Mask = NotDouble_Mask | 0x00008000,
- IsNullOrUndefined_Mask = Immediate_Mask | 0x20000,
- Tag_Shift = 32
- };
- enum ValueType {
- Undefined_Type = Immediate_Mask | 0x00000,
- Null_Type = Immediate_Mask | 0x10000,
- Boolean_Type = Immediate_Mask | 0x20000,
- Integer_Type = Immediate_Mask | 0x30000,
- Managed_Type = NotDouble_Mask | 0x00000,
- Empty_Type = NotDouble_Mask | 0x30000
- };
-
- enum ImmediateFlags {
- ConvertibleToInt = Immediate_Mask | 0x1
- };
-
- enum ValueTypeInternal {
- _Null_Type = Null_Type | ConvertibleToInt,
- _Boolean_Type = Boolean_Type | ConvertibleToInt,
- _Integer_Type = Integer_Type | ConvertibleToInt,
-
- };
-#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 isUndefined() const { return tag == Undefined_Type; }
- inline bool isNull() const { return tag == _Null_Type; }
- inline bool isBoolean() const { return tag == _Boolean_Type; }
-#if QT_POINTER_SIZE == 8
- inline bool isInteger() const { return (val >> IsNumber_Shift) == 1; }
- 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 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; }
- inline bool isManaged() const { return tag == Managed_Type; }
- inline bool isNullOrUndefined() const { return (tag & IsNullOrUndefined_Mask) == Undefined_Type; }
- 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()) {
- double d = doubleValue();
- int i = (int)d;
- if (i == d) {
- int_32 = i;
- tag = _Integer_Type;
- return true;
- }
- }
- return false;
- }
- double asDouble() const {
- if (tag == _Integer_Type)
- return int_32;
- return doubleValue();
- }
-
- bool booleanValue() const {
- return int_32;
- }
- int integerValue() const {
- return int_32;
- }
-
- String *stringValue() const {
- return s;
- }
- Object *objectValue() const {
- return o;
- }
- Managed *managed() const {
- return m;
- }
-
- quint64 rawValue() const {
- return val;
- }
-
- static inline Value fromManaged(Managed *o);
-
- int toUInt16() const;
- inline int toInt32() const;
- inline unsigned int toUInt32() const;
-
- inline bool toBoolean() const;
- double toInteger() const;
- inline 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;
- inline bool tryIntegerConversion() {
- bool b = integerCompatible();
- if (b)
- tag = _Integer_Type;
- return b;
- }
-
- inline String *asString() const;
- inline Managed *asManaged() const;
- inline Object *asObject() const;
- inline FunctionObject *asFunctionObject() const;
- inline NumberObject *asNumberObject() const;
- inline StringObject *asStringObject() const;
- inline DateObject *asDateObject() const;
- inline ArrayObject *asArrayObject() const;
- inline ErrorObject *asErrorObject() const;
-
- template<typename T> inline T *as() const;
-
- inline uint asArrayIndex() const;
- inline uint asArrayLength(bool *ok) const;
-
- inline ExecutionEngine *engine() const;
-
- ReturnedValue asReturnedValue() const { return val; }
- static Value fromReturnedValue(ReturnedValue val) { Value v; v.val = val; return v; }
- Value &operator=(ReturnedValue v) { val = v; return *this; }
- template <typename T>
- inline Value &operator=(Returned<T> *t);
-
- // Section 9.12
- bool sameValue(Value other) const;
-
- inline void mark(ExecutionEngine *e) const;
-};
-
-inline Managed *Value::asManaged() const
-{
- if (isManaged())
- return managed();
- return 0;
-}
-
-inline String *Value::asString() const
-{
- if (isString())
- return stringValue();
- return 0;
-}
-
-struct Q_QML_EXPORT Primitive : public Value
-{
- inline static Primitive emptyValue();
- static inline Primitive fromBoolean(bool b);
- static inline Primitive fromInt32(int i);
- inline static Primitive undefinedValue();
- static inline Primitive nullValue();
- static inline Primitive fromDouble(double d);
- static inline Primitive fromUInt32(uint i);
-
- static double toInteger(double fromNumber);
- static int toInt32(double value);
- static unsigned int toUInt32(double value);
-
- inline operator ValueRef();
- Value asValue() const { return *this; }
-};
-
-inline Primitive Primitive::undefinedValue()
-{
- Primitive v;
-#if QT_POINTER_SIZE == 8
- v.val = quint64(Undefined_Type) << Tag_Shift;
-#else
- v.tag = Undefined_Type;
- v.int_32 = 0;
-#endif
- return v;
-}
-
-inline Primitive Primitive::emptyValue()
-{
- Primitive v;
- v.tag = Value::Empty_Type;
- v.uint_32 = 0;
- return v;
-}
-
-inline Value Value::fromManaged(Managed *m)
-{
- if (!m)
- return QV4::Primitive::undefinedValue();
- Value v;
-#if QT_POINTER_SIZE == 8
- v.m = m;
-#else
- v.tag = Managed_Type;
- v.m = m;
-#endif
- return v;
-}
-
-struct SafeValue : public Value
-{
- SafeValue &operator =(const ScopedValue &v);
- template<typename T>
- SafeValue &operator=(Returned<T> *t);
- SafeValue &operator=(ReturnedValue v) {
- val = v;
- return *this;
- }
- template<typename T>
- SafeValue &operator=(T *t) {
- val = Value::fromManaged(t).val;
- return *this;
- }
-
- template<typename T>
- SafeValue &operator=(const Scoped<T> &t);
- SafeValue &operator=(const ValueRef v);
- SafeValue &operator=(const Value &v) {
- val = v.val;
- return *this;
- }
- template<typename T>
- inline Returned<T> *as();
- template<typename T>
- inline Referenced<T> asRef();
-};
-
-template <typename T>
-struct Safe : public SafeValue
-{
- template<typename X>
- Safe &operator =(X *x) {
- val = Value::fromManaged(x).val;
- }
- Safe &operator =(T *t);
- Safe &operator =(const Scoped<T> &v);
- Safe &operator =(const Referenced<T> &v);
- Safe &operator =(Returned<T> *t);
-
- Safe &operator =(const Safe<T> &t);
-
- bool operator!() const { return !managed(); }
-
- T *operator->() { return static_cast<T *>(managed()); }
- const T *operator->() const { return static_cast<T *>(managed()); }
- T *getPointer() const { return static_cast<T *>(managed()); }
- Returned<T> *ret() const;
-
- void mark(ExecutionEngine *e) { if (managed()) managed()->mark(e); }
-};
-typedef Safe<String> SafeString;
-typedef Safe<Object> SafeObject;
-
-template<typename T>
-T *value_cast(const Value &v)
-{
- return v.as<T>();
-}
-
-template<typename T>
-ReturnedValue value_convert(ExecutionContext *ctx, const Value &v);
-
-
-
-}
-
-QT_END_NAMESPACE
-
-#endif // QV4VALUE_DEF_P_H
diff --git a/src/qml/jsruntime/qv4value_inl_p.h b/src/qml/jsruntime/qv4value_inl_p.h
new file mode 100644
index 0000000000..d82af0643e
--- /dev/null
+++ b/src/qml/jsruntime/qv4value_inl_p.h
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** 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 QV4VALUE_INL_H
+#define QV4VALUE_INL_H
+
+#include <cmath> // this HAS to come
+
+#include <QtCore/QString>
+#include <QtCore/qnumeric.h>
+#include "qv4global_p.h"
+#include "qv4string_p.h"
+#include <QtCore/QDebug>
+#include "qv4managed_p.h"
+#include "qv4engine_p.h"
+#include <private/qtqmlglobal_p.h>
+
+//#include <wtf/MathExtras.h>
+
+#include "qv4value_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+inline bool Value::isString() const
+{
+ if (!isManaged())
+ return false;
+ return managed() && managed()->internalClass->vtable->isString;
+}
+inline bool Value::isObject() const
+{
+ if (!isManaged())
+ return false;
+ return managed() && managed()->internalClass->vtable->isObject;
+}
+
+inline bool Value::isPrimitive() const
+{
+ return !isObject();
+}
+
+inline ExecutionEngine *Value::engine() const
+{
+ Managed *m = asManaged();
+ return m ? m->engine() : 0;
+}
+
+inline void Value::mark(ExecutionEngine *e) const
+{
+ if (!val)
+ return;
+ Managed *m = asManaged();
+ if (m)
+ m->mark(e);
+}
+
+inline Primitive Primitive::nullValue()
+{
+ Primitive v;
+#if QT_POINTER_SIZE == 8
+ v.val = quint64(_Null_Type) << Tag_Shift;
+#else
+ v.tag = _Null_Type;
+ v.int_32 = 0;
+#endif
+ return v;
+}
+
+inline Primitive Primitive::fromBoolean(bool b)
+{
+ Primitive v;
+ v.tag = _Boolean_Type;
+ v.int_32 = (bool)b;
+ return v;
+}
+
+inline Primitive Primitive::fromDouble(double d)
+{
+ Primitive v;
+ v.setDouble(d);
+ return v;
+}
+
+inline Primitive Primitive::fromInt32(int i)
+{
+ Primitive v;
+ v.tag = _Integer_Type;
+ v.int_32 = i;
+ return v;
+}
+
+inline Primitive Primitive::fromUInt32(uint i)
+{
+ Primitive v;
+ if (i < INT_MAX) {
+ v.tag = _Integer_Type;
+ v.int_32 = (int)i;
+ } else {
+ v.setDouble(i);
+ }
+ 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 Primitive::toInt32(d);
+}
+
+inline unsigned int Value::toUInt32() const
+{
+ return (unsigned int)toInt32();
+}
+
+
+inline bool Value::toBoolean() const
+{
+ switch (type()) {
+ case Value::Undefined_Type:
+ case Value::Null_Type:
+ return false;
+ case Value::Boolean_Type:
+ case Value::Integer_Type:
+ return (bool)int_32;
+ case Value::Managed_Type:
+ if (isString())
+ return stringValue()->toQString().length() > 0;
+ return true;
+ default: // double
+ return doubleValue() && !std::isnan(doubleValue());
+ }
+}
+
+inline uint Value::asArrayIndex() const
+{
+#if QT_POINTER_SIZE == 8
+ if (!isNumber())
+ return UINT_MAX;
+ if (isInteger())
+ return int_32 >= 0 ? (uint)int_32 : UINT_MAX;
+#else
+ if (isInteger() && int_32 >= 0)
+ return (uint)int_32;
+ if (!isDouble())
+ return UINT_MAX;
+#endif
+ double d = doubleValue();
+ uint idx = (uint)d;
+ if (idx != d)
+ return UINT_MAX;
+ return idx;
+}
+
+inline uint Value::asArrayLength(bool *ok) const
+{
+ *ok = true;
+ if (integerCompatible() && int_32 >= 0)
+ return (uint)int_32;
+ if (isDouble()) {
+ double d = doubleValue();
+ uint idx = (uint)d;
+ if (idx != d) {
+ *ok = false;
+ return UINT_MAX;
+ }
+ return idx;
+ }
+ if (isString())
+ return stringValue()->toUInt(ok);
+
+ uint idx = toUInt32();
+ double d = toNumber();
+ if (d != idx) {
+ *ok = false;
+ return UINT_MAX;
+ }
+ return idx;
+}
+
+inline Object *Value::asObject() const
+{
+ return isObject() ? objectValue() : 0;
+}
+
+inline FunctionObject *Value::asFunctionObject() const
+{
+ return isObject() ? managed()->asFunctionObject() : 0;
+}
+
+inline NumberObject *Value::asNumberObject() const
+{
+ return isObject() ? managed()->asNumberObject() : 0;
+}
+
+inline StringObject *Value::asStringObject() const
+{
+ return isObject() ? managed()->asStringObject() : 0;
+}
+
+inline DateObject *Value::asDateObject() const
+{
+ return isObject() ? managed()->asDateObject() : 0;
+}
+
+inline ArrayObject *Value::asArrayObject() const
+{
+ return isObject() ? managed()->asArrayObject() : 0;
+}
+
+inline ErrorObject *Value::asErrorObject() const
+{
+ return isObject() ? managed()->asErrorObject() : 0;
+}
+
+template<typename T>
+inline T *Value::as() const { Managed *m = isObject() ? managed() : 0; return m ? m->as<T>() : 0; }
+
+} // namespace QV4
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 680c7465ca..27c81d59a5 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -38,360 +38,530 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef QMLJS_VALUE_H
-#define QMLJS_VALUE_H
+#ifndef QV4VALUE_P_H
+#define QV4VALUE_P_H
-#include <cmath> // this HAS to come
+#include <limits.h>
#include <QtCore/QString>
-#include <QtCore/qnumeric.h>
#include "qv4global_p.h"
-#include "qv4string_p.h"
-#include <QtCore/QDebug>
-#include "qv4managed_p.h"
-#include "qv4engine_p.h"
-#include <private/qtqmlglobal_p.h>
-
-//#include <wtf/MathExtras.h>
-
-#include "qv4value_def_p.h"
QT_BEGIN_NAMESPACE
namespace QV4 {
-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;
-}
+typedef uint Bool;
-inline bool Value::isPrimitive() const
+template <typename T>
+struct Returned : private T
{
- return !isObject();
-}
+ 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;
+};
-inline ExecutionEngine *Value::engine() const
+struct Q_QML_EXPORT Value
{
- Managed *m = asManaged();
- return m ? m->engine() : 0;
-}
+ /*
+ We use two different ways of encoding JS values. One for 32bit and one for 64bit systems.
-inline void Value::mark(ExecutionEngine *e) const
-{
- if (!val)
- return;
- Managed *m = asManaged();
- if (m)
- m->mark(e);
-}
+ 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.
-inline Primitive Primitive::nullValue()
-{
- Primitive v;
+ 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
- v.val = quint64(_Null_Type) << Tag_Shift;
+ Managed *m;
+ Object *o;
+ String *s;
#else
- v.tag = _Null_Type;
- v.int_32 = 0;
+ double dbl;
+#endif
+ struct {
+#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
+ uint tag;
+#endif
+ union {
+ uint uint_32;
+ int int_32;
+#if QT_POINTER_SIZE == 4
+ Managed *m;
+ Object *o;
+ String *s;
+#endif
+ };
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ uint tag;
+#endif
+ };
+ };
+
+#if QT_POINTER_SIZE == 4
+ enum Masks {
+ NaN_Mask = 0x7ff80000,
+ NotDouble_Mask = 0x7ffc0000,
+ Type_Mask = 0xffff8000,
+ Immediate_Mask = NotDouble_Mask | 0x00008000,
+ IsNullOrUndefined_Mask = Immediate_Mask | 0x20000,
+ Tag_Shift = 32
+ };
+ enum ValueType {
+ Undefined_Type = Immediate_Mask | 0x00000,
+ Null_Type = Immediate_Mask | 0x10000,
+ Boolean_Type = Immediate_Mask | 0x20000,
+ Integer_Type = Immediate_Mask | 0x30000,
+ Managed_Type = NotDouble_Mask | 0x00000,
+ Empty_Type = NotDouble_Mask | 0x30000
+ };
+
+ enum ImmediateFlags {
+ ConvertibleToInt = Immediate_Mask | 0x1
+ };
+
+ enum ValueTypeInternal {
+ _Null_Type = Null_Type | ConvertibleToInt,
+ _Boolean_Type = Boolean_Type | ConvertibleToInt,
+ _Integer_Type = Integer_Type | ConvertibleToInt,
+
+ };
+#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
- return v;
-}
-
-inline Primitive Primitive::fromBoolean(bool b)
-{
- Primitive v;
- v.tag = _Boolean_Type;
- v.int_32 = (bool)b;
- return v;
-}
-inline Primitive Primitive::fromDouble(double d)
-{
- Primitive v;
- v.setDouble(d);
- return v;
-}
+ inline unsigned type() const {
+ return tag & Type_Mask;
+ }
-inline Primitive Primitive::fromInt32(int i)
-{
- Primitive v;
- v.tag = _Integer_Type;
- v.int_32 = i;
- return v;
-}
+ // used internally in property
+ inline bool isEmpty() const { return tag == Empty_Type; }
-inline Primitive Primitive::fromUInt32(uint i)
-{
- Primitive v;
- if (i < INT_MAX) {
- v.tag = _Integer_Type;
- v.int_32 = (int)i;
- } else {
- v.setDouble(i);
+ inline bool isUndefined() const { return tag == Undefined_Type; }
+ inline bool isNull() const { return tag == _Null_Type; }
+ inline bool isBoolean() const { return tag == _Boolean_Type; }
+#if QT_POINTER_SIZE == 8
+ inline bool isInteger() const { return (val >> IsNumber_Shift) == 1; }
+ 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();
}
- return v;
-}
-
-inline double Value::toNumber() const
-{
- if (integerCompatible())
- return int_32;
- if (isDouble())
+ 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 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; }
+ inline bool isManaged() const { return tag == Managed_Type; }
+ inline bool isNullOrUndefined() const { return (tag & IsNullOrUndefined_Mask) == Undefined_Type; }
+ 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()) {
+ double d = doubleValue();
+ int i = (int)d;
+ if (i == d) {
+ int_32 = i;
+ tag = _Integer_Type;
+ return true;
+ }
+ }
+ return false;
+ }
+ double asDouble() const {
+ if (tag == _Integer_Type)
+ return int_32;
return doubleValue();
- return toNumberImpl();
-}
+ }
-inline int Value::toInt32() const
-{
- if (integerCompatible())
+ bool booleanValue() const {
+ return int_32;
+ }
+ int integerValue() const {
return int_32;
- double d;
- if (isDouble())
- d = doubleValue();
- else
- d = toNumberImpl();
+ }
- const double D32 = 4294967296.0;
- const double D31 = D32 / 2.0;
+ String *stringValue() const {
+ return s;
+ }
+ Object *objectValue() const {
+ return o;
+ }
+ Managed *managed() const {
+ return m;
+ }
- if ((d >= -D31 && d < D31))
- return static_cast<int>(d);
+ quint64 rawValue() const {
+ return val;
+ }
- return Primitive::toInt32(d);
-}
+ static inline Value fromManaged(Managed *o);
+
+ int toUInt16() const;
+ inline int toInt32() const;
+ inline unsigned int toUInt32() const;
+
+ inline bool toBoolean() const;
+ double toInteger() const;
+ inline double toNumber() const;
+ double toNumberImpl() const;
+ QString toQStringNoThrow() const;
+ QString toQString() const;
+ String *toString(ExecutionEngine *e) const;
+ String *toString(ExecutionContext *ctx) const;
+ Object *toObject(ExecutionContext *ctx) const;
+
+ inline bool isPrimitive() const;
+ inline bool tryIntegerConversion() {
+ bool b = integerCompatible();
+ if (b)
+ tag = _Integer_Type;
+ return b;
+ }
-inline unsigned int Value::toUInt32() const
-{
- return (unsigned int)toInt32();
-}
+ inline String *asString() const;
+ inline Managed *asManaged() const;
+ inline Object *asObject() const;
+ inline FunctionObject *asFunctionObject() const;
+ inline NumberObject *asNumberObject() const;
+ inline StringObject *asStringObject() const;
+ inline DateObject *asDateObject() const;
+ inline ArrayObject *asArrayObject() const;
+ inline ErrorObject *asErrorObject() const;
+ template<typename T> inline T *as() const;
-inline bool Value::toBoolean() const
-{
- switch (type()) {
- case Value::Undefined_Type:
- case Value::Null_Type:
- return false;
- case Value::Boolean_Type:
- case Value::Integer_Type:
- return (bool)int_32;
- case Value::Managed_Type:
- if (isString())
- return stringValue()->toQString().length() > 0;
- return true;
- default: // double
- return doubleValue() && !std::isnan(doubleValue());
- }
-}
+ inline uint asArrayIndex() const;
+ inline uint asArrayLength(bool *ok) const;
-inline uint Value::asArrayIndex() const
-{
-#if QT_POINTER_SIZE == 8
- if (!isNumber())
- return UINT_MAX;
- if (isInteger())
- return int_32 >= 0 ? (uint)int_32 : UINT_MAX;
-#else
- if (isInteger() && int_32 >= 0)
- return (uint)int_32;
- if (!isDouble())
- return UINT_MAX;
-#endif
- double d = doubleValue();
- uint idx = (uint)d;
- if (idx != d)
- return UINT_MAX;
- return idx;
-}
+ inline ExecutionEngine *engine() const;
-inline uint Value::asArrayLength(bool *ok) const
-{
- *ok = true;
- if (integerCompatible() && int_32 >= 0)
- return (uint)int_32;
- if (isDouble()) {
- double d = doubleValue();
- uint idx = (uint)d;
- if (idx != d) {
- *ok = false;
- return UINT_MAX;
- }
- return idx;
+ 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;
+
+ inline void mark(ExecutionEngine *e) const;
+
+ Value &operator =(const ScopedValue &v);
+ Value &operator=(ReturnedValue v) { val = v; return *this; }
+ template<typename T>
+ Value &operator=(Returned<T> *t);
+ template<typename T>
+ Value &operator=(T *t) {
+ val = Value::fromManaged(t).val;
+ return *this;
}
- if (isString())
- return stringValue()->toUInt(ok);
- uint idx = toUInt32();
- double d = toNumber();
- if (d != idx) {
- *ok = false;
- return UINT_MAX;
+ template<typename T>
+ Value &operator=(const Scoped<T> &t);
+ Value &operator=(const ValueRef v);
+ Value &operator=(const Value &v) {
+ val = v.val;
+ return *this;
}
- return idx;
-}
+ template<typename T>
+ inline Returned<T> *as();
+};
-inline Object *Value::asObject() const
+inline Managed *Value::asManaged() const
{
- return isObject() ? objectValue() : 0;
+ if (isManaged())
+ return managed();
+ return 0;
}
-inline FunctionObject *Value::asFunctionObject() const
+inline String *Value::asString() const
{
- return isObject() ? managed()->asFunctionObject() : 0;
+ if (isString())
+ return stringValue();
+ return 0;
}
-inline NumberObject *Value::asNumberObject() const
+struct Q_QML_EXPORT Primitive : public Value
{
- return isObject() ? managed()->asNumberObject() : 0;
-}
+ inline static Primitive emptyValue();
+ static inline Primitive fromBoolean(bool b);
+ static inline Primitive fromInt32(int i);
+ inline static Primitive undefinedValue();
+ static inline Primitive nullValue();
+ static inline Primitive fromDouble(double d);
+ static inline Primitive fromUInt32(uint i);
+
+ static double toInteger(double fromNumber);
+ static int toInt32(double value);
+ static unsigned int toUInt32(double value);
+
+ inline operator ValueRef();
+ Value asValue() const { return *this; }
+};
-inline StringObject *Value::asStringObject() const
+inline Primitive Primitive::undefinedValue()
{
- return isObject() ? managed()->asStringObject() : 0;
+ Primitive v;
+#if QT_POINTER_SIZE == 8
+ v.val = quint64(Undefined_Type) << Tag_Shift;
+#else
+ v.tag = Undefined_Type;
+ v.int_32 = 0;
+#endif
+ return v;
}
-inline DateObject *Value::asDateObject() const
+inline Primitive Primitive::emptyValue()
{
- return isObject() ? managed()->asDateObject() : 0;
+ Primitive v;
+ v.tag = Value::Empty_Type;
+ v.uint_32 = 0;
+ return v;
}
-inline ArrayObject *Value::asArrayObject() const
+inline Value Value::fromManaged(Managed *m)
{
- return isObject() ? managed()->asArrayObject() : 0;
+ if (!m)
+ return QV4::Primitive::undefinedValue();
+ Value v;
+#if QT_POINTER_SIZE == 8
+ v.m = m;
+#else
+ v.tag = Managed_Type;
+ v.m = m;
+#endif
+ return v;
}
-inline ErrorObject *Value::asErrorObject() const
+template <typename T>
+struct TypedValue : public Value
{
- return isObject() ? managed()->asErrorObject() : 0;
-}
+ template<typename X>
+ TypedValue &operator =(X *x) {
+ val = Value::fromManaged(x).val;
+ }
+ TypedValue &operator =(T *t);
+ TypedValue &operator =(const Scoped<T> &v);
+// TypedValue &operator =(const ManagedRef<T> &v);
+ TypedValue &operator =(Returned<T> *t);
-template<typename T>
-inline T *Value::as() const { Managed *m = isObject() ? managed() : 0; return m ? m->as<T>() : 0; }
+ TypedValue &operator =(const TypedValue<T> &t);
-struct Q_QML_PRIVATE_EXPORT PersistentValuePrivate
-{
- PersistentValuePrivate(ReturnedValue v, ExecutionEngine *engine = 0, bool weak = false);
- virtual ~PersistentValuePrivate();
- SafeValue value;
- uint refcount;
- bool weak;
- QV4::ExecutionEngine *engine;
- PersistentValuePrivate **prev;
- PersistentValuePrivate *next;
-
- void init();
- void removeFromList();
- void ref() { ++refcount; }
- void deref();
- PersistentValuePrivate *detach(const ReturnedValue value, bool weak = false);
-
- bool checkEngine(QV4::ExecutionEngine *otherEngine) {
- if (!engine) {
- Q_ASSERT(!value.isObject());
- engine = otherEngine;
- }
- return (engine == otherEngine);
- }
-};
+ bool operator!() const { return !managed(); }
-class Q_QML_EXPORT PersistentValue
-{
-public:
- PersistentValue() : d(0) {}
- PersistentValue(const PersistentValue &other);
- PersistentValue &operator=(const PersistentValue &other);
+ T *operator->() { return static_cast<T *>(managed()); }
+ const T *operator->() const { return static_cast<T *>(managed()); }
+ T *getPointer() const { return static_cast<T *>(managed()); }
+ Returned<T> *ret() const;
+
+ void mark(ExecutionEngine *e) { if (managed()) managed()->mark(e); }
+};
+typedef TypedValue<String> StringValue;
- PersistentValue(const ValueRef val);
- PersistentValue(ReturnedValue val);
- template<typename T>
- PersistentValue(Returned<T> *obj);
- template<typename T>
- PersistentValue(const Referenced<T> obj);
- PersistentValue &operator=(const ValueRef other);
- PersistentValue &operator =(ReturnedValue other);
- template<typename T>
- PersistentValue &operator=(Returned<T> *obj);
- template<typename T>
- PersistentValue &operator=(const Referenced<T> obj);
- ~PersistentValue();
- ReturnedValue value() const {
- return (d ? d->value.asReturnedValue() : Primitive::undefinedValue().asReturnedValue());
+struct Encode {
+ static ReturnedValue undefined() {
+ return quint64(Value::Undefined_Type) << Value::Tag_Shift;
+ }
+ static ReturnedValue null() {
+ return quint64(Value::_Null_Type) << Value::Tag_Shift;
}
- ExecutionEngine *engine() {
- if (!d)
- return 0;
- if (d->engine)
- return d->engine;
- Managed *m = d->value.asManaged();
- return m ? m->engine() : 0;
+ Encode(bool b) {
+ val = (quint64(Value::_Boolean_Type) << Value::Tag_Shift) | (uint)b;
+ }
+ Encode(double d) {
+ Value v;
+ v.setDouble(d);
+ val = v.val;
+ }
+ Encode(int i) {
+ val = (quint64(Value::_Integer_Type) << Value::Tag_Shift) | (uint)i;
+ }
+ Encode(uint i) {
+ if (i <= INT_MAX) {
+ val = (quint64(Value::_Integer_Type) << Value::Tag_Shift) | i;
+ } else {
+ Value v;
+ v.setDouble(i);
+ val = v.val;
+ }
+ }
+ Encode(ReturnedValue v) {
+ val = v;
}
- bool isUndefined() const { return !d || d->value.isUndefined(); }
- bool isNullOrUndefined() const { return !d || d->value.isNullOrUndefined(); }
- void clear() {
- *this = PersistentValue();
+ template<typename T>
+ Encode(Returned<T> *t) {
+ val = t->getPointer()->asReturnedValue();
}
+ operator ReturnedValue() const {
+ return val;
+ }
+ quint64 val;
private:
- friend struct ValueRef;
- PersistentValuePrivate *d;
+ Encode(void *);
};
-class Q_QML_EXPORT WeakValue
-{
-public:
- WeakValue() : d(0) {}
- WeakValue(const ValueRef val);
- WeakValue(const WeakValue &other);
- WeakValue(ReturnedValue val);
- template<typename T>
- WeakValue(Returned<T> *obj);
- WeakValue &operator=(const WeakValue &other);
- WeakValue &operator=(const ValueRef other);
- WeakValue &operator =(const ReturnedValue &other);
- template<typename T>
- WeakValue &operator=(Returned<T> *obj);
-
- ~WeakValue();
+struct ValueRef {
+ ValueRef(const ScopedValue &v);
+ template <typename T>
+ ValueRef(const Scoped<T> &v);
+ ValueRef(const PersistentValue &v);
+ ValueRef(PersistentValuePrivate *p);
+ ValueRef(Value &v) { ptr = &v; }
+ // Important: Do NOT add a copy constructor to this class
+ // adding a copy constructor actually changes the calling convention, ie.
+ // is not even binary compatible. Adding it would break assumptions made
+ // in the jit'ed code.
+ ValueRef &operator=(const ScopedValue &o);
+ ValueRef &operator=(const Value &v)
+ { *ptr = v; return *this; }
+ ValueRef &operator=(const ReturnedValue &v) {
+ ptr->val = v;
+ return *this;
+ }
+ template <typename T>
+ ValueRef &operator=(Returned<T> *v) {
+ ptr->val = v->asReturnedValue();
+ return *this;
+ }
- ReturnedValue value() const {
- return (d ? d->value.asReturnedValue() : Primitive::undefinedValue().asReturnedValue());
+ operator const Value *() const {
+ return ptr;
+ }
+ const Value *operator->() const {
+ return ptr;
}
- ExecutionEngine *engine() {
- if (!d)
- return 0;
- if (d->engine)
- return d->engine;
- Managed *m = d->value.asManaged();
- return m ? m->engine() : 0;
+ operator Value *() {
+ return ptr;
+ }
+ Value *operator->() {
+ return ptr;
}
- bool isUndefined() const { return !d || d->value.isUndefined(); }
- bool isNullOrUndefined() const { return !d || d->value.isNullOrUndefined(); }
- void clear() {
- *this = WeakValue();
+ static ValueRef fromRawValue(Value *v) {
+ return ValueRef(v);
+ }
+ static const ValueRef fromRawValue(const Value *v) {
+ return ValueRef(const_cast<Value *>(v));
}
- void markOnce(ExecutionEngine *e);
+ ReturnedValue asReturnedValue() const { return ptr->val; }
+ // ### get rid of this one!
+ ValueRef(Value *v) { ptr = reinterpret_cast<Value *>(v); }
private:
- friend struct ValueRef;
- PersistentValuePrivate *d;
+ Value *ptr;
};
-} // namespace QV4
+
+template<typename T>
+T *value_cast(const Value &v)
+{
+ return v.as<T>();
+}
+
+template<typename T>
+ReturnedValue value_convert(ExecutionEngine *e, const Value &v);
+
+
+
+}
QT_END_NAMESPACE
-#endif
+#endif // QV4VALUE_DEF_P_H
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index dfa4ac5775..92cc19d8b9 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-DEFINE_MANAGED_VTABLE(VariantObject);
+DEFINE_OBJECT_VTABLE(VariantObject);
VariantObject::VariantObject(InternalClass *ic)
: Object(ic)
@@ -77,7 +77,7 @@ QVariant VariantObject::toVariant(const QV4::ValueRef v)
if (v->isBoolean())
return QVariant(v->booleanValue());
if (v->isNumber()) {
- QV4::SafeValue val;
+ QV4::Value val;
val = v;
if (val.isInt32())
return QVariant(val.integerValue());
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index 4e14839184..656608d49b 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -57,7 +57,7 @@
#include <QtQml/qqmllist.h>
#include <QtCore/qvariant.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
@@ -66,7 +66,7 @@ namespace QV4 {
struct VariantObject : Object, public ExecutionEngine::ScarceResourceData
{
- Q_MANAGED
+ V4_OBJECT
public:
VariantObject(InternalClass *ic);
VariantObject(ExecutionEngine *engine, const QVariant &value);
@@ -82,6 +82,8 @@ public:
static bool isEqualTo(Managed *m, Managed *other);
};
+DEFINE_REF(VariantObject, Object);
+
struct VariantPrototype : VariantObject
{
public:
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 9d6540ebe9..df8e3632fb 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -41,7 +41,7 @@
#include "qv4vme_moth_p.h"
#include "qv4instr_moth_p.h"
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4debugging_p.h>
#include <private/qv4math_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -64,8 +64,6 @@ using namespace QQmlJS::Moth;
#define MOTH_BEGIN_INSTR_COMMON(I) { \
const InstrMeta<(int)Instr::I>::DataType &instr = InstrMeta<(int)Instr::I>::data(*genericInstr); \
code += InstrMeta<(int)Instr::I>::Size; \
- if (debugger && (instr.breakPoint || debugger->pauseAtNextOpportunity())) \
- debugger->maybeBreakAtInstruction(code, instr.breakPoint); \
Q_UNUSED(instr); \
TRACE_INSTR(I)
@@ -74,11 +72,6 @@ using namespace QQmlJS::Moth;
# define MOTH_BEGIN_INSTR(I) op_##I: \
MOTH_BEGIN_INSTR_COMMON(I)
-# define MOTH_NEXT_INSTR(I) { \
- genericInstr = reinterpret_cast<const Instr *>(code); \
- goto *genericInstr->common.code; \
- }
-
# define MOTH_END_INSTR(I) } \
genericInstr = reinterpret_cast<const Instr *>(code); \
goto *genericInstr->common.code; \
@@ -89,10 +82,6 @@ using namespace QQmlJS::Moth;
case Instr::I: \
MOTH_BEGIN_INSTR_COMMON(I)
-# define MOTH_NEXT_INSTR(I) { \
- continue; \
- }
-
# define MOTH_END_INSTR(I) } \
continue;
@@ -161,16 +150,15 @@ Param traceParam(const Param &param)
#define STOREVALUE(param, value) { \
QV4::ReturnedValue tmp = (value); \
- if (context->engine->hasException) \
+ if (engine->hasException) \
goto catchException; \
VALUE(param) = tmp; \
}
#define CHECK_EXCEPTION \
- if (context->engine->hasException) \
+ if (engine->hasException) \
goto catchException
-QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
- QV4::SafeValue *stack, unsigned stackSize
+QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
#ifdef MOTH_THREADED_INTERPRETER
, void ***storeJumpTable
#endif
@@ -192,15 +180,18 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
}
#endif
+ QV4::Value *stack = 0;
+ unsigned stackSize = 0;
+
const uchar *exceptionHandler = 0;
- QV4::Debugging::Debugger *debugger = context->engine->debugger;
+ QV4::ExecutionEngine *engine = context->engine;
#ifdef DO_TRACE_INSTR
qDebug("Starting VME with context=%p and code=%p", context, code);
#endif // DO_TRACE_INSTR
- QV4::SafeString * const runtimeStrings = context->compilationUnit->runtimeStrings;
+ QV4::StringValue * const runtimeStrings = context->compilationUnit->runtimeStrings;
context->interpreterInstructionPointer = &code;
// setup lookup scopes
@@ -213,9 +204,9 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
}
}
- QV4::SafeValue **scopes = static_cast<QV4::SafeValue **>(alloca(sizeof(QV4::SafeValue *)*(2 + 2*scopeDepth)));
+ QV4::Value **scopes = static_cast<QV4::Value **>(alloca(sizeof(QV4::Value *)*(2 + 2*scopeDepth)));
{
- scopes[0] = const_cast<QV4::SafeValue *>(context->compilationUnit->data->constants());
+ scopes[0] = const_cast<QV4::Value *>(context->compilationUnit->data->constants());
// stack gets setup in push instruction
scopes[1] = 0;
QV4::ExecutionContext *scope = context;
@@ -247,6 +238,10 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
VALUE(instr.result) = VALUE(instr.source);
MOTH_END_INSTR(Move)
+ MOTH_BEGIN_INSTR(MoveConst)
+ VALUE(instr.result) = instr.source;
+ MOTH_END_INSTR(MoveConst)
+
MOTH_BEGIN_INSTR(SwapTemps)
qSwap(VALUE(instr.left), VALUE(instr.right));
MOTH_END_INSTR(MoveTemp)
@@ -286,11 +281,22 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
STOREVALUE(instr.result, __qmljs_get_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index)));
MOTH_END_INSTR(LoadElement)
+ MOTH_BEGIN_INSTR(LoadElementLookup)
+ QV4::Lookup *l = context->lookups + instr.lookup;
+ STOREVALUE(instr.result, l->indexedGetter(l, VALUEPTR(instr.base), VALUEPTR(instr.index)));
+ MOTH_END_INSTR(LoadElementLookup)
+
MOTH_BEGIN_INSTR(StoreElement)
__qmljs_set_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index), VALUEPTR(instr.source));
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreElement)
+ MOTH_BEGIN_INSTR(StoreElementLookup)
+ QV4::Lookup *l = context->lookups + instr.lookup;
+ l->indexedSetter(l, VALUEPTR(instr.base), VALUEPTR(instr.index), VALUEPTR(instr.source));
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(StoreElementLookup)
+
MOTH_BEGIN_INSTR(LoadProperty)
STOREVALUE(instr.result, __qmljs_get_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name]));
MOTH_END_INSTR(LoadProperty)
@@ -328,7 +334,9 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
TRACE(inline, "stack size: %u", instr.value);
stackSize = instr.value;
stack = context->engine->stackPush(stackSize);
- memset(stack, 0, stackSize * sizeof(QV4::SafeValue));
+#ifndef QT_NO_DEBUG
+ memset(stack, 0, stackSize * sizeof(QV4::Value));
+#endif
scopes[1] = stack;
MOTH_END_INSTR(Push)
@@ -343,7 +351,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
}
}
#endif // DO_TRACE_INSTR
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -353,7 +361,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallProperty)
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -363,7 +371,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallPropertyLookup)
TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(context)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -372,7 +380,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallElement)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -382,7 +390,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallActivationProperty)
TRACE(args, "starting at %d, length %d", instr.args, instr.argc);
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -392,7 +400,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallGlobalLookup)
TRACE(args, "starting at %d, length %d", instr.args, instr.argc);
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -475,12 +483,12 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CallBuiltinDefineArray)
Q_ASSERT(instr.args + instr.argc <= stackSize);
- QV4::SafeValue *args = stack + instr.args;
+ QV4::Value *args = stack + instr.args;
STOREVALUE(instr.result, __qmljs_builtin_define_array(context, args, instr.argc));
MOTH_END_INSTR(CallBuiltinDefineArray)
MOTH_BEGIN_INSTR(CallBuiltinDefineObjectLiteral)
- QV4::SafeValue *args = stack + instr.args;
+ QV4::Value *args = stack + instr.args;
STOREVALUE(instr.result, __qmljs_builtin_define_object_literal(context, args, instr.internalClassId));
MOTH_END_INSTR(CallBuiltinDefineObjectLiteral)
@@ -494,7 +502,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_END_INSTR(CallBuiltinConvertThisToObject)
MOTH_BEGIN_INSTR(CreateValue)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -503,7 +511,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_END_INSTR(CreateValue)
MOTH_BEGIN_INSTR(CreateProperty)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -512,7 +520,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_END_INSTR(CreateProperty)
MOTH_BEGIN_INSTR(ConstructPropertyLookup)
- Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -522,7 +530,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(CreateActivationProperty)
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 + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -532,7 +540,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_BEGIN_INSTR(ConstructGlobalLookup)
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 + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize);
+ Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
callData->tag = QV4::Value::Integer_Type;
callData->argc = instr.argc;
@@ -544,14 +552,19 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
code = ((uchar *)&instr.offset) + instr.offset;
MOTH_END_INSTR(Jump)
- MOTH_BEGIN_INSTR(CJump)
- uint cond = __qmljs_to_boolean(VALUEPTR(instr.condition));
+ MOTH_BEGIN_INSTR(JumpEq)
+ bool cond = VALUEPTR(instr.condition)->toBoolean();
TRACE(condition, "%s", cond ? "TRUE" : "FALSE");
- if (instr.invert)
- cond = !cond;
if (cond)
code = ((uchar *)&instr.offset) + instr.offset;
- MOTH_END_INSTR(CJump)
+ MOTH_END_INSTR(JumpEq)
+
+ MOTH_BEGIN_INSTR(JumpNe)
+ bool cond = VALUEPTR(instr.condition)->toBoolean();
+ TRACE(condition, "%s", cond ? "TRUE" : "FALSE");
+ if (!cond)
+ code = ((uchar *)&instr.offset) + instr.offset;
+ MOTH_END_INSTR(JumpNe)
MOTH_BEGIN_INSTR(UNot)
STOREVALUE(instr.result, __qmljs_not(VALUEPTR(instr.source)));
@@ -606,6 +619,14 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
STOREVALUE(instr.result, __qmljs_bit_xor(VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(BitXor)
+ MOTH_BEGIN_INSTR(Shr)
+ STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() >> (VALUEPTR(instr.rhs)->toInt32() & 0x1f))));
+ MOTH_END_INSTR(Shr)
+
+ MOTH_BEGIN_INSTR(Shl)
+ STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() << (VALUEPTR(instr.rhs)->toInt32() & 0x1f))));
+ MOTH_END_INSTR(Shl)
+
MOTH_BEGIN_INSTR(BitAndConst)
int lhs = VALUEPTR(instr.lhs)->toInt32();
STOREVALUE(instr.result, QV4::Encode((int)(lhs & instr.rhs)));
@@ -621,6 +642,14 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
STOREVALUE(instr.result, QV4::Encode((int)(lhs ^ instr.rhs)));
MOTH_END_INSTR(BitXor)
+ MOTH_BEGIN_INSTR(ShrConst)
+ STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() >> instr.rhs)));
+ MOTH_END_INSTR(ShrConst)
+
+ MOTH_BEGIN_INSTR(ShlConst)
+ STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() << instr.rhs)));
+ MOTH_END_INSTR(ShlConst)
+
MOTH_BEGIN_INSTR(Mul)
STOREVALUE(instr.result, __qmljs_mul(VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(Mul)
@@ -633,30 +662,18 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
STOREVALUE(instr.result, instr.alu(context, VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(BinopContext)
- MOTH_BEGIN_INSTR(AddNumberParams)
- double lhs = VALUE(instr.lhs).asDouble();
- double rhs = VALUE(instr.rhs).asDouble();
- VALUEPTR(instr.result)->setDouble(lhs + rhs);
- MOTH_END_INSTR(AddNumberParams)
-
- MOTH_BEGIN_INSTR(MulNumberParams)
- double lhs = VALUE(instr.lhs).asDouble();
- double rhs = VALUE(instr.rhs).asDouble();
- VALUEPTR(instr.result)->setDouble(lhs * rhs);
- MOTH_END_INSTR(MulNumberParams)
-
- MOTH_BEGIN_INSTR(SubNumberParams)
- double lhs = VALUE(instr.lhs).asDouble();
- double rhs = VALUE(instr.rhs).asDouble();
- VALUEPTR(instr.result)->setDouble(lhs - rhs);
- MOTH_END_INSTR(SubNumberParams)
-
MOTH_BEGIN_INSTR(Ret)
context->engine->stackPop(stackSize);
// TRACE(Ret, "returning value %s", result.toString(context)->toQString().toUtf8().constData());
return VALUE(instr.result).asReturnedValue();
MOTH_END_INSTR(Ret)
+ MOTH_BEGIN_INSTR(Debug)
+ QV4::Debugging::Debugger *debugger = context->engine->debugger;
+ if (debugger && (instr.breakPoint || debugger->pauseAtNextOpportunity()))
+ debugger->maybeBreakAtInstruction(code, instr.breakPoint);
+ MOTH_END_INSTR(Debug)
+
MOTH_BEGIN_INSTR(LoadThis)
VALUE(instr.result) = context->callData->thisObject;
MOTH_END_INSTR(LoadThis)
@@ -709,7 +726,7 @@ void **VME::instructionJumpTable()
static void **jumpTable = 0;
if (!jumpTable) {
const uchar *code = 0;
- VME().run(0, code, 0, 0, &jumpTable);
+ VME().run(0, code, &jumpTable);
}
return jumpTable;
}
diff --git a/src/qml/jsruntime/qv4vme_moth_p.h b/src/qml/jsruntime/qv4vme_moth_p.h
index 974dfdd615..8d0822f16f 100644
--- a/src/qml/jsruntime/qv4vme_moth_p.h
+++ b/src/qml/jsruntime/qv4vme_moth_p.h
@@ -60,8 +60,7 @@ public:
#endif
private:
- QV4::ReturnedValue run(QV4::ExecutionContext *, const uchar *code,
- QV4::SafeValue *stack = 0, unsigned stackSize = 0
+ QV4::ReturnedValue run(QV4::ExecutionContext *, const uchar *code
#ifdef MOTH_THREADED_INTERPRETER
, void ***storeJumpTable = 0
#endif
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index 8e8ed954ad..73d0a8c3dd 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -707,7 +707,7 @@ again:
_validTokenText = true;
_tokenText.resize(0);
startCode--;
- while (startCode != _codePtr - 1)
+ while (startCode != _codePtr - 1)
_tokenText += *startCode++;
while (_codePtr <= _endPtr) {
diff --git a/src/qml/parser/qqmljsmemorypool_p.h b/src/qml/parser/qqmljsmemorypool_p.h
index 820ae8ed71..29103930ad 100644
--- a/src/qml/parser/qqmljsmemorypool_p.h
+++ b/src/qml/parser/qqmljsmemorypool_p.h
@@ -108,6 +108,8 @@ public:
_ptr = _end = 0;
}
+ template <typename _Tp> _Tp *New() { return new (this->allocate(sizeof(_Tp))) _Tp(); }
+
private:
void *allocate_helper(size_t size)
{
diff --git a/src/qml/qml/ftw/qbitfield_p.h b/src/qml/qml/ftw/qbitfield_p.h
index b224f5b57d..12e98dc655 100644
--- a/src/qml/qml/ftw/qbitfield_p.h
+++ b/src/qml/qml/ftw/qbitfield_p.h
@@ -91,13 +91,13 @@ QBitField::QBitField(const quint32 *bitData, int bitCount)
QBitField::QBitField(const QBitField &other)
: bits(other.bits), ownData(other.ownData), data(other.data)
{
- if (ownData)
+ if (ownData)
++(*ownData);
}
QBitField::~QBitField()
{
- if (ownData)
+ if (ownData)
if(0 == --(*ownData)) delete [] ownData;
}
@@ -106,14 +106,14 @@ QBitField &QBitField::operator=(const QBitField &other)
if (other.data == data)
return *this;
- if (ownData)
+ if (ownData)
if(0 == --(*ownData)) delete [] ownData;
bits = other.bits;
ownData = other.ownData;
data = other.data;
- if (ownData)
+ if (ownData)
++(*ownData);
return *this;
diff --git a/src/qml/qml/ftw/qfieldlist_p.h b/src/qml/qml/ftw/qfieldlist_p.h
index 5d37751f05..c90b6773a1 100644
--- a/src/qml/qml/ftw/qfieldlist_p.h
+++ b/src/qml/qml/ftw/qfieldlist_p.h
@@ -90,7 +90,7 @@ private:
// QFieldList is a simple linked list, that can append and prepend and also
// maintains a count
template<class N, N *N::*nextMember>
-class QFieldList
+class QFieldList
{
public:
inline QFieldList();
@@ -253,7 +253,7 @@ N *QFieldList<N, nextMember>::takeFirst()
}
value->*nextMember = 0;
--_count;
- }
+ }
return value;
}
diff --git a/src/qml/qml/ftw/qfinitestack_p.h b/src/qml/qml/ftw/qfinitestack_p.h
index 8b499d9b6d..6bfd353771 100644
--- a/src/qml/qml/ftw/qfinitestack_p.h
+++ b/src/qml/qml/ftw/qfinitestack_p.h
@@ -83,7 +83,7 @@ private:
template<typename T>
QFiniteStack<T>::QFiniteStack()
-: _array(0), _alloc(0), _size(0)
+: _array(0), _alloc(0), _size(0)
{
}
@@ -114,6 +114,7 @@ T &QFiniteStack<T>::top()
template<typename T>
void QFiniteStack<T>::push(const T &o)
{
+ Q_ASSERT(_size < _alloc);
if (QTypeInfo<T>::isComplex) {
new (_array + _size++) T(o);
} else {
@@ -124,6 +125,7 @@ void QFiniteStack<T>::push(const T &o)
template<typename T>
T QFiniteStack<T>::pop()
{
+ Q_ASSERT(_size > 0);
--_size;
if (QTypeInfo<T>::isComplex) {
@@ -134,7 +136,7 @@ T QFiniteStack<T>::pop()
return _array[_size];
}
}
-
+
template<typename T>
int QFiniteStack<T>::count() const
{
@@ -154,7 +156,7 @@ T &QFiniteStack<T>::operator[](int index)
}
template<typename T>
-void QFiniteStack<T>::allocate(int size)
+void QFiniteStack<T>::allocate(int size)
{
Q_ASSERT(_array == 0);
Q_ASSERT(_alloc == 0);
@@ -171,7 +173,7 @@ void QFiniteStack<T>::deallocate()
{
if (QTypeInfo<T>::isComplex) {
T *i = _array + _size;
- while (i != _array)
+ while (i != _array)
(--i)->~T();
}
diff --git a/src/qml/qml/ftw/qhashedstring.cpp b/src/qml/qml/ftw/qhashedstring.cpp
index 012412b6b5..fa3524ff3e 100644
--- a/src/qml/qml/ftw/qhashedstring.cpp
+++ b/src/qml/qml/ftw/qhashedstring.cpp
@@ -198,19 +198,19 @@ bool QHashedString::compare(const QChar *lhs, const QChar *rhs, int length)
QHashedStringRef QHashedStringRef::mid(int offset, int length) const
{
Q_ASSERT(offset < m_length);
- return QHashedStringRef(m_data + offset,
+ return QHashedStringRef(m_data + offset,
(length == -1 || (offset + length) > m_length)?(m_length - offset):length);
}
bool QHashedStringRef::endsWith(const QString &s) const
{
- return s.length() < m_length &&
+ return s.length() < m_length &&
QHashedString::compare(s.constData(), m_data + m_length - s.length(), s.length());
}
bool QHashedStringRef::startsWith(const QString &s) const
{
- return s.length() < m_length &&
+ return s.length() < m_length &&
QHashedString::compare(s.constData(), m_data, s.length());
}
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index 46f0533740..61a492013d 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -97,7 +97,7 @@ private:
};
class QHashedCStringRef;
-class Q_AUTOTEST_EXPORT QHashedStringRef
+class Q_AUTOTEST_EXPORT QHashedStringRef
{
public:
inline QHashedStringRef();
@@ -258,15 +258,15 @@ public:
}
inline bool equals(const QHashedStringRef &string) const {
- return length == string.length() &&
- hash == string.hash() &&
+ return length == string.length() &&
+ hash == string.hash() &&
(isQString()?QHashedString::compare(string.constData(), (QChar *)utf16Data(), length):
QHashedString::compare(string.constData(), cStrData(), length));
}
inline bool equals(const QHashedCStringRef &string) const {
- return length == string.length() &&
- hash == string.hash() &&
+ return length == string.length() &&
+ hash == string.hash() &&
(isQString()?QHashedString::compare((QChar *)utf16Data(), string.constData(), length):
QHashedString::compare(string.constData(), cStrData(), length));
}
@@ -275,7 +275,7 @@ public:
class Q_AUTOTEST_EXPORT QStringHashData
{
public:
- QStringHashData()
+ QStringHashData()
: buckets(0), numBuckets(0), size(0), numBits(0)
#ifdef QSTRINGHASH_LINK_DEBUG
, linkCount(0)
@@ -1026,33 +1026,33 @@ typename QStringHash<T>::ConstIterator QStringMultiHash<T>::findNext(const Const
return ConstIterator();
}
-inline uint qHash(const QHashedString &string)
-{
- return uint(string.hash());
+inline uint qHash(const QHashedString &string)
+{
+ return uint(string.hash());
}
-inline uint qHash(const QHashedStringRef &string)
-{
- return uint(string.hash());
+inline uint qHash(const QHashedStringRef &string)
+{
+ return uint(string.hash());
}
-QHashedString::QHashedString()
-: QString(), m_hash(0)
+QHashedString::QHashedString()
+: QString(), m_hash(0)
{
}
-QHashedString::QHashedString(const QString &string)
-: QString(string), m_hash(0)
+QHashedString::QHashedString(const QString &string)
+: QString(string), m_hash(0)
{
}
-QHashedString::QHashedString(const QString &string, quint32 hash)
-: QString(string), m_hash(hash)
+QHashedString::QHashedString(const QString &string, quint32 hash)
+: QString(string), m_hash(hash)
{
}
-QHashedString::QHashedString(const QHashedString &string)
-: QString(string), m_hash(string.m_hash)
+QHashedString::QHashedString(const QHashedString &string)
+: QString(string), m_hash(string.m_hash)
{
}
@@ -1065,29 +1065,29 @@ QHashedString &QHashedString::operator=(const QHashedString &string)
bool QHashedString::operator==(const QHashedString &string) const
{
- return (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
+ return (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
static_cast<const QString &>(*this) == static_cast<const QString &>(string);
}
bool QHashedString::operator==(const QHashedStringRef &string) const
{
return length() == string.m_length &&
- (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
+ (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
QHashedString::compare(constData(), string.m_data, string.m_length);
}
quint32 QHashedString::hash() const
-{
+{
if (!m_hash) computeHash();
return m_hash;
}
quint32 QHashedString::existingHash() const
-{
+{
return m_hash;
}
-QHashedStringRef::QHashedStringRef()
+QHashedStringRef::QHashedStringRef()
: m_data(0), m_length(0), m_hash(0)
{
}
@@ -1138,21 +1138,21 @@ bool QHashedStringRef::operator==(const QString &string) const
bool QHashedStringRef::operator==(const QHashedString &string) const
{
- return m_length == string.length() &&
+ return m_length == string.length() &&
(m_hash == string.m_hash || !m_hash || !string.m_hash) &&
QHashedString::compare(string.constData(), m_data, m_length);
}
bool QHashedStringRef::operator==(const QHashedStringRef &string) const
{
- return m_length == string.m_length &&
+ return m_length == string.m_length &&
(m_hash == string.m_hash || !m_hash || !string.m_hash) &&
QHashedString::compare(string.m_data, m_data, m_length);
}
bool QHashedStringRef::operator==(const QHashedCStringRef &string) const
{
- return m_length == string.m_length &&
+ return m_length == string.m_length &&
(m_hash == string.m_hash || !m_hash || !string.m_hash) &&
QHashedString::compare(m_data, string.m_data, m_length);
}
@@ -1165,7 +1165,7 @@ bool QHashedStringRef::operator!=(const QString &string) const
bool QHashedStringRef::operator!=(const QHashedString &string) const
{
- return m_length != string.length() ||
+ return m_length != string.length() ||
(m_hash != string.m_hash && m_hash && string.m_hash) ||
!QHashedString::compare(string.constData(), m_data, m_length);
}
@@ -1224,7 +1224,7 @@ bool QHashedStringRef::startsWithUpper() const
}
quint32 QHashedStringRef::hash() const
-{
+{
if (!m_hash) computeHash();
return m_hash;
}
@@ -1279,20 +1279,20 @@ void QHashedCStringRef::writeUtf16(quint16 *output) const
{
int l = m_length;
const char *d = m_data;
- while (l--)
+ while (l--)
*output++ = *d++;
}
-bool QHashedString::compare(const QChar *lhs, const char *rhs, int length)
+bool QHashedString::compare(const QChar *lhs, const char *rhs, int length)
{
Q_ASSERT(lhs && rhs);
const quint16 *l = (const quint16*)lhs;
- while (length--)
+ while (length--)
if (*l++ != *rhs++) return false;
return true;
}
-bool QHashedString::compare(const char *lhs, const char *rhs, int length)
+bool QHashedString::compare(const char *lhs, const char *rhs, int length)
{
Q_ASSERT(lhs && rhs);
return 0 == ::memcmp(lhs, rhs, length);
diff --git a/src/qml/qml/ftw/qhashfield_p.h b/src/qml/qml/ftw/qhashfield_p.h
index 32c7a0fbe2..aa8840688a 100644
--- a/src/qml/qml/ftw/qhashfield_p.h
+++ b/src/qml/qml/ftw/qhashfield_p.h
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
// example where you would write:
// QSet<QString> strings;
// for (int ii = 0; ii < mystrings.count(); ++ii) {
-// if (strings.contains(mystrings.at(ii)))
+// if (strings.contains(mystrings.at(ii)))
// qFatal("Duplication!");
// strings.insert(mystrings);
// }
@@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
// if (strings.testAndSet(qHash(mystrings.at(ii)))) {
// // The string *might* be duplicated
// for (int jj = 0; jj < ii; ++jj) {
-// if (mystrings.at(ii) == mystrings.at(jj))
+// if (mystrings.at(ii) == mystrings.at(jj))
// qFatal("Duplication!");
// }
// }
diff --git a/src/qml/qml/ftw/qintrusivelist.cpp b/src/qml/qml/ftw/qintrusivelist.cpp
index 12d710ca47..7c80b57c9d 100644
--- a/src/qml/qml/ftw/qintrusivelist.cpp
+++ b/src/qml/qml/ftw/qintrusivelist.cpp
@@ -46,7 +46,7 @@
\brief The QIntrusiveList class is a template class that provides a list of objects using static storage.
\internal
-QIntrusiveList creates a linked list of objects. Adding and removing objects from the
+QIntrusiveList creates a linked list of objects. Adding and removing objects from the
QIntrusiveList is a constant time operation and is very quick. The list performs no memory
allocations, but does require the objects being added to the list to contain a QIntrusiveListNode
instance for the list's use. Even so, for small lists QIntrusiveList uses less memory than Qt's
@@ -102,7 +102,7 @@ Destroy the list. All entries are removed.
/*!
\fn void QIntrusiveList::insert(N *object);
-Insert \a object into the list. If \a object is a member of this, or another list, it will be
+Insert \a object into the list. If \a object is a member of this, or another list, it will be
removed and inserted at the head of this list.
*/
diff --git a/src/qml/qml/ftw/qintrusivelist_p.h b/src/qml/qml/ftw/qintrusivelist_p.h
index ccaeee2e40..67de569951 100644
--- a/src/qml/qml/ftw/qintrusivelist_p.h
+++ b/src/qml/qml/ftw/qintrusivelist_p.h
@@ -82,7 +82,7 @@ public:
inline iterator &operator++();
inline iterator &erase();
-
+
private:
N *_value;
};
@@ -114,60 +114,60 @@ public:
};
template<class N, QIntrusiveListNode N::*member>
-QIntrusiveList<N, member>::iterator::iterator()
-: _value(0)
+QIntrusiveList<N, member>::iterator::iterator()
+: _value(0)
{
}
template<class N, QIntrusiveListNode N::*member>
-QIntrusiveList<N, member>::iterator::iterator(N *value)
-: _value(value)
+QIntrusiveList<N, member>::iterator::iterator(N *value)
+: _value(value)
{
}
template<class N, QIntrusiveListNode N::*member>
-N *QIntrusiveList<N, member>::iterator::operator*() const
-{
- return _value;
+N *QIntrusiveList<N, member>::iterator::operator*() const
+{
+ return _value;
}
template<class N, QIntrusiveListNode N::*member>
-N *QIntrusiveList<N, member>::iterator::operator->() const
-{
- return _value;
+N *QIntrusiveList<N, member>::iterator::operator->() const
+{
+ return _value;
}
template<class N, QIntrusiveListNode N::*member>
-bool QIntrusiveList<N, member>::iterator::operator==(const iterator &other) const
-{
- return other._value == _value;
+bool QIntrusiveList<N, member>::iterator::operator==(const iterator &other) const
+{
+ return other._value == _value;
}
template<class N, QIntrusiveListNode N::*member>
-bool QIntrusiveList<N, member>::iterator::operator!=(const iterator &other) const
-{
- return other._value != _value;
+bool QIntrusiveList<N, member>::iterator::operator!=(const iterator &other) const
+{
+ return other._value != _value;
}
template<class N, QIntrusiveListNode N::*member>
-typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::operator++()
-{
- _value = QIntrusiveList<N, member>::next(_value);
- return *this;
+typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::operator++()
+{
+ _value = QIntrusiveList<N, member>::next(_value);
+ return *this;
}
template<class N, QIntrusiveListNode N::*member>
-typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::erase()
-{
- N *old = _value;
- _value = QIntrusiveList<N, member>::next(_value);
- (old->*member).remove();
+typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::erase()
+{
+ N *old = _value;
+ _value = QIntrusiveList<N, member>::next(_value);
+ (old->*member).remove();
return *this;
}
-
+
template<class N, QIntrusiveListNode N::*member>
-QIntrusiveList<N, member>::QIntrusiveList()
-: __first(0)
+QIntrusiveList<N, member>::QIntrusiveList()
+: __first(0)
{
}
@@ -184,7 +184,7 @@ bool QIntrusiveList<N, member>::isEmpty() const
}
template<class N, QIntrusiveListNode N::*member>
-void QIntrusiveList<N, member>::insert(N *n)
+void QIntrusiveList<N, member>::insert(N *n)
{
QIntrusiveListNode *nnode = &(n->*member);
nnode->remove();
@@ -215,13 +215,13 @@ bool QIntrusiveList<N, member>::contains(N *n) const
}
template<class N, QIntrusiveListNode N::*member>
-N *QIntrusiveList<N, member>::first() const
-{
- return __first?nodeToN(__first):0;
+N *QIntrusiveList<N, member>::first() const
+{
+ return __first?nodeToN(__first):0;
}
template<class N, QIntrusiveListNode N::*member>
-N *QIntrusiveList<N, member>::next(N *current)
+N *QIntrusiveList<N, member>::next(N *current)
{
QIntrusiveListNode *nextnode = (current->*member)._next;
N *nextstruct = nextnode?nodeToN(nextnode):0;
@@ -229,19 +229,19 @@ N *QIntrusiveList<N, member>::next(N *current)
}
template<class N, QIntrusiveListNode N::*member>
-typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::begin()
-{
- return __first?iterator(nodeToN(__first)):iterator();
+typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::begin()
+{
+ return __first?iterator(nodeToN(__first)):iterator();
}
template<class N, QIntrusiveListNode N::*member>
-typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::end()
-{
- return iterator();
+typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::end()
+{
+ return iterator();
}
template<class N, QIntrusiveListNode N::*member>
-N *QIntrusiveList<N, member>::nodeToN(QIntrusiveListNode *node)
+N *QIntrusiveList<N, member>::nodeToN(QIntrusiveListNode *node)
{
return (N *)((char *)node - ((char *)&(((N *)0)->*member) - (char *)0));
}
diff --git a/src/qml/qml/ftw/qqmlpool_p.h b/src/qml/qml/ftw/qqmlpool_p.h
index 408ac74771..7a04291cd4 100644
--- a/src/qml/qml/ftw/qqmlpool_p.h
+++ b/src/qml/qml/ftw/qqmlpool_p.h
@@ -63,7 +63,7 @@ class Q_QML_PRIVATE_EXPORT QQmlPool
{
public:
// The class has a destructor that needs to be called
- class Class {
+ class Class {
public:
inline QQmlPool *pool() const;
@@ -82,7 +82,7 @@ public:
class POD {
public:
inline QQmlPool *pool() const;
-
+
private:
void *operator new(size_t);
void *operator new(size_t, void *m) { return m; }
@@ -120,16 +120,16 @@ public:
int count() const {
return m_length;
}
- int length() const {
- return m_length;
+ int length() const {
+ return m_length;
}
- const T &at(int index) const {
- Q_ASSERT(index < m_length);
- return m_data[index];
+ const T &at(int index) const {
+ Q_ASSERT(index < m_length);
+ return m_data[index];
};
T &operator[](int index) {
- Q_ASSERT(index < m_length);
- return m_data[index];
+ Q_ASSERT(index < m_length);
+ return m_data[index];
};
const T *data() const { return m_data; }
private:
diff --git a/src/qml/qml/ftw/qqmlrefcount_p.h b/src/qml/qml/ftw/qqmlrefcount_p.h
index 24c3e7a2cc..de32f0e915 100644
--- a/src/qml/qml/ftw/qqmlrefcount_p.h
+++ b/src/qml/qml/ftw/qqmlrefcount_p.h
@@ -86,7 +86,7 @@ public:
inline QQmlRefPointer<T> &operator=(const QQmlRefPointer<T> &o);
inline QQmlRefPointer<T> &operator=(T *);
-
+
inline bool isNull() const { return !o; }
inline T* operator->() const { return o; }
@@ -100,27 +100,27 @@ private:
T *o;
};
-QQmlRefCount::QQmlRefCount()
-: refCount(1)
+QQmlRefCount::QQmlRefCount()
+: refCount(1)
{
}
-QQmlRefCount::~QQmlRefCount()
+QQmlRefCount::~QQmlRefCount()
{
Q_ASSERT(refCount.load() == 0);
}
-void QQmlRefCount::addref()
-{
+void QQmlRefCount::addref()
+{
Q_ASSERT(refCount.load() > 0);
- refCount.ref();
+ refCount.ref();
}
-void QQmlRefCount::release()
-{
+void QQmlRefCount::release()
+{
Q_ASSERT(refCount.load() > 0);
- if (!refCount.deref())
- destroy();
+ if (!refCount.deref())
+ destroy();
}
int QQmlRefCount::count() const
@@ -128,20 +128,20 @@ int QQmlRefCount::count() const
return refCount.load();
}
-void QQmlRefCount::destroy()
-{
- delete this;
+void QQmlRefCount::destroy()
+{
+ delete this;
}
template<class T>
QQmlRefPointer<T>::QQmlRefPointer()
-: o(0)
+: o(0)
{
}
template<class T>
QQmlRefPointer<T>::QQmlRefPointer(T *o)
-: o(o)
+: o(o)
{
if (o) o->addref();
}
diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp
index 1ea3f25405..c49463c913 100644
--- a/src/qml/qml/ftw/qqmlthread.cpp
+++ b/src/qml/qml/ftw/qqmlthread.cpp
@@ -83,10 +83,10 @@ public:
void threadEvent();
protected:
- virtual bool event(QEvent *);
+ virtual bool event(QEvent *);
private:
- struct MainObject : public QObject {
+ struct MainObject : public QObject {
MainObject(QQmlThreadPrivate *p);
virtual bool event(QEvent *e);
QQmlThreadPrivate *p;
@@ -97,8 +97,8 @@ private:
QWaitCondition _wait;
};
-QQmlThreadPrivate::MainObject::MainObject(QQmlThreadPrivate *p)
-: p(p)
+QQmlThreadPrivate::MainObject::MainObject(QQmlThreadPrivate *p)
+: p(p)
{
}
@@ -116,22 +116,22 @@ void QQmlThreadPrivate::triggerThreadEvent()
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
}
-bool QQmlThreadPrivate::MainObject::event(QEvent *e)
+bool QQmlThreadPrivate::MainObject::event(QEvent *e)
{
- if (e->type() == QEvent::User)
+ if (e->type() == QEvent::User)
p->mainEvent();
return QObject::event(e);
}
-
+
QQmlThreadPrivate::QQmlThreadPrivate(QQmlThread *q)
-: q(q), m_threadProcessing(false), m_mainProcessing(false), m_shutdown(false),
+: q(q), m_threadProcessing(false), m_mainProcessing(false), m_shutdown(false),
m_mainThreadWaiting(false), mainSync(0), m_mainObject(this)
{
}
bool QQmlThreadPrivate::event(QEvent *e)
{
- if (e->type() == QEvent::User)
+ if (e->type() == QEvent::User)
threadEvent();
return QThread::event(e);
}
@@ -175,7 +175,7 @@ void QQmlThreadPrivate::mainEvent()
unlock();
}
-void QQmlThreadPrivate::threadEvent()
+void QQmlThreadPrivate::threadEvent()
{
lock();
diff --git a/src/qml/qml/ftw/qqmlthread_p.h b/src/qml/qml/ftw/qqmlthread_p.h
index 688fce6d5a..ee5996d9ef 100644
--- a/src/qml/qml/ftw/qqmlthread_p.h
+++ b/src/qml/qml/ftw/qqmlthread_p.h
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
class QThread;
class QQmlThreadPrivate;
-class QQmlThread
+class QQmlThread
{
public:
QQmlThread();
diff --git a/src/qml/qml/ftw/qrecursionwatcher_p.h b/src/qml/qml/ftw/qrecursionwatcher_p.h
index c6b3db38d4..8a8d6575da 100644
--- a/src/qml/qml/ftw/qrecursionwatcher_p.h
+++ b/src/qml/qml/ftw/qrecursionwatcher_p.h
@@ -76,7 +76,7 @@ private:
};
QRecursionNode::QRecursionNode()
-: _r(0)
+: _r(0)
{
}
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 641209d1f3..633953c81c 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -55,10 +55,10 @@
#define QML_DECLARE_TYPE(TYPE) \
Q_DECLARE_METATYPE(TYPE *) \
- Q_DECLARE_METATYPE(QQmlListProperty<TYPE>)
+ Q_DECLARE_METATYPE(QQmlListProperty<TYPE>)
#define QML_DECLARE_TYPE_HASMETATYPE(TYPE) \
- Q_DECLARE_METATYPE(QQmlListProperty<TYPE>)
+ Q_DECLARE_METATYPE(QQmlListProperty<TYPE>)
#define QML_DECLARE_INTERFACE(INTERFACE) \
QML_DECLARE_TYPE(INTERFACE)
@@ -109,7 +109,7 @@ int qmlRegisterType()
QML_GETTYPENAMES
QQmlPrivate::RegisterType type = {
- 0,
+ 0,
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
@@ -121,7 +121,7 @@ int qmlRegisterType()
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
- QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
+ QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
@@ -204,7 +204,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
QML_GETTYPENAMES
QQmlPrivate::RegisterType type = {
- 0,
+ 0,
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
@@ -216,7 +216,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
- QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
+ QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
@@ -298,7 +298,7 @@ int qmlRegisterExtendedType()
QML_GETTYPENAMES
QQmlPrivate::RegisterType type = {
- 0,
+ 0,
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
@@ -310,7 +310,7 @@ int qmlRegisterExtendedType()
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
- QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
+ QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
@@ -324,20 +324,20 @@ int qmlRegisterExtendedType()
}
template<typename T, typename E>
-int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
+int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
const char *qmlName)
{
QML_GETTYPENAMES
QQmlAttachedPropertiesFunc attached = QQmlPrivate::attachedPropertiesFunc<E>();
- const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
+ const QMetaObject * attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<E>();
if (!attached) {
attached = QQmlPrivate::attachedPropertiesFunc<T>();
attachedMetaObject = QQmlPrivate::attachedPropertiesMetaObject<T>();
}
QQmlPrivate::RegisterType type = {
- 0,
+ 0,
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
@@ -349,7 +349,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
attached,
attachedMetaObject,
- QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
+ QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
@@ -383,13 +383,13 @@ int qmlRegisterInterface(const char *typeName)
}
template<typename T>
-int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
+int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
const char *qmlName, QQmlCustomParser *parser)
{
QML_GETTYPENAMES
QQmlPrivate::RegisterType type = {
- 0,
+ 0,
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
@@ -401,7 +401,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
- QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
+ QQmlPrivate::StaticCastSelector<T,QQmlParserStatus>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
@@ -506,7 +506,7 @@ inline int qmlRegisterSingletonType(const QUrl &url, const char *uri, int versio
inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
{
- if (url.isRelative()) {
+ if (url.isRelative()) {
// User input check must go here, because QQmlPrivate::qmlregister is also used internally for composite types
qWarning("qmlRegisterType requires absolute URLs.");
return 0;
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 9e2fb07066..9b83feebb4 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -146,7 +146,8 @@ QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlConte
typeData->release();
}
- }
+ } else
+ code = scriptPrivate->script;
setNotifyOnValueChanged(true);
QQmlAbstractExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context));
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index bc56fe1f2d..d0476a92d4 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -54,7 +54,7 @@
#include <private/qv4debugservice_p.h>
#include "qqmlinfo.h"
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <QtCore/qstringbuilder.h>
#include <QtCore/qdebug.h>
diff --git a/src/qml/qml/qqmlcleanup.cpp b/src/qml/qml/qqmlcleanup.cpp
index 36f633c29f..94762d4fc7 100644
--- a/src/qml/qml/qqmlcleanup.cpp
+++ b/src/qml/qml/qqmlcleanup.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
/*!
\internal
\class QQmlCleanup
-\brief The QQmlCleanup provides a callback when a QQmlEngine is deleted.
+\brief The QQmlCleanup provides a callback when a QQmlEngine is deleted.
Any object that needs cleanup to occur before the QQmlEngine's V8 engine is
destroyed should inherit from QQmlCleanup. The clear() virtual method will be
@@ -111,7 +111,7 @@ QQmlCleanup::~QQmlCleanup()
if (prev) *prev = next;
if (next) next->prev = prev;
- prev = 0;
+ prev = 0;
next = 0;
}
diff --git a/src/qml/qml/qqmlcleanup_p.h b/src/qml/qml/qqmlcleanup_p.h
index 249ef97cc3..1f210ea7ce 100644
--- a/src/qml/qml/qqmlcleanup_p.h
+++ b/src/qml/qml/qqmlcleanup_p.h
@@ -44,7 +44,7 @@
#include <private/qtqmlglobal_p.h>
-//
+//
// W A R N I N G
// -------------
//
diff --git a/src/qml/qml/qqmlcompileddata.cpp b/src/qml/qml/qqmlcompileddata.cpp
index 76bf24fe6b..75740e17e6 100644
--- a/src/qml/qml/qqmlcompileddata.cpp
+++ b/src/qml/qml/qqmlcompileddata.cpp
@@ -88,7 +88,7 @@ int QQmlCompiledData::indexForUrl(const QUrl &data)
QQmlCompiledData::QQmlCompiledData(QQmlEngine *engine)
: engine(engine), importCache(0), metaTypeId(-1), listMetaTypeId(-1), isRegisteredWithEngine(false),
- rootPropertyCache(0), compilationUnit(0), qmlUnit(0)
+ rootPropertyCache(0), compilationUnit(0), qmlUnit(0), totalBindingsCount(0), totalParserStatusCount(0)
{
Q_ASSERT(engine);
@@ -117,15 +117,17 @@ QQmlCompiledData::~QQmlCompiledData()
types.at(ii).typePropertyCache->release();
}
- for (QHash<int, TypeReference>::Iterator resolvedType = resolvedTypes.begin(), end = resolvedTypes.end();
+ for (QHash<int, TypeReference*>::Iterator resolvedType = resolvedTypes.begin(), end = resolvedTypes.end();
resolvedType != end; ++resolvedType) {
- if (resolvedType->component)
- resolvedType->component->release();
- if (resolvedType->typePropertyCache)
- resolvedType->typePropertyCache->release();
+ if ((*resolvedType)->component)
+ (*resolvedType)->component->release();
+ if ((*resolvedType)->typePropertyCache)
+ (*resolvedType)->typePropertyCache->release();
}
+ qDeleteAll(resolvedTypes);
+ resolvedTypes.clear();
- for (int ii = 0; ii < propertyCaches.count(); ++ii)
+ for (int ii = 0; ii < propertyCaches.count(); ++ii)
if (propertyCaches.at(ii))
propertyCaches.at(ii)->release();
@@ -161,7 +163,7 @@ QQmlPropertyCache *QQmlCompiledData::TypeReference::propertyCache() const
/*!
Returns the property cache, creating one if it doesn't already exist. The cache is not referenced.
*/
-QQmlPropertyCache *QQmlCompiledData::TypeReference::createPropertyCache(QQmlEngine *engine)
+QQmlPropertyCache *QQmlCompiledData::TypeReference::createPropertyCache(QQmlEngine *engine)
{
if (typePropertyCache) {
return typePropertyCache;
@@ -232,13 +234,13 @@ int QQmlCompiledData::addInstructionHelper(QQmlInstruction::Type type, QQmlInstr
return ptrOffset;
}
-int QQmlCompiledData::nextInstructionIndex()
-{
+int QQmlCompiledData::nextInstructionIndex()
+{
return bytecode.size();
}
-QQmlInstruction *QQmlCompiledData::instruction(int index)
-{
+QQmlInstruction *QQmlCompiledData::instruction(int index)
+{
return (QQmlInstruction *)(bytecode.constData() + index);
}
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 71e803a4c8..9262e2a119 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -102,7 +102,7 @@ QQmlCompiler::QQmlCompiler(QQmlPool *pool)
: compileState(0), pool(pool), output(0), engine(0), enginePrivate(0), unitRoot(0), unit(0), cachedComponentTypeRef(-1),
cachedTranslationContextIndex(-1), componentStats(0)
{
- if (compilerStatDump())
+ if (compilerStatDump())
componentStats = pool->New<ComponentStats>();
}
@@ -1007,13 +1007,13 @@ bool QQmlCompiler::buildObject(QQmlScript::Object *obj, const BindingContext &ct
if (tr.type && obj->metatype->metaObject() == &QQmlComponent::staticMetaObject) {
COMPILE_CHECK(buildComponent(obj, ctxt));
return true;
- }
+ }
if (tr.component) {
- typedef QQmlInstruction I;
+ typedef QQmlInstruction I;
const I *init = ((const I *)tr.component->bytecode.constData());
Q_ASSERT(init && tr.component->instructionType(init) == QQmlInstruction::Init);
-
+
// Adjust stack depths to include nested components
compileState->objectDepth.pushPop(init->init.objectStackSize);
compileState->listDepth.pushPop(init->init.listStackSize);
@@ -1027,7 +1027,7 @@ bool QQmlCompiler::buildObject(QQmlScript::Object *obj, const BindingContext &ct
BindingContext objCtxt(obj);
// Create the synthesized meta object, ignoring aliases
- COMPILE_CHECK(checkDynamicMeta(obj));
+ COMPILE_CHECK(checkDynamicMeta(obj));
COMPILE_CHECK(mergeDynamicMetaProperties(obj));
COMPILE_CHECK(buildDynamicMeta(obj, Normal));
@@ -1058,7 +1058,7 @@ bool QQmlCompiler::buildObject(QQmlScript::Object *obj, const BindingContext &ct
}
}
- // Merge
+ // Merge
Property *defaultProperty = 0;
Property *skipProperty = 0;
if (obj->defaultProperty) {
@@ -1098,7 +1098,7 @@ bool QQmlCompiler::buildObject(QQmlScript::Object *obj, const BindingContext &ct
}
defaultProperty->values.insertAfter(insertPos, explicitProperty->values);
- }
+ }
}
QQmlCustomParser *cp = 0;
@@ -1316,9 +1316,9 @@ void QQmlCompiler::genObjectBody(QQmlScript::Object *obj)
Instruction::DeferInit dinit;
// XXX - these are now massive over allocations
dinit.bindingsSize = compileState->totalBindingsCount;
- dinit.parserStatusSize = compileState->parserStatusCount;
- dinit.objectStackSize = compileState->objectDepth.maxDepth();
- dinit.listStackSize = compileState->listDepth.maxDepth();
+ dinit.parserStatusSize = compileState->parserStatusCount;
+ dinit.objectStackSize = compileState->objectDepth.maxDepth();
+ dinit.listStackSize = compileState->listDepth.maxDepth();
output->addInstruction(dinit);
for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
@@ -1404,7 +1404,7 @@ void QQmlCompiler::genObjectBody(QQmlScript::Object *obj)
}
for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
- if (prop->isDeferred)
+ if (prop->isDeferred)
continue;
if (prop->isAlias)
genValueProperty(prop, obj);
@@ -1485,7 +1485,7 @@ void QQmlCompiler::genComponent(QQmlScript::Object *obj)
Instruction::Done done;
output->addInstruction(done);
- output->instruction(createInstruction)->createComponent.count =
+ output->instruction(createInstruction)->createComponent.count =
output->nextInstructionIndex() - nextInstructionIndex;
compileState = oldCompileState;
@@ -1516,12 +1516,12 @@ bool QQmlCompiler::buildComponent(QQmlScript::Object *obj,
if (obj->properties.isMany() ||
(obj->properties.isOne() && obj->properties.first()->name() != id_string))
COMPILE_EXCEPTION(obj->properties.first(), tr("Component elements may not contain properties other than id"));
-
+
if (!obj->properties.isEmpty())
idProp = obj->properties.first();
if (idProp) {
- if (idProp->value || idProp->values.isMany() || idProp->values.first()->object)
+ if (idProp->value || idProp->values.isMany() || idProp->values.first()->object)
COMPILE_EXCEPTION(idProp, tr("Invalid component id specification"));
COMPILE_CHECK(checkValidId(idProp->values.first(), idProp->values.first()->primitive()))
@@ -1791,7 +1791,7 @@ bool QQmlCompiler::buildProperty(QQmlScript::Property *prop,
QQmlScript::Object *obj,
const BindingContext &ctxt)
{
- if (prop->isEmpty())
+ if (prop->isEmpty())
COMPILE_EXCEPTION(prop, tr("Empty property assignment"));
if (isAttachedPropertyName(prop->name())) {
@@ -1809,7 +1809,7 @@ bool QQmlCompiler::buildProperty(QQmlScript::Property *prop,
unit->imports().resolveType(prop->name(), &type, 0, 0, &typeNamespace);
if (typeNamespace) {
- COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj,
+ COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj,
ctxt));
return true;
} else if (!type || !type->attachedPropertiesType()) {
@@ -1853,13 +1853,13 @@ bool QQmlCompiler::buildProperty(QQmlScript::Property *prop,
// We can't error here as the "id" property does not require a
// successful index resolution
- if (prop->index != -1)
+ if (prop->index != -1)
prop->type = prop->core.propType;
// Check if this is an alias
- if (prop->index != -1 &&
- prop->parent &&
- prop->parent->type != -1 &&
+ if (prop->index != -1 &&
+ prop->parent &&
+ prop->parent->type != -1 &&
output->types.at(prop->parent->type).component) {
QQmlPropertyCache *cache = output->types.at(prop->parent->type).component->rootPropertyCache;
@@ -1867,7 +1867,7 @@ bool QQmlCompiler::buildProperty(QQmlScript::Property *prop,
prop->isAlias = true;
}
- if (prop->index != -1 && !prop->values.isEmpty())
+ if (prop->index != -1 && !prop->values.isEmpty())
prop->parent->setBindingBit(prop->index);
}
@@ -1925,14 +1925,14 @@ bool QQmlCompiler::buildPropertyInNamespace(QQmlImportNamespace *ns,
for (Property *prop = nsProp->value->properties.first(); prop; prop = nsProp->value->properties.next(prop)) {
if (!isAttachedPropertyName(prop->name()))
- COMPILE_EXCEPTION(prop, tr("Not an attached property name"));
+ COMPILE_EXCEPTION(prop, tr("Expected type name"));
// Setup attached property data
QQmlType *type = 0;
unit->imports().resolveType(ns, prop->name(), &type, 0, 0);
- if (!type || !type->attachedPropertiesType())
+ if (!type || !type->attachedPropertiesType())
COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
if (!prop->value)
@@ -2132,7 +2132,7 @@ void QQmlCompiler::saveComponentState()
compileState->root->componentCompileState = compileState;
- if (componentStats)
+ if (componentStats)
componentStats->savedComponentStats.append(componentStats->componentStat);
}
@@ -2235,7 +2235,7 @@ bool QQmlCompiler::buildGroupedProperty(QQmlScript::Property *prop,
if (!prop->value->metatype)
COMPILE_EXCEPTION(prop, tr("Invalid grouped property access"));
- if (!prop->values.isEmpty())
+ if (!prop->values.isEmpty())
COMPILE_EXCEPTION(prop->values.first(), tr( "Cannot assign a value directly to a grouped property"));
obj->addGroupedProperty(prop);
@@ -2264,7 +2264,7 @@ bool QQmlCompiler::buildValueTypeProperty(QObject *type,
for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
QQmlPropertyData *d = property(obj, prop->name());
- if (d == 0)
+ if (d == 0)
COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name().toString()));
prop->index = d->coreIndex;
@@ -2312,7 +2312,7 @@ bool QQmlCompiler::buildValueTypeProperty(QObject *type,
for (Value *v = prop->onValues.first(); v; v = Property::ValueList::next(v)) {
Q_ASSERT(v->object);
- COMPILE_CHECK(buildPropertyOnAssignment(prop, obj, baseObj, v, ctxt));
+ COMPILE_CHECK(buildPropertyOnAssignment(prop, obj, baseObj, v, ctxt));
}
obj->addValueProperty(prop);
@@ -2324,7 +2324,7 @@ bool QQmlCompiler::buildValueTypeProperty(QObject *type,
}
// Build assignments to QML lists. QML lists are properties of type
-// QQmlListProperty<T>. List properties can accept a list of
+// QQmlListProperty<T>. List properties can accept a list of
// objects, or a single binding.
bool QQmlCompiler::buildListProperty(QQmlScript::Property *prop,
QQmlScript::Object *obj,
@@ -2377,7 +2377,7 @@ bool QQmlCompiler::buildScriptStringProperty(QQmlScript::Property *prop,
const BindingContext &ctxt)
{
if (prop->values.isMany())
- COMPILE_EXCEPTION(prop->values.first()->nextValue, tr( "Cannot assign multiple values to a script property"));
+ COMPILE_EXCEPTION(prop->values.first(), tr( "Cannot assign multiple values to a script property"));
if (prop->values.first()->object)
COMPILE_EXCEPTION(prop->values.first(), tr( "Invalid property assignment: script expected"));
@@ -2615,7 +2615,7 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
if (isIntProp) {
// Allow enum assignment to ints.
bool ok;
- int enumval = evaluateEnum(typeName, enumValue.toUtf8(), &ok);
+ int enumval = evaluateEnum(typeName.toString(), enumValue.toUtf8(), &ok);
if (ok) {
v->type = Value::Literal;
v->value = QQmlScript::Variant((double)enumval);
@@ -2666,46 +2666,14 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
return true;
}
-// Similar logic to above, but not knowing target property.
-int QQmlCompiler::evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue, bool *ok) const
-{
- Q_ASSERT_X(ok, "QQmlCompiler::evaluateEnum", "ok must not be a null pointer");
- *ok = false;
-
- if (scope != QLatin1String("Qt")) {
- QQmlType *type = 0;
- unit->imports().resolveType(scope, &type, 0, 0, 0);
- return type ? type->enumValue(QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1;
- }
-
- const QMetaObject *mo = StaticQtMetaObject::get();
- int i = mo->enumeratorCount();
- while (i--) {
- int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
- if (*ok)
- return v;
- }
- return -1;
-}
-
-const QMetaObject *QQmlCompiler::resolveType(const QString& name) const
-{
- QQmlType *qmltype = 0;
- if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0))
- return 0;
- if (!qmltype)
- return 0;
- return qmltype->metaObject();
-}
-
-int QQmlCompiler::bindingIdentifier(const QString &name, const Variant &value, const BindingContext &ctxt)
+QQmlBinding::Identifier QQmlCompiler::bindingIdentifier(const Variant &value, const QString &name, QQmlCustomParser *customParser)
{
JSBindingReference *reference = pool->New<JSBindingReference>();
reference->expression = value;
reference->property = pool->New<Property>();
reference->property->setName(name);
reference->value = 0;
- reference->bindingContext = ctxt;
+ reference->bindingContext = QQmlCompilerTypes::BindingContext(customParser->object);
reference->bindingContext.owner++;
// Unfortunately this is required for example for PropertyChanges where the bindings
// will be executed in the dynamic scope of the target, so we can't resolve any lookups
@@ -2753,7 +2721,7 @@ bool QQmlCompiler::checkDynamicMeta(QQmlScript::Object *obj)
}
if (propNames.testAndSet(prop.name.hash())) {
- for (Object::DynamicProperty *p2 = obj->dynamicProperties.first(); p2 != p;
+ for (Object::DynamicProperty *p2 = obj->dynamicProperties.first(); p2 != p;
p2 = obj->dynamicProperties.next(p2)) {
if (p2->name == prop.name) {
COMPILE_EXCEPTION_LOCATION(prop.nameLocation.line,
@@ -2831,7 +2799,7 @@ bool QQmlCompiler::mergeDynamicMetaProperties(QQmlScript::Object *obj)
property = obj->getDefaultProperty();
} else {
property = obj->getProperty(p->name);
- if (!property->values.isEmpty())
+ if (!property->values.isEmpty())
COMPILE_EXCEPTION(property, tr("Property value set multiple times"));
}
@@ -2883,7 +2851,7 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod
Object::DynamicProperty::Type dtype;
int metaType;
} builtinTypes[] = {
- { Object::DynamicProperty::Var, QMetaType::QVariant },
+ { Object::DynamicProperty::Var, qMetaTypeId<QJSValue>() },
{ Object::DynamicProperty::Variant, QMetaType::QVariant },
{ Object::DynamicProperty::Int, QMetaType::Int },
{ Object::DynamicProperty::Bool, QMetaType::Bool },
@@ -3488,7 +3456,7 @@ bool QQmlCompiler::buildBinding(QQmlScript::Value *value,
Q_ASSERT(prop->parent->metatype);
if (!prop->core.isWritable() && !prop->core.isQList() && !prop->isReadOnlyDeclaration)
- COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
+ COMPILE_EXCEPTION(value, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
JSBindingReference *reference = pool->New<JSBindingReference>();
reference->expression = value->value;
@@ -3653,7 +3621,7 @@ int QQmlCompiler::genContextCache()
}
QQmlPropertyData
-QQmlCompiler::genValueTypeData(QQmlScript::Property *valueTypeProp,
+QQmlCompiler::genValueTypeData(QQmlScript::Property *valueTypeProp,
QQmlScript::Property *prop)
{
QQmlValueType *vt = QQmlValueTypeFactory::valueType(prop->type);
@@ -3666,8 +3634,8 @@ bool QQmlCompiler::completeComponentBuild()
if (componentStats)
componentStats->componentStat.ids = compileState->ids.count();
- for (Object *aliasObject = compileState->aliasingObjects.first(); aliasObject;
- aliasObject = compileState->aliasingObjects.next(aliasObject))
+ for (Object *aliasObject = compileState->aliasingObjects.first(); aliasObject;
+ aliasObject = compileState->aliasingObjects.next(aliasObject))
COMPILE_CHECK(buildDynamicMetaAliases(aliasObject));
const QQmlScript::Parser &parser = unit->parser();
@@ -3917,7 +3885,7 @@ QQmlCompiler::signal(QQmlScript::Object *object, const QHashedStringRef &name, b
QHashedStringRef propName = name.mid(0, name.length() - Changed_string.length());
d = property(object, propName, notInRevision);
- if (d)
+ if (d)
return cache->signal(d->notifyIndex);
}
@@ -3925,20 +3893,20 @@ QQmlCompiler::signal(QQmlScript::Object *object, const QHashedStringRef &name, b
}
// This code must match the semantics of QQmlPropertyPrivate::findSignalByName
-int QQmlCompiler::indexOfSignal(QQmlScript::Object *object, const QString &name,
+int QQmlCompiler::indexOfSignal(QQmlScript::Object *object, const QString &name,
bool *notInRevision)
{
QQmlPropertyData *d = signal(object, QStringRef(&name), notInRevision);
return d?d->coreIndex:-1;
}
-int QQmlCompiler::indexOfProperty(QQmlScript::Object *object, const QString &name,
+int QQmlCompiler::indexOfProperty(QQmlScript::Object *object, const QString &name,
bool *notInRevision)
{
return indexOfProperty(object, QStringRef(&name), notInRevision);
}
-int QQmlCompiler::indexOfProperty(QQmlScript::Object *object, const QHashedStringRef &name,
+int QQmlCompiler::indexOfProperty(QQmlScript::Object *object, const QHashedStringRef &name,
bool *notInRevision)
{
QQmlPropertyData *d = property(object, name, notInRevision);
diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h
index 516f6653ca..2ce850da5d 100644
--- a/src/qml/qml/qqmlcompiler_p.h
+++ b/src/qml/qml/qqmlcompiler_p.h
@@ -65,6 +65,7 @@
#include <private/qqmlcodegenerator_p.h>
#include "private/qv4identifier_p.h"
#include <private/qqmljsastfwd_p.h>
+#include "qqmlcustomparser_p.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qset.h>
@@ -84,6 +85,7 @@ class QQmlComponent;
class QQmlContext;
class QQmlContextData;
+// ### Merge with QV4::CompiledData::CompilationUnit
class Q_AUTOTEST_EXPORT QQmlCompiledData : public QQmlRefCount, public QQmlCleanup
{
public:
@@ -100,7 +102,7 @@ public:
int listMetaTypeId;
bool isRegisteredWithEngine;
- struct TypeReference
+ struct TypeReference
{
TypeReference()
: type(0), typePropertyCache(0), component(0)
@@ -128,7 +130,7 @@ public:
QList<TypeReference> types;
// --- new compiler:
// map from name index
- QHash<int, TypeReference> resolvedTypes;
+ QHash<int, TypeReference*> resolvedTypes;
// ---
struct V8Program {
@@ -144,9 +146,9 @@ public:
QQmlPropertyCache *rootPropertyCache;
QList<QString> primitives;
- QList<QByteArray> datas;
+ QVector<QByteArray> datas;
QByteArray bytecode;
- QList<QQmlPropertyCache *> propertyCaches;
+ QVector<QQmlPropertyCache *> propertyCaches;
QList<QVector<QQmlContextData::ObjectIdMapping> > contextCaches;
QList<QQmlScriptData *> scripts;
QList<QUrl> urls;
@@ -157,7 +159,11 @@ public:
// index in first hash is component index, hash inside maps from object index in that scope to integer id
QHash<int, QHash<int, int> > objectIndexToIdPerComponent;
QHash<int, int> objectIndexToIdForRoot;
+ // hash key is object index
+ QHash<int, QByteArray> customParserData;
QVector<int> customParserBindings; // index is binding identifier, value is compiled function index.
+ int totalBindingsCount; // Number of bindings used in this type
+ int totalParserStatusCount; // Number of instantiated types that are QQmlParserStatus subclasses
bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); }
bool isCompositeType() const { return !datas.at(qmlUnit->indexOfRootObject).isEmpty(); }
@@ -205,7 +211,7 @@ private:
};
namespace QQmlCompilerTypes {
- struct BindingContext
+ struct BindingContext
{
BindingContext()
: stack(0), owner(0), object(0) {}
@@ -255,7 +261,7 @@ namespace QQmlCompilerTypes {
int n;
};
- struct IdList : public QFieldList<QQmlScript::Object,
+ struct IdList : public QFieldList<QQmlScript::Object,
&QQmlScript::Object::nextIdObject>
{
QQmlScript::Object *value(const QString &id) const {
@@ -289,8 +295,8 @@ namespace QQmlCompilerTypes {
// more than one of these for each compile
struct ComponentCompileState : public QQmlPool::Class
{
- ComponentCompileState()
- : parserStatusCount(0), totalBindingsCount(0), pushedProperties(0), nested(false),
+ ComponentCompileState()
+ : parserStatusCount(0), totalBindingsCount(0), pushedProperties(0), nested(false),
root(0) {}
IdList ids;
@@ -330,7 +336,7 @@ namespace QQmlCompilerTypes {
};
class QMetaObjectBuilder;
-class Q_AUTOTEST_EXPORT QQmlCompiler
+class Q_AUTOTEST_EXPORT QQmlCompiler : public QQmlCustomParserCompilerBackend
{
Q_DECLARE_TR_FUNCTIONS(QQmlCompiler)
public:
@@ -346,9 +352,9 @@ public:
static bool isAttachedPropertyName(const QHashedStringRef &);
static bool isSignalPropertyName(const QHashedStringRef &);
- int evaluateEnum(const QHashedStringRef &scope, const QByteArray& enumValue, bool *ok) const; // for QQmlCustomParser::evaluateEnum
- const QMetaObject *resolveType(const QString& name) const; // for QQmlCustomParser::resolveType
- int bindingIdentifier(const QString &name, const QQmlScript::Variant& value, const QQmlCompilerTypes::BindingContext &ctxt); // for QQmlCustomParser::bindingIndex
+ virtual QQmlBinding::Identifier bindingIdentifier(const QQmlScript::Variant&value, const QString&name, QQmlCustomParser *customParser);
+
+ virtual const QQmlImports &imports() const { return unit->imports(); }
private:
typedef QQmlCompiledData::Instruction Instruction;
@@ -361,23 +367,23 @@ private:
bool buildObject(QQmlScript::Object *obj, const QQmlCompilerTypes::BindingContext &);
bool buildComponent(QQmlScript::Object *obj, const QQmlCompilerTypes::BindingContext &);
bool buildSubObject(QQmlScript::Object *obj, const QQmlCompilerTypes::BindingContext &);
- bool buildSignal(QQmlScript::Property *prop, QQmlScript::Object *obj,
+ bool buildSignal(QQmlScript::Property *prop, QQmlScript::Object *obj,
const QQmlCompilerTypes::BindingContext &);
- bool buildProperty(QQmlScript::Property *prop, QQmlScript::Object *obj,
+ bool buildProperty(QQmlScript::Property *prop, QQmlScript::Object *obj,
const QQmlCompilerTypes::BindingContext &);
bool buildPropertyInNamespace(QQmlImportNamespace *ns,
- QQmlScript::Property *prop,
- QQmlScript::Object *obj,
+ QQmlScript::Property *prop,
+ QQmlScript::Object *obj,
const QQmlCompilerTypes::BindingContext &);
bool buildIdProperty(QQmlScript::Property *prop, QQmlScript::Object *obj);
- bool buildAttachedProperty(QQmlScript::Property *prop,
+ bool buildAttachedProperty(QQmlScript::Property *prop,
QQmlScript::Object *obj,
const QQmlCompilerTypes::BindingContext &ctxt);
bool buildGroupedProperty(QQmlScript::Property *prop,
QQmlScript::Object *obj,
const QQmlCompilerTypes::BindingContext &ctxt);
- bool buildValueTypeProperty(QObject *type,
- QQmlScript::Object *obj,
+ bool buildValueTypeProperty(QObject *type,
+ QQmlScript::Object *obj,
QQmlScript::Object *baseObj,
const QQmlCompilerTypes::BindingContext &ctxt);
bool buildListProperty(QQmlScript::Property *prop,
@@ -429,13 +435,13 @@ private:
void genComponent(QQmlScript::Object *obj);
void genValueProperty(QQmlScript::Property *prop, QQmlScript::Object *obj);
void genListProperty(QQmlScript::Property *prop, QQmlScript::Object *obj);
- void genPropertyAssignment(QQmlScript::Property *prop,
+ void genPropertyAssignment(QQmlScript::Property *prop,
QQmlScript::Object *obj,
QQmlScript::Property *valueTypeProperty = 0);
void genLiteralAssignment(QQmlScript::Property *prop,
QQmlScript::Value *value);
- void genBindingAssignment(QQmlScript::Value *binding,
- QQmlScript::Property *prop,
+ void genBindingAssignment(QQmlScript::Value *binding,
+ QQmlScript::Property *prop,
QQmlScript::Object *obj,
QQmlScript::Property *valueTypeProperty = 0);
int genContextCache();
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 21bcd3569c..6abf805a4a 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -862,7 +862,7 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
enginePriv->referenceScarceResources();
QObject *rv = 0;
if (enginePriv->useNewCompiler) {
- state.creator = new QmlObjectCreator(context, cc);
+ state.creator = new QmlObjectCreator(context, cc, creationContext);
rv = state.creator->create(start);
if (!rv)
state.errors = state.creator->errors;
@@ -914,7 +914,8 @@ void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionS
{
if (state->completePending) {
if (enginePriv->useNewCompiler) {
- state->creator->finalize();
+ QQmlInstantiationInterrupt interrupt;
+ state->creator->finalize(interrupt);
} else {
state->vme.complete();
}
@@ -991,7 +992,7 @@ QQmlComponentAttached *QQmlComponent::qmlAttachedProperties(QObject *obj)
if (p->activeVME) { // XXX should only be allowed during begin
a->add(&p->activeVME->componentAttached);
} else if (p->activeObjectCreator) {
- a->add(&p->activeObjectCreator->componentAttached);
+ a->add(p->activeObjectCreator->componentAttached);
} else {
QQmlData *d = QQmlData::get(obj);
Q_ASSERT(d);
@@ -1056,7 +1057,11 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context,
p->compiledData = d->cc;
p->compiledData->addref();
- p->vme.init(contextData, d->cc, d->start, d->creationContext);
+ if (enginePriv->useNewCompiler) {
+ p->creator.reset(new QmlObjectCreator(contextData, d->cc, d->creationContext));
+ p->subComponentToCreate = d->start;
+ } else
+ p->vme.init(contextData, d->cc, d->start, d->creationContext);
enginePriv->incubate(incubator, forContextData);
}
@@ -1065,7 +1070,7 @@ class QQmlComponentIncubator;
class QmlIncubatorObject : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
public:
QmlIncubatorObject(QV8Engine *engine, QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous);
@@ -1081,15 +1086,15 @@ public:
QScopedPointer<QQmlComponentIncubator> incubator;
QV8Engine *v8;
QPointer<QObject> parent;
- QV4::SafeValue valuemap;
- QV4::SafeValue qmlGlobal;
- QV4::SafeValue m_statusChanged;
+ QV4::Value valuemap;
+ QV4::Value qmlGlobal;
+ QV4::Value m_statusChanged;
void statusChanged(QQmlIncubator::Status);
void setInitialState(QObject *);
};
-DEFINE_MANAGED_VTABLE(QmlIncubatorObject);
+DEFINE_OBJECT_VTABLE(QmlIncubatorObject);
class QQmlComponentIncubator : public QQmlIncubator
{
@@ -1463,7 +1468,7 @@ QmlIncubatorObject::QmlIncubatorObject(QV8Engine *engine, QQmlIncubator::Incubat
{
incubator.reset(new QQmlComponentIncubator(this, m));
v8 = engine;
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
valuemap = QV4::Primitive::undefinedValue();
qmlGlobal = QV4::Primitive::undefinedValue();
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 8bf4005dd6..7e855fdfd0 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -81,7 +81,7 @@ class QQmlComponentAttached;
class Q_QML_PRIVATE_EXPORT QQmlComponentPrivate : public QObjectPrivate, public QQmlTypeData::TypeDataCallback
{
Q_DECLARE_PUBLIC(QQmlComponent)
-
+
public:
QQmlComponentPrivate()
: typeData(0), progress(0.), start(-1), cc(0), engine(0), creationContext(0), depthIncreased(false) {}
@@ -95,7 +95,7 @@ public:
QQmlTypeData *typeData;
virtual void typeDataReady(QQmlTypeData *);
virtual void typeDataProgress(QQmlTypeData *, qreal);
-
+
void fromTypeData(QQmlTypeData *data);
QUrl url;
@@ -124,7 +124,7 @@ public:
};
ConstructionState state;
- static void beginDeferred(QQmlEnginePrivate *enginePriv, QObject *object,
+ static void beginDeferred(QQmlEnginePrivate *enginePriv, QObject *object,
ConstructionState *state);
static void complete(QQmlEnginePrivate *enginePriv, ConstructionState *state);
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 78e6650d02..7b1ba46db2 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -403,7 +403,7 @@ QVariant QQmlContext::contextProperty(const QString &name) const
}
/*!
-Returns the name of \a object in this context, or an empty string if \a object
+Returns the name of \a object in this context, or an empty string if \a object
is not named in the context. Objects are named by setContextProperty(), or by ids in
the case of QML created contexts.
@@ -521,7 +521,7 @@ QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, int ind
QQmlContextData::QQmlContextData()
-: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
+: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false),
publicContext(0), activeVMEData(0),
contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0),
@@ -531,7 +531,7 @@ QQmlContextData::QQmlContextData()
}
QQmlContextData::QQmlContextData(QQmlContext *ctxt)
-: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
+: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false),
publicContext(ctxt), activeVMEData(0),
contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0),
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index 26048b0217..464bee82c0 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -134,7 +134,7 @@ public:
QUrl resolvedUrl(const QUrl &);
- // My containing QQmlContext. If isInternal is true this owns publicContext.
+ // My containing QQmlContext. If isInternal is true this owns publicContext.
// If internal is false publicContext owns this.
QQmlContext *asQQmlContext();
QQmlContextPrivate *asQQmlContextPrivate();
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index b3c2105e68..1ca9c6ac12 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -46,7 +46,7 @@
#include <private/qqmlcontext_p.h>
#include <private/qv4engine_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4objectproto_p.h>
#include <private/qv4mm_p.h>
#include <private/qv4function_p.h>
@@ -59,14 +59,14 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-DEFINE_MANAGED_VTABLE(QmlContextWrapper);
+DEFINE_OBJECT_VTABLE(QmlContextWrapper);
QmlContextWrapper::QmlContextWrapper(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext)
: Object(QV8Engine::getV4(engine)),
v8(engine), readOnly(true), ownsContext(ownsContext), isNullWrapper(false),
context(context), scopeObject(scopeObject), idObjectsWrapper(0)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
QmlContextWrapper::~QmlContextWrapper()
@@ -433,13 +433,13 @@ ReturnedValue QmlContextWrapper::qmlSingletonWrapper(const StringRef &name)
return QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine());
}
-DEFINE_MANAGED_VTABLE(QQmlIdObjectsArray);
+DEFINE_OBJECT_VTABLE(QQmlIdObjectsArray);
QQmlIdObjectsArray::QQmlIdObjectsArray(ExecutionEngine *engine, QmlContextWrapper *contextWrapper)
: Object(engine)
, contextWrapper(contextWrapper)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
ReturnedValue QQmlIdObjectsArray::getIndexed(Managed *m, uint index, bool *hasProperty)
diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h
index 89ace7090c..0ecec93652 100644
--- a/src/qml/qml/qqmlcontextwrapper_p.h
+++ b/src/qml/qml/qqmlcontextwrapper_p.h
@@ -56,7 +56,7 @@
#include <QtCore/qglobal.h>
#include <private/qtqmlglobal_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4object_p.h>
#include <private/qqmlcontext_p.h>
#include <private/qv4functionobject_p.h>
@@ -73,7 +73,7 @@ struct QQmlIdObjectsArray;
struct Q_QML_EXPORT QmlContextWrapper : Object
{
- Q_MANAGED
+ V4_OBJECT
QmlContextWrapper(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext = false);
~QmlContextWrapper();
@@ -112,7 +112,7 @@ private:
struct QQmlIdObjectsArray : public Object
{
- Q_MANAGED
+ V4_OBJECT
QQmlIdObjectsArray(ExecutionEngine *engine, QmlContextWrapper *contextWrapper);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index 19e49009ce..004d9f435a 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -93,7 +93,7 @@ using namespace QQmlScript;
The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
*/
-QQmlCustomParserNode
+QQmlCustomParserNode
QQmlCustomParserNodePrivate::fromObject(QQmlScript::Object *root)
{
QQmlCustomParserNode rootNode;
@@ -111,7 +111,7 @@ QQmlCustomParserNodePrivate::fromObject(QQmlScript::Object *root)
return rootNode;
}
-QQmlCustomParserProperty
+QQmlCustomParserProperty
QQmlCustomParserNodePrivate::fromProperty(QQmlScript::Property *p)
{
QQmlCustomParserProperty prop;
@@ -256,7 +256,6 @@ void QQmlCustomParser::error(const QString& description)
void QQmlCustomParser::error(const QQmlCustomParserProperty& prop, const QString& description)
{
QQmlError error;
- QString exceptionDescription;
error.setLine(prop.location().line);
error.setColumn(prop.location().column);
error.setDescription(description);
@@ -271,7 +270,6 @@ void QQmlCustomParser::error(const QQmlCustomParserProperty& prop, const QString
void QQmlCustomParser::error(const QQmlCustomParserNode& node, const QString& description)
{
QQmlError error;
- QString exceptionDescription;
error.setLine(node.location().line);
error.setColumn(node.location().column);
error.setDescription(description);
@@ -279,6 +277,34 @@ void QQmlCustomParser::error(const QQmlCustomParserNode& node, const QString& de
}
/*!
+ Reports an error in parsing \a binding, with the given \a description.
+
+ An error is generated referring to the position of \a node in the source file.
+*/
+void QQmlCustomParser::error(const QV4::CompiledData::Binding *binding, const QString &description)
+{
+ QQmlError error;
+ error.setLine(binding->location.line);
+ error.setColumn(binding->location.column);
+ error.setDescription(description);
+ exceptions << error;
+}
+
+/*!
+ Reports an error in parsing \a object, with the given \a description.
+
+ An error is generated referring to the position of \a object in the source file.
+*/
+void QQmlCustomParser::error(const QV4::CompiledData::Object *object, const QString &description)
+{
+ QQmlError error;
+ error.setLine(object->location.line);
+ error.setColumn(object->location.column);
+ error.setDescription(description);
+ exceptions << error;
+}
+
+/*!
If \a script is a simple enumeration expression (eg. Text.AlignLeft),
returns the integer equivalent (eg. 1), and sets \a ok to true.
@@ -313,7 +339,54 @@ const QMetaObject *QQmlCustomParser::resolveType(const QString& name) const
*/
QQmlBinding::Identifier QQmlCustomParser::bindingIdentifier(const QQmlScript::Variant &value, const QString& name)
{
- return compiler->bindingIdentifier(name, value, QQmlCompilerTypes::BindingContext(object));
+ return compiler->bindingIdentifier(value, name, this);
+}
+
+QQmlBinding::Identifier QQmlCustomParser::bindingIdentifier(const QV4::CompiledData::Binding *binding)
+{
+ return compiler->bindingIdentifier(binding, this);
+}
+
+AST::Node *QQmlCustomParser::astForBinding(int scriptIndex) const
+{
+ return compiler->astForBinding(scriptIndex);
+}
+
+struct StaticQtMetaObject : public QObject
+{
+ static const QMetaObject *get()
+ { return &staticQtMetaObject; }
+};
+
+int QQmlCustomParserCompilerBackend::evaluateEnum(const QString &scope, const QByteArray &enumValue, bool *ok) const
+{
+ Q_ASSERT_X(ok, "QQmlCompiler::evaluateEnum", "ok must not be a null pointer");
+ *ok = false;
+
+ if (scope != QLatin1String("Qt")) {
+ QQmlType *type = 0;
+ imports().resolveType(scope, &type, 0, 0, 0);
+ return type ? type->enumValue(QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1;
+ }
+
+ const QMetaObject *mo = StaticQtMetaObject::get();
+ int i = mo->enumeratorCount();
+ while (i--) {
+ int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
+ if (*ok)
+ return v;
+ }
+ return -1;
+}
+
+const QMetaObject *QQmlCustomParserCompilerBackend::resolveType(const QString &name) const
+{
+ QQmlType *qmltype = 0;
+ if (!imports().resolveType(name, &qmltype, 0, 0, 0))
+ return 0;
+ if (!qmltype)
+ return 0;
+ return qmltype->metaObject();
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index 27f7e00b31..b406717410 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -79,7 +79,7 @@ public:
QQmlScript::Location location() const;
bool isList() const;
- // Will be one of QQmlScript::Variant, QQmlCustomParserProperty or
+ // Will be one of QQmlScript::Variant, QQmlCustomParserProperty or
// QQmlCustomParserNode
QList<QVariant> assignedValues() const;
@@ -108,6 +108,20 @@ private:
QQmlCustomParserNodePrivate *d;
};
+struct QQmlCustomParserCompilerBackend
+{
+ virtual ~QQmlCustomParserCompilerBackend() {}
+ virtual const QQmlImports &imports() const = 0;
+
+ int evaluateEnum(const QString &scope, const QByteArray& enumValue, bool *ok) const;
+ const QMetaObject *resolveType(const QString& name) const;
+
+ virtual QQmlBinding::Identifier bindingIdentifier(const QQmlScript::Variant&, const QString&, QQmlCustomParser *) { return QQmlBinding::Invalid; }
+ virtual QQmlBinding::Identifier bindingIdentifier(const QV4::CompiledData::Binding *, QQmlCustomParser *) { return QQmlBinding::Invalid; }
+
+ virtual QQmlJS::AST::Node *astForBinding(int) const { return 0; }
+};
+
class Q_QML_PRIVATE_EXPORT QQmlCustomParser
{
public:
@@ -126,6 +140,7 @@ public:
Flags flags() const { return m_flags; }
virtual QByteArray compile(const QList<QQmlCustomParserProperty> &)=0;
+ virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings) = 0;
virtual void setCustomData(QObject *, const QByteArray &)=0;
QList<QQmlError> errors() const { return exceptions; }
@@ -134,19 +149,25 @@ protected:
void error(const QString& description);
void error(const QQmlCustomParserProperty&, const QString& description);
void error(const QQmlCustomParserNode&, const QString& description);
+ void error(const QV4::CompiledData::Binding *binding, const QString& description);
+ void error(const QV4::CompiledData::Object *object, const QString& description);
int evaluateEnum(const QByteArray&, bool *ok) const;
const QMetaObject *resolveType(const QString&) const;
QQmlBinding::Identifier bindingIdentifier(const QQmlScript::Variant&, const QString&);
+ QQmlBinding::Identifier bindingIdentifier(const QV4::CompiledData::Binding *binding);
+
+ QQmlJS::AST::Node *astForBinding(int scriptIndex) const;
private:
QList<QQmlError> exceptions;
- QQmlCompiler *compiler;
+ QQmlCustomParserCompilerBackend *compiler;
QQmlScript::Object *object;
Flags m_flags;
friend class QQmlCompiler;
+ friend class QQmlPropertyValidator;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlCustomParser::Flags)
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index 982156ea15..93060e97fb 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -56,7 +56,8 @@
#include <private/qtqmlglobal_p.h>
#include <private/qobject_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
+#include <private/qv4persistent_p.h>
QT_BEGIN_NAMESPACE
@@ -143,7 +144,7 @@ public:
void layout(QQmlNotifierEndpoint*);
};
NotifyList *notifyList;
-
+
inline QQmlNotifierEndpoint *notify(int index);
void addNotify(int index, QQmlNotifierEndpoint *);
int endpointCount(int index);
@@ -151,7 +152,7 @@ public:
void disconnectNotifiers();
// The context that created the C++ object
- QQmlContextData *context;
+ QQmlContextData *context;
// The outermost context in which this object lives
QQmlContextData *outerContext;
@@ -163,7 +164,7 @@ public:
QQmlData**prevContextObject;
int bindingBitsSize;
- quint32 *bindingBits;
+ quint32 *bindingBits;
inline bool hasBindingBit(int) const;
void clearBindingBit(int);
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index acc66c8ce5..68d021b5cb 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -62,12 +62,14 @@
#include "qqmllist_p.h"
#include "qqmltypenamecache_p.h"
#include "qqmlnotifier_p.h"
+#include <private/qqmldebugserver_p.h>
#include <private/qqmlprofilerservice_p.h>
#include <private/qv4debugservice_p.h>
#include <private/qdebugmessageservice_p.h>
+#include <private/qqmlenginecontrolservice_p.h>
#include "qqmlincubator.h"
#include "qqmlabstracturlinterceptor.h"
-#include <private/qv8profilerservice_p.h>
+#include <private/qv4profilerservice_p.h>
#include <private/qqmlboundsignal_p.h>
#include <QtCore/qstandardpaths.h>
@@ -107,7 +109,7 @@
#include <qlibrary.h>
#include <windows.h>
-#define CSIDL_APPDATA 0x001a // <username>\Application Data
+#define CSIDL_APPDATA 0x001a // <username>\Application Data
#endif
Q_DECLARE_METATYPE(QQmlProperty)
@@ -813,11 +815,13 @@ void QQmlEnginePrivate::init()
if (QCoreApplication::instance()->thread() == q->thread() &&
QQmlEngineDebugService::isDebuggingEnabled()) {
isDebugging = true;
- QQmlEngineDebugService::instance()->addEngine(q);
- QV4DebugService::instance()->addEngine(q);
- QV8ProfilerService::initialize();
- QQmlProfilerService::initialize();
+ QQmlEngineDebugService::instance();
+ QV4DebugService::instance();
+ QV4ProfilerService::instance();
+ QQmlProfilerService::instance();
QDebugMessageService::instance();
+ QQmlEngineControlService::instance();
+ QQmlDebugServer::instance()->addEngine(q);
}
}
@@ -895,10 +899,8 @@ QQmlEngine::QQmlEngine(QQmlEnginePrivate &dd, QObject *parent)
QQmlEngine::~QQmlEngine()
{
Q_D(QQmlEngine);
- if (d->isDebugging) {
- QQmlEngineDebugService::instance()->remEngine(this);
- QV4DebugService::instance()->removeEngine(this);
- }
+ if (d->isDebugging)
+ QQmlDebugServer::instance()->removeEngine(this);
// Emit onDestruction signals for the root context before
// we destroy the contexts, engine, Singleton Types etc. that
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 19eb320fbe..e292dbf6c0 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -271,16 +271,16 @@ public:
mutable QMutex mutex;
private:
- // Locker locks the QQmlEnginePrivate data structures for read and write, if necessary.
- // Currently, locking is only necessary if the threaded loader is running concurrently. If it is
+ // Locker locks the QQmlEnginePrivate data structures for read and write, if necessary.
+ // Currently, locking is only necessary if the threaded loader is running concurrently. If it is
// either idle, or is running with the main thread blocked, no locking is necessary. This way
// we only pay for locking when we have to.
- // Consequently, this class should only be used to protect simple accesses or modifications of the
+ // Consequently, this class should only be used to protect simple accesses or modifications of the
// QQmlEnginePrivate structures or operations that can be guaranteed not to start activity
// on the loader thread.
- // The Locker API is identical to QMutexLocker. Locker reuses the QQmlEnginePrivate::mutex
+ // The Locker API is identical to QMutexLocker. Locker reuses the QQmlEnginePrivate::mutex
// QMutex instance and multiple Lockers are recursive in the same thread.
- class Locker
+ class Locker
{
public:
inline Locker(const QQmlEngine *);
@@ -333,7 +333,7 @@ QQmlEnginePrivate::Locker::~Locker()
void QQmlEnginePrivate::Locker::unlock()
{
- if (m_locked) {
+ if (m_locked) {
m_ep->mutex.unlock();
m_locked = false;
}
@@ -373,7 +373,7 @@ thread, \a value will be deleted immediately.
This method should be used for *any* type that has resources that need to
be freed in the engine thread. This is generally types that use V8 handles.
As there is some small overhead in checking the current thread, it is best
-practice to check if any V8 handles actually need to be freed and delete
+practice to check if any V8 handles actually need to be freed and delete
the instance directly if not.
*/
template<typename T>
@@ -384,7 +384,7 @@ void QQmlEnginePrivate::deleteInEngineThread(T *value)
Q_ASSERT(value);
if (isEngineThread()) {
delete value;
- } else {
+ } else {
struct I : public Deletable {
I(T *value) : value(value) {}
~I() { delete value; }
@@ -420,10 +420,10 @@ is returned.
The returned cache is not referenced, so if it is to be stored, call addref().
XXX thread There is a potential future race condition in this and all the cache()
-functions. As the QQmlPropertyCache is returned unreferenced, when called
-from the loader thread, it is possible that the cache will have been dereferenced
+functions. As the QQmlPropertyCache is returned unreferenced, when called
+from the loader thread, it is possible that the cache will have been dereferenced
and deleted before the loader thread has a chance to use or reference it. This
-can't currently happen as the cache holds a reference to the
+can't currently happen as the cache holds a reference to the
QQmlPropertyCache until the QQmlEngine is destroyed.
*/
QQmlPropertyCache *QQmlEnginePrivate::cache(QObject *obj)
@@ -475,8 +475,8 @@ QQmlPropertyCache *QQmlEnginePrivate::cache(QQmlType *type, int minorVersion, QQ
return rv;
}
-QV8Engine *QQmlEnginePrivate::getV8Engine(QQmlEngine *e)
-{
+QV8Engine *QQmlEnginePrivate::getV8Engine(QQmlEngine *e)
+{
Q_ASSERT(e);
return e->d_func()->v8engine();
@@ -489,32 +489,32 @@ QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e)
return e->d_func()->v4engine();
}
-QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlEngine *e)
-{
+QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlEngine *e)
+{
Q_ASSERT(e);
return e->d_func();
}
-const QQmlEnginePrivate *QQmlEnginePrivate::get(const QQmlEngine *e)
-{
+const QQmlEnginePrivate *QQmlEnginePrivate::get(const QQmlEngine *e)
+{
Q_ASSERT(e);
return e->d_func();
}
-QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlContext *c)
-{
- return (c && c->engine()) ? QQmlEnginePrivate::get(c->engine()) : 0;
+QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlContext *c)
+{
+ return (c && c->engine()) ? QQmlEnginePrivate::get(c->engine()) : 0;
}
-QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlContextData *c)
-{
- return (c && c->engine) ? QQmlEnginePrivate::get(c->engine) : 0;
+QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlContextData *c)
+{
+ return (c && c->engine) ? QQmlEnginePrivate::get(c->engine) : 0;
}
-QQmlEngine *QQmlEnginePrivate::get(QQmlEnginePrivate *p)
-{
+QQmlEngine *QQmlEnginePrivate::get(QQmlEnginePrivate *p)
+{
Q_ASSERT(p);
return p->q_func();
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index ad95ecdf06..c583156c43 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -131,7 +131,7 @@ QQmlError &QQmlError::operator=(const QQmlError &other)
}
/*!
- \internal
+ \internal
*/
QQmlError::~QQmlError()
{
@@ -297,7 +297,7 @@ QDebug operator<<(QDebug debug, const QQmlError &error)
if(error.column() > 0) {
int column = qMax(0, error.column() - 1);
- column = qMin(column, line.length());
+ column = qMin(column, line.length());
QByteArray ind;
ind.reserve(column);
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 7b968a7e46..eca13e8fb8 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -193,14 +193,14 @@ struct QQmlGraphics_DerivedObject : public QObject
};
/*!
- Returns true if the case of \a fileName is equivalent to the file case of
+ Returns true if the case of \a fileName is equivalent to the file case of
\a fileName on disk, and false otherwise.
- This is used to ensure that the behavior of QML on a case-insensitive file
- system is the same as on a case-sensitive file system. This function
- performs a "best effort" attempt to determine the real case of the file.
+ This is used to ensure that the behavior of QML on a case-insensitive file
+ system is the same as on a case-sensitive file system. This function
+ performs a "best effort" attempt to determine the real case of the file.
It may have false positives (say the case is correct when it isn't), but it
- should never have a false negative (say the case is incorrect when it is
+ should never have a false negative (say the case is incorrect when it is
correct).
Length specifies specifies the number of characters to be checked from
diff --git a/src/qml/qml/qqmlguard_p.h b/src/qml/qml/qqmlguard_p.h
index 455f5c93a8..b2e0949c74 100644
--- a/src/qml/qml/qqmlguard_p.h
+++ b/src/qml/qml/qqmlguard_p.h
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
-class QQmlGuardImpl
+class QQmlGuardImpl
{
public:
inline QQmlGuardImpl();
@@ -91,7 +91,7 @@ public:
inline T *object() const;
inline void setObject(T *g);
-
+
inline bool isNull() const
{ return !o; }
@@ -141,7 +141,7 @@ void QQmlGuardImpl::addGuard()
{
Q_ASSERT(!prev);
- if (QObjectPrivate::get(o)->wasDeleted)
+ if (QObjectPrivate::get(o)->wasDeleted)
return;
QQmlData *data = QQmlData::get(o, true);
@@ -198,13 +198,13 @@ QQmlGuard<T> &QQmlGuard<T>::operator=(T *g)
}
template<class T>
-T *QQmlGuard<T>::object() const
-{
- return static_cast<T *>(o);
+T *QQmlGuard<T>::object() const
+{
+ return static_cast<T *>(o);
}
template<class T>
-void QQmlGuard<T>::setObject(T *g)
+void QQmlGuard<T>::setObject(T *g)
{
if (g != o) {
if (prev) remGuard();
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 8645d2116a..97f82a2e8d 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -180,17 +180,22 @@ struct RegisteredPlugin {
QPluginLoader* loader;
};
-typedef QMap<QString, RegisteredPlugin> StringRegisteredPluginMap;
+struct StringRegisteredPluginMap : public QMap<QString, RegisteredPlugin> {
+ QMutex mutex;
+};
+
Q_GLOBAL_STATIC(StringRegisteredPluginMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri and the PluginLoaders
void qmlClearEnginePlugins()
{
- foreach (RegisteredPlugin plugin, qmlEnginePluginsWithRegisteredTypes()->values()) {
+ StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
+ QMutexLocker lock(&plugins->mutex);
+ foreach (RegisteredPlugin plugin, plugins->values()) {
QPluginLoader* loader = plugin.loader;
if (!loader->unload())
qWarning("Unloading %s failed: %s", qPrintable(plugin.uri), qPrintable(loader->errorString()));
delete loader;
}
- qmlEnginePluginsWithRegisteredTypes()->clear();
+ plugins->clear();
}
typedef QPair<QStaticPlugin, QJsonArray> StaticPluginPair;
@@ -303,7 +308,7 @@ public:
\brief The QQmlImports class encapsulates one QML document's import statements.
\internal
*/
-QQmlImports::QQmlImports(const QQmlImports &copy)
+QQmlImports::QQmlImports(const QQmlImports &copy)
: d(copy.d)
{
++d->ref;
@@ -1631,7 +1636,7 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader,
}
if (qmlImportTrace())
- qDebug() << "QQmlImportDatabase::resolvePlugin: Could not resolve plugin" << baseName
+ qDebug() << "QQmlImportDatabase::resolvePlugin: Could not resolve plugin" << baseName
<< "in" << qmldirPath;
return QString();
@@ -1909,10 +1914,12 @@ bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &ur
const QString absoluteFilePath = fileInfo.absoluteFilePath();
bool engineInitialized = initializedPlugins.contains(absoluteFilePath);
- bool typesRegistered = qmlEnginePluginsWithRegisteredTypes()->contains(absoluteFilePath);
+ StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
+ QMutexLocker lock(&plugins->mutex);
+ bool typesRegistered = plugins->contains(absoluteFilePath);
if (typesRegistered) {
- Q_ASSERT_X(qmlEnginePluginsWithRegisteredTypes()->value(absoluteFilePath).uri == uri,
+ Q_ASSERT_X(plugins->value(absoluteFilePath).uri == uri,
"QQmlImportDatabase::importPlugin",
"Internal error: Plugin imported previously with different uri");
}
@@ -1942,7 +1949,7 @@ bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &ur
return false;
}
} else {
- loader = qmlEnginePluginsWithRegisteredTypes()->value(absoluteFilePath).loader;
+ loader = plugins->value(absoluteFilePath).loader;
}
QObject *instance = loader->instance();
@@ -1951,7 +1958,7 @@ bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &ur
RegisteredPlugin plugin;
plugin.uri = uri;
plugin.loader = loader;
- qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath, plugin);
+ plugins->insert(absoluteFilePath, plugin);
// Continue with shared code path for dynamic and static plugins:
if (!importPlugin(instance, fileInfo.absolutePath(), uri, typeNamespace, false, errors))
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index ade4634c2d..1cc75387a3 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -46,9 +46,10 @@
#include "qqmlcompiler_p.h"
#include "qqmlexpression_p.h"
#include "qqmlmemoryprofiler_p.h"
+#include "qqmlobjectcreator_p.h"
-// XXX TODO
-// - check that the Component.onCompleted behavior is the same as 4.8 in the synchronous and
+// XXX TODO
+// - check that the Component.onCompleted behavior is the same as 4.8 in the synchronous and
// async if nested cases
void QQmlEnginePrivate::incubate(QQmlIncubator &i, QQmlContextData *forContext)
{
@@ -90,14 +91,17 @@ void QQmlEnginePrivate::incubate(QQmlIncubator &i, QQmlContextData *forContext)
p->changeStatus(QQmlIncubator::Loading);
if (!watcher.hasRecursed()) {
- QQmlVME::Interrupt i;
+ QQmlInstantiationInterrupt i;
p->incubate(i);
}
} else {
incubatorList.insert(p.data());
incubatorCount++;
- p->vmeGuard.guard(&p->vme);
+ if (useNewCompiler)
+ p->vmeGuard.guard(p->creator.data());
+ else
+ p->vmeGuard.guard(&p->vme);
p->changeStatus(QQmlIncubator::Loading);
if (incubationController)
@@ -106,7 +110,7 @@ void QQmlEnginePrivate::incubate(QQmlIncubator &i, QQmlContextData *forContext)
}
/*!
-Sets the engine's incubation \a controller. The engine can only have one active controller
+Sets the engine's incubation \a controller. The engine can only have one active controller
and it does not take ownership of it.
\sa incubationController()
@@ -180,7 +184,7 @@ the process of creating objects a QQmlIncubators must be driven only during the
application's idle time. QQmlIncubationController allows the application to control
exactly when, how often and for how long this processing occurs.
-A QQmlIncubationController derived instance should be created and set on a
+A QQmlIncubationController derived instance should be created and set on a
QQmlEngine by calling the QQmlEngine::setIncubationController() method.
Processing is then controlled by calling the QQmlIncubationController::incubateFor()
or QQmlIncubationController::incubateWhile() methods as dictated by the application's
@@ -190,12 +194,12 @@ For example, this is an example of a incubation controller that will incubate fo
of 5 milliseconds out of every 16 milliseconds.
\code
-class PeriodicIncubationController : public QObject,
- public QQmlIncubationController
+class PeriodicIncubationController : public QObject,
+ public QQmlIncubationController
{
public:
- PeriodicIncubationController() {
- startTimer(16);
+ PeriodicIncubationController() {
+ startTimer(16);
}
protected:
@@ -207,7 +211,7 @@ protected:
Although the previous example would work, it is not optimal. Real world incubation
controllers should try and maximize the amount of idle time they consume - rather
-than a static amount like 5 milliseconds - while not disturbing the application.
+than a static amount like 5 milliseconds - while not disturbing the application.
*/
/*!
@@ -243,7 +247,7 @@ int QQmlIncubationController::incubatingObjectCount() const
}
/*!
-Called when the number of incubating objects changes. \a incubatingObjectCount is the
+Called when the number of incubating objects changes. \a incubatingObjectCount is the
new number of incubating objects.
The default implementation does nothing.
@@ -253,7 +257,7 @@ void QQmlIncubationController::incubatingObjectCountChanged(int incubatingObject
Q_UNUSED(incubatingObjectCount);
}
-void QQmlIncubatorPrivate::forceCompletion(QQmlVME::Interrupt &i)
+void QQmlIncubatorPrivate::forceCompletion(QQmlInstantiationInterrupt &i)
{
while (QQmlIncubator::Loading == status) {
while (QQmlIncubator::Loading == status && !waitingFor.isEmpty())
@@ -263,7 +267,7 @@ void QQmlIncubatorPrivate::forceCompletion(QQmlVME::Interrupt &i)
}
}
-void QQmlIncubatorPrivate::incubate(QQmlVME::Interrupt &i)
+void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
{
if (!compiledData)
return;
@@ -292,14 +296,21 @@ void QQmlIncubatorPrivate::incubate(QQmlVME::Interrupt &i)
if (progress == QQmlIncubatorPrivate::Execute) {
enginePriv->referenceScarceResources();
- QObject *tresult = vme.execute(&errors, i);
+ QObject *tresult = 0;
+ if (enginePriv->useNewCompiler) {
+ tresult = creator->create(subComponentToCreate);
+ if (!tresult)
+ errors = creator->errors;
+ } else {
+ tresult = vme.execute(&errors, i);
+ }
enginePriv->dereferenceScarceResources();
if (watcher.hasRecursed())
return;
result = tresult;
- if (errors.isEmpty() && result == 0)
+ if (errors.isEmpty() && result == 0)
goto finishIncubate;
if (result) {
@@ -335,7 +346,11 @@ void QQmlIncubatorPrivate::incubate(QQmlVME::Interrupt &i)
if (watcher.hasRecursed())
return;
- QQmlContextData *ctxt = vme.complete(i);
+ QQmlContextData *ctxt = 0;
+ if (enginePriv->useNewCompiler)
+ ctxt = creator->finalize(i);
+ else
+ ctxt = vme.complete(i);
if (ctxt) {
rootContext = ctxt;
progress = QQmlIncubatorPrivate::Completed;
@@ -367,7 +382,10 @@ finishIncubate:
}
}
} else {
- vmeGuard.guard(&vme);
+ if (enginePriv->useNewCompiler)
+ vmeGuard.guard(creator.data());
+ else
+ vmeGuard.guard(&vme);
}
}
@@ -379,7 +397,7 @@ void QQmlIncubationController::incubateFor(int msecs)
if (!d || !d->incubatorCount)
return;
- QQmlVME::Interrupt i(msecs * 1000000);
+ QQmlInstantiationInterrupt i(msecs * 1000000);
i.reset();
do {
static_cast<QQmlIncubatorPrivate*>(d->incubatorList.first())->incubate(i);
@@ -398,7 +416,7 @@ void QQmlIncubationController::incubateWhile(volatile bool *flag, int msecs)
if (!d || !d->incubatorCount)
return;
- QQmlVME::Interrupt i(flag, msecs * 1000000);
+ QQmlInstantiationInterrupt i(flag, msecs * 1000000);
i.reset();
do {
static_cast<QQmlIncubatorPrivate*>(d->incubatorList.first())->incubate(i);
@@ -416,8 +434,8 @@ application uses QQmlComponent::create() directly, the QML object instance is cr
synchronously which, depending on the complexity of the object, can cause noticeable pauses or
stutters in the application.
-The use of QQmlIncubator gives more control over the creation of a QML object,
-including allowing it to be created asynchronously using application idle time. The following
+The use of QQmlIncubator gives more control over the creation of a QML object,
+including allowing it to be created asynchronously using application idle time. The following
example shows a simple use of QQmlIncubator.
\code
@@ -431,25 +449,25 @@ while (incubator.isReady()) {
QObject *object = incubator.object();
\endcode
-Asynchronous incubators are controlled by a QQmlIncubationController that is
+Asynchronous incubators are controlled by a QQmlIncubationController that is
set on the QQmlEngine, which lets the engine know when the application is idle and
incubating objects should be processed. If an incubation controller is not set on the
QQmlEngine, QQmlIncubator creates objects synchronously regardless of the
-specified IncubationMode.
+specified IncubationMode.
QQmlIncubator supports three incubation modes:
\list
\li Synchronous The creation occurs synchronously. That is, once the
QQmlComponent::create() call returns, the incubator will already be in either the
Error or Ready state. A synchronous incubator has no real advantage compared to using
-the synchronous creation methods on QQmlComponent directly, but it may simplify an
-application's implementation to use the same API for both synchronous and asynchronous
+the synchronous creation methods on QQmlComponent directly, but it may simplify an
+application's implementation to use the same API for both synchronous and asynchronous
creations.
\li Asynchronous (default) The creation occurs asynchronously, assuming a
-QQmlIncubatorController is set on the QQmlEngine.
+QQmlIncubatorController is set on the QQmlEngine.
-The incubator will remain in the Loading state until either the creation is complete or an error
+The incubator will remain in the Loading state until either the creation is complete or an error
occurs. The statusChanged() callback can be used to be notified of status changes.
Applications should use the Asynchronous incubation mode to create objects that are not needed
@@ -459,31 +477,31 @@ the object is needed immediately the QQmlIncubator::forceCompletion() method can
to complete the creation process synchronously.
\li AsynchronousIfNested The creation will occur asynchronously if part of a nested asynchronous
-creation, or synchronously if not.
+creation, or synchronously if not.
In most scenarios where a QML component wants the appearance of a synchronous
-instantiation, it should use this mode.
+instantiation, it should use this mode.
This mode is best explained with an example. When the ListView type is first created, it needs
-to populate itself with an initial set of delegates to show. If the ListView was 400 pixels high,
+to populate itself with an initial set of delegates to show. If the ListView was 400 pixels high,
and each delegate was 100 pixels high, it would need to create four initial delegate instances. If
the ListView used the Asynchronous incubation mode, the ListView would always be created empty and
then, sometime later, the four initial items would appear.
-Conversely, if the ListView was to use the Synchronous incubation mode it would behave correctly
-but it may introduce stutters into the application. As QML would have to stop and instantiate the
-ListView's delegates synchronously, if the ListView was part of a QML component that was being
+Conversely, if the ListView was to use the Synchronous incubation mode it would behave correctly
+but it may introduce stutters into the application. As QML would have to stop and instantiate the
+ListView's delegates synchronously, if the ListView was part of a QML component that was being
instantiated asynchronously this would undo much of the benefit of asynchronous instantiation.
The AsynchronousIfNested mode reconciles this problem. By using AsynchronousIfNested, the ListView
delegates are instantiated asynchronously if the ListView itself is already part of an asynchronous
instantiation, and synchronously otherwise. In the case of a nested asynchronous instantiation, the
outer asynchronous instantiation will not complete until after all the nested instantiations have also
-completed. This ensures that by the time the outer asynchronous instantitation completes, inner
+completed. This ensures that by the time the outer asynchronous instantitation completes, inner
items like ListView have already completed loading their initial delegates.
It is almost always incorrect to use the Synchronous incubation mode - elements or components that
-want the appearance of synchronous instantiation, but without the downsides of introducing freezes
+want the appearance of synchronous instantiation, but without the downsides of introducing freezes
or stutters into the application, should use the AsynchronousIfNested incubation mode.
\endlist
*/
@@ -511,14 +529,14 @@ QQmlIncubator::~QQmlIncubator()
/*!
\enum QQmlIncubator::IncubationMode
-Specifies the mode the incubator operates in. Regardless of the incubation mode, a
+Specifies the mode the incubator operates in. Regardless of the incubation mode, a
QQmlIncubator will behave synchronously if the QQmlEngine does not have
a QQmlIncubationController set.
\value Asynchronous The object will be created asynchronously.
\value AsynchronousIfNested If the object is being created in a context that is already part
-of an asynchronous creation, this incubator will join that existing incubation and execute
-asynchronously. The existing incubation will not become Ready until both it and this
+of an asynchronous creation, this incubator will join that existing incubation and execute
+asynchronously. The existing incubation will not become Ready until both it and this
incubation have completed. Otherwise, the incubation will execute synchronously.
\value Synchronous The object will be created synchronously.
*/
@@ -535,7 +553,7 @@ Specifies the status of the QQmlIncubator.
*/
/*!
-Clears the incubator. Any in-progress incubation is aborted. If the incubator is in the
+Clears the incubator. Any in-progress incubation is aborted. If the incubator is in the
Ready state, the created object is \b not deleted.
*/
void QQmlIncubator::clear()
@@ -566,6 +584,7 @@ void QQmlIncubator::clear()
d->vme.reset();
d->vmeGuard.clear();
+ d->creator.reset(0);
Q_ASSERT(d->compiledData == 0);
Q_ASSERT(d->waitingOnMe.data() == 0);
@@ -596,7 +615,7 @@ returns, the incubator will not be in the Loading state.
*/
void QQmlIncubator::forceCompletion()
{
- QQmlVME::Interrupt i;
+ QQmlInstantiationInterrupt i;
d->forceCompletion(i);
}
@@ -693,7 +712,7 @@ void QQmlIncubator::setInitialState(QObject *object)
void QQmlIncubatorPrivate::changeStatus(QQmlIncubator::Status s)
{
- if (s == status)
+ if (s == status)
return;
status = s;
@@ -703,13 +722,13 @@ void QQmlIncubatorPrivate::changeStatus(QQmlIncubator::Status s)
QQmlIncubator::Status QQmlIncubatorPrivate::calculateStatus() const
{
- if (!errors.isEmpty())
+ if (!errors.isEmpty())
return QQmlIncubator::Error;
else if (result && progress == QQmlIncubatorPrivate::Completed && waitingFor.isEmpty())
return QQmlIncubator::Ready;
else if (compiledData)
return QQmlIncubator::Loading;
- else
+ else
return QQmlIncubator::Null;
}
diff --git a/src/qml/qml/qqmlincubator.h b/src/qml/qml/qqmlincubator.h
index 4d3287a394..2bcaee8a45 100644
--- a/src/qml/qml/qqmlincubator.h
+++ b/src/qml/qml/qqmlincubator.h
@@ -60,11 +60,11 @@ public:
AsynchronousIfNested,
Synchronous
};
- enum Status {
- Null,
- Ready,
- Loading,
- Error
+ enum Status {
+ Null,
+ Ready,
+ Loading,
+ Error
};
QQmlIncubator(IncubationMode = Asynchronous);
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h
index e7246ce3b2..b7009bfe43 100644
--- a/src/qml/qml/qqmlincubator_p.h
+++ b/src/qml/qml/qqmlincubator_p.h
@@ -88,7 +88,12 @@ public:
QPointer<QObject> result;
QQmlGuardedContextData rootContext;
QQmlCompiledData *compiledData;
+ // --- old compiler
QQmlVME vme;
+ // --- new compiler
+ QScopedPointer<QmlObjectCreator> creator;
+ int subComponentToCreate;
+ // ---
QQmlVMEGuard vmeGuard;
QExplicitlySharedDataPointer<QQmlIncubatorPrivate> waitingOnMe;
@@ -99,8 +104,8 @@ public:
void clear();
- void forceCompletion(QQmlVME::Interrupt &i);
- void incubate(QQmlVME::Interrupt &i);
+ void forceCompletion(QQmlInstantiationInterrupt &i);
+ void incubate(QQmlInstantiationInterrupt &i);
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp
index 32f0eeef36..63ce2d419c 100644
--- a/src/qml/qml/qqmlinfo.cpp
+++ b/src/qml/qml/qqmlinfo.cpp
@@ -61,13 +61,13 @@ QT_BEGIN_NAMESPACE
When QML types display warning messages, it improves traceability
if they include the QML file and line number on which the
particular instance was instantiated.
-
+
To include the file and line number, an object must be passed. If
the file and line number is not available for that instance
(either it was not instantiated by the QML engine or location
information is disabled), "unknown location" will be used instead.
- For example,
+ For example,
\code
qmlInfo(object) << tr("component property is a write-once property");
diff --git a/src/qml/qml/qqmlinstruction_p.h b/src/qml/qml/qqmlinstruction_p.h
index 8b27cf06dd..d76c9f9f64 100644
--- a/src/qml/qml/qqmlinstruction_p.h
+++ b/src/qml/qml/qqmlinstruction_p.h
@@ -131,7 +131,7 @@ QT_BEGIN_NAMESPACE
F(Defer, defer) \
F(PopFetchedObject, common) \
F(FetchValueType, fetchValue) \
- F(PopValueType, fetchValue)
+ F(PopValueType, fetchValue)
#ifndef QT_NO_TRANSLATION
#define F_TRANSLATION(F, I, FMT) F(I, FMT)
@@ -163,7 +163,7 @@ QT_BEGIN_NAMESPACE
class QQmlCompiledData;
union QQmlInstruction
{
- enum Type {
+ enum Type {
FOR_EACH_QML_INSTR(QML_INSTR_ENUM)
};
@@ -195,7 +195,7 @@ union QQmlInstruction
struct instr_completeQml {
QML_INSTR_HEADER
ushort column;
- ushort line;
+ ushort line;
bool isRoot;
};
struct instr_create {
@@ -203,7 +203,7 @@ union QQmlInstruction
int type;
int data;
ushort column;
- ushort line;
+ ushort line;
bool isRoot:1;
bool parentToSuper:1;
};
@@ -213,7 +213,7 @@ union QQmlInstruction
int typeSize;
int type;
ushort column;
- ushort line;
+ ushort line;
bool parentToSuper;
};
struct instr_storeMeta {
@@ -268,7 +268,7 @@ union QQmlInstruction
struct instr_begin {
QML_INSTR_HEADER
int castValue;
- };
+ };
struct instr_storeFloat {
QML_INSTR_HEADER
int propertyIndex;
@@ -324,7 +324,7 @@ union QQmlInstruction
double numberValue;
bool isStringLiteral:1;
bool isNumberLiteral:1;
- };
+ };
struct instr_storeScript {
QML_INSTR_HEADER
int value;
@@ -401,7 +401,7 @@ union QQmlInstruction
struct instr_assignSignalObject {
QML_INSTR_HEADER
int signal;
- ushort line;
+ ushort line;
};
struct instr_createComponent {
QML_INSTR_HEADER
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 499ade1ca5..b7673bdb37 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -43,7 +43,7 @@
#include <private/qqmlexpression_p.h>
#include <private/qqmlcontextwrapper_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4script_p.h>
#include <private/qv4errorobject_p.h>
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index d172c9a185..6d0fddf2ad 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -109,7 +109,7 @@ QML list properties are typesafe. Only QObject's that derive from the correct b
the list. The listElementType() method can be used to query the QMetaObject of the QObject type supported.
Attempting to add objects of the incorrect type to a list property will fail.
-Like with normal lists, when accessing a list element by index, it is the callers responsibility to ensure
+Like with normal lists, when accessing a list element by index, it is the callers responsibility to ensure
that it does not request an out of range element using the count() method before calling at().
The \l {Qt Quick 1} version of this class is named QDeclarativeListReference.
@@ -125,7 +125,7 @@ QQmlListReference::QQmlListReference()
/*!
Constructs a QQmlListReference for \a object's \a property. If \a property is not a list
-property, an invalid QQmlListReference is created. If \a object is destroyed after
+property, an invalid QQmlListReference is created. If \a object is destroyed after
the reference is constructed, it will automatically become invalid. That is, it is safe to hold
QQmlListReference instances even after \a object is deleted.
@@ -243,7 +243,7 @@ bool QQmlListReference::canClear() const
}
/*!
-Returns true if the list property can be queried for its element count, otherwise false.
+Returns true if the list property can be queried for its element count, otherwise false.
Returns false if the reference is invalid.
\sa count()
@@ -336,7 +336,7 @@ int QQmlListReference::count() const
\class QQmlListProperty
\since 5.0
\inmodule QtQml
-\brief The QQmlListProperty class allows applications to expose list-like
+\brief The QQmlListProperty class allows applications to expose list-like
properties to QML.
QML has many list properties, where more than one object value can be assigned.
@@ -344,7 +344,7 @@ The use of a list property from QML looks like this:
\code
FruitBasket {
- fruit: [
+ fruit: [
Apple {},
Orange{},
Banana{}
@@ -354,10 +354,10 @@ FruitBasket {
The QQmlListProperty encapsulates a group of function pointers that represet the
set of actions QML can perform on the list - adding items, retrieving items and
-clearing the list. In the future, additional operations may be supported. All
+clearing the list. In the future, additional operations may be supported. All
list properties must implement the append operation, but the rest are optional.
-To provide a list property, a C++ class must implement the operation callbacks,
+To provide a list property, a C++ class must implement the operation callbacks,
and then return an appropriate QQmlListProperty value from the property getter.
List properties should have no setter. In the example above, the Q_PROPERTY()
declarative will look like this:
@@ -366,7 +366,7 @@ declarative will look like this:
Q_PROPERTY(QQmlListProperty<Fruit> fruit READ fruit);
\endcode
-QML list properties are typesafe - in this case \c {Fruit} is a QObject type that
+QML list properties are typesafe - in this case \c {Fruit} is a QObject type that
\c {Apple}, \c {Orange} and \c {Banana} all derive from.
The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty.
@@ -375,7 +375,7 @@ The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty.
*/
/*!
-\fn QQmlListProperty::QQmlListProperty()
+\fn QQmlListProperty::QQmlListProperty()
\internal
*/
@@ -386,7 +386,7 @@ Convenience constructor for making a QQmlListProperty value from an existing
QList \a list. The \a list reference must remain valid for as long as \a object
exists. \a object must be provided.
-Generally this constructor should not be used in production code, as a
+Generally this constructor should not be used in production code, as a
writable QList violates QML's memory management rules. However, this constructor
can very useful while prototyping.
*/
@@ -401,12 +401,12 @@ remains valid while \a object exists.
*/
/*!
-\fn QQmlListProperty::QQmlListProperty(QObject *object, void *data, AppendFunction append,
+\fn QQmlListProperty::QQmlListProperty(QObject *object, void *data, AppendFunction append,
CountFunction count, AtFunction at,
ClearFunction clear)
Construct a QQmlListProperty from a set of operation functions. An opaque \a data handle
-may be passed which can be accessed from within the operation functions. The list property
+may be passed which can be accessed from within the operation functions. The list property
remains valid while \a object exists.
Null pointers can be passed for any function. If any null pointers are passed in, the list
@@ -431,7 +431,7 @@ Return the number of elements in the list \a property.
*/
/*!
-\fn bool QQmlListProperty::operator==(const QQmlListProperty &other) const
+\fn bool QQmlListProperty::operator==(const QQmlListProperty &other) const
Returns true if this QQmlListProperty is equal to \a other, otherwise false.
*/
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index 7b975c2cc8..0d60fee5d0 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -50,14 +50,17 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-DEFINE_MANAGED_VTABLE(QmlListWrapper);
+DEFINE_OBJECT_VTABLE(QmlListWrapper);
QmlListWrapper::QmlListWrapper(QV8Engine *engine)
: Object(QV8Engine::getV4(engine)),
v8(engine)
{
- setVTable(&static_vtbl);
- flags &= ~SimpleArray;
+ setVTable(staticVTable());
+ QV4::Scope scope(QV8Engine::getV4(engine));
+ QV4::ScopedObject protectThis(scope, this);
+ Q_UNUSED(protectThis);
+ setArrayType(ArrayData::Custom);
}
QmlListWrapper::~QmlListWrapper()
@@ -150,21 +153,20 @@ void QmlListWrapper::destroy(Managed *that)
w->~QmlListWrapper();
}
-Property *QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
+void QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attrs)
{
name = (String *)0;
*index = UINT_MAX;
QmlListWrapper *w = m->as<QmlListWrapper>();
quint32 count = w->property.count ? w->property.count(&w->property) : 0;
if (it->arrayIndex < count) {
- if (attrs)
- *attrs = QV4::Attr_Data;
*index = it->arrayIndex;
++it->arrayIndex;
- it->tmpDynamicProperty.value = QV4::QObjectWrapper::wrap(w->engine(), w->property.at(&w->property, *index));
- return &it->tmpDynamicProperty;
+ *attrs = QV4::Attr_Data;
+ p->value = QV4::QObjectWrapper::wrap(w->engine(), w->property.at(&w->property, *index));
+ return;
}
- return QV4::Object::advanceIterator(m, it, name, index, attrs);
+ return QV4::Object::advanceIterator(m, it, name, index, p, attrs);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h
index 9ece5851ed..a7ce8b30bf 100644
--- a/src/qml/qml/qqmllistwrapper_p.h
+++ b/src/qml/qml/qqmllistwrapper_p.h
@@ -58,7 +58,7 @@
#include <QtQml/qqmllist.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
@@ -69,7 +69,7 @@ namespace QV4 {
struct Q_QML_EXPORT QmlListWrapper : Object
{
- Q_MANAGED
+ V4_OBJECT
protected:
QmlListWrapper(QV8Engine *engine);
~QmlListWrapper();
@@ -84,7 +84,7 @@ public:
static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, const StringRef name, const ValueRef value);
- static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
+ static void advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, Property *p, PropertyAttributes *attributes);
static void destroy(Managed *that);
private:
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 14b5471317..fc9e2fc42a 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -54,64 +54,7 @@
QT_BEGIN_NAMESPACE
-class QQmlLocaleData : public QV4::Object
-{
- Q_MANAGED
-public:
- QQmlLocaleData(QV4::ExecutionEngine *engine)
- : QV4::Object(engine)
- {
- setVTable(&static_vtbl);
- type = Type_Object;
- }
-
- QLocale locale;
-
- static QLocale *getThisLocale(QV4::CallContext *ctx) {
- QQmlLocaleData *thisObject = ctx->callData->thisObject.asObject()->as<QQmlLocaleData>();
- if (!thisObject) {
- ctx->throwTypeError();
- return 0;
- }
- return &thisObject->locale;
- }
-
- static QV4::ReturnedValue method_currencySymbol(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_dateTimeFormat(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_timeFormat(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_dateFormat(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_monthName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_standaloneMonthName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_dayName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_standaloneDayName(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_firstDayOfWeek(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_measurementSystem(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_textDirection(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_weekDays(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_uiLanguages(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_name(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_nativeLanguageName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_nativeCountryName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_decimalPoint(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_groupSeparator(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_percent(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_zeroDigit(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_negativeSign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_positiveSign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_exponential(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_amText(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_pmText(QV4::CallContext *ctx);
-
-private:
- static void destroy(Managed *that)
- {
- static_cast<QQmlLocaleData *>(that)->~QQmlLocaleData();
- }
-};
-
-DEFINE_MANAGED_VTABLE(QQmlLocaleData);
+DEFINE_OBJECT_VTABLE(QQmlLocaleData);
#define GET_LOCALE_DATA_RESOURCE(OBJECT) \
QV4::Scoped<QQmlLocaleData> r(scope, OBJECT.as<QQmlLocaleData>()); \
@@ -555,12 +498,11 @@ QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::CallContext *ctx)
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) {
int day = days.at(i);
if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday)
day = 0;
- result->arrayData[i].value = QV4::Primitive::fromInt32(day);
+ result->arrayPut(i, QV4::Primitive::fromInt32(day));
}
result->setArrayLengthUnchecked(days.size());
@@ -577,10 +519,9 @@ QV4::ReturnedValue QQmlLocaleData::method_get_uiLanguages(QV4::CallContext *ctx)
QStringList langs = locale->uiLanguages();
QV4::Scoped<QV4::ArrayObject> result(scope, ctx->engine->newArrayObject());
result->arrayReserve(langs.size());
- for (int i = 0; i < langs.size(); ++i) {
- result->arrayData[i].value = ctx->engine->newString(langs.at(i));
- result->arrayDataLen = i + 1;
- }
+ QV4::ScopedValue v(scope);
+ for (int i = 0; i < langs.size(); ++i)
+ result->arrayPut(i, (v = ctx->engine->newString(langs.at(i))));
result->setArrayLengthUnchecked(langs.size());
@@ -857,14 +798,21 @@ QQmlLocale::~QQmlLocale()
{
}
-QV4::ReturnedValue QQmlLocale::locale(QV8Engine *v8engine, const QString &locale)
+QV4::ReturnedValue QQmlLocale::locale(QV8Engine *v8engine, const QString &localeName)
+{
+ QLocale qlocale;
+ if (!localeName.isEmpty())
+ qlocale = localeName;
+ return wrap(v8engine, qlocale);
+}
+
+QV4::ReturnedValue QQmlLocale::wrap(QV8Engine *engine, const QLocale &locale)
{
- QV8LocaleDataDeletable *d = localeV8Data(v8engine);
- QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine);
- QV4::Scope scope(engine);
- QV4::Scoped<QQmlLocaleData> wrapper(scope, new (engine->memoryManager) QQmlLocaleData(engine));
- if (!locale.isEmpty())
- wrapper->locale = QLocale(locale);
+ QV8LocaleDataDeletable *d = localeV8Data(engine);
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope scope(v4);
+ QV4::Scoped<QQmlLocaleData> wrapper(scope, new (v4->memoryManager) QQmlLocaleData(v4));
+ wrapper->locale = locale;
QV4::ScopedObject p(scope, d->prototype.value());
wrapper->setPrototype(p.getPointer());
return wrapper.asReturnedValue();
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 8ca67a8c83..cafe448313 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -118,7 +118,8 @@ public:
Saturday = Qt::Saturday
};
- static QV4::ReturnedValue locale(QV8Engine *v8engine, const QString &lang);
+ static QV4::ReturnedValue locale(QV8Engine *v8engine, const QString &localeName);
+ static QV4::ReturnedValue wrap(QV8Engine *engine, const QLocale &locale);
static void registerStringLocaleCompare(QV4::ExecutionEngine *engine);
@@ -128,6 +129,61 @@ private:
static QV4::ReturnedValue method_localeCompare(QV4::CallContext *ctx);
};
+class QQmlLocaleData : public QV4::Object
+{
+ V4_OBJECT
+public:
+ QQmlLocaleData(QV4::ExecutionEngine *engine)
+ : QV4::Object(engine)
+ {
+ setVTable(staticVTable());
+ }
+
+ QLocale locale;
+
+ static QLocale *getThisLocale(QV4::CallContext *ctx) {
+ QQmlLocaleData *thisObject = ctx->callData->thisObject.asObject()->as<QQmlLocaleData>();
+ if (!thisObject) {
+ ctx->throwTypeError();
+ return 0;
+ }
+ return &thisObject->locale;
+ }
+
+ static QV4::ReturnedValue method_currencySymbol(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_dateTimeFormat(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_timeFormat(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_dateFormat(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_monthName(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_standaloneMonthName(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_dayName(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_standaloneDayName(QV4::CallContext *ctx);
+
+ static QV4::ReturnedValue method_get_firstDayOfWeek(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_measurementSystem(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_textDirection(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_weekDays(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_uiLanguages(QV4::CallContext *ctx);
+
+ static QV4::ReturnedValue method_get_name(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_nativeLanguageName(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_nativeCountryName(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_decimalPoint(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_groupSeparator(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_percent(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_zeroDigit(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_negativeSign(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_positiveSign(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_exponential(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_amText(QV4::CallContext *ctx);
+ static QV4::ReturnedValue method_get_pmText(QV4::CallContext *ctx);
+
+private:
+ static void destroy(Managed *that)
+ {
+ static_cast<QQmlLocaleData *>(that)->~QQmlLocaleData();
+ }
+};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index d1ab50c4af..90d3ca3308 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -116,7 +116,7 @@ struct QQmlMetaTypeData
class QQmlTypeModulePrivate
{
public:
- QQmlTypeModulePrivate()
+ QQmlTypeModulePrivate()
: minMinorVersion(INT_MAX), maxMinorVersion(0), locked(false) {}
static QQmlTypeModulePrivate* get(QQmlTypeModule* q) { return q->d; }
@@ -479,7 +479,7 @@ QQmlType *QQmlType::superType() const
return d->superType;
}
-static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
+static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd)
{
// Set classname
@@ -491,7 +491,7 @@ static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
int otherIndex = ignoreEnd->indexOfClassInfo(info.name());
if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
- // Skip
+ // Skip
} else {
builder.addClassInfo(info.name(), info.value());
}
@@ -504,7 +504,7 @@ static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
int otherIndex = ignoreEnd->indexOfProperty(property.name());
if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) {
builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void"));
- // Skip
+ // Skip
} else {
builder.addProperty(property);
}
@@ -520,7 +520,7 @@ static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
bool found = false;
- for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount();
+ for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount();
!found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount();
++ii) {
@@ -540,7 +540,7 @@ static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name());
if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) {
- // Skip
+ // Skip
} else {
builder.addEnumerator(enumerator);
}
@@ -860,7 +860,7 @@ const QMetaObject *QQmlType::attachedPropertiesType() const
/*
This is the id passed to qmlAttachedPropertiesById(). This is different from the index
-for the case that a single class is registered under two or more names (eg. Item in
+for the case that a single class is registered under two or more names (eg. Item in
Qt 4.7 and QtQuick 1.0).
*/
int QQmlType::attachedPropertiesId() const
@@ -1128,7 +1128,7 @@ int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
int registerInterface(const QQmlPrivate::RegisterInterface &interface)
{
- if (interface.version > 0)
+ if (interface.version > 0)
qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
QWriteLocker lock(metaTypeDataLock());
@@ -1472,7 +1472,7 @@ bool QQmlMetaType::isModule(const QString &module, int versionMajor, int version
QQmlMetaTypeData *data = metaTypeData();
// first, check Types
- QQmlTypeModule *tm =
+ QQmlTypeModule *tm =
data->uriToModule.value(QQmlMetaTypeData::VersionedUri(module, versionMajor));
if (tm && tm->minimumMinorVersion() <= versionMinor && tm->maximumMinorVersion() >= versionMinor)
return true;
@@ -1755,7 +1755,7 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStri
}
/*!
- Returns the type (if any) that corresponds to the QVariant::Type \a userType.
+ Returns the type (if any) that corresponds to the QVariant::Type \a userType.
Returns null if no type is registered.
*/
QQmlType *QQmlMetaType::qmlType(int userType)
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 64f7702b64..019e6b8821 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -104,7 +104,7 @@ public:
enum TypeCategory { Unknown, Object, List };
static TypeCategory typeCategory(int);
-
+
static bool isInterface(int);
static const char *interfaceIId(int);
static bool isList(int);
@@ -278,7 +278,7 @@ private:
QQmlTypeModulePrivate *d;
};
-class QQmlTypeModuleVersion
+class QQmlTypeModuleVersion
{
public:
QQmlTypeModuleVersion();
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index 3d4b260574..fb058379be 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -84,7 +84,7 @@ void QQmlNotifier::emitNotify(QQmlNotifierEndpoint *endpoint, void **a)
// End of notifying, restore values
endpoint->senderPtr = originalSenderPtr;
}
- }
+ }
}
/*! \internal
diff --git a/src/qml/qml/qqmlnotifier_p.h b/src/qml/qml/qqmlnotifier_p.h
index 93f2cd68da..0794f3a911 100644
--- a/src/qml/qml/qqmlnotifier_p.h
+++ b/src/qml/qml/qqmlnotifier_p.h
@@ -123,7 +123,7 @@ QQmlNotifier::QQmlNotifier()
}
QQmlNotifier::~QQmlNotifier()
-{
+{
QQmlNotifierEndpoint *endpoint = endpoints;
while (endpoint) {
QQmlNotifierEndpoint *n = endpoint;
@@ -221,7 +221,7 @@ bool QQmlNotifierEndpoint::isNotifying() const
/*!
Cancel any notifies that are in progress.
*/
-void QQmlNotifierEndpoint::cancelNotify()
+void QQmlNotifierEndpoint::cancelNotify()
{
if (isNotifying()) {
qintptr sp = *((qintptr *)(senderPtr & ~0x1));
diff --git a/src/qml/qml/qqmlnullablevalue_p_p.h b/src/qml/qml/qqmlnullablevalue_p_p.h
index ed3dfb8780..6c17153181 100644
--- a/src/qml/qml/qqmlnullablevalue_p_p.h
+++ b/src/qml/qml/qqmlnullablevalue_p_p.h
@@ -56,7 +56,7 @@
QT_BEGIN_NAMESPACE
template<typename T>
-struct QQmlNullableValue
+struct QQmlNullableValue
{
QQmlNullableValue()
: isNull(true), value(T()) {}
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 3798129e8b..e2063a979f 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -42,7 +42,6 @@
#include "qqmlobjectcreator_p.h"
#include <private/qqmlengine_p.h>
-#include <private/qqmlabstractbinding_p.h>
#include <private/qqmlvmemetaobject_p.h>
#include <private/qv4function_p.h>
#include <private/qv4functionobject_p.h>
@@ -52,9 +51,11 @@
#include <private/qqmlboundsignal_p.h>
#include <private/qqmltrace_p.h>
#include <private/qqmlcomponentattached_p.h>
-#include <QQmlComponent>
#include <private/qqmlcomponent_p.h>
-#include <private/qqmlcodegenerator_p.h>
+#include <private/qqmlcustomparser_p.h>
+#include <private/qqmlscriptstring_p.h>
+#include <private/qqmlpropertyvalueinterceptor_p.h>
+#include <private/qqmlvaluetypeproxybinding_p.h>
QT_USE_NAMESPACE
@@ -70,394 +71,6 @@ struct ActiveOCRestorer
};
}
-QQmlCompilePass::QQmlCompilePass(const QUrl &url, const QV4::CompiledData::QmlUnit *unit)
- : url(url)
- , qmlUnit(unit)
-{
-}
-
-void QQmlCompilePass::recordError(const QV4::CompiledData::Location &location, const QString &description)
-{
- QQmlError error;
- error.setUrl(url);
- error.setLine(location.line);
- error.setColumn(location.column);
- error.setDescription(description);
- errors << error;
-}
-
-#define COMPILE_EXCEPTION(token, desc) \
- { \
- recordError((token)->location, desc); \
- return false; \
- }
-
-static QAtomicInt classIndexCounter(0);
-
-QQmlPropertyCacheCreator::QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QV4::CompiledData::QmlUnit *unit, const QUrl &url, const QQmlImports *imports,
- QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes)
- : QQmlCompilePass(url, unit)
- , enginePrivate(enginePrivate)
- , imports(imports)
- , resolvedTypes(resolvedTypes)
-{
-}
-
-bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQmlPropertyCache **resultCache, QByteArray *vmeMetaObjectData)
-{
- Q_ASSERT(!stringAt(obj->inheritedTypeNameIndex).isEmpty());
-
- QQmlCompiledData::TypeReference typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex);
- QQmlPropertyCache *baseTypeCache = typeRef.createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
- Q_ASSERT(baseTypeCache);
- if (obj->nProperties == 0 && obj->nSignals == 0 && obj->nFunctions == 0) {
- *resultCache = baseTypeCache;
- vmeMetaObjectData->clear();
- return true;
- }
-
- QQmlPropertyCache *cache = baseTypeCache->copyAndReserve(QQmlEnginePrivate::get(enginePrivate),
- obj->nProperties,
- obj->nFunctions + obj->nProperties + obj->nSignals,
- obj->nSignals + obj->nProperties);
- *resultCache = cache;
-
- vmeMetaObjectData->clear();
-
- struct TypeData {
- QV4::CompiledData::Property::Type dtype;
- int metaType;
- } builtinTypes[] = {
- { QV4::CompiledData::Property::Var, QMetaType::QVariant },
- { QV4::CompiledData::Property::Variant, QMetaType::QVariant },
- { QV4::CompiledData::Property::Int, QMetaType::Int },
- { QV4::CompiledData::Property::Bool, QMetaType::Bool },
- { QV4::CompiledData::Property::Real, QMetaType::Double },
- { QV4::CompiledData::Property::String, QMetaType::QString },
- { QV4::CompiledData::Property::Url, QMetaType::QUrl },
- { QV4::CompiledData::Property::Color, QMetaType::QColor },
- { QV4::CompiledData::Property::Font, QMetaType::QFont },
- { QV4::CompiledData::Property::Time, QMetaType::QTime },
- { QV4::CompiledData::Property::Date, QMetaType::QDate },
- { QV4::CompiledData::Property::DateTime, QMetaType::QDateTime },
- { QV4::CompiledData::Property::Rect, QMetaType::QRectF },
- { QV4::CompiledData::Property::Point, QMetaType::QPointF },
- { QV4::CompiledData::Property::Size, QMetaType::QSizeF },
- { QV4::CompiledData::Property::Vector2D, QMetaType::QVector2D },
- { QV4::CompiledData::Property::Vector3D, QMetaType::QVector3D },
- { QV4::CompiledData::Property::Vector4D, QMetaType::QVector4D },
- { QV4::CompiledData::Property::Matrix4x4, QMetaType::QMatrix4x4 },
- { QV4::CompiledData::Property::Quaternion, QMetaType::QQuaternion }
- };
- static const uint builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData);
-
- QByteArray newClassName;
-
- if (false /* ### compileState->root == obj && !compileState->nested*/) {
-#if 0 // ###
- QString path = output->url.path();
- int lastSlash = path.lastIndexOf(QLatin1Char('/'));
- if (lastSlash > -1) {
- QString nameBase = path.mid(lastSlash + 1, path.length()-lastSlash-5);
- if (!nameBase.isEmpty() && nameBase.at(0).isUpper())
- newClassName = nameBase.toUtf8() + "_QMLTYPE_" +
- QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1));
- }
-#endif
- }
- if (newClassName.isEmpty()) {
- newClassName = QQmlMetaObject(baseTypeCache).className();
- newClassName.append("_QML_");
- newClassName.append(QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1)));
- }
-
- cache->_dynamicClassName = newClassName;
-
- int aliasCount = 0;
- int varPropCount = 0;
-
- const QV4::CompiledData::Property *p = obj->propertyTable();
- for (quint32 i = 0; i < obj->nProperties; ++i, ++p) {
-
- if (p->type == QV4::CompiledData::Property::Alias)
- aliasCount++;
- else if (p->type == QV4::CompiledData::Property::Var)
- varPropCount++;
-
-#if 0 // ### Do this elsewhere
- // No point doing this for both the alias and non alias cases
- QQmlPropertyData *d = property(obj, p->name);
- if (d && d->isFinal())
- COMPILE_EXCEPTION(p, tr("Cannot override FINAL property"));
-#endif
- }
-
- typedef QQmlVMEMetaData VMD;
-
- QByteArray &dynamicData = *vmeMetaObjectData = QByteArray(sizeof(QQmlVMEMetaData)
- + obj->nProperties * sizeof(VMD::PropertyData)
- + obj->nFunctions * sizeof(VMD::MethodData)
- + aliasCount * sizeof(VMD::AliasData), 0);
-
- int effectivePropertyIndex = cache->propertyIndexCacheStart;
- int effectiveMethodIndex = cache->methodIndexCacheStart;
-
- // For property change signal override detection.
- // We prepopulate a set of signal names which already exist in the object,
- // and throw an error if there is a signal/method defined as an override.
- QSet<QString> seenSignals;
- seenSignals << QStringLiteral("destroyed") << QStringLiteral("parentChanged") << QStringLiteral("objectNameChanged");
- QQmlPropertyCache *parentCache = cache;
- while ((parentCache = parentCache->parent())) {
- if (int pSigCount = parentCache->signalCount()) {
- int pSigOffset = parentCache->signalOffset();
- for (int i = pSigOffset; i < pSigCount; ++i) {
- QQmlPropertyData *currPSig = parentCache->signal(i);
- // XXX TODO: find a better way to get signal name from the property data :-/
- for (QQmlPropertyCache::StringCache::ConstIterator iter = parentCache->stringCache.begin();
- iter != parentCache->stringCache.end(); ++iter) {
- if (currPSig == (*iter).second) {
- seenSignals.insert(iter.key());
- break;
- }
- }
- }
- }
- }
-
- // First set up notify signals for properties - first normal, then var, then alias
- enum { NSS_Normal = 0, NSS_Var = 1, NSS_Alias = 2 };
- for (int ii = NSS_Normal; ii <= NSS_Alias; ++ii) { // 0 == normal, 1 == var, 2 == alias
-
- if (ii == NSS_Var && varPropCount == 0) continue;
- else if (ii == NSS_Alias && aliasCount == 0) continue;
-
- const QV4::CompiledData::Property *p = obj->propertyTable();
- for (quint32 i = 0; i < obj->nProperties; ++i, ++p) {
- if ((ii == NSS_Normal && (p->type == QV4::CompiledData::Property::Alias ||
- p->type == QV4::CompiledData::Property::Var)) ||
- ((ii == NSS_Var) && (p->type != QV4::CompiledData::Property::Var)) ||
- ((ii == NSS_Alias) && (p->type != QV4::CompiledData::Property::Alias)))
- continue;
-
- quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction |
- QQmlPropertyData::IsVMESignal;
-
- QString changedSigName = stringAt(p->nameIndex) + QLatin1String("Changed");
- seenSignals.insert(changedSigName);
-
- cache->appendSignal(changedSigName, flags, effectiveMethodIndex++);
- }
- }
-
- // Dynamic signals
- for (uint i = 0; i < obj->nSignals; ++i) {
- const QV4::CompiledData::Signal *s = obj->signalAt(i);
- const int paramCount = s->nParameters;
-
- QList<QByteArray> names;
- QVarLengthArray<int, 10> paramTypes(paramCount?(paramCount + 1):0);
-
- if (paramCount) {
- paramTypes[0] = paramCount;
-
- for (int i = 0; i < paramCount; ++i) {
- const QV4::CompiledData::Parameter *param = s->parameterAt(i);
- names.append(stringAt(param->nameIndex).toUtf8());
- if (param->type < builtinTypeCount) {
- // built-in type
- paramTypes[i + 1] = builtinTypes[param->type].metaType;
- } else {
- // lazily resolved type
- Q_ASSERT(param->type == QV4::CompiledData::Property::Custom);
- const QString customTypeName = stringAt(param->customTypeNameIndex);
- QQmlType *qmltype = 0;
- if (!imports->resolveType(customTypeName, &qmltype, 0, 0, 0))
- COMPILE_EXCEPTION(s, tr("Invalid signal parameter type: %1").arg(customTypeName));
-
- if (qmltype->isComposite()) {
- QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl());
- Q_ASSERT(tdata);
- Q_ASSERT(tdata->isComplete());
-
- QQmlCompiledData *data = tdata->compiledData();
-
- paramTypes[i + 1] = data->metaTypeId;
-
- tdata->release();
- } else {
- paramTypes[i + 1] = qmltype->typeId();
- }
- }
- }
- }
-
- ((QQmlVMEMetaData *)dynamicData.data())->signalCount++;
-
- quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction |
- QQmlPropertyData::IsVMESignal;
- if (paramCount)
- flags |= QQmlPropertyData::HasArguments;
-
- QString signalName = stringAt(s->nameIndex);
- if (seenSignals.contains(signalName))
- COMPILE_EXCEPTION(s, tr("Duplicate signal name: invalid override of property change signal or superclass signal"));
- seenSignals.insert(signalName);
-
- cache->appendSignal(signalName, flags, effectiveMethodIndex++,
- paramCount?paramTypes.constData():0, names);
- }
-
-
- // Dynamic slots
- const quint32 *functionIndex = obj->functionOffsetTable();
- for (quint32 i = 0; i < obj->nFunctions; ++i, ++functionIndex) {
- const QV4::CompiledData::Function *s = qmlUnit->header.functionAt(*functionIndex);
- int paramCount = s->nFormals;
-
- quint32 flags = QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMEFunction;
-
- if (paramCount)
- flags |= QQmlPropertyData::HasArguments;
-
- QString slotName = stringAt(s->nameIndex);
- if (seenSignals.contains(slotName))
- COMPILE_EXCEPTION(s, tr("Duplicate method name: invalid override of property change signal or superclass signal"));
- // Note: we don't append slotName to the seenSignals list, since we don't
- // protect against overriding change signals or methods with properties.
-
- const quint32 *formalsIndices = s->formalsTable();
- QList<QByteArray> parameterNames;
- parameterNames.reserve(paramCount);
- for (int i = 0; i < paramCount; ++i)
- parameterNames << stringAt(formalsIndices[i]).toUtf8();
-
- cache->appendMethod(slotName, flags, effectiveMethodIndex++, parameterNames);
- }
-
-
- // Dynamic properties (except var and aliases)
- int effectiveSignalIndex = cache->signalHandlerIndexCacheStart;
- /* const QV4::CompiledData::Property* */ p = obj->propertyTable();
- for (quint32 i = 0; i < obj->nProperties; ++i, ++p) {
-
- if (p->type == QV4::CompiledData::Property::Alias ||
- p->type == QV4::CompiledData::Property::Var)
- continue;
-
- int propertyType = 0;
- int vmePropertyType = 0;
- quint32 propertyFlags = 0;
-
- if (p->type < builtinTypeCount) {
- propertyType = builtinTypes[p->type].metaType;
- vmePropertyType = propertyType;
-
- if (p->type == QV4::CompiledData::Property::Variant)
- propertyFlags |= QQmlPropertyData::IsQVariant;
- } else {
- Q_ASSERT(p->type == QV4::CompiledData::Property::CustomList ||
- p->type == QV4::CompiledData::Property::Custom);
-
- QQmlType *qmltype = 0;
- if (!imports->resolveType(stringAt(p->customTypeNameIndex), &qmltype, 0, 0, 0)) {
- COMPILE_EXCEPTION(p, tr("Invalid property type"));
- }
-
- Q_ASSERT(qmltype);
- if (qmltype->isComposite()) {
- QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl());
- Q_ASSERT(tdata);
- Q_ASSERT(tdata->isComplete());
-
- QQmlCompiledData *data = tdata->compiledData();
-
- if (p->type == QV4::CompiledData::Property::Custom) {
- propertyType = data->metaTypeId;
- vmePropertyType = QMetaType::QObjectStar;
- } else {
- propertyType = data->listMetaTypeId;
- vmePropertyType = qMetaTypeId<QQmlListProperty<QObject> >();
- }
-
- tdata->release();
- } else {
- if (p->type == QV4::CompiledData::Property::Custom) {
- propertyType = qmltype->typeId();
- vmePropertyType = QMetaType::QObjectStar;
- } else {
- propertyType = qmltype->qListTypeId();
- vmePropertyType = qMetaTypeId<QQmlListProperty<QObject> >();
- }
- }
-
- if (p->type == QV4::CompiledData::Property::Custom)
- propertyFlags |= QQmlPropertyData::IsQObjectDerived;
- else
- propertyFlags |= QQmlPropertyData::IsQList;
- }
-
- if ((!p->flags & QV4::CompiledData::Property::IsReadOnly) && p->type != QV4::CompiledData::Property::CustomList)
- propertyFlags |= QQmlPropertyData::IsWritable;
-
-
- QString propertyName = stringAt(p->nameIndex);
- if (i == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName;
- cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- propertyType, effectiveSignalIndex);
-
- effectiveSignalIndex++;
-
- VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
- (vmd->propertyData() + vmd->propertyCount)->propertyType = vmePropertyType;
- vmd->propertyCount++;
- }
-
- // Now do var properties
- /* const QV4::CompiledData::Property* */ p = obj->propertyTable();
- for (quint32 i = 0; i < obj->nProperties; ++i, ++p) {
-
- if (p->type != QV4::CompiledData::Property::Var)
- continue;
-
- quint32 propertyFlags = QQmlPropertyData::IsVarProperty;
- if (!p->flags & QV4::CompiledData::Property::IsReadOnly)
- propertyFlags |= QQmlPropertyData::IsWritable;
-
- VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
- (vmd->propertyData() + vmd->propertyCount)->propertyType = QMetaType::QVariant;
- vmd->propertyCount++;
- ((QQmlVMEMetaData *)dynamicData.data())->varPropertyCount++;
-
- QString propertyName = stringAt(p->nameIndex);
- if (i == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName;
- cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- QMetaType::QVariant, effectiveSignalIndex);
-
- effectiveSignalIndex++;
- }
-
- // Alias property count. Actual data is setup in buildDynamicMetaAliases
- ((QQmlVMEMetaData *)dynamicData.data())->aliasCount = aliasCount;
-
- // Dynamic slot data - comes after the property data
- /*const quint32* */functionIndex = obj->functionOffsetTable();
- for (quint32 i = 0; i < obj->nFunctions; ++i, ++functionIndex) {
- const QV4::CompiledData::Function *s = qmlUnit->header.functionAt(*functionIndex);
-
- VMD::MethodData methodData = { /* runtimeFunctionIndex*/ 0, // ###
- int(s->nFormals),
- /* s->location.start.line */0 }; // ###
-
- VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
- VMD::MethodData &md = *(vmd->methodData() + vmd->methodCount);
- vmd->methodCount++;
- md = methodData;
- }
-
- return true;
-}
-
static void removeBindingOnProperty(QObject *o, int index)
{
int coreIndex = index & 0x0000FFFF;
@@ -467,19 +80,26 @@ static void removeBindingOnProperty(QObject *o, int index)
if (binding) binding->destroy();
}
-QmlObjectCreator::QmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData)
- : QQmlCompilePass(compiledData->url, compiledData->qmlUnit)
- , componentAttached(0)
+QmlObjectCreator::QmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData, QQmlContextData *creationContext, QQmlContextData *rootContext,
+ QFiniteStack<QQmlAbstractBinding *> *inheritedBindingStack, QFiniteStack<QQmlParserStatus *> *inheritedParserStatusStack)
+ : componentAttached(0)
+ , url(compiledData->url)
, engine(parentContext->engine)
+ , qmlUnit(compiledData->qmlUnit)
, jsUnit(compiledData->compilationUnit)
, parentContext(parentContext)
+ , creationContext(creationContext)
, context(0)
, resolvedTypes(compiledData->resolvedTypes)
, propertyCaches(compiledData->propertyCaches)
, vmeMetaObjectData(compiledData->datas)
+ , allCreatedBindings(0)
+ , allParserStatusCallbacks(0)
+ , ownBindingAndParserStatusStacks(false)
, compiledData(compiledData)
+ , rootContext(rootContext)
, _qobject(0)
- , _qobjectForBindings(0)
+ , _scopeObject(0)
, _valueTypeProperty(0)
, _compiledObject(0)
, _ddata(0)
@@ -489,12 +109,51 @@ QmlObjectCreator::QmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledD
{
if (!compiledData->isInitialized())
compiledData->initialize(engine);
+
+ componentAttachedImpl = 0;
+ componentAttached = &componentAttachedImpl;
+
+ if (inheritedBindingStack) {
+ Q_ASSERT(rootContext);
+ Q_ASSERT(inheritedParserStatusStack);
+ allCreatedBindings = inheritedBindingStack;
+ allParserStatusCallbacks = inheritedParserStatusStack;
+ ownBindingAndParserStatusStacks = false;
+ } else {
+ ownBindingAndParserStatusStacks = true;
+ allCreatedBindings = new QFiniteStack<QQmlAbstractBinding*>;
+ allCreatedBindings->allocate(compiledData->totalBindingsCount);
+ allParserStatusCallbacks = new QFiniteStack<QQmlParserStatus*>;
+ allParserStatusCallbacks->allocate(compiledData->totalParserStatusCount);
+ }
+}
+
+QmlObjectCreator::~QmlObjectCreator()
+{
+ if (ownBindingAndParserStatusStacks) {
+ for (int i = 0; i < allCreatedBindings->count(); ++i) {
+ QQmlAbstractBinding *b = allCreatedBindings->at(i);
+ if (b)
+ b->m_mePtr = 0;
+ }
+ for (int i = 0; i < allParserStatusCallbacks->count(); ++i) {
+ QQmlParserStatus *ps = allParserStatusCallbacks->at(i);
+ if (ps)
+ ps->d = 0;
+ }
+
+ delete allCreatedBindings;
+ delete allParserStatusCallbacks;
+ }
}
QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
{
int objectToCreate;
+ Q_ASSERT(!ownBindingAndParserStatusStacks || allCreatedBindings->isEmpty());
+ Q_ASSERT(!ownBindingAndParserStatusStacks || allParserStatusCallbacks->isEmpty());
+
if (subComponentIndex == -1) {
objectIndexToId = compiledData->objectIndexToIdForRoot;
objectToCreate = qmlUnit->indexOfRootObject;
@@ -512,6 +171,11 @@ QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
context->imports->addref();
context->setParent(parentContext);
+ if (!rootContext) {
+ rootContext = context;
+ rootContext->isRootObjectInCreation = true;
+ }
+
QVector<QQmlContextData::ObjectIdMapping> mapping(objectIndexToId.count());
for (QHash<int, int>::ConstIterator it = objectIndexToId.constBegin(), end = objectIndexToId.constEnd();
it != end; ++it) {
@@ -528,13 +192,13 @@ QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
QV4::ScopedObject scripts(scope, v4->newArrayObject(compiledData->scripts.count()));
+ context->importedScripts = scripts;
for (int i = 0; i < compiledData->scripts.count(); ++i) {
QQmlScriptData *s = compiledData->scripts.at(i);
scripts->putIndexed(i, s->scriptValueForContext(context));
}
- context->importedScripts = scripts;
- } else if (parentContext) {
- context->importedScripts = parentContext->importedScripts;
+ } else if (creationContext) {
+ context->importedScripts = creationContext->importedScripts;
}
QObject *instance = createInstance(objectToCreate, parent);
@@ -546,6 +210,7 @@ QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
context->contextObject = instance;
}
+
return instance;
}
@@ -558,7 +223,15 @@ void QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::C
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
- // ### enums
+
+ // ### This should be resolved earlier at compile time and the binding value should be changed accordingly.
+ if (property->isEnum() && !(binding->flags & QV4::CompiledData::Binding::IsResolvedEnum)) {
+ QVariant value = binding->valueAsString(&qmlUnit->header);
+ bool ok = QQmlPropertyPrivate::write(_qobject, *property, value, context);
+ Q_ASSERT(ok);
+ Q_UNUSED(ok);
+ return;
+ }
switch (property->propType) {
case QMetaType::QVariant: {
@@ -604,109 +277,79 @@ void QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::C
}
break;
case QVariant::String: {
- if (binding->type == QV4::CompiledData::Binding::Type_String) {
- QString value = binding->valueAsString(&qmlUnit->header);
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: string expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String);
+ QString value = binding->valueAsString(&qmlUnit->header);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::StringList: {
- if (binding->type == QV4::CompiledData::Binding::Type_String) {
- QStringList value(binding->valueAsString(&qmlUnit->header));
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: string or string list expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String);
+ QStringList value(binding->valueAsString(&qmlUnit->header));
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::ByteArray: {
- if (binding->type == QV4::CompiledData::Binding::Type_String) {
- QByteArray value(binding->valueAsString(&qmlUnit->header).toUtf8());
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: byte array expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String);
+ QByteArray value(binding->valueAsString(&qmlUnit->header).toUtf8());
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::Url: {
- if (binding->type == QV4::CompiledData::Binding::Type_String) {
- QString string = binding->valueAsString(&qmlUnit->header);
- // Encoded dir-separators defeat QUrl processing - decode them first
- string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
- QUrl value = string.isEmpty() ? QUrl() : this->url.resolved(QUrl(string));
- // Apply URL interceptor
- if (engine->urlInterceptor())
- value = engine->urlInterceptor()->intercept(value, QQmlAbstractUrlInterceptor::UrlString);
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: url expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String);
+ QString string = binding->valueAsString(&qmlUnit->header);
+ // Encoded dir-separators defeat QUrl processing - decode them first
+ string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
+ QUrl value = string.isEmpty() ? QUrl() : this->url.resolved(QUrl(string));
+ // Apply URL interceptor
+ if (engine->urlInterceptor())
+ value = engine->urlInterceptor()->intercept(value, QQmlAbstractUrlInterceptor::UrlString);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::UInt: {
- if (binding->type == QV4::CompiledData::Binding::Type_Number) {
- double d = binding->valueAsNumber();
- if (double(uint(d)) == d) {
- uint value = uint(d);
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- break;
- }
- }
- recordError(binding->location, tr("Invalid property assignment: unsigned int expected"));
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number);
+ double d = binding->valueAsNumber();
+ uint value = uint(d);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
+ break;
}
break;
case QVariant::Int: {
- if (binding->type == QV4::CompiledData::Binding::Type_Number) {
- double d = binding->valueAsNumber();
- if (double(int(d)) == d) {
- int value = int(d);
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- break;
- }
- }
- recordError(binding->location, tr("Invalid property assignment: int expected"));
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number);
+ double d = binding->valueAsNumber();
+ int value = int(d);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
+ break;
}
break;
case QMetaType::Float: {
- if (binding->type == QV4::CompiledData::Binding::Type_Number) {
- float value = float(binding->valueAsNumber());
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: number expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number);
+ float value = float(binding->valueAsNumber());
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::Double: {
- if (binding->type == QV4::CompiledData::Binding::Type_Number) {
- double value = binding->valueAsNumber();
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: number expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number);
+ double value = binding->valueAsNumber();
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::Color: {
bool ok = false;
uint colorValue = QQmlStringConverters::rgbaFromString(binding->valueAsString(&qmlUnit->header), &ok);
-
- if (ok) {
- struct { void *data[4]; } buffer;
- if (QQml_valueTypeProvider()->storeValueType(property->propType, &colorValue, &buffer, sizeof(buffer))) {
- argv[0] = reinterpret_cast<void *>(&buffer);
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- }
- } else {
- recordError(binding->location, tr("Invalid property assignment: color expected"));
+ Q_ASSERT(ok);
+ struct { void *data[4]; } buffer;
+ if (QQml_valueTypeProvider()->storeValueType(property->propType, &colorValue, &buffer, sizeof(buffer))) {
+ argv[0] = reinterpret_cast<void *>(&buffer);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
}
break;
@@ -714,111 +357,87 @@ void QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::C
case QVariant::Date: {
bool ok = false;
QDate value = QQmlStringConverters::dateFromString(binding->valueAsString(&qmlUnit->header), &ok);
- if (ok) {
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: date expected"));
- }
+ Q_ASSERT(ok);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::Time: {
bool ok = false;
QTime value = QQmlStringConverters::timeFromString(binding->valueAsString(&qmlUnit->header), &ok);
- if (ok) {
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: time expected"));
- }
+ Q_ASSERT(ok);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::DateTime: {
bool ok = false;
QDateTime value = QQmlStringConverters::dateTimeFromString(binding->valueAsString(&qmlUnit->header), &ok);
- if (ok) {
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: datetime expected"));
+ // ### VME compatibility :(
+ {
+ const qint64 date = value.date().toJulianDay();
+ const int msecsSinceStartOfDay = value.time().msecsSinceStartOfDay();
+ value = QDateTime(QDate::fromJulianDay(date), QTime::fromMSecsSinceStartOfDay(msecsSinceStartOfDay));
}
+ Q_ASSERT(ok);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
#endif // QT_NO_DATESTRING
case QVariant::Point: {
bool ok = false;
QPoint value = QQmlStringConverters::pointFFromString(binding->valueAsString(&qmlUnit->header), &ok).toPoint();
- if (ok) {
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: point expected"));
- }
+ Q_ASSERT(ok);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::PointF: {
bool ok = false;
QPointF value = QQmlStringConverters::pointFFromString(binding->valueAsString(&qmlUnit->header), &ok);
- if (ok) {
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: point expected"));
- }
+ Q_ASSERT(ok);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::Size: {
bool ok = false;
QSize value = QQmlStringConverters::sizeFFromString(binding->valueAsString(&qmlUnit->header), &ok).toSize();
- if (ok) {
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: size expected"));
- }
+ Q_ASSERT(ok);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::SizeF: {
bool ok = false;
QSizeF value = QQmlStringConverters::sizeFFromString(binding->valueAsString(&qmlUnit->header), &ok);
- if (ok) {
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: size expected"));
- }
+ Q_ASSERT(ok);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::Rect: {
bool ok = false;
QRect value = QQmlStringConverters::rectFFromString(binding->valueAsString(&qmlUnit->header), &ok).toRect();
- if (ok) {
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: point expected"));
- }
+ Q_ASSERT(ok);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::RectF: {
bool ok = false;
QRectF value = QQmlStringConverters::rectFFromString(binding->valueAsString(&qmlUnit->header), &ok);
- if (ok) {
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: point expected"));
- }
+ Q_ASSERT(ok);
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::Bool: {
- if (binding->type == QV4::CompiledData::Binding::Type_Boolean) {
- bool value = binding->valueAsBoolean();
- argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: boolean expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Boolean);
+ bool value = binding->valueAsBoolean();
+ argv[0] = &value;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::Vector3D: {
@@ -827,12 +446,11 @@ void QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::C
float yp;
float zy;
} vec;
- if (QQmlStringConverters::createFromString(QMetaType::QVector3D, binding->valueAsString(&qmlUnit->header), &vec, sizeof(vec))) {
- argv[0] = reinterpret_cast<void *>(&vec);
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: 3D vector expected"));
- }
+ bool ok = QQmlStringConverters::createFromString(QMetaType::QVector3D, binding->valueAsString(&qmlUnit->header), &vec, sizeof(vec));
+ Q_ASSERT(ok);
+ Q_UNUSED(ok);
+ argv[0] = reinterpret_cast<void *>(&vec);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::Vector4D: {
@@ -842,74 +460,55 @@ void QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::C
float zy;
float wp;
} vec;
- if (QQmlStringConverters::createFromString(QMetaType::QVector4D, binding->valueAsString(&qmlUnit->header), &vec, sizeof(vec))) {
- argv[0] = reinterpret_cast<void *>(&vec);
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: 4D vector expected"));
- }
+ bool ok = QQmlStringConverters::createFromString(QMetaType::QVector4D, binding->valueAsString(&qmlUnit->header), &vec, sizeof(vec));
+ Q_ASSERT(ok);
+ Q_UNUSED(ok);
+ argv[0] = reinterpret_cast<void *>(&vec);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
case QVariant::RegExp:
- recordError(binding->location, tr("Invalid property assignment: regular expression expected; use /pattern/ syntax"));
+ Q_ASSERT(!"not possible");
break;
default: {
// generate single literal value assignment to a list property if required
if (property->propType == qMetaTypeId<QList<qreal> >()) {
- if (binding->type == QV4::CompiledData::Binding::Type_Number) {
- QList<qreal> value;
- value.append(binding->valueAsNumber());
- argv[0] = reinterpret_cast<void *>(&value);
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: real or array of reals expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number);
+ QList<qreal> value;
+ value.append(binding->valueAsNumber());
+ argv[0] = reinterpret_cast<void *>(&value);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
break;
} else if (property->propType == qMetaTypeId<QList<int> >()) {
- if (binding->type == QV4::CompiledData::Binding::Type_Number) {
- double n = binding->valueAsNumber();
- if (double(int(n)) == n) {
- QList<int> value;
- value.append(int(n));
- argv[0] = reinterpret_cast<void *>(&value);
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- break;
- } else {
- recordError(binding->location, tr("Invalid property assignment: int or array of ints expected"));
- }
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Number);
+ double n = binding->valueAsNumber();
+ QList<int> value;
+ value.append(int(n));
+ argv[0] = reinterpret_cast<void *>(&value);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
break;
} else if (property->propType == qMetaTypeId<QList<bool> >()) {
- if (binding->type == QV4::CompiledData::Binding::Type_Boolean) {
- QList<bool> value;
- value.append(binding->valueAsBoolean());
- argv[0] = reinterpret_cast<void *>(&value);
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: bool or array of bools expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Boolean);
+ QList<bool> value;
+ value.append(binding->valueAsBoolean());
+ argv[0] = reinterpret_cast<void *>(&value);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
break;
} else if (property->propType == qMetaTypeId<QList<QUrl> >()) {
- if (binding->type == QV4::CompiledData::Binding::Type_String) {
- QString urlString = binding->valueAsString(&qmlUnit->header);
- QUrl u = urlString.isEmpty() ? QUrl() : this->url.resolved(QUrl(urlString));
- QList<QUrl> value;
- value.append(u);
- argv[0] = reinterpret_cast<void *>(&value);
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: url or array of urls expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String);
+ QString urlString = binding->valueAsString(&qmlUnit->header);
+ QUrl u = urlString.isEmpty() ? QUrl() : this->url.resolved(QUrl(urlString));
+ QList<QUrl> value;
+ value.append(u);
+ argv[0] = reinterpret_cast<void *>(&value);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
break;
} else if (property->propType == qMetaTypeId<QList<QString> >()) {
- if (binding->type == QV4::CompiledData::Binding::Type_String) {
- QList<QString> value;
- value.append(binding->valueAsString(&qmlUnit->header));
- argv[0] = reinterpret_cast<void *>(&value);
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: string or array of strings expected"));
- }
+ Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String);
+ QList<QString> value;
+ value.append(binding->valueAsString(&qmlUnit->header));
+ argv[0] = reinterpret_cast<void *>(&value);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
break;
} else if (property->propType == qMetaTypeId<QJSValue>()) {
QJSValue value;
@@ -932,38 +531,45 @@ void QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::C
// otherwise, try a custom type assignment
QString stringValue = binding->valueAsString(&qmlUnit->header);
QQmlMetaType::StringConverter converter = QQmlMetaType::customStringConverter(property->propType);
- if (converter) {
- QVariant value = (*converter)(stringValue);
+ Q_ASSERT(converter);
+ QVariant value = (*converter)(stringValue);
- QMetaProperty metaProperty = _qobject->metaObject()->property(property->coreIndex);
- if (value.isNull() || ((int)metaProperty.type() != property->propType && metaProperty.userType() != property->propType)) {
- recordError(binding->location, tr("Cannot assign value %1 to property %2").arg(stringValue).arg(QString::fromUtf8(metaProperty.name())));
- break;
- }
-
- argv[0] = value.data();
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QMetaType::typeName(property->propType))));
+ QMetaProperty metaProperty = _qobject->metaObject()->property(property->coreIndex);
+ if (value.isNull() || ((int)metaProperty.type() != property->propType && metaProperty.userType() != property->propType)) {
+ recordError(binding->location, tr("Cannot assign value %1 to property %2").arg(stringValue).arg(QString::fromUtf8(metaProperty.name())));
+ break;
}
+
+ argv[0] = value.data();
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
break;
}
}
+static QQmlType *qmlTypeForObject(QObject *object)
+{
+ QQmlType *type = 0;
+ const QMetaObject *mo = object->metaObject();
+ while (mo && !type) {
+ type = QQmlMetaType::qmlType(mo);
+ mo = mo->superClass();
+ }
+ return type;
+}
+
void QmlObjectCreator::setupBindings()
{
QQmlListProperty<void> savedList;
qSwap(_currentList, savedList);
QQmlPropertyData *property = 0;
- bool defaultPropertyQueried = false;
- QQmlPropertyData *defaultProperty = 0;
+ QQmlPropertyData *defaultProperty = _compiledObject->indexOfDefaultProperty != -1 ? _propertyCache->parent()->defaultProperty() : _propertyCache->defaultProperty();
QString id = stringAt(_compiledObject->idIndex);
if (!id.isEmpty()) {
QQmlPropertyData *idProperty = _propertyCache->property(QStringLiteral("id"), _qobject, context);
- if (idProperty) {
+ if (idProperty && idProperty->isWritable()) {
QV4::CompiledData::Binding idBinding;
idBinding.propertyNameIndex = 0; // Not used
idBinding.flags = 0;
@@ -974,6 +580,36 @@ void QmlObjectCreator::setupBindings()
}
}
+ // ### this is best done through type-compile-time binding skip lists.
+ if (_valueTypeProperty) {
+ QQmlAbstractBinding *binding =
+ QQmlPropertyPrivate::binding(_bindingTarget, _valueTypeProperty->coreIndex, -1);
+
+ if (binding && binding->bindingType() != QQmlAbstractBinding::ValueTypeProxy) {
+ QQmlPropertyPrivate::setBinding(_bindingTarget, _valueTypeProperty->coreIndex, -1, 0);
+ binding->destroy();
+ } else if (binding) {
+ QQmlValueTypeProxyBinding *proxy =
+ static_cast<QQmlValueTypeProxyBinding *>(binding);
+
+ if (qmlTypeForObject(_bindingTarget)) {
+ quint32 bindingSkipList = 0;
+
+ const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
+ for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
+ if (binding->type != QV4::CompiledData::Binding::Type_Script)
+ continue;
+ property = binding->propertyNameIndex != 0 ? _propertyCache->property(stringAt(binding->propertyNameIndex), _qobject, context) : defaultProperty;
+ if (property)
+ bindingSkipList |= (1 << property->coreIndex);
+ }
+ property = 0;
+
+ proxy->removeBindings(bindingSkipList);
+ }
+ }
+ }
+
const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
@@ -981,16 +617,18 @@ void QmlObjectCreator::setupBindings()
if (name.isEmpty())
property = 0;
- if (!property || (i > 0 && (binding - 1)->propertyNameIndex != binding->propertyNameIndex)) {
- if (!name.isEmpty())
- property = _propertyCache->property(name, _qobject, context);
- else {
- if (!defaultPropertyQueried) {
- defaultProperty = _propertyCache->defaultProperty();
- defaultPropertyQueried = true;
- }
+ if (!property
+ || (i > 0 && ((binding - 1)->propertyNameIndex != binding->propertyNameIndex
+ || (binding - 1)->flags != binding->flags))
+ ) {
+ if (!name.isEmpty()) {
+ if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression
+ || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
+ property = PropertyResolver(_propertyCache).signal(name, /*notInRevision*/0, _qobject, context);
+ else
+ property = _propertyCache->property(name, _qobject, context);
+ } else
property = defaultProperty;
- }
if (property && property->isQList()) {
void *argv[1] = { (void*)&_currentList };
@@ -1000,29 +638,50 @@ void QmlObjectCreator::setupBindings()
}
- if (!setPropertyValue(property, i, binding))
+ if (!setPropertyBinding(property, binding))
return;
}
qSwap(_currentList, savedList);
}
-bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingIndex, const QV4::CompiledData::Binding *binding)
+bool QmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4::CompiledData::Binding *binding)
{
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
Q_ASSERT(stringAt(qmlUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex).isEmpty());
- QQmlType *attachedType = resolvedTypes.value(binding->propertyNameIndex).type;
+ QQmlCompiledData::TypeReference *tr = resolvedTypes.value(binding->propertyNameIndex);
+ Q_ASSERT(tr);
+ QQmlType *attachedType = tr->type;
const int id = attachedType->attachedPropertiesId();
QObject *qmlObject = qmlAttachedPropertiesObjectById(id, _qobject);
QQmlRefPointer<QQmlPropertyCache> cache = QQmlEnginePrivate::get(engine)->cache(qmlObject);
- if (!populateInstance(binding->value.objectIndex, qmlObject, cache, _qobject, /*value type property*/0))
+ if (!populateInstance(binding->value.objectIndex, qmlObject, cache, qmlObject, /*value type property*/0))
return false;
return true;
}
+ // ### resolve this at compile time
+ if (property && property->propType == qMetaTypeId<QQmlScriptString>()) {
+ QQmlScriptString ss(binding->valueAsScriptString(&qmlUnit->header), context->asQQmlContext(), _scopeObject);
+ ss.d.data()->bindingId = QQmlBinding::Invalid;
+ ss.d.data()->lineNumber = binding->location.line;
+ ss.d.data()->columnNumber = binding->location.column;
+ ss.d.data()->isStringLiteral = binding->type == QV4::CompiledData::Binding::Type_String;
+ ss.d.data()->isNumberLiteral = binding->type == QV4::CompiledData::Binding::Type_Number;
+ ss.d.data()->numberValue = binding->valueAsNumber();
+
+ QQmlPropertyPrivate::WriteFlags propertyWriteFlags = QQmlPropertyPrivate::BypassInterceptor |
+ QQmlPropertyPrivate::RemoveBindingOnAliasWrite;
+ int propertyWriteStatus = -1;
+ void *argv[] = { &ss, 0, &propertyWriteStatus, &propertyWriteFlags };
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
+ return true;
+ }
+
QObject *createdSubObject = 0;
if (binding->type == QV4::CompiledData::Binding::Type_Object) {
- createdSubObject = createInstance(binding->value.objectIndex, _qobject);
+ Q_ASSERT(!_valueTypeProperty);
+ createdSubObject = createInstance(binding->value.objectIndex, _bindingTarget);
if (!createdSubObject)
return false;
}
@@ -1035,11 +694,11 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI
if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) {
QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
- QQmlRefPointer<QQmlPropertyCache> groupedObjCache;
- QObject *groupedObjInstance = 0;
- QObject *objForBindings = _qobjectForBindings;
+ QQmlRefPointer<QQmlPropertyCache> groupObjectPropertyCache;
+ QObject *groupObject = 0;
QQmlValueType *valueType = 0;
QQmlPropertyData *valueTypeProperty = 0;
+ QObject *bindingTarget = _bindingTarget;
if (QQmlValueTypeFactory::isValueType(property->propType)) {
valueType = QQmlValueTypeFactory::valueType(property->propType);
@@ -1050,27 +709,27 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI
valueType->read(_qobject, property->coreIndex);
- groupedObjCache = enginePrivate->cache(valueType);
- groupedObjInstance = valueType;
+ groupObjectPropertyCache = enginePrivate->cache(valueType);
+ groupObject = valueType;
valueTypeProperty = property;
} else {
- groupedObjCache = enginePrivate->propertyCacheForType(property->propType);
- if (!groupedObjCache) {
+ groupObjectPropertyCache = enginePrivate->propertyCacheForType(property->propType);
+ if (!groupObjectPropertyCache) {
recordError(binding->location, tr("Invalid grouped property access"));
return false;
}
- void *argv[1] = { &groupedObjInstance };
+ void *argv[1] = { &groupObject };
QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property->coreIndex, argv);
- if (!groupedObjInstance) {
+ if (!groupObject) {
recordError(binding->location, tr("Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex)));
return false;
}
- objForBindings = groupedObjInstance;
+ bindingTarget = groupObject;
}
- if (!populateInstance(binding->value.objectIndex, groupedObjInstance, groupedObjCache, objForBindings, valueTypeProperty))
+ if (!populateInstance(binding->value.objectIndex, groupObject, groupObjectPropertyCache, bindingTarget, valueTypeProperty))
return false;
if (valueType)
@@ -1080,8 +739,10 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI
}
}
- if (_ddata->hasBindingBit(property->coreIndex))
- removeBindingOnProperty(_qobject, property->coreIndex);
+ if (_ddata->hasBindingBit(property->coreIndex) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression)
+ && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment)
+ && !_valueTypeProperty)
+ removeBindingOnProperty(_bindingTarget, property->coreIndex);
if (binding->type == QV4::CompiledData::Binding::Type_Script) {
QV4::Function *runtimeFunction = jsUnit->runtimeFunctions[binding->value.compiledScriptIndex];
@@ -1091,14 +752,14 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) {
int signalIndex = _propertyCache->methodIndexToSignalIndex(property->coreIndex);
- QQmlBoundSignal *bs = new QQmlBoundSignal(_qobject, signalIndex, _qobject, engine);
- QQmlBoundSignalExpression *expr = new QQmlBoundSignalExpression(_qobject, signalIndex,
- context, _qobject, function);
+ QQmlBoundSignal *bs = new QQmlBoundSignal(_bindingTarget, signalIndex, _scopeObject, engine);
+ QQmlBoundSignalExpression *expr = new QQmlBoundSignalExpression(_bindingTarget, signalIndex,
+ context, _scopeObject, function);
bs->takeExpression(expr);
} else {
- QQmlBinding *qmlBinding = new QQmlBinding(function, _qobject, context,
- QString(), 0, 0); // ###
+ QQmlBinding *qmlBinding = new QQmlBinding(function, _scopeObject, context,
+ context->urlString, binding->location.line, binding->location.column);
// When writing bindings to grouped properties implemented as value types,
// such as point.x: { someExpression; }, then the binding is installed on
@@ -1109,16 +770,82 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI
if (_valueTypeProperty)
targetCorePropertyData = QQmlPropertyPrivate::saveValueType(*_valueTypeProperty, _qobject->metaObject(), property->coreIndex, engine);
- qmlBinding->setTarget(_qobjectForBindings, targetCorePropertyData, context);
- qmlBinding->addToObject();
+ qmlBinding->setTarget(_bindingTarget, targetCorePropertyData, context);
- _createdBindings[bindingIndex] = qmlBinding;
- qmlBinding->m_mePtr = &_createdBindings[bindingIndex];
+ if (targetCorePropertyData.isAlias()) {
+ QQmlAbstractBinding *old =
+ QQmlPropertyPrivate::setBindingNoEnable(_bindingTarget,
+ targetCorePropertyData.coreIndex,
+ targetCorePropertyData.getValueTypeCoreIndex(),
+ qmlBinding);
+ if (old) { old->destroy(); }
+ } else {
+ qmlBinding->addToObject();
+ }
+
+ allCreatedBindings->push(qmlBinding);
+ qmlBinding->m_mePtr = &allCreatedBindings->top();
}
return true;
}
if (binding->type == QV4::CompiledData::Binding::Type_Object) {
+ if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) {
+ // ### determine value source and interceptor casts ahead of time.
+ QQmlType *type = qmlTypeForObject(createdSubObject);
+ Q_ASSERT(type);
+
+ QQmlPropertyData targetCorePropertyData = *property;
+ if (_valueTypeProperty)
+ targetCorePropertyData = QQmlPropertyPrivate::saveValueType(*_valueTypeProperty, _qobject->metaObject(), property->coreIndex, engine);
+
+ int valueSourceCast = type->propertyValueSourceCast();
+ if (valueSourceCast != -1) {
+ QQmlPropertyValueSource *vs = reinterpret_cast<QQmlPropertyValueSource *>(reinterpret_cast<char *>(createdSubObject) + valueSourceCast);
+ QObject *target = createdSubObject->parent();
+ vs->setTarget(QQmlPropertyPrivate::restore(target, targetCorePropertyData, context));
+ return true;
+ }
+ int valueInterceptorCast = type->propertyValueInterceptorCast();
+ if (valueInterceptorCast != -1) {
+ QQmlPropertyValueInterceptor *vi = reinterpret_cast<QQmlPropertyValueInterceptor *>(reinterpret_cast<char *>(createdSubObject) + valueInterceptorCast);
+ QObject *target = createdSubObject->parent();
+
+ QQmlProperty prop =
+ QQmlPropertyPrivate::restore(target, targetCorePropertyData, context);
+ vi->setTarget(prop);
+ QQmlVMEMetaObject *mo = QQmlVMEMetaObject::get(target);
+ Q_ASSERT(mo);
+ mo->registerInterceptor(prop.index(), QQmlPropertyPrivate::valueTypeCoreIndex(prop), vi);
+ return true;
+ }
+ return false;
+ }
+
+ // Assigning object to signal property?
+ if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) {
+ if (!property->isFunction()) {
+ recordError(binding->valueLocation, tr("Cannot assign an object to signal property %1").arg(property->name(_qobject)));
+ return false;
+ }
+ QMetaMethod method = QQmlMetaType::defaultMethod(createdSubObject);
+ if (!method.isValid()) {
+ recordError(binding->valueLocation, tr("Cannot assign object type %1 with no default method").arg(QString::fromLatin1(createdSubObject->metaObject()->className())));
+ return false;
+ }
+
+ QMetaMethod signalMethod = _qobject->metaObject()->method(property->coreIndex);
+ if (!QMetaObject::checkConnectArgs(signalMethod, method)) {
+ recordError(binding->valueLocation, tr("Cannot connect mismatched signal/slot %1 %vs. %2")
+ .arg(QString::fromLatin1(method.methodSignature().constData()))
+ .arg(QString::fromLatin1(signalMethod.methodSignature().constData())));
+ return false;
+ }
+
+ QQmlPropertyPrivate::connect(_qobject, property->coreIndex, createdSubObject, method.methodIndex());
+ return true;
+ }
+
QQmlPropertyPrivate::WriteFlags propertyWriteFlags = QQmlPropertyPrivate::BypassInterceptor |
QQmlPropertyPrivate::RemoveBindingOnAliasWrite;
int propertyWriteStatus = -1;
@@ -1159,33 +886,9 @@ bool QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, int bindingI
if (_currentList.append)
_currentList.append(&_currentList, itemToAdd);
} else {
- QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
-
- // We want to raw metaObject here as the raw metaobject is the
- // actual property type before we applied any extensions that might
- // effect the properties on the type, but don't effect assignability
- QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(property->propType);
-
- // Will be true if the assgned type inherits propertyMetaObject
- bool isAssignable = false;
- // Determine isAssignable value
- if (propertyMetaObject) {
- QQmlPropertyCache *c = propertyCaches.value(binding->value.objectIndex);
- if (!c)
- c = enginePrivate->cache(createdSubObject);
- while (c && !isAssignable) {
- isAssignable |= c == propertyMetaObject;
- c = c->parent();
- }
- }
-
- if (isAssignable) {
- argv[0] = &createdSubObject;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
- } else {
- recordError(binding->location, tr("Cannot assign object to property"));
- return false;
- }
+ // pointer compatibility was tested in QQmlPropertyValidator at type compile time
+ argv[0] = &createdSubObject;
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex, argv);
}
return true;
}
@@ -1203,7 +906,6 @@ void QmlObjectCreator::setupFunctions()
{
QV4::Scope scope(_qmlContext);
QV4::ScopedValue function(scope);
- QQmlVMEMetaObject *vme = QQmlVMEMetaObject::get(_qobject);
const quint32 *functionIdx = _compiledObject->functionOffsetTable();
for (quint32 i = 0; i < _compiledObject->nFunctions; ++i, ++functionIdx) {
@@ -1215,16 +917,28 @@ void QmlObjectCreator::setupFunctions()
continue;
function = QV4::FunctionObject::creatScriptFunction(_qmlContext, runtimeFunction);
- vme->setVmeMethod(property->coreIndex, function);
+ _vmeMetaObject->setVmeMethod(property->coreIndex, function);
}
}
+void QmlObjectCreator::recordError(const QV4::CompiledData::Location &location, const QString &description)
+{
+ QQmlError error;
+ error.setUrl(url);
+ error.setLine(location.line);
+ error.setColumn(location.column);
+ error.setDescription(description);
+ errors << error;
+}
+
QObject *QmlObjectCreator::createInstance(int index, QObject *parent)
{
ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
bool isComponent = false;
QObject *instance = 0;
+ QQmlCustomParser *customParser = 0;
+ QQmlParserStatus *parserStatus = 0;
if (compiledData->isComponent(index)) {
isComponent = true;
@@ -1234,30 +948,41 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent)
} else {
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
- QQmlCompiledData::TypeReference typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
- QQmlType *type = typeRef.type;
+ QQmlCompiledData::TypeReference *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
+ Q_ASSERT(typeRef);
+ QQmlType *type = typeRef->type;
if (type) {
instance = type->create();
if (!instance) {
recordError(obj->location, tr("Unable to create object of type %1").arg(stringAt(obj->inheritedTypeNameIndex)));
return 0;
}
+
+ const int parserStatusCast = type->parserStatusCast();
+ if (parserStatusCast != -1)
+ parserStatus = reinterpret_cast<QQmlParserStatus*>(reinterpret_cast<char *>(instance) + parserStatusCast);
+
+ customParser = type->customParser();
+
+ if (rootContext->isRootObjectInCreation) {
+ QQmlData *ddata = QQmlData::get(instance, /*create*/true);
+ ddata->rootObjectInCreation = true;
+ rootContext->isRootObjectInCreation = false;
+ }
} else {
- Q_ASSERT(typeRef.component);
- if (typeRef.component->qmlUnit->isSingleton())
+ Q_ASSERT(typeRef->component);
+ if (typeRef->component->qmlUnit->isSingleton())
{
recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
return 0;
}
- QmlObjectCreator subCreator(context, typeRef.component);
+ QmlObjectCreator subCreator(context, typeRef->component, creationContext, rootContext, allCreatedBindings, allParserStatusCallbacks);
+ subCreator.componentAttached = componentAttached;
instance = subCreator.create();
if (!instance) {
errors += subCreator.errors;
return 0;
}
- if (subCreator.componentAttached)
- subCreator.componentAttached->add(&componentAttached);
- allCreatedBindings << subCreator.allCreatedBindings;
}
// ### use no-event variant
if (parent)
@@ -1265,6 +990,7 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent)
}
QQmlData *ddata = QQmlData::get(instance, /*create*/true);
+ ddata->setImplicitDestructible();
if (static_cast<quint32>(index) == qmlUnit->indexOfRootObject) {
if (ddata->context) {
Q_ASSERT(ddata->context != context);
@@ -1281,50 +1007,103 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent)
ddata->outerContext = context;
+ if (parserStatus) {
+ parserStatus->classBegin();
+ allParserStatusCallbacks->push(parserStatus);
+ parserStatus->d = &allParserStatusCallbacks->top();
+ }
+
QHash<int, int>::ConstIterator idEntry = objectIndexToId.find(index);
if (idEntry != objectIndexToId.constEnd())
context->setIdProperty(idEntry.value(), instance);
- if (!isComponent) {
- QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.value(index);
- Q_ASSERT(!cache.isNull());
-
- if (!populateInstance(index, instance, cache, instance, /*value type property*/0))
- return 0;
+ if (customParser) {
+ QHash<int, QByteArray>::ConstIterator entry = compiledData->customParserData.find(index);
+ if (entry != compiledData->customParserData.constEnd())
+ customParser->setCustomData(instance, *entry);
}
- return instance;
+ if (isComponent)
+ return instance;
+
+ QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.value(index);
+ Q_ASSERT(!cache.isNull());
+
+ QObject *scopeObject = instance;
+ qSwap(_scopeObject, scopeObject);
+
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope valueScope(v4);
+ QV4::ScopedValue scopeObjectProtector(valueScope, ddata ? ddata->jsWrapper.value() : 0);
+ Q_UNUSED(scopeObjectProtector);
+ QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject));
+ QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, qmlScope));
+ QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context();
+
+ qSwap(_qmlContext, qmlContext);
+
+ bool result = populateInstance(index, instance, cache, /*binding target*/instance, /*value type property*/0);
+
+ qSwap(_qmlContext, qmlContext);
+ qSwap(_scopeObject, scopeObject);
+
+ return result ? instance : 0;
}
-void QmlObjectCreator::finalize()
+QQmlContextData *QmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
{
{
QQmlTrace trace("VME Binding Enable");
trace.event("begin binding eval");
- Q_ASSERT(allCreatedBindings.isEmpty() || allCreatedBindings.isDetached());
+ while (!allCreatedBindings->isEmpty()) {
+ if (interrupt.shouldInterrupt())
+ return 0;
- for (QLinkedList<QVector<QQmlAbstractBinding*> >::Iterator it = allCreatedBindings.begin(), end = allCreatedBindings.end();
- it != end; ++it) {
- const QVector<QQmlAbstractBinding *> &bindings = *it;
- for (int i = 0; i < bindings.count(); ++i) {
- QQmlAbstractBinding *b = bindings.at(i);
- if (!b)
- continue;
- b->m_mePtr = 0;
- QQmlData *data = QQmlData::get(b->object());
- Q_ASSERT(data);
- data->clearPendingBindingBit(b->propertyIndex());
- b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor |
- QQmlPropertyPrivate::DontRemoveBinding);
+ QQmlAbstractBinding *b = allCreatedBindings->pop();
+ if (!b)
+ continue;
+ b->m_mePtr = 0;
+ QQmlData *data = QQmlData::get(b->object());
+ Q_ASSERT(data);
+ data->clearPendingBindingBit(b->propertyIndex());
+ b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor |
+ QQmlPropertyPrivate::DontRemoveBinding);
+ }
+ }
+
+ if (true /* ### componentCompleteEnabled()*/) { // the qml designer does the component complete later
+ QQmlTrace trace("VME Component Complete");
+ while (!allParserStatusCallbacks->isEmpty()) {
+ QQmlParserStatus *status = allParserStatusCallbacks->pop();
+
+ if (status && status->d) {
+ status->d = 0;
+ status->componentComplete();
+ }
+
+ if (interrupt.shouldInterrupt())
+ return 0;
+ }
+ }
+
+ {
+ QQmlTrace trace("VME Finalize Callbacks");
+ for (int ii = 0; ii < finalizeCallbacks.count(); ++ii) {
+ QQmlEnginePrivate::FinalizeCallback callback = finalizeCallbacks.at(ii);
+ QObject *obj = callback.first;
+ if (obj) {
+ void *args[] = { 0 };
+ QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, callback.second, args);
}
}
+ finalizeCallbacks.clear();
}
{
QQmlTrace trace("VME Component.onCompleted Callbacks");
- while (componentAttached) {
- QQmlComponentAttached *a = componentAttached;
+ while (componentAttachedImpl) {
+ QQmlComponentAttached *a = componentAttachedImpl;
a->rem();
QQmlData *d = QQmlData::get(a->parent());
Q_ASSERT(d);
@@ -1333,42 +1112,39 @@ void QmlObjectCreator::finalize()
// ### designer if (componentCompleteEnabled())
emit a->completed();
-#if 0 // ###
- if (watcher.hasRecursed() || interrupt.shouldInterrupt())
+ if (interrupt.shouldInterrupt())
return 0;
-#endif
}
}
+
+ return rootContext;
}
-bool QmlObjectCreator::populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache,
- QObject *scopeObjectForBindings, QQmlPropertyData *valueTypeProperty)
+bool QmlObjectCreator::populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty)
{
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(index);
- Q_ASSERT(scopeObjectForBindings);
-
QQmlData *declarativeData = QQmlData::get(instance, /*create*/true);
qSwap(_propertyCache, cache);
qSwap(_qobject, instance);
- qSwap(_qobjectForBindings, scopeObjectForBindings);
qSwap(_valueTypeProperty, valueTypeProperty);
qSwap(_compiledObject, obj);
qSwap(_ddata, declarativeData);
+ qSwap(_bindingTarget, bindingTarget);
QQmlVMEMetaObject *vmeMetaObject = 0;
const QByteArray data = vmeMetaObjectData.value(index);
if (!data.isEmpty()) {
// install on _object
- vmeMetaObject = new QQmlVMEMetaObject(_qobjectForBindings, _propertyCache, reinterpret_cast<const QQmlVMEMetaData*>(data.constData()));
+ vmeMetaObject = new QQmlVMEMetaObject(_qobject, _propertyCache, reinterpret_cast<const QQmlVMEMetaData*>(data.constData()));
if (_ddata->propertyCache)
_ddata->propertyCache->release();
- _ddata->propertyCache = _propertyCache;
- _ddata->propertyCache->addref();
} else {
- vmeMetaObject = QQmlVMEMetaObject::get(_qobjectForBindings);
+ vmeMetaObject = QQmlVMEMetaObject::get(_qobject);
}
+ _ddata->propertyCache = _propertyCache;
+ _ddata->propertyCache->addref();
_ddata->lineNumber = _compiledObject->location.line;
_ddata->columnNumber = _compiledObject->location.column;
@@ -1376,389 +1152,19 @@ bool QmlObjectCreator::populateInstance(int index, QObject *instance, QQmlRefPoi
qSwap(_vmeMetaObject, vmeMetaObject);
QVector<QQmlAbstractBinding*> createdBindings(_compiledObject->nBindings, 0);
- qSwap(_createdBindings, createdBindings);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
- QV4::Scope valueScope(v4);
- QV4::ScopedObject scopeObject(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _qobjectForBindings));
- QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, scopeObject));
- QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context();
-
- qSwap(_qmlContext, qmlContext);
-
- setupBindings();
setupFunctions();
+ setupBindings();
- allCreatedBindings.append(_createdBindings);
-
- qSwap(_qmlContext, qmlContext);
-
- qSwap(_createdBindings, createdBindings);
qSwap(_vmeMetaObject, vmeMetaObject);
- qSwap(_propertyCache, cache);
+ qSwap(_bindingTarget, bindingTarget);
qSwap(_ddata, declarativeData);
qSwap(_compiledObject, obj);
qSwap(_valueTypeProperty, valueTypeProperty);
- qSwap(_qobjectForBindings, scopeObjectForBindings);
qSwap(_qobject, instance);
+ qSwap(_propertyCache, cache);
return errors.isEmpty();
}
-QQmlComponentAndAliasResolver::QQmlComponentAndAliasResolver(const QUrl &url, const QV4::CompiledData::QmlUnit *qmlUnit,
- const QHash<int, QQmlCompiledData::TypeReference> &resolvedTypes,
- const QList<QQmlPropertyCache *> &propertyCaches, QList<QByteArray> *vmeMetaObjectData,
- QHash<int, int> *objectIndexToIdForRoot,
- QHash<int, QHash<int, int> > *objectIndexToIdPerComponent)
- : QQmlCompilePass(url, qmlUnit)
- , _componentIndex(-1)
- , _objectIndexToIdInScope(0)
- , resolvedTypes(resolvedTypes)
- , propertyCaches(propertyCaches)
- , vmeMetaObjectData(vmeMetaObjectData)
- , objectIndexToIdForRoot(objectIndexToIdForRoot)
- , objectIndexToIdPerComponent(objectIndexToIdPerComponent)
-{
-}
-
-bool QQmlComponentAndAliasResolver::resolve()
-{
- Q_ASSERT(componentRoots.isEmpty());
-
- // Find objects that are Components. This is missing an extra pass
- // that finds implicitly defined components, i.e.
- // someProperty: Item { ... }
- // when someProperty _is_ a QQmlComponent. In that case the Item {}
- // should be implicitly surrounded by Component {}
-
- for (quint32 i = 0; i < qmlUnit->nObjects; ++i) {
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(i);
- if (stringAt(obj->inheritedTypeNameIndex).isEmpty())
- continue;
-
- QQmlCompiledData::TypeReference tref = resolvedTypes.value(obj->inheritedTypeNameIndex);
- if (!tref.type)
- continue;
- if (tref.type->metaObject() != &QQmlComponent::staticMetaObject)
- continue;
-
- componentRoots.append(i);
- // Sanity checks: There can be only an (optional) id property and
- // a default property, that defines the component tree.
- }
-
- std::sort(componentRoots.begin(), componentRoots.end());
-
- // For each component's tree, remember to which component the children
- // belong to
- for (int i = 0; i < componentRoots.count(); ++i) {
- const QV4::CompiledData::Object *component = qmlUnit->objectAt(componentRoots.at(i));
-
- if (component->nFunctions > 0)
- COMPILE_EXCEPTION(component, tr("Component objects cannot declare new functions."));
- if (component->nProperties > 0)
- COMPILE_EXCEPTION(component, tr("Component objects cannot declare new properties."));
- if (component->nSignals > 0)
- COMPILE_EXCEPTION(component, tr("Component objects cannot declare new signals."));
-
- if (component->nBindings == 0)
- COMPILE_EXCEPTION(component, tr("Cannot create empty component specification"));
-
- const QV4::CompiledData::Binding *rootBinding = component->bindingTable();
- if (component->nBindings > 1 || rootBinding->type != QV4::CompiledData::Binding::Type_Object)
- COMPILE_EXCEPTION(rootBinding, tr("Component elements may not contain properties other than id"));
-
- _componentIndex = i;
- _idToObjectIndex.clear();
-
- _objectIndexToIdInScope = &(*objectIndexToIdPerComponent)[componentRoots.at(i)];
-
- _objectsWithAliases.clear();
-
- if (!collectIdsAndAliases(rootBinding->value.objectIndex))
- return false;
-
- if (!resolveAliases())
- return false;
- }
-
- // Collect ids and aliases for root
- _componentIndex = -1;
- _idToObjectIndex.clear();
- _objectIndexToIdInScope = objectIndexToIdForRoot;
- _objectsWithAliases.clear();
-
- collectIdsAndAliases(qmlUnit->indexOfRootObject);
-
- resolveAliases();
-
- return errors.isEmpty();
-}
-
-bool QQmlComponentAndAliasResolver::collectIdsAndAliases(int objectIndex)
-{
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(objectIndex);
-
- // Only include creatable types. Everything else is synthetic, such as group property
- // objects.
- if (_componentIndex != -1 && !stringAt(obj->inheritedTypeNameIndex).isEmpty())
- objectIndexToComponentIndex.insert(objectIndex, _componentIndex);
-
- QString id = stringAt(obj->idIndex);
- if (!id.isEmpty()) {
- if (_idToObjectIndex.contains(obj->idIndex)) {
- recordError(obj->locationOfIdProperty, tr("id is not unique"));
- return false;
- }
- _idToObjectIndex.insert(obj->idIndex, objectIndex);
- _objectIndexToIdInScope->insert(objectIndex, _objectIndexToIdInScope->count());
- }
-
- const QV4::CompiledData::Property *property = obj->propertyTable();
- for (quint32 i = 0; i < obj->nProperties; ++i, ++property)
- if (property->type == QV4::CompiledData::Property::Alias) {
- _objectsWithAliases.append(objectIndex);
- break;
- }
-
- const QV4::CompiledData::Binding *binding = obj->bindingTable();
- for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) {
- if (binding->type != QV4::CompiledData::Binding::Type_Object
- && binding->type != QV4::CompiledData::Binding::Type_AttachedProperty
- && binding->type != QV4::CompiledData::Binding::Type_GroupProperty)
- continue;
-
- // Stop at Component boundary
- if (std::binary_search(componentRoots.constBegin(), componentRoots.constEnd(), binding->value.objectIndex))
- continue;
-
- if (!collectIdsAndAliases(binding->value.objectIndex))
- return false;
- }
-
- return true;
-}
-
-bool QQmlComponentAndAliasResolver::resolveAliases()
-{
- foreach (int objectIndex, _objectsWithAliases) {
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(objectIndex);
-
- QQmlPropertyCache *propertyCache = propertyCaches.value(objectIndex);
- Q_ASSERT(propertyCache);
-
- int effectiveSignalIndex = propertyCache->signalHandlerIndexCacheStart + propertyCache->propertyIndexCache.count();
- int effectivePropertyIndex = propertyCache->propertyIndexCacheStart + propertyCache->propertyIndexCache.count();
- int effectiveAliasIndex = 0;
-
- const QV4::CompiledData::Property *p = obj->propertyTable();
- for (quint32 propertyIndex = 0; propertyIndex < obj->nProperties; ++propertyIndex, ++p) {
- if (p->type != QV4::CompiledData::Property::Alias)
- continue;
-
- const int idIndex = p->aliasIdValueIndex;
- const int targetObjectIndex = _idToObjectIndex.value(idIndex, -1);
- if (targetObjectIndex == -1) {
- recordError(p->aliasLocation, tr("Invalid alias reference. Unable to find id \"%1\"").arg(stringAt(idIndex)));
- return false;
- }
- const int targetId = _objectIndexToIdInScope->value(targetObjectIndex, -1);
- Q_ASSERT(targetId != -1);
-
- const QString aliasPropertyValue = stringAt(p->aliasPropertyValueIndex);
-
- QStringRef property;
- QStringRef subProperty;
-
- const int propertySeparator = aliasPropertyValue.indexOf(QLatin1Char('.'));
- if (propertySeparator != -1) {
- property = aliasPropertyValue.leftRef(propertySeparator);
- subProperty = aliasPropertyValue.midRef(propertySeparator + 1);
- } else
- property = QStringRef(&aliasPropertyValue, 0, aliasPropertyValue.length());
-
- int propIdx = -1;
- int propType = 0;
- int notifySignal = -1;
- int flags = 0;
- int type = 0;
- bool writable = false;
- bool resettable = false;
-
- quint32 propertyFlags = QQmlPropertyData::IsAlias;
-
- if (property.isEmpty()) {
- const QV4::CompiledData::Object *targetObject = qmlUnit->objectAt(targetObjectIndex);
- QQmlCompiledData::TypeReference typeRef = resolvedTypes.value(targetObject->inheritedTypeNameIndex);
-
- if (typeRef.type)
- type = typeRef.type->typeId();
- else
- type = typeRef.component->metaTypeId;
-
- flags |= QML_ALIAS_FLAG_PTR;
- propertyFlags |= QQmlPropertyData::IsQObjectDerived;
- } else {
- QQmlPropertyCache *targetCache = propertyCaches.value(targetObjectIndex);
- Q_ASSERT(targetCache);
- QtQml::PropertyResolver resolver(targetCache);
-
- QQmlPropertyData *targetProperty = resolver.property(property.toString());
- if (!targetProperty || targetProperty->coreIndex > 0x0000FFFF) {
- recordError(p->aliasLocation, tr("Invalid alias location"));
- return false;
- }
-
- propIdx = targetProperty->coreIndex;
- type = targetProperty->propType;
-
- writable = targetProperty->isWritable();
- resettable = targetProperty->isResettable();
- notifySignal = targetProperty->notifyIndex;
-
- if (!subProperty.isEmpty()) {
- QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type);
- if (!valueType) {
- recordError(p->aliasLocation, tr("Invalid alias location"));
- return false;
- }
-
- propType = type;
-
- int valueTypeIndex =
- valueType->metaObject()->indexOfProperty(subProperty.toString().toUtf8().constData());
- if (valueTypeIndex == -1) {
- recordError(p->aliasLocation, tr("Invalid alias location"));
- return false;
- }
- Q_ASSERT(valueTypeIndex <= 0x0000FFFF);
-
- propIdx |= (valueTypeIndex << 16);
- if (valueType->metaObject()->property(valueTypeIndex).isEnumType())
- type = QVariant::Int;
- else
- type = valueType->metaObject()->property(valueTypeIndex).userType();
-
- } else {
- if (targetProperty->isEnum()) {
- type = QVariant::Int;
- } else {
- // Copy type flags
- propertyFlags |= targetProperty->getFlags() & QQmlPropertyData::PropTypeFlagMask;
-
- if (targetProperty->isVarProperty())
- propertyFlags |= QQmlPropertyData::IsQVariant;
-
- if (targetProperty->isQObject())
- flags |= QML_ALIAS_FLAG_PTR;
- }
- }
- }
-
- QQmlVMEMetaData::AliasData aliasData = { targetId, propIdx, propType, flags, notifySignal };
-
- typedef QQmlVMEMetaData VMD;
- QByteArray &dynamicData = (*vmeMetaObjectData)[objectIndex];
- Q_ASSERT(!dynamicData.isEmpty());
- VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
- *(vmd->aliasData() + effectiveAliasIndex++) = aliasData;
-
- Q_ASSERT(dynamicData.isDetached());
-
- if (!(p->flags & QV4::CompiledData::Property::IsReadOnly) && writable)
- propertyFlags |= QQmlPropertyData::IsWritable;
- else
- propertyFlags &= ~QQmlPropertyData::IsWritable;
-
- if (resettable)
- propertyFlags |= QQmlPropertyData::IsResettable;
- else
- propertyFlags &= ~QQmlPropertyData::IsResettable;
-
- QString propertyName = stringAt(p->nameIndex);
- if (propertyIndex == obj->indexOfDefaultProperty) propertyCache->_defaultPropertyName = propertyName;
- propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- type, effectiveSignalIndex++);
-
- }
- }
- return true;
-}
-
-
-QQmlPropertyValidator::QQmlPropertyValidator(const QUrl &url, const QV4::CompiledData::QmlUnit *qmlUnit,
- const QHash<int, QQmlCompiledData::TypeReference> &resolvedTypes,
- const QList<QQmlPropertyCache *> &propertyCaches, const QHash<int, QHash<int, int> > &objectIndexToIdPerComponent)
- : QQmlCompilePass(url, qmlUnit)
- , resolvedTypes(resolvedTypes)
- , propertyCaches(propertyCaches)
- , objectIndexToIdPerComponent(objectIndexToIdPerComponent)
-{
-}
-
-bool QQmlPropertyValidator::validate()
-{
- for (quint32 i = 0; i < qmlUnit->nObjects; ++i) {
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(i);
- if (stringAt(obj->inheritedTypeNameIndex).isEmpty())
- continue;
-
- if (isComponent(i))
- continue;
-
- QQmlPropertyCache *propertyCache = propertyCaches.value(i);
- Q_ASSERT(propertyCache);
-
- if (!validateObject(obj, i, propertyCache))
- return false;
- }
- return true;
-}
-
-bool QQmlPropertyValidator::validateObject(const QV4::CompiledData::Object *obj, int objectIndex, QQmlPropertyCache *propertyCache)
-{
- PropertyResolver propertyResolver(propertyCache);
-
- QQmlPropertyData *defaultProperty = propertyCache->defaultProperty();
-
- const QV4::CompiledData::Binding *binding = obj->bindingTable();
- for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) {
- if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty
- || binding->type == QV4::CompiledData::Binding::Type_GroupProperty)
- continue;
-
- const QString name = stringAt(binding->propertyNameIndex);
-
- bool bindingToDefaultProperty = false;
-
- bool notInRevision = false;
- QQmlPropertyData *pd = 0;
- if (!name.isEmpty()) {
- pd = propertyResolver.property(name, &notInRevision);
-
- if (notInRevision) {
- QString typeName = stringAt(obj->inheritedTypeNameIndex);
- QQmlCompiledData::TypeReference type = resolvedTypes.value(objectIndex);
- if (type.type) {
- COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(type.type->module()).arg(type.majorVersion).arg(type.minorVersion));
- } else {
- COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(name));
- }
- }
- } else {
- pd = defaultProperty;
- bindingToDefaultProperty = true;
- }
-
- if (!pd) {
- if (bindingToDefaultProperty) {
- COMPILE_EXCEPTION(binding, tr("Cannot assign to non-existent default property"));
- } else {
- COMPILE_EXCEPTION(binding, tr("Cannot assign to non-existent property \"%1\"").arg(name));
- }
- }
- }
-
- return true;
-}
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index ec4b362491..68f2eaeab3 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -45,139 +45,73 @@
#include <private/qqmltypenamecache_p.h>
#include <private/qv4compileddata_p.h>
#include <private/qqmlcompiler_p.h>
-#include <QLinkedList>
+#include <private/qqmltypecompiler_p.h>
+#include <private/qfinitestack_p.h>
QT_BEGIN_NAMESPACE
class QQmlAbstractBinding;
+struct QQmlTypeCompiler;
+class QQmlInstantiationInterrupt;
-struct QQmlCompilePass
-{
- QQmlCompilePass(const QUrl &url, const QV4::CompiledData::QmlUnit *unit);
- QList<QQmlError> errors;
-
-protected:
- QString stringAt(int idx) const { return qmlUnit->header.stringAt(idx); }
- void recordError(const QV4::CompiledData::Location &location, const QString &description);
-
- const QUrl url;
- const QV4::CompiledData::QmlUnit *qmlUnit;
-};
-
-class QQmlPropertyCacheCreator : public QQmlCompilePass
-{
- Q_DECLARE_TR_FUNCTIONS(QQmlPropertyCacheCreator)
-public:
- QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QV4::CompiledData::QmlUnit *qmlUnit,
- const QUrl &url, const QQmlImports *imports,
- QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes);
-
- bool create(const QV4::CompiledData::Object *obj, QQmlPropertyCache **cache, QByteArray *vmeMetaObjectData);
-
-protected:
- QQmlEnginePrivate *enginePrivate;
- const QQmlImports *imports;
- QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes;
-};
-
-class QQmlComponentAndAliasResolver : public QQmlCompilePass
-{
- Q_DECLARE_TR_FUNCTIONS(QQmlAnonymousComponentResolver)
-public:
- QQmlComponentAndAliasResolver(const QUrl &url, const QV4::CompiledData::QmlUnit *qmlUnit,
- const QHash<int, QQmlCompiledData::TypeReference> &resolvedTypes,
- const QList<QQmlPropertyCache *> &propertyCaches,
- QList<QByteArray> *vmeMetaObjectData,
- QHash<int, int> *objectIndexToIdForRoot,
- QHash<int, QHash<int, int> > *objectIndexToIdPerComponent);
-
- bool resolve();
-
- QVector<int> componentRoots;
- QHash<int, int> objectIndexToComponentIndex;
-
-protected:
- bool collectIdsAndAliases(int objectIndex);
- bool resolveAliases();
-
- bool isComponentType(int typeNameIndex) const
- { return resolvedTypes.value(typeNameIndex).type == 0; }
-
- int _componentIndex;
- QHash<int, int> _idToObjectIndex;
- QHash<int, int> *_objectIndexToIdInScope;
- QList<int> _objectsWithAliases;
-
- const QHash<int, QQmlCompiledData::TypeReference> resolvedTypes;
- const QList<QQmlPropertyCache *> propertyCaches;
- QList<QByteArray> *vmeMetaObjectData;
- QHash<int, int> *objectIndexToIdForRoot;
- QHash<int, QHash<int, int> > *objectIndexToIdPerComponent;
-};
-
-class QQmlPropertyValidator : public QQmlCompilePass
-{
- Q_DECLARE_TR_FUNCTIONS(QQmlPropertyValidator)
-public:
- QQmlPropertyValidator(const QUrl &url, const QV4::CompiledData::QmlUnit *qmlUnit,
- const QHash<int, QQmlCompiledData::TypeReference> &resolvedTypes,
- const QList<QQmlPropertyCache *> &propertyCaches,
- const QHash<int, QHash<int, int> > &objectIndexToIdPerComponent);
-
- bool validate();
-
-private:
- bool validateObject(const QV4::CompiledData::Object *obj, int objectIndex, QQmlPropertyCache *propertyCache);
-
- bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); }
-
- const QHash<int, QQmlCompiledData::TypeReference> &resolvedTypes;
- const QList<QQmlPropertyCache *> &propertyCaches;
- const QHash<int, QHash<int, int> > objectIndexToIdPerComponent;
-};
-
-class QmlObjectCreator : public QQmlCompilePass
+class QmlObjectCreator
{
Q_DECLARE_TR_FUNCTIONS(QmlObjectCreator)
public:
- QmlObjectCreator(QQmlContextData *contextData, QQmlCompiledData *compiledData);
+ QmlObjectCreator(QQmlContextData *contextData, QQmlCompiledData *compiledData, QQmlContextData *creationContext, QQmlContextData *rootContext = 0,
+ QFiniteStack<QQmlAbstractBinding*> *inheritedBindingStack = 0, QFiniteStack<QQmlParserStatus*> *inheritedParserStatusStack = 0);
+ ~QmlObjectCreator();
QObject *create(int subComponentIndex = -1, QObject *parent = 0);
- void finalize();
+ QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
- QQmlComponentAttached *componentAttached;
+ QQmlComponentAttached **componentAttached;
QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
+ QList<QQmlError> errors;
+
+ QQmlContextData *parentContextData() const { return parentContext; }
+
private:
QObject *createInstance(int index, QObject *parent = 0);
- bool populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache,
- QObject *scopeObjectForJavaScript, QQmlPropertyData *valueTypeProperty);
+ bool populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty);
void setupBindings();
- bool setPropertyValue(QQmlPropertyData *property, int index, const QV4::CompiledData::Binding *binding);
+ bool setPropertyBinding(QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
void setPropertyValue(QQmlPropertyData *property, const QV4::CompiledData::Binding *binding);
void setupFunctions();
+ QString stringAt(int idx) const { return qmlUnit->header.stringAt(idx); }
+ void recordError(const QV4::CompiledData::Location &location, const QString &description);
+
+ QUrl url;
QQmlEngine *engine;
+ const QV4::CompiledData::QmlUnit *qmlUnit;
const QV4::CompiledData::CompilationUnit *jsUnit;
QQmlContextData *parentContext;
+ QQmlContextData *creationContext;
QQmlContextData *context;
- const QHash<int, QQmlCompiledData::TypeReference> resolvedTypes;
- const QList<QQmlPropertyCache *> propertyCaches;
- const QList<QByteArray> vmeMetaObjectData;
+ const QHash<int, QQmlCompiledData::TypeReference*> resolvedTypes;
+ const QVector<QQmlPropertyCache *> propertyCaches;
+ const QVector<QByteArray> vmeMetaObjectData;
QHash<int, int> objectIndexToId;
- QLinkedList<QVector<QQmlAbstractBinding*> > allCreatedBindings;
+ QFiniteStack<QQmlAbstractBinding*> *allCreatedBindings;
+ QFiniteStack<QQmlParserStatus*> *allParserStatusCallbacks;
+ bool ownBindingAndParserStatusStacks;
QQmlCompiledData *compiledData;
+ QQmlContextData *rootContext;
+ QQmlComponentAttached *componentAttachedImpl;
QObject *_qobject;
- QObject *_qobjectForBindings;
+ QObject *_scopeObject;
+ QObject *_bindingTarget;
+
QQmlPropertyData *_valueTypeProperty; // belongs to _qobjectForBindings's property cache
const QV4::CompiledData::Object *_compiledObject;
QQmlData *_ddata;
QQmlRefPointer<QQmlPropertyCache> _propertyCache;
QQmlVMEMetaObject *_vmeMetaObject;
- QVector<QQmlAbstractBinding*> _createdBindings;
QQmlListProperty<void> _currentList;
QV4::ExecutionContext *_qmlContext;
};
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index 5745f35498..4d2c3d0332 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -254,7 +254,7 @@ int QQmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
propertyWritten(propId);
activate(d->object, d->type->d->signalOffset + propId, 0);
}
- }
+ }
return -1;
} else {
if (d->parent)
diff --git a/src/qml/qml/qqmlparserstatus.cpp b/src/qml/qml/qqmlparserstatus.cpp
index 41b7d962ce..0da22fb668 100644
--- a/src/qml/qml/qqmlparserstatus.cpp
+++ b/src/qml/qml/qqmlparserstatus.cpp
@@ -109,7 +109,7 @@ QQmlParserStatus::~QQmlParserStatus()
/*!
\fn void QQmlParserStatus::componentComplete()
- Invoked after the root component that caused this instantiation has
+ Invoked after the root component that caused this instantiation has
completed construction. At this point all static values and binding values
have been assigned to the class.
*/
diff --git a/src/qml/qml/qqmlparserstatus.h b/src/qml/qml/qqmlparserstatus.h
index d3447e7752..1d63afd978 100644
--- a/src/qml/qml/qqmlparserstatus.h
+++ b/src/qml/qml/qqmlparserstatus.h
@@ -62,6 +62,7 @@ private:
friend class QQmlComponent;
friend class QQmlComponentPrivate;
friend class QQmlEnginePrivate;
+ friend class QmlObjectCreator;
QQmlParserStatus **d;
};
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 15306cb131..90e7961e6b 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -85,8 +85,8 @@ namespace QQmlPrivate
class QQmlElement : public T
{
public:
- virtual ~QQmlElement() {
- QQmlPrivate::qdeclarativeelement_destructor(this);
+ virtual ~QQmlElement() {
+ QQmlPrivate::qdeclarativeelement_destructor(this);
}
};
@@ -130,7 +130,7 @@ namespace QQmlPrivate
};
template <typename T, bool hasMember>
- class has_attachedPropertiesMethod
+ class has_attachedPropertiesMethod
{
public:
typedef int yes_type;
@@ -141,7 +141,7 @@ namespace QQmlPrivate
static no_type check(...);
static bool const value = sizeof(check(&T::qmlAttachedProperties)) == sizeof(yes_type);
- };
+ };
template <typename T>
class has_attachedPropertiesMethod<T, false>
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 3975b88bb0..0bbcafda54 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1250,7 +1250,7 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object,
return rv;
}
-bool QQmlPropertyPrivate::write(QObject *object,
+bool QQmlPropertyPrivate::write(QObject *object,
const QQmlPropertyData &property,
const QVariant &value, QQmlContextData *context,
WriteFlags flags)
diff --git a/src/qml/qml/qqmlproperty.h b/src/qml/qml/qqmlproperty.h
index c3322c0048..992d579aed 100644
--- a/src/qml/qml/qqmlproperty.h
+++ b/src/qml/qml/qqmlproperty.h
@@ -64,7 +64,7 @@ public:
Normal
};
- enum Type {
+ enum Type {
Invalid,
Property,
SignalProperty
diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h
index ce15061ba0..28e9dca515 100644
--- a/src/qml/qml/qqmlproperty_p.h
+++ b/src/qml/qml/qqmlproperty_p.h
@@ -101,11 +101,11 @@ public:
bool writeValueProperty(const QVariant &, WriteFlags);
static QQmlMetaObject rawMetaObjectForType(QQmlEnginePrivate *, int);
- static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object,
+ static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object,
const QVariant &value, int flags);
static bool writeValueProperty(QObject *,
const QQmlPropertyData &,
- const QVariant &, QQmlContextData *,
+ const QVariant &, QQmlContextData *,
WriteFlags flags = 0);
static bool write(QObject *, const QQmlPropertyData &, const QVariant &,
QQmlContextData *, WriteFlags flags = 0);
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 6c40557886..a0af0e94ef 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -50,7 +50,7 @@
#include <private/qqmlaccessors_p.h>
#include <private/qmetaobjectbuilder_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <QtCore/qdebug.h>
@@ -1140,7 +1140,7 @@ QString QQmlPropertyCache::signalParameterStringForJS(QQmlEngine *engine, const
{
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
bool unnamedParameter = false;
- const QV4::IdentifierHash<bool> &illegalNames = ep->v8engine()->illegalNames();
+ const QSet<QString> &illegalNames = ep->v8engine()->illegalNames();
QString error;
QString parameters;
@@ -1195,7 +1195,7 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index,
int argc = m.parameterCount();
if (!rv->arguments) {
- A *args = c->createArgumentsObject(argc);
+ A *args = c->createArgumentsObject(argc, m.parameterNames());
rv->arguments = args;
}
A *args = static_cast<A *>(rv->arguments);
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index bc0cef9f4c..fe7f204e87 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -62,7 +62,7 @@
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qvector.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
QT_BEGIN_NAMESPACE
@@ -351,7 +351,7 @@ private:
QQmlPropertyData::Flag signalFlags = QQmlPropertyData::NoFlags);
QQmlPropertyCacheMethodArguments *createArgumentsObject(int count,
- const QList<QByteArray> &names = QList<QByteArray>());
+ const QList<QByteArray> &names);
QQmlPropertyData *signal(int, QQmlPropertyCache **) const;
typedef QVector<QQmlPropertyData> IndexCache;
diff --git a/src/qml/qml/qqmlproxymetaobject.cpp b/src/qml/qml/qqmlproxymetaobject.cpp
index 8a6af7cb05..282cbb7a21 100644
--- a/src/qml/qml/qqmlproxymetaobject.cpp
+++ b/src/qml/qml/qqmlproxymetaobject.cpp
@@ -78,7 +78,7 @@ int QQmlProxyMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
if (id >= data.propertyOffset) {
if (!proxies) {
proxies = new QObject*[metaObjects->count()];
- ::memset(proxies, 0,
+ ::memset(proxies, 0,
sizeof(QObject *) * metaObjects->count());
}
@@ -93,7 +93,7 @@ int QQmlProxyMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
// ### - Can this be done more optimally?
for (int jj = 0; jj < methods; ++jj) {
- QMetaMethod method =
+ QMetaMethod method =
metaObject->method(jj + methodOffset);
if (method.methodType() == QMetaMethod::Signal)
QQmlPropertyPrivate::connect(proxy, methodOffset + jj, object, localOffset + jj);
diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp
index 6cb23ec07c..0618c90fa5 100644
--- a/src/qml/qml/qqmlscript.cpp
+++ b/src/qml/qml/qqmlscript.cpp
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
using namespace QQmlJS;
using namespace QQmlScript;
-//
+//
// Parser IR classes
//
QQmlScript::Object::Object()
@@ -68,8 +68,8 @@ QQmlScript::Object::Object()
{
}
-QQmlScript::Object::~Object()
-{
+QQmlScript::Object::~Object()
+{
if (synthCache) synthCache->release();
}
@@ -215,7 +215,7 @@ int QQmlScript::Object::DynamicSlot::parameterNamesLength() const
}
QQmlScript::Property::Property()
-: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false),
+: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false),
isValueTypeSubProperty(false), isAlias(false), isReadOnlyDeclaration(false),
scriptStringScope(-1), nextMainProperty(0), nextProperty(0)
{
@@ -354,7 +354,7 @@ QString escapedString(const QString &string)
QString QQmlScript::Variant::asScript() const
{
- switch(type()) {
+ switch (type()) {
default:
case Invalid:
return QString();
@@ -363,7 +363,7 @@ QString QQmlScript::Variant::asScript() const
case Number:
if (asWritten.isEmpty())
return QString::number(d);
- else
+ else
return asWritten.toString();
case String:
return escapedString(asString());
@@ -727,7 +727,7 @@ ProcessAST::defineObjectBinding(AST::Node *node,
} else {
// Class
- QQmlScript::Object *obj = _parser->_pool.New<QQmlScript::Object>();
+ QQmlScript::Object *obj = _parser->_pool.New<QQmlScript::Object>();
obj->type = _parser->findOrCreateTypeId(objectType, obj);
obj->typeReference = _parser->_refTypes.at(obj->type);
@@ -1034,11 +1034,11 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
bool typeFound = false;
Object::DynamicProperty::Type type;
- if ((unsigned)memberType.length() == strlen("alias") &&
+ if ((unsigned)memberType.length() == strlen("alias") &&
QHashedString::compare(memberType.constData(), "alias", int(strlen("alias")))) {
type = Object::DynamicProperty::Alias;
typeFound = true;
- }
+ }
for(int ii = 0; !typeFound && ii < propTypeNameToTypesCount; ++ii) {
const TypeNameToType *t = propTypeNameToTypes + ii;
@@ -1054,7 +1054,7 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
if (typeModifier.isEmpty()) {
type = Object::DynamicProperty::Custom;
- } else if((unsigned)typeModifier.length() == strlen("list") &&
+ } else if ((unsigned)typeModifier.length() == strlen("list") &&
QHashedString::compare(typeModifier.constData(), "list", int(strlen("list")))) {
type = Object::DynamicProperty::CustomList;
} else {
@@ -1411,7 +1411,7 @@ QList<QQmlError> QQmlScript::Parser::errors() const
return _errors;
}
-static void replaceWithSpace(QString &str, int idx, int n)
+static void replaceWithSpace(QString &str, int idx, int n)
{
QChar *data = str.data() + idx;
const QChar space(QLatin1Char(' '));
@@ -1490,42 +1490,42 @@ QQmlScript::Object::ScriptBlock::Pragmas QQmlScript::Parser::extractPragmas(QStr
#define CHECK_TOKEN(t) if (token != QQmlJSGrammar:: t) return rv;
static const int uriTokens[] = {
- QQmlJSGrammar::T_IDENTIFIER,
- QQmlJSGrammar::T_PROPERTY,
- QQmlJSGrammar::T_SIGNAL,
- QQmlJSGrammar::T_READONLY,
- QQmlJSGrammar::T_ON,
- QQmlJSGrammar::T_BREAK,
- QQmlJSGrammar::T_CASE,
- QQmlJSGrammar::T_CATCH,
- QQmlJSGrammar::T_CONTINUE,
- QQmlJSGrammar::T_DEFAULT,
- QQmlJSGrammar::T_DELETE,
- QQmlJSGrammar::T_DO,
- QQmlJSGrammar::T_ELSE,
- QQmlJSGrammar::T_FALSE,
- QQmlJSGrammar::T_FINALLY,
- QQmlJSGrammar::T_FOR,
- QQmlJSGrammar::T_FUNCTION,
- QQmlJSGrammar::T_IF,
- QQmlJSGrammar::T_IN,
- QQmlJSGrammar::T_INSTANCEOF,
- QQmlJSGrammar::T_NEW,
- QQmlJSGrammar::T_NULL,
- QQmlJSGrammar::T_RETURN,
- QQmlJSGrammar::T_SWITCH,
- QQmlJSGrammar::T_THIS,
- QQmlJSGrammar::T_THROW,
- QQmlJSGrammar::T_TRUE,
- QQmlJSGrammar::T_TRY,
- QQmlJSGrammar::T_TYPEOF,
- QQmlJSGrammar::T_VAR,
- QQmlJSGrammar::T_VOID,
- QQmlJSGrammar::T_WHILE,
- QQmlJSGrammar::T_CONST,
- QQmlJSGrammar::T_DEBUGGER,
- QQmlJSGrammar::T_RESERVED_WORD,
- QQmlJSGrammar::T_WITH,
+ QQmlJSGrammar::T_IDENTIFIER,
+ QQmlJSGrammar::T_PROPERTY,
+ QQmlJSGrammar::T_SIGNAL,
+ QQmlJSGrammar::T_READONLY,
+ QQmlJSGrammar::T_ON,
+ QQmlJSGrammar::T_BREAK,
+ QQmlJSGrammar::T_CASE,
+ QQmlJSGrammar::T_CATCH,
+ QQmlJSGrammar::T_CONTINUE,
+ QQmlJSGrammar::T_DEFAULT,
+ QQmlJSGrammar::T_DELETE,
+ QQmlJSGrammar::T_DO,
+ QQmlJSGrammar::T_ELSE,
+ QQmlJSGrammar::T_FALSE,
+ QQmlJSGrammar::T_FINALLY,
+ QQmlJSGrammar::T_FOR,
+ QQmlJSGrammar::T_FUNCTION,
+ QQmlJSGrammar::T_IF,
+ QQmlJSGrammar::T_IN,
+ QQmlJSGrammar::T_INSTANCEOF,
+ QQmlJSGrammar::T_NEW,
+ QQmlJSGrammar::T_NULL,
+ QQmlJSGrammar::T_RETURN,
+ QQmlJSGrammar::T_SWITCH,
+ QQmlJSGrammar::T_THIS,
+ QQmlJSGrammar::T_THROW,
+ QQmlJSGrammar::T_TRUE,
+ QQmlJSGrammar::T_TRY,
+ QQmlJSGrammar::T_TYPEOF,
+ QQmlJSGrammar::T_VAR,
+ QQmlJSGrammar::T_VOID,
+ QQmlJSGrammar::T_WHILE,
+ QQmlJSGrammar::T_CONST,
+ QQmlJSGrammar::T_DEBUGGER,
+ QQmlJSGrammar::T_RESERVED_WORD,
+ QQmlJSGrammar::T_WITH,
QQmlJSGrammar::EOF_SYMBOL
};
diff --git a/src/qml/qml/qqmlscript_p.h b/src/qml/qml/qqmlscript_p.h
index fac31add5c..29da97fe83 100644
--- a/src/qml/qml/qqmlscript_p.h
+++ b/src/qml/qml/qqmlscript_p.h
@@ -72,14 +72,14 @@ namespace QQmlCompilerTypes { struct BindingReference; struct ComponentCompileSt
namespace QQmlScript {
-struct Location
+struct Location
{
Location() : line(0), column(0) {}
quint16 line;
quint16 column;
inline bool operator<(const Location &other) {
- return line < other.line ||
+ return line < other.line ||
(line == other.line && column < other.column);
}
};
@@ -253,12 +253,12 @@ public:
void addValue(Value *v);
void addOnValue(Value *v);
- // The QVariant::Type of the property, or 0 (QVariant::Invalid) if
+ // The QVariant::Type of the property, or 0 (QVariant::Invalid) if
// unknown.
int type;
// The metaobject index of this property, or -1 if unknown.
int index;
- // The core data in the case of a regular property.
+ // The core data in the case of a regular property.
// XXX This has to be a value now as the synthCache may change during
// compilation which invalidates pointers. We should fix this.
QQmlPropertyData core;
@@ -280,14 +280,14 @@ public:
const QHashedStringRef &name() const { return _name; }
void setName(const QString &n) { _name = QHashedStringRef(pool()->NewString(n)); }
void setName(const QHashedStringRef &n) { _name = n; }
- // True if this property was accessed as the default property.
+ // True if this property was accessed as the default property.
bool isDefault;
// True if the setting of this property will be deferred. Set by the
// QQmlCompiler
bool isDeferred;
// True if this property is a value-type pseudo-property
bool isValueTypeSubProperty;
- // True if this property is a property alias. Set by the
+ // True if this property is a property alias. Set by the
// QQmlCompiler
bool isAlias;
// True if this is a readonly property declaration
@@ -314,9 +314,9 @@ class Object : public QQmlPool::Class
{
public:
Object();
- virtual ~Object();
+ virtual ~Object();
- // Type of the object. The integer is an index into the
+ // Type of the object. The integer is an index into the
// QQmlCompiledData::types array, or -1 if the object is a property
// group.
int type;
@@ -331,7 +331,7 @@ public:
// Custom parsed data
QByteArray custom;
// Bit mask of the properties assigned bindings
- QByteArray bindingBitmask;
+ QByteArray bindingBitmask;
void setBindingBit(int);
QQmlPropertyCache *metatype;
@@ -374,7 +374,7 @@ public:
// Script blocks that were nested under this object
struct ScriptBlock {
- enum Pragma {
+ enum Pragma {
None = 0x00000000,
Shared = 0x00000001
};
@@ -385,14 +385,14 @@ public:
Pragmas pragmas;
};
- // The bytes to cast instances by to get to the QQmlParserStatus
+ // The bytes to cast instances by to get to the QQmlParserStatus
// interface. -1 indicates the type doesn't support this interface.
// Set by the QQmlCompiler.
int parserStatusCast;
LocationSpan location;
- struct DynamicProperty : public QQmlPool::POD
+ struct DynamicProperty : public QQmlPool::POD
{
DynamicProperty();
@@ -500,7 +500,7 @@ public:
class JavaScriptMetaData {
public:
- JavaScriptMetaData()
+ JavaScriptMetaData()
: pragmas(QQmlScript::Object::ScriptBlock::None) {}
QQmlScript::Object::ScriptBlock::Pragmas pragmas;
diff --git a/src/qml/qml/qqmlscriptstring.h b/src/qml/qml/qqmlscriptstring.h
index 5421ef95fc..852e7d629d 100644
--- a/src/qml/qml/qqmlscriptstring.h
+++ b/src/qml/qml/qqmlscriptstring.h
@@ -53,7 +53,8 @@ QT_BEGIN_NAMESPACE
class QObject;
class QQmlContext;
class QQmlScriptStringPrivate;
-class Q_QML_EXPORT QQmlScriptString
+class QmlObjectCreator;
+class Q_QML_EXPORT QQmlScriptString
{
public:
QQmlScriptString();
@@ -74,6 +75,7 @@ private:
QQmlScriptString(const QString &script, QQmlContext *context, QObject *scope);
QSharedDataPointer<QQmlScriptStringPrivate> d;
+ friend class QmlObjectCreator;
friend class QQmlScriptStringPrivate;
friend class QQmlVME;
friend class QQmlExpression;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 6eda55e35b..7c32d4f19c 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -52,6 +52,7 @@
#include <private/qqmlprofilerservice_p.h>
#include <private/qqmlmemoryprofiler_p.h>
#include <private/qqmlcodegenerator_p.h>
+#include <private/qqmltypecompiler_p.h>
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
@@ -93,7 +94,7 @@
#else
-#define ASSERT_MAINTHREAD()
+#define ASSERT_MAINTHREAD()
#define ASSERT_LOADTHREAD()
#define ASSERT_CALLBACK()
@@ -115,9 +116,9 @@ namespace {
}
// This is a lame object that we need to ensure that slots connected to
-// QNetworkReply get called in the correct thread (the loader thread).
+// QNetworkReply get called in the correct thread (the loader thread).
// As QQmlDataLoader lives in the main thread, and we can't use
-// Qt::DirectConnection connections from a QNetworkReply (because then
+// Qt::DirectConnection connections from a QNetworkReply (because then
// sender() wont work), we need to insert this object in the middle.
class QQmlDataLoaderNetworkReplyProxy : public QObject
{
@@ -167,8 +168,8 @@ private:
};
-QQmlDataLoaderNetworkReplyProxy::QQmlDataLoaderNetworkReplyProxy(QQmlDataLoader *l)
-: l(l)
+QQmlDataLoaderNetworkReplyProxy::QQmlDataLoaderNetworkReplyProxy(QQmlDataLoader *l)
+: l(l)
{
}
@@ -240,7 +241,7 @@ This enum describes the type of the data blob.
Create a new QQmlDataBlob for \a url and of the provided \a type.
*/
QQmlDataBlob::QQmlDataBlob(const QUrl &url, Type type)
-: m_type(type), m_url(url), m_finalUrl(url), m_manager(0), m_redirectCount(0),
+: m_type(type), m_url(url), m_finalUrl(url), m_manager(0), m_redirectCount(0),
m_inCallback(false), m_isDone(false)
{
}
@@ -395,7 +396,7 @@ QList<QQmlError> QQmlDataBlob::errors() const
/*!
Mark this blob as having \a errors.
-All outstanding dependencies will be cancelled. Requests to add new dependencies
+All outstanding dependencies will be cancelled. Requests to add new dependencies
will be ignored. Entry into the Error state is irreversable.
The setError() method may only be called from within a QQmlDataBlob callback.
@@ -433,8 +434,8 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors)
tryDone();
}
-/*!
-Wait for \a blob to become complete or to error. If \a blob is already
+/*!
+Wait for \a blob to become complete or to error. If \a blob is already
complete or in error, or this blob is already complete, this has no effect.
The setError() method may only be called from within a QQmlDataBlob callback.
@@ -447,7 +448,7 @@ void QQmlDataBlob::addDependency(QQmlDataBlob *blob)
if (!blob ||
blob->status() == Error || blob->status() == Complete ||
- status() == Error || status() == Complete || m_isDone ||
+ status() == Error || status() == Complete || m_isDone ||
m_waitingFor.contains(blob))
return;
@@ -468,7 +469,7 @@ or addDependency().
*/
/*!
-Invoked once data has either been received or a network error occurred, and all
+Invoked once data has either been received or a network error occurred, and all
dependencies are complete.
You can set an error in this method, but you cannot add new dependencies. Implementors
@@ -536,7 +537,7 @@ void QQmlDataBlob::networkError(QNetworkReply::NetworkError networkError)
setError(error);
}
-/*!
+/*!
Called if \a blob, which was previously waited for, has an error.
The default implementation does nothing.
@@ -556,9 +557,9 @@ void QQmlDataBlob::dependencyComplete(QQmlDataBlob *blob)
Q_UNUSED(blob);
}
-/*!
-Called when all blobs waited for have completed. This occurs regardless of
-whether they are in error, or complete state.
+/*!
+Called when all blobs waited for have completed. This occurs regardless of
+whether they are in error, or complete state.
The default implementation does nothing.
*/
@@ -570,9 +571,9 @@ void QQmlDataBlob::allDependenciesDone()
Called when the download progress of this blob changes. \a progress goes
from 0 to 1.
-This callback is only invoked if an asynchronous load for this blob is
+This callback is only invoked if an asynchronous load for this blob is
made. An asynchronous load is one in which the Asynchronous mode is
-specified explicitly, or one that is implicitly delayed due to a network
+specified explicitly, or one that is implicitly delayed due to a network
operation.
The default implementation does nothing.
@@ -586,12 +587,12 @@ void QQmlDataBlob::downloadProgressChanged(qreal progress)
Invoked on the main thread sometime after done() was called on the load thread.
You cannot modify the blobs state at all in this callback and cannot depend on the
-order or timeliness of these callbacks. Implementors should use this callback to notify
+order or timeliness of these callbacks. Implementors should use this callback to notify
dependencies on the main thread that the blob is done and not a lot else.
-This callback is only invoked if an asynchronous load for this blob is
+This callback is only invoked if an asynchronous load for this blob is
made. An asynchronous load is one in which the Asynchronous mode is
-specified explicitly, or one that is implicitly delayed due to a network
+specified explicitly, or one that is implicitly delayed due to a network
operation.
The default implementation does nothing.
@@ -669,7 +670,7 @@ void QQmlDataBlob::notifyComplete(QQmlDataBlob *blob)
blob->release();
- if (!isError() && m_waitingFor.isEmpty())
+ if (!isError() && m_waitingFor.isEmpty())
allDependenciesDone();
m_inCallback = false;
@@ -753,10 +754,10 @@ QQmlDataLoaderNetworkReplyProxy *QQmlDataLoaderThread::networkReplyProxy() const
return m_networkReplyProxy;
}
-void QQmlDataLoaderThread::load(QQmlDataBlob *b)
-{
+void QQmlDataLoaderThread::load(QQmlDataBlob *b)
+{
b->addref();
- callMethodInThread(&This::loadThread, b);
+ callMethodInThread(&This::loadThread, b);
}
void QQmlDataLoaderThread::loadAsync(QQmlDataBlob *b)
@@ -777,19 +778,19 @@ void QQmlDataLoaderThread::loadWithStaticDataAsync(QQmlDataBlob *b, const QByteA
postMethodToThread(&This::loadWithStaticDataThread, b, d);
}
-void QQmlDataLoaderThread::callCompleted(QQmlDataBlob *b)
-{
- b->addref();
- postMethodToMain(&This::callCompletedMain, b);
+void QQmlDataLoaderThread::callCompleted(QQmlDataBlob *b)
+{
+ b->addref();
+ postMethodToMain(&This::callCompletedMain, b);
}
-void QQmlDataLoaderThread::callDownloadProgressChanged(QQmlDataBlob *b, qreal p)
-{
- b->addref();
- postMethodToMain(&This::callDownloadProgressChangedMain, b, p);
+void QQmlDataLoaderThread::callDownloadProgressChanged(QQmlDataBlob *b, qreal p)
+{
+ b->addref();
+ postMethodToMain(&This::callDownloadProgressChangedMain, b, p);
}
-void QQmlDataLoaderThread::initializeEngine(QQmlExtensionInterface *iface,
+void QQmlDataLoaderThread::initializeEngine(QQmlExtensionInterface *iface,
const char *uri)
{
callMethodInMain(&This::initializeEngineMain, iface, uri);
@@ -803,9 +804,9 @@ void QQmlDataLoaderThread::shutdownThread()
m_networkReplyProxy = 0;
}
-void QQmlDataLoaderThread::loadThread(QQmlDataBlob *b)
-{
- m_loader->loadThread(b);
+void QQmlDataLoaderThread::loadThread(QQmlDataBlob *b)
+{
+ m_loader->loadThread(b);
b->release();
}
@@ -815,27 +816,27 @@ void QQmlDataLoaderThread::loadWithStaticDataThread(QQmlDataBlob *b, const QByte
b->release();
}
-void QQmlDataLoaderThread::callCompletedMain(QQmlDataBlob *b)
-{
+void QQmlDataLoaderThread::callCompletedMain(QQmlDataBlob *b)
+{
QML_MEMORY_SCOPE_URL(b->url());
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataLoaderThread: %s completed() callback", qPrintable(b->url().toString()));
+ qWarning("QQmlDataLoaderThread: %s completed() callback", qPrintable(b->url().toString()));
#endif
- b->completed();
- b->release();
+ b->completed();
+ b->release();
}
-void QQmlDataLoaderThread::callDownloadProgressChangedMain(QQmlDataBlob *b, qreal p)
-{
+void QQmlDataLoaderThread::callDownloadProgressChangedMain(QQmlDataBlob *b, qreal p)
+{
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataLoaderThread: %s downloadProgressChanged(%f) callback",
- qPrintable(b->url().toString()), p);
+ qWarning("QQmlDataLoaderThread: %s downloadProgressChanged(%f) callback",
+ qPrintable(b->url().toString()), p);
#endif
- b->downloadProgressChanged(p);
- b->release();
+ b->downloadProgressChanged(p);
+ b->release();
}
-void QQmlDataLoaderThread::initializeEngineMain(QQmlExtensionInterface *iface,
+void QQmlDataLoaderThread::initializeEngineMain(QQmlExtensionInterface *iface,
const char *uri)
{
Q_ASSERT(m_loader->engine()->thread() == QThread::currentThread());
@@ -855,7 +856,7 @@ The loader then fetches the data over the network or from the local file system
QQmlDataBlob is an abstract class, so should always be specialized.
Once data is received, the QQmlDataBlob::dataReceived() method is invoked on the blob. The
-derived class should use this callback to process the received data. Processing of the data can
+derived class should use this callback to process the received data. Processing of the data can
result in an error being set (QQmlDataBlob::setError()), or one or more dependencies being
created (QQmlDataBlob::addDependency()). Dependencies are other QQmlDataBlob's that
are required before processing can fully complete.
@@ -883,7 +884,7 @@ QQmlDataLoader::QQmlDataLoader(QQmlEngine *engine)
/*! \internal */
QQmlDataLoader::~QQmlDataLoader()
{
- for (NetworkReplies::Iterator iter = m_networkReplies.begin(); iter != m_networkReplies.end(); ++iter)
+ for (NetworkReplies::Iterator iter = m_networkReplies.begin(); iter != m_networkReplies.end(); ++iter)
(*iter)->release();
shutdownThread();
@@ -908,7 +909,7 @@ The loader must be locked.
void QQmlDataLoader::load(QQmlDataBlob *blob, Mode mode)
{
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataLoader::load(%s): %s thread", qPrintable(blob->m_url.toString()),
+ qWarning("QQmlDataLoader::load(%s): %s thread", qPrintable(blob->m_url.toString()),
m_thread->isThisThread()?"Compile":"Engine");
#endif
blob->startLoading(this);
@@ -940,7 +941,7 @@ The loader must be locked.
void QQmlDataLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &data, Mode mode)
{
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataLoader::loadWithStaticData(%s, data): %s thread", qPrintable(blob->m_url.toString()),
+ qWarning("QQmlDataLoader::loadWithStaticData(%s, data): %s thread", qPrintable(blob->m_url.toString()),
m_thread->isThisThread()?"Compile":"Engine");
#endif
@@ -1117,7 +1118,7 @@ QQmlEngine *QQmlDataLoader::engine() const
Call the initializeEngine() method on \a iface. Used by QQmlImportDatabase to ensure it
gets called in the correct thread.
*/
-void QQmlDataLoader::initializeEngine(QQmlExtensionInterface *iface,
+void QQmlDataLoader::initializeEngine(QQmlExtensionInterface *iface,
const char *uri)
{
Q_ASSERT(m_thread->isThisThread() || engine()->thread() == QThread::currentThread());
@@ -1157,7 +1158,7 @@ void QQmlDataLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::Data &d)
if (!blob->isError() && !blob->isWaiting())
blob->allDependenciesDone();
- if (blob->status() != QQmlDataBlob::Error)
+ if (blob->status() != QQmlDataBlob::Error)
blob->m_data.setStatus(QQmlDataBlob::WaitingForDependencies);
blob->m_inCallback = false;
@@ -1524,12 +1525,12 @@ Returns a QQmlTypeData for the specified \a url. The QQmlTypeData may be cached
*/
QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode)
{
- Q_ASSERT(!url.isRelative() &&
+ Q_ASSERT(!url.isRelative() &&
(QQmlFile::urlToLocalFileOrQrc(url).isEmpty() ||
!QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url))));
LockHolder<QQmlTypeLoader> holder(this);
-
+
QQmlTypeData *typeData = m_typeCache.value(url);
if (!typeData) {
@@ -1545,7 +1546,7 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode)
}
/*!
-Returns a QQmlTypeData for the given \a data with the provided base \a url. The
+Returns a QQmlTypeData for the given \a data with the provided base \a url. The
QQmlTypeData will not be cached.
*/
QQmlTypeData *QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url)
@@ -1563,7 +1564,7 @@ Return a QQmlScriptBlob for \a url. The QQmlScriptData may be cached.
*/
QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &url)
{
- Q_ASSERT(!url.isRelative() &&
+ Q_ASSERT(!url.isRelative() &&
(QQmlFile::urlToLocalFileOrQrc(url).isEmpty() ||
!QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url))));
@@ -1587,7 +1588,7 @@ Returns a QQmlQmldirData for \a url. The QQmlQmldirData may be cached.
*/
QQmlQmldirData *QQmlTypeLoader::getQmldir(const QUrl &url)
{
- Q_ASSERT(!url.isRelative() &&
+ Q_ASSERT(!url.isRelative() &&
(QQmlFile::urlToLocalFileOrQrc(url).isEmpty() ||
!QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url))));
@@ -1904,7 +1905,7 @@ void QQmlTypeLoader::clearCache()
{
for (TypeCache::Iterator iter = m_typeCache.begin(); iter != m_typeCache.end(); ++iter)
(*iter)->release();
- for (ScriptCache::Iterator iter = m_scriptCache.begin(); iter != m_scriptCache.end(); ++iter)
+ for (ScriptCache::Iterator iter = m_scriptCache.begin(); iter != m_scriptCache.end(); ++iter)
(*iter)->release();
for (QmldirCache::Iterator iter = m_qmldirCache.begin(); iter != m_qmldirCache.end(); ++iter)
(*iter)->release();
@@ -1970,9 +1971,9 @@ QQmlTypeData::QQmlTypeData(const QUrl &url, QQmlTypeLoader *manager)
QQmlTypeData::~QQmlTypeData()
{
- for (int ii = 0; ii < m_scripts.count(); ++ii)
+ for (int ii = 0; ii < m_scripts.count(); ++ii)
m_scripts.at(ii).script->release();
- for (int ii = 0; ii < m_types.count(); ++ii)
+ for (int ii = 0; ii < m_types.count(); ++ii)
if (m_types.at(ii).typeData) m_types.at(ii).typeData->release();
if (m_compiledData)
m_compiledData->release();
@@ -2109,7 +2110,7 @@ void QQmlTypeData::done()
}
// Compile component
- if (!isError())
+ if (!isError())
compile();
scriptParser.clear();
@@ -2154,8 +2155,9 @@ void QQmlTypeData::dataReceived(const Data &data)
if (data.isFile()) preparseData = data.asFile()->metaData(QLatin1String("qml:preparse"));
if (m_useNewCompiler) {
- parsedQML.reset(new QtQml::ParsedQML(QV8Engine::getV4(typeLoader()->engine())->debugger != 0));
- QQmlCodeGenerator compiler;
+ QQmlEngine *qmlEngine = typeLoader()->engine();
+ parsedQML.reset(new QtQml::ParsedQML(QV8Engine::getV4(qmlEngine)->debugger != 0));
+ QQmlCodeGenerator compiler(QV8Engine::get(qmlEngine)->illegalNames());
if (!compiler.generateFromQml(code, finalUrl(), finalUrlString(), parsedQML.data())) {
setError(compiler.errors);
return;
@@ -2305,173 +2307,9 @@ void QQmlTypeData::compile()
QQmlCompilingProfiler prof(m_compiledData->name);
if (m_useNewCompiler) {
- m_compiledData->importCache = new QQmlTypeNameCache;
-
- foreach (const QString &ns, m_namespaces)
- m_compiledData->importCache->add(ns);
-
- // Add any Composite Singletons that were used to the import cache
- for (int i = 0; i < compositeSingletons().count(); ++i) {
- m_compiledData->importCache->add(compositeSingletons().at(i).type->qmlTypeName(),
- compositeSingletons().at(i).type->sourceUrl(), compositeSingletons().at(i).prefix);
- }
-
- m_imports.populateCache(m_compiledData->importCache);
- m_compiledData->importCache->addref();
-
- QQmlEngine *engine = typeLoader()->engine();
- QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
-
- for (QHash<int, TypeReference>::ConstIterator resolvedType = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd();
- resolvedType != end; ++resolvedType) {
- QQmlCompiledData::TypeReference ref;
- if (resolvedType->typeData) {
- ref.component = resolvedType->typeData->compiledData();
- ref.component->addref();
- } else {
- ref.type = resolvedType->type;
- Q_ASSERT(ref.type);
- }
- ref.majorVersion = resolvedType->majorVersion;
- ref.minorVersion = resolvedType->minorVersion;
- m_compiledData->resolvedTypes.insert(resolvedType.key(), ref);
- }
-
- {
- SignalHandlerConverter converter(QQmlEnginePrivate::get(engine),
- parsedQML.data(),
- m_compiledData);
- if (!converter.convertSignalHandlerExpressionsToFunctionDeclarations()) {
- setError(converter.errors);
- m_compiledData->release();
- m_compiledData = 0;
- return;
- }
- }
-
- // Collect imported scripts
- m_compiledData->scripts.reserve(m_scripts.count());
- for (int scriptIndex = 0; scriptIndex < m_scripts.count(); ++scriptIndex) {
- const ScriptReference &script = m_scripts.at(scriptIndex);
-
- QString qualifier = script.qualifier;
- QString enclosingNamespace;
-
- const int lastDotIndex = qualifier.lastIndexOf(QLatin1Char('.'));
- if (lastDotIndex != -1) {
- enclosingNamespace = qualifier.left(lastDotIndex);
- qualifier = qualifier.mid(lastDotIndex+1);
- }
-
- m_compiledData->importCache->add(qualifier, scriptIndex, enclosingNamespace);
- QQmlScriptData *scriptData = script.script->scriptData();
- scriptData->addref();
- m_compiledData->scripts << scriptData;
- }
-
- // Compile JS binding expressions and signal handlers
-
- JSCodeGen jsCodeGen(finalUrlString(), parsedQML->code, &parsedQML->jsModule, &parsedQML->jsParserEngine, parsedQML->program, m_compiledData->importCache);
- const QVector<int> runtimeFunctionIndices = jsCodeGen.generateJSCodeForFunctionsAndBindings(parsedQML->functions);
-
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine());
-
- QScopedPointer<QQmlJS::EvalInstructionSelection> isel(v4->iselFactory->create(enginePrivate, v4->executableAllocator, &parsedQML->jsModule, &parsedQML->jsGenerator));
- isel->setUseFastLookups(false);
- QV4::CompiledData::CompilationUnit *jsUnit = isel->compile(/*generated unit data*/false);
-
- // Generate QML compiled type data structures
-
- QmlUnitGenerator qmlGenerator;
- QV4::CompiledData::QmlUnit *qmlUnit = qmlGenerator.generate(*parsedQML.data(), runtimeFunctionIndices);
-
- if (jsUnit) {
- Q_ASSERT(!jsUnit->data);
- jsUnit->ownsData = false;
- jsUnit->data = &qmlUnit->header;
- }
-
- m_compiledData->compilationUnit = jsUnit;
- if (m_compiledData->compilationUnit)
- m_compiledData->compilationUnit->ref();
- m_compiledData->qmlUnit = qmlUnit; // ownership transferred to m_compiledData
-
- QList<QQmlError> errors;
-
- // Build property caches and VME meta object data
-
- m_compiledData->datas.reserve(qmlUnit->nObjects);
- m_compiledData->propertyCaches.reserve(qmlUnit->nObjects);
-
- QQmlPropertyCacheCreator propertyCacheBuilder(enginePrivate,
- qmlUnit, m_compiledData->url,
- &m_imports, &m_compiledData->resolvedTypes);
-
- for (quint32 i = 0; i < qmlUnit->nObjects; ++i) {
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(i);
-
- QByteArray vmeMetaObjectData;
- QQmlPropertyCache *propertyCache = 0;
-
- // If the object has no type, then it's probably a nested object definition as part
- // of a group property.
- const bool objectHasType = !parsedQML->jsGenerator.strings.at(obj->inheritedTypeNameIndex).isEmpty();
- if (objectHasType) {
- if (!propertyCacheBuilder.create(obj, &propertyCache, &vmeMetaObjectData)) {
- errors << propertyCacheBuilder.errors;
- break;
- }
- }
-
- m_compiledData->datas << vmeMetaObjectData;
- if (propertyCache)
- propertyCache->addref();
- m_compiledData->propertyCaches << propertyCache;
-
- if (i == qmlUnit->indexOfRootObject) {
- Q_ASSERT(propertyCache);
- m_compiledData->rootPropertyCache = propertyCache;
- propertyCache->addref();
- }
- }
-
- // Resolve component boundaries and aliases
-
- if (errors.isEmpty()) {
- // Scan for components, determine their scopes and resolve aliases within the scope.
- QQmlComponentAndAliasResolver resolver(m_compiledData->url, m_compiledData->qmlUnit, m_compiledData->resolvedTypes, m_compiledData->propertyCaches,
- &m_compiledData->datas, &m_compiledData->objectIndexToIdForRoot, &m_compiledData->objectIndexToIdPerComponent);
- if (!resolver.resolve())
- errors << resolver.errors;
- }
-
- if (errors.isEmpty()) {
- // Add to type registry of composites
- if (m_compiledData->isCompositeType())
- QQmlEnginePrivate::get(engine)->registerInternalCompositeType(m_compiledData);
- else {
- const QV4::CompiledData::Object *obj = qmlUnit->objectAt(qmlUnit->indexOfRootObject);
- QQmlCompiledData::TypeReference typeRef = m_compiledData->resolvedTypes.value(obj->inheritedTypeNameIndex);
- if (typeRef.component) {
- m_compiledData->metaTypeId = typeRef.component->metaTypeId;
- m_compiledData->listMetaTypeId = typeRef.component->listMetaTypeId;
- } else {
- m_compiledData->metaTypeId = typeRef.type->typeId();
- m_compiledData->listMetaTypeId = typeRef.type->qListTypeId();
- }
- }
- }
-
- // Sanity check property bindings
- if (errors.isEmpty()) {
- QQmlPropertyValidator validator(m_compiledData->url, m_compiledData->qmlUnit, m_compiledData->resolvedTypes,
- m_compiledData->propertyCaches, m_compiledData->objectIndexToIdPerComponent);
- if (!validator.validate())
- errors << validator.errors;
- }
-
- if (!errors.isEmpty()) {
- setError(errors);
+ QQmlTypeCompiler compiler(QQmlEnginePrivate::get(typeLoader()->engine()), m_compiledData, this, parsedQML.data());
+ if (!compiler.compile()) {
+ setError(compiler.compilationErrors());
m_compiledData->release();
m_compiledData = 0;
}
@@ -2615,8 +2453,8 @@ void QQmlTypeData::resolveTypes()
error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(name).arg(error.description()));
}
- error.setLine(unresolvedRef->line);
- error.setColumn(unresolvedRef->column);
+ error.setLine(unresolvedRef->location.line);
+ error.setColumn(unresolvedRef->location.column);
errors.prepend(error);
setError(errors);
@@ -2630,8 +2468,10 @@ void QQmlTypeData::resolveTypes()
ref.majorVersion = majorVersion;
ref.minorVersion = minorVersion;
- ref.location.line = unresolvedRef->line;
- ref.location.column = unresolvedRef->column;
+ ref.location.line = unresolvedRef->location.line;
+ ref.location.column = unresolvedRef->location.column;
+
+ ref.needsCreation = unresolvedRef->needsCreation;
m_resolvedTypes.insert(unresolvedRef.key(), ref);
}
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index b93cf2942d..ab6f47e8de 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -69,7 +69,7 @@
#include <private/qqmlbundle_p.h>
#include <private/qflagpointer_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4script_p.h>
QT_BEGIN_NAMESPACE
@@ -189,7 +189,7 @@ private:
// m_errors should *always* be written before the status is set to Error.
// We use the status change as a memory fence around m_errors so that locking
- // isn't required. Once the status is set to Error (or Complete), m_errors
+ // isn't required. Once the status is set to Error (or Complete), m_errors
// cannot be changed.
QList<QQmlError> m_errors;
@@ -244,7 +244,7 @@ private:
void loadWithStaticDataThread(QQmlDataBlob *, const QByteArray &);
void networkReplyFinished(QNetworkReply *);
void networkReplyProgress(QNetworkReply *, qint64, qint64);
-
+
typedef QHash<QNetworkReply *, QQmlDataBlob *> NetworkReplies;
void setData(QQmlDataBlob *, const QByteArray &);
@@ -396,7 +396,7 @@ class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob
public:
struct TypeReference
{
- TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0) {}
+ TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0), needsCreation(true) {}
QQmlScript::Location location;
QQmlType *type;
@@ -404,6 +404,7 @@ public:
int minorVersion;
QQmlTypeData *typeData;
QString prefix; // used by CompositeSingleton types
+ bool needsCreation;
};
struct ScriptReference
@@ -425,7 +426,12 @@ public:
const QQmlScript::Parser &parser() const;
+ // old compiler:
const QList<TypeReference> &resolvedTypes() const;
+ // new compiler:
+ const QHash<int, TypeReference> &resolvedTypeRefs() const { return m_resolvedTypes; }
+ // ---
+
const QList<ScriptReference> &resolvedScripts() const;
const QSet<QString> &namespaces() const;
const QList<TypeReference> &compositeSingletons() const;
@@ -486,10 +492,10 @@ private:
bool loadImplicitImport();
};
-// QQmlScriptData instances are created, uninitialized, by the loader in the
+// QQmlScriptData instances are created, uninitialized, by the loader in the
// load thread. The first time they are used by the VME, they are initialized which
// creates their v8 objects and they are referenced and added to the engine's cleanup
-// list. During QQmlCleanup::clear() all v8 resources are destroyed, and the
+// list. During QQmlCleanup::clear() all v8 resources are destroyed, and the
// reference that was created is released but final deletion only occurs once all the
// references as released. This is all intended to ensure that the v8 resources are
// only created and destroyed in the main thread :)
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index a880bbdd58..f388972559 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -99,7 +99,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name)
return result;
}
-QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name,
+QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name,
const void *importNamespace)
{
Q_ASSERT(importNamespace);
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 9c350a54a5..573779acab 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -54,13 +54,13 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-DEFINE_MANAGED_VTABLE(QmlTypeWrapper);
+DEFINE_OBJECT_VTABLE(QmlTypeWrapper);
QmlTypeWrapper::QmlTypeWrapper(QV8Engine *engine)
: Object(QV8Engine::getV4(engine)),
v8(engine), mode(IncludeEnums), type(0), typeNamespace(0), importNamespace(0)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
QmlTypeWrapper::~QmlTypeWrapper()
@@ -248,7 +248,7 @@ void QmlTypeWrapper::put(Managed *m, const StringRef name, const ValueRef value)
if (type && !type->isSingleton() && w->object) {
QObject *object = w->object;
QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object);
- if (ao)
+ if (ao)
QV4::QObjectWrapper::setQmlProperty(v4->currentContext(), context, ao, name.getPointer(), QV4::QObjectWrapper::IgnoreRevision, value);
} else if (type && type->isSingleton()) {
QQmlEngine *e = v8engine->engine();
@@ -277,7 +277,7 @@ PropertyAttributes QmlTypeWrapper::query(const Managed *m, StringRef name)
Scope scope(m->engine());
ScopedString n(scope, name);
bool hasProperty = false;
- const_cast<Managed*>(m)->get(n, &hasProperty);
+ static_cast<Object *>(const_cast<Managed*>(m))->get(n, &hasProperty);
return hasProperty ? Attr_Data : Attr_Invalid;
}
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index ee462d6479..355a6751a9 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -56,7 +56,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qpointer.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
@@ -68,7 +68,7 @@ namespace QV4 {
struct Q_QML_EXPORT QmlTypeWrapper : Object
{
- Q_MANAGED
+ V4_OBJECT
private:
QmlTypeWrapper(QV8Engine *engine);
~QmlTypeWrapper();
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index bd44dfb0cf..953ea2154d 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -247,7 +247,7 @@ public:
qreal y() const;
void setX(qreal);
void setY(qreal);
-
+
qreal width() const;
qreal height() const;
void setWidth(qreal);
@@ -270,7 +270,7 @@ public:
int y() const;
void setX(int);
void setY(int);
-
+
int width() const;
int height() const;
void setWidth(int);
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 50d7cbcc5e..56da6819fe 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-DEFINE_MANAGED_VTABLE(QmlValueTypeWrapper);
+DEFINE_OBJECT_VTABLE(QmlValueTypeWrapper);
class QmlValueTypeReference : public QmlValueTypeWrapper
{
@@ -79,7 +79,7 @@ QmlValueTypeWrapper::QmlValueTypeWrapper(QV8Engine *engine, ObjectType objectTyp
: Object(QV8Engine::getV4(engine)), objectType(objectType)
{
v8 = engine;
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
QmlValueTypeWrapper::~QmlValueTypeWrapper()
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index 9dd3e8dcbe..d66dbbba0c 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -56,7 +56,7 @@
#include <QtCore/qglobal.h>
#include <private/qtqmlglobal_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
@@ -68,7 +68,7 @@ namespace QV4 {
struct Q_QML_EXPORT QmlValueTypeWrapper : Object
{
- Q_MANAGED
+ V4_OBJECT
protected:
enum ObjectType { Reference, Copy };
QmlValueTypeWrapper(QV8Engine *engine, ObjectType type);
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index dfc184b9f7..54c70feecc 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -173,9 +173,9 @@ bool QQmlVME::initDeferred(QObject *object)
}
namespace {
-struct ActiveVMERestorer
+struct ActiveVMERestorer
{
- ActiveVMERestorer(QQmlVME *me, QQmlEnginePrivate *ep)
+ ActiveVMERestorer(QQmlVME *me, QQmlEnginePrivate *ep)
: ep(ep), oldVME(ep->activeVME) { ep->activeVME = me; }
~ActiveVMERestorer() { ep->activeVME = oldVME; }
@@ -184,7 +184,7 @@ struct ActiveVMERestorer
};
}
-QObject *QQmlVME::execute(QList<QQmlError> *errors, const Interrupt &interrupt)
+QObject *QQmlVME::execute(QList<QQmlError> *errors, const QQmlInstantiationInterrupt &interrupt)
{
Q_ASSERT(states.count() >= 1);
@@ -202,7 +202,7 @@ QObject *QQmlVME::execute(QList<QQmlError> *errors, const Interrupt &interrupt)
return rv;
}
-inline bool fastHasBinding(QObject *o, int index)
+inline bool fastHasBinding(QObject *o, int index)
{
if (QQmlData *ddata = static_cast<QQmlData *>(QObjectPrivate::get(o)->declarativeData)) {
int coreIndex = index & 0x0000FFFF;
@@ -226,7 +226,7 @@ static QVariant variantFromString(const QString &string)
return QQmlStringConverters::variantFromString(string);
}
-static QV4::ExecutionContext *qmlBindingContext(QQmlEngine *engine, QV4::ExecutionEngine *v4, QV4::SafeValue *qmlBindingWrappers, QQmlContextData *context, QObject *scope, int objIdx)
+static QV4::ExecutionContext *qmlBindingContext(QQmlEngine *engine, QV4::ExecutionEngine *v4, QV4::Value *qmlBindingWrappers, QQmlContextData *context, QObject *scope, int objIdx)
{
QV4::Scope valueScope(v4);
QV4::Scoped<QV4::QmlBindingWrapper> wrapper(valueScope, qmlBindingWrappers[objIdx]);
@@ -238,7 +238,7 @@ static QV4::ExecutionContext *qmlBindingContext(QQmlEngine *engine, QV4::Executi
return wrapper->context();
}
-// XXX we probably need some form of "work count" here to prevent us checking this
+// XXX we probably need some form of "work count" here to prevent us checking this
// for every instruction.
#define QML_BEGIN_INSTR_COMMON(I) { \
const QQmlInstructionMeta<(int)QQmlInstruction::I>::DataType &instr = QQmlInstructionMeta<(int)QQmlInstruction::I>::data(*genericInstr); \
@@ -330,7 +330,7 @@ static QV4::ExecutionContext *qmlBindingContext(QQmlEngine *engine, QV4::Executi
removeBindingOnProperty(o, index)
QObject *QQmlVME::run(QList<QQmlError> *errors,
- const Interrupt &interrupt
+ const QQmlInstantiationInterrupt &interrupt
#ifdef QML_THREADED_VME_INTERPRETER
, void * const **storeJumpTable
#endif
@@ -355,7 +355,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QV4::ExecutionEngine *v4 = ep->v4engine();
QV4::Scope valueScope(v4);
QV4::ScopedValue tmpValue(valueScope);
- QV4::SafeValue *qmlBindingWrappers = valueScope.alloc(objects.capacity());
+ QV4::Value *qmlBindingWrappers = valueScope.alloc(objects.capacity());
std::fill(qmlBindingWrappers, qmlBindingWrappers + objects.capacity(), QV4::Primitive::undefinedValue());
int status = -1; // needed for dbus
@@ -461,7 +461,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
CTXT->imports = COMP->importCache;
CTXT->imports->addref();
CTXT->setParent(parentCtxt);
- if (instr.contextCache != -1)
+ if (instr.contextCache != -1)
CTXT->setIdPropertyData(COMP->contextCaches.at(instr.contextCache));
if (states.count() == 1) {
rootContext = CTXT;
@@ -469,7 +469,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
rootContext->isRootObjectInCreation = true;
}
if (states.count() == 1 && !creationContext.isNull()) {
- // A component that is logically created within another component instance shares the
+ // A component that is logically created within another component instance shares the
// same instances of script imports. For example:
//
// import QtQuick 2.0
@@ -482,7 +482,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
// }
//
// Has the same "Test" instance. To implement this, we simply copy the v8 handles into
- // the inner context. We have to create a fresh persistent handle for each to prevent
+ // the inner context. We have to create a fresh persistent handle for each to prevent
// double dispose. It is possible we could do this more efficiently using some form of
// referencing instead.
CTXT->importedScripts = creationContext->importedScripts;
@@ -503,10 +503,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
const QQmlCompiledData::TypeReference &type = TYPES.at(instr.type);
Q_ASSERT(type.component);
- if (profiler.start()) {
- profiler.updateTypeName(type.component->name);
- profiler.background();
- }
+ Q_QML_VME_PROFILE(profiler.startBackground(type.component->name));
states.push(State());
@@ -529,8 +526,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QML_END_INSTR(CreateQMLObject)
QML_BEGIN_INSTR(CompleteQMLObject)
- if (profiler.foreground())
- profiler.updateLocation(CTXT->url, instr.line, instr.column);
+ Q_QML_VME_PROFILE(profiler.foreground(CTXT->url, instr.line, instr.column));
QObject *o = objects.top();
Q_ASSERT(o);
@@ -574,10 +570,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QML_BEGIN_INSTR(CreateCppObject)
const QQmlCompiledData::TypeReference &type = TYPES.at(instr.type);
Q_ASSERT(type.type);
- if (profiler.start()) {
- profiler.updateLocation(CTXT->url, instr.line, instr.column);
- profiler.updateTypeName(type.type->qmlTypeName());
- }
+ Q_QML_VME_PROFILE(profiler.start(type.type->qmlTypeName(), CTXT->url, instr.line, instr.column));
QObject *o = 0;
void *memory = 0;
@@ -637,9 +630,9 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
if (!objects.isEmpty()) {
QObject *parent = objects.at(objects.count() - 1 - (instr.parentToSuper?1:0));
#if 0 // ### refactor
- if (o->isWidgetType() && parent->isWidgetType())
+ if (o->isWidgetType() && parent->isWidgetType())
static_cast<QWidget*>(o)->setParent(static_cast<QWidget*>(parent));
- else
+ else
#endif
QQml_setParent_noEvent(o, parent);
ddata->parentFrozen = true;
@@ -650,11 +643,8 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QML_BEGIN_INSTR(CreateSimpleObject)
const QQmlCompiledData::TypeReference &ref = TYPES.at(instr.type);
- if (profiler.start()) {
- profiler.updateLocation(CTXT->url, instr.line, instr.column);
- profiler.updateTypeName(ref.type->qmlTypeName());
- }
- QObject *o = (QObject *)operator new(instr.typeSize + sizeof(QQmlData));
+ Q_QML_VME_PROFILE(profiler.start(ref.type->qmlTypeName(), CTXT->url, instr.line, instr.column));
+ QObject *o = (QObject *)operator new(instr.typeSize + sizeof(QQmlData));
::memset(static_cast<void *>(o), 0, instr.typeSize + sizeof(QQmlData));
instr.create(o);
@@ -666,16 +656,16 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
ddata->lineNumber = instr.line;
ddata->columnNumber = instr.column;
- QObjectPrivate::get(o)->declarativeData = ddata;
+ QObjectPrivate::get(o)->declarativeData = ddata;
ddata->context = ddata->outerContext = CTXT;
- ddata->nextContextObject = CTXT->contextObjects;
- if (ddata->nextContextObject)
- ddata->nextContextObject->prevContextObject = &ddata->nextContextObject;
- ddata->prevContextObject = &CTXT->contextObjects;
- CTXT->contextObjects = ddata;
+ ddata->nextContextObject = CTXT->contextObjects;
+ if (ddata->nextContextObject)
+ ddata->nextContextObject->prevContextObject = &ddata->nextContextObject;
+ ddata->prevContextObject = &CTXT->contextObjects;
+ CTXT->contextObjects = ddata;
QObject *parent = objects.at(objects.count() - 1 - (instr.parentToSuper?1:0));
- QQml_setParent_noEvent(o, parent);
+ QQml_setParent_noEvent(o, parent);
ddata->parentFrozen = true;
objects.push(o);
@@ -692,7 +682,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QML_END_INSTR(SetDefault)
QML_BEGIN_INSTR(CreateComponent)
- QQmlComponent *qcomp =
+ QQmlComponent *qcomp =
new QQmlComponent(CTXT->engine, COMP, INSTRUCTIONSTREAM - COMP->bytecode.constData(),
objects.isEmpty() ? 0 : objects.top());
@@ -727,7 +717,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QQmlPropertyCache *propertyCache = PROPERTYCACHES.at(instr.propertyCache);
- const QQmlVMEMetaData *data =
+ const QQmlVMEMetaData *data =
(const QQmlVMEMetaData *)DATAS.at(instr.aliasData).constData();
QV4::ExecutionContext *qmlContext = qmlBindingContext(engine, QV8Engine::getV4(engine), qmlBindingWrappers, CTXT, target, objects.count() - 1);
@@ -749,13 +739,13 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QQmlMetaType::StringConverter converter = QQmlMetaType::customStringConverter(type);
QVariant v = (*converter)(primitive);
- QMetaProperty prop =
+ QMetaProperty prop =
target->metaObject()->property(instr.propertyIndex);
- if (v.isNull() || ((int)prop.type() != type && prop.userType() != type))
+ if (v.isNull() || ((int)prop.type() != type && prop.userType() != type))
VME_EXCEPTION(tr("Cannot assign value %1 to property %2").arg(primitive).arg(QString::fromUtf8(prop.name())), instr.line);
void *a[] = { (void *)v.data(), 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.propertyIndex, a);
QML_END_INSTR(AssignCustomType)
@@ -828,12 +818,12 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
ss.d.data()->numberValue = instr.numberValue;
void *a[] = { &ss, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.propertyIndex, a);
QML_END_INSTR(StoreScriptString)
QML_BEGIN_INSTR(BeginObject)
- profiler.push();
+ Q_QML_VME_PROFILE(profiler.push());
QObject *target = objects.top();
QQmlParserStatus *status = reinterpret_cast<QQmlParserStatus *>(reinterpret_cast<char *>(target) + instr.castValue);
parserStatus.push(status);
@@ -847,9 +837,9 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QML_END_INSTR(BeginObject)
QML_BEGIN_INSTR(StoreBinding)
- QObject *target =
+ QObject *target =
objects.at(objects.count() - 1 - instr.owner);
- QObject *context =
+ QObject *context =
objects.at(objects.count() - 1 - instr.context);
if (instr.isRoot && BINDINGSKIPLIST.testBit(instr.property.coreIndex))
@@ -901,7 +891,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QObject *obj = objects.pop();
QQmlPropertyValueInterceptor *vi = reinterpret_cast<QQmlPropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.castValue);
QObject *target = obj->parent();
- QQmlProperty prop =
+ QQmlProperty prop =
QQmlPropertyPrivate::restore(target, instr.property, CTXT);
vi->setTarget(prop);
QQmlVMEMetaObject *mo = QQmlVMEMetaObject::get(target);
@@ -929,9 +919,9 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
void *ptr = 0;
const char *iid = QQmlMetaType::interfaceIId(type);
- if (iid)
+ if (iid)
ptr = assign->qt_metacast(iid);
- if (!ptr)
+ if (!ptr)
VME_EXCEPTION(tr("Cannot assign object to list"), instr.line);
if (list.qListProperty.append)
@@ -954,17 +944,17 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
void *ptr = assign->qt_metacast(iid);
if (ptr) {
void *a[] = { &ptr, 0, &status, &flags };
- QMetaObject::metacall(target,
+ QMetaObject::metacall(target,
QMetaObject::WriteProperty,
coreIdx, a);
ok = true;
}
- }
+ }
- if (!ok)
+ if (!ok)
VME_EXCEPTION(tr("Cannot assign object to interface property"), instr.line);
QML_END_INSTR(StoreInterface)
-
+
QML_BEGIN_INSTR(FetchAttached)
QObject *target = objects.top();
@@ -984,7 +974,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
void *a[1];
a[0] = (void *)&(lists.top().qListProperty);
- QMetaObject::metacall(target, QMetaObject::ReadProperty,
+ QMetaObject::metacall(target, QMetaObject::ReadProperty,
instr.property, a);
QML_END_INSTR(FetchQList)
@@ -992,11 +982,11 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QObject *target = objects.top();
QObject *obj = 0;
- // NOTE: This assumes a cast to QObject does not alter the
+ // NOTE: This assumes a cast to QObject does not alter the
// object pointer
void *a[1];
a[0] = &obj;
- QMetaObject::metacall(target, QMetaObject::ReadProperty,
+ QMetaObject::metacall(target, QMetaObject::ReadProperty,
instr.property, a);
if (!obj)
@@ -1042,14 +1032,14 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
// Possibly need to clear bindings
QQmlData *targetData = QQmlData::get(target);
if (targetData) {
- QQmlAbstractBinding *binding =
+ QQmlAbstractBinding *binding =
QQmlPropertyPrivate::binding(target, instr.property, -1);
if (binding && binding->bindingType() != QQmlAbstractBinding::ValueTypeProxy) {
QQmlPropertyPrivate::setBinding(target, instr.property, -1, 0);
binding->destroy();
} else if (binding) {
- QQmlValueTypeProxyBinding *proxy =
+ QQmlValueTypeProxyBinding *proxy =
static_cast<QQmlValueTypeProxyBinding *>(binding);
proxy->removeBindings(instr.bindingSkipList);
}
@@ -1064,7 +1054,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QML_END_INSTR(FetchValueType)
QML_BEGIN_INSTR(PopValueType)
- QQmlValueType *valueHandler =
+ QQmlValueType *valueHandler =
static_cast<QQmlValueType *>(objects.pop());
QObject *target = objects.top();
valueHandler->write(target, instr.property, QQmlPropertyPrivate::BypassInterceptor);
@@ -1097,7 +1087,7 @@ normalExit:
objects.deallocate();
lists.deallocate();
states.clear();
- profiler.stop();
+ Q_QML_VME_PROFILE(profiler.stop());
return rv;
}
@@ -1109,9 +1099,9 @@ void QQmlVME::reset()
QRecursionWatcher<QQmlVME, &QQmlVME::recursion> watcher(this);
if (!objects.isEmpty() && !(states.at(0).flags & State::Deferred))
- delete objects.at(0);
-
- if (!rootContext.isNull())
+ delete objects.at(0);
+
+ if (!rootContext.isNull())
rootContext->activeVMEData = 0;
// Remove the QQmlParserStatus and QQmlAbstractBinding back pointers
@@ -1122,7 +1112,7 @@ void QQmlVME::reset()
QQmlComponentAttached *a = componentAttached;
a->rem();
}
-
+
engine = 0;
objects.deallocate();
lists.deallocate();
@@ -1135,7 +1125,13 @@ void QQmlVME::reset()
states.clear();
rootContext = 0;
creationContext = 0;
- profiler.clear();
+
+ // If profiling is switched off during a VME run and then switched back on
+ // before or during the next run background ranges from the first run will
+ // be reported in the second run because we don't clear() here. We accept
+ // that as the collected data will be incomplete anyway and because not
+ // calling clear() here is benefitial for the non-profiling case.
+ Q_QML_VME_PROFILE(profiler.clear());
}
#ifdef QML_THREADED_VME_INTERPRETER
@@ -1144,14 +1140,14 @@ void *const *QQmlVME::instructionJumpTable()
static void * const *jumpTable = 0;
if (!jumpTable) {
QQmlVME dummy;
- QQmlVME::Interrupt i;
+ QQmlInstantiationInterrupt i;
dummy.run(0, i, &jumpTable);
}
return jumpTable;
}
#endif
-QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
+QQmlContextData *QQmlVME::complete(const QQmlInstantiationInterrupt &interrupt)
{
Q_ASSERT(engine ||
(bindValues.isEmpty() &&
@@ -1195,7 +1191,7 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
if (componentCompleteEnabled()) { // the qml designer does the component complete later
QQmlTrace trace("VME Component Complete");
while (!parserStatus.isEmpty()) {
- profiler.pop();
+ Q_QML_VME_PROFILE(profiler.pop());
QQmlParserStatus *status = parserStatus.pop();
#ifdef QML_ENABLE_TRACE
QQmlData *data = parserStatusData.pop();
@@ -1215,7 +1211,7 @@ QQmlContextData *QQmlVME::complete(const Interrupt &interrupt)
return 0;
}
parserStatus.deallocate();
- profiler.clear();
+ Q_QML_VME_PROFILE(profiler.clear());
}
{
@@ -1303,7 +1299,7 @@ QQmlVMEGuard::~QQmlVMEGuard()
void QQmlVMEGuard::guard(QQmlVME *vme)
{
clear();
-
+
m_objectCount = vme->objects.count();
m_objects = new QPointer<QObject>[m_objectCount];
for (int ii = 0; ii < m_objectCount; ++ii)
@@ -1311,12 +1307,20 @@ void QQmlVMEGuard::guard(QQmlVME *vme)
m_contextCount = (vme->rootContext.isNull()?0:1) + vme->states.count();
m_contexts = new QQmlGuardedContextData[m_contextCount];
- for (int ii = 0; ii < vme->states.count(); ++ii)
+ for (int ii = 0; ii < vme->states.count(); ++ii)
m_contexts[ii] = vme->states.at(ii).context;
if (!vme->rootContext.isNull())
m_contexts[m_contextCount - 1] = vme->rootContext.contextData();
}
+void QQmlVMEGuard::guard(QmlObjectCreator *creator)
+{
+ clear();
+ m_contextCount = 1;
+ m_contexts = new QQmlGuardedContextData[m_contextCount];
+ m_contexts[0] = creator->parentContextData();
+}
+
void QQmlVMEGuard::clear()
{
delete [] m_objects;
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index d5afd4c67a..4da1aec74b 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -102,28 +102,28 @@ Q_DECLARE_TYPEINFO(QQmlVMETypes::List, Q_PRIMITIVE_TYPE | Q_MOVABLE_TYPE);
template<>
class QTypeInfo<QQmlVMETypes::State> : public QTypeInfoMerger<QQmlVMETypes::State, QBitField> {}; //Q_DECLARE_TYPEINFO
+class QQmlInstantiationInterrupt {
+public:
+ inline QQmlInstantiationInterrupt();
+ inline QQmlInstantiationInterrupt(volatile bool *runWhile, int nsecs=0);
+ inline QQmlInstantiationInterrupt(int nsecs);
+
+ inline void reset();
+ inline bool shouldInterrupt() const;
+private:
+ enum Mode { None, Time, Flag };
+ Mode mode;
+ struct {
+ QElapsedTimer timer;
+ int nsecs;
+ };
+ volatile bool *runWhile;
+};
+
class Q_QML_PRIVATE_EXPORT QQmlVME
{
Q_DECLARE_TR_FUNCTIONS(QQmlVME)
public:
- class Interrupt {
- public:
- inline Interrupt();
- inline Interrupt(volatile bool *runWhile, int nsecs=0);
- inline Interrupt(int nsecs);
-
- inline void reset();
- inline bool shouldInterrupt() const;
- private:
- enum Mode { None, Time, Flag };
- Mode mode;
- struct {
- QElapsedTimer timer;
- int nsecs;
- };
- volatile bool *runWhile;
- };
-
QQmlVME() : data(0), componentAttached(0) {}
QQmlVME(void *data) : data(data), componentAttached(0) {}
@@ -136,8 +136,8 @@ public:
bool initDeferred(QObject *);
void reset();
- QObject *execute(QList<QQmlError> *errors, const Interrupt & = Interrupt());
- QQmlContextData *complete(const Interrupt & = Interrupt());
+ QObject *execute(QList<QQmlError> *errors, const QQmlInstantiationInterrupt & = QQmlInstantiationInterrupt());
+ QQmlContextData *complete(const QQmlInstantiationInterrupt & = QQmlInstantiationInterrupt());
static void enableComponentComplete();
static void disableComponentComplete();
@@ -146,7 +146,7 @@ public:
private:
friend class QQmlVMEGuard;
- QObject *run(QList<QQmlError> *errors, const Interrupt &
+ QObject *run(QList<QQmlError> *errors, const QQmlInstantiationInterrupt &
#ifdef QML_THREADED_VME_INTERPRETER
, void *const**storeJumpTable = 0
#endif
@@ -187,7 +187,7 @@ private:
};
// Used to check that a QQmlVME that is interrupted mid-execution
-// is still valid. Checks all the objects and contexts have not been
+// is still valid. Checks all the objects and contexts have not been
// deleted.
class QQmlVMEGuard
{
@@ -196,6 +196,7 @@ public:
~QQmlVMEGuard();
void guard(QQmlVME *);
+ void guard(QmlObjectCreator *);
void clear();
bool isOK() const;
@@ -207,28 +208,28 @@ private:
QQmlGuardedContextData *m_contexts;
};
-QQmlVME::Interrupt::Interrupt()
+QQmlInstantiationInterrupt::QQmlInstantiationInterrupt()
: mode(None), nsecs(0), runWhile(0)
{
}
-QQmlVME::Interrupt::Interrupt(volatile bool *runWhile, int nsecs)
+QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(volatile bool *runWhile, int nsecs)
: mode(Flag), nsecs(nsecs), runWhile(runWhile)
{
}
-QQmlVME::Interrupt::Interrupt(int nsecs)
+QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(int nsecs)
: mode(Time), nsecs(nsecs), runWhile(0)
{
}
-void QQmlVME::Interrupt::reset()
+void QQmlInstantiationInterrupt::reset()
{
if (mode == Time || nsecs)
timer.start();
}
-bool QQmlVME::Interrupt::shouldInterrupt() const
+bool QQmlInstantiationInterrupt::shouldInterrupt() const
{
if (mode == None) {
return false;
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index ebe72b2ff6..f9cb9565b3 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -224,7 +224,7 @@ const void *QQmlVMEVariant::dataPtr() const
return &data;
}
-void *QQmlVMEVariant::dataPtr()
+void *QQmlVMEVariant::dataPtr()
{
return &data;
}
@@ -234,7 +234,7 @@ size_t QQmlVMEVariant::dataSize() const
return sizeof(data);
}
-QObject *QQmlVMEVariant::asQObject()
+QObject *QQmlVMEVariant::asQObject()
{
if (type != QMetaType::QObjectStar)
setValue((QObject *)0, 0, -1);
@@ -242,7 +242,7 @@ QObject *QQmlVMEVariant::asQObject()
return *(QQmlGuard<QObject> *)(dataPtr());
}
-const QVariant &QQmlVMEVariant::asQVariant()
+const QVariant &QQmlVMEVariant::asQVariant()
{
if (type != QMetaType::QVariant)
setValue(QVariant());
@@ -250,7 +250,7 @@ const QVariant &QQmlVMEVariant::asQVariant()
return *(QVariant *)(dataPtr());
}
-int QQmlVMEVariant::asInt()
+int QQmlVMEVariant::asInt()
{
if (type != QMetaType::Int)
setValue(int(0));
@@ -258,7 +258,7 @@ int QQmlVMEVariant::asInt()
return *(int *)(dataPtr());
}
-bool QQmlVMEVariant::asBool()
+bool QQmlVMEVariant::asBool()
{
if (type != QMetaType::Bool)
setValue(bool(false));
@@ -266,7 +266,7 @@ bool QQmlVMEVariant::asBool()
return *(bool *)(dataPtr());
}
-double QQmlVMEVariant::asDouble()
+double QQmlVMEVariant::asDouble()
{
if (type != QMetaType::Double)
setValue(double(0));
@@ -274,7 +274,7 @@ double QQmlVMEVariant::asDouble()
return *(double *)(dataPtr());
}
-const QString &QQmlVMEVariant::asQString()
+const QString &QQmlVMEVariant::asQString()
{
if (type != QMetaType::QString)
setValue(QString());
@@ -282,7 +282,7 @@ const QString &QQmlVMEVariant::asQString()
return *(QString *)(dataPtr());
}
-const QUrl &QQmlVMEVariant::asQUrl()
+const QUrl &QQmlVMEVariant::asQUrl()
{
if (type != QMetaType::QUrl)
setValue(QUrl());
@@ -290,7 +290,7 @@ const QUrl &QQmlVMEVariant::asQUrl()
return *(QUrl *)(dataPtr());
}
-const QTime &QQmlVMEVariant::asQTime()
+const QTime &QQmlVMEVariant::asQTime()
{
if (type != QMetaType::QTime)
setValue(QTime());
@@ -298,7 +298,7 @@ const QTime &QQmlVMEVariant::asQTime()
return *(QTime *)(dataPtr());
}
-const QDate &QQmlVMEVariant::asQDate()
+const QDate &QQmlVMEVariant::asQDate()
{
if (type != QMetaType::QDate)
setValue(QDate());
@@ -306,7 +306,7 @@ const QDate &QQmlVMEVariant::asQDate()
return *(QDate *)(dataPtr());
}
-const QDateTime &QQmlVMEVariant::asQDateTime()
+const QDateTime &QQmlVMEVariant::asQDateTime()
{
if (type != QMetaType::QDateTime)
setValue(QDateTime());
@@ -779,9 +779,9 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
if (t == qMetaTypeId<QQmlListProperty<QObject> >()) {
int listIndex = data[id].asInt();
const List *list = &listProperties.at(listIndex);
- *reinterpret_cast<QQmlListProperty<QObject> *>(a[0]) =
+ *reinterpret_cast<QQmlListProperty<QObject> *>(a[0]) =
QQmlListProperty<QObject>(object, (void *)list,
- list_append, list_count, list_at,
+ list_append, list_count, list_at,
list_clear);
}
@@ -858,7 +858,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
QQmlVMEMetaData::AliasData *d = metaData->aliasData() + id;
- if (d->flags & QML_ALIAS_FLAG_PTR && c == QMetaObject::ReadProperty)
+ if (d->flags & QML_ALIAS_FLAG_PTR && c == QMetaObject::ReadProperty)
*reinterpret_cast<void **>(a[0]) = 0;
if (!ctxt) return -1;
@@ -867,7 +867,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
QQmlContextPrivate *ctxtPriv = QQmlContextPrivate::get(context);
QObject *target = ctxtPriv->data->idValues[d->contextIdx].data();
- if (!target)
+ if (!target)
return -1;
connectAlias(id);
@@ -875,8 +875,8 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
if (d->isObjectAlias()) {
*reinterpret_cast<QObject **>(a[0]) = target;
return -1;
- }
-
+ }
+
// Remove binding (if any) on write
if(c == QMetaObject::WriteProperty) {
int flags = *reinterpret_cast<int*>(a[3]);
@@ -888,7 +888,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
}
}
}
-
+
if (d->isValueTypeAlias()) {
// Value type property
QQmlValueType *valueType = QQmlValueTypeFactory::valueType(d->valueType());
@@ -896,7 +896,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
valueType->read(target, d->propertyIndex());
int rv = QMetaObject::metacall(valueType, c, d->valueTypeIndex(), a);
-
+
if (c == QMetaObject::WriteProperty)
valueType->write(target, d->propertyIndex(), 0x00);
@@ -987,7 +987,7 @@ QV4::ReturnedValue QQmlVMEMetaObject::method(int index)
return QV4::Primitive::undefinedValue().asReturnedValue();
}
- if (!v8methods)
+ if (!v8methods)
v8methods = new QV4::PersistentValue[metaData->methodCount];
return v8methods[index].value();
@@ -1086,7 +1086,8 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
// 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::ScopedValue newv(scope, QQmlEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value));
- if (QV4::Referenced<QV4::VariantObject> v = newv->asRef<QV4::VariantObject>())
+ QV4::VariantObjectRef v = newv;
+ if (!!v)
v->addVmePropertyReference();
// Write the value and emit change signal as appropriate.
@@ -1186,7 +1187,7 @@ void QQmlVMEMetaObject::setVmeMethod(int index, QV4::ValueRef function)
int plainSignals = metaData->signalCount + metaData->propertyCount + metaData->aliasCount;
Q_ASSERT(index >= (methodOffset() + plainSignals) && index < (methodOffset() + plainSignals + metaData->methodCount));
- if (!v8methods)
+ if (!v8methods)
v8methods = new QV4::PersistentValue[metaData->methodCount];
int methodIndex = index - methodOffset() - plainSignals;
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index a9a0308ded..778559d0c4 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -71,7 +71,7 @@
#include <private/qv8engine_p.h>
#include <private/qflagpointer_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
QT_BEGIN_NAMESPACE
@@ -113,7 +113,7 @@ struct QQmlVMEMetaData
return (propertyIdx & 0xFFFF0000) ? propType : 0;
}
};
-
+
struct PropertyData {
int propertyType;
};
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index ad231d0769..e2cdac16c0 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -122,11 +122,11 @@ QQmlXMLHttpRequestData::~QQmlXMLHttpRequestData()
namespace {
class DocumentImpl;
-class NodeImpl
+class NodeImpl
{
public:
NodeImpl() : type(Element), document(0), parent(0) {}
- virtual ~NodeImpl() {
+ virtual ~NodeImpl() {
for (int ii = 0; ii < children.count(); ++ii)
delete children.at(ii);
for (int ii = 0; ii < attributes.count(); ++ii)
@@ -134,18 +134,18 @@ public:
}
// These numbers are copied from the Node IDL definition
- enum Type {
- Attr = 2,
- CDATA = 4,
- Comment = 8,
- Document = 9,
- DocumentFragment = 11,
+ enum Type {
+ Attr = 2,
+ CDATA = 4,
+ Comment = 8,
+ Document = 9,
+ DocumentFragment = 11,
DocumentType = 10,
- Element = 1,
- Entity = 6,
+ Element = 1,
+ Entity = 6,
EntityReference = 5,
- Notation = 12,
- ProcessingInstruction = 7,
+ Notation = 12,
+ ProcessingInstruction = 7,
Text = 3
};
Type type;
@@ -185,14 +185,14 @@ public:
class NamedNodeMap : public Object
{
- Q_MANAGED
+ V4_OBJECT
public:
NamedNodeMap(ExecutionEngine *engine, NodeImpl *data, const QList<NodeImpl *> &list)
: Object(engine)
, list(list)
, d(data)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
if (d)
d->addref();
@@ -216,17 +216,17 @@ public:
NodeImpl *d;
};
-DEFINE_MANAGED_VTABLE(NamedNodeMap);
+DEFINE_OBJECT_VTABLE(NamedNodeMap);
class NodeList : public Object
{
- Q_MANAGED
+ V4_OBJECT
public:
NodeList(ExecutionEngine *engine, NodeImpl *data)
: Object(engine)
, d(data)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
if (d)
d->addref();
@@ -249,16 +249,16 @@ public:
NodeImpl *d;
};
-DEFINE_MANAGED_VTABLE(NodeList);
+DEFINE_OBJECT_VTABLE(NodeList);
class NodePrototype : public Object
{
- Q_MANAGED
+ V4_OBJECT
public:
NodePrototype(ExecutionEngine *engine)
: Object(engine)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
Scope scope(engine);
ScopedObject protectThis(scope, this);
@@ -302,17 +302,17 @@ public:
};
-DEFINE_MANAGED_VTABLE(NodePrototype);
+DEFINE_OBJECT_VTABLE(NodePrototype);
class Node : public Object
{
- Q_MANAGED
+ V4_OBJECT
Node(ExecutionEngine *engine, NodeImpl *data)
: Object(engine)
, d(data)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
if (d)
d->addref();
@@ -339,7 +339,7 @@ private:
Node &operator=(const Node &);
};
-DEFINE_MANAGED_VTABLE(Node);
+DEFINE_OBJECT_VTABLE(Node);
class Element : public Node
{
@@ -407,7 +407,7 @@ public:
}
-void NodeImpl::addref()
+void NodeImpl::addref()
{
document->addref();
}
@@ -826,7 +826,7 @@ ReturnedValue Document::load(QV8Engine *engine, const QByteArray &data)
break;
case QXmlStreamReader::EndDocument:
break;
- case QXmlStreamReader::StartElement:
+ case QXmlStreamReader::StartElement:
{
Q_ASSERT(document);
NodeImpl *node = new NodeImpl;
@@ -851,7 +851,7 @@ ReturnedValue Document::load(QV8Engine *engine, const QByteArray &data)
attr->parent = node;
node->attributes.append(attr);
}
- }
+ }
break;
case QXmlStreamReader::EndElement:
nodeStack.pop();
@@ -1045,7 +1045,7 @@ class QQmlXMLHttpRequest : public QObject
{
Q_OBJECT
public:
- enum State { Unsent = 0,
+ enum State { Unsent = 0,
Opened = 1, HeadersReceived = 2,
Loading = 3, Done = 4 };
@@ -1250,7 +1250,7 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
}
request.setHeader(QNetworkRequest::ContentTypeHeader, str);
} else {
- request.setHeader(QNetworkRequest::ContentTypeHeader,
+ request.setHeader(QNetworkRequest::ContentTypeHeader,
QLatin1String("text/plain;charset=UTF-8"));
}
}
@@ -1258,7 +1258,7 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
if (xhrDump()) {
qWarning().nospace() << "XMLHttpRequest: " << qPrintable(m_method) << ' ' << qPrintable(url.toString());
if (!m_data.isEmpty()) {
- qWarning().nospace() << " "
+ qWarning().nospace() << " "
<< qPrintable(QString::fromUtf8(m_data));
}
}
@@ -1303,7 +1303,7 @@ ReturnedValue QQmlXMLHttpRequest::abort(const ValueRef me)
m_errorFlag = true;
m_request = QNetworkRequest();
- if (!(m_state == Unsent ||
+ if (!(m_state == Unsent ||
(m_state == Opened && !m_sendFlag) ||
m_state == Done)) {
@@ -1329,7 +1329,7 @@ void QQmlXMLHttpRequest::setMe(const ValueRef me)
void QQmlXMLHttpRequest::readyRead()
{
- m_status =
+ m_status =
m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
m_statusText =
QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());
@@ -1394,7 +1394,7 @@ void QQmlXMLHttpRequest::error(QNetworkReply::NetworkError error)
} else {
m_errorFlag = true;
m_responseEntityBody = QByteArray();
- }
+ }
m_state = Done;
@@ -1438,7 +1438,7 @@ void QQmlXMLHttpRequest::finished()
if (xhrDump()) {
qWarning().nospace() << "XMLHttpRequest: RESPONSE " << qPrintable(m_url.toString());
if (!m_responseEntityBody.isEmpty()) {
- qWarning().nospace() << " "
+ qWarning().nospace() << " "
<< qPrintable(QString::fromUtf8(m_responseEntityBody));
}
}
@@ -1479,7 +1479,7 @@ void QQmlXMLHttpRequest::readEncoding()
}
}
- if (m_mime.isEmpty() || m_mime == "text/xml" || m_mime == "application/xml" || m_mime.endsWith("+xml"))
+ if (m_mime.isEmpty() || m_mime == "text/xml" || m_mime == "application/xml" || m_mime.endsWith("+xml"))
m_gotXml = true;
}
@@ -1494,7 +1494,7 @@ QTextCodec* QQmlXMLHttpRequest::findTextCodec() const
{
QTextCodec *codec = 0;
- if (!m_charset.isEmpty())
+ if (!m_charset.isEmpty())
codec = QTextCodec::codecForName(m_charset);
if (!codec && m_gotXml) {
@@ -1503,7 +1503,7 @@ QTextCodec* QQmlXMLHttpRequest::findTextCodec() const
codec = QTextCodec::codecForName(reader.documentEncoding().toString().toUtf8());
}
- if (!codec && m_mime == "text/html")
+ if (!codec && m_mime == "text/html")
codec = QTextCodec::codecForHtml(m_responseEntityBody, 0);
if (!codec)
@@ -1600,12 +1600,12 @@ void QQmlXMLHttpRequest::destroyNetwork()
struct QQmlXMLHttpRequestWrapper : public Object
{
- Q_MANAGED
+ V4_OBJECT
QQmlXMLHttpRequestWrapper(ExecutionEngine *engine, QQmlXMLHttpRequest *request)
: Object(engine)
, request(request)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
~QQmlXMLHttpRequestWrapper() {
delete request;
@@ -1618,15 +1618,15 @@ struct QQmlXMLHttpRequestWrapper : public Object
QQmlXMLHttpRequest *request;
};
-DEFINE_MANAGED_VTABLE(QQmlXMLHttpRequestWrapper);
+DEFINE_OBJECT_VTABLE(QQmlXMLHttpRequestWrapper);
struct QQmlXMLHttpRequestCtor : public FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
QQmlXMLHttpRequestCtor(ExecutionEngine *engine)
: FunctionObject(engine->rootContext, QStringLiteral("XMLHttpRequest"))
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
Scope scope(engine);
ScopedValue protectThis(scope, this);
@@ -1688,7 +1688,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
Object *proto;
};
-DEFINE_MANAGED_VTABLE(QQmlXMLHttpRequestCtor);
+DEFINE_OBJECT_VTABLE(QQmlXMLHttpRequestCtor);
void QQmlXMLHttpRequestCtor::setupProto()
{
@@ -1737,7 +1737,7 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx)
// Argument 0 - Method
QString method = ctx->callData->args[0].toQStringNoThrow().toUpper();
- if (method != QLatin1String("GET") &&
+ if (method != QLatin1String("GET") &&
method != QLatin1String("PUT") &&
method != QLatin1String("HEAD") &&
method != QLatin1String("POST") &&
@@ -1747,7 +1747,7 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx)
// Argument 1 - URL
QUrl url = QUrl(ctx->callData->args[1].toQStringNoThrow());
- if (url.isRelative())
+ if (url.isRelative())
url = engine->callingContext()->resolvedUrl(url);
// Argument 2 - async (optional)
@@ -1811,7 +1811,7 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(CallContext *ctx)
nameUpper == QLatin1String("USER-AGENT") ||
nameUpper == QLatin1String("VIA") ||
nameUpper.startsWith(QLatin1String("PROXY-")) ||
- nameUpper.startsWith(QLatin1String("SEC-")))
+ nameUpper.startsWith(QLatin1String("SEC-")))
return Encode::undefined();
r->addHeader(name, value);
@@ -1958,7 +1958,7 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(CallContext *ctx)
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)
return engine->toString(QString());
- else
+ else
return engine->toString(r->responseBody());
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 67b7e789bd..26ef86836c 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -48,7 +48,7 @@
#include <private/qqmllocale_p.h>
#include <private/qv8engine_p.h>
-#include <private/qv8profilerservice_p.h>
+#include <private/qv4profilerservice_p.h>
#include <private/qqmlprofilerservice_p.h>
#include <private/qqmlglobal_p.h>
@@ -77,7 +77,7 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-DEFINE_MANAGED_VTABLE(QtObject);
+DEFINE_OBJECT_VTABLE(QtObject);
struct StaticQtMetaObject : public QObject
{
@@ -90,7 +90,7 @@ QV4::QtObject::QtObject(ExecutionEngine *v4, QQmlEngine *qmlEngine)
, m_platform(0)
, m_application(0)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
Scope scope(v4);
ScopedObject protectThis(scope, this);
@@ -1178,12 +1178,12 @@ namespace {
struct BindingFunction : public QV4::FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
BindingFunction(FunctionObject *originalFunction)
: QV4::FunctionObject(originalFunction->scope, originalFunction->name)
, originalFunction(originalFunction)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
bindingKeyFlag = true;
}
@@ -1203,7 +1203,7 @@ struct BindingFunction : public QV4::FunctionObject
QV4::FunctionObject *originalFunction;
};
-DEFINE_MANAGED_VTABLE(BindingFunction);
+DEFINE_OBJECT_VTABLE(BindingFunction);
}
@@ -1435,7 +1435,7 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx)
if (!QQmlDebugService::isDebuggingEnabled()) {
logger.warning("Cannot start profiling because debug service is disabled. Start with -qmljsdebugger=port:XXXXX.");
} else if (QQmlProfilerService::startProfiling()) {
- QV8ProfilerService::instance()->startProfiling(title);
+ QV4ProfilerService::instance()->startProfiling(title);
logger.debug("Profiling started.");
} else {
@@ -1460,7 +1460,7 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx)
QMessageLogger logger(baSource.constData(), frame.line, baFunction.constData());
if (QQmlProfilerService::stopProfiling()) {
- QV8ProfilerService *profiler = QV8ProfilerService::instance();
+ QV4ProfilerService *profiler = QV4ProfilerService::instance();
profiler->stopProfiling(title);
QQmlProfilerService::sendProfilingData();
profiler->sendProfilingData();
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index 90536c09dd..b0c63f1ad4 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -65,7 +65,7 @@ namespace QV4 {
struct QtObject : Object
{
- Q_MANAGED
+ V4_OBJECT
QtObject(ExecutionEngine *v4, QQmlEngine *qmlEngine);
static ReturnedValue method_isQtObject(CallContext *ctx);
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 33f5a00a6c..76327e3a69 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -68,7 +68,7 @@
#include <QtCore/qdatetime.h>
#include <private/qsimd_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4dateobject_p.h>
#include <private/qv4objectiterator_p.h>
#include <private/qv4mm_p.h>
@@ -164,7 +164,7 @@ QVariant QV8Engine::toVariant(const QV4::ValueRef value, int typeHint)
QV4::ScopedArrayObject a(scope, value);
if (typeHint == qMetaTypeId<QList<QObject *> >()) {
QList<QObject *> list;
- uint32_t length = a->arrayLength();
+ uint32_t length = a->getLength();
QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope);
for (uint32_t ii = 0; ii < length; ++ii) {
qobjectWrapper = a->getIndexed(ii);
@@ -196,10 +196,10 @@ static QV4::ReturnedValue arrayFromStringList(QV8Engine *engine, const QStringLi
QV4::Scoped<QV4::ArrayObject> a(scope, e->newArrayObject());
int len = list.count();
a->arrayReserve(len);
- for (int ii = 0; ii < len; ++ii) {
- a->arrayData[ii].value = QV4::Encode(e->newString(list.at(ii)));
- a->arrayDataLen = ii + 1;
- }
+ QV4::ScopedValue v(scope);
+ for (int ii = 0; ii < len; ++ii)
+ a->arrayPut(ii, (v = QV4::Encode(e->newString(list.at(ii)))));
+
a->setArrayLengthUnchecked(len);
return a.asReturnedValue();
}
@@ -211,10 +211,10 @@ static QV4::ReturnedValue arrayFromVariantList(QV8Engine *engine, const QVariant
QV4::Scoped<QV4::ArrayObject> a(scope, e->newArrayObject());
int len = list.count();
a->arrayReserve(len);
- for (int ii = 0; ii < len; ++ii) {
- a->arrayData[ii].value = engine->fromVariant(list.at(ii));
- a->arrayDataLen = ii + 1;
- }
+ QV4::ScopedValue v(scope);
+ for (int ii = 0; ii < len; ++ii)
+ a->arrayPut(ii, (v = engine->fromVariant(list.at(ii))));
+
a->setArrayLengthUnchecked(len);
return a.asReturnedValue();
}
@@ -298,7 +298,8 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
return QV4::JsonObject::fromJsonObject(m_v4Engine, *reinterpret_cast<const QJsonObject *>(ptr));
case QMetaType::QJsonArray:
return QV4::JsonObject::fromJsonArray(m_v4Engine, *reinterpret_cast<const QJsonArray *>(ptr));
-
+ case QMetaType::QLocale:
+ return QQmlLocale::wrap(this, *reinterpret_cast<const QLocale*>(ptr));
default:
break;
}
@@ -325,10 +326,9 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
const QList<QObject *> &list = *(QList<QObject *>*)ptr;
QV4::Scoped<QV4::ArrayObject> a(scope, m_v4Engine->newArrayObject());
a->arrayReserve(list.count());
- for (int ii = 0; ii < list.count(); ++ii) {
- a->arrayData[ii].value = QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii));
- a->arrayDataLen = ii + 1;
- }
+ QV4::ScopedValue v(scope);
+ for (int ii = 0; ii < list.count(); ++ii)
+ a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii))));
a->setArrayLengthUnchecked(list.count());
return a.asReturnedValue();
} else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) {
@@ -361,7 +361,7 @@ QNetworkAccessManager *QV8Engine::networkAccessManager()
return QQmlEnginePrivate::get(m_engine)->getNetworkAccessManager();
}
-const QV4::IdentifierHash<bool> &QV8Engine::illegalNames() const
+const QSet<QString> &QV8Engine::illegalNames() const
{
return m_illegalNames;
}
@@ -392,6 +392,8 @@ QVariant QV8Engine::toBasicVariant(const QV4::ValueRef value)
return value->asDouble();
if (value->isString())
return value->stringValue()->toQString();
+ if (QQmlLocaleData *ld = value->as<QQmlLocaleData>())
+ return ld->locale;
if (QV4::DateObject *d = value->asDateObject())
return d->toQDateTime();
// NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)!
@@ -407,7 +409,7 @@ QVariant QV8Engine::toBasicVariant(const QV4::ValueRef value)
QV4::ScopedValue v(scope);
QVariantList rv;
- int length = a->arrayLength();
+ int length = a->getLength();
for (int ii = 0; ii < length; ++ii) {
v = a->getIndexed(ii);
rv << toVariant(v, -1);
@@ -437,9 +439,8 @@ void QV8Engine::initializeGlobal()
qt_add_sqlexceptions(m_v4Engine);
{
- m_illegalNames = QV4::IdentifierHash<bool>(m_v4Engine);
for (uint i = 0; i < m_v4Engine->globalObject->internalClass->size; ++i)
- m_illegalNames.add(m_v4Engine->globalObject->internalClass->nameMap.at(i)->toQString(), true);
+ m_illegalNames.insert(m_v4Engine->globalObject->internalClass->nameMap.at(i)->toQString());
}
{
@@ -541,10 +542,9 @@ QV4::ReturnedValue QV8Engine::variantListToJS(const QVariantList &lst)
QV4::Scope scope(m_v4Engine);
QV4::Scoped<QV4::ArrayObject> a(scope, m_v4Engine->newArrayObject());
a->arrayReserve(lst.size());
- for (int i = 0; i < lst.size(); i++) {
- a->arrayData[i].value = variantToJS(lst.at(i));
- a->arrayDataLen = i + 1;
- }
+ QV4::ScopedValue v(scope);
+ for (int i = 0; i < lst.size(); i++)
+ a->arrayPut(i, (v = variantToJS(lst.at(i))));
a->setArrayLengthUnchecked(lst.size());
return a.asReturnedValue();
}
@@ -569,7 +569,7 @@ QVariantList QV8Engine::variantListFromJS(QV4::ArrayObjectRef a,
QV4::Scope scope(a->engine());
QV4::ScopedValue v(scope);
- quint32 length = a->arrayLength();
+ quint32 length = a->getLength();
for (quint32 i = 0; i < length; ++i) {
v = a->getIndexed(i);
result.append(variantFromJS(v, visitedObjects));
@@ -590,10 +590,11 @@ QV4::ReturnedValue QV8Engine::variantMapToJS(const QVariantMap &vmap)
QV4::Scoped<QV4::Object> o(scope, m_v4Engine->newObject());
QVariantMap::const_iterator it;
QV4::ScopedString s(scope);
+ QV4::ScopedValue v(scope);
for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) {
s = m_v4Engine->newIdentifier(it.key());
- QV4::Property *p = o->insertMember(s, QV4::Attr_Data);
- p->value = variantToJS(it.value());
+ v = variantToJS(it.value());
+ o->insertMember(s, v);
}
return o.asReturnedValue();
}
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index e37b0d4920..1295e671f0 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -68,7 +68,7 @@
#include <private/qqmlpropertycache_p.h>
#include <private/qv4qobjectwrapper_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4object_p.h>
#include <private/qv4identifier_p.h>
@@ -117,7 +117,7 @@ namespace QV4 {
// ...
// Q_INVOKABLE void myMethod(QQmlV8Function*);
// };
-// The QQmlV8Function - and consequently the arguments and return value - only remains
+// The QQmlV8Function - and consequently the arguments and return value - only remains
// valid during the call. If the return value isn't set within myMethod(), the will return
// undefined.
class QV8Engine;
@@ -217,7 +217,7 @@ public:
virtual QNetworkAccessManager *networkAccessManager();
// Return the list of illegal id names (the names of the properties on the global object)
- const QV4::IdentifierHash<bool> &illegalNames() const;
+ const QSet<QString> &illegalNames() const;
void gc();
@@ -268,7 +268,7 @@ protected:
QVector<Deletable *> m_extensionData;
Deletable *m_listModelData;
- QV4::IdentifierHash<bool> m_illegalNames;
+ QSet<QString> m_illegalNames;
QElapsedTimer m_time;
QHash<QString, qint64> m_startedTimers;
diff --git a/src/qml/qml/v8/qv8profiler_p.h b/src/qml/qml/v8/qv8profiler_p.h
deleted file mode 100644
index 39a87f2156..0000000000
--- a/src/qml/qml/v8/qv8profiler_p.h
+++ /dev/null
@@ -1,42 +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 <private/v8-profiler.h>
diff --git a/src/qml/qml/v8/v8.pri b/src/qml/qml/v8/v8.pri
index 2480848514..b4eb706574 100644
--- a/src/qml/qml/v8/v8.pri
+++ b/src/qml/qml/v8/v8.pri
@@ -1,6 +1,5 @@
HEADERS += \
$$PWD/qv8debug_p.h \
- $$PWD/qv8profiler_p.h \
$$PWD/qv8engine_p.h \
$$PWD/qv4domerrors_p.h \
$$PWD/qv4sqlerrors_p.h \
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 5e6a1a084a..b8920deb21 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -251,6 +251,44 @@ QQmlConnectionsParser::compile(const QList<QQmlCustomParserProperty> &props)
return rv;
}
+QByteArray QQmlConnectionsParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props)
+{
+ QByteArray rv;
+ QDataStream ds(&rv, QIODevice::WriteOnly);
+
+ for (int ii = 0; ii < props.count(); ++ii) {
+ const QV4::CompiledData::Binding *binding = props.at(ii);
+ QString propName = qmlUnit->header.stringAt(binding->propertyNameIndex);
+ int propLine = binding->location.line;
+ int propColumn = binding->location.column;
+
+ if (!propName.startsWith(QLatin1String("on")) || !propName.at(2).isUpper()) {
+ error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
+ return QByteArray();
+ }
+
+
+ if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
+ const QV4::CompiledData::Object *target = qmlUnit->objectAt(binding->value.objectIndex);
+ if (!qmlUnit->header.stringAt(target->inheritedTypeNameIndex).isEmpty())
+ error(binding, QQmlConnections::tr("Connections: nested objects not allowed"));
+ else
+ error(binding, QQmlConnections::tr("Connections: syntax error"));
+ return QByteArray();
+ } if (binding->type != QV4::CompiledData::Binding::Type_Script) {
+ error(binding, QQmlConnections::tr("Connections: script expected"));
+ return QByteArray();
+ } else {
+ ds << propName;
+ ds << binding->valueAsString(&qmlUnit->header);
+ ds << propLine;
+ ds << propColumn;
+ }
+ }
+
+ return rv;
+}
+
void QQmlConnectionsParser::setCustomData(QObject *object,
const QByteArray &data)
{
diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h
index 9bc668e5f4..2579e4c239 100644
--- a/src/qml/types/qqmlconnections_p.h
+++ b/src/qml/types/qqmlconnections_p.h
@@ -85,6 +85,7 @@ class QQmlConnectionsParser : public QQmlCustomParser
{
public:
virtual QByteArray compile(const QList<QQmlCustomParserProperty> &);
+ virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props);
virtual void setCustomData(QObject *, const QByteArray &);
};
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 7276c0e5c6..3b02e1850b 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -52,7 +52,7 @@
#include <private/qqmlincubator_p.h>
#include <private/qqmlcompiler_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4functionobject_p.h>
QT_BEGIN_NAMESPACE
@@ -61,7 +61,7 @@ class QQmlDelegateModelItem;
struct DelegateModelGroupFunction: QV4::FunctionObject
{
- Q_MANAGED
+ V4_OBJECT
QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::ValueRef arg);
uint flag;
@@ -71,7 +71,7 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
, code(code)
, flag(flag)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
static QV4::ReturnedValue construct(QV4::Managed *m, QV4::CallData *)
@@ -93,7 +93,7 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
}
};
-DEFINE_MANAGED_VTABLE(DelegateModelGroupFunction);
+DEFINE_OBJECT_VTABLE(DelegateModelGroupFunction);
@@ -1629,37 +1629,46 @@ void QQmlDelegateModelItemMetaType::initializePrototype()
proto->defineAccessorProperty(QStringLiteral("model"), QQmlDelegateModelItem::get_model, 0);
proto->defineAccessorProperty(QStringLiteral("groups"), QQmlDelegateModelItem::get_groups, QQmlDelegateModelItem::set_groups);
QV4::ScopedString s(scope);
+ QV4::ScopedProperty p(scope);
+
s = v4->newString(QStringLiteral("isUnresolved"));
- QV4::Property *p = proto->insertMember(s, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, 30, QQmlDelegateModelItem::get_member));
+ p->setSetter(0);
+ proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
+
s = v4->newString(QStringLiteral("inItems"));
- p = proto->insertMember(s, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, QQmlListCompositor::Default, QQmlDelegateModelItem::get_member));
p->setSetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, QQmlListCompositor::Default, QQmlDelegateModelItem::set_member));
+ proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
+
s = v4->newString(QStringLiteral("inPersistedItems"));
- p = proto->insertMember(s, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_member));
p->setSetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, QQmlListCompositor::Persisted, QQmlDelegateModelItem::set_member));
+ proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
+
s = v4->newString(QStringLiteral("itemsIndex"));
- p = proto->insertMember(s, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, QQmlListCompositor::Default, QQmlDelegateModelItem::get_index));
+ proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
+
s = v4->newString(QStringLiteral("persistedItemsIndex"));
- p = proto->insertMember(s, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_index));
+ p->setSetter(0);
+ proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
for (int i = 2; i < groupNames.count(); ++i) {
QString propertyName = QStringLiteral("in") + groupNames.at(i);
propertyName.replace(2, 1, propertyName.at(2).toUpper());
s = v4->newString(propertyName);
- p = proto->insertMember(s, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, i + 1, QQmlDelegateModelItem::get_member));
p->setSetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, i + 1, QQmlDelegateModelItem::set_member));
+ proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
for (int i = 2; i < groupNames.count(); ++i) {
const QString propertyName = groupNames.at(i) + QStringLiteral("Index");
s = v4->newString(propertyName);
- p = proto->insertMember(s, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
p->setGetter(new (v4->memoryManager) DelegateModelGroupFunction(v4->rootContext, i + 1, QQmlDelegateModelItem::get_index));
+ p->setSetter(0);
+ proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
modelItemProto = proto;
}
@@ -1692,7 +1701,7 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::ValueRef groups) const
QV4::ScopedArrayObject array(scope, groups);
if (array) {
QV4::ScopedValue v(scope);
- uint arrayLength = array->arrayLength();
+ uint arrayLength = array->getLength();
for (uint i = 0; i < arrayLength; ++i) {
v = array->getIndexed(i);
const QString groupName = v->toQString();
@@ -1786,7 +1795,7 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisI
//---------------------------------------------------------------------------
-DEFINE_MANAGED_VTABLE(QQmlDelegateModelItemObject);
+DEFINE_OBJECT_VTABLE(QQmlDelegateModelItemObject);
QQmlDelegateModelItemObject::~QQmlDelegateModelItemObject()
{
@@ -1863,11 +1872,16 @@ void QQmlDelegateModelItem::incubateObject(
incubatorPriv->compiledData = componentPriv->cc;
incubatorPriv->compiledData->addref();
- incubatorPriv->vme.init(
- context,
- componentPriv->cc,
- componentPriv->start,
- componentPriv->creationContext);
+ if (enginePriv->useNewCompiler) {
+ incubatorPriv->creator.reset(new QmlObjectCreator(context, componentPriv->cc, componentPriv->creationContext));
+ incubatorPriv->subComponentToCreate = componentPriv->start;
+ } else {
+ incubatorPriv->vme.init(
+ context,
+ componentPriv->cc,
+ componentPriv->start,
+ componentPriv->creationContext);
+ }
enginePriv->incubate(*incubationTask, forContext);
}
@@ -3140,11 +3154,11 @@ void QQmlPartsModel::emitModelUpdated(const QQmlChangeSet &changeSet, bool reset
struct QQmlDelegateModelGroupChange : QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
QQmlDelegateModelGroupChange(QV4::ExecutionEngine *engine)
: Object(engine)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
static QV4::ReturnedValue method_get_index(QV4::CallContext *ctx) {
@@ -3174,17 +3188,20 @@ struct QQmlDelegateModelGroupChange : QV4::Object
QQmlChangeSet::Change change;
};
-DEFINE_MANAGED_VTABLE(QQmlDelegateModelGroupChange);
+DEFINE_OBJECT_VTABLE(QQmlDelegateModelGroupChange);
class QQmlDelegateModelGroupChangeArray : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
public:
QQmlDelegateModelGroupChangeArray(QV4::ExecutionEngine *engine)
: Object(engine)
{
- setVTable(&static_vtbl);
- flags &= ~SimpleArray;
+ setVTable(staticVTable());
+ QV4::Scope scope(engine);
+ QV4::ScopedObject protectThis(scope, this);
+ Q_UNUSED(protectThis);
+ setArrayType(QV4::ArrayData::Custom);
}
virtual ~QQmlDelegateModelGroupChangeArray() {}
@@ -3239,7 +3256,7 @@ public:
};
-DEFINE_MANAGED_VTABLE(QQmlDelegateModelGroupChangeArray);
+DEFINE_OBJECT_VTABLE(QQmlDelegateModelGroupChangeArray);
class QQmlDelegateModelGroupRemoveArray : public QQmlDelegateModelGroupChangeArray
{
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index f78cf38535..32b1154d30 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -161,11 +161,11 @@ protected:
struct QQmlDelegateModelItemObject : QV4::Object
{
- Q_MANAGED;
+ V4_OBJECT;
QQmlDelegateModelItemObject(QV4::ExecutionEngine *engine, QQmlDelegateModelItem *item)
: Object(engine)
, item(item)
- { setVTable(&static_vtbl); }
+ { setVTable(staticVTable()); }
~QQmlDelegateModelItemObject();
static void destroy(Managed *that);
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 7e441023c9..03dfb6690f 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -441,7 +441,7 @@ void ListModel::set(int elementIndex, QV4::ObjectRef object, QVector<int> *roles
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
- int arrayLength = a->arrayLength();
+ int arrayLength = a->getLength();
for (int j=0 ; j < arrayLength ; ++j) {
o = a->getIndexed(j);
subModel->append(o, eng);
@@ -517,7 +517,7 @@ void ListModel::set(int elementIndex, QV4::ObjectRef object, QV8Engine *eng)
if (r.type == ListLayout::Role::List) {
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
- int arrayLength = a->arrayLength();
+ int arrayLength = a->getLength();
for (int j=0 ; j < arrayLength ; ++j) {
o = a->getIndexed(j);
subModel->append(o, eng);
@@ -1188,7 +1188,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::ValueRef
QV4::Scoped<QV4::Object> o(scope);
ListModel *subModel = new ListModel(role.subLayout, 0, -1);
- int arrayLength = a->arrayLength();
+ int arrayLength = a->getLength();
for (int j=0 ; j < arrayLength ; ++j) {
o = a->getIndexed(j);
subModel->append(o, eng);
@@ -1953,7 +1953,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
if (objectArray) {
QV4::ScopedObject argObject(scope);
- int objectArrayLength = objectArray->arrayLength();
+ int objectArrayLength = objectArray->getLength();
for (int i=0 ; i < objectArrayLength ; ++i) {
argObject = objectArray->getIndexed(i);
@@ -2055,7 +2055,7 @@ void QQmlListModel::append(QQmlV4Function *args)
if (objectArray) {
QV4::Scoped<QV4::Object> argObject(scope);
- int objectArrayLength = objectArray->arrayLength();
+ int objectArrayLength = objectArray->getLength();
int index = count();
for (int i=0 ; i < objectArrayLength ; ++i) {
@@ -2384,6 +2384,136 @@ bool QQmlListModelParser::compileProperty(const QQmlCustomParserProperty &prop,
return true;
}
+bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding, QList<QQmlListModelParser::ListInstruction> &instr, QByteArray &data)
+{
+ if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
+ const QV4::CompiledData::Object *target = qmlUnit->objectAt(binding->value.objectIndex);
+ QString objName = qmlUnit->header.stringAt(target->inheritedTypeNameIndex);
+ if (objName != listElementTypeName) {
+ const QMetaObject *mo = resolveType(objName);
+ if (mo != &QQmlListElement::staticMetaObject) {
+ error(target, QQmlListModel::tr("ListElement: cannot contain nested elements"));
+ return false;
+ }
+ listElementTypeName = objName; // cache right name for next time
+ }
+
+ {
+ ListInstruction li;
+ li.type = ListInstruction::Push;
+ li.dataIdx = -1;
+ instr << li;
+ }
+
+ if (!qmlUnit->header.stringAt(target->idIndex).isEmpty()) {
+ error(binding, QQmlListModel::tr("ListElement: cannot use reserved \"id\" property"));
+ return false;
+ }
+
+ const QV4::CompiledData::Binding *binding = target->bindingTable();
+ for (quint32 i = 0; i < target->nBindings; ++i, ++binding) {
+ QString propName = qmlUnit->header.stringAt(binding->propertyNameIndex);
+ if (propName.isEmpty()) {
+ error(binding, QQmlListModel::tr("ListElement: cannot contain nested elements"));
+ return false;
+ }
+ ListInstruction li;
+ int ref = data.count();
+ data.append(propName.toUtf8());
+ data.append('\0');
+ li.type = ListInstruction::Set;
+ li.dataIdx = ref;
+ instr << li;
+
+ if (!compileProperty(qmlUnit, binding, instr, data))
+ return false;
+
+ li.type = ListInstruction::Pop;
+ li.dataIdx = -1;
+ instr << li;
+ }
+
+ {
+ ListInstruction li;
+ li.type = ListInstruction::Pop;
+ li.dataIdx = -1;
+ instr << li;
+ }
+
+ } else {
+ int ref = data.count();
+
+ QByteArray d;
+
+ if (binding->type == QV4::CompiledData::Binding::Type_String) {
+ d += char(QQmlScript::Variant::String);
+ d += binding->valueAsString(&qmlUnit->header).toUtf8();
+ } else if (binding->type == QV4::CompiledData::Binding::Type_Number) {
+ d += char(QQmlScript::Variant::Number);
+ d += QByteArray::number(binding->valueAsNumber(),'g',20);
+ } else if (binding->type == QV4::CompiledData::Binding::Type_Boolean) {
+ d += char(QQmlScript::Variant::Boolean);
+ d += char(binding->valueAsBoolean());
+ } else if (binding->type == QV4::CompiledData::Binding::Type_Script) {
+ QString scriptStr = binding->valueAsScriptString(&qmlUnit->header);
+ if (definesEmptyList(scriptStr)) {
+ d[0] = char(QQmlScript::Variant::Invalid); // marks empty list
+ } else {
+ QByteArray script = scriptStr.toUtf8();
+ bool ok;
+ int v = evaluateEnum(script, &ok);
+ if (!ok) {
+ using namespace QQmlJS;
+ AST::Node *node = astForBinding(binding->value.compiledScriptIndex);
+ if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement*>(node))
+ node = stmt->expression;
+ AST::StringLiteral *literal = 0;
+ if (AST::CallExpression *callExpr = AST::cast<AST::CallExpression *>(node)) {
+ if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(callExpr->base)) {
+ if (idExpr->name == QLatin1String("QT_TR_NOOP") || idExpr->name == QLatin1String("QT_TRID_NOOP")) {
+ if (callExpr->arguments && !callExpr->arguments->next)
+ literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->expression);
+ if (!literal) {
+ error(binding, QQmlListModel::tr("ListElement: improperly specified %1").arg(idExpr->name.toString()));
+ return false;
+ }
+ } else if (idExpr->name == QLatin1String("QT_TRANSLATE_NOOP")) {
+ if (callExpr->arguments && callExpr->arguments->next && !callExpr->arguments->next->next)
+ literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->next->expression);
+ if (!literal) {
+ error(binding, QQmlListModel::tr("ListElement: improperly specified QT_TRANSLATE_NOOP"));
+ return false;
+ }
+ }
+ }
+ }
+
+ if (literal) {
+ d[0] = char(QQmlScript::Variant::String);
+ d += literal->value.toUtf8();
+ } else {
+ error(binding, QQmlListModel::tr("ListElement: cannot use script for property value"));
+ return false;
+ }
+ } else {
+ d[0] = char(QQmlScript::Variant::Number);
+ d += QByteArray::number(v);
+ }
+ }
+ }
+
+ d.append('\0');
+ data.append(d);
+
+ ListInstruction li;
+ li.type = ListInstruction::Value;
+ li.dataIdx = ref;
+ instr << li;
+ }
+
+ return true;
+}
+
QByteArray QQmlListModelParser::compile(const QList<QQmlCustomParserProperty> &customProps)
{
QList<ListInstruction> instr;
@@ -2420,6 +2550,40 @@ QByteArray QQmlListModelParser::compile(const QList<QQmlCustomParserProperty> &c
return rv;
}
+QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
+{
+ QList<ListInstruction> instr;
+ QByteArray data;
+ listElementTypeName = QString(); // unknown
+
+ foreach (const QV4::CompiledData::Binding *binding, bindings) {
+ QString propName = qmlUnit->header.stringAt(binding->propertyNameIndex);
+ if (!propName.isEmpty()) { // isn't default property
+ error(binding, QQmlListModel::tr("ListModel: undefined property '%1'").arg(propName));
+ return QByteArray();
+ }
+ if (!compileProperty(qmlUnit, binding, instr, data))
+ return QByteArray();
+ }
+
+ int size = sizeof(ListModelData) +
+ instr.count() * sizeof(ListInstruction) +
+ data.count();
+
+ QByteArray rv;
+ rv.resize(size);
+
+ ListModelData *lmd = (ListModelData *)rv.data();
+ lmd->dataOffset = sizeof(ListModelData) +
+ instr.count() * sizeof(ListInstruction);
+ lmd->instrCount = instr.count();
+ for (int ii = 0; ii < instr.count(); ++ii)
+ lmd->instructions()[ii] = instr.at(ii);
+ ::memcpy(rv.data() + lmd->dataOffset, data.constData(), data.count());
+
+ return rv;
+}
+
void QQmlListModelParser::setCustomData(QObject *obj, const QByteArray &d)
{
QQmlListModel *rv = static_cast<QQmlListModel *>(obj);
diff --git a/src/qml/types/qqmllistmodel_p.h b/src/qml/types/qqmllistmodel_p.h
index 722cb2b44d..172d857687 100644
--- a/src/qml/types/qqmllistmodel_p.h
+++ b/src/qml/types/qqmllistmodel_p.h
@@ -160,6 +160,7 @@ class QQmlListModelParser : public QQmlCustomParser
public:
QQmlListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {}
QByteArray compile(const QList<QQmlCustomParserProperty> &);
+ QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings);
void setCustomData(QObject *, const QByteArray &);
private:
@@ -175,6 +176,7 @@ private:
ListInstruction *instructions() const;
};
bool compileProperty(const QQmlCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data);
+ bool compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding, QList<ListInstruction> &instr, QByteArray &data);
bool definesEmptyList(const QString &);
@@ -188,8 +190,12 @@ private:
ListModel *model;
int elementIndex;
};
+
+ friend class QTypeInfo<QQmlListModelParser::ListInstruction>;
};
+Q_DECLARE_TYPEINFO(QQmlListModelParser::ListInstruction, Q_PRIMITIVE_TYPE);
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQmlListModel)
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 53e45e2003..da34101c36 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -62,7 +62,7 @@
#include <private/qv8engine_p.h>
#include <private/qv4serialize_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4script_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -195,15 +195,15 @@ private:
void reportScriptException(WorkerScript *, const QQmlError &error);
};
-QQuickWorkerScriptEnginePrivate::WorkerEngine::WorkerEngine(QQuickWorkerScriptEnginePrivate *parent)
+QQuickWorkerScriptEnginePrivate::WorkerEngine::WorkerEngine(QQuickWorkerScriptEnginePrivate *parent)
: QV8Engine(0), p(parent), accessManager(0)
{
m_v4Engine->v8Engine = this;
}
-QQuickWorkerScriptEnginePrivate::WorkerEngine::~WorkerEngine()
-{
- delete accessManager;
+QQuickWorkerScriptEnginePrivate::WorkerEngine::~WorkerEngine()
+{
+ delete accessManager;
}
void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
@@ -264,7 +264,7 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(i
return v.asReturnedValue();
}
-QNetworkAccessManager *QQuickWorkerScriptEnginePrivate::WorkerEngine::networkAccessManager()
+QNetworkAccessManager *QQuickWorkerScriptEnginePrivate::WorkerEngine::networkAccessManager()
{
if (!accessManager) {
if (p->qmlengine && p->qmlengine->networkAccessManagerFactory()) {
@@ -411,7 +411,7 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
}
}
-void QQuickWorkerScriptEnginePrivate::reportScriptException(WorkerScript *script,
+void QQuickWorkerScriptEnginePrivate::reportScriptException(WorkerScript *script,
const QQmlError &error)
{
QQuickWorkerScriptEnginePrivate *p = QQuickWorkerScriptEnginePrivate::get(workerEngine);
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index 38fdffdde6..d38e5ac3df 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -46,7 +46,7 @@
#include <private/qqmlproperty_p.h>
#include <private/qv8engine_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4functionobject_p.h>
QT_BEGIN_NAMESPACE
@@ -219,6 +219,7 @@ public:
QV4::Scoped<QV4::Object> proto(scope, v4->newObject());
proto->defineAccessorProperty(QStringLiteral("index"), get_index, 0);
proto->defineAccessorProperty(QStringLiteral("hasModelChildren"), get_hasModelChildren, 0);
+ QV4::ScopedProperty p(scope);
typedef QHash<QByteArray, int>::const_iterator iterator;
for (iterator it = roleNames.constBegin(), end = roleNames.constEnd(); it != end; ++it) {
@@ -226,9 +227,9 @@ public:
const QByteArray &propertyName = it.key();
QV4::ScopedString name(scope, v4->newString(QString::fromUtf8(propertyName)));
- QV4::Property *p = proto->insertMember(name, QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable);
p->setGetter(new (v4->memoryManager) QV4::IndexedBuiltinFunction(v4->rootContext, propertyId, QQmlDMCachedModelData::get_property));
p->setSetter(new (v4->memoryManager) QV4::IndexedBuiltinFunction(v4->rootContext, propertyId, QQmlDMCachedModelData::set_property));
+ proto->insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable);
}
prototype = proto;
}
diff --git a/src/quick/doc/snippets/qml/animatedimage.qml b/src/quick/doc/snippets/qml/animatedimage.qml
index d2f778e030..f6e8d027ea 100644
--- a/src/quick/doc/snippets/qml/animatedimage.qml
+++ b/src/quick/doc/snippets/qml/animatedimage.qml
@@ -49,7 +49,7 @@ Rectangle {
AnimatedImage { id: animation; source: "animation.gif" }
- Rectangle {
+ Rectangle {
property int frames: animation.frameCount
width: 4; height: 8
diff --git a/src/quick/doc/snippets/qml/listview/listview.qml b/src/quick/doc/snippets/qml/listview/listview.qml
index 41c7f78fbe..868ba4dfc1 100644
--- a/src/quick/doc/snippets/qml/listview/listview.qml
+++ b/src/quick/doc/snippets/qml/listview/listview.qml
@@ -141,7 +141,7 @@ ListView {
}
model: ContactModel {}
- delegate: contactsDelegate
+ delegate: contactsDelegate
focus: true
}
//![isCurrentItem]
diff --git a/src/quick/doc/snippets/qml/loader/connections.qml b/src/quick/doc/snippets/qml/loader/connections.qml
index cc63fad40d..a433f4a40e 100644
--- a/src/quick/doc/snippets/qml/loader/connections.qml
+++ b/src/quick/doc/snippets/qml/loader/connections.qml
@@ -49,7 +49,7 @@ Item {
source: "MyItem.qml"
}
- Connections {
+ Connections {
target: myLoader.item
onMessage: console.log(msg)
}
diff --git a/src/quick/doc/snippets/qml/loader/simple.qml b/src/quick/doc/snippets/qml/loader/simple.qml
index 4a68a3ce53..e9a1940ac6 100644
--- a/src/quick/doc/snippets/qml/loader/simple.qml
+++ b/src/quick/doc/snippets/qml/loader/simple.qml
@@ -46,7 +46,7 @@ Item {
Loader { id: pageLoader }
- MouseArea {
+ MouseArea {
anchors.fill: parent
onClicked: pageLoader.source = "Page1.qml"
}
diff --git a/src/quick/doc/snippets/qml/parentanimation.qml b/src/quick/doc/snippets/qml/parentanimation.qml
index c5077ba000..6652030e15 100644
--- a/src/quick/doc/snippets/qml/parentanimation.qml
+++ b/src/quick/doc/snippets/qml/parentanimation.qml
@@ -43,13 +43,13 @@ import QtQuick 2.0
Item {
width: 200; height: 100
- Rectangle {
+ Rectangle {
id: redRect
width: 100; height: 100
color: "red"
}
- Rectangle {
+ Rectangle {
id: blueRect
x: redRect.width
width: 50; height: 50
diff --git a/src/quick/doc/snippets/qml/parentchange.qml b/src/quick/doc/snippets/qml/parentchange.qml
index 777fa225eb..4f1fb2a286 100644
--- a/src/quick/doc/snippets/qml/parentchange.qml
+++ b/src/quick/doc/snippets/qml/parentchange.qml
@@ -43,13 +43,13 @@ import QtQuick 2.0
Item {
width: 200; height: 100
- Rectangle {
+ Rectangle {
id: redRect
width: 100; height: 100
color: "red"
}
- Rectangle {
+ Rectangle {
id: blueRect
x: redRect.width
width: 50; height: 50
diff --git a/src/quick/doc/snippets/qml/propertyanimation.qml b/src/quick/doc/snippets/qml/propertyanimation.qml
index 4d7140d406..db589bbc21 100644
--- a/src/quick/doc/snippets/qml/propertyanimation.qml
+++ b/src/quick/doc/snippets/qml/propertyanimation.qml
@@ -55,8 +55,8 @@ Rectangle {
}
//! [single state]
- transitions: Transition {
- PropertyAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
+ transitions: Transition {
+ PropertyAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
}
}
//![transition]
diff --git a/src/quick/doc/snippets/qml/propertychanges.qml b/src/quick/doc/snippets/qml/propertychanges.qml
index b49b9df2eb..f9f1b807e0 100644
--- a/src/quick/doc/snippets/qml/propertychanges.qml
+++ b/src/quick/doc/snippets/qml/propertychanges.qml
@@ -53,9 +53,9 @@ Item {
width: 100; height: 100
color: "red"
- MouseArea {
+ MouseArea {
id: mouseArea
- anchors.fill: parent
+ anchors.fill: parent
}
states: State {
diff --git a/src/quick/doc/snippets/qml/repeaters/repeater.qml b/src/quick/doc/snippets/qml/repeaters/repeater.qml
index 704bea6bee..3afc8c67c2 100644
--- a/src/quick/doc/snippets/qml/repeaters/repeater.qml
+++ b/src/quick/doc/snippets/qml/repeaters/repeater.qml
@@ -48,7 +48,7 @@ Row {
Row {
Repeater {
model: 3
- Rectangle {
+ Rectangle {
width: 100; height: 40
border.width: 1
color: "yellow"
@@ -60,7 +60,7 @@ Row {
//! [index]
Column {
Repeater {
- model: 10
+ model: 10
Text { text: "I'm item " + index }
}
}
@@ -79,7 +79,7 @@ Column {
Row {
Rectangle { width: 10; height: 20; color: "red" }
Repeater {
- model: 10
+ model: 10
Rectangle { width: 20; height: 20; radius: 10; color: "green" }
}
Rectangle { width: 10; height: 20; color: "blue" }
diff --git a/src/quick/doc/snippets/qml/rotationanimation.qml b/src/quick/doc/snippets/qml/rotationanimation.qml
index 3924332f86..677c798ce9 100644
--- a/src/quick/doc/snippets/qml/rotationanimation.qml
+++ b/src/quick/doc/snippets/qml/rotationanimation.qml
@@ -50,9 +50,9 @@ Item {
color: "red"
antialiasing: true
- states: State {
+ states: State {
name: "rotated"
- PropertyChanges { target: rect; rotation: 180 }
+ PropertyChanges { target: rect; rotation: 180 }
}
transitions: Transition {
diff --git a/src/quick/doc/snippets/qml/row.qml b/src/quick/doc/snippets/qml/row.qml
index ad8a21326b..88f24c9140 100644
--- a/src/quick/doc/snippets/qml/row.qml
+++ b/src/quick/doc/snippets/qml/row.qml
@@ -48,7 +48,7 @@ Rectangle {
Row {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
-
+
spacing: 5
Rectangle { width: 100; height: 100; radius: 20.0
diff --git a/src/quick/doc/snippets/qml/state.qml b/src/quick/doc/snippets/qml/state.qml
index 03475c49ab..09afde4b6f 100644
--- a/src/quick/doc/snippets/qml/state.qml
+++ b/src/quick/doc/snippets/qml/state.qml
@@ -45,9 +45,9 @@ Rectangle {
width: 100; height: 100
color: "black"
- MouseArea {
+ MouseArea {
id: mouseArea
- anchors.fill: parent
+ anchors.fill: parent
onClicked: myRect.state == 'clicked' ? myRect.state = "" : myRect.state = 'clicked';
}
diff --git a/src/quick/doc/snippets/qml/transition-from-to.qml b/src/quick/doc/snippets/qml/transition-from-to.qml
index 415ab4f41f..7afc097eef 100644
--- a/src/quick/doc/snippets/qml/transition-from-to.qml
+++ b/src/quick/doc/snippets/qml/transition-from-to.qml
@@ -52,7 +52,7 @@ Rectangle {
PropertyChanges { target: rect; color: "yellow" }
}
- transitions: Transition {
+ transitions: Transition {
ColorAnimation { duration: 1000 }
}
}
diff --git a/src/quick/doc/snippets/qml/transition-reversible.qml b/src/quick/doc/snippets/qml/transition-reversible.qml
index 03848a37fa..1bb5a0bc5b 100644
--- a/src/quick/doc/snippets/qml/transition-reversible.qml
+++ b/src/quick/doc/snippets/qml/transition-reversible.qml
@@ -54,7 +54,7 @@ Rectangle {
}
//! [sequential animations]
- transitions: Transition {
+ transitions: Transition {
SequentialAnimation {
PropertyAnimation { property: "x"; duration: 1000 }
ColorAnimation { duration: 1000 }
diff --git a/src/quick/doc/snippets/qml/transition.qml b/src/quick/doc/snippets/qml/transition.qml
index a4189074fa..421149764c 100644
--- a/src/quick/doc/snippets/qml/transition.qml
+++ b/src/quick/doc/snippets/qml/transition.qml
@@ -55,8 +55,8 @@ Rectangle {
PropertyChanges { target: rect; x: 50; y: 50 }
}
- transitions: Transition {
- NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
+ transitions: Transition {
+ NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
}
}
//![0]
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index b3a2c9f46a..ed5c8d7bcb 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -54,7 +54,7 @@
#include <QtCore/QBuffer>
#include <QtCore/qdatetime.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -180,7 +180,7 @@ QQuickCanvasItemPrivate::QQuickCanvasItemPrivate()
, renderTarget(QQuickCanvasItem::Image)
, renderStrategy(QQuickCanvasItem::Immediate)
{
- antialiasing = true;
+ implicitAntialiasing = true;
}
QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate()
@@ -642,7 +642,7 @@ void QQuickCanvasItem::updatePolish()
Q_D(QQuickCanvasItem);
if (d->context && d->renderStrategy != QQuickCanvasItem::Cooperative)
- d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, d->antialiasing);
+ d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, antialiasing());
if (d->animationCallbacks.size() > 0 && isVisible()) {
QMap<int, QV4::PersistentValue> animationCallbacks = d->animationCallbacks;
@@ -705,7 +705,7 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
node->setFiltering(QSGTexture::Nearest);
if (d->renderStrategy == QQuickCanvasItem::Cooperative) {
- d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, d->antialiasing);
+ d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, antialiasing());
d->context->flush();
}
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index b6d4f1073c..9851983201 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -65,7 +65,7 @@
#include <QtCore/qnumeric.h>
#include <private/qquickwindow_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4objectproto_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -479,12 +479,12 @@ V8_DEFINE_EXTENSION(QQuickContext2DEngineData, engineData)
class QQuickJSContext2D : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
public:
QQuickJSContext2D(QV4::ExecutionEngine *engine)
: QV4::Object(engine)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
QQuickContext2D* context;
@@ -535,12 +535,12 @@ protected:
}
};
-DEFINE_MANAGED_VTABLE(QQuickJSContext2D);
+DEFINE_OBJECT_VTABLE(QQuickJSContext2D);
struct QQuickJSContext2DPrototype : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
public:
QQuickJSContext2DPrototype(QV4::ExecutionEngine *engine)
: QV4::Object(engine)
@@ -641,19 +641,19 @@ public:
};
-DEFINE_MANAGED_VTABLE(QQuickJSContext2DPrototype);
+DEFINE_OBJECT_VTABLE(QQuickJSContext2DPrototype);
class QQuickContext2DStyle : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
public:
QQuickContext2DStyle(QV4::ExecutionEngine *e)
: QV4::Object(e)
, patternRepeatX(false)
, patternRepeatY(false)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
}
QBrush brush;
bool patternRepeatX:1;
@@ -667,7 +667,7 @@ protected:
}
};
-DEFINE_MANAGED_VTABLE(QQuickContext2DStyle);
+DEFINE_OBJECT_VTABLE(QQuickContext2DStyle);
QImage qt_image_convolute_filter(const QImage& src, const QVector<qreal>& weights, int radius = 0)
{
@@ -866,12 +866,15 @@ static QString qt_composite_mode_to_string(QPainter::CompositionMode op)
struct QQuickJSContext2DPixelData : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
QQuickJSContext2DPixelData(QV4::ExecutionEngine *engine)
: QV4::Object(engine)
{
- setVTable(&static_vtbl);
- flags &= ~SimpleArray;
+ setVTable(staticVTable());
+ QV4::Scope scope(engine);
+ QV4::ScopedObject protectThis(scope, this);
+ Q_UNUSED(protectThis);
+ setArrayType(QV4::ArrayData::Custom);
}
static void destroy(QV4::Managed *that) {
@@ -885,15 +888,15 @@ struct QQuickJSContext2DPixelData : public QV4::Object
QImage image;
};
-DEFINE_MANAGED_VTABLE(QQuickJSContext2DPixelData);
+DEFINE_OBJECT_VTABLE(QQuickJSContext2DPixelData);
struct QQuickJSContext2DImageData : public QV4::Object
{
- Q_MANAGED
+ V4_OBJECT
QQuickJSContext2DImageData(QV4::ExecutionEngine *engine)
: QV4::Object(engine)
{
- setVTable(&static_vtbl);
+ setVTable(staticVTable());
pixelData = QV4::Primitive::undefinedValue();
QV4::Scope scope(engine);
@@ -915,10 +918,12 @@ struct QQuickJSContext2DImageData : public QV4::Object
- QV4::SafeValue pixelData;
+ QV4::Value pixelData;
};
-DEFINE_MANAGED_VTABLE(QQuickJSContext2DImageData);
+DEFINE_REF(QQuickJSContext2DImageData, QV4::Object);
+
+DEFINE_OBJECT_VTABLE(QQuickJSContext2DImageData);
static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV8Engine* engine, const QImage& image)
{
@@ -2109,7 +2114,8 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::CallContext *ctx)
QV4::ScopedValue value(scope, ctx->argument(0));
r->context->beginPath();
- if (QV4::Referenced<QV4::QObjectWrapper> qobjectWrapper = value->asRef<QV4::QObjectWrapper>()) {
+ QV4::QObjectWrapperRef qobjectWrapper = value;
+ if (!!qobjectWrapper) {
if (QQuickPath *path = qobject_cast<QQuickPath*>(qobjectWrapper->object()))
r->context->m_path = path->path();
} else {
@@ -2980,7 +2986,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
pixmap = r->context->createPixmap(url);
} else if (arg->isObject()) {
- if (QV4::Referenced<QV4::QObjectWrapper> qobjectWrapper = arg->asRef<QV4::QObjectWrapper>()) {
+ QV4::QObjectWrapperRef qobjectWrapper = arg;
+ if (!!qobjectWrapper) {
if (QQuickImage *imageItem = qobject_cast<QQuickImage*>(qobjectWrapper->object())) {
pixmap = r->context->createPixmap(imageItem->source());
} else if (QQuickCanvasItem *canvas = qobject_cast<QQuickCanvasItem*>(qobjectWrapper->object())) {
@@ -2990,19 +2997,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
} else {
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
- } else if (QV4::Referenced<QQuickJSContext2DImageData> imageData = arg->asRef<QQuickJSContext2DImageData>()) {
- QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->pixelData.as<QQuickJSContext2DPixelData>());
- if (pix && !pix->image.isNull()) {
- pixmap.take(new QQuickCanvasPixmap(pix->image));
+ } else {
+ QQuickJSContext2DImageDataRef imageData = arg;
+ if (!!imageData) {
+ QV4::Scoped<QQuickJSContext2DPixelData> pix(scope, imageData->pixelData.as<QQuickJSContext2DPixelData>());
+ if (pix && !pix->image.isNull()) {
+ pixmap.take(new QQuickCanvasPixmap(pix->image));
+ } else {
+ V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ }
} else {
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ QUrl url(arg->toQStringNoThrow());
+ if (url.isValid())
+ pixmap = r->context->createPixmap(url);
+ else
+ V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
- } else {
- QUrl url(arg->toQStringNoThrow());
- if (url.isValid())
- pixmap = r->context->createPixmap(url);
- else
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
} else {
V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
@@ -3260,7 +3270,8 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(QV4::CallC
if (ctx->callData->argc == 1) {
QV4::ScopedValue arg0(scope, ctx->callData->args[0]);
- if (QV4::Referenced<QQuickJSContext2DImageData> imgData = arg0->asRef<QQuickJSContext2DImageData>()) {
+ QQuickJSContext2DImageDataRef imgData = arg0;
+ if (!!imgData) {
QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->pixelData.as<QQuickJSContext2DPixelData>());
if (pa) {
qreal w = pa->image.width();
@@ -3337,7 +3348,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
if (!qIsFinite(dx) || !qIsFinite(dy))
V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
- QV4::Referenced<QQuickJSContext2DImageData> imageData = arg0->asRef<QQuickJSContext2DImageData>();
+ QQuickJSContext2DImageDataRef imageData = arg0;
if (!imageData)
return ctx->callData->thisObject.asReturnedValue();
diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h
index 6399da3dee..4390ae62cc 100644
--- a/src/quick/items/context2d/qquickcontext2d_p.h
+++ b/src/quick/items/context2d/qquickcontext2d_p.h
@@ -55,7 +55,7 @@
#include <private/qv8engine_p.h>
#include <QtCore/QWaitCondition>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
//#define QQUICKCONTEXT2D_DEBUG //enable this for just DEBUG purpose!
diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp
index 3c00a7d62d..b5cc6ea3ef 100644
--- a/src/quick/items/qquickaccessibleattached.cpp
+++ b/src/quick/items/qquickaccessibleattached.cpp
@@ -139,6 +139,57 @@ QT_BEGIN_NAMESPACE
\endtable
*/
+/*! \qmlproperty bool focusable
+ \brief This property holds whether this item is focusable.
+
+ By default, this property is false except for items where the role is one of
+ CheckBox, RadioButton, Button, MenuItem, PageTab, EditableText, SpinBox, ComboBox,
+ Terminal or ScrollBar.
+*/
+/*! \qmlproperty bool focused
+ \brief This property holds whether this item currently has the active focus.
+
+ By default, this property is false, but it will return true for items that
+ have \l QQuickItem::hasActiveFocus() returning true.
+*/
+/*! \qmlproperty bool checkable
+ \brief This property holds whether this item is checkable (like a check box or some buttons).
+*/
+/*! \qmlproperty bool checked
+ \brief This property holds whether this item is currently checked.
+*/
+/*! \qmlproperty bool editable
+ \brief This property holds whether this item has editable text.
+*/
+/*! \qmlproperty bool multiLine
+ \brief This property holds whether this item has multiple text lines.
+*/
+/*! \qmlproperty bool readOnly
+ \brief This property holds whether this item while being of type \l QAccessible::EditableText
+ is set to read-only.
+*/
+/*! \qmlproperty bool selected
+ \brief This property holds whether this item is selected.
+*/
+/*! \qmlproperty bool selectable
+ \brief This property holds whether this item can be selected.
+*/
+/*! \qmlproperty bool pressed
+ \brief This property holds whether this item is pressed (for example a button during a mouse click).
+*/
+/*! \qmlproperty bool checkStateMixed
+ \brief This property holds whether this item is in the partially checked state.
+*/
+/*! \qmlproperty bool defaultButton
+ \brief This property holds whether this item is the default button of a dialog.
+*/
+/*! \qmlproperty bool passwordEdit
+ \brief This property holds whether this item is a password text edit.
+*/
+/*! \qmlproperty bool selectableText
+ \brief This property holds whether this item contains selectable text.
+*/
+
QQuickAccessibleAttached::QQuickAccessibleAttached(QObject *parent)
: QObject(parent), m_role(QAccessible::NoRole)
{
diff --git a/src/quick/items/qquickaccessibleattached_p.h b/src/quick/items/qquickaccessibleattached_p.h
index 298c473cf8..1f2c6bf532 100644
--- a/src/quick/items/qquickaccessibleattached_p.h
+++ b/src/quick/items/qquickaccessibleattached_p.h
@@ -55,15 +55,46 @@
QT_BEGIN_NAMESPACE
+#define STATE_PROPERTY(P) \
+ Q_PROPERTY(bool P READ P WRITE set_ ## P NOTIFY P ## Changed FINAL) \
+ bool P() const { return m_state.P ; } \
+ void set_ ## P(bool arg) \
+ { \
+ if (m_state.P == arg) \
+ return; \
+ m_state.P = arg; \
+ emit P ## Changed(arg); \
+ QAccessible::State changedState; \
+ changedState.P = true; \
+ QAccessibleStateChangeEvent ev(parent(), changedState); \
+ QAccessible::updateAccessibility(&ev); \
+ } \
+ Q_SIGNAL void P ## Changed(bool arg);
+
+
class Q_QUICK_PRIVATE_EXPORT QQuickAccessibleAttached : public QObject
{
Q_OBJECT
- Q_PROPERTY(QAccessible::Role role READ role WRITE setRole NOTIFY roleChanged)
- Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
- Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
+ Q_PROPERTY(QAccessible::Role role READ role WRITE setRole NOTIFY roleChanged FINAL)
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL)
+ Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged FINAL)
public:
- Q_ENUMS(QAccessible::Role QAccessible::Event QAccessible::State)
+ Q_ENUMS(QAccessible::Role QAccessible::Event)
+ STATE_PROPERTY(checkable)
+ STATE_PROPERTY(checked)
+ STATE_PROPERTY(editable)
+ STATE_PROPERTY(focusable)
+ STATE_PROPERTY(focused)
+ STATE_PROPERTY(multiLine)
+ STATE_PROPERTY(readOnly)
+ STATE_PROPERTY(selected)
+ STATE_PROPERTY(selectable)
+ STATE_PROPERTY(pressed)
+ STATE_PROPERTY(checkStateMixed)
+ STATE_PROPERTY(defaultButton)
+ STATE_PROPERTY(passwordEdit)
+ STATE_PROPERTY(selectableText)
QQuickAccessibleAttached(QObject *parent);
~QQuickAccessibleAttached();
@@ -76,9 +107,33 @@ public:
Q_EMIT roleChanged();
// There is no way to signify role changes at the moment.
// QAccessible::updateAccessibility(parent(), 0, QAccessible::);
+
+ switch (role) {
+ case QAccessible::CheckBox:
+ case QAccessible::RadioButton:
+ m_state.focusable = true;
+ m_state.checkable = true;
+ break;
+ case QAccessible::Button:
+ case QAccessible::MenuItem:
+ case QAccessible::PageTab:
+ case QAccessible::EditableText:
+ case QAccessible::SpinBox:
+ case QAccessible::ComboBox:
+ case QAccessible::Terminal:
+ case QAccessible::ScrollBar:
+ m_state.focusable = true;
+ break;
+ default:
+ break;
+ }
}
}
- QString name() const { return m_name; }
+ QString name() const {
+ if (m_state.passwordEdit)
+ return QString();
+ return m_name;
+ }
void setName(const QString &name) {
if (name != m_name) {
m_name = name;
@@ -102,12 +157,12 @@ public:
// Factory function
static QQuickAccessibleAttached *qmlAttachedProperties(QObject *obj);
- // Property getter
- static QObject *attachedProperties(const QObject *obj)
+ static QQuickAccessibleAttached *attachedProperties(const QObject *obj)
{
- return qmlAttachedPropertiesObject<QQuickAccessibleAttached>(obj, false);
+ return qobject_cast<QQuickAccessibleAttached*>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(obj, false));
}
+ // Property getter
static QVariant property(const QObject *object, const char *propertyName)
{
if (QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object))
@@ -128,8 +183,8 @@ public:
static QObject *findAccessible(QObject *object, QAccessible::Role role = QAccessible::NoRole)
{
while (object) {
- QObject *att = QQuickAccessibleAttached::attachedProperties(object);
- if (att && (role == QAccessible::NoRole || att->property("role").toInt() == role)) {
+ QQuickAccessibleAttached *att = QQuickAccessibleAttached::attachedProperties(object);
+ if (att && (role == QAccessible::NoRole || att->role() == role)) {
break;
}
object = object->parent();
@@ -137,6 +192,8 @@ public:
return object;
}
+ QAccessible::State state() { return m_state; }
+
public Q_SLOTS:
void valueChanged() {
QAccessibleValueChangeEvent ev(parent(), parent()->property("value"));
@@ -153,7 +210,10 @@ Q_SIGNALS:
void descriptionChanged();
private:
+ QQuickItem *item() const { return static_cast<QQuickItem*>(parent()); }
+
QAccessible::Role m_role;
+ QAccessible::State m_state;
QString m_name;
QString m_description;
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 1107425575..8587da5ac3 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -630,8 +630,8 @@ void QQuickGridViewPrivate::updateViewport()
void QQuickGridViewPrivate::layoutVisibleItems(int fromModelIndex)
{
if (visibleItems.count()) {
- const qreal from = isContentFlowReversed() ? -position() - size() : position();
- const qreal to = isContentFlowReversed() ? -position() : position() + size();
+ const qreal from = isContentFlowReversed() ? -position()-displayMarginBeginning-size() : position()-displayMarginBeginning;
+ const qreal to = isContentFlowReversed() ? -position()+displayMarginEnd : position()+size()+displayMarginEnd;
FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first());
qreal rowPos = firstItem->rowPos();
@@ -1534,7 +1534,35 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
of additional memory usage. It is not a substitute for creating efficient
delegates; the fewer objects and bindings in a delegate, the faster a view may be
scrolled.
+
+ The cacheBuffer operates outside of any display margins specified by
+ displayMarginBeginning or displayMarginEnd.
+*/
+
+/*!
+ \qmlproperty int QtQuick::GridView::displayMarginBeginning
+ \qmlproperty int QtQuick::GridView::displayMarginEnd
+ \since QtQuick 2.3
+
+ This property allows delegates to be displayed outside of the view geometry.
+
+ If this value is non-zero, the view will create extra delegates before the
+ start of the view, or after the end. The view will create as many delegates
+ as it can fit into the pixel size specified.
+
+ For example, if in a vertical view the delegate is 20 pixels high,
+ there are 3 columns, and
+ \c displayMarginBeginning and \c displayMarginEnd are both set to 40,
+ then 6 delegates above and 6 delegates below will be created and shown.
+
+ The default value is 0.
+
+ This property is meant for allowing certain UI configurations,
+ and not as a performance optimization. If you wish to create delegates
+ outside of the view geometry for performance reasons, you probably
+ want to use the cacheBuffer property instead.
*/
+
void QQuickGridView::setHighlightMoveDuration(int duration)
{
Q_D(QQuickGridView);
@@ -2000,8 +2028,8 @@ void QQuickGridView::viewportMoved(Qt::Orientations orient)
d->refillOrLayout();
// Set visibility of items to eliminate cost of items outside the visible area.
- qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
- qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
+ qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
+ qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
for (int i = 0; i < d->visibleItems.count(); ++i) {
FxGridItemSG *item = static_cast<FxGridItemSG*>(d->visibleItems.at(i));
QQuickItemPrivate::get(item->item)->setCulled(item->rowPos() + d->rowSize() < from || item->rowPos() > to);
@@ -2350,7 +2378,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
// Insert items before the visible item.
int insertionIdx = index;
int i = count - 1;
- int from = tempPos - buffer;
+ int from = tempPos - buffer - displayMarginBeginning;
while (i >= 0) {
if (rowPos > from && insertionIdx < visibleIndex) {
@@ -2387,7 +2415,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
}
} else {
int i = 0;
- int to = buffer+tempPos+size()-1;
+ int to = buffer+displayMarginEnd+tempPos+size()-1;
while (i < count && rowPos <= to + rowSize()*(columns - colNum)/qreal(columns+1)) {
FxViewItem *item = 0;
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index 0708304051..62ac72d244 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -62,6 +62,13 @@ public:
{
}
+ void updateTexture(QSGTexture *texture) {
+ if (m_texture == texture)
+ return;
+ m_texture = texture;
+ emit textureChanged();
+ }
+
QSGTexture *texture() const {
if (m_texture) {
m_texture->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest);
@@ -542,7 +549,7 @@ QSGTextureProvider *QQuickImage::textureProvider() const
QQuickImagePrivate *dd = const_cast<QQuickImagePrivate *>(d);
dd->provider = new QQuickImageTextureProvider;
dd->provider->m_smooth = d->smooth;
- dd->provider->m_texture = d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window());
+ dd->provider->updateTexture(d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window()));
}
return d->provider;
@@ -557,7 +564,7 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
// Copy over the current texture state into the texture provider...
if (d->provider) {
d->provider->m_smooth = d->smooth;
- d->provider->m_texture = texture;
+ d->provider->updateTexture(texture);
}
if (!texture || width() <= 0 || height() <= 0) {
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 88ffc7bba3..3b63028a2e 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2709,6 +2709,8 @@ QQuickItemPrivate::QQuickItemPrivate()
, culled(false)
, hasCursor(false)
, activeFocusOnTab(false)
+ , implicitAntialiasing(false)
+ , antialiasingValid(false)
, dirtyAttributes(0)
, nextDirtyItem(0)
, prevDirtyItem(0)
@@ -4480,96 +4482,6 @@ void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
}
#endif // QT_NO_IM
-void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
-{
- Q_Q(QQuickItem);
-
- if (e->type() == QEvent::FocusIn) {
- q->focusInEvent(e);
- } else {
- q->focusOutEvent(e);
- }
-}
-
-void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
-{
- Q_Q(QQuickItem);
-
- Q_ASSERT(e->isAccepted());
-
- switch (e->type()) {
- default:
- Q_ASSERT(!"Unknown event type");
- case QEvent::MouseMove:
- q->mouseMoveEvent(e);
- break;
- case QEvent::MouseButtonPress:
- q->mousePressEvent(e);
- break;
- case QEvent::MouseButtonRelease:
- q->mouseReleaseEvent(e);
- break;
- case QEvent::MouseButtonDblClick:
- q->mouseDoubleClickEvent(e);
- break;
- }
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
-{
- Q_Q(QQuickItem);
- q->wheelEvent(e);
-}
-#endif
-
-void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
-{
- Q_Q(QQuickItem);
- q->touchEvent(e);
-}
-
-void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
-{
- Q_Q(QQuickItem);
- switch (e->type()) {
- default:
- Q_ASSERT(!"Unknown event type");
- case QEvent::HoverEnter:
- q->hoverEnterEvent(e);
- break;
- case QEvent::HoverLeave:
- q->hoverLeaveEvent(e);
- break;
- case QEvent::HoverMove:
- q->hoverMoveEvent(e);
- break;
- }
-}
-
-#ifndef QT_NO_DRAGANDDROP
-void QQuickItemPrivate::deliverDragEvent(QEvent *e)
-{
- Q_Q(QQuickItem);
- switch (e->type()) {
- default:
- Q_ASSERT(!"Unknown event type");
- case QEvent::DragEnter:
- q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
- break;
- case QEvent::DragLeave:
- q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
- break;
- case QEvent::DragMove:
- q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
- break;
- case QEvent::Drop:
- q->dropEvent(static_cast<QDropEvent *>(e));
- break;
- }
-}
-#endif // QT_NO_DRAGANDDROP
-
/*!
Called when \a change occurs for this item.
@@ -5575,6 +5487,9 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
}
}
break;
+ case QQuickItem::ItemAntialiasingHasChanged:
+ q->itemChange(change, data);
+ break;
}
}
@@ -5668,37 +5583,65 @@ void QQuickItem::setActiveFocusOnTab(bool activeFocusOnTab)
/*!
\qmlproperty bool QtQuick::Item::antialiasing
- Primarily used in Rectangle and image based elements to decide if the item should
- use antialiasing or not. Items with antialiasing enabled require more memory and
- are potentially slower to render.
+ Used by visual elements to decide if the item should use antialiasing or not.
+ In some cases items with antialiasing require more memory and are potentially
+ slower to render (see \l {Antialiasing} for more details).
- The default is false.
+ The default is false, but may be overridden by derived elements.
*/
/*!
\property QQuickItem::antialiasing
\brief Specifies whether the item is antialiased or not
- Primarily used in Rectangle and image based elements to decide if the item should
- use antialiasing or not. Items with antialiasing enabled require more memory and
- are potentially slower to render.
+ Used by visual elements to decide if the item should use antialiasing or not.
+ In some cases items with antialiasing require more memory and are potentially
+ slower to render (see \l {Antialiasing} for more details).
- The default is false.
+ The default is false, but may be overridden by derived elements.
*/
bool QQuickItem::antialiasing() const
{
Q_D(const QQuickItem);
- return d->antialiasing;
+ return d->antialiasingValid ? d->antialiasing : d->implicitAntialiasing;
}
-void QQuickItem::setAntialiasing(bool antialiasing)
+
+void QQuickItem::setAntialiasing(bool aa)
{
Q_D(QQuickItem);
- if (d->antialiasing == antialiasing)
+
+ bool changed = (aa != antialiasing());
+ d->antialiasingValid = true;
+
+ if (!changed)
return;
- d->antialiasing = antialiasing;
+ d->antialiasing = aa;
d->dirty(QQuickItemPrivate::Antialiasing);
- emit antialiasingChanged(antialiasing);
+ d->itemChange(ItemAntialiasingHasChanged, d->antialiasing);
+
+ emit antialiasingChanged(antialiasing());
+}
+
+void QQuickItem::resetAntialiasing()
+{
+ Q_D(QQuickItem);
+ if (!d->antialiasingValid)
+ return;
+
+ d->antialiasingValid = false;
+
+ if (d->implicitAntialiasing != d->antialiasing)
+ emit antialiasingChanged(antialiasing());
+}
+
+void QQuickItemPrivate::setImplicitAntialiasing(bool antialiasing)
+{
+ Q_Q(QQuickItem);
+ bool prev = q->antialiasing();
+ implicitAntialiasing = antialiasing;
+ if (componentComplete && (q->antialiasing() != prev))
+ emit q->antialiasingChanged(q->antialiasing());
}
/*!
@@ -6541,6 +6484,17 @@ void QQuickItemPrivate::incrementCursorCount(int delta)
#endif
}
+void QQuickItemPrivate::markObjects(QV4::ExecutionEngine *e)
+{
+ Q_Q(QQuickItem);
+ QQmlData *ddata = QQmlData::get(q);
+ if (ddata)
+ ddata->jsWrapper.markOnce(e);
+
+ foreach (QQuickItem *child, childItems)
+ QQuickItemPrivate::get(child)->markObjects(e);
+}
+
#ifndef QT_NO_CURSOR
/*!
@@ -6983,18 +6937,17 @@ QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
*/
bool QQuickItem::event(QEvent *ev)
{
+ Q_D(QQuickItem);
+
+ switch (ev->type()) {
#if 0
- if (ev->type() == QEvent::PolishRequest) {
- Q_D(QQuickItem);
+ case QEvent::PolishRequest:
d->polishScheduled = false;
updatePolish();
- return true;
- } else {
- return QObject::event(ev);
- }
+ break;
#endif
#ifndef QT_NO_IM
- if (ev->type() == QEvent::InputMethodQuery) {
+ case QEvent::InputMethodQuery: {
QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
Qt::InputMethodQueries queries = query->queries();
for (uint i = 0; i < 32; ++i) {
@@ -7005,20 +6958,79 @@ bool QQuickItem::event(QEvent *ev)
}
}
query->accept();
- return true;
- } else if (ev->type() == QEvent::InputMethod) {
+ break;
+ }
+ case QEvent::InputMethod:
inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
- return true;
- } else
+ break;
#endif // QT_NO_IM
- if (ev->type() == QEvent::StyleAnimationUpdate) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::TouchCancel:
+ touchEvent(static_cast<QTouchEvent*>(ev));
+ break;
+ case QEvent::StyleAnimationUpdate:
if (isVisible()) {
ev->accept();
update();
}
- return true;
+ break;
+ case QEvent::HoverEnter:
+ hoverEnterEvent(static_cast<QHoverEvent*>(ev));
+ break;
+ case QEvent::HoverLeave:
+ hoverLeaveEvent(static_cast<QHoverEvent*>(ev));
+ break;
+ case QEvent::HoverMove:
+ hoverMoveEvent(static_cast<QHoverEvent*>(ev));
+ break;
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ d->deliverKeyEvent(static_cast<QKeyEvent*>(ev));
+ break;
+ case QEvent::FocusIn:
+ focusInEvent(static_cast<QFocusEvent*>(ev));
+ break;
+ case QEvent::FocusOut:
+ focusOutEvent(static_cast<QFocusEvent*>(ev));
+ break;
+ case QEvent::MouseMove:
+ mouseMoveEvent(static_cast<QMouseEvent*>(ev));
+ break;
+ case QEvent::MouseButtonPress:
+ mousePressEvent(static_cast<QMouseEvent*>(ev));
+ break;
+ case QEvent::MouseButtonRelease:
+ mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
+ break;
+ case QEvent::MouseButtonDblClick:
+ mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
+ break;
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+ wheelEvent(static_cast<QWheelEvent*>(ev));
+ break;
+#endif
+#ifndef QT_NO_DRAGANDDROP
+ case QEvent::DragEnter:
+ dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
+ break;
+ case QEvent::DragLeave:
+ dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
+ break;
+ case QEvent::DragMove:
+ dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
+ break;
+ case QEvent::Drop:
+ dropEvent(static_cast<QDropEvent*>(ev));
+ break;
+#endif // QT_NO_DRAGANDDROP
+ default:
+ return QObject::event(ev);
}
- return QObject::event(ev);
+
+ return true;
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 2500a2d33a..2b08cc2598 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
class QQuickItem;
class QQuickTransformPrivate;
-class QQuickTransform : public QObject
+class Q_QUICK_EXPORT QQuickTransform : public QObject
{
Q_OBJECT
public:
@@ -141,7 +141,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_PROPERTY(QQmlListProperty<QQuickTransform> transform READ transform DESIGNABLE false FINAL)
Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged)
- Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing NOTIFY antialiasingChanged)
+ Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing NOTIFY antialiasingChanged RESET resetAntialiasing)
Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged)
Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged)
@@ -172,7 +172,8 @@ public:
ItemParentHasChanged, // value.item
ItemOpacityHasChanged, // value.realValue
ItemActiveFocusHasChanged, // value.boolValue
- ItemRotationHasChanged // value.realValue
+ ItemRotationHasChanged, // value.realValue
+ ItemAntialiasingHasChanged // value.boolValue
};
union ItemChangeData {
@@ -267,6 +268,7 @@ public:
bool antialiasing() const;
void setAntialiasing(bool);
+ void resetAntialiasing();
Flags flags() const;
void setFlag(Flag flag, bool enabled = true);
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 44eabcf0d5..96cb9e8843 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -422,6 +422,8 @@ public:
bool hasCursor:1;
// Bit 32
bool activeFocusOnTab:1;
+ bool implicitAntialiasing:1;
+ bool antialiasingValid:1;
enum DirtyType {
TransformOrigin = 0x00000001,
@@ -521,6 +523,8 @@ public:
virtual void implicitWidthChanged();
virtual void implicitHeightChanged();
+ void setImplicitAntialiasing(bool antialiasing);
+
void resolveLayoutMirror();
void setImplicitLayoutMirror(bool mirror, bool inherit);
void setLayoutMirror(bool mirror);
@@ -540,16 +544,6 @@ public:
#ifndef QT_NO_IM
void deliverInputMethodEvent(QInputMethodEvent *);
#endif
- void deliverFocusEvent(QFocusEvent *);
- void deliverMouseEvent(QMouseEvent *);
-#ifndef QT_NO_WHEELEVENT
- void deliverWheelEvent(QWheelEvent *);
-#endif
- void deliverTouchEvent(QTouchEvent *);
- void deliverHoverEvent(QHoverEvent *);
-#ifndef QT_NO_DRAGANDDROP
- void deliverDragEvent(QEvent *);
-#endif
bool calcEffectiveVisible() const;
bool setEffectiveVisibleRecur(bool);
@@ -589,6 +583,9 @@ public:
virtual void mirrorChange() {}
void incrementCursorCount(int delta);
+
+ // recursive helper to let a visual parent mark its visual children
+ void markObjects(QV4::ExecutionEngine *e);
};
/*
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index a5b78b28e1..a52ccf4832 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -184,6 +184,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickTranslate>(uri,major,minor,"Translate");
qmlRegisterType<QQuickRotation>(uri,major,minor,"Rotation");
qmlRegisterType<QQuickScale>(uri,major,minor,"Scale");
+ qmlRegisterType<QQuickMatrix4x4>(uri,2,4,"Matrix4x4");
qmlRegisterType<QQuickText>(uri,major,minor,"Text");
qmlRegisterType<QQuickTextEdit>(uri,major,minor,"TextEdit");
qmlRegisterType<QQuickTextEdit,1>(uri,2,1,"TextEdit");
@@ -261,12 +262,16 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickItem, 1>(uri, 2, 1,"Item");
qmlRegisterType<QQuickGrid, 1>(uri, 2, 1, "Grid");
qmlRegisterUncreatableType<QQuickItemView, 1>(uri, 2, 1, "ItemView", QQuickItemView::tr("ItemView is an abstract base class"));
+ qmlRegisterUncreatableType<QQuickItemView, 2>(uri, 2, 3, "ItemView", QQuickItemView::tr("ItemView is an abstract base class"));
qmlRegisterType<QQuickListView, 1>(uri, 2, 1, "ListView");
qmlRegisterType<QQuickGridView, 1>(uri, 2, 1, "GridView");
qmlRegisterType<QQuickTextEdit, 1>(uri, 2, 1, "TextEdit");
qmlRegisterType<QQuickText, 2>(uri, 2, 2, "Text");
qmlRegisterType<QQuickTextEdit, 2>(uri, 2, 2, "TextEdit");
+
+ qmlRegisterType<QQuickText, 3>(uri, 2, 3, "Text");
+ qmlRegisterType<QQuickTextEdit, 3>(uri, 2, 3, "TextEdit");
}
static void initResources()
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index e5b2ee822c..10f134f7ae 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -460,6 +460,41 @@ void QQuickItemView::setCacheBuffer(int b)
}
}
+int QQuickItemView::displayMarginBeginning() const
+{
+ Q_D(const QQuickItemView);
+ return d->displayMarginBeginning;
+}
+
+void QQuickItemView::setDisplayMarginBeginning(int margin)
+{
+ Q_D(QQuickItemView);
+ if (d->displayMarginBeginning != margin) {
+ d->displayMarginBeginning = margin;
+ if (isComponentComplete()) {
+ d->refillOrLayout();
+ }
+ emit displayMarginBeginningChanged();
+ }
+}
+
+int QQuickItemView::displayMarginEnd() const
+{
+ Q_D(const QQuickItemView);
+ return d->displayMarginEnd;
+}
+
+void QQuickItemView::setDisplayMarginEnd(int margin)
+{
+ Q_D(QQuickItemView);
+ if (d->displayMarginEnd != margin) {
+ d->displayMarginEnd = margin;
+ if (isComponentComplete()) {
+ d->refillOrLayout();
+ }
+ emit displayMarginEndChanged();
+ }
+}
Qt::LayoutDirection QQuickItemView::layoutDirection() const
{
@@ -1444,6 +1479,7 @@ void QQuickItemView::componentComplete()
QQuickItemViewPrivate::QQuickItemViewPrivate()
: itemCount(0)
, buffer(QML_VIEW_DEFAULTCACHEBUFFER), bufferMode(BufferBefore | BufferAfter)
+ , displayMarginBeginning(0), displayMarginEnd(0)
, layoutDirection(Qt::LeftToRight), verticalLayoutDirection(QQuickItemView::TopToBottom)
, moveReason(Other)
, visibleIndex(0)
@@ -1683,9 +1719,9 @@ void QQuickItemViewPrivate::refill()
{
qreal s = qMax(size(), qreal(0.));
if (isContentFlowReversed())
- refill(-position()-s, -position());
+ refill(-position()-displayMarginBeginning-s, -position()+displayMarginEnd);
else
- refill(position(), position()+s);
+ refill(position()-displayMarginBeginning, position()+displayMarginEnd+s);
}
void QQuickItemViewPrivate::refill(qreal from, qreal to)
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 17d150f480..ad026a3152 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -63,6 +63,8 @@ class Q_AUTOTEST_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
+ Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION 2)
+ Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION 2)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
@@ -133,6 +135,12 @@ public:
int cacheBuffer() const;
void setCacheBuffer(int);
+ int displayMarginBeginning() const;
+ void setDisplayMarginBeginning(int);
+
+ int displayMarginEnd() const;
+ void setDisplayMarginEnd(int);
+
Qt::LayoutDirection layoutDirection() const;
void setLayoutDirection(Qt::LayoutDirection);
Qt::LayoutDirection effectiveLayoutDirection() const;
@@ -218,6 +226,8 @@ Q_SIGNALS:
void keyNavigationWrapsChanged();
void cacheBufferChanged();
+ void displayMarginBeginningChanged();
+ void displayMarginEndChanged();
void layoutDirectionChanged();
void effectiveLayoutDirectionChanged();
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index e0f08fd50f..af7c23c02e 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -257,6 +257,8 @@ public:
int itemCount;
int buffer;
int bufferMode;
+ int displayMarginBeginning;
+ int displayMarginEnd;
Qt::LayoutDirection layoutDirection;
QQuickItemView::VerticalLayoutDirection verticalLayoutDirection;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 06749be819..2dd61e386f 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -777,8 +777,8 @@ void QQuickListViewPrivate::visibleItemsChanged()
void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex)
{
if (!visibleItems.isEmpty()) {
- const qreal from = isContentFlowReversed() ? -position() - size() : position();
- const qreal to = isContentFlowReversed() ? -position() : position() + size();
+ const qreal from = isContentFlowReversed() ? -position()-displayMarginBeginning-size() : position()-displayMarginBeginning;
+ const qreal to = isContentFlowReversed() ? -position()+displayMarginEnd : position()+size()+displayMarginEnd;
FxViewItem *firstItem = *visibleItems.constBegin();
bool fixedCurrent = currentItem && firstItem->item == currentItem->item;
@@ -2145,8 +2145,33 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
of additional memory usage. It is not a substitute for creating efficient
delegates; the fewer objects and bindings in a delegate, the faster a view can be
scrolled.
+
+ The cacheBuffer operates outside of any display margins specified by
+ displayMarginBeginning or displayMarginEnd.
*/
+/*!
+ \qmlproperty int QtQuick::ListView::displayMarginBeginning
+ \qmlproperty int QtQuick::ListView::displayMarginEnd
+ \since QtQuick 2.3
+
+ This property allows delegates to be displayed outside of the view geometry.
+
+ If this value is non-zero, the view will create extra delegates before the
+ start of the view, or after the end. The view will create as many delegates
+ as it can fit into the pixel size specified.
+
+ For example, if in a vertical view the delegate is 20 pixels high and
+ \c displayMarginBeginning and \c displayMarginEnd are both set to 40,
+ then 2 delegates above and 2 delegates below will be created and shown.
+
+ The default value is 0.
+
+ This property is meant for allowing certain UI configurations,
+ and not as a performance optimization. If you wish to create delegates
+ outside of the view geometry for performance reasons, you probably
+ want to use the cacheBuffer property instead.
+*/
/*!
\qmlpropertygroup QtQuick::ListView::section
@@ -2703,8 +2728,8 @@ void QQuickListView::viewportMoved(Qt::Orientations orient)
d->refillOrLayout();
// Set visibility of items to eliminate cost of items outside the visible area.
- qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
- qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
+ qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
+ qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
for (int i = 0; i < d->visibleItems.count(); ++i) {
FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i));
QQuickItemPrivate::get(item->item)->setCulled(item->endPosition() < from || item->position() > to);
@@ -2910,7 +2935,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
// there are no visible items except items marked for removal
index = visibleItems.count();
} else if (visibleItems.at(i)->index + 1 == modelIndex
- && visibleItems.at(i)->endPosition() <= buffer+tempPos+size()) {
+ && visibleItems.at(i)->endPosition() <= buffer+displayMarginEnd+tempPos+size()) {
// Special case of appending an item to the model.
index = visibleItems.count();
} else {
@@ -2939,7 +2964,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
// Insert items before the visible item.
int insertionIdx = index;
int i = 0;
- int from = tempPos - buffer;
+ int from = tempPos - displayMarginBeginning - buffer;
for (i = count-1; i >= 0; --i) {
if (pos > from && insertionIdx < visibleIndex) {
@@ -2970,7 +2995,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
}
} else {
int i = 0;
- int to = buffer+tempPos+size();
+ int to = buffer+displayMarginEnd+tempPos+size();
for (i = 0; i < count && pos <= to; ++i) {
FxViewItem *item = 0;
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index 32c271222d..5783418619 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -58,7 +58,7 @@
#include "qquickitemchangelistener_p.h"
#include <qqmlincubator.h>
-#include <private/qv4value_p.h>
+#include <private/qv4value_inl_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 7a4b359d91..f07571d3cc 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -49,6 +49,7 @@
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qevent.h>
+#include <QtGui/qstylehints.h>
#include <float.h>
@@ -56,8 +57,6 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlVisualTouchDebugging, QML_VISUAL_TOUCH_DEBUGGING)
-static const int PressAndHoldDelay = 800;
-
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
: enabled(true), hovered(false), longPress(false),
moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
@@ -627,7 +626,7 @@ void QQuickMouseArea::mousePressEvent(QMouseEvent *event)
#endif
setHovered(true);
d->startScene = event->windowPos();
- d->pressAndHoldTimer.start(PressAndHoldDelay, this);
+ d->pressAndHoldTimer.start(qApp->styleHints()->mousePressAndHoldInterval(), this);
setKeepMouseGrab(d->stealMouse);
event->setAccepted(setPressed(event->button(), true));
}
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index e0eb641528..973f6efdcc 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -43,6 +43,7 @@
#include <QtQuick/qquickwindow.h>
#include <private/qsgadaptationlayer_p.h>
#include <private/qquickitem_p.h>
+#include <private/qguiapplication_p.h>
#include <QEvent>
#include <QMouseEvent>
#include <math.h>
@@ -677,6 +678,10 @@ bool QQuickMultiPointTouchArea::sendMouseEvent(QMouseEvent *event)
QMouseEvent mouseEvent(event->type(), localPos, event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers());
mouseEvent.setAccepted(false);
+ QGuiApplicationPrivate::setMouseEventCapsAndVelocity(&mouseEvent,
+ QGuiApplicationPrivate::mouseEventCaps(event),
+ QGuiApplicationPrivate::mouseEventVelocity(event));
+ QGuiApplicationPrivate::setMouseEventSource(&mouseEvent, Qt::MouseEventSynthesizedByQt);
switch (mouseEvent.type()) {
case QEvent::MouseMove:
diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp
index 48f79a2192..ee1b66f2b5 100644
--- a/src/quick/items/qquickrectangle.cpp
+++ b/src/quick/items/qquickrectangle.cpp
@@ -321,6 +321,16 @@ void QQuickRectangle::doUpdate()
}
/*!
+ \qmlproperty bool QtQuick::Rectangle::antialiasing
+
+ Used to decide if the Rectangle should use antialiasing or not.
+ \l {Antialiasing} provides information on the performance implications
+ of this property.
+
+ The default is true for Rectangles with a radius, and false otherwise.
+*/
+
+/*!
\qmlpropertygroup QtQuick::Rectangle::border
\qmlproperty int QtQuick::Rectangle::border.width
\qmlproperty color QtQuick::Rectangle::border.color
@@ -409,6 +419,8 @@ void QQuickRectangle::setRadius(qreal radius)
return;
d->radius = radius;
+ d->setImplicitAntialiasing(radius != 0.0);
+
update();
emit radiusChanged();
}
@@ -476,7 +488,7 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
}
rectangle->setRadius(d->radius);
- rectangle->setAntialiasing(d->antialiasing || d->radius > 0);
+ rectangle->setAntialiasing(antialiasing());
QGradientStops stops;
if (d->gradient) {
diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp
index 410f18e767..54c7527eec 100644
--- a/src/quick/items/qquickscreen.cpp
+++ b/src/quick/items/qquickscreen.cpp
@@ -323,7 +323,7 @@ void QQuickScreenAttached::screenChanged(QScreen *screen)
this, SIGNAL(orientationChanged()));
connect(screen, SIGNAL(primaryOrientationChanged(Qt::ScreenOrientation)),
this, SIGNAL(primaryOrientationChanged()));
- connect(screen, SIGNAL(virtualGeometryChanged(const QRect &)),
+ connect(screen, SIGNAL(virtualGeometryChanged(QRect)),
this, SIGNAL(desktopGeometryChanged()));
connect(screen, SIGNAL(logicalDotsPerInchChanged(qreal)),
this, SIGNAL(logicalPixelDensityChanged()));
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index c9dee9a986..287173957f 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -88,6 +88,7 @@ QQuickTextPrivate::QQuickTextPrivate()
, truncated(false), hAlignImplicit(true), rightToLeftText(false)
, layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false)
{
+ implicitAntialiasing = true;
}
QQuickTextPrivate::ExtraData::ExtraData()
@@ -114,6 +115,7 @@ QQuickTextDocumentWithImageResources::QQuickTextDocumentWithImageResources(QQuic
{
setUndoRedoEnabled(false);
documentLayout()->registerHandler(QTextFormat::ImageObject, this);
+ connect(this, SIGNAL(baseUrlChanged(QUrl)), this, SLOT(reset()));
}
QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
@@ -125,14 +127,13 @@ QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
{
QQmlContext *context = qmlContext(parent());
- QUrl url = m_baseUrl.resolved(name);
if (type == QTextDocument::ImageResource) {
- QQuickPixmap *p = loadPixmap(context, url);
+ QQuickPixmap *p = loadPixmap(context, name);
return p->image();
}
- return QTextDocument::loadResource(type,url); // The *resolved* URL
+ return QTextDocument::loadResource(type, name);
}
void QQuickTextDocumentWithImageResources::requestFinished()
@@ -144,14 +145,6 @@ void QQuickTextDocumentWithImageResources::requestFinished()
}
}
-void QQuickTextDocumentWithImageResources::clear()
-{
- clearResources();
-
- QTextDocument::clear();
-}
-
-
QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
QTextDocument *, int, const QTextFormat &format)
{
@@ -166,7 +159,7 @@ QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
QSizeF size(width, height);
if (!hasWidth || !hasHeight) {
QQmlContext *context = qmlContext(parent());
- QUrl url = m_baseUrl.resolved(QUrl(imageFormat.name()));
+ QUrl url = baseUrl().resolved(QUrl(imageFormat.name()));
QQuickPixmap *p = loadPixmap(context, url);
if (!p->isReady()) {
@@ -204,19 +197,16 @@ void QQuickTextDocumentWithImageResources::drawObject(
QImage QQuickTextDocumentWithImageResources::image(const QTextImageFormat &format)
{
QQmlContext *context = qmlContext(parent());
- QUrl url = m_baseUrl.resolved(QUrl(format.name()));
+ QUrl url = baseUrl().resolved(QUrl(format.name()));
QQuickPixmap *p = loadPixmap(context, url);
return p->image();
}
-void QQuickTextDocumentWithImageResources::setBaseUrl(const QUrl &url, bool clear)
+void QQuickTextDocumentWithImageResources::reset()
{
- m_baseUrl = url;
- if (clear) {
- clearResources();
- markContentsDirty(0, characterCount());
- }
+ clearResources();
+ markContentsDirty(0, characterCount());
}
QQuickPixmap *QQuickTextDocumentWithImageResources::loadPixmap(
@@ -297,6 +287,15 @@ qreal QQuickTextPrivate::getImplicitHeight() const
return implicitHeight;
}
+/*!
+ \qmlproperty bool QtQuick::Text::antialiasing
+
+ Used to decide if the Text should use antialiasing or not. Only Text
+ with renderType of Text.NativeRendering can disable antialiasing.
+
+ The default is true.
+*/
+
void QQuickText::q_imagesLoaded()
{
Q_D(QQuickText);
@@ -620,8 +619,9 @@ void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height,
textLine->setHeight(0);
textLine->setLineOffset(lineOffset);
- // use the text item's width by default if it has one and wrap is on
- if (q->widthValid() && q->wrapMode() != QQuickText::NoWrap)
+ // use the text item's width by default if it has one and wrap is on or text must be aligned
+ if (q->widthValid() && (q->wrapMode() != QQuickText::NoWrap ||
+ q->effectiveHAlign() != QQuickText::AlignLeft))
textLine->setWidth(q->width());
else
textLine->setWidth(INT_MAX);
@@ -959,7 +959,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
// If the horizontal alignment is not left and the width was not valid we need to relayout
// now that we know the maximum line width.
- if (!implicitWidthValid && lineCount > 1 && q->effectiveHAlign() != QQuickText::AlignLeft) {
+ if (!implicitWidthValid && unwrappedLineCount > 1 && q->effectiveHAlign() != QQuickText::AlignLeft) {
widthExceeded = false;
heightExceeded = false;
continue;
@@ -1415,6 +1415,9 @@ void QQuickText::setFont(const QFont &font)
QFont oldFont = d->font;
d->font = font;
+ if (!antialiasing())
+ d->font.setStyleStrategy(QFont::NoAntialias);
+
if (d->font.pointSizeF() != -1) {
// 0.5pt resolution
qreal size = qRound(d->font.pointSizeF()*2.0);
@@ -1434,6 +1437,21 @@ void QQuickText::setFont(const QFont &font)
emit fontChanged(d->sourceFont);
}
+void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ Q_D(QQuickText);
+ Q_UNUSED(value);
+ if (change == ItemAntialiasingHasChanged) {
+ if (!antialiasing())
+ d->font.setStyleStrategy(QFont::NoAntialias);
+ else
+ d->font.setStyleStrategy(QFont::PreferAntialias);
+ d->implicitWidthValid = false;
+ d->implicitHeightValid = false;
+ d->updateLayout();
+ }
+}
+
/*!
\qmlproperty string QtQuick::Text::text
@@ -2198,7 +2216,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
else
node = static_cast<QQuickTextNode *>(oldNode);
- node->setUseNativeRenderer(d->renderType == NativeRendering && d->window->devicePixelRatio() <= 1);
+ node->setUseNativeRenderer(d->renderType == NativeRendering);
node->deleteContent();
node->setMatrix(QMatrix4x4());
@@ -2555,7 +2573,7 @@ bool QQuickTextPrivate::isLinkHoveredConnected()
text. The link must be in rich text or HTML format and the \a link
string provides access to the particular link.
- \sa hoveredLink
+ \sa hoveredLink, linkAt()
*/
/*!
@@ -2566,7 +2584,7 @@ bool QQuickTextPrivate::isLinkHoveredConnected()
embedded in the text. The link must be in rich text or HTML format
and the \a hoveredLink string provides access to the particular link.
- \sa onLinkHovered
+ \sa onLinkHovered, linkAt()
*/
QString QQuickText::hoveredLink() const
@@ -2635,9 +2653,6 @@ void QQuickText::hoverLeaveEvent(QHoverEvent *event)
not require advanced features such as transformation of the text. Using such features in
combination with the NativeRendering render type will lend poor and sometimes pixelated
results.
-
- On HighDpi "retina" displays and mobile and embedded platforms, this property is ignored
- and QtRendering is always used.
*/
QQuickText::RenderType QQuickText::renderType() const
{
@@ -2669,4 +2684,19 @@ void QQuickText::doLayout()
d->updateSize();
}
+/*!
+ \qmlmethod QtQuick::Text::linkAt(real x, real y)
+ \since 5.3
+
+ Returns the link string at point \a x, \a y in content coordinates,
+ or an empty string if no link exists at that point.
+
+ \sa hoveredLink
+*/
+QString QQuickText::linkAt(qreal x, qreal y) const
+{
+ Q_D(const QQuickText);
+ return d->anchorAt(QPointF(x, y));
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 489ef58344..44bd5aa9b0 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -210,6 +210,8 @@ public:
QString hoveredLink() const;
+ Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
+
Q_SIGNALS:
void textChanged(const QString &text);
void linkActivated(const QString &link);
@@ -241,6 +243,7 @@ Q_SIGNALS:
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
+ virtual void itemChange(ItemChange change, const ItemChangeData &value);
virtual void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry);
virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 1f6cd3eab5..12113f416c 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -195,16 +195,13 @@ public:
void setText(const QString &);
int resourcesLoading() const { return outstanding; }
- void clearResources();
-
- void clear();
-
QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format);
void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format);
QImage image(const QTextImageFormat &format);
- void setBaseUrl(const QUrl &url, bool clear = true);
+public Q_SLOTS:
+ void clearResources();
Q_SIGNALS:
void imagesLoaded();
@@ -215,11 +212,11 @@ protected:
QQuickPixmap *loadPixmap(QQmlContext *context, const QUrl &name);
private Q_SLOTS:
+ void reset();
void requestFinished();
private:
QHash<QUrl, QQuickPixmap *> m_resources;
- QUrl m_baseUrl;
int outstanding;
static QSet<QUrl> errors;
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index ffc732621d..810a47cfa8 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -418,9 +418,6 @@ void QQuickTextEdit::setTextFormat(TextFormat format)
not require advanced features such as transformation of the text. Using such features in
combination with the NativeRendering render type will lend poor and sometimes pixelated
results.
-
- On HighDpi "retina" displays and mobile and embedded platforms, this property is ignored
- and QtRendering is always used.
*/
QQuickTextEdit::RenderType QQuickTextEdit::renderType() const
{
@@ -830,7 +827,7 @@ void QQuickTextEdit::setBaseUrl(const QUrl &url)
if (baseUrl() != url) {
d->baseUrl = url;
- d->document->setBaseUrl(url, d->richText);
+ d->document->setBaseUrl(url);
emit baseUrlChanged();
}
}
@@ -1281,7 +1278,7 @@ void QQuickTextEdit::componentComplete()
Q_D(QQuickTextEdit);
QQuickImplicitSizeItem::componentComplete();
- d->document->setBaseUrl(baseUrl(), d->richText);
+ d->document->setBaseUrl(baseUrl());
#ifndef QT_NO_TEXTHTML_PARSER
if (d->richText)
d->control->setHtml(d->text);
@@ -2371,7 +2368,7 @@ QQuickTextNode *QQuickTextEditPrivate::createTextNode()
{
Q_Q(QQuickTextEdit);
QQuickTextNode* node = new QQuickTextNode(q);
- node->setUseNativeRenderer(renderType == QQuickTextEdit::NativeRendering && window->devicePixelRatio() <= 1);
+ node->setUseNativeRenderer(renderType == QQuickTextEdit::NativeRendering);
node->initEngine(color, selectedTextColor, selectionColor);
return node;
}
@@ -2518,7 +2515,7 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
The link must be in rich text or HTML format and the
\a link string provides access to the particular link.
- \sa hoveredLink
+ \sa hoveredLink, linkAt()
*/
/*!
@@ -2529,7 +2526,7 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
embedded in the text. The link must be in rich text or HTML format
and the link string provides access to the particular link.
- \sa onLinkHovered
+ \sa onLinkHovered, linkAt()
*/
QString QQuickTextEdit::hoveredLink() const
@@ -2602,4 +2599,19 @@ void QQuickTextEdit::append(const QString &text)
d->control->updateCursorRectangle(false);
}
+/*!
+ \qmlmethod QtQuick::TextEdit::linkAt(real x, real y)
+ \since 5.3
+
+ Returns the link string at point \a x, \a y in content coordinates,
+ or an empty string if no link exists at that point.
+
+ \sa hoveredLink
+*/
+QString QQuickTextEdit::linkAt(qreal x, qreal y) const
+{
+ Q_D(const QQuickTextEdit);
+ return d->control->anchorAt(QPointF(x, y));
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 8057f76be5..b84552d255 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -258,6 +258,8 @@ public:
QString hoveredLink() const;
+ Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
+
Q_SIGNALS:
void textChanged();
void contentSizeChanged();
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 1dd1dfa57e..9f155f9cf7 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -155,9 +155,6 @@ void QQuickTextInput::setText(const QString &s)
not require advanced features such as transformation of the text. Using such features in
combination with the NativeRendering render type will lend poor and sometimes pixelated
results.
-
- On HighDpi "retina" displays and mobile and embedded platforms, this property is ignored
- and QtRendering is always used.
*/
QQuickTextInput::RenderType QQuickTextInput::renderType() const
{
@@ -1862,7 +1859,7 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
}
}
} else {
- node->setUseNativeRenderer(d->renderType == NativeRendering && d->window->devicePixelRatio() <= 1);
+ node->setUseNativeRenderer(d->renderType == NativeRendering);
node->deleteContent();
node->setMatrix(QMatrix4x4());
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index 18ee1a479d..1133636a74 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -144,11 +144,9 @@ QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun
{
QSGRenderContext *sg = QQuickItemPrivate::get(m_ownerElement)->sceneGraphRenderContext();
QRawFont font = glyphs.rawFont();
- bool smoothScalable = QFontDatabase().isSmoothlyScalable(font.familyName(),
- font.styleName());
- QSGGlyphNode *node = m_useNativeRenderer || !smoothScalable
- ? sg->sceneGraphContext()->createNativeGlyphNode(sg)
- : sg->sceneGraphContext()->createGlyphNode(sg);
+ bool smoothScalable = QFontDatabase().isSmoothlyScalable(font.familyName(), font.styleName());
+ bool preferNativeGlyphNode = m_useNativeRenderer || !smoothScalable;
+ QSGGlyphNode *node = sg->sceneGraphContext()->createGlyphNode(sg, preferNativeGlyphNode);
node->setOwnerElement(m_ownerElement);
node->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp
index 20eb1dce5b..14f8c204f3 100644
--- a/src/quick/items/qquicktranslate.cpp
+++ b/src/quick/items/qquicktranslate.cpp
@@ -458,4 +458,79 @@ void QQuickRotation::applyTo(QMatrix4x4 *matrix) const
matrix->translate(-d->origin);
}
+class QQuickMatrix4x4Private : public QQuickTransformPrivate
+{
+public:
+ QQuickMatrix4x4Private()
+ : matrix() {}
+ QMatrix4x4 matrix;
+};
+
+/*!
+ \qmltype Matrix4x4
+ \instantiates QQuickMatrix4x4
+ \inqmlmodule QtQuick
+ \ingroup qtquick-visual-transforms
+ \brief Provides a way to apply a 4x4 tranformation matrix to an \l Item
+
+ The Matrix4x4 type provides a way to apply a transformation to an
+ \l Item through a 4x4 matrix.
+
+ It allows for a combination of rotation, scale, translatation and shearing
+ by using just one tranformation provided in a 4x4-matrix.
+
+ The following example rotates a Rectangle 45 degress (PI/4):
+
+ \qml
+ Rectangle {
+ width: 100
+ height: 100
+ color: "red"
+
+ transform: Matrix4x4 {
+ property real a: Math.PI / 4
+ matrix: Qt.matrix4x4(Math.cos(a), -Math.sin(a), 0, 0,
+ Math.sin(a), Math.cos(a), 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1)
+ }
+ }
+ \endqml
+*/
+QQuickMatrix4x4::QQuickMatrix4x4(QObject *parent)
+ : QQuickTransform(*new QQuickMatrix4x4Private, parent)
+{
+}
+
+QQuickMatrix4x4::~QQuickMatrix4x4()
+{
+}
+
+/*!
+ \qmlproperty QMatrix4x4 QtQuick::Matrix4x4::matrix
+
+ 4x4-matrix which will be used in the tranformation of an \l Item
+*/
+QMatrix4x4 QQuickMatrix4x4::matrix() const
+{
+ Q_D(const QQuickMatrix4x4);
+ return d->matrix;
+}
+
+void QQuickMatrix4x4::setMatrix(const QMatrix4x4 &matrix)
+{
+ Q_D(QQuickMatrix4x4);
+ if (d->matrix == matrix)
+ return;
+ d->matrix = matrix;
+ update();
+ emit matrixChanged();
+}
+
+void QQuickMatrix4x4::applyTo(QMatrix4x4 *matrix) const
+{
+ Q_D(const QQuickMatrix4x4);
+ *matrix *= d->matrix;
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h
index d7843fe103..dd93275a28 100644
--- a/src/quick/items/qquicktranslate_p.h
+++ b/src/quick/items/qquicktranslate_p.h
@@ -148,6 +148,29 @@ private:
Q_DECLARE_PRIVATE(QQuickRotation)
};
+class QQuickMatrix4x4Private;
+class Q_AUTOTEST_EXPORT QQuickMatrix4x4 : public QQuickTransform
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY matrixChanged)
+public:
+ QQuickMatrix4x4(QObject *parent = 0);
+ ~QQuickMatrix4x4();
+
+ QMatrix4x4 matrix() const;
+ void setMatrix(const QMatrix4x4& matrix);
+
+ void applyTo(QMatrix4x4 *matrix) const;
+
+Q_SIGNALS:
+ void matrixChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QQuickMatrix4x4)
+};
+
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickTranslate)
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index d1fe489dcb..1a3d225995 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -56,6 +56,26 @@
QT_BEGIN_NAMESPACE
+DEFINE_OBJECT_VTABLE(QQuickRootItemMarker);
+
+QQuickRootItemMarker::QQuickRootItemMarker(QQuickViewPrivate *view)
+ : QV4::Object(QQmlEnginePrivate::getV4Engine(view->engine.data()))
+ , view(view)
+{
+ setVTable(staticVTable());
+}
+
+void QQuickRootItemMarker::markObjects(QV4::Managed *that, QV4::ExecutionEngine *e)
+{
+ QQuickItem *root = static_cast<QQuickRootItemMarker*>(that)->view->root;
+ if (root) {
+ QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(root);
+ rootPrivate->markObjects(e);
+ }
+
+ QV4::Object::markObjects(that, e);
+}
+
void QQuickViewPrivate::init(QQmlEngine* e)
{
Q_Q(QQuickView);
@@ -68,6 +88,13 @@ void QQuickViewPrivate::init(QQmlEngine* e)
if (!engine.data()->incubationController())
engine.data()->setIncubationController(q->incubationController());
+ {
+ QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine.data());
+ QV4::Scope scope(v4);
+ QV4::Scoped<QQuickRootItemMarker> v(scope, new (v4->memoryManager) QQuickRootItemMarker(this));
+ rootItemMarker = v;
+ }
+
if (QQmlDebugService::isDebuggingEnabled())
QQmlInspectorService::instance()->addView(q);
}
@@ -576,7 +603,7 @@ void QQuickView::resizeEvent(QResizeEvent *e)
/*! \reimp */
void QQuickView::keyPressEvent(QKeyEvent *e)
{
- QQmlProfilerService::addEvent(QQmlProfilerService::Key);
+ Q_QML_PROFILE(addEvent<QQmlProfilerService::Key>());
QQuickWindow::keyPressEvent(e);
}
@@ -584,7 +611,7 @@ void QQuickView::keyPressEvent(QKeyEvent *e)
/*! \reimp */
void QQuickView::keyReleaseEvent(QKeyEvent *e)
{
- QQmlProfilerService::addEvent(QQmlProfilerService::Key);
+ Q_QML_PROFILE(addEvent<QQmlProfilerService::Key>());
QQuickWindow::keyReleaseEvent(e);
}
@@ -592,7 +619,7 @@ void QQuickView::keyReleaseEvent(QKeyEvent *e)
/*! \reimp */
void QQuickView::mouseMoveEvent(QMouseEvent *e)
{
- QQmlProfilerService::addEvent(QQmlProfilerService::Mouse);
+ Q_QML_PROFILE(addEvent<QQmlProfilerService::Mouse>());
QQuickWindow::mouseMoveEvent(e);
}
@@ -600,7 +627,7 @@ void QQuickView::mouseMoveEvent(QMouseEvent *e)
/*! \reimp */
void QQuickView::mousePressEvent(QMouseEvent *e)
{
- QQmlProfilerService::addEvent(QQmlProfilerService::Mouse);
+ Q_QML_PROFILE(addEvent<QQmlProfilerService::Mouse>());
QQuickWindow::mousePressEvent(e);
}
@@ -608,7 +635,7 @@ void QQuickView::mousePressEvent(QMouseEvent *e)
/*! \reimp */
void QQuickView::mouseReleaseEvent(QMouseEvent *e)
{
- QQmlProfilerService::addEvent(QQmlProfilerService::Mouse);
+ Q_QML_PROFILE(addEvent<QQmlProfilerService::Mouse>());
QQuickWindow::mouseReleaseEvent(e);
}
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index 170c93a6cf..74e40081e9 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -51,12 +51,17 @@
#include <QtCore/QWeakPointer>
#include <QtQml/qqmlengine.h>
+#include <private/qv4object_p.h>
#include "qquickwindow_p.h"
#include "qquickitemchangelistener_p.h"
QT_BEGIN_NAMESPACE
+namespace QV4 {
+struct ExecutionEngine;
+}
+
class QQmlContext;
class QQmlError;
class QQuickItem;
@@ -94,6 +99,23 @@ public:
QQuickView::ResizeMode resizeMode;
QSize initialSize;
QElapsedTimer frameTimer;
+ QV4::PersistentValue rootItemMarker;
+};
+
+struct QQuickRootItemMarker : public QV4::Object
+{
+ V4_OBJECT
+
+ QQuickRootItemMarker(QQuickViewPrivate *view);
+
+ static void destroy(Managed *that)
+ {
+ static_cast<QQuickRootItemMarker*>(that)->~QQuickRootItemMarker();
+ }
+
+ static void markObjects(Managed *that, QV4::ExecutionEngine *e);
+
+ QQuickViewPrivate *view;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 532021932f..6778cf13e9 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -257,8 +257,10 @@ void QQuickWindowPrivate::polishItems()
for (QSet<QQuickItem *>::iterator it = itms.begin(); it != itms.end(); ++it) {
QQuickItem *item = *it;
- QQuickItemPrivate::get(item)->polishScheduled = false;
- item->updatePolish();
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->polishScheduled = false;
+ if (item->isVisible() || (itemPrivate->extra.isAllocated() && itemPrivate->extra->effectRefCount>0))
+ item->updatePolish();
}
}
@@ -342,6 +344,7 @@ void QQuickWindowPrivate::syncSceneGraph()
mode |= QSGRenderer::ClearColorBuffer;
renderer->setClearMode(mode);
+ renderer->setCustomRenderMode(customRenderMode);
context->endSync();
}
@@ -416,6 +419,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c)
contentItemPrivate->windowRefCount = 1;
contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
+ customRenderMode = qgetenv("QSG_VISUALIZE");
windowManager = QSGRenderLoop::instance();
QSGContext *sg = windowManager->sceneGraphContext();
context = windowManager->createRenderContext(sg);
@@ -472,6 +476,7 @@ static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::Touc
transformedVelocity = transformMatrix.mapVector(p.velocity()).toVector2D();
}
QGuiApplicationPrivate::setMouseEventCapsAndVelocity(me, event->device()->capabilities(), transformedVelocity);
+ QGuiApplicationPrivate::setMouseEventSource(me, Qt::MouseEventSynthesizedByQt);
return me;
}
@@ -525,7 +530,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
item->grabMouse();
item->grabTouchPoints(QVector<int>() << touchMouseId);
- QQuickItemPrivate::get(item)->deliverMouseEvent(mousePress.data());
+ QCoreApplication::sendEvent(item, mousePress.data());
event->setAccepted(mousePress->isAccepted());
if (!mousePress->isAccepted()) {
touchMouseId = -1;
@@ -538,7 +543,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
if (mousePress->isAccepted() && checkIfDoubleClicked(event->timestamp())) {
QScopedPointer<QMouseEvent> mouseDoubleClick(touchToMouseEvent(QEvent::MouseButtonDblClick, p, event, item));
- QQuickItemPrivate::get(item)->deliverMouseEvent(mouseDoubleClick.data());
+ QCoreApplication::sendEvent(item, mouseDoubleClick.data());
event->setAccepted(mouseDoubleClick->isAccepted());
if (mouseDoubleClick->isAccepted()) {
return true;
@@ -559,7 +564,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
if (p.state() & Qt::TouchPointMoved) {
if (mouseGrabberItem) {
QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event, mouseGrabberItem));
- QQuickItemPrivate::get(item)->deliverMouseEvent(me.data());
+ QCoreApplication::sendEvent(item, me.data());
event->setAccepted(me->isAccepted());
if (me->isAccepted()) {
itemForTouchPointId[p.id()] = mouseGrabberItem; // N.B. the mouseGrabberItem may be different after returning from sendEvent()
@@ -589,7 +594,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
touchMouseId = -1;
if (mouseGrabberItem) {
QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseButtonRelease, p, event, mouseGrabberItem));
- QQuickItemPrivate::get(item)->deliverMouseEvent(me.data());
+ QCoreApplication::sendEvent(item, me.data());
if (mouseGrabberItem) // might have ungrabbed due to event
mouseGrabberItem->ungrabMouse();
return me->isAccepted();
@@ -1298,24 +1303,43 @@ bool QQuickWindow::event(QEvent *e)
void QQuickWindow::keyPressEvent(QKeyEvent *e)
{
Q_D(QQuickWindow);
-
-#ifndef QT_NO_SHORTCUT
- // Try looking for a Shortcut before sending key events
- if (QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focusObject(), e))
- return;
-#endif
-
- if (d->activeFocusItem)
- sendEvent(d->activeFocusItem, e);
+ d->deliverKeyEvent(e);
}
/*! \reimp */
void QQuickWindow::keyReleaseEvent(QKeyEvent *e)
{
Q_D(QQuickWindow);
+ d->deliverKeyEvent(e);
+}
- if (d->activeFocusItem)
- sendEvent(d->activeFocusItem, e);
+void QQuickWindowPrivate::deliverKeyEvent(QKeyEvent *e)
+{
+ Q_Q(QQuickWindow);
+
+#ifndef QT_NO_SHORTCUT
+ // Try looking for a Shortcut before sending key events
+ if (e->type() == QEvent::KeyPress
+ && QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(q->focusObject(), e))
+ return;
+#endif
+
+ if (activeFocusItem)
+ q->sendEvent(activeFocusItem, e);
+#ifdef Q_OS_MAC
+ else {
+ // This is the case for popup windows on Mac, where popup windows get focus
+ // in Qt (after exposure) but they are not "key windows" in the Cocoa sense.
+ // Therefore, the will never receive key events from Cocoa. Instead, the
+ // toplevel non-popup window (the application current "key window") will
+ // receive them. (QWidgetWindow does something similar for widgets, by keeping
+ // a list of popup windows, and forwarding the key event to the top-most popup.)
+ QWindow *focusWindow = qApp->focusWindow();
+ if (focusWindow && focusWindow != q
+ && (focusWindow->flags() & Qt::Popup) == Qt::Popup)
+ QGuiApplication::sendEvent(focusWindow, e);
+ }
+#endif
}
QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos)
@@ -1327,6 +1351,7 @@ QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *t
event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers());
QGuiApplicationPrivate::setMouseEventCapsAndVelocity(me, caps, velocity);
+ QGuiApplicationPrivate::setMouseEventSource(me, QGuiApplicationPrivate::mouseEventSource(event));
me->setTimestamp(event->timestamp());
return me;
}
@@ -1403,6 +1428,12 @@ bool QQuickWindowPrivate::deliverMouseEvent(QMouseEvent *event)
void QQuickWindow::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+
+ if (event->source() == Qt::MouseEventSynthesizedBySystem) {
+ event->accept();
+ return;
+ }
+
#ifdef MOUSE_DEBUG
qWarning() << "QQuickWindow::mousePressEvent()" << event->localPos() << event->button() << event->buttons();
#endif
@@ -1414,6 +1445,12 @@ void QQuickWindow::mousePressEvent(QMouseEvent *event)
void QQuickWindow::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+
+ if (event->source() == Qt::MouseEventSynthesizedBySystem) {
+ event->accept();
+ return;
+ }
+
#ifdef MOUSE_DEBUG
qWarning() << "QQuickWindow::mouseReleaseEvent()" << event->localPos() << event->button() << event->buttons();
#endif
@@ -1432,6 +1469,12 @@ void QQuickWindow::mouseReleaseEvent(QMouseEvent *event)
void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+
+ if (event->source() == Qt::MouseEventSynthesizedBySystem) {
+ event->accept();
+ return;
+ }
+
#ifdef MOUSE_DEBUG
qWarning() << "QQuickWindow::mouseDoubleClickEvent()" << event->localPos() << event->button() << event->buttons();
#endif
@@ -1467,6 +1510,12 @@ bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item,
void QQuickWindow::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+
+ if (event->source() == Qt::MouseEventSynthesizedBySystem) {
+ event->accept();
+ return;
+ }
+
#ifdef MOUSE_DEBUG
qWarning() << "QQuickWindow::mouseMoveEvent()" << event->localPos() << event->button() << event->buttons();
#endif
@@ -1815,11 +1864,11 @@ bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QTouchEv
itemForTouchPointId[id] = item;
// Deliver the touch event to the given item
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- itemPrivate->deliverTouchEvent(touchEvent.data());
+ QCoreApplication::sendEvent(item, touchEvent.data());
touchEventAccepted = touchEvent->isAccepted();
// If the touch event wasn't accepted, synthesize a mouse event and see if the item wants it.
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
if (!touchEventAccepted && (itemPrivate->acceptedMouseButtons() & Qt::LeftButton)) {
// send mouse event
event->setAccepted(translateTouchToMouse(item, event));
@@ -2237,16 +2286,12 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
case QEvent::KeyPress:
case QEvent::KeyRelease:
e->accept();
- QQuickItemPrivate::get(item)->deliverKeyEvent(static_cast<QKeyEvent *>(e));
+ QCoreApplication::sendEvent(item, e);
while (!e->isAccepted() && (item = item->parentItem())) {
e->accept();
- QQuickItemPrivate::get(item)->deliverKeyEvent(static_cast<QKeyEvent *>(e));
+ QCoreApplication::sendEvent(item, e);
}
break;
- case QEvent::FocusIn:
- case QEvent::FocusOut:
- QQuickItemPrivate::get(item)->deliverFocusEvent(static_cast<QFocusEvent *>(e));
- break;
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
@@ -2255,7 +2300,7 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
if (!d->sendFilteredMouseEvent(item->parentItem(), item, e)) {
// accept because qml items by default accept and have to explicitly opt out of accepting
e->accept();
- QQuickItemPrivate::get(item)->deliverMouseEvent(static_cast<QMouseEvent *>(e));
+ QCoreApplication::sendEvent(item, e);
}
break;
case QEvent::UngrabMouse:
@@ -2266,30 +2311,26 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
break;
#ifndef QT_NO_WHEELEVENT
case QEvent::Wheel:
- QQuickItemPrivate::get(item)->deliverWheelEvent(static_cast<QWheelEvent *>(e));
- break;
#endif
+#ifndef QT_NO_DRAGANDDROP
+ case QEvent::DragEnter:
+ case QEvent::DragMove:
+ case QEvent::DragLeave:
+ case QEvent::Drop:
+#endif
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
case QEvent::HoverEnter:
case QEvent::HoverLeave:
case QEvent::HoverMove:
- QQuickItemPrivate::get(item)->deliverHoverEvent(static_cast<QHoverEvent *>(e));
+ case QEvent::TouchCancel:
+ QCoreApplication::sendEvent(item, e);
break;
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
d->sendFilteredTouchEvent(item->parentItem(), item, static_cast<QTouchEvent *>(e));
break;
- case QEvent::TouchCancel:
- QQuickItemPrivate::get(item)->deliverTouchEvent(static_cast<QTouchEvent *>(e));
- break;
-#ifndef QT_NO_DRAGANDDROP
- case QEvent::DragEnter:
- case QEvent::DragMove:
- case QEvent::DragLeave:
- case QEvent::Drop:
- QQuickItemPrivate::get(item)->deliverDragEvent(e);
- break;
-#endif
default:
break;
}
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 418633b6ac..944a320dce 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -57,6 +57,7 @@
#include "qquickwindow.h"
#include <QtQuick/private/qsgcontext_p.h>
+#include <private/qsgbatchrenderer_p.h>
#include <QtCore/qthread.h>
#include <QtCore/qmutex.h>
@@ -111,6 +112,8 @@ public:
QQuickItem *activeFocusItem;
+ void deliverKeyEvent(QKeyEvent *e);
+
// Keeps track of the item currently receiving mouse events
QQuickItem *mouseGrabberItem;
#ifndef QT_NO_CURSOR
@@ -198,6 +201,7 @@ public:
QSGRenderContext *context;
QSGRenderer *renderer;
+ QByteArray customRenderMode; // Default renderer supports "clip", "overdraw", "changes", "batches" and blank.
QSGRenderLoop *windowManager;
QQuickAnimatorController *animationController;
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index 5168ec2c24..e1fccbe762 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -16,8 +16,6 @@ QMAKE_DOCS = $$PWD/doc/qtquick.qdocconf
ANDROID_LIB_DEPENDENCIES = \
lib/libQt5QuickParticles.so
-ANDROID_LIB_DEPENDENCY_REPLACEMENTS = \
- "plugins/platforms/android/libqtforandroid.so:plugins/platforms/android/libqtforandroidGL.so"
MODULE_PLUGIN_TYPES += \
accessible/libqtaccessiblequick.so
ANDROID_BUNDLED_FILES += \
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 42a6c23982..8dfa0d2c2c 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -43,6 +43,10 @@
#include "qsgbatchrenderer_p.h"
#include <private/qsgshadersourcebuilder_p.h>
+#include <QQuickWindow>
+
+#include <qmath.h>
+
#include <QtCore/QElapsedTimer>
#include <QtGui/QGuiApplication>
@@ -107,7 +111,7 @@ bool qsg_sort_batch_is_valid(Batch *a, Batch *b) { return a->first && !b->first;
bool qsg_sort_batch_increasing_order(Batch *a, Batch *b) { return a->first->order < b->first->order; }
bool qsg_sort_batch_decreasing_order(Batch *a, Batch *b) { return a->first->order > b->first->order; }
-QSGMaterial::Flag QSGMaterial_RequiresFullMatrixBit = (QSGMaterial::Flag) (QSGMaterial::RequiresFullMatrix & ~QSGMaterial::RequiresFullMatrixExceptTranslate);
+QSGMaterial::Flag QSGMaterial_FullMatrix = (QSGMaterial::Flag) (QSGMaterial::RequiresFullMatrix & ~QSGMaterial::RequiresFullMatrixExceptTranslate);
struct QMatrix4x4_Accessor
{
@@ -172,11 +176,8 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material)
if (qsg_render_timing)
qDebug(" - compiling material: %dms", (int) qsg_renderer_timer.elapsed());
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphContextFrame,
- qsg_renderer_timer.nsecsElapsed());
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphContextFrame, (
+ qsg_renderer_timer.nsecsElapsed()));
#endif
rewrittenShaders[type] = shader;
@@ -211,11 +212,8 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate
if (qsg_render_timing)
qDebug(" - compiling material: %dms", (int) qsg_renderer_timer.elapsed());
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphContextFrame,
- qsg_renderer_timer.nsecsElapsed());
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphContextFrame, (
+ qsg_renderer_timer.nsecsElapsed()));
#endif
return shader;
@@ -312,6 +310,9 @@ void Updater::updateStates(QSGNode *n)
qDebug() << " - forceupdate";
}
+ if (Q_UNLIKELY(renderer->m_visualizeMode == Renderer::VisualizeChanges))
+ renderer->visualizeChangesPrepare(sn);
+
visitNode(sn);
}
@@ -771,6 +772,7 @@ Renderer::Renderer(QSGRenderContext *ctx)
, m_currentClip(0)
, m_currentClipType(NoClip)
, m_vao(0)
+ , m_visualizeMode(VisualizeNothing)
{
setNodeUpdater(new Updater(this));
@@ -1684,7 +1686,7 @@ void Renderer::uploadMergedElement(Element *e, int vaOffset, char **vertexData,
*indexCount += iCount;
}
-const QMatrix4x4 &Renderer::matrixForRoot(Node *node)
+static QMatrix4x4 qsg_matrixForRoot(Node *node)
{
if (node->type() == QSGNode::TransformNodeType)
return static_cast<QSGTransformNode *>(node->sgNode)->combinedMatrix();
@@ -1717,14 +1719,12 @@ void Renderer::uploadBatch(Batch *b)
QSGGeometryNode *gn = b->first->node;
QSGGeometry *g = gn->geometry();
-
+ QSGMaterial::Flags flags = gn->activeMaterial()->flags();
bool canMerge = (g->drawingMode() == GL_TRIANGLES || g->drawingMode() == GL_TRIANGLE_STRIP)
&& b->positionAttribute >= 0
&& g->indexType() == GL_UNSIGNED_SHORT
- && (gn->activeMaterial()->flags() & QSGMaterial::CustomCompileStep) == 0
- && (((gn->activeMaterial()->flags() & QSGMaterial::RequiresDeterminant) == 0)
- || (((gn->activeMaterial()->flags() & QSGMaterial_RequiresFullMatrixBit) == 0) && b->isTranslateOnlyToRoot())
- )
+ && (flags & (QSGMaterial::CustomCompileStep | QSGMaterial_FullMatrix)) == 0
+ && ((flags & QSGMaterial::RequiresFullMatrixExceptTranslate) == 0 || b->isTranslateOnlyToRoot())
&& b->isSafeToBatch();
b->merged = canMerge;
@@ -2020,7 +2020,7 @@ void Renderer::renderMergedBatch(const Batch *batch)
// We always have dirty matrix as all batches are at a unique z range.
QSGMaterialShader::RenderState::DirtyStates dirty = QSGMaterialShader::RenderState::DirtyMatrix;
if (batch->root)
- m_current_model_view_matrix = matrixForRoot(batch->root);
+ m_current_model_view_matrix = qsg_matrixForRoot(batch->root);
else
m_current_model_view_matrix.setToIdentity();
m_current_determinant = m_current_model_view_matrix.determinant();
@@ -2149,7 +2149,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
char *iOffset = indexBase + batch->vertexCount * gn->geometry()->sizeOfVertex();
#endif
- QMatrix4x4 rootMatrix = batch->root ? matrixForRoot(batch->root) : QMatrix4x4();
+ QMatrix4x4 rootMatrix = batch->root ? qsg_matrixForRoot(batch->root) : QMatrix4x4();
while (e) {
gn = e->node;
@@ -2183,6 +2183,10 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
if (g->drawingMode() == GL_LINE_STRIP || g->drawingMode() == GL_LINE_LOOP || g->drawingMode() == GL_LINES)
glLineWidth(g->lineWidth());
+#if !defined(QT_OPENGL_ES_2)
+ else if (g->drawingMode() == GL_POINTS)
+ glPointSize(g->lineWidth());
+#endif
if (g->indexCount())
glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), iOffset);
@@ -2369,7 +2373,6 @@ void Renderer::render()
cleanupBatches(&m_opaqueBatches);
cleanupBatches(&m_alphaBatches);
-
if (m_rebuild & BuildBatches) {
prepareOpaqueBatches();
prepareAlphaBatches();
@@ -2419,6 +2422,9 @@ void Renderer::render()
m_rebuild = 0;
+ if (m_visualizeMode != VisualizeNothing)
+ visualize();
+
if (m_vao)
m_vao->release();
}
@@ -2457,7 +2463,7 @@ void Renderer::renderRenderNode(Batch *batch)
QMatrix4x4 matrix;
while (xform != rootNode()) {
if (xform->type() == QSGNode::TransformNodeType) {
- matrix = matrixForRoot(e->root) * static_cast<QSGTransformNode *>(xform)->combinedMatrix();
+ matrix = qsg_matrixForRoot(e->root) * static_cast<QSGTransformNode *>(xform)->combinedMatrix();
break;
}
xform = xform->parent();
@@ -2521,6 +2527,312 @@ void Renderer::renderRenderNode(Batch *batch)
}
+class VisualizeShader : public QOpenGLShaderProgram
+{
+public:
+ int color;
+ int matrix;
+ int rotation;
+ int tweak;
+};
+
+void Renderer::visualizeDrawGeometry(const QSGGeometry *g)
+{
+ if (g->attributeCount() < 1)
+ return;
+ const QSGGeometry::Attribute *a = g->attributes();
+ glVertexAttribPointer(0, a->tupleSize, a->type, false, g->sizeOfVertex(), g->vertexData());
+ if (g->indexCount())
+ glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), g->indexData());
+ else
+ glDrawArrays(g->drawingMode(), 0, g->vertexCount());
+
+}
+
+void Renderer::visualizeBatch(Batch *b)
+{
+ VisualizeShader *shader = static_cast<VisualizeShader *>(m_shaderManager->visualizeProgram);
+
+ if (b->positionAttribute != 0)
+ return;
+
+ QSGGeometryNode *gn = b->first->node;
+ QSGGeometry *g = gn->geometry();
+ const QSGGeometry::Attribute &a = g->attributes()[b->positionAttribute];
+
+ glBindBuffer(GL_ARRAY_BUFFER, b->vbo.id);
+
+ QMatrix4x4 matrix(m_current_projection_matrix);
+ if (b->root)
+ matrix = matrix * qsg_matrixForRoot(b->root);
+
+ QRect viewport = viewportRect();
+ shader->setUniformValue(shader->tweak, viewport.width(), viewport.height(), b->merged ? 0 : 1, 0);
+
+ QColor color = QColor::fromHsvF((rand() & 1023) / 1023.0, 1.0, 1.0);
+ float cr = color.redF();
+ float cg = color.greenF();
+ float cb = color.blueF();
+ shader->setUniformValue(shader->color, cr, cg, cb, 1.0);
+
+ if (b->merged) {
+ shader->setUniformValue(shader->matrix, matrix);
+ for (int ds=0; ds<b->drawSets.size(); ++ds) {
+ const DrawSet &set = b->drawSets.at(ds);
+ glVertexAttribPointer(a.position, 2, a.type, false, g->sizeOfVertex(), (void *) (qintptr) (set.vertices));
+ glDrawElements(g->drawingMode(), set.indexCount, GL_UNSIGNED_SHORT, (void *) (qintptr) (b->vbo.data + set.indices));
+ }
+ } else {
+ Element *e = b->first;
+ int offset = 0;
+ while (e) {
+ gn = e->node;
+ g = gn->geometry();
+ shader->setUniformValue(shader->matrix, matrix * *gn->matrix());
+ glVertexAttribPointer(a.position, a.tupleSize, a.type, false, g->sizeOfVertex(), (void *) (qintptr) offset);
+ glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), g->indexData());
+ offset += g->sizeOfVertex() * g->vertexCount();
+ e = e->nextInBatch;
+ }
+ }
+}
+
+
+
+
+void Renderer::visualizeClipping(QSGNode *node)
+{
+ if (node->type() == QSGNode::ClipNodeType) {
+ VisualizeShader *shader = static_cast<VisualizeShader *>(m_shaderManager->visualizeProgram);
+ QSGClipNode *clipNode = static_cast<QSGClipNode *>(node);
+ QMatrix4x4 matrix = m_current_projection_matrix;
+ if (clipNode->matrix())
+ matrix = matrix * *clipNode->matrix();
+ shader->setUniformValue(shader->matrix, matrix);
+ visualizeDrawGeometry(clipNode->geometry());
+ }
+
+ QSGNODE_TRAVERSE(node) {
+ visualizeClipping(child);
+ }
+}
+
+#define QSGNODE_DIRTY_PARENT (QSGNode::DirtyNodeAdded \
+ | QSGNode::DirtyOpacity \
+ | QSGNode::DirtyMatrix \
+ | QSGNode::DirtyNodeRemoved)
+
+void Renderer::visualizeChangesPrepare(Node *n, uint parentChanges)
+{
+ uint childDirty = (parentChanges | n->dirtyState) & QSGNODE_DIRTY_PARENT;
+ uint selfDirty = n->dirtyState | parentChanges;
+ if (n->type() == QSGNode::GeometryNodeType && selfDirty != 0)
+ m_visualizeChanceSet.insert(n, selfDirty);
+ SHADOWNODE_TRAVERSE(n) {
+ visualizeChangesPrepare(*child, childDirty);
+ }
+}
+
+void Renderer::visualizeChanges(Node *n)
+{
+
+ if (n->type() == QSGNode::GeometryNodeType && m_visualizeChanceSet.contains(n)) {
+ uint dirty = m_visualizeChanceSet.value(n);
+ bool tinted = (dirty & QSGNODE_DIRTY_PARENT) != 0;
+
+ VisualizeShader *shader = static_cast<VisualizeShader *>(m_shaderManager->visualizeProgram);
+ QColor color = QColor::fromHsvF((rand() & 1023) / 1023.0, 0.3, 1.0);
+ float ca = 0.5;
+ float cr = color.redF() * ca;
+ float cg = color.greenF() * ca;
+ float cb = color.blueF() * ca;
+ shader->setUniformValue(shader->color, cr, cg, cb, ca);
+
+ QRect viewport = viewportRect();
+ shader->setUniformValue(shader->tweak, viewport.width(), viewport.height(), tinted ? 0.5 : 0, 0);
+
+ QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(n->sgNode);
+
+ QMatrix4x4 matrix = m_current_projection_matrix;
+ if (n->element()->batch->root)
+ matrix = matrix * qsg_matrixForRoot(n->element()->batch->root);
+ matrix = matrix * *gn->matrix();
+ shader->setUniformValue(shader->matrix, matrix);
+ visualizeDrawGeometry(gn->geometry());
+
+ // This is because many changes don't propegate their dirty state to the
+ // parent so the node updater will not unset these states. They are
+ // not used for anything so, unsetting it should have no side effects.
+ n->dirtyState = 0;
+ }
+
+ SHADOWNODE_TRAVERSE(n) {
+ visualizeChanges(*child);
+ }
+}
+
+void Renderer::visualizeOverdraw_helper(Node *node)
+{
+ if (node->type() == QSGNode::GeometryNodeType) {
+ VisualizeShader *shader = static_cast<VisualizeShader *>(m_shaderManager->visualizeProgram);
+ QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(node->sgNode);
+
+ QMatrix4x4 matrix = m_current_projection_matrix;
+ matrix(2, 2) = m_zRange;
+ matrix(2, 3) = 1.0f - node->element()->order * m_zRange;
+
+ if (node->element()->batch->root)
+ matrix = matrix * qsg_matrixForRoot(node->element()->batch->root);
+ matrix = matrix * *gn->matrix();
+ shader->setUniformValue(shader->matrix, matrix);
+
+ QColor color = node->element()->batch->isOpaque ? QColor::fromRgbF(0.3, 1.0, 0.3) : QColor::fromRgbF(1.0, 0.3, 0.3);
+ float ca = 0.33;
+ shader->setUniformValue(shader->color, color.redF() * ca, color.greenF() * ca, color.blueF() * ca, ca);
+
+ visualizeDrawGeometry(gn->geometry());
+ }
+
+ SHADOWNODE_TRAVERSE(node) {
+ visualizeOverdraw_helper(*child);
+ }
+}
+
+void Renderer::visualizeOverdraw()
+{
+ VisualizeShader *shader = static_cast<VisualizeShader *>(m_shaderManager->visualizeProgram);
+ shader->setUniformValue(shader->color, 0.5, 0.5, 1, 1);
+
+ QRect viewport = viewportRect();
+ shader->setUniformValue(shader->tweak, viewport.width(), viewport.height(), 0, 1);
+
+ glBlendFunc(GL_ONE, GL_ONE);
+
+ static float step = 0;
+ step += M_PI * 2 / 1000.;
+ if (step > M_PI * 2)
+ step = 0;
+ float angle = 80.0 * sin(step);
+
+ QMatrix4x4 xrot; xrot.rotate(20, 1, 0, 0);
+ QMatrix4x4 zrot; zrot.rotate(angle, 0, 0, 1);
+ QMatrix4x4 tx; tx.translate(0, 0, 1);
+
+ QMatrix4x4 m;
+
+// m.rotate(180, 0, 1, 0);
+
+ m.translate(0, 0.5, 4);
+ m.scale(2, 2, 1);
+
+ m.rotate(-30, 1, 0, 0);
+ m.rotate(angle, 0, 1, 0);
+ m.translate(0, 0, -1);
+
+ shader->setUniformValue(shader->rotation, m);
+
+ float box[] = {
+ // lower
+ -1, 1, 0, 1, 1, 0,
+ -1, 1, 0, -1, -1, 0,
+ 1, 1, 0, 1, -1, 0,
+ -1, -1, 0, 1, -1, 0,
+
+ // upper
+ -1, 1, 1, 1, 1, 1,
+ -1, 1, 1, -1, -1, 1,
+ 1, 1, 1, 1, -1, 1,
+ -1, -1, 1, 1, -1, 1,
+
+ // sides
+ -1, -1, 0, -1, -1, 1,
+ 1, -1, 0, 1, -1, 1,
+ -1, 1, 0, -1, 1, 1,
+ 1, 1, 0, 1, 1, 1
+ };
+ glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, box);
+ glLineWidth(2);
+ glDrawArrays(GL_LINES, 0, 24);
+
+ visualizeOverdraw_helper(m_nodes.value(rootNode()));
+
+ // Animate the view...
+ QSurface *surface = QOpenGLContext::currentContext()->surface();
+ if (surface->surfaceClass() == QSurface::Window)
+ if (QQuickWindow *window = qobject_cast<QQuickWindow *>(static_cast<QWindow *>(surface)))
+ window->update();
+}
+
+void Renderer::setCustomRenderMode(const QByteArray &mode)
+{
+ if (mode.isEmpty()) m_visualizeMode = VisualizeNothing;
+ else if (mode == "clip") m_visualizeMode = VisualizeClipping;
+ else if (mode == "overdraw") m_visualizeMode = VisualizeOverdraw;
+ else if (mode == "batches") m_visualizeMode = VisualizeBatches;
+ else if (mode == "changes") m_visualizeMode = VisualizeChanges;
+}
+
+void Renderer::visualize()
+{
+ if (!m_shaderManager->visualizeProgram) {
+ VisualizeShader *prog = new VisualizeShader();
+ QSGShaderSourceBuilder::initializeProgramFromFiles(
+ prog,
+ QStringLiteral(":/scenegraph/shaders/visualization.vert"),
+ QStringLiteral(":/scenegraph/shaders/visualization.frag"));
+ prog->bindAttributeLocation("v", 0);
+ prog->link();
+ prog->bind();
+ prog->color = prog->uniformLocation("color");
+ prog->tweak = prog->uniformLocation("tweak");
+ prog->matrix = prog->uniformLocation("matrix");
+ prog->rotation = prog->uniformLocation("rotation");
+ m_shaderManager->visualizeProgram = prog;
+ } else {
+ m_shaderManager->visualizeProgram->bind();
+ }
+ VisualizeShader *shader = static_cast<VisualizeShader *>(m_shaderManager->visualizeProgram);
+
+ glDisable(GL_DEPTH_TEST);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glEnableVertexAttribArray(0);
+
+ // Blacken out the actual rendered content...
+ float bgOpacity = 0.8;
+ if (m_visualizeMode == VisualizeBatches)
+ bgOpacity = 1.0;
+ float v[] = { -1, 1, 1, 1, -1, -1, 1, -1 };
+ shader->setUniformValue(shader->color, 0, 0, 0, bgOpacity);
+ shader->setUniformValue(shader->matrix, QMatrix4x4());
+ shader->setUniformValue(shader->rotation, QMatrix4x4());
+ shader->setUniformValue(shader->tweak, 0, 0, 0, 0);
+ glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, v);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ if (m_visualizeMode == VisualizeBatches) {
+ srand(0); // To force random colors to be roughly the same every time..
+ for (int i=0; i<m_opaqueBatches.size(); ++i) visualizeBatch(m_opaqueBatches.at(i));
+ for (int i=0; i<m_alphaBatches.size(); ++i) visualizeBatch(m_alphaBatches.at(i));
+ } else if (m_visualizeMode == VisualizeClipping) {
+ QRect viewport = viewportRect();
+ shader->setUniformValue(shader->tweak, viewport.width(), viewport.height(), 0.5, 0);
+ shader->setUniformValue(shader->color, 0.2, 0, 0, 0.2);
+ visualizeClipping(rootNode());
+ } else if (m_visualizeMode == VisualizeChanges) {
+ visualizeChanges(m_nodes.value(rootNode()));
+ m_visualizeChanceSet.clear();
+ } else if (m_visualizeMode == VisualizeOverdraw) {
+ visualizeOverdraw();
+ }
+
+ // Reset state back to defaults..
+ glDisable(GL_BLEND);
+ glDisableVertexAttribArray(0);
+ shader->release();
+}
+
QT_END_NAMESPACE
}
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 379c0ee00e..c38c483df4 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -371,7 +371,7 @@ public:
float lastOpacity;
};
- ShaderManager() : blitProgram(0) { }
+ ShaderManager() : blitProgram(0), visualizeProgram(0) { }
~ShaderManager() {
qDeleteAll(rewrittenShaders.values());
qDeleteAll(stockShaders.values());
@@ -388,6 +388,7 @@ public:
QHash<QSGMaterialType *, Shader *> stockShaders;
QOpenGLShaderProgram *blitProgram;
+ QOpenGLShaderProgram *visualizeProgram;
};
class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer
@@ -396,6 +397,14 @@ public:
Renderer(QSGRenderContext *);
~Renderer();
+ enum VisualizeMode {
+ VisualizeNothing,
+ VisualizeBatches,
+ VisualizeClipping,
+ VisualizeChanges,
+ VisualizeOverdraw
+ };
+
protected:
void nodeChanged(QSGNode *node, QSGNode::DirtyState state);
void preprocess() Q_DECL_OVERRIDE;
@@ -451,6 +460,16 @@ private:
inline Batch *newBatch();
void invalidateAndRecycleBatch(Batch *b);
+ void visualize();
+ void visualizeBatch(Batch *b);
+ void visualizeClipping(QSGNode *node);
+ void visualizeChangesPrepare(Node *n, uint parentChanges = 0);
+ void visualizeChanges(Node *n);
+ void visualizeOverdraw();
+ void visualizeOverdraw_helper(Node *node);
+ void visualizeDrawGeometry(const QSGGeometry *g);
+ void setCustomRenderMode(const QByteArray &mode);
+
QSet<Node *> m_taggedRoots;
QDataBuffer<Element *> m_opaqueRenderList;
QDataBuffer<Element *> m_alphaRenderList;
@@ -487,6 +506,9 @@ private:
// For minimal OpenGL core profile support
QOpenGLVertexArrayObject *m_vao;
+
+ QHash<Node *, uint> m_visualizeChanceSet;
+ VisualizeMode m_visualizeMode;
};
Batch *Renderer::newBatch()
diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp
index ffb11fc6fa..40e0a014ab 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry.cpp
+++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp
@@ -525,8 +525,9 @@ void QSGGeometry::setDrawingMode(GLenum mode)
}
/*!
- Gets the current line width to be used for this geometry. This property only
- applies where the drawingMode is GL_LINES or a related value.
+ Gets the current line or point width or to be used for this geometry. This property
+ only applies to line width when the drawingMode is \c GL_LINES, \c GL_LINE_STRIP, or
+ \c GL_LINE_LOOP, and only applies to point size when the drawingMode is \c GL_POINTS.
The default value is \c 1.0
@@ -538,8 +539,9 @@ float QSGGeometry::lineWidth() const
}
/*!
- Sets the line width to be used for this geometry to \a width. The line width
- only applies where the drawingMode is \c GL_LINES or a related value.
+ Sets the line or point width to be used for this geometry to \a width. This property
+ only applies to line width when the drawingMode is \c GL_LINES, \c GL_LINE_STRIP, or
+ \c GL_LINE_LOOP, and only applies to point size when the drawingMode is \c GL_POINTS.
\sa lineWidth(), drawingMode()
*/
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index e35bfe5494..047891e17c 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -287,14 +287,11 @@ void QSGRenderer::renderScene(const QSGBindable &bindable)
int(renderTime / 1000000));
}
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphRendererFrame,
- preprocessTime,
- updatePassTime - preprocessTime,
- bindTime - updatePassTime,
- renderTime - bindTime);
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphRendererFrame, (
+ preprocessTime,
+ updatePassTime - preprocessTime,
+ bindTime - updatePassTime,
+ renderTime - bindTime));
#endif
}
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
index 43811e6d5e..296d6e2cfd 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
@@ -132,6 +132,8 @@ public:
void setClearMode(ClearMode mode) { m_clear_mode = mode; }
ClearMode clearMode() const { return m_clear_mode; }
+ virtual void setCustomRenderMode(const QByteArray &) { };
+
Q_SIGNALS:
void sceneGraphChanged(); // Add, remove, ChangeFlags changes...
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index cb9e4bdf88..aa678b34a6 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -196,13 +196,10 @@ void QSGDistanceFieldGlyphCache::update()
(int) qsg_render_timer.elapsed());
}
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphAdaptationLayerFrame,
- count,
- renderTime,
- qsg_render_timer.nsecsElapsed() - renderTime);
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphAdaptationLayerFrame, (
+ count,
+ renderTime,
+ qsg_render_timer.nsecsElapsed() - renderTime));
#endif
}
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 5135cc629c..dd00f75fae 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -258,32 +258,14 @@ QSGImageNode *QSGContext::createImageNode()
}
/*!
- Factory function for scene graph backends of the Text elements which supports native
- text rendering. Used in special cases where native look and feel is a main objective.
-*/
-QSGGlyphNode *QSGContext::createNativeGlyphNode(QSGRenderContext *rc)
-{
-#if defined(QT_OPENGL_ES) && !defined(QT_OPENGL_ES_2_ANGLE)
- Q_D(QSGContext);
- if (d->distanceFieldDisabled)
- return new QSGDefaultGlyphNode;
- else
- return createGlyphNode(rc);
-#else
- Q_UNUSED(rc);
- return new QSGDefaultGlyphNode;
-#endif
-}
-
-/*!
Factory function for scene graph backends of the Text elements;
*/
-QSGGlyphNode *QSGContext::createGlyphNode(QSGRenderContext *rc)
+QSGGlyphNode *QSGContext::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode)
{
Q_D(QSGContext);
- if (d->distanceFieldDisabled) {
- return createNativeGlyphNode(rc);
+ if (d->distanceFieldDisabled || preferNativeGlyphNode) {
+ return new QSGDefaultGlyphNode;
} else {
QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(rc);
node->setPreferredAntialiasingMode(d->distanceFieldAntialiasing);
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index ef67dcceba..3b58cecd6a 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -162,8 +162,7 @@ public:
virtual QSGRectangleNode *createRectangleNode();
virtual QSGImageNode *createImageNode();
- virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc);
- virtual QSGGlyphNode *createNativeGlyphNode(QSGRenderContext *rc);
+ virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode);
virtual QAnimationDriver *createAnimationDriver(QObject *parent);
virtual QSize minimumFBOSize() const;
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index f0ac725f22..7b6e6d55ee 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -343,13 +343,10 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
lastFrameTime = QTime::currentTime();
}
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphRenderLoopFrame,
- syncTime,
- renderTime,
- swapTime);
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphRenderLoopFrame, (
+ syncTime,
+ renderTime,
+ swapTime));
// Might have been set during syncSceneGraph()
if (data.updatePending)
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 207a4915e1..7cc4293f6c 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -609,13 +609,10 @@ void QSGRenderThread::syncAndRender()
int((renderTime - syncTime)/1000000),
int(threadTimer.elapsed() - renderTime/1000000));
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphRenderLoopFrame,
- syncTime,
- renderTime - syncTime,
- threadTimer.nsecsElapsed() - renderTime);
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphRenderLoopFrame, (
+ syncTime,
+ renderTime - syncTime,
+ threadTimer.nsecsElapsed() - renderTime));
#endif
}
@@ -1143,14 +1140,11 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w)
int((syncTime - waitTime)/1000000),
int((timer.nsecsElapsed() - syncTime)/1000000));
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphPolishAndSync,
- polishTime,
- waitTime - polishTime,
- syncTime - waitTime,
- timer.nsecsElapsed() - syncTime);
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphPolishAndSync, (
+ polishTime,
+ waitTime - polishTime,
+ syncTime - waitTime,
+ timer.nsecsElapsed() - syncTime));
#endif
}
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index 6a6a6ab570..63e3e958f6 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -202,13 +202,10 @@ void QSGWindowsRenderLoop::show(QQuickWindow *window)
int((time_current - time_created)/1000000),
int((qsg_render_timer.nsecsElapsed() - time_current)/1000000));
}
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphWindowsRenderShow,
- time_created - time_start,
- time_current - time_created,
- qsg_render_timer.nsecsElapsed() - time_current);
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphWindowsRenderShow, (
+ time_created - time_start,
+ time_current - time_created,
+ qsg_render_timer.nsecsElapsed() - time_current));
#endif
}
@@ -407,11 +404,8 @@ void QSGWindowsRenderLoop::render()
qDebug("WindowsRenderLoop: animations=%d ms",
int((qsg_render_timer.nsecsElapsed() - time_start)/1000000));
}
- if (QQmlProfilerService::Enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphWindowsAnimations,
- qsg_render_timer.nsecsElapsed() - time_start);
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphWindowsAnimations, (
+ qsg_render_timer.nsecsElapsed() - time_start));
#endif
// It is not given that animations triggered another maybeUpdate()
@@ -473,19 +467,13 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window)
int((time_rendered - time_synced)/1000000),
int((time_swapped - time_rendered)/1000000));
}
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphWindowsPolishFrame,
- time_polished - time_start
- );
-
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphRenderLoopFrame,
- time_synced - time_polished,
- time_rendered - time_synced,
- time_swapped - time_rendered
- );
- }
+
+ Q_QML_SG_PROFILE2(QQmlProfilerService::SceneGraphWindowsPolishFrame,
+ QQmlProfilerService::SceneGraphRenderLoopFrame, (
+ time_synced - time_polished,
+ time_rendered - time_synced,
+ time_swapped - time_rendered,
+ time_polished - time_start));
#endif
}
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index 6868e10b90..570d6b92b5 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -160,5 +160,7 @@ OTHER_FILES += \
$$PWD/shaders/textmask_core.vert \
$$PWD/shaders/texture_core.frag \
$$PWD/shaders/vertexcolor_core.frag \
- $$PWD/shaders/vertexcolor_core.vert
+ $$PWD/shaders/vertexcolor_core.vert \
+ scenegraph/shaders/visualization.frag \
+ scenegraph/shaders/visualization.vert
diff --git a/src/quick/scenegraph/scenegraph.qrc b/src/quick/scenegraph/scenegraph.qrc
index 2be8b246d3..e6a90c9120 100644
--- a/src/quick/scenegraph/scenegraph.qrc
+++ b/src/quick/scenegraph/scenegraph.qrc
@@ -64,5 +64,7 @@
<file>shaders/texture_core.frag</file>
<file>shaders/vertexcolor_core.frag</file>
<file>shaders/vertexcolor_core.vert</file>
+ <file>shaders/visualization.vert</file>
+ <file>shaders/visualization.frag</file>
</qresource>
</RCC>
diff --git a/src/quick/scenegraph/shaders/visualization.frag b/src/quick/scenegraph/shaders/visualization.frag
new file mode 100644
index 0000000000..205b726c03
--- /dev/null
+++ b/src/quick/scenegraph/shaders/visualization.frag
@@ -0,0 +1,11 @@
+uniform lowp vec4 color;
+uniform mediump vec4 tweak; // x,y -> width, height; z -> intensity of ;
+
+varying mediump vec2 pos;
+
+void main(void)
+{
+ lowp vec4 c = color;
+ c.xyz += pow(max(sin(pos.x + pos.y), 0.0), 2.0) * tweak.z * 0.1;
+ gl_FragColor = c;
+}
diff --git a/src/quick/scenegraph/shaders/visualization.vert b/src/quick/scenegraph/shaders/visualization.vert
new file mode 100644
index 0000000000..f1892b71da
--- /dev/null
+++ b/src/quick/scenegraph/shaders/visualization.vert
@@ -0,0 +1,22 @@
+attribute highp vec4 v;
+uniform highp mat4 matrix;
+uniform highp mat4 rotation;
+
+// w -> apply 3d rotation and projection
+uniform lowp vec4 tweak;
+
+varying mediump vec2 pos;
+
+void main()
+{
+ vec4 p = matrix * v;
+
+ if (tweak.w > 0.0) {
+ vec4 proj = rotation * p;
+ gl_Position = vec4(proj.x, proj.y, 0, proj.z);
+ } else {
+ gl_Position = p;
+ }
+
+ pos = v.xy * 1.37;
+}
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index 378451c307..e6a2096c80 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -148,9 +148,10 @@ Atlas::Atlas(const QSize &size)
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK)
QString *deviceName =
static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName"));
- static bool wrongfullyReportsBgra8888Support = deviceName->compare(QStringLiteral("samsung SM-T211"), Qt::CaseInsensitive) == 0
- || deviceName->compare(QStringLiteral("samsung SM-T210"), Qt::CaseInsensitive) == 0
- || deviceName->compare(QStringLiteral("samsung SM-T215"), Qt::CaseInsensitive) == 0;
+ static bool wrongfullyReportsBgra8888Support = deviceName != 0
+ && (deviceName->compare(QStringLiteral("samsung SM-T211"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QStringLiteral("samsung SM-T210"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QStringLiteral("samsung SM-T215"), Qt::CaseInsensitive) == 0);
#else
static bool wrongfullyReportsBgra8888Support = false;
#endif
@@ -393,15 +394,12 @@ bool Atlas::bind(QSGTexture::Filtering filtering)
(int) (qsg_renderer_timer.elapsed()));
}
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphTexturePrepare,
- 0, // bind (not relevant)
- 0, // convert (not relevant)
- 0, // swizzle (not relevant)
- qsg_renderer_timer.nsecsElapsed(), // (upload all of the above)
- 0); // mipmap (not used ever...)
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphTexturePrepare, (
+ 0, // bind (not relevant)
+ 0, // convert (not relevant)
+ 0, // swizzle (not relevant)
+ qsg_renderer_timer.nsecsElapsed(), // (upload all of the above)
+ 0)); // mipmap (not used ever...)
#endif
}
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index bfa0eaf920..b738896a6c 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -636,11 +636,8 @@ void QSGPlainTexture::bind()
m_texture_size.width(),
m_texture_size.height());
}
- if (QQmlProfilerService::enabled) {
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphTextureDeletion,
- qsg_renderer_timer.nsecsElapsed());
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphTextureDeletion, (
+ qsg_renderer_timer.nsecsElapsed()));
#endif
}
m_texture_id = 0;
@@ -687,9 +684,10 @@ void QSGPlainTexture::bind()
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK)
QString *deviceName =
static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName"));
- static bool wrongfullyReportsBgra8888Support = deviceName->compare(QStringLiteral("samsung SM-T211"), Qt::CaseInsensitive) == 0
- || deviceName->compare(QStringLiteral("samsung SM-T210"), Qt::CaseInsensitive) == 0
- || deviceName->compare(QStringLiteral("samsung SM-T215"), Qt::CaseInsensitive) == 0;
+ static bool wrongfullyReportsBgra8888Support = deviceName != 0
+ && (deviceName->compare(QStringLiteral("samsung SM-T211"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QStringLiteral("samsung SM-T210"), Qt::CaseInsensitive) == 0
+ || deviceName->compare(QStringLiteral("samsung SM-T215"), Qt::CaseInsensitive) == 0);
#else
static bool wrongfullyReportsBgra8888Support = false;
#endif
@@ -751,17 +749,12 @@ void QSGPlainTexture::bind()
}
- if (QQmlProfilerService::enabled) {
- mipmapTime = qsg_renderer_timer.nsecsElapsed();
-
- QQmlProfilerService::sceneGraphFrame(
- QQmlProfilerService::SceneGraphTexturePrepare,
- bindTime,
- convertTime - bindTime,
- swizzleTime - convertTime,
- uploadTime - swizzleTime,
- mipmapTime - uploadTime);
- }
+ Q_QML_SG_PROFILE1(QQmlProfilerService::SceneGraphTexturePrepare, (
+ bindTime,
+ convertTime - bindTime,
+ swizzleTime - convertTime,
+ uploadTime - swizzleTime,
+ qsg_renderer_timer.nsecsElapsed() - uploadTime));
#endif
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index fa6f615649..3bc4cef5b9 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -271,7 +271,7 @@ void QQuickTransformAnimatorJob::initialize(QQuickAnimatorController *controller
m_helper = new Helper();
m_helper->item = m_target;
m_controller->m_transforms.insert(m_target, m_helper);
- QObject::connect(m_target, SIGNAL(destroyed(QObject *)), m_controller, SLOT(itemDestroyed(QObject*)), Qt::DirectConnection);
+ QObject::connect(m_target, SIGNAL(destroyed(QObject*)), m_controller, SLOT(itemDestroyed(QObject*)), Qt::DirectConnection);
} else {
++m_helper->ref;
// Make sure leftovers from previous runs are being used...
diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp
index 460e2ca554..407b80915d 100644
--- a/src/quick/util/qquickbehavior.cpp
+++ b/src/quick/util/qquickbehavior.cpp
@@ -185,7 +185,8 @@ void QQuickBehavior::write(const QVariant &value)
return;
}
- if (d->animation->isRunning() && value == d->targetValue)
+ bool behaviorActive = d->animation->isRunning();
+ if (behaviorActive && value == d->targetValue)
return;
d->targetValue = value;
@@ -201,6 +202,14 @@ void QQuickBehavior::write(const QVariant &value)
// to the item, so we need to read the value after.
const QVariant &currentValue = d->property.read();
+ // Don't unnecessarily wake up the animation system if no real animation
+ // is needed (value has not changed). If the Behavior was already
+ // running, let it continue as normal to ensure correct behavior and state.
+ if (!behaviorActive && d->targetValue == currentValue) {
+ QQmlPropertyPrivate::write(d->property, value, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
+ return;
+ }
+
QQuickStateOperation::ActionList actions;
QQuickStateAction action;
action.property = d->property;
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 152d1f34c9..5ae74c2fec 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -398,7 +398,7 @@ public:
if (!array)
return QMatrix4x4();
- if (array->arrayLength() != 16)
+ if (array->getLength() != 16)
return QMatrix4x4();
float matVals[16];
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index 450238bd41..16c18d2594 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -147,8 +147,8 @@ QImage QQuickTextureFactory::image() const
Image { source: "image://myimageprovider/image.png" }
\endqml
- This specifies that the image should be loaded by the image provider named
- "myimageprovider", and the image to be loaded is named "image.png". The QML engine
+ This specifies that the image should be loaded by the image provider named
+ "myimageprovider", and the image to be loaded is named "image.png". The QML engine
invokes the appropriate image provider according to the providers that have
been registered through QQmlEngine::addImageProvider().
@@ -173,11 +173,11 @@ QImage QQuickTextureFactory::image() const
When these images are loaded by QML, it looks for a matching image provider
and calls its requestImage() or requestPixmap() method (depending on its
- imageType()) to load the image. The method is called with the \c id
+ imageType()) to load the image. The method is called with the \c id
parameter set to "yellow" for the first image, and "red" for the second.
- Here is an image provider implementation that can load the images
- requested by the above QML. This implementation dynamically
+ Here is an image provider implementation that can load the images
+ requested by the above QML. This implementation dynamically
generates QPixmap images that are filled with the requested color:
\snippet imageprovider/imageprovider.cpp 0
@@ -188,7 +188,7 @@ QImage QQuickTextureFactory::image() const
with a "colors" identifier:
\code
- int main(int argc, char *argv[])
+ int main(int argc, char *argv[])
{
...
@@ -203,7 +203,7 @@ QImage QQuickTextureFactory::image() const
\image imageprovider.png
- A complete example is available in Qt's
+ A complete example is available in Qt's
\l {qml/imageprovider}{examples/quick/imageprovider}
directory. Note the example registers the provider via a \l{QQmlExtensionPlugin}{plugin}
instead of registering it in the application \c main() function as shown above.
@@ -214,7 +214,7 @@ QImage QQuickTextureFactory::image() const
Image providers that support QImage or Texture loading automatically include support
for asychronous loading of images. To enable asynchronous loading for an
image source, set the \c asynchronous property to \c true for the relevant
- \l Image, \l BorderImage or \l AnimatedImage object. When this is enabled,
+ \l Image, \l BorderImage or \l AnimatedImage object. When this is enabled,
the image request to the provider is run in a low priority thread,
allowing image loading to be executed in the background, and reducing the
performance impact on the user interface.
@@ -285,7 +285,7 @@ QQuickImageProvider::Flags QQuickImageProvider::flags() const
}
/*!
- Implement this method to return the image with \a id. The default
+ Implement this method to return the image with \a id. The default
implementation returns an empty image.
The \a id is the requested image source, with the "image:" scheme and
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 055d6b7e29..3bff2bb890 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -234,7 +234,7 @@ class QQuickPixmapData
{
public:
QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, const QString &e)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Error),
+ : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Error),
url(u), errorString(e), requestSize(s), textureFactory(0), reply(0), prevUnreferenced(0),
prevUnreferencedPtr(0), nextUnreferenced(0)
{
@@ -242,7 +242,7 @@ public:
}
QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r)
- : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Loading),
+ : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Loading),
url(u), requestSize(r), textureFactory(0), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0),
nextUnreferenced(0)
{
@@ -286,7 +286,7 @@ public:
uint refCount;
bool inCache:1;
-
+
QQuickPixmap::Status pixmapStatus;
QUrl url;
QString errorString;
@@ -337,7 +337,7 @@ QNetworkAccessManager *QQuickPixmapReader::networkAccessManager()
return accessManager;
}
-static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize,
+static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize,
const QSize &requestSize)
{
QImageReader imgio(dev);
@@ -469,17 +469,17 @@ QQuickPixmapReaderThreadObject::QQuickPixmapReaderThreadObject(QQuickPixmapReade
{
}
-void QQuickPixmapReaderThreadObject::processJobs()
-{
- QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+void QQuickPixmapReaderThreadObject::processJobs()
+{
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
}
-bool QQuickPixmapReaderThreadObject::event(QEvent *e)
+bool QQuickPixmapReaderThreadObject::event(QEvent *e)
{
- if (e->type() == QEvent::User) {
- reader->processJobs();
- return true;
- } else {
+ if (e->type() == QEvent::User) {
+ reader->processJobs();
+ return true;
+ } else {
return QObject::event(e);
}
}
@@ -495,7 +495,7 @@ void QQuickPixmapReader::processJobs()
QMutexLocker locker(&mutex);
while (true) {
- if (cancelled.isEmpty() && (jobs.isEmpty() || replies.count() >= IMAGEREQUEST_MAX_REQUEST_COUNT))
+ if (cancelled.isEmpty() && (jobs.isEmpty() || replies.count() >= IMAGEREQUEST_MAX_REQUEST_COUNT))
return; // Nothing else to do
// Clean cancelled jobs
@@ -519,8 +519,7 @@ void QQuickPixmapReader::processJobs()
runningJob->loading = true;
QUrl url = runningJob->url;
- QQmlPixmapProfiler pixmapProfiler;
- pixmapProfiler.startLoading(url);
+ Q_QML_PROFILE(pixmapStateChanged<QQmlProfilerService::PixmapLoadingStarted>(url));
QSize requestSize = runningJob->requestSize;
locker.unlock();
@@ -530,7 +529,7 @@ void QQuickPixmapReader::processJobs()
}
}
-void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url,
+void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url,
const QSize &requestSize)
{
// fetch
@@ -650,7 +649,7 @@ QQuickPixmapReply *QQuickPixmapReader::getImage(QQuickPixmapData *data)
QQuickPixmapReply *reply = new QQuickPixmapReply(data);
reply->engineForReader = engine;
jobs.append(reply);
- // XXX
+ // XXX
if (threadObject) threadObject->processJobs();
mutex.unlock();
return reply;
@@ -662,7 +661,7 @@ void QQuickPixmapReader::cancel(QQuickPixmapReply *reply)
if (reply->loading) {
cancelled.append(reply);
reply->data = 0;
- // XXX
+ // XXX
if (threadObject) threadObject->processJobs();
} else {
jobs.removeAll(reply);
@@ -817,7 +816,7 @@ void QQuickPixmapStore::referencePixmap(QQuickPixmapData *data)
Q_ASSERT(data->prevUnreferencedPtr);
*data->prevUnreferencedPtr = data->nextUnreferenced;
- if (data->nextUnreferenced) {
+ if (data->nextUnreferenced) {
data->nextUnreferenced->prevUnreferencedPtr = data->prevUnreferencedPtr;
data->nextUnreferenced->prevUnreferenced = data->prevUnreferenced;
}
@@ -895,14 +894,13 @@ bool QQuickPixmapReply::event(QEvent *event)
if (data) {
Event *de = static_cast<Event *>(event);
data->pixmapStatus = (de->error == NoError) ? QQuickPixmap::Ready : QQuickPixmap::Error;
- QQmlPixmapProfiler pixmapProfiler;
if (data->pixmapStatus == QQuickPixmap::Ready) {
- pixmapProfiler.finishLoading(data->url);
data->textureFactory = de->textureFactory;
data->implicitSize = de->implicitSize;
- pixmapProfiler.setSize(url, data->requestSize.width() > 0 ? data->requestSize : data->implicitSize);
+ Q_QML_PROFILE(pixmapLoadingFinished(data->url,
+ data->requestSize.width() > 0 ? data->requestSize : data->implicitSize));
} else {
- pixmapProfiler.errorLoading(data->url);
+ Q_QML_PROFILE(pixmapStateChanged<QQmlProfilerService::PixmapLoadingError>(data->url));
data->errorString = de->errorString;
data->removeFromCache(); // We don't continue to cache error'd pixmaps
}
@@ -928,8 +926,8 @@ int QQuickPixmapData::cost() const
void QQuickPixmapData::addref()
{
++refCount;
- QQmlPixmapProfiler().referenceCountChanged(url, refCount);
- if (prevUnreferencedPtr)
+ Q_QML_PROFILE(pixmapCountChanged<QQmlProfilerService::PixmapReferenceCountChanged>(url, refCount));
+ if (prevUnreferencedPtr)
pixmapStore()->referencePixmap(this);
}
@@ -937,7 +935,7 @@ void QQuickPixmapData::release()
{
Q_ASSERT(refCount > 0);
--refCount;
- QQmlPixmapProfiler().referenceCountChanged(url, refCount);
+ Q_QML_PROFILE(pixmapCountChanged<QQmlProfilerService::PixmapReferenceCountChanged>(url, refCount));
if (refCount == 0) {
if (reply) {
QQuickPixmapReply *cancelReply = reply;
@@ -968,8 +966,8 @@ void QQuickPixmapData::addToCache()
QQuickPixmapKey key = { &url, &requestSize };
pixmapStore()->m_cache.insert(key, this);
inCache = true;
- QQmlPixmapProfiler pixmapProfiler;
- pixmapProfiler.cacheCountChanged(url, pixmapStore()->m_cache.count());
+ Q_QML_PROFILE(pixmapCountChanged<QQmlProfilerService::PixmapCacheCountChanged>(
+ url, pixmapStore()->m_cache.count()));
}
}
@@ -977,7 +975,8 @@ void QQuickPixmapData::removeFromCache()
{
if (inCache) {
QQuickPixmapKey key = { &url, &requestSize };
- QQmlPixmapProfiler().cacheCountChanged(url, pixmapStore()->m_cache.count());
+ Q_QML_PROFILE(pixmapCountChanged<QQmlProfilerService::PixmapCacheCountChanged>(
+ url, pixmapStore()->m_cache.count()));
pixmapStore()->m_cache.remove(key);
inCache = false;
}
@@ -1030,7 +1029,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
}
QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
- if (localFile.isEmpty())
+ if (localFile.isEmpty())
return 0;
QFile f(localFile);
@@ -1131,7 +1130,7 @@ const QUrl &QQuickPixmap::url() const
const QSize &QQuickPixmap::implicitSize() const
{
- if (d)
+ if (d)
return d->implicitSize;
else
return nullPixmap()->size;
@@ -1240,21 +1239,20 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
if (!(options & QQuickPixmap::Asynchronous)) {
bool ok = false;
- QQmlPixmapProfiler pixmapProfiler;
- pixmapProfiler.startLoading(url);
+ Q_QML_PROFILE(pixmapStateChanged<QQmlProfilerService::PixmapLoadingStarted>(url));
d = createPixmapDataSync(this, engine, url, requestSize, &ok);
if (ok) {
- pixmapProfiler.finishLoading(url);
- pixmapProfiler.setSize(url, d->requestSize.width() > 0 ? d->requestSize : d->implicitSize);
+ Q_QML_PROFILE(pixmapLoadingFinished(url,
+ d->requestSize.width() > 0 ? d->requestSize : d->implicitSize));
if (options & QQuickPixmap::Cache)
d->addToCache();
return;
}
if (d) { // loadable, but encountered error while loading
- pixmapProfiler.errorLoading(url);
+ Q_QML_PROFILE(pixmapStateChanged<QQmlProfilerService::PixmapLoadingError>(url));
return;
}
- }
+ }
if (!engine)
return;
@@ -1285,7 +1283,7 @@ void QQuickPixmap::clear()
void QQuickPixmap::clear(QObject *obj)
{
if (d) {
- if (d->reply)
+ if (d->reply)
QObject::disconnect(d->reply, 0, obj, 0);
d->declarativePixmaps.remove(this);
d->release();
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index 9eb6ec70c3..7bb318fd79 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -264,6 +264,29 @@ QQuickPropertyChangesParser::compileList(QList<QPair<QString, QVariant> > &list,
}
}
+void QQuickPropertyChangesParser::compileList(QList<QPair<QString, const QV4::CompiledData::Binding*> > &list, const QString &pre, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding)
+{
+ QString propName = pre + qmlUnit->header.stringAt(binding->propertyNameIndex);
+
+ if (binding->type == QV4::CompiledData::Binding::Type_Object) {
+ error(qmlUnit->objectAt(binding->value.objectIndex), QQuickPropertyChanges::tr("PropertyChanges does not support creating state-specific objects."));
+ return;
+ }
+
+ if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty
+ || binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
+ QString pre = propName + QLatin1Char('.');
+ const QV4::CompiledData::Object *subObj = qmlUnit->objectAt(binding->value.objectIndex);
+ const QV4::CompiledData::Binding *subBinding = subObj->bindingTable();
+ for (quint32 i = 0; i < subObj->nBindings; ++i, ++subBinding) {
+ compileList(list, pre, qmlUnit, subBinding);
+ }
+ return;
+ }
+
+ list << qMakePair(propName, binding);
+}
+
QByteArray
QQuickPropertyChangesParser::compile(const QList<QQmlCustomParserProperty> &props)
{
@@ -308,6 +331,44 @@ QQuickPropertyChangesParser::compile(const QList<QQmlCustomParserProperty> &prop
return rv;
}
+QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props)
+{
+ QList<QPair<QString, const QV4::CompiledData::Binding *> > data;
+ for (int ii = 0; ii < props.count(); ++ii)
+ compileList(data, QString(), qmlUnit, props.at(ii));
+
+ QByteArray rv;
+ QDataStream ds(&rv, QIODevice::WriteOnly);
+
+ ds << data.count();
+ for (int ii = 0; ii < data.count(); ++ii) {
+ const QV4::CompiledData::Binding *binding = data.at(ii).second;
+ QVariant var;
+ bool isScript = binding->type == QV4::CompiledData::Binding::Type_Script;
+ QQmlBinding::Identifier id = QQmlBinding::Invalid;
+ switch (binding->type) {
+ case QV4::CompiledData::Binding::Type_Script:
+ // ### pre-compile binding
+ case QV4::CompiledData::Binding::Type_String:
+ var = binding->valueAsString(&qmlUnit->header);
+ break;
+ case QV4::CompiledData::Binding::Type_Number:
+ var = binding->valueAsNumber();
+ break;
+ case QV4::CompiledData::Binding::Type_Boolean:
+ var = binding->valueAsBoolean();
+ break;
+ default:
+ break;
+ }
+ ds << data.at(ii).first << isScript << var;
+ if (isScript)
+ ds << id;
+ }
+
+ return rv;
+}
+
void QQuickPropertyChangesPrivate::decode()
{
Q_Q(QQuickPropertyChanges);
diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h
index 0236e4529b..081ea72862 100644
--- a/src/quick/util/qquickpropertychanges_p.h
+++ b/src/quick/util/qquickpropertychanges_p.h
@@ -93,8 +93,10 @@ public:
: QQmlCustomParser(AcceptsAttachedProperties) {}
void compileList(QList<QPair<QString, QVariant> > &list, const QString &pre, const QQmlCustomParserProperty &prop);
+ void compileList(QList<QPair<QString, const QV4::CompiledData::Binding *> > &list, const QString &pre, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding);
virtual QByteArray compile(const QList<QQmlCustomParserProperty> &);
+ virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props);
virtual void setCustomData(QObject *, const QByteArray &);
};
diff --git a/src/quick/util/qquickstate_p_p.h b/src/quick/util/qquickstate_p_p.h
index c559c8163c..82e456ed65 100644
--- a/src/quick/util/qquickstate_p_p.h
+++ b/src/quick/util/qquickstate_p_p.h
@@ -215,7 +215,7 @@ public:
struct OperationGuard : public QQmlGuard<QQuickStateOperation>
{
- OperationGuard(QObject *obj, QList<OperationGuard> *l) : list(l) {
+ OperationGuard(QObject *obj, QList<OperationGuard> *l) : list(l) {
setObject(static_cast<QQuickStateOperation *>(obj));
}
QList<OperationGuard> *list;
diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp
index d8cf9bd877..5305537d24 100644
--- a/src/quick/util/qquicktimeline.cpp
+++ b/src/quick/util/qquicktimeline.cpp
@@ -81,7 +81,7 @@ struct QQuickTimeLinePrivate
Execute
};
Op() {}
- Op(Type t, int l, qreal v, qreal v2, int o,
+ Op(Type t, int l, qreal v, qreal v2, int o,
const QQuickTimeLineCallback &ev = QQuickTimeLineCallback(), const QEasingCurve &es = QEasingCurve())
: type(t), length(l), value(v), value2(v2), order(o), event(ev),
easing(es) {}
@@ -89,8 +89,8 @@ struct QQuickTimeLinePrivate
: type(o.type), length(o.length), value(o.value), value2(o.value2),
order(o.order), event(o.event), easing(o.easing) {}
Op &operator=(const Op &o) {
- type = o.type; length = o.length; value = o.value;
- value2 = o.value2; order = o.order; event = o.event;
+ type = o.type; length = o.length; value = o.value;
+ value2 = o.value2; order = o.order; event = o.event;
easing = o.easing;
return *this;
}
@@ -604,8 +604,8 @@ void QQuickTimeLine::sync(QQuickTimeLineValue &timeLineValue)
d->syncPoint = d->length;
}*/
-/*!
- \internal
+/*!
+ \internal
Temporary hack.
*/
@@ -614,9 +614,9 @@ void QQuickTimeLine::setSyncPoint(int sp)
d->syncPoint = sp;
}
-/*!
- \internal
-
+/*!
+ \internal
+
Temporary hack.
*/
int QQuickTimeLine::syncPoint() const
@@ -739,7 +739,7 @@ int QQuickTimeLinePrivate::advance(int t)
TimeLine &tl = *iter;
Op &op = tl.ops.first();
int length = op.length - tl.consumedOpLength;
-
+
if (length < advanceTime) {
advanceTime = length;
if (advanceTime == 0)
@@ -748,7 +748,7 @@ int QQuickTimeLinePrivate::advance(int t)
}
t -= advanceTime;
- // Process until then. A zero length advance time will only process
+ // Process until then. A zero length advance time will only process
// sets.
QList<QPair<int, Update> > updates;
@@ -762,8 +762,8 @@ int QQuickTimeLinePrivate::advance(int t)
if (advanceTime == 0 && op.length != 0)
continue;
- if (tl.consumedOpLength == 0 &&
- op.type != Op::Pause &&
+ if (tl.consumedOpLength == 0 &&
+ op.type != Op::Pause &&
op.type != Op::Execute)
tl.base = v->value();
diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp
index 769dadc4fc..2821d7628c 100644
--- a/src/quick/util/qquicktransitionmanager.cpp
+++ b/src/quick/util/qquicktransitionmanager.cpp
@@ -89,7 +89,7 @@ bool QQuickTransitionManager::isRunning() const
return d->transitionInstance && d->transitionInstance->isRunning();
}
-void QQuickTransitionManager::complete()
+void QQuickTransitionManager::complete()
{
d->applyBindings();
@@ -100,7 +100,7 @@ void QQuickTransitionManager::complete()
d->completeList.clear();
- if (d->state)
+ if (d->state)
static_cast<QQuickStatePrivate*>(QObjectPrivate::get(d->state))->complete();
finished();
@@ -228,8 +228,8 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
} else {
if (touched.contains(action.property)) {
- if (action.toValue != action.fromValue)
- d->completeList <<
+ if (action.toValue != action.fromValue)
+ d->completeList <<
QQuickSimpleAction(action, QQuickSimpleAction::EndState);
applyList.removeAt(ii);
@@ -242,7 +242,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
// Any actions remaining have not been handled by the transition and should
// be applied immediately. We skip applying bindings, as they are all
- // applied at the end in applyBindings() to avoid any nastiness mid
+ // applied at the end in applyBindings() to avoid any nastiness mid
// transition
foreach(const QQuickStateAction &action, applyList) {
if (action.event && !action.event->changesBindings()) {
@@ -261,7 +261,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
qWarning() << " No transition for event:" << action.event->type();
else
qWarning() << " No transition for:" << action.property.object()
- << action.property.name() << "From:" << action.fromValue
+ << action.property.name() << "From:" << action.fromValue
<< "To:" << action.toValue;
}
}
diff --git a/src/quick/util/qquicktransitionmanager_p_p.h b/src/quick/util/qquicktransitionmanager_p_p.h
index 6211b5488c..bf203feaf4 100644
--- a/src/quick/util/qquicktransitionmanager_p_p.h
+++ b/src/quick/util/qquicktransitionmanager_p_p.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class QQuickStatePrivate;
class QQuickTransitionManagerPrivate;
-class Q_AUTOTEST_EXPORT QQuickTransitionManager
+class Q_AUTOTEST_EXPORT QQuickTransitionManager
{
public:
QQuickTransitionManager();