aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp81
-rw-r--r--src/qml/animations/qabstractanimationjob_p.h11
-rw-r--r--src/qml/animations/qanimationgroupjob.cpp18
-rw-r--r--src/qml/animations/qanimationgroupjob_p.h6
-rw-r--r--src/qml/animations/qcontinuinganimationgroupjob.cpp1
-rw-r--r--src/qml/animations/qparallelanimationgroupjob_p.h4
-rw-r--r--src/qml/animations/qpauseanimationjob.cpp3
-rw-r--r--src/qml/animations/qpauseanimationjob_p.h2
-rw-r--r--src/qml/animations/qsequentialanimationgroupjob.cpp10
-rw-r--r--src/qml/animations/qsequentialanimationgroupjob_p.h12
-rw-r--r--src/qml/compiler/compiler.pri13
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp109
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h56
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator.cpp56
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator_p.h97
-rw-r--r--src/qml/compiler/qqmlpropertyvalidator.cpp34
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp62
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h12
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp32
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h2
-rw-r--r--src/qml/compiler/qv4codegen.cpp102
-rw-r--r--src/qml/compiler/qv4codegen_p.h72
-rw-r--r--src/qml/compiler/qv4compileddata.cpp55
-rw-r--r--src/qml/compiler/qv4compileddata_p.h28
-rw-r--r--src/qml/compiler/qv4compiler.cpp4
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h18
-rw-r--r--src/qml/compiler/qv4compilercontrolflow_p.h12
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp22
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h4
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp10
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h40
-rw-r--r--src/qml/configure.json9
-rw-r--r--src/qml/debugger/qqmlabstractprofileradapter_p.h6
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p.h2
-rw-r--r--src/qml/debugger/qqmldebugconnector.cpp10
-rw-r--r--src/qml/debugger/qqmldebugconnector_p.h4
-rw-r--r--src/qml/debugger/qqmldebugserverconnection_p.h2
-rw-r--r--src/qml/debugger/qqmldebugservice_p.h4
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h47
-rw-r--r--src/qml/debugger/qqmlprofilerdefinitions_p.h21
-rw-r--r--src/qml/doc/qtqml.qdocconf2
-rw-r--r--src/qml/doc/snippets/code/src_script_qjsengine.cpp20
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc2
-rw-r--r--src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc12
-rw-r--r--src/qml/doc/src/cppintegration/topic.qdoc2
-rw-r--r--src/qml/doc/src/cppintegration/warning.qdocinc6
-rw-r--r--src/qml/doc/src/includes/qqmlcomponent.qdoc58
-rw-r--r--src/qml/doc/src/javascript/dynamicobjectcreation.qdoc2
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc27
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/basics.qdoc2
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc39
-rw-r--r--src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc2
-rw-r--r--src/qml/doc/src/qtqml.qdoc5
-rw-r--r--src/qml/jit/qv4assembler.cpp341
-rw-r--r--src/qml/jit/qv4assembler_p.h1
-rw-r--r--src/qml/jit/qv4jit.cpp64
-rw-r--r--src/qml/jit/qv4jit_p.h230
-rw-r--r--src/qml/jsapi/qjsengine.cpp83
-rw-r--r--src/qml/jsapi/qjsengine.h9
-rw-r--r--src/qml/jsapi/qjsengine_p.h4
-rw-r--r--src/qml/jsapi/qjsvalue.cpp106
-rw-r--r--src/qml/jsapi/qjsvalue_p.h8
-rw-r--r--src/qml/jsruntime/jsruntime.pri13
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp4
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h4
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp45
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h9
-rw-r--r--src/qml/jsruntime/qv4context.cpp2
-rw-r--r--src/qml/jsruntime/qv4context_p.h10
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp6
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4debugging_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp84
-rw-r--r--src/qml/jsruntime/qv4engine_p.h25
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h3
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4executableallocator.cpp6
-rw-r--r--src/qml/jsruntime/qv4executableallocator_p.h18
-rw-r--r--src/qml/jsruntime/qv4function_p.h2
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp27
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h47
-rw-r--r--src/qml/jsruntime/qv4global_p.h8
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4identifier.cpp26
-rw-r--r--src/qml/jsruntime/qv4identifier_p.h104
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp4
-rw-r--r--src/qml/jsruntime/qv4include.cpp30
-rw-r--r--src/qml/jsruntime/qv4include_p.h2
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp19
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h8
-rw-r--r--src/qml/jsruntime/qv4jscall_p.h4
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp20
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4managed.cpp8
-rw-r--r--src/qml/jsruntime/qv4managed_p.h2
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4memberdata_p.h6
-rw-r--r--src/qml/jsruntime/qv4object.cpp76
-rw-r--r--src/qml/jsruntime/qv4object_p.h32
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp8
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h4
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp6
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp50
-rw-r--r--src/qml/jsruntime/qv4persistent_p.h24
-rw-r--r--src/qml/jsruntime/qv4profiling.cpp3
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h40
-rw-r--r--src/qml/jsruntime/qv4property_p.h4
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp22
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp131
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h8
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp10
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp42
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp53
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtimecodegen.cpp7
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h6
-rw-r--r--src/qml/jsruntime/qv4script.cpp49
-rw-r--r--src/qml/jsruntime/qv4script_p.h11
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp45
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4sparsearray.cpp42
-rw-r--r--src/qml/jsruntime/qv4sparsearray_p.h8
-rw-r--r--src/qml/jsruntime/qv4string.cpp106
-rw-r--r--src/qml/jsruntime/qv4string_p.h88
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp25
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp10
-rw-r--r--src/qml/jsruntime/qv4value_p.h101
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp18
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h8
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp40
-rw-r--r--src/qml/jsruntime/qv4vme_moth_p.h2
-rw-r--r--src/qml/memory/qv4heap_p.h44
-rw-r--r--src/qml/memory/qv4mm.cpp242
-rw-r--r--src/qml/memory/qv4mm_p.h55
-rw-r--r--src/qml/memory/qv4mmdefs_p.h9
-rw-r--r--src/qml/memory/qv4writebarrier_p.h131
-rw-r--r--src/qml/parser/qqmljsast.cpp8
-rw-r--r--src/qml/parser/qqmljsast_p.h65
-rw-r--r--src/qml/parser/qqmljsengine_p.cpp2
-rw-r--r--src/qml/parser/qqmljsengine_p.h5
-rw-r--r--src/qml/parser/qqmljsgrammar.cpp6
-rw-r--r--src/qml/parser/qqmljslexer.cpp18
-rw-r--r--src/qml/parser/qqmljsmemorypool_p.h22
-rw-r--r--src/qml/parser/qqmljsparser.cpp70
-rw-r--r--src/qml/parser/qqmljsparser_p.h6
-rw-r--r--src/qml/qml.pro35
-rw-r--r--src/qml/qml/ftw/qbitfield_p.h4
-rw-r--r--src/qml/qml/ftw/qfieldlist_p.h22
-rw-r--r--src/qml/qml/ftw/qfinitestack_p.h6
-rw-r--r--src/qml/qml/ftw/qflagpointer_p.h6
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h93
-rw-r--r--src/qml/qml/ftw/qintrusivelist_p.h25
-rw-r--r--src/qml/qml/ftw/qpodvector_p.h14
-rw-r--r--src/qml/qml/ftw/qqmlnullablevalue_p.h4
-rw-r--r--src/qml/qml/ftw/qqmlrefcount_p.h2
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp14
-rw-r--r--src/qml/qml/ftw/qqmlthread_p.h2
-rw-r--r--src/qml/qml/ftw/qrecursionwatcher_p.h4
-rw-r--r--src/qml/qml/ftw/qrecyclepool_p.h4
-rw-r--r--src/qml/qml/qqml.h2
-rw-r--r--src/qml/qml/qqmlabstractbinding.cpp4
-rw-r--r--src/qml/qml/qqmlabstractbinding_p.h4
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp2
-rw-r--r--src/qml/qml/qqmlapplicationengine.h2
-rw-r--r--src/qml/qml/qqmlbinding.cpp48
-rw-r--r--src/qml/qml/qqmlbinding_p.h2
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp32
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h6
-rw-r--r--src/qml/qml/qqmlboundsignalexpressionpointer_p.h4
-rw-r--r--src/qml/qml/qqmlcleanup.cpp8
-rw-r--r--src/qml/qml/qqmlcleanup_p.h2
-rw-r--r--src/qml/qml/qqmlcomponent.cpp107
-rw-r--r--src/qml/qml/qqmlcomponent.h2
-rw-r--r--src/qml/qml/qqmlcomponent_p.h2
-rw-r--r--src/qml/qml/qqmlcomponentattached_p.h4
-rw-r--r--src/qml/qml/qqmlcontext.cpp156
-rw-r--r--src/qml/qml/qqmlcontext.h7
-rw-r--r--src/qml/qml/qqmlcontext_p.h28
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp4
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h4
-rw-r--r--src/qml/qml/qqmldata_p.h58
-rw-r--r--src/qml/qml/qqmldelayedcallqueue.cpp23
-rw-r--r--src/qml/qml/qqmldelayedcallqueue_p.h7
-rw-r--r--src/qml/qml/qqmldirparser_p.h18
-rw-r--r--src/qml/qml/qqmlengine.cpp220
-rw-r--r--src/qml/qml/qqmlengine.h2
-rw-r--r--src/qml/qml/qqmlengine_p.h30
-rw-r--r--src/qml/qml/qqmlerror.cpp14
-rw-r--r--src/qml/qml/qqmlexpression.cpp17
-rw-r--r--src/qml/qml/qqmlexpression.h2
-rw-r--r--src/qml/qml/qqmlexpression_p.h6
-rw-r--r--src/qml/qml/qqmlextensioninterface.h2
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp2
-rw-r--r--src/qml/qml/qqmlextensionplugin.h2
-rw-r--r--src/qml/qml/qqmlfile.cpp10
-rw-r--r--src/qml/qml/qqmlfileselector.cpp6
-rw-r--r--src/qml/qml/qqmlfileselector.h2
-rw-r--r--src/qml/qml/qqmlglobal.cpp18
-rw-r--r--src/qml/qml/qqmlglobal_p.h26
-rw-r--r--src/qml/qml/qqmlguard_p.h17
-rw-r--r--src/qml/qml/qqmlimport.cpp219
-rw-r--r--src/qml/qml/qqmlimport_p.h9
-rw-r--r--src/qml/qml/qqmlincubator.cpp59
-rw-r--r--src/qml/qml/qqmlincubator_p.h3
-rw-r--r--src/qml/qml/qqmlinfo.cpp2
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp34
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h22
-rw-r--r--src/qml/qml/qqmllist.cpp28
-rw-r--r--src/qml/qml/qqmllist.h30
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp12
-rw-r--r--src/qml/qml/qqmllistwrapper_p.h2
-rw-r--r--src/qml/qml/qqmllocale.cpp318
-rw-r--r--src/qml/qml/qqmllocale_p.h88
-rw-r--r--src/qml/qml/qqmlloggingcategory_p.h2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp138
-rw-r--r--src/qml/qml/qqmlmetatype_p.h10
-rw-r--r--src/qml/qml/qqmlnotifier.cpp6
-rw-r--r--src/qml/qml/qqmlnotifier_p.h19
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp207
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h23
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp20
-rw-r--r--src/qml/qml/qqmlopenmetaobject_p.h6
-rw-r--r--src/qml/qml/qqmlparserstatus.cpp4
-rw-r--r--src/qml/qml/qqmlplatform_p.h2
-rw-r--r--src/qml/qml/qqmlprivate.h11
-rw-r--r--src/qml/qml/qqmlproperty.cpp216
-rw-r--r--src/qml/qml/qqmlproperty_p.h8
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp75
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h69
-rw-r--r--src/qml/qml/qqmlpropertyvalueinterceptor.cpp2
-rw-r--r--src/qml/qml/qqmlproxymetaobject.cpp6
-rw-r--r--src/qml/qml/qqmlscriptstring_p.h2
-rw-r--r--src/qml/qml/qqmlstringconverters_p.h18
-rw-r--r--src/qml/qml/qqmltypeloader.cpp245
-rw-r--r--src/qml/qml/qqmltypeloader_p.h35
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp20
-rw-r--r--src/qml/qml/qqmltypenamecache_p.h8
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp24
-rw-r--r--src/qml/qml/qqmlvaluetype.cpp14
-rw-r--r--src/qml/qml/qqmlvaluetype_p.h10
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding.cpp6
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp49
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h2
-rw-r--r--src/qml/qml/qqmlvme.cpp18
-rw-r--r--src/qml/qml/qqmlvme_p.h7
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp52
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h14
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp346
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp546
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h118
-rw-r--r--src/qml/qml/v8/qv8engine.cpp22
-rw-r--r--src/qml/qml/v8/qv8engine_p.h18
-rw-r--r--src/qml/types/qqmlbind.cpp4
-rw-r--r--src/qml/types/qqmlbind_p.h2
-rw-r--r--src/qml/types/qqmlconnections.cpp6
-rw-r--r--src/qml/types/qqmlconnections_p.h2
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp250
-rw-r--r--src/qml/types/qqmldelegatemodel_p.h12
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h25
-rw-r--r--src/qml/types/qqmlinstantiator.cpp18
-rw-r--r--src/qml/types/qqmlinstantiator_p.h2
-rw-r--r--src/qml/types/qqmllistmodel.cpp437
-rw-r--r--src/qml/types/qqmllistmodel_p.h24
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h28
-rw-r--r--src/qml/types/qqmllistmodelworkeragent.cpp91
-rw-r--r--src/qml/types/qqmllistmodelworkeragent_p.h29
-rw-r--r--src/qml/types/qqmlobjectmodel.cpp11
-rw-r--r--src/qml/types/qqmlobjectmodel_p.h11
-rw-r--r--src/qml/types/qqmltimer.cpp4
-rw-r--r--src/qml/types/qqmltimer_p.h2
-rw-r--r--src/qml/types/qquickpackage.cpp2
-rw-r--r--src/qml/types/qquickpackage_p.h2
-rw-r--r--src/qml/types/qquickworkerscript.cpp64
-rw-r--r--src/qml/types/qquickworkerscript_p.h4
-rw-r--r--src/qml/util/qqmladaptormodel.cpp78
-rw-r--r--src/qml/util/qqmladaptormodel_p.h4
-rw-r--r--src/qml/util/qqmlchangeset.cpp2
-rw-r--r--src/qml/util/qqmlchangeset_p.h8
-rw-r--r--src/qml/util/qqmllistaccessor.cpp2
-rw-r--r--src/qml/util/qqmllistaccessor_p.h2
-rw-r--r--src/qml/util/qqmllistcompositor.cpp2
-rw-r--r--src/qml/util/qqmllistcompositor_p.h53
-rw-r--r--src/qml/util/qqmlpropertymap.cpp2
-rw-r--r--src/qml/util/qqmlpropertymap.h2
287 files changed, 5468 insertions, 4550 deletions
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp
index a931d733d6..2bb5766c7b 100644
--- a/src/qml/animations/qabstractanimationjob.cpp
+++ b/src/qml/animations/qabstractanimationjob.cpp
@@ -92,9 +92,8 @@ QQmlAnimationTimer *QQmlAnimationTimer::instance()
void QQmlAnimationTimer::ensureTimerUpdate()
{
- QQmlAnimationTimer *inst = QQmlAnimationTimer::instance(false);
QUnifiedTimer *instU = QUnifiedTimer::instance(false);
- if (instU && inst && inst->isPaused)
+ if (instU && isPaused)
instU->updateAnimationTimers(-1);
}
@@ -129,9 +128,7 @@ void QQmlAnimationTimer::updateAnimationsTime(qint64 delta)
void QQmlAnimationTimer::updateAnimationTimer()
{
- QQmlAnimationTimer *inst = QQmlAnimationTimer::instance(false);
- if (inst)
- inst->restartAnimationTimer();
+ restartAnimationTimer();
}
void QQmlAnimationTimer::restartAnimationTimer()
@@ -176,45 +173,38 @@ void QQmlAnimationTimer::registerAnimation(QAbstractAnimationJob *animation, boo
if (animation->userControlDisabled())
return;
- QQmlAnimationTimer *inst = instance(true); //we create the instance if needed
- inst->registerRunningAnimation(animation);
+ registerRunningAnimation(animation);
if (isTopLevel) {
Q_ASSERT(!animation->m_hasRegisteredTimer);
animation->m_hasRegisteredTimer = true;
- inst->animationsToStart << animation;
- if (!inst->startAnimationPending) {
- inst->startAnimationPending = true;
- QMetaObject::invokeMethod(inst, "startAnimations", Qt::QueuedConnection);
+ animationsToStart << animation;
+ if (!startAnimationPending) {
+ startAnimationPending = true;
+ QMetaObject::invokeMethod(this, "startAnimations", Qt::QueuedConnection);
}
}
}
void QQmlAnimationTimer::unregisterAnimation(QAbstractAnimationJob *animation)
{
- QQmlAnimationTimer *inst = QQmlAnimationTimer::instance(false);
- if (inst) {
- //at this point the unified timer should have been created
- //but it might also have been already destroyed in case the application is shutting down
+ unregisterRunningAnimation(animation);
- inst->unregisterRunningAnimation(animation);
-
- if (!animation->m_hasRegisteredTimer)
- return;
+ if (!animation->m_hasRegisteredTimer)
+ return;
- int idx = inst->animations.indexOf(animation);
- if (idx != -1) {
- inst->animations.removeAt(idx);
- // this is needed if we unregister an animation while its running
- if (idx <= inst->currentAnimationIdx)
- --inst->currentAnimationIdx;
+ int idx = animations.indexOf(animation);
+ if (idx != -1) {
+ animations.removeAt(idx);
+ // this is needed if we unregister an animation while its running
+ if (idx <= currentAnimationIdx)
+ --currentAnimationIdx;
- if (inst->animations.isEmpty() && !inst->stopTimerPending) {
- inst->stopTimerPending = true;
- QMetaObject::invokeMethod(inst, "stopTimer", Qt::QueuedConnection);
- }
- } else {
- inst->animationsToStart.removeOne(animation);
+ if (animations.isEmpty() && !stopTimerPending) {
+ stopTimerPending = true;
+ QMetaObject::invokeMethod(this, "stopTimer", Qt::QueuedConnection);
}
+ } else {
+ animationsToStart.removeOne(animation);
}
animation->m_hasRegisteredTimer = false;
}
@@ -269,7 +259,7 @@ int QQmlAnimationTimer::closestPauseAnimationTimeToFinish()
QAbstractAnimationJob::QAbstractAnimationJob()
: m_loopCount(1)
- , m_group(0)
+ , m_group(nullptr)
, m_direction(QAbstractAnimationJob::Forward)
, m_state(QAbstractAnimationJob::Stopped)
, m_totalCurrentTime(0)
@@ -277,9 +267,9 @@ QAbstractAnimationJob::QAbstractAnimationJob()
, m_currentLoop(0)
, m_uncontrolledFinishTime(-1)
, m_currentLoopStartTime(0)
- , m_nextSibling(0)
- , m_previousSibling(0)
- , m_wasDeleted(0)
+ , m_nextSibling(nullptr)
+ , m_previousSibling(nullptr)
+ , m_wasDeleted(nullptr)
, m_hasRegisteredTimer(false)
, m_isPause(false)
, m_isGroup(false)
@@ -303,8 +293,10 @@ QAbstractAnimationJob::~QAbstractAnimationJob()
stateChanged(oldState, m_state);
Q_ASSERT(m_state == Stopped);
- if (oldState == Running)
- QQmlAnimationTimer::unregisterAnimation(this);
+ if (oldState == Running) {
+ Q_ASSERT(QQmlAnimationTimer::instance() == m_timer);
+ m_timer->unregisterAnimation(this);
+ }
Q_ASSERT(!m_hasRegisteredTimer);
}
@@ -328,6 +320,9 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState)
if (m_loopCount == 0)
return;
+ if (!m_timer)
+ m_timer = QQmlAnimationTimer::instance();
+
State oldState = m_state;
int oldCurrentTime = m_currentTime;
int oldCurrentLoop = m_currentLoop;
@@ -353,11 +348,11 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState)
bool isTopLevel = !m_group || m_group->isStopped();
if (oldState == Running) {
if (newState == Paused && m_hasRegisteredTimer)
- QQmlAnimationTimer::ensureTimerUpdate();
+ m_timer->ensureTimerUpdate();
//the animation, is not running any more
- QQmlAnimationTimer::unregisterAnimation(this);
+ m_timer->unregisterAnimation(this);
} else if (newState == Running) {
- QQmlAnimationTimer::registerAnimation(this, isTopLevel);
+ m_timer->registerAnimation(this, isTopLevel);
}
//starting an animation qualifies as a top level loop change
@@ -384,7 +379,7 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState)
m_currentLoop = 0;
if (isTopLevel) {
// currentTime needs to be updated if pauseTimer is active
- RETURN_IF_DELETED(QQmlAnimationTimer::ensureTimerUpdate());
+ RETURN_IF_DELETED(m_timer->ensureTimerUpdate());
RETURN_IF_DELETED(setCurrentTime(m_totalCurrentTime));
}
}
@@ -421,14 +416,14 @@ void QAbstractAnimationJob::setDirection(Direction direction)
// the commands order below is important: first we need to setCurrentTime with the old direction,
// then update the direction on this and all children and finally restart the pauseTimer if needed
if (m_hasRegisteredTimer)
- QQmlAnimationTimer::ensureTimerUpdate();
+ m_timer->ensureTimerUpdate();
m_direction = direction;
updateDirection(direction);
if (m_hasRegisteredTimer)
// needed to update the timer interval in case of a pause animation
- QQmlAnimationTimer::updateAnimationTimer();
+ m_timer->updateAnimationTimer();
}
void QAbstractAnimationJob::setLoopCount(int loopCount)
diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h
index 95a39b1301..63fd4b0dac 100644
--- a/src/qml/animations/qabstractanimationjob_p.h
+++ b/src/qml/animations/qabstractanimationjob_p.h
@@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE
class QAnimationGroupJob;
class QAnimationJobChangeListener;
+class QQmlAnimationTimer;
+
class Q_QML_PRIVATE_EXPORT QAbstractAnimationJob
{
Q_DISABLE_COPY(QAbstractAnimationJob)
@@ -168,6 +170,7 @@ protected:
QAbstractAnimationJob *m_nextSibling;
QAbstractAnimationJob *m_previousSibling;
+ QQmlAnimationTimer *m_timer = nullptr;
bool *m_wasDeleted;
bool m_hasRegisteredTimer:1;
@@ -203,20 +206,20 @@ public:
static QQmlAnimationTimer *instance();
static QQmlAnimationTimer *instance(bool create);
- static void registerAnimation(QAbstractAnimationJob *animation, bool isTopLevel);
- static void unregisterAnimation(QAbstractAnimationJob *animation);
+ void registerAnimation(QAbstractAnimationJob *animation, bool isTopLevel);
+ void unregisterAnimation(QAbstractAnimationJob *animation);
/*
this is used for updating the currentTime of all animations in case the pause
timer is active or, otherwise, only of the animation passed as parameter.
*/
- static void ensureTimerUpdate();
+ void ensureTimerUpdate();
/*
this will evaluate the need of restarting the pause timer in case there is still
some pause animations running.
*/
- static void updateAnimationTimer();
+ void updateAnimationTimer();
void restartAnimationTimer() override;
void updateAnimationsTime(qint64 timeStep) override;
diff --git a/src/qml/animations/qanimationgroupjob.cpp b/src/qml/animations/qanimationgroupjob.cpp
index ea6d87952a..344791fd83 100644
--- a/src/qml/animations/qanimationgroupjob.cpp
+++ b/src/qml/animations/qanimationgroupjob.cpp
@@ -42,7 +42,7 @@
QT_BEGIN_NAMESPACE
QAnimationGroupJob::QAnimationGroupJob()
- : QAbstractAnimationJob(), m_firstChild(0), m_lastChild(0)
+ : QAbstractAnimationJob(), m_firstChild(nullptr), m_lastChild(nullptr)
{
m_isGroup = true;
}
@@ -111,25 +111,25 @@ void QAnimationGroupJob::removeAnimation(QAbstractAnimationJob *animation)
else
m_lastChild = prev;
- animation->m_previousSibling = 0;
- animation->m_nextSibling = 0;
+ animation->m_previousSibling = nullptr;
+ animation->m_nextSibling = nullptr;
- animation->m_group = 0;
+ animation->m_group = nullptr;
animationRemoved(animation, prev, next);
}
void QAnimationGroupJob::clear()
{
QAbstractAnimationJob *child = firstChild();
- QAbstractAnimationJob *nextSibling = 0;
- while (child != 0) {
- child->m_group = 0;
+ QAbstractAnimationJob *nextSibling = nullptr;
+ while (child != nullptr) {
+ child->m_group = nullptr;
nextSibling = child->nextSibling();
delete child;
child = nextSibling;
}
- m_firstChild = 0;
- m_lastChild = 0;
+ m_firstChild = nullptr;
+ m_lastChild = nullptr;
}
void QAnimationGroupJob::resetUncontrolledAnimationsFinishTime()
diff --git a/src/qml/animations/qanimationgroupjob_p.h b/src/qml/animations/qanimationgroupjob_p.h
index 26965c0264..fb567dc019 100644
--- a/src/qml/animations/qanimationgroupjob_p.h
+++ b/src/qml/animations/qanimationgroupjob_p.h
@@ -61,7 +61,7 @@ class Q_QML_PRIVATE_EXPORT QAnimationGroupJob : public QAbstractAnimationJob
Q_DISABLE_COPY(QAnimationGroupJob)
public:
QAnimationGroupJob();
- ~QAnimationGroupJob();
+ ~QAnimationGroupJob() override;
void appendAnimation(QAbstractAnimationJob *animation);
void prependAnimation(QAbstractAnimationJob *animation);
@@ -90,8 +90,8 @@ protected:
private:
//definition
- QAbstractAnimationJob *m_firstChild;
- QAbstractAnimationJob *m_lastChild;
+ QAbstractAnimationJob *m_firstChild = nullptr;
+ QAbstractAnimationJob *m_lastChild = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/qml/animations/qcontinuinganimationgroupjob.cpp b/src/qml/animations/qcontinuinganimationgroupjob.cpp
index 02dcaf1313..10096bf19c 100644
--- a/src/qml/animations/qcontinuinganimationgroupjob.cpp
+++ b/src/qml/animations/qcontinuinganimationgroupjob.cpp
@@ -43,7 +43,6 @@
QT_BEGIN_NAMESPACE
QContinuingAnimationGroupJob::QContinuingAnimationGroupJob()
- : QAnimationGroupJob()
{
}
diff --git a/src/qml/animations/qparallelanimationgroupjob_p.h b/src/qml/animations/qparallelanimationgroupjob_p.h
index 358b95ce53..67ba626247 100644
--- a/src/qml/animations/qparallelanimationgroupjob_p.h
+++ b/src/qml/animations/qparallelanimationgroupjob_p.h
@@ -76,8 +76,8 @@ private:
void applyGroupState(QAbstractAnimationJob *animation);
//state
- int m_previousLoop;
- int m_previousCurrentTime;
+ int m_previousLoop = 0;
+ int m_previousCurrentTime = 0;
};
QT_END_NAMESPACE
diff --git a/src/qml/animations/qpauseanimationjob.cpp b/src/qml/animations/qpauseanimationjob.cpp
index 27175580dc..0652ed578b 100644
--- a/src/qml/animations/qpauseanimationjob.cpp
+++ b/src/qml/animations/qpauseanimationjob.cpp
@@ -42,8 +42,7 @@
QT_BEGIN_NAMESPACE
QPauseAnimationJob::QPauseAnimationJob(int duration)
- : QAbstractAnimationJob()
- , m_duration(duration)
+ : m_duration(duration)
{
m_isPause = true;
}
diff --git a/src/qml/animations/qpauseanimationjob_p.h b/src/qml/animations/qpauseanimationjob_p.h
index e228f46daa..d0e8d57fc7 100644
--- a/src/qml/animations/qpauseanimationjob_p.h
+++ b/src/qml/animations/qpauseanimationjob_p.h
@@ -60,7 +60,7 @@ class Q_QML_PRIVATE_EXPORT QPauseAnimationJob : public QAbstractAnimationJob
Q_DISABLE_COPY(QPauseAnimationJob)
public:
explicit QPauseAnimationJob(int duration = 250);
- ~QPauseAnimationJob();
+ ~QPauseAnimationJob() override;
int duration() const override;
void setDuration(int msecs);
diff --git a/src/qml/animations/qsequentialanimationgroupjob.cpp b/src/qml/animations/qsequentialanimationgroupjob.cpp
index 25d31e4042..22e20d9268 100644
--- a/src/qml/animations/qsequentialanimationgroupjob.cpp
+++ b/src/qml/animations/qsequentialanimationgroupjob.cpp
@@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE
QSequentialAnimationGroupJob::QSequentialAnimationGroupJob()
: QAnimationGroupJob()
- , m_currentAnimation(0)
+ , m_currentAnimation(nullptr)
, m_previousLoop(0)
{
}
@@ -87,7 +87,7 @@ QSequentialAnimationGroupJob::AnimationIndex QSequentialAnimationGroupJob::index
Q_ASSERT(firstChild());
AnimationIndex ret;
- QAbstractAnimationJob *anim = 0;
+ QAbstractAnimationJob *anim = nullptr;
int duration = 0;
for (anim = firstChild(); anim; anim = anim->nextSibling()) {
@@ -283,7 +283,7 @@ void QSequentialAnimationGroupJob::setCurrentAnimation(QAbstractAnimationJob *an
{
if (!anim) {
Q_ASSERT(!firstChild());
- m_currentAnimation = 0;
+ m_currentAnimation = nullptr;
return;
}
@@ -364,7 +364,7 @@ void QSequentialAnimationGroupJob::uncontrolledAnimationFinished(QAbstractAnimat
void QSequentialAnimationGroupJob::animationInserted(QAbstractAnimationJob *anim)
{
- if (m_currentAnimation == 0)
+ if (m_currentAnimation == nullptr)
setCurrentAnimation(firstChild()); // initialize the current animation
if (m_currentAnimation == anim->nextSibling()
@@ -393,7 +393,7 @@ void QSequentialAnimationGroupJob::animationRemoved(QAbstractAnimationJob *anim,
else if (prev)
setCurrentAnimation(prev);
else// case all animations were removed
- setCurrentAnimation(0);
+ setCurrentAnimation(nullptr);
}
// duration of the previous animations up to the current animation
diff --git a/src/qml/animations/qsequentialanimationgroupjob_p.h b/src/qml/animations/qsequentialanimationgroupjob_p.h
index 5fbafcb9ac..800f0c3b90 100644
--- a/src/qml/animations/qsequentialanimationgroupjob_p.h
+++ b/src/qml/animations/qsequentialanimationgroupjob_p.h
@@ -77,12 +77,12 @@ protected:
private:
struct AnimationIndex
{
- AnimationIndex() : afterCurrent(false), timeOffset(0), animation(0) {}
+ AnimationIndex() {}
// AnimationIndex points to the animation at timeOffset, skipping 0 duration animations.
// Note that the index semantic is slightly different depending on the direction.
- bool afterCurrent; //whether animation is before or after m_currentAnimation //TODO: make enum Before/After/Same
- int timeOffset; // time offset when the animation at index starts.
- QAbstractAnimationJob *animation; //points to the animation at timeOffset
+ bool afterCurrent = false; //whether animation is before or after m_currentAnimation //TODO: make enum Before/After/Same
+ int timeOffset = 0; // time offset when the animation at index starts.
+ QAbstractAnimationJob *animation = nullptr; //points to the animation at timeOffset
};
int animationActualTotalDuration(QAbstractAnimationJob *anim) const;
@@ -103,8 +103,8 @@ private:
void advanceForwards(const AnimationIndex &newAnimationIndex);
//state
- QAbstractAnimationJob *m_currentAnimation;
- int m_previousLoop;
+ QAbstractAnimationJob *m_currentAnimation = nullptr;
+ int m_previousLoop = 0;
};
QT_END_NAMESPACE
diff --git a/src/qml/compiler/compiler.pri b/src/qml/compiler/compiler.pri
index 0d63d3b76f..2ca0c39acc 100644
--- a/src/qml/compiler/compiler.pri
+++ b/src/qml/compiler/compiler.pri
@@ -10,7 +10,8 @@ HEADERS += \
$$PWD/qv4compilerscanfunctions_p.h \
$$PWD/qv4codegen_p.h \
$$PWD/qqmlirbuilder_p.h \
- $$PWD/qqmltypecompiler_p.h
+ $$PWD/qqmltypecompiler_p.h \
+ $$PWD/qv4instr_moth_p.h
SOURCES += \
$$PWD/qv4bytecodegenerator.cpp \
@@ -19,7 +20,8 @@ SOURCES += \
$$PWD/qv4compilercontext.cpp \
$$PWD/qv4compilerscanfunctions.cpp \
$$PWD/qv4codegen.cpp \
- $$PWD/qqmlirbuilder.cpp
+ $$PWD/qqmlirbuilder.cpp \
+ $$PWD/qv4instr_moth.cpp
!qmldevtools_build {
@@ -42,13 +44,6 @@ else: SOURCES += $$PWD/qv4compilationunitmapper_win.cpp
qtConfig(private_tests):qtConfig(dlopen): QMAKE_USE_PRIVATE += libdl
}
-qmldevtools_build|qtConfig(qml-interpreter) {
- HEADERS += \
- $$PWD/qv4instr_moth_p.h
- SOURCES += \
- $$PWD/qv4instr_moth.cpp
-}
-
gcc {
equals(QT_GCC_MAJOR_VERSION, 5): QMAKE_CXXFLAGS += -fno-strict-aliasing
}
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 128eb2c720..237cd9bf3b 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -93,7 +93,7 @@ void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, cons
bindings = pool->New<PoolList<Binding> >();
functions = pool->New<PoolList<Function> >();
functionsAndExpressions = pool->New<PoolList<CompiledFunctionOrExpression> >();
- declarationsOverride = 0;
+ declarationsOverride = nullptr;
}
QString Object::sanityCheckFunctionNames(const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation)
@@ -233,7 +233,7 @@ Binding *Object::findBinding(quint32 nameIndex) const
for (Binding *b = bindings->first; b; b = b->next)
if (b->propertyNameIndex == nameIndex)
return b;
- return 0;
+ return nullptr;
}
void Object::insertSorted(Binding *b)
@@ -275,7 +275,7 @@ void Document::removeScriptPragmas(QString &script)
const QLatin1String pragma("pragma");
const QLatin1String library("library");
- QQmlJS::Lexer l(0);
+ QQmlJS::Lexer l(nullptr);
l.setCode(script, 0);
int token = l.lex();
@@ -317,7 +317,7 @@ void Document::removeScriptPragmas(QString &script)
Document::Document(bool debugMode)
: jsModule(debugMode)
- , program(0)
+ , program(nullptr)
, jsGenerator(&jsModule)
{
}
@@ -363,16 +363,16 @@ void ScriptDirectivesCollector::importModule(const QString &uri, const QString &
IRBuilder::IRBuilder(const QSet<QString> &illegalNames)
: illegalNames(illegalNames)
- , _object(0)
- , _propertyDeclaration(0)
- , pool(0)
- , jsGenerator(0)
+ , _object(nullptr)
+ , _propertyDeclaration(nullptr)
+ , pool(nullptr)
+ , jsGenerator(nullptr)
{
}
bool IRBuilder::generateFromQml(const QString &code, const QString &url, Document *output)
{
- QQmlJS::AST::UiProgram *program = 0;
+ QQmlJS::AST::UiProgram *program = nullptr;
{
QQmlJS::Lexer lexer(&output->jsParserEngine);
lexer.setCode(code, /*line = */ 1);
@@ -479,7 +479,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiObjectDefinition *node)
appendBinding(nameLocation, nameLocation, emptyStringIndex, idx);
} else {
int idx = 0;
- if (!defineQMLObject(&idx, /*qualfied type name id*/0, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, /*declarations should go here*/_object))
+ if (!defineQMLObject(&idx, /*qualfied type name id*/nullptr, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, /*declarations should go here*/_object))
return false;
appendBinding(node->qualifiedTypeNameId, idx);
}
@@ -504,7 +504,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiScriptBinding *node)
bool IRBuilder::visit(QQmlJS::AST::UiArrayBinding *node)
{
const QQmlJS::AST::SourceLocation qualifiedNameLocation = node->qualifiedId->identifierToken;
- Object *object = 0;
+ Object *object = nullptr;
QQmlJS::AST::UiQualifiedId *name = node->qualifiedId;
if (!resolveQualifiedId(&name, &object))
return false;
@@ -513,7 +513,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiArrayBinding *node)
const int propertyNameIndex = registerString(name->name.toString());
- if (bindingsTarget()->findBinding(propertyNameIndex) != 0) {
+ if (bindingsTarget()->findBinding(propertyNameIndex) != nullptr) {
recordError(name->identifierToken, tr("Property value set multiple times"));
return false;
}
@@ -588,7 +588,7 @@ bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qu
_object->declarationsOverride = declarationsOverride;
// A new object is also a boundary for property declarations.
- Property *declaration = 0;
+ Property *declaration = nullptr;
qSwap(_propertyDeclaration, declaration);
accept(initializer);
@@ -831,7 +831,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
return false;
}
- const TypeNameToType *type = 0;
+ const TypeNameToType *type = nullptr;
for (int typeIndex = 0; typeIndex < propTypeNameToTypesCount; ++typeIndex) {
const TypeNameToType *t = propTypeNameToTypes + typeIndex;
if (memberType == QLatin1String(t->name, static_cast<int>(t->nameLength))) {
@@ -1219,7 +1219,7 @@ void IRBuilder::tryGeneratingTranslationBinding(const QStringRef &base, AST::Arg
void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value)
{
const QQmlJS::AST::SourceLocation qualifiedNameLocation = name->identifierToken;
- Object *object = 0;
+ Object *object = nullptr;
if (!resolveQualifiedId(&name, &object))
return;
if (_object == object && name->name == QLatin1String("id")) {
@@ -1234,7 +1234,7 @@ void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Sta
void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment)
{
const QQmlJS::AST::SourceLocation qualifiedNameLocation = name->identifierToken;
- Object *object = 0;
+ Object *object = nullptr;
if (!resolveQualifiedId(&name, &object, isOnAssignment))
return;
qSwap(_object, object);
@@ -1385,7 +1385,7 @@ bool IRBuilder::setId(const QQmlJS::AST::SourceLocation &idLocation, QQmlJS::AST
if (QQmlJS::AST::ExpressionStatement *stmt = QQmlJS::AST::cast<QQmlJS::AST::ExpressionStatement *>(node)) {
if (QQmlJS::AST::StringLiteral *lit = QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(stmt->expression)) {
str = lit->value;
- node = 0;
+ node = nullptr;
} else
node = stmt->expression;
}
@@ -1456,9 +1456,9 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O
if (binding) {
if (isAttachedProperty) {
if (!binding->isAttachedProperty())
- binding = 0;
+ binding = nullptr;
} else if (!binding->isGroupProperty()) {
- binding = 0;
+ binding = nullptr;
}
}
if (!binding) {
@@ -1480,7 +1480,7 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O
binding->type = QV4::CompiledData::Binding::Type_GroupProperty;
int objIndex = 0;
- if (!defineQMLObject(&objIndex, 0, QQmlJS::AST::SourceLocation(), 0, 0))
+ if (!defineQMLObject(&objIndex, nullptr, QQmlJS::AST::SourceLocation(), nullptr, nullptr))
return false;
binding->value.objectIndex = objIndex;
@@ -1582,11 +1582,14 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4:
memset(data + unitSize, 0, totalSize - unitSize);
if (jsUnit != compilationUnit->data)
free(jsUnit);
- jsUnit = 0;
+ jsUnit = nullptr;
QV4::CompiledData::Unit *qmlUnit = reinterpret_cast<QV4::CompiledData::Unit *>(data);
qmlUnit->unitSize = totalSize;
qmlUnit->flags |= QV4::CompiledData::Unit::IsQml;
+ // This unit's memory was allocated with malloc on the heap, so it's
+ // definitely not suitable for StaticData access.
+ qmlUnit->flags &= ~QV4::CompiledData::Unit::StaticData;
qmlUnit->offsetToImports = unitSize;
qmlUnit->nImports = output.imports.count();
qmlUnit->offsetToObjects = unitSize + importSize;
@@ -1770,7 +1773,8 @@ char *QmlUnitGenerator::writeBindings(char *bindingPtr, const Object *o, Binding
JSCodeGen::JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator,
QV4::Compiler::Module *jsModule, QQmlJS::Engine *jsEngine,
- QQmlJS::AST::UiProgram *qmlRoot, QQmlTypeNameCache *imports, const QV4::Compiler::StringTableGenerator *stringPool)
+ QQmlJS::AST::UiProgram *qmlRoot, QQmlTypeNameCache *imports,
+ const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames)
: QV4::Compiler::Codegen(jsUnitGenerator, /*strict mode*/false)
, sourceCode(sourceCode)
, jsEngine(jsEngine)
@@ -1778,10 +1782,11 @@ JSCodeGen::JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *
, imports(imports)
, stringPool(stringPool)
, _disableAcceleratedLookups(false)
- , _contextObject(0)
- , _scopeObject(0)
+ , _contextObject(nullptr)
+ , _scopeObject(nullptr)
, _qmlContextSlot(-1)
, _importedScriptsSlot(-1)
+ , m_globalNames(globalNames)
{
_module = jsModule;
_fileNameIsUrl = true;
@@ -1791,7 +1796,7 @@ void JSCodeGen::beginContextScope(const JSCodeGen::ObjectIdMapping &objectIds, Q
{
_idObjects = objectIds;
_contextObject = contextObject;
- _scopeObject = 0;
+ _scopeObject = nullptr;
}
void JSCodeGen::beginObjectScope(QQmlPropertyCache *scopeObject)
@@ -1804,7 +1809,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
QVector<int> runtimeFunctionIndices(functions.size());
QV4::Compiler::ScanFunctions scan(this, sourceCode, QV4::Compiler::GlobalCode);
- scan.enterEnvironment(0, QV4::Compiler::QmlBinding);
+ scan.enterEnvironment(nullptr, QV4::Compiler::QmlBinding);
scan.enterQmlScope(qmlRoot, QStringLiteral("context scope"));
for (const CompiledFunctionOrExpression &f : functions) {
Q_ASSERT(f.node != qmlRoot);
@@ -1821,7 +1826,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
scan.leaveEnvironment();
scan.leaveEnvironment();
- _context = 0;
+ _context = nullptr;
for (int i = 0; i < functions.count(); ++i) {
const CompiledFunctionOrExpression &qmlFunction = functions.at(i);
@@ -1840,7 +1845,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
QQmlJS::AST::SourceElements *body;
if (function)
- body = function->body ? function->body->elements : 0;
+ body = function->body ? function->body->elements : nullptr;
else {
// Synthesize source elements.
QQmlJS::MemoryPool *pool = jsEngine->pool();
@@ -1858,7 +1863,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
_disableAcceleratedLookups = qmlFunction.disableAcceleratedLookups;
int idx = defineFunction(name, node,
- function ? function->formals : 0,
+ function ? function->formals : nullptr,
body);
runtimeFunctionIndices[i] = idx;
}
@@ -1884,14 +1889,14 @@ int JSCodeGen::defineFunction(const QString &name, AST::Node *ast, AST::FormalPa
#ifndef V4_BOOTSTRAP
QQmlPropertyData *JSCodeGen::lookupQmlCompliantProperty(QQmlPropertyCache *cache, const QString &name)
{
- QQmlPropertyData *pd = cache->property(name, /*object*/0, /*context*/0);
+ QQmlPropertyData *pd = cache->property(name, /*object*/nullptr, /*context*/nullptr);
// Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
if (!pd || pd->isFunction())
- return 0;
+ return nullptr;
if (!cache->isAllowedInRevision(pd))
- return 0;
+ return nullptr;
return pd;
}
@@ -2226,20 +2231,34 @@ QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &n
QQmlPropertyData *data = lookupQmlCompliantProperty(_scopeObject, name);
if (!data)
return Reference::fromName(this, name);
+
Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
- bool captureRequired = !data->isConstant() && !data->isQmlBinding();
- return Reference::fromQmlScopeObject(base, data->coreIndex(), data->notifyIndex(),
- captureRequired);
+ Reference::PropertyCapturePolicy capturePolicy;
+ if (!data->isConstant() && !data->isQmlBinding())
+ capturePolicy = Reference::CaptureAtRuntime;
+ else
+ capturePolicy = data->isConstant() ? Reference::DontCapture : Reference::CaptureAheadOfTime;
+ return Reference::fromQmlScopeObject(base, data->coreIndex(), data->notifyIndex(), capturePolicy);
}
if (_contextObject) {
QQmlPropertyData *data = lookupQmlCompliantProperty(_contextObject, name);
if (!data)
return Reference::fromName(this, name);
+
Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
- bool captureRequired = !data->isConstant() && !data->isQmlBinding();
- return Reference::fromQmlContextObject(base, data->coreIndex(), data->notifyIndex(),
- captureRequired);
+ Reference::PropertyCapturePolicy capturePolicy;
+ if (!data->isConstant() && !data->isQmlBinding())
+ capturePolicy = Reference::CaptureAtRuntime;
+ else
+ capturePolicy = data->isConstant() ? Reference::DontCapture : Reference::CaptureAheadOfTime;
+ return Reference::fromQmlContextObject(base, data->coreIndex(), data->notifyIndex(), capturePolicy);
+ }
+
+ if (m_globalNames.contains(name)) {
+ Reference r = Reference::fromName(this, name);
+ r.global = true;
+ return r;
}
#else
Q_UNUSED(name)
@@ -2254,7 +2273,7 @@ QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRev
{
if (notInRevision) *notInRevision = false;
- QQmlPropertyData *d = cache->property(name, 0, 0);
+ QQmlPropertyData *d = cache->property(name, nullptr, nullptr);
// Find the first property
while (d && d->isFunction())
@@ -2262,7 +2281,7 @@ QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRev
if (check != IgnoreRevision && d && !cache->isAllowedInRevision(d)) {
if (notInRevision) *notInRevision = true;
- return 0;
+ return nullptr;
} else {
return d;
}
@@ -2273,7 +2292,7 @@ QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevis
{
if (notInRevision) *notInRevision = false;
- QQmlPropertyData *d = cache->property(name, 0, 0);
+ QQmlPropertyData *d = cache->property(name, nullptr, nullptr);
if (notInRevision) *notInRevision = false;
while (d && !(d->isFunction()))
@@ -2281,7 +2300,7 @@ QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevis
if (d && !cache->isAllowedInRevision(d)) {
if (notInRevision) *notInRevision = true;
- return 0;
+ return nullptr;
} else if (d && d->isSignal()) {
return d;
}
@@ -2294,7 +2313,7 @@ QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevis
return cache->signal(d->notifyIndex());
}
- return 0;
+ return nullptr;
}
IRLoader::IRLoader(const QV4::CompiledData::Unit *qmlData, QmlIR::Document *output)
@@ -2431,7 +2450,7 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO
f->location = compiledFunction->location;
f->nameIndex = compiledFunction->nameIndex;
- QQmlJS::AST::FormalParameterList *paramList = 0;
+ QQmlJS::AST::FormalParameterList *paramList = nullptr;
const quint32_le *formalNameIdx = compiledFunction->formalsTable();
for (uint i = 0; i < compiledFunction->nFormals; ++i, ++formalNameIdx) {
const QString formal = unit->stringAt(*formalNameIdx);
@@ -2447,7 +2466,7 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO
paramList = paramList->finish();
const QString name = unit->stringAt(compiledFunction->nameIndex);
- f->functionDeclaration = new(pool) QQmlJS::AST::FunctionDeclaration(jsParserEngine->newStringRef(name), paramList, /*body*/0);
+ f->functionDeclaration = new(pool) QQmlJS::AST::FunctionDeclaration(jsParserEngine->newStringRef(name), paramList, /*body*/nullptr);
f->formals.allocate(pool, int(compiledFunction->nFormals));
formalNameIdx = compiledFunction->formalsTable();
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index 406c939998..c2cf18e3c4 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -80,17 +80,16 @@ template <typename T>
struct PoolList
{
PoolList()
- : first(0)
- , last(0)
- , count(0)
+ : first(nullptr)
+ , last(nullptr)
{}
T *first;
T *last;
- int count;
+ int count = 0;
int append(T *item) {
- item->next = 0;
+ item->next = nullptr;
if (last)
last->next = item;
else
@@ -110,7 +109,7 @@ struct PoolList
template <typename Sortable, typename Base, Sortable Base::*sortMember>
T *findSortedInsertionPoint(T *item) const
{
- T *insertPos = 0;
+ T *insertPos = nullptr;
for (T *it = first; it; it = it->next) {
if (!(it->*sortMember <= item->*sortMember))
@@ -205,11 +204,11 @@ class FixedPoolArray
{
T *data;
public:
- int count;
+ int count = 0;
FixedPoolArray()
- : data(0)
- , count(0)
+ : data(nullptr)
+
{}
void allocate(QQmlJS::MemoryPool *pool, int size)
@@ -343,21 +342,16 @@ struct Function
struct Q_QML_PRIVATE_EXPORT CompiledFunctionOrExpression
{
CompiledFunctionOrExpression()
- : node(0)
- , nameIndex(0)
- , disableAcceleratedLookups(false)
- , next(0)
+
{}
CompiledFunctionOrExpression(QQmlJS::AST::Node *n)
: node(n)
- , nameIndex(0)
- , disableAcceleratedLookups(false)
- , next(0)
+
{}
- QQmlJS::AST::Node *node; // FunctionDeclaration, Statement or Expression
- quint32 nameIndex;
- bool disableAcceleratedLookups;
- CompiledFunctionOrExpression *next;
+ QQmlJS::AST::Node *node = nullptr; // FunctionDeclaration, Statement or Expression
+ quint32 nameIndex = 0;
+ bool disableAcceleratedLookups = false;
+ CompiledFunctionOrExpression *next = nullptr;
};
struct Q_QML_PRIVATE_EXPORT Object
@@ -514,8 +508,8 @@ public:
void accept(QQmlJS::AST::Node *node);
// returns index in _objects
- bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::AST::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride = 0);
- bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiObjectDefinition *node, Object *declarationsOverride = 0)
+ bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::AST::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride = nullptr);
+ bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiObjectDefinition *node, Object *declarationsOverride = nullptr)
{ return defineQMLObject(objectIndex, node->qualifiedTypeNameId, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, declarationsOverride); }
static QString asString(QQmlJS::AST::UiQualifiedId *node);
@@ -598,7 +592,7 @@ struct Q_QML_EXPORT PropertyResolver
IgnoreRevision
};
- QQmlPropertyData *property(const QString &name, bool *notInRevision = 0, RevisionCheck check = CheckRevision) const;
+ QQmlPropertyData *property(const QString &name, bool *notInRevision = nullptr, RevisionCheck check = CheckRevision) const;
// This code must match the semantics of QQmlPropertyPrivate::findSignalByName
QQmlPropertyData *signal(const QString &name, bool *notInRevision) const;
@@ -610,8 +604,8 @@ struct Q_QML_EXPORT PropertyResolver
struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen
{
JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator, QV4::Compiler::Module *jsModule,
- QQmlJS::Engine *jsEngine, QQmlJS::AST::UiProgram *qmlRoot, QQmlTypeNameCache *imports,
- const QV4::Compiler::StringTableGenerator *stringPool);
+ QQmlJS::Engine *jsEngine, QQmlJS::AST::UiProgram *qmlRoot,
+ QQmlTypeNameCache *imports, const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames);
struct IdMapping
{
@@ -651,6 +645,7 @@ private:
QQmlPropertyCache *_scopeObject;
int _qmlContextSlot;
int _importedScriptsSlot;
+ QSet<QString> m_globalNames;
};
struct Q_QML_PRIVATE_EXPORT IRLoader {
@@ -670,6 +665,17 @@ private:
} // namespace QmlIR
+struct QQmlCompileError
+{
+ QQmlCompileError() {}
+ QQmlCompileError(const QV4::CompiledData::Location &location, const QString &description)
+ : location(location), description(description) {}
+ QV4::CompiledData::Location location;
+ QString description;
+
+ bool isSet() const { return !description.isEmpty(); }
+};
+
QT_END_NAMESPACE
#endif // QQMLIRBUILDER_P_H
diff --git a/src/qml/compiler/qqmlpropertycachecreator.cpp b/src/qml/compiler/qqmlpropertycachecreator.cpp
index f8d63ec634..fd22cd58f1 100644
--- a/src/qml/compiler/qqmlpropertycachecreator.cpp
+++ b/src/qml/compiler/qqmlpropertycachecreator.cpp
@@ -45,26 +45,54 @@ QT_BEGIN_NAMESPACE
QAtomicInt QQmlPropertyCacheCreatorBase::classIndexCounter(0);
-QQmlBindingInstantiationContext::QQmlBindingInstantiationContext()
- : referencingObjectIndex(-1)
- , instantiatingBinding(nullptr)
- , instantiatingProperty(nullptr)
+QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding,
+ const QString &instantiatingPropertyName, QQmlPropertyCache *referencingObjectPropertyCache)
+ : referencingObjectIndex(referencingObjectIndex)
+ , instantiatingBinding(instantiatingBinding)
+ , instantiatingPropertyName(instantiatingPropertyName)
+ , referencingObjectPropertyCache(referencingObjectPropertyCache)
{
+}
+bool QQmlBindingInstantiationContext::resolveInstantiatingProperty()
+{
+ if (!instantiatingBinding || instantiatingBinding->type != QV4::CompiledData::Binding::Type_GroupProperty)
+ return true;
+
+ Q_ASSERT(referencingObjectIndex >= 0);
+ Q_ASSERT(referencingObjectPropertyCache);
+ Q_ASSERT(instantiatingBinding->propertyNameIndex != 0);
+
+ bool notInRevision = false;
+ instantiatingProperty = QmlIR::PropertyResolver(referencingObjectPropertyCache).property(instantiatingPropertyName, &notInRevision, QmlIR::PropertyResolver::IgnoreRevision);
+ return instantiatingProperty != nullptr;
}
-QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding, const QString &instantiatingPropertyName, const QQmlPropertyCache *referencingObjectPropertyCache)
- : referencingObjectIndex(referencingObjectIndex)
- , instantiatingBinding(instantiatingBinding)
- , instantiatingProperty(nullptr)
+QQmlRefPointer<QQmlPropertyCache> QQmlBindingInstantiationContext::instantiatingPropertyCache(QQmlEnginePrivate *enginePrivate) const
{
- if (instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty) {
- Q_ASSERT(referencingObjectIndex >= 0);
- Q_ASSERT(referencingObjectPropertyCache);
- Q_ASSERT(instantiatingBinding->propertyNameIndex != 0);
+ if (instantiatingProperty) {
+ if (instantiatingProperty->isQObject()) {
+ return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType(), instantiatingProperty->typeMinorVersion());
+ } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType())) {
+ return enginePrivate->cache(vtmo);
+ }
+ }
+ return QQmlRefPointer<QQmlPropertyCache>();
+}
+
+void QQmlPendingGroupPropertyBindings::resolveMissingPropertyCaches(QQmlEnginePrivate *enginePrivate, QQmlPropertyCacheVector *propertyCaches) const
+{
+ for (QQmlBindingInstantiationContext pendingBinding: *this) {
+ const int groupPropertyObjectIndex = pendingBinding.instantiatingBinding->value.objectIndex;
+
+ if (propertyCaches->at(groupPropertyObjectIndex))
+ continue;
+
+ if (!pendingBinding.resolveInstantiatingProperty())
+ continue;
- bool notInRevision = false;
- instantiatingProperty = QmlIR::PropertyResolver(referencingObjectPropertyCache).property(instantiatingPropertyName, &notInRevision);
+ auto cache = pendingBinding.instantiatingPropertyCache(enginePrivate);
+ propertyCaches->set(groupPropertyObjectIndex, cache);
}
}
diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h
index 5d6a5c177a..8bbc8291b4 100644
--- a/src/qml/compiler/qqmlpropertycachecreator_p.h
+++ b/src/qml/compiler/qqmlpropertycachecreator_p.h
@@ -50,18 +50,31 @@
// We mean it.
//
-#include "qqmltypecompiler_p.h"
#include <private/qqmlvaluetype_p.h>
#include <private/qqmlengine_p.h>
QT_BEGIN_NAMESPACE
struct QQmlBindingInstantiationContext {
- QQmlBindingInstantiationContext();
- QQmlBindingInstantiationContext(int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding, const QString &instantiatingPropertyName, const QQmlPropertyCache *referencingObjectPropertyCache);
- int referencingObjectIndex;
- const QV4::CompiledData::Binding *instantiatingBinding;
- QQmlPropertyData *instantiatingProperty;
+ QQmlBindingInstantiationContext() {}
+ QQmlBindingInstantiationContext(int referencingObjectIndex,
+ const QV4::CompiledData::Binding *instantiatingBinding,
+ const QString &instantiatingPropertyName,
+ QQmlPropertyCache *referencingObjectPropertyCache);
+
+ bool resolveInstantiatingProperty();
+ QQmlRefPointer<QQmlPropertyCache> instantiatingPropertyCache(QQmlEnginePrivate *enginePrivate) const;
+
+ int referencingObjectIndex = -1;
+ const QV4::CompiledData::Binding *instantiatingBinding = nullptr;
+ QString instantiatingPropertyName;
+ QQmlRefPointer<QQmlPropertyCache> referencingObjectPropertyCache;
+ QQmlPropertyData *instantiatingProperty = nullptr;
+};
+
+struct QQmlPendingGroupPropertyBindings : public QVector<QQmlBindingInstantiationContext>
+{
+ void resolveMissingPropertyCaches(QQmlEnginePrivate *enginePrivate, QQmlPropertyCacheVector *propertyCaches) const;
};
struct QQmlPropertyCacheCreatorBase
@@ -77,7 +90,10 @@ class QQmlPropertyCacheCreator : public QQmlPropertyCacheCreatorBase
public:
typedef typename ObjectContainer::CompiledObject CompiledObject;
- QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches, QQmlEnginePrivate *enginePrivate, const ObjectContainer *objectContainer, const QQmlImports *imports);
+ QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches,
+ QQmlPendingGroupPropertyBindings *pendingGroupPropertyBindings,
+ QQmlEnginePrivate *enginePrivate,
+ const ObjectContainer *objectContainer, const QQmlImports *imports);
QQmlCompileError buildMetaObjects();
@@ -92,14 +108,19 @@ protected:
const ObjectContainer * const objectContainer;
const QQmlImports * const imports;
QQmlPropertyCacheVector *propertyCaches;
+ QQmlPendingGroupPropertyBindings *pendingGroupPropertyBindings;
};
template <typename ObjectContainer>
-inline QQmlPropertyCacheCreator<ObjectContainer>::QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches, QQmlEnginePrivate *enginePrivate, const ObjectContainer *objectContainer, const QQmlImports *imports)
+inline QQmlPropertyCacheCreator<ObjectContainer>::QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches,
+ QQmlPendingGroupPropertyBindings *pendingGroupPropertyBindings,
+ QQmlEnginePrivate *enginePrivate,
+ const ObjectContainer *objectContainer, const QQmlImports *imports)
: enginePrivate(enginePrivate)
, objectContainer(objectContainer)
, imports(imports)
, propertyCaches(propertyCaches)
+ , pendingGroupPropertyBindings(pendingGroupPropertyBindings)
{
propertyCaches->resize(objectContainer->objectCount());
}
@@ -169,6 +190,14 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObje
for ( ; binding != end; ++binding)
if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
QQmlBindingInstantiationContext context(objectIndex, &(*binding), stringAt(binding->propertyNameIndex), thisCache);
+
+ // Binding to group property where we failed to look up the type of the
+ // property? Possibly a group property that is an alias that's not resolved yet.
+ // Let's attempt to resolve it after we're done with the aliases and fill in the
+ // propertyCaches entry then.
+ if (!context.resolveInstantiatingProperty())
+ pendingGroupPropertyBindings->append(context);
+
QQmlCompileError error = buildMetaObjectRecursively(binding->value.objectIndex, context);
if (error.isSet())
return error;
@@ -183,11 +212,7 @@ template <typename ObjectContainer>
inline QQmlPropertyCache *QQmlPropertyCacheCreator<ObjectContainer>::propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlCompileError *error) const
{
if (context.instantiatingProperty) {
- if (context.instantiatingProperty->isQObject()) {
- return enginePrivate->rawPropertyCacheForType(context.instantiatingProperty->propType());
- } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(context.instantiatingProperty->propType())) {
- return enginePrivate->cache(vtmo);
- }
+ return context.instantiatingPropertyCache(enginePrivate);
} else if (obj->inheritedTypeNameIndex != 0) {
auto *typeRef = objectContainer->resolvedTypes.value(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
@@ -214,7 +239,7 @@ inline QQmlPropertyCache *QQmlPropertyCacheCreator<ObjectContainer>::propertyCac
QQmlType qmltype = typeRef->type;
if (!qmltype.isValid()) {
QString propertyName = stringAt(context.instantiatingBinding->propertyNameIndex);
- if (imports->resolveType(propertyName, &qmltype, 0, 0, 0)) {
+ if (imports->resolveType(propertyName, &qmltype, nullptr, nullptr, nullptr)) {
if (qmltype.isComposite()) {
QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl());
Q_ASSERT(tdata);
@@ -411,7 +436,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
Q_ASSERT(param->type == QV4::CompiledData::Property::Custom);
const QString customTypeName = stringAt(param->customTypeNameIndex);
QQmlType qmltype;
- if (!imports->resolveType(customTypeName, &qmltype, 0, 0, 0))
+ if (!imports->resolveType(customTypeName, &qmltype, nullptr, nullptr, nullptr))
return QQmlCompileError(s->location, QQmlPropertyCacheCreatorBase::tr("Invalid signal parameter type: %1").arg(customTypeName));
if (qmltype.isComposite()) {
@@ -441,7 +466,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
seenSignals.insert(signalName);
cache->appendSignal(signalName, flags, effectiveMethodIndex++,
- paramCount?paramTypes.constData():0, names);
+ paramCount?paramTypes.constData():nullptr, names);
}
@@ -476,6 +501,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
pend = obj->propertiesEnd();
for ( ; p != pend; ++p, ++propertyIdx) {
int propertyType = 0;
+ int propertTypeMinorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
if (p->type == QV4::CompiledData::Property::Var) {
@@ -491,7 +517,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
p->type == QV4::CompiledData::Property::Custom);
QQmlType qmltype;
- if (!imports->resolveType(stringAt(p->customTypeNameIndex), &qmltype, 0, 0, 0)) {
+ if (!imports->resolveType(stringAt(p->customTypeNameIndex), &qmltype, nullptr, nullptr, nullptr)) {
return QQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type"));
}
@@ -513,6 +539,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
} else {
if (p->type == QV4::CompiledData::Property::Custom) {
propertyType = qmltype.typeId();
+ propertTypeMinorVersion = qmltype.minorVersion();
} else {
propertyType = qmltype.qListTypeId();
}
@@ -532,7 +559,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
if (!obj->defaultPropertyIsAlias && propertyIdx == obj->indexOfDefaultPropertyOrAlias)
cache->_defaultPropertyName = propertyName;
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- propertyType, effectiveSignalIndex);
+ propertyType, propertTypeMinorVersion, effectiveSignalIndex);
effectiveSignalIndex++;
}
@@ -551,11 +578,11 @@ public:
void appendAliasPropertiesToMetaObjects();
- void appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex);
+ QQmlCompileError appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex);
private:
void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex);
- void propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QQmlPropertyRawData::Flags *propertyFlags);
+ QQmlCompileError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyRawData::Flags *propertyFlags);
void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const;
@@ -666,8 +693,8 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl
}
template <typename ObjectContainer>
-inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(
- const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type,
+inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(
+ const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion,
QQmlPropertyData::Flags *propertyFlags)
{
const int targetObjectIndex = objectForId(component, alias.targetObjectId);
@@ -685,18 +712,24 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias
auto targetAlias = targetObject.aliasesBegin();
for (uint i = 0; i < alias.localAliasIndex; ++i)
++targetAlias;
- propertyDataForAlias(component, *targetAlias, type, propertyFlags);
- return;
+ return propertyDataForAlias(component, *targetAlias, type, minorVersion, propertyFlags);
} else if (alias.encodedMetaPropertyIndex == -1) {
Q_ASSERT(alias.flags & QV4::CompiledData::Alias::AliasPointsToPointerObject);
auto *typeRef = objectContainer->resolvedTypes.value(targetObject.inheritedTypeNameIndex);
- Q_ASSERT(typeRef);
+ if (!typeRef) {
+ // Can be caused by the alias target not being a valid id or property. E.g.:
+ // property alias dataValue: dataVal
+ // invalidAliasComponent { id: dataVal }
+ return QQmlCompileError(targetObject.location, QQmlPropertyCacheCreatorBase::tr("Invalid alias target"));
+ }
if (typeRef->type.isValid())
*type = typeRef->type.typeId();
else
*type = typeRef->compilationUnit->metaTypeId;
+ *minorVersion = typeRef->minorVersion;
+
propertyFlags->type = QQmlPropertyData::Flags::QObjectDerivedType;
} else {
int coreIndex = QQmlPropertyIndex::fromEncoded(alias.encodedMetaPropertyIndex).coreIndex();
@@ -733,15 +766,16 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias
propertyFlags->isWritable = !(alias.flags & QV4::CompiledData::Property::IsReadOnly) && writable;
propertyFlags->isResettable = resettable;
+ return QQmlCompileError();
}
template <typename ObjectContainer>
-inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache(
+inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache(
const CompiledObject &component, int objectIndex)
{
const CompiledObject &object = *objectContainer->objectAt(objectIndex);
if (!object.aliasCount())
- return;
+ return QQmlCompileError();
QQmlPropertyCache *propertyCache = propertyCaches->at(objectIndex);
Q_ASSERT(propertyCache);
@@ -756,8 +790,11 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPrope
Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved);
int type = 0;
+ int minorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
- propertyDataForAlias(component, *alias, &type, &propertyFlags);
+ QQmlCompileError error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags);
+ if (error.isSet())
+ return error;
const QString propertyName = objectContainer->stringAt(alias->nameIndex);
@@ -765,8 +802,10 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPrope
propertyCache->_defaultPropertyName = propertyName;
propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- type, effectiveSignalIndex++);
+ type, minorVersion, effectiveSignalIndex++);
}
+
+ return QQmlCompileError();
}
template <typename ObjectContainer>
diff --git a/src/qml/compiler/qqmlpropertyvalidator.cpp b/src/qml/compiler/qqmlpropertyvalidator.cpp
index 7ea89b378d..00bb694ef4 100644
--- a/src/qml/compiler/qqmlpropertyvalidator.cpp
+++ b/src/qml/compiler/qqmlpropertyvalidator.cpp
@@ -58,7 +58,7 @@ QQmlPropertyValidator::QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, c
QVector<QQmlCompileError> QQmlPropertyValidator::validate()
{
- return validateObject(/*root object*/0, /*instantiatingBinding*/0);
+ return validateObject(/*root object*/0, /*instantiatingBinding*/nullptr);
}
typedef QVarLengthArray<const QV4::CompiledData::Binding *, 8> GroupPropertyVector;
@@ -94,7 +94,7 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
if (!propertyCache)
return QVector<QQmlCompileError>();
- QQmlCustomParser *customParser = 0;
+ QQmlCustomParser *customParser = nullptr;
if (auto typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
if (typeRef->type.isValid())
customParser = typeRef->type.customParser();
@@ -124,7 +124,7 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
QmlIR::PropertyResolver propertyResolver(propertyCache);
QString defaultPropertyName;
- QQmlPropertyData *defaultProperty = 0;
+ QQmlPropertyData *defaultProperty = nullptr;
if (obj->indexOfDefaultPropertyOrAlias != -1) {
QQmlPropertyCache *cache = propertyCache->parent();
defaultPropertyName = cache->defaultPropertyName();
@@ -157,7 +157,7 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
bool isGroupProperty = instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty;
bool notInRevision = false;
- QQmlPropertyData *pd = 0;
+ QQmlPropertyData *pd = nullptr;
if (!name.isEmpty()) {
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression
|| binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject)
@@ -188,15 +188,21 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
if (name.constData()->isUpper() && !binding->isAttachedProperty()) {
QQmlType type;
- QQmlImportNamespace *typeNamespace = 0;
- imports.resolveType(stringAt(binding->propertyNameIndex), &type, 0, 0, &typeNamespace);
+ QQmlImportNamespace *typeNamespace = nullptr;
+ imports.resolveType(stringAt(binding->propertyNameIndex), &type, nullptr, nullptr, &typeNamespace);
if (typeNamespace)
return recordError(binding->location, tr("Invalid use of namespace"));
return recordError(binding->location, tr("Invalid attached object assignment"));
}
if (binding->type >= QV4::CompiledData::Binding::Type_Object && (pd || binding->isAttachedProperty())) {
- const QVector<QQmlCompileError> subObjectValidatorErrors = validateObject(binding->value.objectIndex, binding, pd && QQmlValueTypeFactory::metaObjectForMetaType(pd->propType()));
+ const bool populatingValueTypeGroupProperty
+ = pd
+ && QQmlValueTypeFactory::metaObjectForMetaType(pd->propType())
+ && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment);
+ const QVector<QQmlCompileError> subObjectValidatorErrors
+ = validateObject(binding->value.objectIndex, binding,
+ populatingValueTypeGroupProperty);
if (!subObjectValidatorErrors.isEmpty())
return subObjectValidatorErrors;
}
@@ -287,6 +293,9 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
}
if (obj->idNameIndex) {
+ if (populatingValueTypeGroupProperty)
+ return recordError(obj->locationOfIdProperty, tr("Invalid use of id property with a value type"));
+
bool notInRevision = false;
collectedBindingPropertyData << propertyResolver.property(QStringLiteral("id"), &notInRevision);
}
@@ -297,9 +306,9 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
customParser->engine = enginePrivate;
customParser->imports = &imports;
customParser->verifyBindings(qmlUnit, customBindings);
- customParser->validator = 0;
- customParser->engine = 0;
- customParser->imports = (QQmlImports*)0;
+ customParser->validator = nullptr;
+ customParser->engine = nullptr;
+ customParser->imports = (QQmlImports*)nullptr;
QVector<QQmlCompileError> parserErrors = customParser->errors();
if (!parserErrors.isEmpty())
return parserErrors;
@@ -665,10 +674,11 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *
} else if (property->propType() == qMetaTypeId<QQmlScriptString>()) {
return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected"));
} else {
- // We want to raw metaObject here as the raw metaobject is the
+ // We want to use the 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());
+ // Using -1 for the minor version ensures that we get the raw metaObject.
+ QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(property->propType(), -1);
// Will be true if the assgned type inherits propertyMetaObject
bool isAssignable = false;
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 97ca597953..a896745b3f 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -45,7 +45,6 @@
#include <private/qqmlvmemetaobject_p.h>
#include <private/qqmlcomponent_p.h>
-#include "qqmlpropertycachecreator_p.h"
//#include "qv4jssimplifier_p.h"
#define COMPILE_EXCEPTION(token, desc) \
@@ -79,8 +78,12 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
customParsers.insert(it.key(), customParser);
}
+ QQmlPendingGroupPropertyBindings pendingGroupPropertyBindings;
+
+
{
- QQmlPropertyCacheCreator<QQmlTypeCompiler> propertyCacheBuilder(&m_propertyCaches, engine, this, imports());
+ QQmlPropertyCacheCreator<QQmlTypeCompiler> propertyCacheBuilder(&m_propertyCaches, &pendingGroupPropertyBindings,
+ engine, this, imports());
QQmlCompileError error = propertyCacheBuilder.buildMetaObjects();
if (error.isSet()) {
recordError(error);
@@ -122,6 +125,8 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
QQmlComponentAndAliasResolver resolver(this);
if (!resolver.resolve())
return nullptr;
+
+ pendingGroupPropertyBindings.resolveMissingPropertyCaches(engine, &m_propertyCaches);
}
{
@@ -139,10 +144,11 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
sss.scan();
}
- document->jsModule.fileName = typeData->finalUrlString();
- QmlIR::JSCodeGen v4CodeGenerator(document->code, &document->jsGenerator, &document->jsModule, &document->jsParserEngine, document->program, typeNameCache, &document->jsGenerator.stringTable);
+ document->jsModule.fileName = typeData->urlString();
+ document->jsModule.finalUrl = typeData->finalUrlString();
+ QmlIR::JSCodeGen v4CodeGenerator(document->code, &document->jsGenerator, &document->jsModule, &document->jsParserEngine,
+ document->program, typeNameCache, &document->jsGenerator.stringTable, engine->v8engine()->illegalNames());
v4CodeGenerator.setUseFastLookups(false);
- // ### v4CodeGenerator.setUseTypeInference(true);
QQmlJSCodeGenerator jsCodeGen(this, &v4CodeGenerator);
if (!jsCodeGen.generateCodeForComponents())
return nullptr;
@@ -295,7 +301,7 @@ SignalHandlerConverter::SignalHandlerConverter(QQmlTypeCompiler *typeCompiler)
, imports(typeCompiler->imports())
, customParsers(typeCompiler->customParserCache())
, resolvedTypes(typeCompiler->resolvedTypes)
- , illegalNames(QV8Engine::get(QQmlEnginePrivate::get(typeCompiler->enginePrivate()))->illegalNames())
+ , illegalNames(typeCompiler->enginePrivate()->v8engine()->illegalNames())
, propertyCaches(typeCompiler->propertyCaches())
{
}
@@ -331,7 +337,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
auto *typeRef = resolvedTypes.value(binding->propertyNameIndex);
QQmlType type = typeRef ? typeRef->type : QQmlType();
if (!type.isValid()) {
- if (imports->resolveType(propertyName, &type, 0, 0, 0)) {
+ if (imports->resolveType(propertyName, &type, nullptr, nullptr, nullptr)) {
if (type.isComposite()) {
QQmlTypeData *tdata = enginePrivate->typeLoader.getType(type.sourceUrl());
Q_ASSERT(tdata);
@@ -396,7 +402,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
} else {
if (notInRevision) {
// Try assinging it as a property later
- if (resolver.property(propertyName, /*notInRevision ptr*/0))
+ if (resolver.property(propertyName, /*notInRevision ptr*/nullptr))
continue;
const QString &originalPropertyName = stringAt(binding->propertyNameIndex);
@@ -456,7 +462,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
QQmlJS::MemoryPool *pool = compiler->memoryPool();
- QQmlJS::AST::FormalParameterList *paramList = 0;
+ QQmlJS::AST::FormalParameterList *paramList = nullptr;
for (const QString &param : qAsConst(parameters)) {
QStringRef paramNameRef = compiler->newStringRef(param);
@@ -470,7 +476,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
paramList = paramList->finish();
QmlIR::CompiledFunctionOrExpression *foe = obj->functionsAndExpressions->slowAt(binding->value.compiledScriptIndex);
- QQmlJS::AST::FunctionDeclaration *functionDeclaration = 0;
+ QQmlJS::AST::FunctionDeclaration *functionDeclaration = nullptr;
if (QQmlJS::AST::ExpressionStatement *es = QQmlJS::AST::cast<QQmlJS::AST::ExpressionStatement*>(foe->node)) {
if (QQmlJS::AST::FunctionExpression *fe = QQmlJS::AST::cast<QQmlJS::AST::FunctionExpression*>(es->expression)) {
functionDeclaration = new (pool) QQmlJS::AST::FunctionDeclaration(fe->name, fe->formals, fe->body);
@@ -610,7 +616,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
return true;
}
QQmlType type;
- imports->resolveType(typeName, &type, 0, 0, 0);
+ imports->resolveType(typeName, &type, nullptr, nullptr, nullptr);
if (!type.isValid() && !isQtObject)
return true;
@@ -662,7 +668,7 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QStringRef &e
if (scope != QLatin1String("Qt")) {
QQmlType type;
- imports->resolveType(scope, &type, 0, 0, 0);
+ imports->resolveType(scope, &type, nullptr, nullptr, nullptr);
if (!type.isValid())
return -1;
if (!enumName.isEmpty())
@@ -813,7 +819,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
continue;
}
- QQmlPropertyData *pd = 0;
+ QQmlPropertyData *pd = nullptr;
if (binding->propertyNameIndex != quint32(0)) {
bool notInRevision = false;
pd = propertyResolver.property(stringAt(binding->propertyNameIndex), &notInRevision);
@@ -823,8 +829,8 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
if (!pd || !pd->isQObject())
continue;
- QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType());
- const QMetaObject *mo = pc ? pc->firstCppMetaObject() : 0;
+ QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeMinorVersion());
+ const QMetaObject *mo = pc ? pc->firstCppMetaObject() : nullptr;
while (mo) {
if (mo == &QQmlComponent::staticMetaObject)
break;
@@ -1022,7 +1028,11 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex)
}
if (result == AllAliasesResolved) {
- aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex);
+ QQmlCompileError error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex);
+ if (error.isSet()) {
+ recordError(error);
+ return false;
+ }
atLeastOneAliasResolved = true;
} else if (result == SomeAliasesResolved) {
atLeastOneAliasResolved = true;
@@ -1092,7 +1102,11 @@ QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolv
alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject;
} else {
QQmlPropertyCache *targetCache = propertyCaches.at(targetObjectIndex);
- Q_ASSERT(targetCache);
+ if (!targetCache) {
+ *error = QQmlCompileError(alias->referenceLocation, tr("Invalid alias target location: %1").arg(property.toString()));
+ break;
+ }
+
QmlIR::PropertyResolver resolver(targetCache);
QQmlPropertyData *targetProperty = resolver.property(property.toString());
@@ -1195,7 +1209,7 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex)
return true;
QString defaultPropertyName;
- QQmlPropertyData *defaultProperty = 0;
+ QQmlPropertyData *defaultProperty = nullptr;
if (obj->indexOfDefaultPropertyOrAlias != -1) {
QQmlPropertyCache *cache = propertyCache->parent();
defaultPropertyName = cache->defaultPropertyName();
@@ -1220,7 +1234,7 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex)
}
for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
- QQmlPropertyData *pd = 0;
+ QQmlPropertyData *pd = nullptr;
QString name = stringAt(binding->propertyNameIndex);
if (customParser) {
@@ -1325,7 +1339,7 @@ bool QQmlJSCodeGenerator::compileComponent(int contextObject)
auto *tref = resolvedTypes.value(obj->inheritedTypeNameIndex);
if (tref && tref->isFullyDynamicType)
- m.type = 0;
+ m.type = nullptr;
idMapping << m;
}
@@ -1403,10 +1417,10 @@ void QQmlDefaultPropertyMerger::mergeDefaultProperties(int objectIndex)
QmlIR::Object *object = qmlObjects.at(objectIndex);
QString defaultProperty = object->indexOfDefaultPropertyOrAlias != -1 ? propertyCache->parent()->defaultPropertyName() : propertyCache->defaultPropertyName();
- QmlIR::Binding *bindingsToReinsert = 0;
- QmlIR::Binding *tail = 0;
+ QmlIR::Binding *bindingsToReinsert = nullptr;
+ QmlIR::Binding *tail = nullptr;
- QmlIR::Binding *previousBinding = 0;
+ QmlIR::Binding *previousBinding = nullptr;
QmlIR::Binding *binding = object->firstBinding();
while (binding) {
if (binding->propertyNameIndex == quint32(0) || stringAt(binding->propertyNameIndex) != defaultProperty) {
@@ -1425,7 +1439,7 @@ void QQmlDefaultPropertyMerger::mergeDefaultProperties(int objectIndex)
tail->next = toReinsert;
tail = tail->next;
}
- tail->next = 0;
+ tail->next = nullptr;
}
binding = bindingsToReinsert;
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index d905b956c7..b8eddcb9b2 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -55,6 +55,7 @@
#include <qhash.h>
#include <private/qqmltypeloader_p.h>
#include <private/qqmlirbuilder_p.h>
+#include <private/qqmlpropertycachecreator_p.h>
QT_BEGIN_NAMESPACE
@@ -74,17 +75,6 @@ struct Location;
}
}
-struct QQmlCompileError
-{
- QQmlCompileError() {}
- QQmlCompileError(const QV4::CompiledData::Location &location, const QString &description)
- : location(location), description(description) {}
- QV4::CompiledData::Location location;
- QString description;
-
- bool isSet() const { return !description.isEmpty(); }
-};
-
struct QQmlTypeCompiler
{
Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp
index 05bbf25292..4d50654d27 100644
--- a/src/qml/compiler/qv4bytecodegenerator.cpp
+++ b/src/qml/compiler/qv4bytecodegenerator.cpp
@@ -74,16 +74,20 @@ void BytecodeGenerator::packInstruction(I &i)
Q_ASSERT(type >= MOTH_NUM_INSTRUCTIONS());
if (type >= MOTH_NUM_INSTRUCTIONS())
type -= MOTH_NUM_INSTRUCTIONS();
- int instructionsAsInts[sizeof(Instr)/sizeof(int)];
+ int instructionsAsInts[sizeof(Instr)/sizeof(int)] = {};
int nMembers = Moth::InstrInfo::argumentCount[static_cast<int>(i.type)];
- memcpy(instructionsAsInts, i.packed + 1, nMembers*sizeof(int));
+ for (int j = 0; j < nMembers; ++j) {
+ instructionsAsInts[j] = qFromLittleEndian<qint32>(i.packed + 1 + j * sizeof(int));
+ }
enum {
Normal,
Wide
} width = Normal;
for (int n = 0; n < nMembers; ++n) {
- if (width == Normal && (static_cast<char>(instructionsAsInts[n]) != instructionsAsInts[n]))
+ if (width == Normal && (static_cast<qint8>(instructionsAsInts[n]) != instructionsAsInts[n])) {
width = Wide;
+ break;
+ }
}
char *code = i.packed;
switch (width) {
@@ -91,7 +95,7 @@ void BytecodeGenerator::packInstruction(I &i)
*reinterpret_cast<uchar *>(code) = type;
++code;
for (int n = 0; n < nMembers; ++n) {
- char v = static_cast<char>(instructionsAsInts[n]);
+ qint8 v = static_cast<qint8>(instructionsAsInts[n]);
memcpy(code, &v, 1);
code += 1;
}
@@ -113,17 +117,17 @@ void BytecodeGenerator::adjustJumpOffsets()
continue;
Q_ASSERT(i.linkedLabel != -1 && labels.at(i.linkedLabel) != -1);
const auto &linkedInstruction = instructions.at(labels.at(i.linkedLabel));
- char *c = i.packed + i.offsetForJump;
+ qint8 *c = reinterpret_cast<qint8*>(i.packed + i.offsetForJump);
int jumpOffset = linkedInstruction.position - (i.position + i.size);
// qDebug() << "adjusting jump offset for instruction" << index << i.position << i.size << "offsetForJump" << i.offsetForJump << "target"
// << labels.at(i.linkedLabel) << linkedInstruction.position << "jumpOffset" << jumpOffset;
uchar type = *reinterpret_cast<const uchar *>(i.packed);
if (type >= MOTH_NUM_INSTRUCTIONS()) {
Q_ASSERT(i.offsetForJump == i.size - 4);
- memcpy(c, &jumpOffset, sizeof(int));
+ qToLittleEndian<qint32>(jumpOffset, c);
} else {
Q_ASSERT(i.offsetForJump == i.size - 1);
- char o = jumpOffset;
+ qint8 o = jumpOffset;
Q_ASSERT(o == jumpOffset);
*c = o;
}
@@ -181,6 +185,7 @@ void BytecodeGenerator::finalize(Compiler::Context *context)
}
int BytecodeGenerator::addInstructionHelper(Instr::Type type, const Instr &i, int offsetOfOffset) {
+#if QT_CONFIG(qml_debug)
if (debugMode && type != Instr::Type::Debug) {
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // broken gcc warns about Instruction::Debug()
@@ -193,10 +198,14 @@ QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // broken gcc warns about Instru
}
QT_WARNING_POP
}
+#else
+ Q_UNUSED(debugMode);
+#endif
const int pos = instructions.size();
- int s = Moth::InstrInfo::argumentCount[static_cast<int>(type)]*sizeof(int);
+ const int argCount = Moth::InstrInfo::argumentCount[static_cast<int>(type)];
+ int s = argCount*sizeof(int);
if (offsetOfOffset != -1)
offsetOfOffset += 1;
I instr{type, static_cast<short>(s + 1), 0, currentLine, offsetOfOffset, -1, "\0\0" };
@@ -204,7 +213,12 @@ QT_WARNING_POP
*reinterpret_cast<uchar *>(code) = static_cast<uchar>(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type));
++code;
Q_ASSERT(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type) < 256);
- memcpy(code, &i, s);
+
+ for (int j = 0; j < argCount; ++j) {
+ qToLittleEndian<qint32>(i.argumentsAsInts[j], code);
+ code += sizeof(int);
+ }
+
instructions.append(instr);
return pos;
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index 3d516da922..3b3c766bfe 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -94,7 +94,7 @@ public:
generator->labels[index] = generator->instructions.size();
}
- BytecodeGenerator *generator = 0;
+ BytecodeGenerator *generator = nullptr;
int index = -1;
};
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 6abcf82f44..bc4ca5d6f4 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -89,10 +89,10 @@ static inline void setJumpOutLocation(QV4::Moth::BytecodeGenerator *bytecodeGene
}
Codegen::Codegen(QV4::Compiler::JSUnitGenerator *jsUnitGenerator, bool strict)
- : _module(0)
+ : _module(nullptr)
, _returnAddress(0)
- , _context(0)
- , _labelledStatement(0)
+ , _context(nullptr)
+ , _labelledStatement(nullptr)
, jsUnitGenerator(jsUnitGenerator)
, _strictMode(strict)
, _fileNameIsUrl(false)
@@ -102,6 +102,7 @@ Codegen::Codegen(QV4::Compiler::JSUnitGenerator *jsUnitGenerator, bool strict)
}
void Codegen::generateFromProgram(const QString &fileName,
+ const QString &finalUrl,
const QString &sourceCode,
Program *node,
Module *module,
@@ -110,14 +111,16 @@ void Codegen::generateFromProgram(const QString &fileName,
Q_ASSERT(node);
_module = module;
- _context = 0;
+ _context = nullptr;
+ // ### should be set on the module outside of this method
_module->fileName = fileName;
+ _module->finalUrl = finalUrl;
ScanFunctions scan(this, sourceCode, mode);
scan(node);
- defineFunction(QStringLiteral("%entry"), node, 0, node->elements);
+ defineFunction(QStringLiteral("%entry"), node, nullptr, node->elements);
}
void Codegen::enterContext(Node *node)
@@ -199,6 +202,7 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr)
} else {
// intentionally fall-through: the result is never used, so it's equivalent to
// "expr += 1", which is what a pre-increment does as well.
+ Q_FALLTHROUGH();
}
case PreIncrement: {
Reference e = expr.asLValue();
@@ -224,6 +228,7 @@ Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr)
} else {
// intentionally fall-through: the result is never used, so it's equivalent to
// "expr -= 1", which is what a pre-decrement does as well.
+ Q_FALLTHROUGH();
}
case PreDecrement: {
Reference e = expr.asLValue();
@@ -630,14 +635,14 @@ bool Codegen::visit(ArrayLiteral *ast)
for (ElementList *it = ast->elements; it; it = it->next) {
for (Elision *elision = it->elision; elision; elision = elision->next)
- push(0);
+ push(nullptr);
push(it->expression);
if (hasError)
return false;
}
for (Elision *elision = ast->elision; elision; elision = elision->next)
- push(0);
+ push(nullptr);
if (args == -1) {
Q_ASSERT(argc == 0);
@@ -1258,6 +1263,8 @@ bool Codegen::visit(CallExpression *ast)
switch (base.type) {
case Reference::Member:
case Reference::Subscript:
+ case Reference::QmlScopeObject:
+ case Reference::QmlContextObject:
base = base.asLValue();
break;
case Reference::Name:
@@ -1272,7 +1279,21 @@ bool Codegen::visit(CallExpression *ast)
return false;
//### Do we really need all these call instructions? can's we load the callee in a temp?
- if (base.type == Reference::Member) {
+ if (base.type == Reference::QmlScopeObject) {
+ Instruction::CallScopeObjectProperty call;
+ call.base = base.qmlBase.stackSlot();
+ call.name = base.qmlCoreIndex;
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+ } else if (base.type == Reference::QmlContextObject) {
+ Instruction::CallContextObjectProperty call;
+ call.base = base.qmlBase.stackSlot();
+ call.name = base.qmlCoreIndex;
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+ } else if (base.type == Reference::Member) {
if (useFastLookups) {
Instruction::CallPropertyLookup call;
call.base = base.propertyBase.stackSlot();
@@ -1475,7 +1496,7 @@ bool Codegen::visit(FunctionExpression *ast)
RegisterScope scope(this);
- int function = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : 0);
+ int function = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : nullptr);
loadClosure(function);
_expr.setResult(Reference::fromAccumulator(this));
return false;
@@ -1699,7 +1720,7 @@ bool Codegen::visit(ObjectLiteral *ast)
v.rvalue = value.storeOnStack();
} else if (PropertyGetterSetter *gs = AST::cast<AST::PropertyGetterSetter *>(it->assignment)) {
- const int function = defineFunction(name, gs, gs->formals, gs->functionBody ? gs->functionBody->elements : 0);
+ const int function = defineFunction(name, gs, gs->formals, gs->functionBody ? gs->functionBody->elements : nullptr);
ObjectPropertyValue &v = valueMap[name];
if (v.rvalue.isValid() ||
(gs->type == PropertyGetterSetter::Getter && v.hasGetter()) ||
@@ -2121,7 +2142,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
for (const Context::Member &member : qAsConst(_context->members)) {
if (member.function) {
const int function = defineFunction(member.function->name.toString(), member.function, member.function->formals,
- member.function->body ? member.function->body->elements : 0);
+ member.function->body ? member.function->body->elements : nullptr);
loadClosure(function);
if (! _context->parent) {
Reference::fromName(this, member.function->name.toString()).storeConsumeAccumulator();
@@ -2333,7 +2354,8 @@ bool Codegen::visit(ForEachStatement *ast)
RegisterScope scope(this);
- Reference obj = Reference::fromStackSlot(this);
+ Reference nextIterObj = Reference::fromStackSlot(this);
+ Reference iterObj = Reference::fromStackSlot(this);
Reference expr = expression(ast->expression);
if (hasError)
return true;
@@ -2341,7 +2363,9 @@ bool Codegen::visit(ForEachStatement *ast)
expr.loadInAccumulator();
Instruction::ForeachIteratorObject iteratorObjInstr;
bytecodeGenerator->addInstruction(iteratorObjInstr);
- obj.storeConsumeAccumulator();
+ iterObj.storeConsumeAccumulator();
+
+ Reference lhs = expression(ast->initialiser).asLValue();
BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
@@ -2352,20 +2376,21 @@ bool Codegen::visit(ForEachStatement *ast)
BytecodeGenerator::Label body = bytecodeGenerator->label();
+ nextIterObj.loadInAccumulator();
+ lhs.storeConsumeAccumulator();
+
statement(ast->statement);
setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
in.link();
- Reference lhs = expression(ast->initialiser).asLValue();
-
- obj.loadInAccumulator();
+ iterObj.loadInAccumulator();
Instruction::ForeachNextPropertyName nextPropInstr;
bytecodeGenerator->addInstruction(nextPropInstr);
- lhs = lhs.storeRetainAccumulator().storeOnStack();
+ nextIterObj.storeConsumeAccumulator();
Reference::fromConst(this, QV4::Encode::null()).loadInAccumulator();
- bytecodeGenerator->jumpStrictNotEqual(lhs.stackSlot(), body);
+ bytecodeGenerator->jumpStrictNotEqual(nextIterObj.stackSlot(), body);
end.link();
@@ -2477,7 +2502,8 @@ bool Codegen::visit(LocalForEachStatement *ast)
RegisterScope scope(this);
- Reference obj = Reference::fromStackSlot(this);
+ Reference nextIterObj = Reference::fromStackSlot(this);
+ Reference iterObj = Reference::fromStackSlot(this);
Reference expr = expression(ast->expression);
if (hasError)
return true;
@@ -2487,7 +2513,7 @@ bool Codegen::visit(LocalForEachStatement *ast)
expr.loadInAccumulator();
Instruction::ForeachIteratorObject iteratorObjInstr;
bytecodeGenerator->addInstruction(iteratorObjInstr);
- obj.storeConsumeAccumulator();
+ iterObj.storeConsumeAccumulator();
BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
@@ -2498,18 +2524,22 @@ bool Codegen::visit(LocalForEachStatement *ast)
BytecodeGenerator::Label body = bytecodeGenerator->label();
Reference it = referenceForName(ast->declaration->name.toString(), true).asLValue();
+
+ nextIterObj.loadInAccumulator();
+ it.storeConsumeAccumulator();
+
statement(ast->statement);
setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
in.link();
- obj.loadInAccumulator();
+ iterObj.loadInAccumulator();
Instruction::ForeachNextPropertyName nextPropInstr;
bytecodeGenerator->addInstruction(nextPropInstr);
- auto lhs = it.storeRetainAccumulator().storeOnStack();
+ nextIterObj.storeConsumeAccumulator();
Reference::fromConst(this, QV4::Encode::null()).loadInAccumulator();
- bytecodeGenerator->jumpStrictNotEqual(lhs.stackSlot(), body);
+ bytecodeGenerator->jumpStrictNotEqual(nextIterObj.stackSlot(), body);
end.link();
@@ -2898,43 +2928,43 @@ public:
return locs;
}
- bool visit(ArrayMemberExpression *) Q_DECL_OVERRIDE
+ bool visit(ArrayMemberExpression *) override
{
locs.setAllVolatile();
return false;
}
- bool visit(FieldMemberExpression *) Q_DECL_OVERRIDE
+ bool visit(FieldMemberExpression *) override
{
locs.setAllVolatile();
return false;
}
- bool visit(PostIncrementExpression *e) Q_DECL_OVERRIDE
+ bool visit(PostIncrementExpression *e) override
{
collectIdentifiers(locs.specificLocations, e->base);
return false;
}
- bool visit(PostDecrementExpression *e) Q_DECL_OVERRIDE
+ bool visit(PostDecrementExpression *e) override
{
collectIdentifiers(locs.specificLocations, e->base);
return false;
}
- bool visit(PreIncrementExpression *e) Q_DECL_OVERRIDE
+ bool visit(PreIncrementExpression *e) override
{
collectIdentifiers(locs.specificLocations, e->expression);
return false;
}
- bool visit(PreDecrementExpression *e) Q_DECL_OVERRIDE
+ bool visit(PreDecrementExpression *e) override
{
collectIdentifiers(locs.specificLocations, e->expression);
return false;
}
- bool visit(BinaryExpression *e) Q_DECL_OVERRIDE
+ bool visit(BinaryExpression *e) override
{
switch (e->op) {
case QSOperator::InplaceAnd:
@@ -3073,7 +3103,7 @@ Codegen::Reference &Codegen::Reference::operator =(const Reference &other)
qmlBase = other.qmlBase;
qmlCoreIndex = other.qmlCoreIndex;
qmlNotifyIndex = other.qmlNotifyIndex;
- captureRequired = other.captureRequired;
+ capturePolicy = other.capturePolicy;
break;
}
@@ -3110,7 +3140,7 @@ bool Codegen::Reference::operator==(const Codegen::Reference &other) const
case QmlScopeObject:
case QmlContextObject:
return qmlCoreIndex == other.qmlCoreIndex && qmlNotifyIndex == other.qmlNotifyIndex
- && captureRequired == other.captureRequired;
+ && capturePolicy == other.capturePolicy;
}
return true;
}
@@ -3439,18 +3469,18 @@ QT_WARNING_POP
Instruction::LoadScopeObjectProperty load;
load.base = qmlBase;
load.propertyIndex = qmlCoreIndex;
- load.captureRequired = captureRequired;
+ load.captureRequired = capturePolicy == CaptureAtRuntime;
codegen->bytecodeGenerator->addInstruction(load);
- if (!captureRequired)
+ if (capturePolicy == CaptureAheadOfTime)
codegen->_context->scopeObjectPropertyDependencies.insert(qmlCoreIndex, qmlNotifyIndex);
} return;
case QmlContextObject: {
Instruction::LoadContextObjectProperty load;
load.base = qmlBase;
load.propertyIndex = qmlCoreIndex;
- load.captureRequired = captureRequired;
+ load.captureRequired = capturePolicy == CaptureAtRuntime;
codegen->bytecodeGenerator->addInstruction(load);
- if (!captureRequired)
+ if (capturePolicy == CaptureAheadOfTime)
codegen->_context->contextObjectPropertyDependencies.insert(qmlCoreIndex, qmlNotifyIndex);
} return;
case Invalid:
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index dba9388292..a46d47cb67 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -97,6 +97,7 @@ public:
void generateFromProgram(const QString &fileName,
+ const QString &finalUrl,
const QString &sourceCode,
AST::Program *ast,
Module *module,
@@ -190,10 +191,7 @@ public:
bool isLValue() const { return !isReadonly; }
Reference(Codegen *cg, Type type = Invalid) : type(type), codegen(cg) {}
- Reference()
- : type(Invalid)
- , codegen(nullptr)
- {}
+ Reference() {}
Reference(const Reference &other);
Reference &operator =(const Reference &other);
@@ -218,6 +216,28 @@ public:
return isStackSlot();
}
+ enum PropertyCapturePolicy {
+ /*
+ We're reading a property from the scope or context object, but it's a CONSTANT property,
+ so we don't need to register a dependency at all.
+ */
+ DontCapture,
+ /*
+ We're reading the property of a QObject, and we know that it's the
+ scope object or context object, which we know very well. Instead of registering a
+ property capture every time, we can do that ahead of time and then register all those
+ captures in one shot in registerQmlDependencies().
+ */
+ CaptureAheadOfTime,
+ /*
+ We're reading the property of a QObject, and we're not quite sure where
+ the QObject comes from or what it is. So, when reading that property at run-time,
+ make sure that we capture where we read that property so that if it changes we can
+ re-evaluate the entire expression.
+ */
+ CaptureAtRuntime
+ };
+
static Reference fromAccumulator(Codegen *cg) {
return Reference(cg, Accumulator);
}
@@ -266,20 +286,20 @@ public:
r.isReadonly = true;
return r;
}
- static Reference fromQmlScopeObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, bool captureRequired) {
+ static Reference fromQmlScopeObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, PropertyCapturePolicy capturePolicy) {
Reference r(base.codegen, QmlScopeObject);
r.qmlBase = base.storeOnStack().stackSlot();
r.qmlCoreIndex = coreIndex;
r.qmlNotifyIndex = notifyIndex;
- r.captureRequired = captureRequired;
+ r.capturePolicy = capturePolicy;
return r;
}
- static Reference fromQmlContextObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, bool captureRequired) {
+ static Reference fromQmlContextObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, PropertyCapturePolicy capturePolicy) {
Reference r(base.codegen, QmlContextObject);
r.qmlBase = base.storeOnStack().stackSlot();
r.qmlCoreIndex = coreIndex;
r.qmlNotifyIndex = notifyIndex;
- r.captureRequired = captureRequired;
+ r.capturePolicy = capturePolicy;
return r;
}
static Reference fromThis(Codegen *cg) {
@@ -335,7 +355,7 @@ public:
Moth::StackSlot qmlBase;
qint16 qmlCoreIndex;
qint16 qmlNotifyIndex;
- bool captureRequired;
+ PropertyCapturePolicy capturePolicy;
};
};
QString name;
@@ -344,7 +364,7 @@ public:
bool stackSlotIsLocalOrArgument = false;
bool isVolatile = false;
bool global = false;
- Codegen *codegen;
+ Codegen *codegen = nullptr;
private:
void storeAccumulator() const;
@@ -363,16 +383,12 @@ public:
};
struct ObjectPropertyValue {
- ObjectPropertyValue()
- : getter(-1)
- , setter(-1)
- , keyAsIndex(UINT_MAX)
- {}
+ ObjectPropertyValue() {}
Reference rvalue;
- int getter; // index in _module->functions or -1 if not set
- int setter;
- uint keyAsIndex;
+ int getter = -1; // index in _module->functions or -1 if not set
+ int setter = -1;
+ uint keyAsIndex = UINT_MAX;
bool hasGetter() const { return getter >= 0; }
bool hasSetter() const { return setter >= 0; }
@@ -383,34 +399,26 @@ protected:
class Result {
Reference _result;
- const BytecodeGenerator::Label *_iftrue;
- const BytecodeGenerator::Label *_iffalse;
- Format _format;
+ const BytecodeGenerator::Label *_iftrue = nullptr;
+ const BytecodeGenerator::Label *_iffalse = nullptr;
+ Format _format = ex;
Format _requested;
bool _trueBlockFollowsCondition = false;
public:
explicit Result(const Reference &lrvalue)
: _result(lrvalue)
- , _iftrue(nullptr)
- , _iffalse(nullptr)
- , _format(ex)
, _requested(ex)
- {
- }
+ {}
explicit Result(Format requested = ex)
- : _iftrue(0)
- , _iffalse(0)
- , _format(ex)
- , _requested(requested) {}
+ : _requested(requested) {}
explicit Result(const BytecodeGenerator::Label *iftrue,
const BytecodeGenerator::Label *iffalse,
bool trueBlockFollowsCondition)
: _iftrue(iftrue)
, _iffalse(iffalse)
- , _format(ex)
, _requested(cx)
, _trueBlockFollowsCondition(trueBlockFollowsCondition)
{
@@ -648,7 +656,7 @@ protected:
Context *_context;
AST::LabelledStatement *_labelledStatement;
QV4::Compiler::JSUnitGenerator *jsUnitGenerator;
- BytecodeGenerator *bytecodeGenerator = 0;
+ BytecodeGenerator *bytecodeGenerator = nullptr;
bool _strictMode;
bool useFastLookups = true;
bool requiresReturnValue = false;
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index d889e634c0..cc11b250f3 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -65,6 +65,9 @@
#include <QCryptographicHash>
#include <QSaveFile>
+// generated by qmake:
+#include "qml_compile_hash_p.h"
+
#include <algorithm>
#if defined(QT_BUILD_INTERNAL)
@@ -84,8 +87,10 @@ static QString cacheFilePath(const QUrl &url)
{
const QString localSourcePath = QQmlFile::urlToLocalFileOrQrc(url);
const QString localCachePath = localSourcePath + QLatin1Char('c');
+#ifndef Q_OS_ANDROID
if (QFile::exists(localCachePath) || QFileInfo(QFileInfo(localSourcePath).dir().absolutePath()).isWritable())
return localCachePath;
+#endif
QCryptographicHash fileNameHash(QCryptographicHash::Sha1);
fileNameHash.addData(localSourcePath.toUtf8());
QString directory = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/qmlcache/");
@@ -94,7 +99,8 @@ static QString cacheFilePath(const QUrl &url)
}
#endif
-CompilationUnit::CompilationUnit()
+CompilationUnit::CompilationUnit(const Unit *unitData)
+ : data(unitData)
{}
#ifndef V4_BOOTSTRAP
@@ -103,7 +109,7 @@ CompilationUnit::~CompilationUnit()
unlink();
if (data && !(data->flags & QV4::CompiledData::Unit::StaticData))
free(const_cast<Unit *>(data));
- data = 0;
+ data = nullptr;
}
QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
@@ -195,7 +201,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
if (data->indexOfRootFunction != -1)
return runtimeFunctions[data->indexOfRootFunction];
else
- return 0;
+ return nullptr;
}
void CompilationUnit::unlink()
@@ -222,16 +228,16 @@ void CompilationUnit::unlink()
qDeleteAll(resolvedTypes);
resolvedTypes.clear();
- engine = 0;
- qmlEngine = 0;
+ engine = nullptr;
+ qmlEngine = nullptr;
free(runtimeStrings);
- runtimeStrings = 0;
+ runtimeStrings = nullptr;
delete [] runtimeLookups;
- runtimeLookups = 0;
+ runtimeLookups = nullptr;
delete [] runtimeRegularExpressions;
- runtimeRegularExpressions = 0;
+ runtimeRegularExpressions = nullptr;
free(runtimeClasses);
- runtimeClasses = 0;
+ runtimeClasses = nullptr;
qDeleteAll(runtimeFunctions);
runtimeFunctions.clear();
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
@@ -251,11 +257,11 @@ void CompilationUnit::markObjects(QV4::MarkStack *markStack)
}
}
-IdentifierHash<int> CompilationUnit::namedObjectsPerComponent(int componentObjectIndex)
+IdentifierHash CompilationUnit::namedObjectsPerComponent(int componentObjectIndex)
{
auto it = namedObjectsPerComponentCache.find(componentObjectIndex);
if (it == namedObjectsPerComponentCache.end()) {
- IdentifierHash<int> namedObjectCache(engine);
+ IdentifierHash namedObjectCache(engine);
const CompiledData::Object *component = data->objectAt(componentObjectIndex);
const quint32_le *namedObjectIndexPtr = component->namedObjectsInComponentTable();
for (quint32 i = 0; i < component->nNamedObjectsInComponent; ++i, ++namedObjectIndexPtr) {
@@ -354,24 +360,6 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeS
return false;
}
- {
- const QString foundArchitecture = stringAt(data->architectureIndex);
- const QString expectedArchitecture = QSysInfo::buildAbi();
- if (foundArchitecture != expectedArchitecture) {
- *errorString = QString::fromUtf8("Architecture mismatch. Found %1 expected %2").arg(foundArchitecture).arg(expectedArchitecture);
- return false;
- }
- }
-
- {
- const QString foundCodeGenerator = stringAt(data->codeGeneratorIndex);
- const QString expectedCodeGenerator = QStringLiteral("moth"); // ###
- if (foundCodeGenerator != expectedCodeGenerator) {
- *errorString = QString::fromUtf8("Code generator mismatch. Found code generated by %1 but expected %2").arg(foundCodeGenerator).arg(expectedCodeGenerator);
- return false;
- }
- }
-
dataPtrChange.commit();
free(const_cast<Unit*>(oldDataPtr));
backingFile.reset(cacheFile.take());
@@ -465,6 +453,7 @@ Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument)
if (jsUnit->sourceFileIndex == quint32(0) || jsUnit->stringAt(jsUnit->sourceFileIndex) != irDocument->jsModule.fileName) {
ensureWritableUnit();
jsUnit->sourceFileIndex = stringTable.registerString(irDocument->jsModule.fileName);
+ jsUnit->finalUrlIndex = stringTable.registerString(irDocument->jsModule.finalUrl);
}
// Collect signals that have had a change in signature (from onClicked to onClicked(mouse) for example)
@@ -687,7 +676,7 @@ bool qtTypeInherits(const QMetaObject *mo) {
void ResolvedTypeReference::doDynamicTypeCheck()
{
- const QMetaObject *mo = 0;
+ const QMetaObject *mo = nullptr;
if (typePropertyCache)
mo = typePropertyCache->firstCppMetaObject();
else if (type.isValid())
@@ -709,7 +698,7 @@ static QByteArray ownLibraryChecksum()
// the cache files may end up being re-used. To avoid that we also add the checksum of
// the QtQml library.
Dl_info libInfo;
- if (dladdr(reinterpret_cast<const void *>(&ownLibraryChecksum), &libInfo) != 0) {
+ if (dladdr(reinterpret_cast<void *>(&ownLibraryChecksum), &libInfo) != 0) {
QFile library(QFile::decodeName(libInfo.dli_fname));
if (library.open(QIODevice::ReadOnly)) {
QCryptographicHash hash(QCryptographicHash::Md5);
@@ -717,10 +706,8 @@ static QByteArray ownLibraryChecksum()
libraryChecksum = hash.result();
}
}
-#elif defined(QML_COMPILE_HASH)
- libraryChecksum = QByteArray(QT_STRINGIFY(QML_COMPILE_HASH));
#else
- // Not implemented.
+ libraryChecksum = QByteArray(QML_COMPILE_HASH);
#endif
return libraryChecksum;
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index eb115a590a..a1eefe3988 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -72,7 +72,7 @@
QT_BEGIN_NAMESPACE
// Bump this whenever the compiler data structures change in an incompatible way.
-#define QV4_DATA_STRUCTURE_VERSION 0x15
+#define QV4_DATA_STRUCTURE_VERSION 0x17
class QIODevice;
class QQmlPropertyCache;
@@ -691,8 +691,6 @@ struct Unit
char md5Checksum[16]; // checksum of all bytes following this field.
void generateChecksum();
- quint32_le architectureIndex; // string index to QSysInfo::buildAbi()
- quint32_le codeGeneratorIndex;
char dependencyMD5Checksum[16];
enum : unsigned int {
@@ -719,6 +717,7 @@ struct Unit
quint32_le offsetToJSClassTable;
qint32_le indexOfRootFunction;
quint32_le sourceFileIndex;
+ quint32_le finalUrlIndex;
/* QML specific fields */
quint32_le nImports;
@@ -726,6 +725,8 @@ struct Unit
quint32_le nObjects;
quint32_le offsetToObjects;
+ quint32_le padding;
+
const Import *importAt(int idx) const {
return reinterpret_cast<const Import*>((reinterpret_cast<const char *>(this)) + offsetToImports + idx * sizeof(Import));
}
@@ -890,7 +891,7 @@ Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeRegularExpressions) == offs
struct Q_QML_PRIVATE_EXPORT CompilationUnit final : public CompilationUnitBase
{
public:
- CompilationUnit();
+ CompilationUnit(const Unit *unitData = nullptr);
#ifdef V4_BOOTSTRAP
~CompilationUnit() {}
#else
@@ -924,13 +925,28 @@ public:
ExecutionEngine *engine = nullptr;
QQmlEnginePrivate *qmlEngine = nullptr; // only used in QML environment for composite types, not in plain QJSEngine case.
+ // url() and fileName() shall be used to load the actual QML/JS code or to show errors or
+ // warnings about that code. They include any potential URL interceptions and thus represent the
+ // "physical" location of the code.
+ //
+ // finalUrl() and finalUrlString() shall be used to resolve further URLs referred to in the code
+ // They are _not_ intercepted and thus represent the "logical" name for the code.
+
QString fileName() const { return data->stringAt(data->sourceFileIndex); }
+ QString finalUrlString() const { return data->stringAt(data->finalUrlIndex); }
QUrl url() const { if (m_url.isNull) m_url = QUrl(fileName()); return m_url; }
+ QUrl finalUrl() const
+ {
+ if (m_finalUrl.isNull)
+ m_finalUrl = QUrl(finalUrlString());
+ return m_finalUrl;
+ }
QV4::Lookup *runtimeLookups = nullptr;
QV4::InternalClass **runtimeClasses = nullptr;
QVector<QV4::Function *> runtimeFunctions;
mutable QQmlNullableValue<QUrl> m_url;
+ mutable QQmlNullableValue<QUrl> m_finalUrl;
// QML specific fields
QQmlPropertyCacheVector propertyCaches;
@@ -945,8 +961,8 @@ public:
// mapping from component object index (CompiledData::Unit object index that points to component) to identifier hash of named objects
// this is initialized on-demand by QQmlContextData
- QHash<int, IdentifierHash<int>> namedObjectsPerComponentCache;
- IdentifierHash<int> namedObjectsPerComponent(int componentObjectIndex);
+ QHash<int, IdentifierHash> namedObjectsPerComponentCache;
+ IdentifierHash namedObjectsPerComponent(int componentObjectIndex);
void finalizeCompositeType(QQmlEnginePrivate *qmlEngine);
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 96c9307513..f2e1f4a0de 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -222,6 +222,7 @@ int QV4::Compiler::JSUnitGenerator::registerJSClass(int count, CompiledData::JSC
QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorOption option)
{
registerString(module->fileName);
+ registerString(module->finalUrl);
for (Context *f : qAsConst(module->functions)) {
registerString(f->name);
for (int i = 0; i < f->arguments.size(); ++i)
@@ -394,8 +395,6 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
unit.version = QV4_DATA_STRUCTURE_VERSION;
unit.qtVersion = QT_VERSION;
memset(unit.md5Checksum, 0, sizeof(unit.md5Checksum));
- unit.architectureIndex = registerString(module->targetABI.isEmpty() ? QSysInfo::buildAbi() : module->targetABI);
- unit.codeGeneratorIndex = registerString(codeGeneratorName);
memset(unit.dependencyMD5Checksum, 0, sizeof(unit.dependencyMD5Checksum));
quint32 nextOffset = sizeof(CompiledData::Unit);
@@ -448,6 +447,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
}
unit.indexOfRootFunction = -1;
unit.sourceFileIndex = getStringId(module->fileName);
+ unit.finalUrlIndex = getStringId(module->finalUrl);
unit.sourceTimeStamp = module->sourceTimeStamp.isValid() ? module->sourceTimeStamp.toMSecsSinceEpoch() : 0;
unit.nImports = 0;
unit.offsetToImports = 0;
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
index 3db30ea23d..a78a66db52 100644
--- a/src/qml/compiler/qv4compilercontext_p.h
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -92,10 +92,10 @@ struct Module {
QList<Context *> functions;
Context *rootContext;
QString fileName;
+ QString finalUrl;
QDateTime sourceTimeStamp;
uint unitFlags = 0; // flags merged into CompiledData::Unit::flags
bool debugMode = false;
- QString targetABI; // ### seems unused currently
};
@@ -120,7 +120,7 @@ struct Context {
int index = -1;
QQmlJS::AST::VariableDeclaration::VariableScope scope = QQmlJS::AST::VariableDeclaration::FunctionScope;
mutable bool canEscape = false;
- QQmlJS::AST::FunctionExpression *function = 0;
+ QQmlJS::AST::FunctionExpression *function = nullptr;
bool isLexicallyScoped() const { return this->scope != QQmlJS::AST::VariableDeclaration::FunctionScope; }
};
@@ -128,12 +128,12 @@ struct Context {
MemberMap members;
QSet<QString> usedVariables;
- QQmlJS::AST::FormalParameterList *formals = 0;
+ QQmlJS::AST::FormalParameterList *formals = nullptr;
QStringList arguments;
QStringList locals;
QVector<Context *> nestedContexts;
- ControlFlow *controlFlow = 0;
+ ControlFlow *controlFlow = nullptr;
QByteArray code;
QVector<CompiledData::CodeOffsetToLine> lineNumberMapping;
@@ -173,10 +173,10 @@ struct Context {
// Map from meta property index (existence implies dependency) to notify signal index
struct KeyValuePair
{
- quint32 _key;
- quint32 _value;
+ quint32 _key = 0;
+ quint32 _value = 0;
- KeyValuePair(): _key(0), _value(0) {}
+ KeyValuePair() {}
KeyValuePair(quint32 key, quint32 value): _key(key), _value(value) {}
quint32 key() const { return _key; }
@@ -245,7 +245,7 @@ struct Context {
Q_ASSERT(m);
MemberMap::const_iterator it = members.find(name);
if (it == members.end()) {
- *m = 0;
+ *m = nullptr;
return false;
}
*m = &(*it);
@@ -256,7 +256,7 @@ struct Context {
usedVariables.insert(name);
}
- void addLocalVar(const QString &name, MemberType type, QQmlJS::AST::VariableDeclaration::VariableScope scope, QQmlJS::AST::FunctionExpression *function = 0)
+ void addLocalVar(const QString &name, MemberType type, QQmlJS::AST::VariableDeclaration::VariableScope scope, QQmlJS::AST::FunctionExpression *function = nullptr)
{
if (! name.isEmpty()) {
if (type != FunctionDefinition) {
diff --git a/src/qml/compiler/qv4compilercontrolflow_p.h b/src/qml/compiler/qv4compilercontrolflow_p.h
index 13716fe29f..9bda20905a 100644
--- a/src/qml/compiler/qv4compilercontrolflow_p.h
+++ b/src/qml/compiler/qv4compilercontrolflow_p.h
@@ -159,7 +159,7 @@ struct ControlFlow {
virtual Handler getHandler(HandlerType type, const QString &label = QString()) = 0;
BytecodeGenerator::ExceptionHandler *parentExceptionHandler() {
- return parent ? parent->exceptionHandler() : 0;
+ return parent ? parent->exceptionHandler() : nullptr;
}
virtual BytecodeGenerator::ExceptionHandler *exceptionHandler() {
@@ -184,7 +184,7 @@ protected:
QString label;
if (cg->_labelledStatement) {
label = cg->_labelledStatement->label.toString();
- cg->_labelledStatement = 0;
+ cg->_labelledStatement = nullptr;
}
return label;
}
@@ -196,10 +196,10 @@ protected:
struct ControlFlowLoop : public ControlFlow
{
QString loopLabel;
- BytecodeGenerator::Label *breakLabel = 0;
- BytecodeGenerator::Label *continueLabel = 0;
+ BytecodeGenerator::Label *breakLabel = nullptr;
+ BytecodeGenerator::Label *continueLabel = nullptr;
- ControlFlowLoop(Codegen *cg, BytecodeGenerator::Label *breakLabel, BytecodeGenerator::Label *continueLabel = 0)
+ ControlFlowLoop(Codegen *cg, BytecodeGenerator::Label *breakLabel, BytecodeGenerator::Label *continueLabel = nullptr)
: ControlFlow(cg, Loop), loopLabel(ControlFlow::loopLabel()), breakLabel(breakLabel), continueLabel(continueLabel)
{
}
@@ -407,7 +407,7 @@ struct ControlFlowFinally : public ControlFlowUnwind
ControlFlowFinally(Codegen *cg, AST::Finally *finally)
: ControlFlowUnwind(cg, Finally), finally(finally)
{
- Q_ASSERT(finally != 0);
+ Q_ASSERT(finally != nullptr);
generator()->setExceptionHandler(&unwindLabel);
}
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp
index 6a9b064bd8..89f602b409 100644
--- a/src/qml/compiler/qv4compilerscanfunctions.cpp
+++ b/src/qml/compiler/qv4compilerscanfunctions.cpp
@@ -59,7 +59,7 @@ using namespace QQmlJS::AST;
ScanFunctions::ScanFunctions(Codegen *cg, const QString &sourceCode, CompilationMode defaultProgramMode)
: _cg(cg)
, _sourceCode(sourceCode)
- , _context(0)
+ , _context(nullptr)
, _allowFuncDecls(true)
, defaultProgramMode(defaultProgramMode)
{
@@ -130,13 +130,15 @@ void ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc)
}
}
}
-void ScanFunctions::checkForArguments(AST::FormalParameterList *parameters)
+
+bool ScanFunctions::formalsContainName(AST::FormalParameterList *parameters, const QString &name)
{
while (parameters) {
- if (parameters->name == QLatin1String("arguments"))
- _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
+ if (parameters->name == name)
+ return true;
parameters = parameters->next;
}
+ return false;
}
bool ScanFunctions::visit(Program *ast)
@@ -206,7 +208,7 @@ bool ScanFunctions::visit(VariableDeclaration *ast)
return false;
}
QString name = ast->name.toString();
- const Context::Member *m = 0;
+ const Context::Member *m = nullptr;
if (_context->memberInfo(name, &m)) {
if (m->isLexicallyScoped() || ast->isLexicallyScoped()) {
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Identifier %1 has already been declared").arg(name));
@@ -256,7 +258,7 @@ void ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName)
{
if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode"));
- enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : 0);
+ enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : nullptr);
}
void ScanFunctions::endVisit(FunctionExpression *)
@@ -285,7 +287,7 @@ bool ScanFunctions::visit(ObjectLiteral *ast)
bool ScanFunctions::visit(PropertyGetterSetter *ast)
{
TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
- enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/0);
+ enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/nullptr);
return true;
}
@@ -398,9 +400,11 @@ void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete
}
enterEnvironment(ast, FunctionCode);
- checkForArguments(formals);
+ if (formalsContainName(formals, QStringLiteral("arguments")))
+ _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
+
- if (!name.isEmpty())
+ if (!name.isEmpty() && !formalsContainName(formals, name))
_context->addLocalVar(name, Context::ThisFunctionName, QQmlJS::AST::VariableDeclaration::FunctionScope);
_context->formals = formals;
diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h
index 0b898e587d..745e9f8a73 100644
--- a/src/qml/compiler/qv4compilerscanfunctions_p.h
+++ b/src/qml/compiler/qv4compilerscanfunctions_p.h
@@ -88,7 +88,7 @@ public:
void leaveEnvironment();
void enterQmlScope(AST::Node *ast, const QString &name)
- { enterFunction(ast, name, /*formals*/0, /*body*/0, /*expr*/0); }
+ { enterFunction(ast, name, /*formals*/nullptr, /*body*/nullptr, /*expr*/nullptr); }
void enterQmlFunction(AST::FunctionDeclaration *ast)
{ enterFunction(ast, false); }
@@ -100,7 +100,7 @@ protected:
void checkDirectivePrologue(AST::SourceElements *ast);
void checkName(const QStringRef &name, const AST::SourceLocation &loc);
- void checkForArguments(AST::FormalParameterList *parameters);
+ bool formalsContainName(AST::FormalParameterList *parameters, const QString &name);
bool visit(AST::Program *ast) override;
void endVisit(AST::Program *) override;
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index fbc6902f3d..34953d52ce 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -369,6 +369,14 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << index << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(CallGlobalLookup)
+ MOTH_BEGIN_INSTR(CallScopeObjectProperty)
+ d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallScopeObjectProperty)
+
+ MOTH_BEGIN_INSTR(CallContextObjectProperty)
+ d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallContextObjectProperty)
+
MOTH_BEGIN_INSTR(SetExceptionHandler)
if (offset)
d << ABSOLUTE_OFFSET();
@@ -616,10 +624,8 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_BEGIN_INSTR(Ret)
MOTH_END_INSTR(Ret)
-#ifndef QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(Debug)
MOTH_END_INSTR(Debug)
-#endif // QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(LoadQmlContext)
d << dumpRegister(result, nFormals);
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 0c1b5e240c..2d1428bd19 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -54,19 +54,8 @@
#include <private/qv4value_p.h>
#include <private/qv4runtime_p.h>
-#if !defined(V4_BOOTSTRAP)
-QT_REQUIRE_CONFIG(qml_interpreter);
-#endif
-
QT_BEGIN_NAMESPACE
-#if !QT_CONFIG(qml_debug)
-#define MOTH_DEBUG_INSTR(F)
-#else
-#define MOTH_DEBUG_INSTR(F) \
- F(Debug)
-#endif
-
#define INSTRUCTION(op, name, nargs, ...) \
op##_INSTRUCTION(name, nargs, __VA_ARGS__)
@@ -116,6 +105,8 @@ QT_BEGIN_NAMESPACE
#define INSTR_CallName(op) INSTRUCTION(op, CallName, 3, name, argc, argv)
#define INSTR_CallPossiblyDirectEval(op) INSTRUCTION(op, CallPossiblyDirectEval, 2, argc, argv)
#define INSTR_CallGlobalLookup(op) INSTRUCTION(op, CallGlobalLookup, 3, index, argc, argv)
+#define INSTR_CallScopeObjectProperty(op) INSTRUCTION(op, CallScopeObjectProperty, 4, name, base, argc, argv)
+#define INSTR_CallContextObjectProperty(op) INSTRUCTION(op, CallContextObjectProperty, 4, name, base, argc, argv)
#define INSTR_SetExceptionHandler(op) INSTRUCTION(op, SetExceptionHandler, 1, offset)
#define INSTR_ThrowException(op) INSTRUCTION(op, ThrowException, 0)
#define INSTR_GetException(op) INSTRUCTION(op, GetException, 0)
@@ -232,6 +223,8 @@ QT_BEGIN_NAMESPACE
F(CallName) \
F(CallPossiblyDirectEval) \
F(CallGlobalLookup) \
+ F(CallScopeObjectProperty) \
+ F(CallContextObjectProperty) \
F(SetExceptionHandler) \
F(ThrowException) \
F(GetException) \
@@ -301,7 +294,10 @@ QT_BEGIN_NAMESPACE
F(LoadQmlSingleton)
#define MOTH_NUM_INSTRUCTIONS() (static_cast<int>(Moth::Instr::Type::LoadQmlSingleton) + 1)
-#if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200)
+#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
+// icc before version 1200 doesn't support computed goto, and at least up to version 18.0.0 the
+// current use results in an internal compiler error. We could enable this if/when it gets fixed
+// in a later version.
# define MOTH_COMPUTED_GOTO
#endif
@@ -353,7 +349,7 @@ QT_BEGIN_NAMESPACE
nargs,
#define MOTH_DECODE_ARG(arg, type, nargs, offset) \
- arg = reinterpret_cast<const type *>(code)[-nargs + offset];
+ arg = qFromLittleEndian<type>(reinterpret_cast<const type *>(code)[-nargs + offset]);
#define MOTH_ADJUST_CODE(type, nargs) \
code += static_cast<quintptr>(nargs*sizeof(type) + 1)
@@ -363,9 +359,9 @@ QT_BEGIN_NAMESPACE
MOTH_ADJUST_CODE(int, nargs); \
MOTH_DECODE_ARGS(name, int, nargs, __VA_ARGS__) \
goto op_main_##name; \
- op_char_##name: \
- MOTH_ADJUST_CODE(char, nargs); \
- MOTH_DECODE_ARGS(name, char, nargs, __VA_ARGS__) \
+ op_byte_##name: \
+ MOTH_ADJUST_CODE(qint8, nargs); \
+ MOTH_DECODE_ARGS(name, qint8, nargs, __VA_ARGS__) \
op_main_##name: \
; \
@@ -377,10 +373,10 @@ QT_BEGIN_NAMESPACE
MOTH_ADJUST_CODE(int, nargs); \
MOTH_DECODE_ARGS(name, int, nargs, __VA_ARGS__) \
goto op_main_##name; \
- op_char_##name: \
+ op_byte_##name: \
base_ptr = code; \
- MOTH_ADJUST_CODE(char, nargs); \
- MOTH_DECODE_ARGS(name, char, nargs, __VA_ARGS__) \
+ MOTH_ADJUST_CODE(qint8, nargs); \
+ MOTH_DECODE_ARGS(name, qint8, nargs, __VA_ARGS__) \
op_main_##name: \
; \
@@ -405,7 +401,7 @@ QT_BEGIN_NAMESPACE
#define COLLECT_LABELS(instr) \
INSTR_##instr(GET_LABEL)
#define GET_LABEL_INSTRUCTION(name, ...) \
- &&op_char_##name,
+ &&op_byte_##name,
#define COLLECT_LABELS_WIDE(instr) \
INSTR_##instr(GET_LABEL_WIDE)
#define GET_LABEL_WIDE_INSTRUCTION(name, ...) \
@@ -425,7 +421,7 @@ QT_BEGIN_NAMESPACE
#define MOTH_INSTR_CASE_AND_JUMP(instr) \
INSTR_##instr(GET_CASE_AND_JUMP)
#define GET_CASE_AND_JUMP_INSTRUCTION(name, ...) \
- case static_cast<uchar>(Instr::Type::name): goto op_char_##name;
+ case static_cast<uchar>(Instr::Type::name): goto op_byte_##name;
#define MOTH_INSTR_CASE_AND_JUMP_WIDE(instr) \
INSTR_##instr(GET_CASE_AND_JUMP_WIDE)
#define GET_CASE_AND_JUMP_WIDE_INSTRUCTION(name, ...) \
@@ -483,6 +479,8 @@ union Instr
FOR_EACH_MOTH_INSTR(MOTH_EMIT_STRUCTS)
FOR_EACH_MOTH_INSTR(MOTH_EMIT_INSTR_MEMBERS)
+
+ int argumentsAsInts[4];
};
struct InstrInfo
diff --git a/src/qml/configure.json b/src/qml/configure.json
index a589e9f950..b744ea6948 100644
--- a/src/qml/configure.json
+++ b/src/qml/configure.json
@@ -7,23 +7,17 @@
"commandline": {
"options": {
- "qml-interpreter": "boolean",
"qml-network": "boolean",
"qml-debug": "boolean"
}
},
"features": {
- "qml-interpreter": {
- "label": "QML interpreter",
- "purpose": "Provides the QML interpreter.",
- "section": "QML",
- "output": [ "privateFeature" ]
- },
"qml-network": {
"label": "QML network support",
"purpose": "Provides network transparency.",
"section": "QML",
+ "condition": "features.network",
"output": [ "publicFeature" ]
},
"qml-debug": {
@@ -52,7 +46,6 @@
{
"section": "Qt QML",
"entries": [
- "qml-interpreter",
"qml-network",
"qml-debug"
]
diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h
index 5d1b339324..c63e694c7e 100644
--- a/src/qml/debugger/qqmlabstractprofileradapter_p.h
+++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h
@@ -68,9 +68,9 @@ class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public
public:
static const int s_numMessagesPerBatch = 1000;
- QQmlAbstractProfilerAdapter(QObject *parent = 0) :
- QObject(parent), service(0), waiting(true), featuresEnabled(0) {}
- virtual ~QQmlAbstractProfilerAdapter() {}
+ QQmlAbstractProfilerAdapter(QObject *parent = nullptr) :
+ QObject(parent), service(nullptr), waiting(true), featuresEnabled(0) {}
+ ~QQmlAbstractProfilerAdapter() override {}
void setService(QQmlProfilerService *new_service) { service = new_service; }
virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages, bool trackLocations) = 0;
diff --git a/src/qml/debugger/qqmlconfigurabledebugservice_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
index e09d5f779a..96ec46f475 100644
--- a/src/qml/debugger/qqmlconfigurabledebugservice_p.h
+++ b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
@@ -63,7 +63,7 @@ template <class Base>
class QQmlConfigurableDebugService : public Base
{
protected:
- QQmlConfigurableDebugService(float version, QObject *parent = 0) :
+ QQmlConfigurableDebugService(float version, QObject *parent = nullptr) :
Base(version, parent), m_configMutex(QMutex::Recursive)
{
init();
diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp
index 01f74f08be..d9f51ce09f 100644
--- a/src/qml/debugger/qqmldebugconnector.cpp
+++ b/src/qml/debugger/qqmldebugconnector.cpp
@@ -66,7 +66,7 @@ struct QQmlDebugConnectorParams {
QString arguments;
QQmlDebugConnector *instance;
- QQmlDebugConnectorParams() : instance(0)
+ QQmlDebugConnectorParams() : instance(nullptr)
{
if (qApp) {
QCoreApplicationPrivate *appD =
@@ -109,7 +109,7 @@ QQmlDebugConnector *QQmlDebugConnector::instance()
{
QQmlDebugConnectorParams *params = qmlDebugConnectorParams();
if (!params)
- return 0;
+ return nullptr;
if (!QQmlEnginePrivate::qml_debugging_enabled) {
if (!params->arguments.isEmpty()) {
@@ -118,14 +118,14 @@ QQmlDebugConnector *QQmlDebugConnector::instance()
"has not been enabled.").arg(params->arguments);
params->arguments.clear();
}
- return 0;
+ return nullptr;
}
if (!params->instance) {
if (!params->pluginKey.isEmpty()) {
params->instance = loadQQmlDebugConnector(params->pluginKey);
} else if (params->arguments.isEmpty()) {
- return 0; // no explicit class name given and no command line arguments
+ return nullptr; // no explicit class name given and no command line arguments
} else if (params->arguments.startsWith(QLatin1String("connector:"))) {
static const int connectorBegin = int(strlen("connector:"));
@@ -169,7 +169,7 @@ QQmlDebugConnectorFactory::~QQmlDebugConnectorFactory()
params->arguments.clear();
params->services.clear();
delete params->instance;
- params->instance = 0;
+ params->instance = nullptr;
}
}
diff --git a/src/qml/debugger/qqmldebugconnector_p.h b/src/qml/debugger/qqmldebugconnector_p.h
index a2a6f5047d..d1ad90adfd 100644
--- a/src/qml/debugger/qqmldebugconnector_p.h
+++ b/src/qml/debugger/qqmldebugconnector_p.h
@@ -114,7 +114,7 @@ public:
static Service *service()
{
QQmlDebugConnector *inst = instance();
- return inst ? static_cast<Service *>(inst->service(Service::s_key)) : 0;
+ return inst ? static_cast<Service *>(inst->service(Service::s_key)) : nullptr;
}
protected:
@@ -126,7 +126,7 @@ class Q_QML_PRIVATE_EXPORT QQmlDebugConnectorFactory : public QObject {
Q_OBJECT
public:
virtual QQmlDebugConnector *create(const QString &key) = 0;
- ~QQmlDebugConnectorFactory();
+ ~QQmlDebugConnectorFactory() override;
};
#define QQmlDebugConnectorFactory_iid "org.qt-project.Qt.QQmlDebugConnectorFactory"
diff --git a/src/qml/debugger/qqmldebugserverconnection_p.h b/src/qml/debugger/qqmldebugserverconnection_p.h
index 536ad830b4..9c4af4d225 100644
--- a/src/qml/debugger/qqmldebugserverconnection_p.h
+++ b/src/qml/debugger/qqmldebugserverconnection_p.h
@@ -61,7 +61,7 @@ class Q_QML_PRIVATE_EXPORT QQmlDebugServerConnection : public QObject
{
Q_OBJECT
public:
- QQmlDebugServerConnection(QObject *parent = 0) : QObject(parent) {}
+ QQmlDebugServerConnection(QObject *parent = nullptr) : QObject(parent) {}
virtual void setServer(QQmlDebugServer *server) = 0;
virtual bool setPortRange(int portFrom, int portTo, bool block, const QString &hostaddress) = 0;
diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h
index 34bbd631ec..c52ba90a79 100644
--- a/src/qml/debugger/qqmldebugservice_p.h
+++ b/src/qml/debugger/qqmldebugservice_p.h
@@ -69,7 +69,7 @@ class Q_QML_PRIVATE_EXPORT QQmlDebugService : public QObject
Q_DECLARE_PRIVATE(QQmlDebugService)
public:
- ~QQmlDebugService();
+ ~QQmlDebugService() override;
const QString &name() const;
float version() const;
@@ -93,7 +93,7 @@ public:
static QObject *objectForId(int id) { return objectsForIds().value(id); }
protected:
- explicit QQmlDebugService(const QString &, float version, QObject *parent = 0);
+ explicit QQmlDebugService(const QString &, float version, QObject *parent = nullptr);
signals:
void attachedToEngine(QJSEngine *);
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index f17b1a7528..deb4d107d6 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -163,9 +163,8 @@ public:
// be available anymore when we send the data.
struct RefLocation : public Location {
RefLocation()
- : Location(), locationType(MaximumRangeType), sent(false)
+ : Location(), locationType(MaximumRangeType), something(nullptr), sent(false)
{
- function = nullptr;
}
RefLocation(QV4::Function *ref)
@@ -226,6 +225,9 @@ public:
void addref()
{
+ if (isNull())
+ return;
+
switch (locationType) {
case Binding:
function->compilationUnit->addref();
@@ -247,6 +249,9 @@ public:
void release()
{
+ if (isNull())
+ return;
+
switch (locationType) {
case Binding:
function->compilationUnit->release();
@@ -271,12 +276,18 @@ public:
return locationType != MaximumRangeType;
}
+ bool isNull() const
+ {
+ return !something;
+ }
+
RangeType locationType;
union {
QV4::Function *function;
QV4::CompiledData::CompilationUnit *unit;
QQmlBoundSignalExpression *boundSignal;
QQmlDataBlob *blob;
+ void *something;
};
bool sent;
};
@@ -287,17 +298,23 @@ public:
{
// Use the QV4::Function as ID, as that is common among different instances of the same
// component. QQmlBinding is per instance.
- // Add 1 to the ID, to make it different from the IDs the V4 profiler produces. The +1 makes
- // the pointer point into the middle of the QV4::Function. Thus it still points to valid
- // memory but we cannot accidentally create a duplicate key from another object.
- quintptr locationId(id(function) + 1);
+ // Add 1 to the ID, to make it different from the IDs the V4 and signal handling profilers
+ // produce. The +1 makes the pointer point into the middle of the QV4::Function. Thus it
+ // still points to valid memory but we cannot accidentally create a duplicate key from
+ // another object.
+ // If there is no function, use a static but valid address: The profiler itself.
+ quintptr locationId = function ? id(function) + 1 : id(this);
m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
(1 << RangeStart | 1 << RangeLocation), Binding,
locationId));
RefLocation &location = m_locations[locationId];
- if (!location.isValid())
- location = RefLocation(function);
+ if (!location.isValid()) {
+ if (function)
+ location = RefLocation(function);
+ else // Make it valid without actually providing a location
+ location.locationType = Binding;
+ }
}
// Have toByteArrays() construct another RangeData event from the same QString later.
@@ -316,7 +333,12 @@ public:
void startHandlingSignal(QQmlBoundSignalExpression *expression)
{
- quintptr locationId(id(expression));
+ // Use the QV4::Function as ID, as that is common among different instances of the same
+ // component. QQmlBoundSignalExpression is per instance.
+ // Add 2 to the ID, to make it different from the IDs the V4 and binding profilers produce.
+ // The +2 makes the pointer point into the middle of the QV4::Function. Thus it still points
+ // to valid memory but we cannot accidentally create a duplicate key from another object.
+ quintptr locationId(id(expression->function()) + 2);
m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
(1 << RangeStart | 1 << RangeLocation), HandlingSignal,
locationId));
@@ -428,7 +450,7 @@ struct QQmlCompilingProfiler : public QQmlProfilerHelper {
struct QQmlVmeProfiler : public QQmlProfilerDefinitions {
public:
- QQmlVmeProfiler() : profiler(0) {}
+ QQmlVmeProfiler() : profiler(nullptr) {}
void init(QQmlProfiler *p, int maxDepth)
{
@@ -499,7 +521,12 @@ private:
QQmlProfiler *profiler;
};
+#endif // QT_CONFIG(qml_debug)
+
QT_END_NAMESPACE
+
+#if QT_CONFIG(qml_debug)
+
Q_DECLARE_METATYPE(QVector<QQmlProfilerData>)
Q_DECLARE_METATYPE(QQmlProfiler::LocationHash)
diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h
index 91d0376837..f84a2c44e2 100644
--- a/src/qml/debugger/qqmlprofilerdefinitions_p.h
+++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h
@@ -69,6 +69,7 @@ struct QQmlProfilerDefinitions {
PixmapCacheEvent,
SceneGraphFrame,
MemoryAllocation,
+ DebugMessage,
MaximumMessage
};
@@ -161,6 +162,26 @@ struct QQmlProfilerDefinitions {
MaximumInputEventType
};
+
+ static ProfileFeature featureFromRangeType(RangeType range)
+ {
+ switch (range) {
+ case Painting:
+ return ProfilePainting;
+ case Compiling:
+ return ProfileCompiling;
+ case Creating:
+ return ProfileCreating;
+ case Binding:
+ return ProfileBinding;
+ case HandlingSignal:
+ return ProfileHandlingSignal;
+ case Javascript:
+ return ProfileJavaScript;
+ default:
+ return MaximumProfileFeature;
+ }
+ }
};
QT_END_NAMESPACE
diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf
index 74b61fd6e1..6161760471 100644
--- a/src/qml/doc/qtqml.qdocconf
+++ b/src/qml/doc/qtqml.qdocconf
@@ -53,6 +53,8 @@ manifestmeta.thumbnail.names += "QtQml/Chapter 4*" \
"QtQml/Chapter 6*" \
"QtQml/C++ Extensions: *"
+manifestmeta.highlighted.names = "QtQml/Writing QML Extensions with C++"
+
navigation.landingpage = "Qt QML"
navigation.cppclassespage = "Qt QML C++ Classes"
navigation.qmltypespage = "Qt QML QML Types"
diff --git a/src/qml/doc/snippets/code/src_script_qjsengine.cpp b/src/qml/doc/snippets/code/src_script_qjsengine.cpp
index 3799189f83..6c58fd8a18 100644
--- a/src/qml/doc/snippets/code/src_script_qjsengine.cpp
+++ b/src/qml/doc/snippets/code/src_script_qjsengine.cpp
@@ -114,3 +114,23 @@ engine.globalObject().setProperty("myObject", myScriptQObject);
qDebug() << engine.evaluate("myObject.dynamicProperty").toInt();
//! [6]
+
+
+//! [7]
+class MyObject : public QObject
+{
+ Q_OBJECT
+
+public:
+ Q_INVOKABLE MyObject() {}
+};
+//! [7]
+
+//! [8]
+QJSValue jsMetaObject = engine.newQMetaObject(&MyObject::staticMetaObject);
+engine.globalObject().setProperty("MyObject", jsMetaObject);
+//! [8]
+
+//! [9]
+engine.evaluate("var myObject = new MyObject()");
+//! [9]
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index afc76ce31d..027e4b9923 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -620,7 +620,7 @@ signals:
private slots:
void updateProperty() {
- m_targetProperty.write(QRandomGenerator::bounded(m_maxValue));
+ m_targetProperty.write(QRandomGenerator::global()->bounded(m_maxValue));
}
private:
diff --git a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc
index 4dc32e3588..7c2ff703c6 100644
--- a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc
+++ b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc
@@ -114,17 +114,7 @@ multiple children with the same \c objectName. In this case,
QObject::findChildren() can be used to find all children with a matching
\c objectName.
-\warning While it is possible to use C++ to access and manipulate QML objects
-deep into the object tree, we recommend that you do not take this approach
-outside of application testing and prototyping. One strength of QML and C++
-integration is the ability to implement the QML user interface separately
-from the C++ logic and dataset backend, and this strategy breaks if the C++
-side reaches deep into the QML components to manipulate them directly. This
-would make it difficult to, for example, swap a QML view component for
-another view, if the new component was missing a required \c objectName. It
-is better for the C++ implementation to know as little as possible about the
-QML user interface implementation and the composition of the QML object tree.
-
+\include warning.qdocinc
\section1 Accessing Members of a QML Object Type from C++
diff --git a/src/qml/doc/src/cppintegration/topic.qdoc b/src/qml/doc/src/cppintegration/topic.qdoc
index da06c195dc..6b6e308edf 100644
--- a/src/qml/doc/src/cppintegration/topic.qdoc
+++ b/src/qml/doc/src/cppintegration/topic.qdoc
@@ -190,6 +190,8 @@ invoke their methods and receive their signal notifications. This is possible du
all QML object types are implemented using QObject-derived classes, enabling the QML engine to
dynamically load and introspect objects through the Qt meta object system.
+\include warning.qdocinc
+
For more information on accessing QML objects from C++, see the documentation on
\l{qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++}.
diff --git a/src/qml/doc/src/cppintegration/warning.qdocinc b/src/qml/doc/src/cppintegration/warning.qdocinc
new file mode 100644
index 0000000000..a5da22b2a7
--- /dev/null
+++ b/src/qml/doc/src/cppintegration/warning.qdocinc
@@ -0,0 +1,6 @@
+\warning Although it is possible to access QML objects from C++ and manipulate
+them, it is not the recommended approach, except for testing and prototyping
+purposes. One of the strengths of QML and C++ integration is the ability to
+implement UIs in QML separate from the C++ logic and dataset backend, and this
+fails if the C++ side starts manipulating QML directly. Such an approach also
+makes changing the QML UI difficult without affecting its C++ counterpart.
diff --git a/src/qml/doc/src/includes/qqmlcomponent.qdoc b/src/qml/doc/src/includes/qqmlcomponent.qdoc
new file mode 100644
index 0000000000..6949d8823a
--- /dev/null
+++ b/src/qml/doc/src/includes/qqmlcomponent.qdoc
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [url-note]
+Ensure that the URL provided is full and correct, in particular, use
+\l QUrl::fromLocalFile() when loading a file from the local filesystem.
+
+Relative paths will be resolved against
+\l {QQmlEngine::baseUrl}{QQmlEngine::baseUrl()}, which is the current working directory
+unless specified.
+//! [url-note]
diff --git a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
index 0471d7db9b..be4db4c917 100644
--- a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
+++ b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
@@ -157,7 +157,7 @@ to inside the string literals.
When managing dynamically created objects, you must ensure the creation context
outlives the created object. Otherwise, if the creation context is destroyed
-first, the bindings in the dynamic object will no longer work.
+first, the bindings and signal handlers in the dynamic object will no longer work.
The actual creation context depends on how an object is created:
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 8a62a18eec..ede213b84a 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -324,6 +324,19 @@
qmlRegisterSingletonType("Qt.example.qjsvalueApi", 1, 0, "MyApi", example_qjsvalue_singletontype_provider);
\endcode
+ Alternatively, you can use a C++11 lambda:
+
+ \code
+ qmlRegisterSingletonType("Qt.example.qjsvalueApi", 1, 0, "MyApi", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QJSValue {
+ Q_UNUSED(engine)
+
+ static int seedValue = 5;
+ QJSValue example = scriptEngine->newObject();
+ example.setProperty("someProperty", seedValue++);
+ return example;
+ });
+ \endcode
+
In order to use the registered singleton type in QML, you must import the singleton type.
\qml
import QtQuick 2.0
@@ -336,7 +349,7 @@
*/
/*!
- \fn Object *qmlAttachedPropertiesObject(const QObject *attachee, bool create = true)
+ \fn template<typename T> QObject *qmlAttachedPropertiesObject(const QObject *attachee, bool create = true)
\relates QQmlEngine
The form of this template function is:
@@ -423,6 +436,18 @@
qmlRegisterSingletonType<SingletonTypeExample>("Qt.example.qobjectSingleton", 1, 0, "MyApi", example_qobject_singletontype_provider);
\endcode
+ Alternatively, you can use a C++11 lambda:
+
+ \code
+ qmlRegisterSingletonType<SingletonTypeExample>("Qt.example.qjsvalueApi", 1, 0, "MyApi", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
+ Q_UNUSED(engine)
+ Q_UNUSED(scriptEngine)
+
+ SingletonTypeExample *example = new SingletonTypeExample();
+ return example;
+ });
+ \endcode
+
In order to use the registered singleton type in QML, you must import the singleton type.
\qml
import QtQuick 2.0
diff --git a/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc b/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc
index 1b645a94c0..9eb8f72cf2 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/basics.qdoc
@@ -38,6 +38,8 @@ imperative code, in the case where complex custom application behavior is needed
QML source code is generally loaded by the engine through QML \e documents, which are
standalone documents of QML code. These can be used to define \l {QML Object Types}{QML object types} that can then be reused throughout an application.
+Note that type names must begin with an uppercase letter in order
+to be declared as QML object types in a QML file.
\section1 Import Statements
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index 207fb53ca0..31650db7c0 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -449,13 +449,38 @@ right-hand-side of the property declaration must be a valid alias reference:
[default] property alias <name>: <alias reference>
\endcode
-Unlike an ordinary property, an alias can only refer to an object, or the
-property of an object, that is within the scope of the \l{QML Object Types}
-{type} within which the alias is declared. It cannot contain arbitrary
-JavaScript expressions and it cannot refer to objects declared outside of
-the scope of its type. Also note the \e {alias reference} is not optional,
-unlike the optional default value for an ordinary property; the alias reference
-must be provided when the alias is first declared.
+Unlike an ordinary property, an alias has the following restrictions:
+
+\list
+\li It can only refer to an object, or the
+ property of an object, that is within the scope of the \l{QML Object Types}
+ {type} within which the alias is declared.
+\li It cannot contain arbitrary
+ JavaScript expressions
+\li It cannot refer to objects declared outside of
+ the scope of its type.
+\li The \e {alias reference} is not optional,
+ unlike the optional default value for an ordinary property; the alias reference
+ must be provided when the alias is first declared.
+\li It cannot refer to grouped properties; the following code will not work:
+ \code
+ property alias color: rectangle.border.color
+
+ Rectangle {
+ id: rectangle
+ }
+ \endcode
+
+ However, aliases to \l {QML Basic Types}{value type} properties do work:
+ \code
+ property alias rectX: object.rectProperty.x
+
+ Item {
+ id: object
+ property rect rectProperty
+ }
+ \endcode
+\endlist
For example, below is a \c Button type with a \c buttonText aliased property
which is connected to the \c text object of the \l Text child:
diff --git a/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc
index b74646b7d0..5f089b5ebc 100644
--- a/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/typesystem/objecttypes.qdoc
@@ -45,6 +45,8 @@ type, as discussed in \l {qtqml-documents-definetypes.html}
{Documents as QML object type definitions}, or by defining a QML type from C++
and registering the type with the QML engine, as discussed in
\l{qtqml-cppintegration-definetypes.html}{Defining QML Types from C++}.
+Note that in both cases, the type name must begin with an uppercase letter in
+order to be declared as a QML object type in a QML file.
\section1 Defining Object Types from QML
diff --git a/src/qml/doc/src/qtqml.qdoc b/src/qml/doc/src/qtqml.qdoc
index 833436a67c..a9f8e2a960 100644
--- a/src/qml/doc/src/qtqml.qdoc
+++ b/src/qml/doc/src/qtqml.qdoc
@@ -134,12 +134,13 @@ the QML code to interact with C++ code.
\section1 Licenses and Attributions
Qt QML is available under commercial licenses from \l{The Qt Company}.
-In addition, it is available under the
+In addition, it is available under free software licenses. Since Qt 5.4,
+these free software licenses are
\l{GNU Lesser General Public License, version 3}, or
the \l{GNU General Public License, version 2}.
See \l{Qt Licensing} for further details.
-Furthermore Qt QML potentially contains third party
+Furthermore Qt QML in Qt \QtVersion may contain third party
modules under following permissive licenses:
\generatelist{groupsbymodule attributions-qtqml}
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index b0470ed89d..186e5952da 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -52,15 +52,6 @@
#undef ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES
-#ifdef Q_STATIC_ASSERT_FOR_SANE_COMPILERS
-# undef Q_STATIC_ASSERT_FOR_SANE_COMPILERS
-#endif
-#if defined(Q_CC_MSVC) && _MSC_VER < 1900
-# define Q_STATIC_ASSERT_FOR_SANE_COMPILERS(x) // insane
-#else
-# define Q_STATIC_ASSERT_FOR_SANE_COMPILERS(x) Q_STATIC_ASSERT(x)
-#endif
-
#ifdef V4_ENABLE_JIT
QT_BEGIN_NAMESPACE
@@ -70,6 +61,7 @@ namespace JIT {
#define callHelper(x) PlatformAssemblerCommon::callRuntime(#x, reinterpret_cast<void *>(&x))
const QV4::Value::ValueTypeInternal IntegerTag = QV4::Value::ValueTypeInternal::Integer;
+const int IsIntegerConvertible_Shift = QV4::Value::IsIntegerConvertible_Shift;
static ReturnedValue toNumberHelper(ReturnedValue v)
{
@@ -89,6 +81,7 @@ struct PlatformAssembler_X86_64_SysV : JSC::MacroAssembler<JSC::MacroAssemblerX8
static const RegisterID NoRegister = RegisterID(-1);
static const RegisterID ReturnValueRegister = RegisterID::eax;
+ static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
static const RegisterID AccumulatorRegister = RegisterID::eax;
static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
static const RegisterID ScratchRegister = RegisterID::r10;
@@ -125,7 +118,6 @@ struct PlatformAssembler_X86_64_SysV : JSC::MacroAssembler<JSC::MacroAssemblerX8
push(EngineRegister);
move(Arg0Reg, CppStackFrameRegister);
move(Arg1Reg, EngineRegister);
- loadPtr(Address(CppStackFrameRegister, offsetof(CppStackFrame, jsFrame)), JSStackFrameRegister);
}
void generatePlatformFunctionExit()
@@ -167,6 +159,7 @@ struct PlatformAssembler_Win64 : JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
static const RegisterID NoRegister = RegisterID(-1);
static const RegisterID ReturnValueRegister = RegisterID::eax;
+ static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
static const RegisterID AccumulatorRegister = RegisterID::eax;
static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
static const RegisterID ScratchRegister = RegisterID::r10;
@@ -203,7 +196,6 @@ struct PlatformAssembler_Win64 : JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
push(EngineRegister);
move(Arg0Reg, CppStackFrameRegister);
move(Arg1Reg, EngineRegister);
- loadPtr(Address(CppStackFrameRegister, offsetof(CppStackFrame, jsFrame)), JSStackFrameRegister);
}
void generatePlatformFunctionExit()
@@ -285,7 +277,6 @@ struct PlatformAssembler_X86_All : JSC::MacroAssembler<JSC::MacroAssemblerX86>
push(EngineRegister);
loadPtr(Address(FramePointerRegister, 2 * PointerSize), CppStackFrameRegister);
loadPtr(Address(FramePointerRegister, 3 * PointerSize), EngineRegister);
- loadPtr(Address(CppStackFrameRegister, offsetof(CppStackFrame, jsFrame)), JSStackFrameRegister);
}
void generatePlatformFunctionExit()
@@ -328,6 +319,7 @@ struct PlatformAssembler_ARM64 : JSC::MacroAssembler<JSC::MacroAssemblerARM64>
static const RegisterID NoRegister = RegisterID(-1);
static const RegisterID ReturnValueRegister = JSC::ARM64Registers::x0;
+ static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
static const RegisterID AccumulatorRegister = JSC::ARM64Registers::x9;
static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
static const RegisterID ScratchRegister = JSC::ARM64Registers::x10;
@@ -639,7 +631,12 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
{
PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
if (dest == Assembler::ResultInAccumulator)
- move(ReturnValueRegister, AccumulatorRegister);
+ saveReturnValueInAccumulator();
+ }
+
+ void saveReturnValueInAccumulator()
+ {
+ move(ReturnValueRegister, AccumulatorRegister);
}
void loadUndefined(RegisterID dest = AccumulatorRegister)
@@ -689,6 +686,11 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
move(TrustedImm64(value), AccumulatorRegister);
}
+ void storeHeapObject(RegisterID source, Address addr)
+ {
+ store64(source, addr);
+ }
+
void generateCatchTrampoline()
{
PlatformAssemblerCommon::generateCatchTrampoline([this](){loadUndefined();});
@@ -715,25 +717,66 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
void toNumber()
{
+ urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister);
+ auto isNumber = branch32(GreaterThanOrEqual, ScratchRegister, TrustedImm32(Value::QT_Int));
+
move(AccumulatorRegister, registerForArg(0));
callHelper(toNumberHelper);
- move(ReturnValueRegister, AccumulatorRegister);
+ saveReturnValueInAccumulator();
+
+ isNumber.link(this);
+ }
+
+ void toInt32LhsAcc(Address lhs, RegisterID lhsTarget)
+ {
+ load64(lhs, lhsTarget);
+ urshift64(lhsTarget, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto lhsIsInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
+
+ pushAligned(AccumulatorRegister);
+ move(lhsTarget, registerForArg(0));
+ callHelper(toInt32Helper);
+ move(ReturnValueRegister, lhsTarget);
+ popAligned(AccumulatorRegister);
+
+ lhsIsInt.link(this);
+ urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
+
+ pushAligned(lhsTarget);
+ move(AccumulatorRegister, registerForArg(0));
+ callHelper(toInt32Helper);
+ saveReturnValueInAccumulator();
+ popAligned(lhsTarget);
+
+ isInt.link(this);
}
void toInt32()
{
+ urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
+
move(AccumulatorRegister, registerForArg(0));
callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
Assembler::ResultInAccumulator);
+
+ isInt.link(this);
}
void regToInt32(Address srcReg, RegisterID targetReg)
{
+ load64(srcReg, targetReg);
+ urshift64(targetReg, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
+
pushAligned(AccumulatorRegister);
- load64(srcReg, registerForArg(0));
+ move(targetReg, registerForArg(0));
callHelper(toInt32Helper);
move(ReturnValueRegister, targetReg);
popAligned(AccumulatorRegister);
+
+ isInt.link(this);
}
void isNullOrUndefined()
@@ -750,6 +793,12 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
isUndef.link(this);
}
+ Jump isIntOrBool()
+ {
+ urshift64(AccumulatorRegister, TrustedImm32(Value::IsIntegerOrBool_Shift), ScratchRegister);
+ return branch32(Equal, TrustedImm32(3), ScratchRegister);
+ }
+
void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
{
Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
@@ -819,8 +868,8 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
Jump unopIntPath(std::function<Jump(void)> fastPath)
{
- urshift64(AccumulatorRegister, TrustedImm32(32), ScratchRegister);
- Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister);
+ urshift64(AccumulatorRegister, TrustedImm32(IsIntegerConvertible_Shift), ScratchRegister);
+ Jump accNotIntConvertible = branch32(NotEqual, TrustedImm32(1), ScratchRegister);
// both integer
Jump failure = fastPath();
@@ -829,10 +878,16 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
// all other cases
if (failure.isSet())
failure.link(this);
- accNotInt.link(this);
+ accNotIntConvertible.link(this);
return done;
}
+
+ void callWithAccumulatorByValueAsFirstArgument(std::function<void()> doCall)
+ {
+ passAsArg(AccumulatorRegister, 0);
+ doCall();
+ }
};
typedef PlatformAssembler64 PlatformAssembler;
@@ -845,10 +900,14 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
Assembler::CallResultDestination dest)
{
PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
- if (dest == Assembler::ResultInAccumulator) {
- move(ReturnValueRegisterValue, AccumulatorRegisterValue);
- move(ReturnValueRegisterTag, AccumulatorRegisterTag);
- }
+ if (dest == Assembler::ResultInAccumulator)
+ saveReturnValueInAccumulator();
+ }
+
+ void saveReturnValueInAccumulator()
+ {
+ move(ReturnValueRegisterValue, AccumulatorRegisterValue);
+ move(ReturnValueRegisterTag, AccumulatorRegisterTag);
}
void loadUndefined()
@@ -909,6 +968,14 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
move(TrustedImm32(Value::fromReturnedValue(value).tag()), AccumulatorRegisterTag);
}
+ void storeHeapObject(RegisterID source, Address addr)
+ {
+ store32(source, addr);
+ addr.offset += 4;
+ store32(TrustedImm32(0), addr);
+ }
+
+
void generateCatchTrampoline()
{
PlatformAssemblerCommon::generateCatchTrampoline([this](){loadUndefined();});
@@ -916,6 +983,9 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
void toNumber()
{
+ urshift32(AccumulatorRegisterTag, TrustedImm32(Value::QuickType_Shift - 32), ScratchRegister);
+ auto isNumber = branch32(GreaterThanOrEqual, ScratchRegister, TrustedImm32(Value::QT_Int));
+
if (ArgInRegCount < 2) {
push(AccumulatorRegisterTag);
push(AccumulatorRegisterValue);
@@ -925,14 +995,71 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
}
callRuntime("toNumberHelper", reinterpret_cast<void *>(&toNumberHelper),
Assembler::ResultInAccumulator);
- move(ReturnValueRegisterValue, AccumulatorRegisterValue);
- move(ReturnValueRegisterTag, AccumulatorRegisterTag);
+ saveReturnValueInAccumulator();
if (ArgInRegCount < 2)
addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+
+ isNumber.link(this);
+ }
+
+ void toInt32LhsAcc(Address lhs, RegisterID lhsTarget)
+ {
+ bool accumulatorNeedsSaving = AccumulatorRegisterValue == ReturnValueRegisterValue
+ || AccumulatorRegisterTag == ReturnValueRegisterTag;
+ lhs.offset += 4;
+ load32(lhs, lhsTarget);
+ lhs.offset -= 4;
+ auto lhsIsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), lhsTarget);
+ load32(lhs, lhsTarget);
+ auto lhsIsInt = jump();
+
+ lhsIsNotInt.link(this);
+ if (accumulatorNeedsSaving) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ }
+ if (ArgInRegCount < 2) {
+ push(lhsTarget);
+ load32(lhs, lhsTarget);
+ push(lhsTarget);
+ } else {
+ move(lhsTarget, registerForArg(1));
+ load32(lhs, registerForArg(0));
+ }
+ callHelper(toInt32Helper);
+ move(ReturnValueRegisterValue, lhsTarget);
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ if (accumulatorNeedsSaving) {
+ pop(AccumulatorRegisterValue);
+ pop(AccumulatorRegisterTag);
+ }
+ lhsIsInt.link(this);
+
+ auto rhsIsInt = branch32(Equal, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag);
+
+ pushAligned(lhsTarget);
+ if (ArgInRegCount < 2) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ } else {
+ move(AccumulatorRegisterValue, registerForArg(0));
+ move(AccumulatorRegisterTag, registerForArg(1));
+ }
+ callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
+ Assembler::ResultInAccumulator);
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ popAligned(lhsTarget);
+
+ rhsIsInt.link(this);
}
void toInt32()
{
+ urshift32(AccumulatorRegisterTag, TrustedImm32(Value::QuickType_Shift - 32), ScratchRegister);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister);
+
if (ArgInRegCount < 2) {
push(AccumulatorRegisterTag);
push(AccumulatorRegisterValue);
@@ -944,6 +1071,8 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
Assembler::ResultInAccumulator);
if (ArgInRegCount < 2)
addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+
+ isInt.link(this);
}
void regToInt32(Address srcReg, RegisterID targetReg)
@@ -990,6 +1119,12 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
done.link(this);
}
+ Jump isIntOrBool()
+ {
+ urshift32(AccumulatorRegisterTag, TrustedImm32(Value::IsIntegerOrBool_Shift - 32), ScratchRegister);
+ return branch32(Equal, TrustedImm32(3), ScratchRegister);
+ }
+
void pushValue(ReturnedValue v)
{
push(TrustedImm32(v >> 32));
@@ -1123,6 +1258,20 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
return done;
}
+
+ void callWithAccumulatorByValueAsFirstArgument(std::function<void()> doCall)
+ {
+ if (ArgInRegCount < 2) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ } else {
+ move(AccumulatorRegisterValue, registerForArg(0));
+ move(AccumulatorRegisterTag, registerForArg(1));
+ }
+ doCall();
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ }
};
typedef PlatformAssembler32 PlatformAssembler;
@@ -1170,7 +1319,7 @@ class QIODevicePrintStream: public FilePrintStream
public:
explicit QIODevicePrintStream(QIODevice *dest)
- : FilePrintStream(0)
+ : FilePrintStream(nullptr)
, dest(dest)
, buf(4096, '0')
{
@@ -1224,7 +1373,7 @@ void Assembler::link(Function *function)
jumpTarget.jump.linkTo(pasm()->labelsByOffset[jumpTarget.offset], pasm());
JSC::JSGlobalData dummy(function->internalClass->engine->executableAllocator);
- JSC::LinkBuffer<PlatformAssembler::MacroAssembler> linkBuffer(dummy, pasm(), 0);
+ JSC::LinkBuffer<PlatformAssembler::MacroAssembler> linkBuffer(dummy, pasm(), nullptr);
for (const auto &ehTarget : pasm()->ehTargets) {
auto targetLabel = pasm()->labelsByOffset.value(ehTarget.offset);
@@ -1321,6 +1470,11 @@ void Assembler::loadValue(ReturnedValue value)
pasm()->loadValue(value);
}
+void JIT::Assembler::storeHeapObject(int reg)
+{
+ pasm()->storeHeapObject(PlatformAssembler::ReturnValueRegisterValue, regAddr(reg));
+}
+
void Assembler::toNumber()
{
pasm()->toNumber();
@@ -1342,9 +1496,14 @@ void Assembler::ucompl()
pasm()->setAccumulatorTag(IntegerTag);
}
-static ReturnedValue incHelper(const Value &v)
+static ReturnedValue incHelper(const Value v)
{
- return Encode(v.toNumber() + 1.);
+ double d;
+ if (Q_LIKELY(v.isDouble()))
+ d = v.doubleValue();
+ else
+ d = v.toNumberImpl();
+ return Encode(d + 1.);
}
void Assembler::inc()
@@ -1359,19 +1518,24 @@ void Assembler::inc()
});
// slow path:
- saveAccumulatorInFrame();
- prepareCallWithArgCount(1);
- passAccumulatorAsArg(0);
- IN_JIT_GENERATE_RUNTIME_CALL(incHelper, ResultInAccumulator);
+ pasm()->callWithAccumulatorByValueAsFirstArgument([this]() {
+ pasm()->callHelper(incHelper);
+ pasm()->saveReturnValueInAccumulator();
+ });
checkException();
// done.
done.link(pasm());
}
-static ReturnedValue decHelper(const Value &v)
+static ReturnedValue decHelper(const Value v)
{
- return Encode(v.toNumber() - 1.);
+ double d;
+ if (Q_LIKELY(v.isDouble()))
+ d = v.doubleValue();
+ else
+ d = v.toNumberImpl();
+ return Encode(d - 1.);
}
void Assembler::dec()
@@ -1386,10 +1550,10 @@ void Assembler::dec()
});
// slow path:
- saveAccumulatorInFrame();
- prepareCallWithArgCount(1);
- passAccumulatorAsArg(0);
- IN_JIT_GENERATE_RUNTIME_CALL(decHelper, ResultInAccumulator);
+ pasm()->callWithAccumulatorByValueAsFirstArgument([this]() {
+ pasm()->callHelper(decHelper);
+ pasm()->saveReturnValueInAccumulator();
+ });
checkException();
// done.
@@ -1432,10 +1596,7 @@ void Assembler::add(int lhs)
void Assembler::bitAnd(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
- pasm()->regToInt32(lhsAddr, PlatformAssembler::ScratchRegister);
- pasm()->pushAligned(PlatformAssembler::ScratchRegister);
- pasm()->toInt32();
- pasm()->popAligned(PlatformAssembler::ScratchRegister);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
pasm()->and32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
@@ -1443,10 +1604,7 @@ void Assembler::bitAnd(int lhs)
void Assembler::bitOr(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
- pasm()->regToInt32(lhsAddr, PlatformAssembler::ScratchRegister);
- pasm()->pushAligned(PlatformAssembler::ScratchRegister);
- pasm()->toInt32();
- pasm()->popAligned(PlatformAssembler::ScratchRegister);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
pasm()->or32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
@@ -1454,10 +1612,7 @@ void Assembler::bitOr(int lhs)
void Assembler::bitXor(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
- pasm()->regToInt32(lhsAddr, PlatformAssembler::ScratchRegister);
- pasm()->pushAligned(PlatformAssembler::ScratchRegister);
- pasm()->toInt32();
- pasm()->popAligned(PlatformAssembler::ScratchRegister);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
pasm()->xor32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
@@ -1465,13 +1620,10 @@ void Assembler::bitXor(int lhs)
void Assembler::ushr(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
- pasm()->regToInt32(lhsAddr, PlatformAssembler::ScratchRegister);
- pasm()->pushAligned(PlatformAssembler::ScratchRegister);
- pasm()->toInt32();
- pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue,
- PlatformAssembler::ScratchRegister);
- pasm()->popAligned(PlatformAssembler::AccumulatorRegisterValue);
- pasm()->urshift32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
+ pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->urshift32(PlatformAssembler::AccumulatorRegisterValue, PlatformAssembler::ScratchRegister);
+ pasm()->move(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
auto doubleEncode = pasm()->branch32(PlatformAssembler::LessThan,
PlatformAssembler::AccumulatorRegisterValue,
TrustedImm32(0));
@@ -1489,26 +1641,20 @@ void Assembler::ushr(int lhs)
void Assembler::shr(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
- pasm()->regToInt32(lhsAddr, PlatformAssembler::ScratchRegister);
- pasm()->pushAligned(PlatformAssembler::ScratchRegister);
- pasm()->toInt32();
- pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue,
- PlatformAssembler::ScratchRegister);
- pasm()->popAligned(PlatformAssembler::AccumulatorRegisterValue);
- pasm()->rshift32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
+ pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->rshift32(PlatformAssembler::AccumulatorRegisterValue, PlatformAssembler::ScratchRegister);
+ pasm()->move(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
void Assembler::shl(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
- pasm()->regToInt32(lhsAddr, PlatformAssembler::ScratchRegister);
- pasm()->pushAligned(PlatformAssembler::ScratchRegister);
- pasm()->toInt32();
- pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue,
- PlatformAssembler::ScratchRegister);
- pasm()->popAligned(PlatformAssembler::AccumulatorRegisterValue);
- pasm()->lshift32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
+ pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->lshift32(PlatformAssembler::AccumulatorRegisterValue, PlatformAssembler::ScratchRegister);
+ pasm()->move(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
@@ -1537,27 +1683,32 @@ void Assembler::ushrConst(int rhs)
{
rhs &= 0x1f;
pasm()->toInt32();
- if (rhs) // shift with 0 can act weird
+ if (rhs) {
+ // a non zero shift will always give a number encodable as an int
pasm()->urshift32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
- auto doubleEncode = pasm()->branch32(PlatformAssembler::LessThan,
- PlatformAssembler::AccumulatorRegisterValue,
- TrustedImm32(0));
- pasm()->setAccumulatorTag(IntegerTag);
- auto done = pasm()->jump();
+ pasm()->setAccumulatorTag(IntegerTag);
+ } else {
+ // shift with 0 can lead to a negative result
+ auto doubleEncode = pasm()->branch32(PlatformAssembler::LessThan,
+ PlatformAssembler::AccumulatorRegisterValue,
+ TrustedImm32(0));
+ pasm()->setAccumulatorTag(IntegerTag);
+ auto done = pasm()->jump();
- doubleEncode.link(pasm());
- pasm()->convertUInt32ToDouble(PlatformAssembler::AccumulatorRegisterValue,
- PlatformAssembler::FPScratchRegister,
- PlatformAssembler::ScratchRegister);
- pasm()->encodeDoubleIntoAccumulator(PlatformAssembler::FPScratchRegister);
- done.link(pasm());
+ doubleEncode.link(pasm());
+ pasm()->convertUInt32ToDouble(PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::FPScratchRegister,
+ PlatformAssembler::ScratchRegister);
+ pasm()->encodeDoubleIntoAccumulator(PlatformAssembler::FPScratchRegister);
+ done.link(pasm());
+ }
}
void Assembler::shrConst(int rhs)
{
rhs &= 0x1f;
pasm()->toInt32();
- if (rhs) // shift with 0 can act weird
+ if (rhs)
pasm()->rshift32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
@@ -1566,7 +1717,7 @@ void Assembler::shlConst(int rhs)
{
rhs &= 0x1f;
pasm()->toInt32();
- if (rhs) // shift with 0 can act weird
+ if (rhs)
pasm()->lshift32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
@@ -1652,6 +1803,7 @@ void Assembler::cmpneNull()
void Assembler::cmpeqInt(int lhs)
{
+ auto isIntOrBool = pasm()->isIntOrBool();
saveAccumulatorInFrame();
pasm()->pushValueAligned(Encode(lhs));
if (PlatformAssembler::ArgInRegCount < 2)
@@ -1663,10 +1815,18 @@ void Assembler::cmpeqInt(int lhs)
if (PlatformAssembler::ArgInRegCount < 2)
pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
pasm()->popValueAligned();
+ auto done = pasm()->jump();
+ isIntOrBool.link(pasm());
+ pasm()->compare32(PlatformAssembler::Equal, PlatformAssembler::AccumulatorRegisterValue,
+ TrustedImm32(lhs),
+ PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+ done.link(pasm());
}
void Assembler::cmpneInt(int lhs)
{
+ auto isIntOrBool = pasm()->isIntOrBool();
saveAccumulatorInFrame();
pasm()->pushValueAligned(Encode(lhs));
if (PlatformAssembler::ArgInRegCount < 2)
@@ -1678,6 +1838,13 @@ void Assembler::cmpneInt(int lhs)
if (PlatformAssembler::ArgInRegCount < 2)
pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
pasm()->popValueAligned();
+ auto done = pasm()->jump();
+ isIntOrBool.link(pasm());
+ pasm()->compare32(PlatformAssembler::NotEqual, PlatformAssembler::AccumulatorRegisterValue,
+ TrustedImm32(lhs),
+ PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+ done.link(pasm());
}
void Assembler::cmp(int cond, CmpFunc function, const char *functionName, int lhs)
@@ -1956,7 +2123,7 @@ void Assembler::gotoCatchException()
void Assembler::getException()
{
- Q_STATIC_ASSERT_FOR_SANE_COMPILERS(sizeof(QV4::EngineBase::hasException) == 1);
+ Q_STATIC_ASSERT(sizeof(QV4::EngineBase::hasException) == 1);
Address hasExceptionAddr(PlatformAssembler::EngineRegister,
offsetof(EngineBase, hasException));
@@ -1981,7 +2148,7 @@ void Assembler::setException()
pasm()->loadPtr(addr, PlatformAssembler::ScratchRegister);
pasm()->storeAccumulator(Address(PlatformAssembler::ScratchRegister));
addr.offset = offsetof(EngineBase, hasException);
- Q_STATIC_ASSERT_FOR_SANE_COMPILERS(sizeof(QV4::EngineBase::hasException) == 1);
+ Q_STATIC_ASSERT(sizeof(QV4::EngineBase::hasException) == 1);
pasm()->store8(TrustedImm32(1), addr);
}
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 5cd64096b1..37d4232a17 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -95,6 +95,7 @@ public:
void storeLocal(int index, int level = 0);
void loadString(int stringId);
void loadValue(ReturnedValue value);
+ void storeHeapObject(int reg);
// numeric ops
void unot();
diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp
index 42ee1ff5df..5dc98a591a 100644
--- a/src/qml/jit/qv4jit.cpp
+++ b/src/qml/jit/qv4jit.cpp
@@ -548,6 +548,32 @@ void BaselineJIT::generate_CallGlobalLookup(int index, int argc, int argv)
as->checkException();
}
+void BaselineJIT::generate_CallScopeObjectProperty(int propIdx, int base, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(5);
+ as->passInt32AsArg(argc, 4);
+ as->passRegAsArg(argv, 3);
+ as->passInt32AsArg(propIdx, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlScopeObjectProperty, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_CallContextObjectProperty(int propIdx, int base, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(5);
+ as->passInt32AsArg(argc, 4);
+ as->passRegAsArg(argv, 3);
+ as->passInt32AsArg(propIdx, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlContextObjectProperty, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
void BaselineJIT::generate_SetExceptionHandler(int offset)
{
if (offset)
@@ -570,17 +596,12 @@ void BaselineJIT::generate_ThrowException()
void BaselineJIT::generate_GetException() { as->getException(); }
void BaselineJIT::generate_SetException() { as->setException(); }
-static void createCallContextHelper(Value *stack, CppStackFrame *frame)
-{
- stack[CallData::Context] = ExecutionContext::newCallContext(frame);
-}
-
void BaselineJIT::generate_CreateCallContext()
{
- as->prepareCallWithArgCount(2);
- as->passCppFrameAsArg(1);
- as->passRegAsArg(0, 0);
- JIT_GENERATE_RUNTIME_CALL(createCallContextHelper, Assembler::IgnoreResult);
+ as->prepareCallWithArgCount(1);
+ as->passCppFrameAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(ExecutionContext::newCallContext, Assembler::IgnoreResult); // keeps result in return value register
+ as->storeHeapObject(CallData::Context);
}
void BaselineJIT::generate_PushCatchContext(int name, int reg) { as->pushCatchContext(name, reg); }
@@ -951,6 +972,11 @@ void BaselineJIT::collectLabelsInBytecode()
{
MOTH_JUMP_TABLE;
+ const auto addLabel = [&](int offset) {
+ Q_ASSERT(offset >= 0 && offset < static_cast<int>(function->compiledFunction->codeSize));
+ labels.push_back(offset);
+ };
+
const char *code = reinterpret_cast<const char *>(function->codeData);
const char *start = code;
const char *end = code + function->compiledFunction->codeSize;
@@ -1087,8 +1113,14 @@ void BaselineJIT::collectLabelsInBytecode()
MOTH_BEGIN_INSTR(CallGlobalLookup)
MOTH_END_INSTR(CallGlobalLookup)
+ MOTH_BEGIN_INSTR(CallScopeObjectProperty)
+ MOTH_END_INSTR(CallScopeObjectProperty)
+
+ MOTH_BEGIN_INSTR(CallContextObjectProperty)
+ MOTH_END_INSTR(CallContextObjectProperty)
+
MOTH_BEGIN_INSTR(SetExceptionHandler)
- labels.push_back(code - start + offset);
+ addLabel(code - start + offset);
MOTH_END_INSTR(SetExceptionHandler)
MOTH_BEGIN_INSTR(ThrowException)
@@ -1155,15 +1187,15 @@ void BaselineJIT::collectLabelsInBytecode()
MOTH_END_INSTR(Construct)
MOTH_BEGIN_INSTR(Jump)
- labels.push_back(code - start + offset);
+ addLabel(code - start + offset);
MOTH_END_INSTR(Jump)
MOTH_BEGIN_INSTR(JumpTrue)
- labels.push_back(code - start + offset);
+ addLabel(code - start + offset);
MOTH_END_INSTR(JumpTrue)
MOTH_BEGIN_INSTR(JumpFalse)
- labels.push_back(code - start + offset);
+ addLabel(code - start + offset);
MOTH_END_INSTR(JumpFalse)
MOTH_BEGIN_INSTR(CmpEqNull)
@@ -1209,11 +1241,11 @@ void BaselineJIT::collectLabelsInBytecode()
MOTH_END_INSTR(CmpInstanceOf)
MOTH_BEGIN_INSTR(JumpStrictEqualStackSlotInt)
- labels.push_back(code - start + offset);
+ addLabel(code - start + offset);
MOTH_END_INSTR(JumpStrictEqualStackSlotInt)
MOTH_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt)
- labels.push_back(code - start + offset);
+ addLabel(code - start + offset);
MOTH_END_INSTR(JumpStrictNotEqualStackSlotInt)
MOTH_BEGIN_INSTR(UNot)
@@ -1288,10 +1320,8 @@ void BaselineJIT::collectLabelsInBytecode()
MOTH_BEGIN_INSTR(Ret)
MOTH_END_INSTR(Ret)
-#ifndef QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(Debug)
MOTH_END_INSTR(Debug)
-#endif // QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(LoadQmlContext)
MOTH_END_INSTR(LoadQmlContext)
diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h
index c7ec1700c3..c17ab4ff6e 100644
--- a/src/qml/jit/qv4jit_p.h
+++ b/src/qml/jit/qv4jit_p.h
@@ -119,129 +119,131 @@ public:
void generate();
- void generate_Ret() Q_DECL_OVERRIDE;
- void generate_Debug() Q_DECL_OVERRIDE;
- void generate_LoadConst(int index) Q_DECL_OVERRIDE;
- void generate_LoadZero() Q_DECL_OVERRIDE;
- void generate_LoadTrue() Q_DECL_OVERRIDE;
- void generate_LoadFalse() Q_DECL_OVERRIDE;
- void generate_LoadNull() Q_DECL_OVERRIDE;
- void generate_LoadUndefined() Q_DECL_OVERRIDE;
- void generate_LoadInt(int value) Q_DECL_OVERRIDE;
- void generate_MoveConst(int constIndex, int destTemp) Q_DECL_OVERRIDE;
- void generate_LoadReg(int reg) Q_DECL_OVERRIDE;
- void generate_StoreReg(int reg) Q_DECL_OVERRIDE;
- void generate_MoveReg(int srcReg, int destReg) Q_DECL_OVERRIDE;
- void generate_LoadLocal(int index) Q_DECL_OVERRIDE;
- void generate_StoreLocal(int index) Q_DECL_OVERRIDE;
- void generate_LoadScopedLocal(int scope, int index) Q_DECL_OVERRIDE;
- void generate_StoreScopedLocal(int scope, int index) Q_DECL_OVERRIDE;
- void generate_LoadRuntimeString(int stringId) Q_DECL_OVERRIDE;
- void generate_MoveRegExp(int regExpId, int destReg) Q_DECL_OVERRIDE;
- void generate_LoadClosure(int value) Q_DECL_OVERRIDE;
- void generate_LoadName(int name) Q_DECL_OVERRIDE;
- void generate_LoadGlobalLookup(int index) Q_DECL_OVERRIDE;
- void generate_StoreNameSloppy(int name) Q_DECL_OVERRIDE;
- void generate_StoreNameStrict(int name) Q_DECL_OVERRIDE;
- void generate_LoadElement(int base, int index) Q_DECL_OVERRIDE;
- void generate_LoadElementA(int base) Q_DECL_OVERRIDE;
- void generate_StoreElement(int base, int index) Q_DECL_OVERRIDE;
- void generate_LoadProperty(int name, int base) Q_DECL_OVERRIDE;
- void generate_LoadPropertyA(int name) Q_DECL_OVERRIDE;
- void generate_GetLookup(int index, int base) Q_DECL_OVERRIDE;
- void generate_GetLookupA(int index) Q_DECL_OVERRIDE;
- void generate_StoreProperty(int name, int base) Q_DECL_OVERRIDE;
- void generate_SetLookup(int index, int base) Q_DECL_OVERRIDE;
+ void generate_Ret() override;
+ void generate_Debug() override;
+ void generate_LoadConst(int index) override;
+ void generate_LoadZero() override;
+ void generate_LoadTrue() override;
+ void generate_LoadFalse() override;
+ void generate_LoadNull() override;
+ void generate_LoadUndefined() override;
+ void generate_LoadInt(int value) override;
+ void generate_MoveConst(int constIndex, int destTemp) override;
+ void generate_LoadReg(int reg) override;
+ void generate_StoreReg(int reg) override;
+ void generate_MoveReg(int srcReg, int destReg) override;
+ void generate_LoadLocal(int index) override;
+ void generate_StoreLocal(int index) override;
+ void generate_LoadScopedLocal(int scope, int index) override;
+ void generate_StoreScopedLocal(int scope, int index) override;
+ void generate_LoadRuntimeString(int stringId) override;
+ void generate_MoveRegExp(int regExpId, int destReg) override;
+ void generate_LoadClosure(int value) override;
+ void generate_LoadName(int name) override;
+ void generate_LoadGlobalLookup(int index) override;
+ void generate_StoreNameSloppy(int name) override;
+ void generate_StoreNameStrict(int name) override;
+ void generate_LoadElement(int base, int index) override;
+ void generate_LoadElementA(int base) override;
+ void generate_StoreElement(int base, int index) override;
+ void generate_LoadProperty(int name, int base) override;
+ void generate_LoadPropertyA(int name) override;
+ void generate_GetLookup(int index, int base) override;
+ void generate_GetLookupA(int index) override;
+ void generate_StoreProperty(int name, int base) override;
+ void generate_SetLookup(int index, int base) override;
void generate_StoreScopeObjectProperty(int base,
- int propertyIndex) Q_DECL_OVERRIDE;
+ int propertyIndex) override;
void generate_StoreContextObjectProperty(int base,
- int propertyIndex) Q_DECL_OVERRIDE;
+ int propertyIndex) override;
void generate_LoadScopeObjectProperty(int propertyIndex, int base,
- int captureRequired) Q_DECL_OVERRIDE;
+ int captureRequired) override;
void generate_LoadContextObjectProperty(int propertyIndex, int base,
- int captureRequired) Q_DECL_OVERRIDE;
- void generate_LoadIdObject(int index, int base) Q_DECL_OVERRIDE;
- void generate_CallValue(int name, int argc, int argv) Q_DECL_OVERRIDE;
- void generate_CallProperty(int name, int base, int argc, int argv) Q_DECL_OVERRIDE;
- void generate_CallPropertyLookup(int lookupIndex, int base, int argc, int argv) Q_DECL_OVERRIDE;
- void generate_CallElement(int base, int index, int argc, int argv) Q_DECL_OVERRIDE;
- void generate_CallName(int name, int argc, int argv) Q_DECL_OVERRIDE;
- void generate_CallPossiblyDirectEval(int argc, int argv) Q_DECL_OVERRIDE;
- void generate_CallGlobalLookup(int index, int argc, int argv) Q_DECL_OVERRIDE;
- void generate_SetExceptionHandler(int offset) Q_DECL_OVERRIDE;
- void generate_ThrowException() Q_DECL_OVERRIDE;
- void generate_GetException() Q_DECL_OVERRIDE;
- void generate_SetException() Q_DECL_OVERRIDE;
- void generate_CreateCallContext() Q_DECL_OVERRIDE;
- void generate_PushCatchContext(int name, int reg) Q_DECL_OVERRIDE;
- void generate_PushWithContext(int reg) Q_DECL_OVERRIDE;
- void generate_PopContext(int reg) Q_DECL_OVERRIDE;
- void generate_ForeachIteratorObject() Q_DECL_OVERRIDE;
- void generate_ForeachNextPropertyName() Q_DECL_OVERRIDE;
- void generate_DeleteMember(int member, int base) Q_DECL_OVERRIDE;
- void generate_DeleteSubscript(int base, int index) Q_DECL_OVERRIDE;
- void generate_DeleteName(int name) Q_DECL_OVERRIDE;
- void generate_TypeofName(int name) Q_DECL_OVERRIDE;
- void generate_TypeofValue() Q_DECL_OVERRIDE;
- void generate_DeclareVar(int varName, int isDeletable) Q_DECL_OVERRIDE;
- void generate_DefineArray(int argc, int args) Q_DECL_OVERRIDE;
+ int captureRequired) override;
+ void generate_LoadIdObject(int index, int base) override;
+ void generate_CallValue(int name, int argc, int argv) override;
+ void generate_CallProperty(int name, int base, int argc, int argv) override;
+ void generate_CallPropertyLookup(int lookupIndex, int base, int argc, int argv) override;
+ void generate_CallElement(int base, int index, int argc, int argv) override;
+ void generate_CallName(int name, int argc, int argv) override;
+ void generate_CallPossiblyDirectEval(int argc, int argv) override;
+ void generate_CallGlobalLookup(int index, int argc, int argv) override;
+ void generate_CallScopeObjectProperty(int propIdx, int base, int argc, int argv) override;
+ void generate_CallContextObjectProperty(int propIdx, int base, int argc, int argv) override;
+ void generate_SetExceptionHandler(int offset) override;
+ void generate_ThrowException() override;
+ void generate_GetException() override;
+ void generate_SetException() override;
+ void generate_CreateCallContext() override;
+ void generate_PushCatchContext(int name, int reg) override;
+ void generate_PushWithContext(int reg) override;
+ void generate_PopContext(int reg) override;
+ void generate_ForeachIteratorObject() override;
+ void generate_ForeachNextPropertyName() override;
+ void generate_DeleteMember(int member, int base) override;
+ void generate_DeleteSubscript(int base, int index) override;
+ void generate_DeleteName(int name) override;
+ void generate_TypeofName(int name) override;
+ void generate_TypeofValue() override;
+ void generate_DeclareVar(int varName, int isDeletable) override;
+ void generate_DefineArray(int argc, int args) override;
void generate_DefineObjectLiteral(int internalClassId, int arrayValueCount,
int arrayGetterSetterCountAndFlags,
- int args) Q_DECL_OVERRIDE;
- void generate_CreateMappedArgumentsObject() Q_DECL_OVERRIDE;
- void generate_CreateUnmappedArgumentsObject() Q_DECL_OVERRIDE;
- void generate_ConvertThisToObject() Q_DECL_OVERRIDE;
- void generate_Construct(int func, int argc, int argv) Q_DECL_OVERRIDE;
- void generate_Jump(int offset) Q_DECL_OVERRIDE;
- void generate_JumpTrue(int offset) Q_DECL_OVERRIDE;
- void generate_JumpFalse(int offset) Q_DECL_OVERRIDE;
- void generate_CmpEqNull() Q_DECL_OVERRIDE;
- void generate_CmpNeNull() Q_DECL_OVERRIDE;
- void generate_CmpEqInt(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpNeInt(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpEq(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpNe(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpGt(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpGe(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpLt(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpLe(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpStrictEqual(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpStrictNotEqual(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpIn(int lhs) Q_DECL_OVERRIDE;
- void generate_CmpInstanceOf(int lhs) Q_DECL_OVERRIDE;
+ int args) override;
+ void generate_CreateMappedArgumentsObject() override;
+ void generate_CreateUnmappedArgumentsObject() override;
+ void generate_ConvertThisToObject() override;
+ void generate_Construct(int func, int argc, int argv) override;
+ void generate_Jump(int offset) override;
+ void generate_JumpTrue(int offset) override;
+ void generate_JumpFalse(int offset) override;
+ void generate_CmpEqNull() override;
+ void generate_CmpNeNull() override;
+ void generate_CmpEqInt(int lhs) override;
+ void generate_CmpNeInt(int lhs) override;
+ void generate_CmpEq(int lhs) override;
+ void generate_CmpNe(int lhs) override;
+ void generate_CmpGt(int lhs) override;
+ void generate_CmpGe(int lhs) override;
+ void generate_CmpLt(int lhs) override;
+ void generate_CmpLe(int lhs) override;
+ void generate_CmpStrictEqual(int lhs) override;
+ void generate_CmpStrictNotEqual(int lhs) override;
+ void generate_CmpIn(int lhs) override;
+ void generate_CmpInstanceOf(int lhs) override;
void generate_JumpStrictEqualStackSlotInt(int lhs, int rhs,
- int offset) Q_DECL_OVERRIDE;
+ int offset) override;
void generate_JumpStrictNotEqualStackSlotInt(int lhs, int rhs,
- int offset) Q_DECL_OVERRIDE;
- void generate_UNot() Q_DECL_OVERRIDE;
- void generate_UPlus() Q_DECL_OVERRIDE;
- void generate_UMinus() Q_DECL_OVERRIDE;
- void generate_UCompl() Q_DECL_OVERRIDE;
- void generate_Increment() Q_DECL_OVERRIDE;
- void generate_Decrement() Q_DECL_OVERRIDE;
- void generate_Add(int lhs) Q_DECL_OVERRIDE;
- void generate_BitAnd(int lhs) Q_DECL_OVERRIDE;
- void generate_BitOr(int lhs) Q_DECL_OVERRIDE;
- void generate_BitXor(int lhs) Q_DECL_OVERRIDE;
- void generate_UShr(int lhs) Q_DECL_OVERRIDE;
- void generate_Shr(int lhs) Q_DECL_OVERRIDE;
- void generate_Shl(int lhs) Q_DECL_OVERRIDE;
- void generate_BitAndConst(int rhs) Q_DECL_OVERRIDE;
- void generate_BitOrConst(int rhs) Q_DECL_OVERRIDE;
- void generate_BitXorConst(int rhs) Q_DECL_OVERRIDE;
- void generate_UShrConst(int rhs) Q_DECL_OVERRIDE;
- void generate_ShrConst(int rhs) Q_DECL_OVERRIDE;
- void generate_ShlConst(int rhs) Q_DECL_OVERRIDE;
- void generate_Mul(int lhs) Q_DECL_OVERRIDE;
- void generate_Div(int lhs) Q_DECL_OVERRIDE;
- void generate_Mod(int lhs) Q_DECL_OVERRIDE;
- void generate_Sub(int lhs) Q_DECL_OVERRIDE;
- void generate_LoadQmlContext(int result) Q_DECL_OVERRIDE;
- void generate_LoadQmlImportedScripts(int result) Q_DECL_OVERRIDE;
- void generate_LoadQmlSingleton(int name) Q_DECL_OVERRIDE;
+ int offset) override;
+ void generate_UNot() override;
+ void generate_UPlus() override;
+ void generate_UMinus() override;
+ void generate_UCompl() override;
+ void generate_Increment() override;
+ void generate_Decrement() override;
+ void generate_Add(int lhs) override;
+ void generate_BitAnd(int lhs) override;
+ void generate_BitOr(int lhs) override;
+ void generate_BitXor(int lhs) override;
+ void generate_UShr(int lhs) override;
+ void generate_Shr(int lhs) override;
+ void generate_Shl(int lhs) override;
+ void generate_BitAndConst(int rhs) override;
+ void generate_BitOrConst(int rhs) override;
+ void generate_BitXorConst(int rhs) override;
+ void generate_UShrConst(int rhs) override;
+ void generate_ShrConst(int rhs) override;
+ void generate_ShlConst(int rhs) override;
+ void generate_Mul(int lhs) override;
+ void generate_Div(int lhs) override;
+ void generate_Mod(int lhs) override;
+ void generate_Sub(int lhs) override;
+ void generate_LoadQmlContext(int result) override;
+ void generate_LoadQmlImportedScripts(int result) override;
+ void generate_LoadQmlSingleton(int name) override;
- void startInstruction(Moth::Instr::Type instr) Q_DECL_OVERRIDE;
- void endInstruction(Moth::Instr::Type instr) Q_DECL_OVERRIDE;
+ void startInstruction(Moth::Instr::Type instr) override;
+ void endInstruction(Moth::Instr::Type instr) override;
protected:
bool hasLabel() const
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index bca4057fbe..c483af638b 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -166,16 +166,30 @@ Q_DECLARE_METATYPE(QList<int>)
properties of the proxy object. No binding code is needed because it
is done dynamically using the Qt meta object system.
+ \snippet code/src_script_qjsengine.cpp 5
+
Use newQMetaObject() to wrap a QMetaObject; this gives you a
"script representation" of a QObject-based class. newQMetaObject()
returns a proxy script object; enum values of the class are available
as properties of the proxy object.
- Constructors exposed to the meta-object system ( using Q_INVOKABLE ) can be
+ Constructors exposed to the meta-object system (using Q_INVOKABLE) can be
called from the script to create a new QObject instance with
- JavaScriptOwnership.
+ JavaScriptOwnership. For example, given the following class definition:
- \snippet code/src_script_qjsengine.cpp 5
+ \snippet code/src_script_qjsengine.cpp 7
+
+ The \c staticMetaObject for the class can be exposed to JavaScript like so:
+
+ \snippet code/src_script_qjsengine.cpp 8
+
+ Instances of the class can then be created in JavaScript:
+
+ \snippet code/src_script_qjsengine.cpp 9
+
+ \note Currently only classes using the Q_OBJECT macro are supported; it is
+ not possible to expose the \c staticMetaObject of a Q_GADGET class to
+ JavaScript.
\section2 Dynamic QObject Properties
@@ -290,8 +304,9 @@ QJSEngine::QJSEngine()
QJSEngine::QJSEngine(QObject *parent)
: QObject(*new QJSEnginePrivate, parent)
- , d(new QV8Engine(this))
+ , m_v4Engine(new QV4::ExecutionEngine)
{
+ m_v4Engine->v8Engine = new QV8Engine(this, m_v4Engine);
checkForApplicationInstance();
QJSEnginePrivate::addToDebugServer(this);
@@ -302,8 +317,9 @@ QJSEngine::QJSEngine(QObject *parent)
*/
QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
: QObject(dd, parent)
- , d(new QV8Engine(this))
+ , m_v4Engine(new QV4::ExecutionEngine)
{
+ m_v4Engine->v8Engine = new QV8Engine(this, m_v4Engine);
checkForApplicationInstance();
}
@@ -317,11 +333,12 @@ QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
QJSEngine::~QJSEngine()
{
QJSEnginePrivate::removeFromDebugServer(this);
- delete d;
+ delete m_v4Engine->v8Engine;
+ delete m_v4Engine;
}
/*!
- \fn QV8Engine *QJSEngine::handle() const
+ \fn QV4::ExecutionEngine *QJSEngine::handle() const
\internal
*/
@@ -338,7 +355,7 @@ QJSEngine::~QJSEngine()
*/
void QJSEngine::collectGarbage()
{
- d->m_v4Engine->memoryManager->runGC();
+ m_v4Engine->memoryManager->runGC();
}
#if QT_DEPRECATED_SINCE(5, 6)
@@ -395,12 +412,12 @@ void QJSEngine::installTranslatorFunctions(const QJSValue &object)
void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSValue &object)
{
QV4::ExecutionEngine *otherEngine = QJSValuePrivate::engine(&object);
- if (otherEngine && otherEngine != d->m_v4Engine) {
+ if (otherEngine && otherEngine != m_v4Engine) {
qWarning("QJSEngine: Trying to install extensions from a different engine");
return;
}
- QV4::Scope scope(d->m_v4Engine);
+ QV4::Scope scope(m_v4Engine);
QV4::ScopedObject obj(scope);
QV4::Value *val = QJSValuePrivate::getValue(&object);
if (val)
@@ -441,11 +458,11 @@ void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSVal
*/
QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
{
- QV4::ExecutionEngine *v4 = d->m_v4Engine;
+ QV4::ExecutionEngine *v4 = m_v4Engine;
QV4::Scope scope(v4);
QV4::ScopedValue result(scope);
- QV4::Script script(v4->rootContext(), QV4::Compiler::EvalCode, program, fileName, lineNumber);
+ QV4::Script script(v4->rootContext(), QV4::Compiler::GlobalCode, program, fileName, lineNumber);
script.strictMode = false;
if (v4->currentStackFrame)
script.strictMode = v4->currentStackFrame->v4Function->isStrict();
@@ -473,9 +490,9 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
*/
QJSValue QJSEngine::newObject()
{
- QV4::Scope scope(d->m_v4Engine);
- QV4::ScopedValue v(scope, d->m_v4Engine->newObject());
- return QJSValue(d->m_v4Engine, v->asReturnedValue());
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedValue v(scope, m_v4Engine->newObject());
+ return QJSValue(m_v4Engine, v->asReturnedValue());
}
/*!
@@ -485,12 +502,12 @@ QJSValue QJSEngine::newObject()
*/
QJSValue QJSEngine::newArray(uint length)
{
- QV4::Scope scope(d->m_v4Engine);
- QV4::ScopedArrayObject array(scope, d->m_v4Engine->newArrayObject());
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedArrayObject array(scope, m_v4Engine->newArrayObject());
if (length < 0x1000)
array->arrayReserve(length);
array->setArrayLengthUnchecked(length);
- return QJSValue(d->m_v4Engine, array.asReturnedValue());
+ return QJSValue(m_v4Engine, array.asReturnedValue());
}
/*!
@@ -516,7 +533,7 @@ QJSValue QJSEngine::newArray(uint length)
QJSValue QJSEngine::newQObject(QObject *object)
{
Q_D(QJSEngine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(d);
+ QV4::ExecutionEngine *v4 = m_v4Engine;
QV4::Scope scope(v4);
if (object) {
QQmlData *ddata = QQmlData::get(object, true);
@@ -538,24 +555,24 @@ QJSValue QJSEngine::newQObject(QObject *object)
When called as a constructor, a new instance of the class will be created.
Only constructors exposed by Q_INVOKABLE will be visible from the script engine.
- \sa newQObject()
+ \sa newQObject(), {QObject Integration}
*/
QJSValue QJSEngine::newQMetaObject(const QMetaObject* metaObject) {
Q_D(QJSEngine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(d);
+ QV4::ExecutionEngine *v4 = m_v4Engine;
QV4::Scope scope(v4);
QV4::ScopedValue v(scope, QV4::QMetaObjectWrapper::create(v4, metaObject));
return QJSValue(v4, v->asReturnedValue());
}
-/*! \fn QJSValue QJSEngine::newQMetaObject<T>()
+/*! \fn template <typename T> QJSValue QJSEngine::newQMetaObject()
\since 5.8
Creates a JavaScript object that wraps the static QMetaObject associated
with class \c{T}.
- \sa newQObject()
+ \sa newQObject(), {QObject Integration}
*/
@@ -571,10 +588,9 @@ QJSValue QJSEngine::newQMetaObject(const QMetaObject* metaObject) {
*/
QJSValue QJSEngine::globalObject() const
{
- Q_D(const QJSEngine);
- QV4::Scope scope(d->m_v4Engine);
- QV4::ScopedValue v(scope, d->m_v4Engine->globalObject);
- return QJSValue(d->m_v4Engine, v->asReturnedValue());
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedValue v(scope, m_v4Engine->globalObject);
+ return QJSValue(m_v4Engine, v->asReturnedValue());
}
/*!
@@ -583,10 +599,9 @@ QJSValue QJSEngine::globalObject() const
*/
QJSValue QJSEngine::create(int type, const void *ptr)
{
- Q_D(QJSEngine);
- QV4::Scope scope(d->m_v4Engine);
+ QV4::Scope scope(m_v4Engine);
QV4::ScopedValue v(scope, scope.engine->metaTypeToJS(type, ptr));
- return QJSValue(d->m_v4Engine, v->asReturnedValue());
+ return QJSValue(m_v4Engine, v->asReturnedValue());
}
/*!
@@ -709,14 +724,14 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
}
}
-/*! \fn QJSValue QJSEngine::toScriptValue(const T &value)
+/*! \fn template <typename T> QJSValue QJSEngine::toScriptValue(const T &value)
Creates a QJSValue with the given \a value.
\sa fromScriptValue()
*/
-/*! \fn T QJSEngine::fromScriptValue(const QJSValue &value)
+/*! \fn template <typename T> T QJSEngine::fromScriptValue(const QJSValue &value)
Returns the given \a value converted to the template type \c{T}.
@@ -726,7 +741,7 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
QJSEnginePrivate *QJSEnginePrivate::get(QV4::ExecutionEngine *e)
{
- return e->v8Engine->publicEngine()->d_func();
+ return e->jsEngine()->d_func();
}
QJSEnginePrivate::~QJSEnginePrivate()
@@ -768,7 +783,7 @@ QJSEngine *qjsEngine(const QObject *object)
{
QQmlData *data = QQmlData::get(object, false);
if (!data || data->jsWrapper.isNullOrUndefined())
- return 0;
+ return nullptr;
return data->jsWrapper.engine()->jsEngine();
}
diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h
index 913757107f..3ba2b52e89 100644
--- a/src/qml/jsapi/qjsengine.h
+++ b/src/qml/jsapi/qjsengine.h
@@ -52,8 +52,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
-
template <typename T>
inline T qjsvalue_cast(const QJSValue &);
@@ -65,7 +63,7 @@ class Q_QML_EXPORT QJSEngine
public:
QJSEngine();
explicit QJSEngine(QObject *parent);
- virtual ~QJSEngine();
+ ~QJSEngine() override;
QJSValue globalObject() const;
@@ -111,7 +109,7 @@ public:
void installExtensions(Extensions extensions, const QJSValue &object = QJSValue());
- QV8Engine *handle() const { return d; }
+ QV4::ExecutionEngine *handle() const { return m_v4Engine; }
private:
QJSValue create(int type, const void *ptr);
@@ -124,10 +122,9 @@ protected:
QJSEngine(QJSEnginePrivate &dd, QObject *parent = nullptr);
private:
- QV8Engine *d;
+ QV4::ExecutionEngine *m_v4Engine;
Q_DISABLE_COPY(QJSEngine)
Q_DECLARE_PRIVATE(QJSEngine)
- friend class QV8Engine;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QJSEngine::Extensions)
diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h
index cbfe0f14a3..360c9df075 100644
--- a/src/qml/jsapi/qjsengine_p.h
+++ b/src/qml/jsapi/qjsengine_p.h
@@ -75,7 +75,7 @@ public:
static QJSEnginePrivate* get(QV4::ExecutionEngine *e);
QJSEnginePrivate() : mutex(QMutex::Recursive) {}
- ~QJSEnginePrivate();
+ ~QJSEnginePrivate() override;
static void addToDebugServer(QJSEngine *q);
static void removeFromDebugServer(QJSEngine *q);
@@ -163,7 +163,7 @@ QQmlPropertyCache until the QQmlEngine is destroyed.
QQmlPropertyCache *QJSEnginePrivate::cache(QObject *obj)
{
if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted)
- return 0;
+ return nullptr;
Locker locker(this);
const QMetaObject *mo = obj->metaObject();
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index c1a135c835..b97468ab7b 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -67,7 +67,7 @@
QJSValue supports the types defined in the \l{ECMA-262}
standard: The primitive types, which are Undefined, Null, Boolean,
- Number, and String; and the Object type. Additionally, built-in
+ Number, and String; and the Object and Array types. Additionally, built-in
support is provided for Qt/C++ types such as QVariant and QObject.
For the object-based types (including Date and RegExp), use the
@@ -108,6 +108,38 @@
script code, or QJSValueIterator in C++.
\sa QJSEngine, QJSValueIterator
+
+ \section1 Working With Arrays
+
+ To create an array using QJSValue, use \l QJSEngine::newArray():
+
+ \code
+ // Assumes that this class was declared in QML.
+ QJSValue jsArray = engine->newArray(3);
+ \endcode
+
+ To set individual elements in the array, use
+ the \l {QJSValue::}{setProperty(quint32 arrayIndex, const QJSValue &value)}
+ overload. For example, to fill the array above with integers:
+
+ \code
+ for (int i = 0; i < 3; ++i) {
+ jsArray.setProperty(i, QRandomGenerator::global().generate());
+ }
+ \endcode
+
+ To determine the length of the array, access the \c "length" property.
+ To access array elements, use the
+ \l {QJSValue::}{property(quint32 arrayIndex)} overload. The following code
+ reads the array we created above back into a list:
+
+ \code
+ QVector<int> integers;
+ const int length = jsArray.property("length").toInt();
+ for (int i = 0; i < length; ++i) {
+ integers.append(jsArray.property(i).toInt());
+ }
+ \endcode
*/
/*!
@@ -232,7 +264,7 @@ QJSValue::QJSValue(const QJSValue& other)
*/
/*!
- \fn QJSValue &operator=(QJSValue && other)
+ \fn QJSValue &QJSValue::operator=(QJSValue && other)
Move-assigns \a other to this QJSValue object.
*/
@@ -630,7 +662,7 @@ QVariant QJSValue::toVariant() const
return QVariant(val->asDouble());
}
if (val->isNull())
- return QVariant(QMetaType::Nullptr, 0);
+ return QVariant(QMetaType::Nullptr, nullptr);
Q_ASSERT(val->isUndefined());
return QVariant();
}
@@ -799,7 +831,7 @@ QJSEngine* QJSValue::engine() const
QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
if (engine)
return engine->jsEngine();
- return 0;
+ return nullptr;
}
#endif // QT_DEPRECATED
@@ -852,7 +884,7 @@ void QJSValue::setPrototype(const QJSValue& prototype)
if (!val)
return;
if (val->isNull()) {
- o->setPrototype(0);
+ o->setPrototype(nullptr);
return;
}
@@ -1008,6 +1040,10 @@ bool QJSValue::strictlyEquals(const QJSValue& other) const
occurred, property() returns the value that was thrown (typically
an \c{Error} object).
+ To access array elements, use the
+ \l {QJSValue::}{setProperty(quint32 arrayIndex, const QJSValue &value)}
+ overload instead.
+
\sa setProperty(), hasProperty(), QJSValueIterator
*/
QJSValue QJSValue::property(const QString& name) const
@@ -1039,8 +1075,25 @@ QJSValue QJSValue::property(const QString& name) const
Returns the property at the given \a arrayIndex.
- This function is provided for convenience and performance when
- working with array objects.
+ It is possible to access elements in an array in two ways. The first is to
+ use the array index as the property name:
+
+ \code
+ qDebug() << jsValueArray.property(QLatin1String("4")).toString();
+ \endcode
+
+ The second is to use the overload that takes an index:
+
+ \code
+ qDebug() << jsValueArray.property(4).toString();
+ \endcode
+
+ Both of these approaches achieve the same result, except that the latter:
+
+ \list
+ \li Is easier to use (can use an integer directly)
+ \li Is faster (no conversion to integer)
+ \endlist
If this QJSValue is not an Array object, this function behaves
as if property() was called with the string representation of \a
@@ -1072,6 +1125,10 @@ QJSValue QJSValue::property(quint32 arrayIndex) const
If this QJSValue does not already have a property with name \a name,
a new property is created.
+ To modify array elements, use the
+ \l {QJSValue::}{setProperty(quint32 arrayIndex, const QJSValue &value)}
+ overload instead.
+
\sa property(), deleteProperty()
*/
void QJSValue::setProperty(const QString& name, const QJSValue& value)
@@ -1109,12 +1166,31 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
Sets the property at the given \a arrayIndex to the given \a value.
- This function is provided for convenience and performance when
- working with array objects.
+ It is possible to modify elements in an array in two ways. The first is to
+ use the array index as the property name:
+
+ \code
+ jsValueArray.setProperty(QLatin1String("4"), value);
+ \endcode
+
+ The second is to use the overload that takes an index:
+
+ \code
+ jsValueArray.setProperty(4, value);
+ \endcode
+
+ Both of these approaches achieve the same result, except that the latter:
+
+ \list
+ \li Is easier to use (can use an integer directly)
+ \li Is faster (no conversion to integer)
+ \endlist
If this QJSValue is not an Array object, this function behaves
as if setProperty() was called with the string representation of \a
arrayIndex.
+
+ \sa {QJSValue::}{property(quint32 arrayIndex)}, {Working With Arrays}
*/
void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
{
@@ -1232,11 +1308,11 @@ QObject *QJSValue::toQObject() const
{
QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
if (!engine)
- return 0;
+ return nullptr;
QV4::Scope scope(engine);
QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, QJSValuePrivate::getValue(this));
if (!wrapper)
- return 0;
+ return nullptr;
return wrapper->object();
}
@@ -1253,11 +1329,11 @@ const QMetaObject *QJSValue::toQMetaObject() const
{
QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this);
if (!engine)
- return 0;
+ return nullptr;
QV4::Scope scope(engine);
QV4::Scoped<QV4::QMetaObjectWrapper> wrapper(scope, QJSValuePrivate::getValue(this));
if (!wrapper)
- return 0;
+ return nullptr;
return wrapper->metaObject();
}
@@ -1313,7 +1389,7 @@ bool QJSValue::isRegExp() const
bool QJSValue::isQObject() const
{
QV4::Value *val = QJSValuePrivate::getValue(this);
- return val && val->as<QV4::QObjectWrapper>() != 0;
+ return val && val->as<QV4::QObjectWrapper>() != nullptr;
}
/*!
@@ -1327,7 +1403,7 @@ bool QJSValue::isQObject() const
bool QJSValue::isQMetaObject() const
{
QV4::Value *val = QJSValuePrivate::getValue(this);
- return val && val->as<QV4::QMetaObjectWrapper>() != 0;
+ return val && val->as<QV4::QMetaObjectWrapper>() != nullptr;
}
QT_END_NAMESPACE
diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h
index c4761ad6ea..62e09f72be 100644
--- a/src/qml/jsapi/qjsvalue_p.h
+++ b/src/qml/jsapi/qjsvalue_p.h
@@ -68,7 +68,7 @@ public:
static inline QV4::Value *getValue(const QJSValue *jsval)
{
if (jsval->d & 3)
- return 0;
+ return nullptr;
return reinterpret_cast<QV4::Value *>(jsval->d);
}
@@ -76,7 +76,7 @@ public:
{
if (jsval->d & 1)
return reinterpret_cast<QVariant *>(jsval->d & ~3);
- return 0;
+ return nullptr;
}
static inline void setVariant(QJSValue *jsval, const QVariant &v) {
@@ -153,14 +153,14 @@ public:
*v = QV4::Encode(variant->toUInt());
break;
default:
- return 0;
+ return nullptr;
}
return v;
}
static QV4::ExecutionEngine *engine(const QJSValue *jsval) {
QV4::Value *v = getValue(jsval);
- return v ? QV4::PersistentValueStorage::getEngine(v) : 0;
+ return v ? QV4::PersistentValueStorage::getEngine(v) : nullptr;
}
static inline bool checkEngine(QV4::ExecutionEngine *e, const QJSValue &jsval) {
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index 519c87d0c4..4bc877bd9d 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -41,7 +41,8 @@ SOURCES += \
$$PWD/qv4qobjectwrapper.cpp \
$$PWD/qv4arraybuffer.cpp \
$$PWD/qv4typedarray.cpp \
- $$PWD/qv4dataview.cpp
+ $$PWD/qv4dataview.cpp \
+ $$PWD/qv4vme_moth.cpp
qtConfig(qml-debug): SOURCES += $$PWD/qv4profiling.cpp
@@ -94,14 +95,8 @@ HEADERS += \
$$PWD/qv4profiling_p.h \
$$PWD/qv4arraybuffer_p.h \
$$PWD/qv4typedarray_p.h \
- $$PWD/qv4dataview_p.h
-
-qtConfig(qml-interpreter) {
- HEADERS += \
- $$PWD/qv4vme_moth_p.h
- SOURCES += \
- $$PWD/qv4vme_moth.cpp
-}
+ $$PWD/qv4dataview_p.h \
+ $$PWD/qv4vme_moth_p.h
}
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index f7b9e8acef..c4eddb6b2a 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -96,7 +96,7 @@ void Heap::ArrayBuffer::init(size_t length)
Object::init();
data = QTypedArrayData<char>::allocate(length + 1);
if (!data) {
- data = 0;
+ data = nullptr;
internalClass->engine->throwRangeError(QStringLiteral("ArrayBuffer: out of memory"));
return;
}
@@ -152,7 +152,7 @@ void ArrayBufferPrototype::init(ExecutionEngine *engine, Object *ctor)
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
ctor->defineDefaultProperty(QStringLiteral("isView"), ArrayBufferCtor::method_isView, 1);
defineDefaultProperty(engine->id_constructor(), (o = ctor));
- defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, 0);
+ defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, nullptr);
defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
defineDefaultProperty(QStringLiteral("toString"), method_toString, 0);
}
diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h
index e236a23d1f..59e78ee85f 100644
--- a/src/qml/jsruntime/qv4arraybuffer_p.h
+++ b/src/qml/jsruntime/qv4arraybuffer_p.h
@@ -93,8 +93,8 @@ struct Q_QML_PRIVATE_EXPORT ArrayBuffer : Object
QByteArray asByteArray() const;
uint byteLength() const { return d()->byteLength(); }
- char *data() { detach(); return d()->data ? d()->data->data() : 0; }
- const char *constData() { detach(); return d()->data ? d()->data->data() : 0; }
+ char *data() { detach(); return d()->data ? d()->data->data() : nullptr; }
+ const char *constData() { detach(); return d()->data ? d()->data->data() : nullptr; }
private:
void detach();
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 390840fb1e..30c8527f21 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -50,7 +50,7 @@ using namespace QV4;
QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON
const QV4::VTable QV4::ArrayData::static_vtbl = {
- 0,
+ nullptr,
0,
0,
QV4::ArrayData::IsExecutionContext,
@@ -69,7 +69,7 @@ const QV4::VTable QV4::ArrayData::static_vtbl = {
const ArrayVTable SimpleArrayData::static_vtbl =
{
- DEFINE_MANAGED_VTABLE_INT(SimpleArrayData, 0),
+ DEFINE_MANAGED_VTABLE_INT(SimpleArrayData, nullptr),
Heap::ArrayData::Simple,
SimpleArrayData::reallocate,
SimpleArrayData::get,
@@ -85,7 +85,7 @@ const ArrayVTable SimpleArrayData::static_vtbl =
const ArrayVTable SparseArrayData::static_vtbl =
{
- DEFINE_MANAGED_VTABLE_INT(SparseArrayData, 0),
+ DEFINE_MANAGED_VTABLE_INT(SparseArrayData, nullptr),
Heap::ArrayData::Sparse,
SparseArrayData::reallocate,
SparseArrayData::get,
@@ -170,7 +170,7 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
newData->setType(newType);
if (d)
newData->d()->needsMark = d->d()->needsMark;
- newData->setAttrs(enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->d()->values.values + alloc) : 0);
+ newData->setAttrs(enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->d()->values.values + alloc) : nullptr);
o->setArrayData(newData);
if (d) {
@@ -203,12 +203,11 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
if (d && d->type() == Heap::ArrayData::Sparse) {
Heap::SparseArrayData *old = static_cast<Heap::SparseArrayData *>(d->d());
sparse->sparse = old->sparse;
- old->sparse = 0;
- sparse->freeList = old->freeList;
- lastFree = &sparse->freeList;
+ old->sparse = nullptr;
+ lastFree = &sparse->sparse->freeList;
} else {
sparse->sparse = new SparseArray;
- lastFree = &sparse->freeList;
+ lastFree = &sparse->sparse->freeList;
storeValue(lastFree, 0);
for (uint i = 0; i < toCopy; ++i) {
if (!sparse->values[i].isEmpty()) {
@@ -228,10 +227,10 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
sparse->values.values[i].setEmpty();
lastFree = &sparse->values.values[i].rawValueRef();
}
- storeValue(lastFree, UINT_MAX);
}
+ storeValue(lastFree, UINT_MAX);
- Q_ASSERT(Value::fromReturnedValue(sparse->freeList).isEmpty());
+ Q_ASSERT(Value::fromReturnedValue(sparse->sparse->freeList).isEmpty());
// ### Could explicitly free the old data
}
@@ -373,12 +372,12 @@ void SparseArrayData::free(Heap::ArrayData *d, uint idx)
Value *v = d->values.values + idx;
if (d->attrs && d->attrs[idx].isAccessor()) {
// double slot, free both. Order is important, so we have a double slot for allocation again afterwards.
- v[1].setEmpty(Value::fromReturnedValue(d->freeList).emptyValue());
+ v[1].setEmpty(Value::fromReturnedValue(d->sparse->freeList).emptyValue());
v[0].setEmpty(idx + 1);
} else {
- v->setEmpty(Value::fromReturnedValue(d->freeList).emptyValue());
+ v->setEmpty(Value::fromReturnedValue(d->sparse->freeList).emptyValue());
}
- d->freeList = Primitive::emptyValue(idx).asReturnedValue();
+ d->sparse->freeList = Primitive::emptyValue(idx).asReturnedValue();
if (d->attrs)
d->attrs[idx].clear();
}
@@ -395,12 +394,12 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
Q_ASSERT(o->d()->arrayData->type == Heap::ArrayData::Sparse);
Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (doubleSlot) {
- ReturnedValue *last = &dd->freeList;
+ ReturnedValue *last = &dd->sparse->freeList;
while (1) {
if (Value::fromReturnedValue(*last).value() == UINT_MAX) {
reallocate(o, dd->values.alloc + 2, true);
dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- last = &dd->freeList;
+ last = &dd->sparse->freeList;
Q_ASSERT(Value::fromReturnedValue(*last).value() != UINT_MAX);
}
@@ -417,14 +416,14 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
last = &dd->values.values[Value::fromReturnedValue(*last).value()].rawValueRef();
}
} else {
- if (Value::fromReturnedValue(dd->freeList).value() == UINT_MAX) {
+ if (Value::fromReturnedValue(dd->sparse->freeList).value() == UINT_MAX) {
reallocate(o, dd->values.alloc + 1, false);
dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
- uint idx = Value::fromReturnedValue(dd->freeList).value();
+ uint idx = Value::fromReturnedValue(dd->sparse->freeList).value();
Q_ASSERT(idx != UINT_MAX);
- dd->freeList = dd->values[idx].asReturnedValue();
- Q_ASSERT(Value::fromReturnedValue(dd->freeList).isEmpty());
+ dd->sparse->freeList = dd->values[idx].asReturnedValue();
+ Q_ASSERT(Value::fromReturnedValue(dd->sparse->freeList).isEmpty());
if (dd->attrs)
dd->attrs[idx] = Attr_Data;
return idx;
@@ -479,14 +478,14 @@ bool SparseArrayData::del(Object *o, uint index)
if (isAccessor) {
// free up both indices
- dd->values.values[pidx + 1].setEmpty(Value::fromReturnedValue(dd->freeList).emptyValue());
+ dd->values.values[pidx + 1].setEmpty(Value::fromReturnedValue(dd->sparse->freeList).emptyValue());
dd->values.values[pidx].setEmpty(pidx + 1);
} else {
Q_ASSERT(dd->type == Heap::ArrayData::Sparse);
- dd->values.values[pidx].setEmpty(Value::fromReturnedValue(dd->freeList).emptyValue());
+ dd->values.values[pidx].setEmpty(Value::fromReturnedValue(dd->sparse->freeList).emptyValue());
}
- dd->freeList = Primitive::emptyValue(pidx).asReturnedValue();
+ dd->sparse->freeList = Primitive::emptyValue(pidx).asReturnedValue();
dd->sparse->erase(n);
return true;
}
@@ -780,7 +779,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
if (!sparse->sparse()->nEntries())
return;
- thisObject->setArrayData(0);
+ thisObject->setArrayData(nullptr);
ArrayData::realloc(thisObject, Heap::ArrayData::Simple, sparse->sparse()->nEntries(), sparse->attrs() ? true : false);
Heap::SimpleArrayData *d = thisObject->d()->arrayData.cast<Heap::SimpleArrayData>();
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index db9db5a220..9356670b6d 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -95,7 +95,6 @@ namespace Heap {
Member(class, NoMark, ushort, needsMark) \
Member(class, NoMark, uint, offset) \
Member(class, NoMark, PropertyAttributes *, attrs) \
- Member(class, NoMark, ReturnedValue, freeList) \
Member(class, NoMark, SparseArray *, sparse) \
Member(class, ValueArray, ValueArray, values)
@@ -142,7 +141,7 @@ DECLARE_HEAP_OBJECT(ArrayData, Base) {
uint mappedIndex(uint index) const;
};
-V4_ASSERT_IS_TRIVIAL(ArrayData)
+Q_STATIC_ASSERT(std::is_trivial< ArrayData >::value);
struct SimpleArrayData : public ArrayData {
uint mappedIndex(uint index) const { index += offset; if (index >= values.alloc) index -= values.alloc; return index; }
@@ -157,7 +156,7 @@ struct SimpleArrayData : public ArrayData {
return attrs ? attrs[i] : Attr_Data;
}
};
-V4_ASSERT_IS_TRIVIAL(SimpleArrayData)
+Q_STATIC_ASSERT(std::is_trivial< SimpleArrayData >::value);
struct SparseArrayData : public ArrayData {
void destroy() {
@@ -264,8 +263,6 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
V4_INTERNALCLASS(SparseArrayData)
V4_NEEDS_DESTROY
- ReturnedValue &freeList() { return d()->freeList; }
- ReturnedValue freeList() const { return d()->freeList; }
SparseArray *sparse() const { return d()->sparse; }
void setSparse(SparseArray *s) { d()->sparse = s; }
@@ -334,7 +331,7 @@ ArrayData::Index ArrayData::getValueOrSetter(uint index, PropertyAttributes *att
uint idx = mappedIndex(index);
if (idx == UINT_MAX) {
*attrs = Attr_Invalid;
- return { 0, 0 };
+ return { nullptr, 0 };
}
*attrs = attributes(index);
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 00d816fe91..020e519e74 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -302,7 +302,7 @@ ReturnedValue ExecutionContext::getProperty(String *name)
ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base)
{
- base->setM(0);
+ base->setM(nullptr);
name->makeIdentifier();
Heap::ExecutionContext *ctx = d();
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 4efd0bc899..512bfa06d8 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -143,7 +143,7 @@ DECLARE_HEAP_OBJECT(ExecutionContext, Base) {
quint8 padding_[4];
#endif
};
-V4_ASSERT_IS_TRIVIAL(ExecutionContext)
+Q_STATIC_ASSERT(std::is_trivial< ExecutionContext >::value);
Q_STATIC_ASSERT(sizeof(ExecutionContext) == sizeof(Base) + sizeof(ExecutionContextData) + QT_POINTER_SIZE);
Q_STATIC_ASSERT(std::is_standard_layout<ExecutionContextData>::value);
@@ -170,7 +170,7 @@ DECLARE_HEAP_OBJECT(CallContext, ExecutionContext) {
}
void setArg(uint index, Value v);
};
-V4_ASSERT_IS_TRIVIAL(CallContext)
+Q_STATIC_ASSERT(std::is_trivial< CallContext >::value);
Q_STATIC_ASSERT(std::is_standard_layout<CallContextData>::value);
Q_STATIC_ASSERT(offsetof(CallContextData, function) == 0);
//### The following size check fails on Win8. With the ValueArray at the end of the
@@ -190,7 +190,7 @@ DECLARE_HEAP_OBJECT(CatchContext, ExecutionContext) {
void init(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue);
};
-V4_ASSERT_IS_TRIVIAL(CatchContext)
+Q_STATIC_ASSERT(std::is_trivial< CatchContext >::value);
}
@@ -246,12 +246,12 @@ struct CatchContext : public ExecutionContext
inline CallContext *ExecutionContext::asCallContext()
{
- return d()->type == Heap::ExecutionContext::Type_CallContext ? static_cast<CallContext *>(this) : 0;
+ return d()->type == Heap::ExecutionContext::Type_CallContext ? static_cast<CallContext *>(this) : nullptr;
}
inline const CallContext *ExecutionContext::asCallContext() const
{
- return d()->type == Heap::ExecutionContext::Type_CallContext ? static_cast<const CallContext *>(this) : 0;
+ return d()->type == Heap::ExecutionContext::Type_CallContext ? static_cast<const CallContext *>(this) : nullptr;
}
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index 397ef1cfec..d894d909ff 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -88,9 +88,9 @@ void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(3));
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
defineDefaultProperty(engine->id_constructor(), (o = ctor));
- defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, 0);
- defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, 0);
- defineAccessorProperty(QStringLiteral("byteOffset"), method_get_byteOffset, 0);
+ defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, nullptr);
+ defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, nullptr);
+ defineAccessorProperty(QStringLiteral("byteOffset"), method_get_byteOffset, nullptr);
defineDefaultProperty(QStringLiteral("getInt8"), method_getChar<signed char>, 0);
defineDefaultProperty(QStringLiteral("getUint8"), method_getChar<unsigned char>, 0);
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index b8392d27e9..bc9b3013d1 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -328,7 +328,7 @@ static inline double DaylightSavingTA(double t) // t is a UTC time
static inline double DaylightSavingTA(double t)
{
struct tm tmtm;
-#if defined(_MSC_VER) && _MSC_VER >= 1400
+#if defined(Q_CC_MSVC)
__time64_t tt = (__time64_t)(t / msPerSecond);
// _localtime_64_s returns non-zero on failure
if (_localtime64_s(&tmtm, &tt) != 0)
@@ -854,7 +854,7 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
ScopedString us(scope, engine->newIdentifier(toUtcString));
ScopedString gs(scope, engine->newIdentifier(toGmtString));
ExecutionContext *global = engine->rootContext();
- ScopedFunctionObject toUtcGmtStringFn(scope, BuiltinFunction::create(global, us, method_toUTCString));
+ ScopedFunctionObject toUtcGmtStringFn(scope, FunctionObject::createBuiltinFunction(global, us, method_toUTCString));
toUtcGmtStringFn->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(0));
defineDefaultProperty(us, toUtcGmtStringFn);
defineDefaultProperty(gs, toUtcGmtStringFn);
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index a4ab0a27ed..2b9a580288 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -101,7 +101,7 @@ struct DateObject: Object {
template<>
inline const DateObject *Value::as() const {
- return isManaged() && m()->vtable()->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : 0;
+ return isManaged() && m()->vtable()->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : nullptr;
}
struct DateCtor: FunctionObject
diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h
index 61a55964ab..9b41bb6e7a 100644
--- a/src/qml/jsruntime/qv4debugging_p.h
+++ b/src/qml/jsruntime/qv4debugging_p.h
@@ -78,7 +78,7 @@ class Q_QML_EXPORT Debugger : public QObject
Q_OBJECT
public:
- virtual ~Debugger() {}
+ ~Debugger() override {}
virtual bool pauseAtNextOpportunity() const = 0;
virtual void maybeBreakAtInstruction() = 0;
virtual void enteringFunction() = 0;
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index c57f39f61c..5f59e1e809 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -101,7 +101,7 @@ using namespace QV4;
static QBasicAtomicInt engineSerial = Q_BASIC_ATOMIC_INITIALIZER(1);
-ReturnedValue throwTypeError(const BuiltinFunction *b, CallData *)
+ReturnedValue throwTypeError(const FunctionObject *b, const QV4::Value *, const QV4::Value *, int)
{
return b->engine()->throwTypeError();
}
@@ -127,13 +127,16 @@ ExecutionEngine::ExecutionEngine()
, bumperPointerAllocator(new WTF::BumpPointerAllocator)
, jsStack(new WTF::PageAllocation)
, gcStack(new WTF::PageAllocation)
- , globalCode(0)
- , v8Engine(0)
- , argumentsAccessors(0)
+ , globalCode(nullptr)
+ , v8Engine(nullptr)
+ , argumentsAccessors(nullptr)
, nArgumentsAccessors(0)
, m_engineId(engineSerial.fetchAndAddOrdered(1))
- , regExpCache(0)
- , m_multiplyWrappedQObjects(0)
+ , regExpCache(nullptr)
+ , m_multiplyWrappedQObjects(nullptr)
+#if defined(V4_ENABLE_JIT) && !defined(V4_BOOTSTRAP)
+ , m_canAllocateExecutableMemory(OSAllocator::canAllocateExecutableMemory())
+#endif
{
memoryManager = new QV4::MemoryManager(this);
@@ -168,6 +171,15 @@ ExecutionEngine::ExecutionEngine()
/* writable */ true, /* executable */ false,
/* includesGuardPages */ true);
+ {
+ bool ok = false;
+ jitCallCountThreshold = qEnvironmentVariableIntValue("QV4_JIT_CALL_THRESHOLD", &ok);
+ if (!ok)
+ jitCallCountThreshold = 3;
+ if (qEnvironmentVariableIsSet("QV4_FORCE_INTERPRETER"))
+ jitCallCountThreshold = std::numeric_limits<int>::max();
+ }
+
exceptionValue = jsAlloca(1);
globalObject = static_cast<Object *>(jsAlloca(1));
jsObjects = jsAlloca(NJSObjects);
@@ -188,6 +200,7 @@ ExecutionEngine::ExecutionEngine()
internalClasses[Class_SimpleArrayData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::SimpleArrayData::staticVTable());
internalClasses[Class_SparseArrayData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::SparseArrayData::staticVTable());
internalClasses[Class_ExecutionContext] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::ExecutionContext::staticVTable());
+ internalClasses[Class_QmlContext] = internalClasses[EngineBase::Class_ExecutionContext]->changeVTable(QV4::QmlContext::staticVTable());
internalClasses[Class_CallContext] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::CallContext::staticVTable());
jsStrings[String_Empty] = newIdentifier(QString());
@@ -230,6 +243,7 @@ ExecutionEngine::ExecutionEngine()
InternalClass *ic = internalClasses[Class_Empty]->changeVTable(QV4::Object::staticVTable());
jsObjects[ObjectProto] = memoryManager->allocObject<ObjectPrototype>(ic);
internalClasses[Class_Object] = ic->changePrototype(objectPrototype()->d());
+ internalClasses[EngineBase::Class_QmlContextWrapper] = internalClasses[Class_Object]->changeVTable(QV4::QQmlContextWrapper::staticVTable());
ic = newInternalClass(ArrayPrototype::staticVTable(), objectPrototype());
Q_ASSERT(ic->prototype);
@@ -275,8 +289,6 @@ ExecutionEngine::ExecutionEngine()
ic = ic->changeVTable(ScriptFunction::staticVTable());
internalClasses[EngineBase::Class_ScriptFunction] = ic->addMember(id_length(), Attr_ReadOnly, &index);
Q_ASSERT(index == Heap::ScriptFunction::Index_Length);
- internalClasses[EngineBase::Class_BuiltinFunction] = ic->changeVTable(BuiltinFunction::staticVTable());
- Q_ASSERT(index == Heap::ScriptFunction::Index_Length);
internalClasses[EngineBase::Class_ObjectProto] = internalClasses[Class_Object]->addMember(id_constructor(), Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_ProtoConstructor);
@@ -302,7 +314,7 @@ ExecutionEngine::ExecutionEngine()
internalClasses[EngineBase::Class_RegExpExecArray] = ic->addMember(id_input(), Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayInput);
- ic = newInternalClass(ErrorObject::staticVTable(), 0);
+ ic = newInternalClass(ErrorObject::staticVTable(), nullptr);
ic = ic->addMember((str = newIdentifier(QStringLiteral("stack"))), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorObject::Index_Stack);
ic = ic->addMember((str = newIdentifier(QStringLiteral("fileName"))), Attr_Data|Attr_NotEnumerable, &index);
@@ -320,7 +332,7 @@ ExecutionEngine::ExecutionEngine()
internalClasses[EngineBase::Class_ErrorProto] = ic->addMember(id_name(), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorPrototype::Index_Name);
- jsObjects[GetStack_Function] = BuiltinFunction::create(rootContext(), str = newIdentifier(QStringLiteral("stack")), ErrorObject::method_get_stack);
+ jsObjects[GetStack_Function] = FunctionObject::createBuiltinFunction(rootContext(), str = newIdentifier(QStringLiteral("stack")), ErrorObject::method_get_stack);
getStackFunction()->defineReadonlyProperty(id_length(), Primitive::fromInt32(0));
jsObjects[ErrorProto] = memoryManager->allocObject<ErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto], objectPrototype());
@@ -384,8 +396,8 @@ ExecutionEngine::ExecutionEngine()
jsObjects[DataView_Ctor] = memoryManager->allocObject<DataViewCtor>(global);
jsObjects[DataViewProto] = memoryManager->allocObject<DataViewPrototype>();
static_cast<DataViewPrototype *>(dataViewPrototype())->init(this, dataViewCtor());
- jsObjects[ValueTypeProto] = (Heap::Base *) 0;
- jsObjects[SignalHandlerProto] = (Heap::Base *) 0;
+ jsObjects[ValueTypeProto] = (Heap::Base *) nullptr;
+ jsObjects[SignalHandlerProto] = (Heap::Base *) nullptr;
for (int i = 0; i < Heap::TypedArray::NTypes; ++i) {
static_cast<Value &>(typedArrayCtors[i]) = memoryManager->allocObject<TypedArrayCtor>(global, Heap::TypedArray::Type(i));
@@ -442,8 +454,8 @@ ExecutionEngine::ExecutionEngine()
ScopedString pi(scope, newIdentifier(piString));
ScopedString pf(scope, newIdentifier(pfString));
ExecutionContext *global = rootContext();
- ScopedFunctionObject parseIntFn(scope, BuiltinFunction::create(global, pi, GlobalFunctions::method_parseInt));
- ScopedFunctionObject parseFloatFn(scope, BuiltinFunction::create(global, pf, GlobalFunctions::method_parseFloat));
+ ScopedFunctionObject parseIntFn(scope, FunctionObject::createBuiltinFunction(global, pi, GlobalFunctions::method_parseInt));
+ ScopedFunctionObject parseFloatFn(scope, FunctionObject::createBuiltinFunction(global, pf, GlobalFunctions::method_parseFloat));
parseIntFn->defineReadonlyConfigurableProperty(id_length(), Primitive::fromInt32(2));
parseFloatFn->defineReadonlyConfigurableProperty(id_length(), Primitive::fromInt32(1));
globalObject->defineDefaultProperty(piString, parseIntFn);
@@ -462,13 +474,13 @@ ExecutionEngine::ExecutionEngine()
globalObject->defineDefaultProperty(QStringLiteral("unescape"), GlobalFunctions::method_unescape, 1);
ScopedString name(scope, newString(QStringLiteral("thrower")));
- jsObjects[ThrowerObject] = BuiltinFunction::create(global, name, ::throwTypeError);
+ jsObjects[ThrowerObject] = FunctionObject::createBuiltinFunction(global, name, ::throwTypeError);
}
ExecutionEngine::~ExecutionEngine()
{
delete m_multiplyWrappedQObjects;
- m_multiplyWrappedQObjects = 0;
+ m_multiplyWrappedQObjects = nullptr;
delete identifierTable;
delete memoryManager;
@@ -519,7 +531,7 @@ InternalClass *ExecutionEngine::newClass(const InternalClass &other)
InternalClass *ExecutionEngine::newInternalClass(const VTable *vtable, Object *prototype)
{
- return internalClasses[EngineBase::Class_Empty]->changeVTable(vtable)->changePrototype(prototype ? prototype->d() : 0);
+ return internalClasses[EngineBase::Class_Empty]->changeVTable(vtable)->changePrototype(prototype ? prototype->d() : nullptr);
}
Heap::Object *ExecutionEngine::newObject()
@@ -721,18 +733,18 @@ Heap::Object *ExecutionEngine::newForEachIteratorObject(Object *o)
Heap::QmlContext *ExecutionEngine::qmlContext() const
{
if (!currentStackFrame)
- return 0;
+ return nullptr;
Heap::ExecutionContext *ctx = currentContext()->d();
if (ctx->type != Heap::ExecutionContext::Type_QmlContext && !ctx->outer)
- return 0;
+ return nullptr;
while (ctx->outer && ctx->outer->type != Heap::ExecutionContext::Type_GlobalContext)
ctx = ctx->outer;
Q_ASSERT(ctx);
if (ctx->type != Heap::ExecutionContext::Type_QmlContext)
- return 0;
+ return nullptr;
return static_cast<Heap::QmlContext *>(ctx);
}
@@ -741,7 +753,7 @@ QObject *ExecutionEngine::qmlScopeObject() const
{
Heap::QmlContext *ctx = qmlContext();
if (!ctx)
- return 0;
+ return nullptr;
return ctx->qml()->scopeObject;
}
@@ -771,7 +783,7 @@ QQmlContextData *ExecutionEngine::callingQmlContext() const
{
Heap::QmlContext *ctx = qmlContext();
if (!ctx)
- return 0;
+ return nullptr;
return ctx->qml()->context->contextData();
}
@@ -868,14 +880,14 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file)
CppStackFrame *f = currentStackFrame;
while (f) {
if (f->v4Function) {
- base.setUrl(f->v4Function->sourceFile());
+ base = f->v4Function->finalUrl();
break;
}
f = f->parent;
}
if (base.isEmpty() && globalCode)
- base.setUrl(globalCode->sourceFile());
+ base = globalCode->finalUrl();
if (base.isEmpty())
return src;
@@ -898,7 +910,7 @@ void ExecutionEngine::requireArgumentsAccessors(int n)
nArgumentsAccessors = qMax(8, n);
argumentsAccessors = new Property[nArgumentsAccessors];
if (oldAccessors) {
- memcpy(argumentsAccessors, oldAccessors, oldSize*sizeof(Property));
+ memcpy(static_cast<void *>(argumentsAccessors), static_cast<const void *>(oldAccessors), oldSize*sizeof(Property));
delete [] oldAccessors;
}
ExecutionContext *global = rootContext();
@@ -1079,7 +1091,7 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError()
typedef QSet<QV4::Heap::Object *> V4ObjectSet;
static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int typeHint, bool createJSValueForObjects, V4ObjectSet *visitedObjects);
static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::Value &value);
-static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V4ObjectSet *visitedObjects = 0);
+static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V4ObjectSet *visitedObjects = nullptr);
static bool convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::Value &value,
const QByteArray &targetType,
void **result);
@@ -1093,7 +1105,7 @@ static QV4::ReturnedValue variantToJS(QV4::ExecutionEngine *v4, const QVariant &
QVariant ExecutionEngine::toVariant(const Value &value, int typeHint, bool createJSValueForObjects)
{
- return ::toVariant(this, value, typeHint, createJSValueForObjects, 0);
+ return ::toVariant(this, value, typeHint, createJSValueForObjects, nullptr);
}
@@ -1457,7 +1469,7 @@ static QV4::ReturnedValue variantMapToJS(QV4::ExecutionEngine *v4, const QVarian
// Returns the value if conversion succeeded, an empty handle otherwise.
QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data)
{
- Q_ASSERT(data != 0);
+ Q_ASSERT(data != nullptr);
// check if it's one of the types we know
switch (QMetaType::Type(type)) {
@@ -1545,13 +1557,9 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data)
return 0;
}
-bool ExecutionEngine::canJIT()
+ReturnedValue ExecutionEngine::global()
{
-#ifdef V4_ENABLE_JIT
- return true;
-#else
- return false;
-#endif
+ return globalObject->asReturnedValue();
}
// Converts a JS value to a meta-type.
@@ -1734,7 +1742,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
QByteArray className = name.left(name.size()-1);
QV4::ScopedObject p(scope, proto.getPointer());
if (QObject *qobject = qtObjectFromJS(this, p))
- canCast = qobject->qt_metacast(className) != 0;
+ canCast = qobject->qt_metacast(className) != nullptr;
}
if (canCast) {
QByteArray varTypeName = QMetaType::typeName(var.userType());
@@ -1748,7 +1756,7 @@ bool ExecutionEngine::metaTypeFromJS(const Value *value, int type, void *data)
}
}
} else if (value->isNull() && name.endsWith('*')) {
- *reinterpret_cast<void* *>(data) = 0;
+ *reinterpret_cast<void* *>(data) = nullptr;
return true;
} else if (type == qMetaTypeId<QJSValue>()) {
*reinterpret_cast<QJSValue*>(data) = QJSValue(this, value->asReturnedValue());
@@ -1776,7 +1784,7 @@ static bool convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::Value &va
static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::Value &value)
{
if (!value.isObject())
- return 0;
+ return nullptr;
QV4::Scope scope(engine);
QV4::Scoped<QV4::VariantObject> v(scope, value);
@@ -1789,7 +1797,7 @@ static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::Value &v
}
QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, value);
if (!wrapper)
- return 0;
+ return nullptr;
return wrapper->object();
}
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 346f290feb..5edf89f720 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -56,7 +56,9 @@
#include <private/qintrusivelist_p.h>
#include "qv4enginebase_p.h"
+
#ifndef V4_BOOTSTRAP
+# include "qv4function_p.h"
# include <private/qv8engine_p.h>
# include <private/qv4compileddata_p.h>
#endif
@@ -85,6 +87,7 @@ namespace CompiledData {
struct CompilationUnit;
}
+struct Function;
struct InternalClass;
struct InternalClassPool;
@@ -365,6 +368,9 @@ public:
// but any time a QObject is wrapped a second time in another engine, we have to do
// bookkeeping.
MultiplyWrappedQObjectMap *m_multiplyWrappedQObjects;
+#if defined(V4_ENABLE_JIT) && !defined(V4_BOOTSTRAP)
+ const bool m_canAllocateExecutableMemory;
+#endif
int internalClassIdCount = 0;
@@ -453,7 +459,7 @@ public:
StackTrace exceptionStackTrace;
ReturnedValue throwError(const Value &value);
- ReturnedValue catchException(StackTrace *trace = 0);
+ ReturnedValue catchException(StackTrace *trace = nullptr);
ReturnedValue throwError(const QString &message);
ReturnedValue throwSyntaxError(const QString &message);
@@ -481,13 +487,28 @@ public:
bool checkStackLimits();
- static bool canJIT();
+ bool canJIT(Function *f = nullptr)
+ {
+#if defined(V4_ENABLE_JIT) && !defined(V4_BOOTSTRAP)
+ if (!m_canAllocateExecutableMemory)
+ return false;
+ if (f)
+ return f->interpreterCallCount >= jitCallCountThreshold;
+ return true;
+#else
+ Q_UNUSED(f);
+ return false;
+#endif
+ }
+
+ QV4::ReturnedValue global();
private:
#if QT_CONFIG(qml_debug)
QScopedPointer<QV4::Debugging::Debugger> m_debugger;
QScopedPointer<QV4::Profiling::Profiler> m_profiler;
#endif
+ int jitCallCountThreshold;
};
// This is a trick to tell the code generators that functions taking a NoThrowContext won't
diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h
index e0f5f3ffb1..59fb4a564a 100644
--- a/src/qml/jsruntime/qv4enginebase_p.h
+++ b/src/qml/jsruntime/qv4enginebase_p.h
@@ -101,7 +101,6 @@ struct Q_QML_EXPORT EngineBase {
Class_FunctionObject,
Class_StringObject,
Class_ScriptFunction,
- Class_BuiltinFunction,
Class_ObjectProto,
Class_RegExp,
Class_RegExpObject,
@@ -111,6 +110,8 @@ struct Q_QML_EXPORT EngineBase {
Class_ErrorObject,
Class_ErrorObjectWithMessage,
Class_ErrorProto,
+ Class_QmlContextWrapper,
+ Class_QmlContext,
NClasses
};
InternalClass *internalClasses[NClasses];
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index a5ee0eb886..6b578e8c38 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -180,7 +180,7 @@ struct ErrorObject: Object {
template<>
inline const ErrorObject *Value::as() const {
- return isManaged() && m()->vtable()->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : 0;
+ return isManaged() && m()->vtable()->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : nullptr;
}
struct EvalErrorObject: ErrorObject {
@@ -322,7 +322,7 @@ struct URIErrorPrototype : ErrorObject
inline SyntaxErrorObject *ErrorObject::asSyntaxError()
{
- return d()->errorType == QV4::Heap::ErrorObject::SyntaxError ? static_cast<SyntaxErrorObject *>(this) : 0;
+ return d()->errorType == QV4::Heap::ErrorObject::SyntaxError ? static_cast<SyntaxErrorObject *>(this) : nullptr;
}
diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp
index 64ac1267ce..6f04a712e6 100644
--- a/src/qml/jsruntime/qv4executableallocator.cpp
+++ b/src/qml/jsruntime/qv4executableallocator.cpp
@@ -159,7 +159,7 @@ ExecutableAllocator::~ExecutableAllocator()
ExecutableAllocator::Allocation *ExecutableAllocator::allocate(size_t size)
{
QMutexLocker locker(&mutex);
- Allocation *allocation = 0;
+ Allocation *allocation = nullptr;
// Code is best aligned to 16-byte boundaries.
size = WTF::roundUpToMultipleOf(16, size);
@@ -217,7 +217,7 @@ void ExecutableAllocator::free(Allocation *allocation)
if (!merged)
freeAllocations.insert(allocation->size, allocation);
- allocation = 0;
+ allocation = nullptr;
if (!chunk->firstAllocation->next) {
freeAllocations.remove(chunk->firstAllocation->size, chunk->firstAllocation);
@@ -235,7 +235,7 @@ ExecutableAllocator::ChunkOfPages *ExecutableAllocator::chunkForAllocation(Alloc
if (it != chunks.begin())
--it;
if (it == chunks.end())
- return 0;
+ return nullptr;
return *it;
}
diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h
index dad02d9560..19eaed8723 100644
--- a/src/qml/jsruntime/qv4executableallocator_p.h
+++ b/src/qml/jsruntime/qv4executableallocator_p.h
@@ -82,11 +82,8 @@ public:
struct Allocation
{
Allocation()
- : addr(0)
- , size(0)
+ : size(0)
, free(true)
- , next(0)
- , prev(0)
{}
void *start() const;
@@ -103,16 +100,16 @@ public:
bool mergeNext(ExecutableAllocator *allocator);
bool mergePrevious(ExecutableAllocator *allocator);
- quintptr addr;
#ifndef QT_NO_BITFIELDS
+ quintptr addr = 0;
uint size : 31; // More than 2GB of function code? nah :)
uint free : 1;
#else
uint size = 31; // More than 2GB of function code? nah :)
uint free = 1;
#endif
- Allocation *next;
- Allocation *prev;
+ Allocation *next = nullptr;
+ Allocation *prev = nullptr;
};
// for debugging / unit-testing
@@ -122,13 +119,12 @@ public:
struct ChunkOfPages
{
ChunkOfPages()
- : pages(0)
- , firstAllocation(0)
+
{}
~ChunkOfPages();
- WTF::PageAllocation *pages;
- Allocation *firstAllocation;
+ WTF::PageAllocation *pages = nullptr;
+ Allocation *firstAllocation = nullptr;
bool contains(Allocation *alloc) const;
};
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 0e61be5115..4c8c790ca7 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -83,6 +83,7 @@ struct Q_QML_EXPORT Function {
// first nArguments names in internalClass are the actual arguments
InternalClass *internalClass;
uint nFormals;
+ int interpreterCallCount = 0;
bool hasQmlDependencies;
Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function, Code codePtr);
@@ -95,6 +96,7 @@ struct Q_QML_EXPORT Function {
return compilationUnit->runtimeStrings[compiledFunction->nameIndex];
}
inline QString sourceFile() const { return compilationUnit->fileName(); }
+ inline QUrl finalUrl() const { return compilationUnit->finalUrl(); }
inline bool usesArgumentsObject() const { return compiledFunction->flags & CompiledData::Function::UsesArgumentsObject; }
inline bool isStrict() const { return compiledFunction->flags & CompiledData::Function::IsStrict; }
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 4293d43791..a8c1640767 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -232,7 +232,7 @@ ReturnedValue FunctionCtor::callAsConstructor(const FunctionObject *f, const Val
if (!fe)
return scope.engine->throwSyntaxError(QLatin1String("Parse error"));
- Compiler::Module module(scope.engine->debugger() != 0);
+ Compiler::Module module(scope.engine->debugger() != nullptr);
Compiler::JSUnitGenerator jsGenerator(&module);
RuntimeCodegen cg(scope.engine, &jsGenerator, false);
@@ -351,7 +351,7 @@ ReturnedValue FunctionPrototype::method_bind(const FunctionObject *b, const Valu
return scope.engine->throwTypeError();
ScopedValue boundThis(scope, argc ? argv[0] : Primitive::undefinedValue());
- Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)0);
+ Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)nullptr);
if (argc > 1) {
boundArgs = MemberData::allocate(scope.engine, argc - 1);
boundArgs->d()->values.size = argc - 1;
@@ -430,27 +430,6 @@ InternalClass *ScriptFunction::classForConstructor() const
return ic;
}
-DEFINE_OBJECT_VTABLE(BuiltinFunction);
-
-void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(const QV4::BuiltinFunction *, CallData *))
-{
- Heap::FunctionObject::init(scope, name);
- this->code = code;
-}
-
-ReturnedValue BuiltinFunction::callAsConstructor(const QV4::FunctionObject *f, const Value *, int)
-{
- return f->engine()->throwTypeError();
-}
-
-ReturnedValue BuiltinFunction::call(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc)
-{
- const BuiltinFunction *f = static_cast<const BuiltinFunction *>(fo);
- Scope scope(f->engine());
- JSCallData callData(scope, argc, argv, thisObject);
- return f->d()->code(f, callData.callData());
-}
-
DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
DEFINE_OBJECT_VTABLE(BoundFunction);
@@ -461,7 +440,7 @@ void Heap::BoundFunction::init(QV4::ExecutionContext *scope, QV4::FunctionObject
Scope s(scope);
Heap::FunctionObject::init(scope, QStringLiteral("__bound function__"));
this->target.set(s.engine, target->d());
- this->boundArgs.set(s.engine, boundArgs ? boundArgs->d() : 0);
+ this->boundArgs.set(s.engine, boundArgs ? boundArgs->d() : nullptr);
this->boundThis.set(scope->engine(), boundThis);
ScopedObject f(s, this);
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index d61006a6b0..d6066ec648 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -61,7 +61,6 @@ struct QQmlSourceLocation;
namespace QV4 {
-struct BuiltinFunction;
struct IndexedBuiltinFunction;
struct JSCallData;
@@ -84,8 +83,8 @@ DECLARE_HEAP_OBJECT(FunctionObject, Object) {
Index_ProtoConstructor = 0
};
- void init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(const QV4::FunctionObject *, const Value *thisObject, const Value *argv, int argc));
- void init(QV4::ExecutionContext *scope, QV4::String *name = 0, bool createProto = false);
+ Q_QML_PRIVATE_EXPORT void init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(const QV4::FunctionObject *, const Value *thisObject, const Value *argv, int argc));
+ void init(QV4::ExecutionContext *scope, QV4::String *name = nullptr, bool createProto = false);
void init(QV4::ExecutionContext *scope, QV4::Function *function, bool createProto = false);
void init(QV4::ExecutionContext *scope, const QString &name, bool createProto = false);
void init();
@@ -105,13 +104,8 @@ struct FunctionPrototype : FunctionObject {
void init();
};
-struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
- void init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(const QV4::BuiltinFunction *, CallData *));
- ReturnedValue (*code)(const QV4::BuiltinFunction *, CallData *);
-};
-
-struct IndexedBuiltinFunction : BuiltinFunction {
- inline void init(QV4::ExecutionContext *scope, uint index, ReturnedValue (*code)(const QV4::BuiltinFunction *, CallData *));
+struct IndexedBuiltinFunction : FunctionObject {
+ inline void init(QV4::ExecutionContext *scope, uint index, ReturnedValue (*code)(const QV4::FunctionObject *, const Value *, const Value *, int));
uint index;
};
@@ -170,6 +164,11 @@ struct Q_QML_EXPORT FunctionObject: Object {
static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function);
+ static Heap::FunctionObject *createBuiltinFunction(ExecutionContext *scope, String *name,
+ ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc))
+ {
+ return scope->engine()->memoryManager->allocObject<FunctionObject>(scope, name, code);
+ }
bool strictMode() const { return d()->function ? d()->function->isStrict() : false; }
bool isBinding() const;
@@ -180,7 +179,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
template<>
inline const FunctionObject *Value::as() const {
- return isManaged() && m()->vtable()->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : 0;
+ return isManaged() && m()->vtable()->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : nullptr;
}
@@ -204,34 +203,16 @@ struct FunctionPrototype: FunctionObject
static ReturnedValue method_bind(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
-struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
- V4_OBJECT2(BuiltinFunction, FunctionObject)
- V4_INTERNALCLASS(BuiltinFunction)
-
- static Heap::BuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(const BuiltinFunction *, CallData *))
- {
- return scope->engine()->memoryManager->allocObject<BuiltinFunction>(scope, name, code);
- }
-
- static Heap::FunctionObject *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc))
- {
- return scope->engine()->memoryManager->allocObject<FunctionObject>(scope, name, code);
- }
-
- static ReturnedValue callAsConstructor(const FunctionObject *, const Value *argv, int argc);
- static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
-};
-
-struct IndexedBuiltinFunction: BuiltinFunction
+struct IndexedBuiltinFunction : FunctionObject
{
- V4_OBJECT2(IndexedBuiltinFunction, BuiltinFunction)
+ V4_OBJECT2(IndexedBuiltinFunction, FunctionObject)
};
void Heap::IndexedBuiltinFunction::init(QV4::ExecutionContext *scope, uint index,
- ReturnedValue (*code)(const QV4::BuiltinFunction *, CallData *))
+ ReturnedValue (*code)(const QV4::FunctionObject *, const Value *thisObject, const Value *argv, int argc))
{
Heap::FunctionObject::init(scope);
- this->code = code;
+ this->jsCall = code;
this->index = index;
}
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 29eddc864d..382dd9b7e1 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -76,9 +76,6 @@ namespace std {
inline bool isinf(double d) { return !_finite(d) && !_isnan(d); }
inline bool isnan(double d) { return !!_isnan(d); }
inline bool isfinite(double d) { return _finite(d); }
-#if _MSC_VER < 1800
-inline bool signbit(double d) { return _copysign(1.0, d) < 0; }
-#endif
} // namespace std
@@ -95,7 +92,7 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
&& (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD))
# define V4_ENABLE_JIT
#elif defined(Q_PROCESSOR_X86_64) && (QT_POINTER_SIZE == 8) \
- && (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD))
+ && (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_MAC) || defined(Q_OS_FREEBSD))
# define V4_ENABLE_JIT
#elif defined(Q_PROCESSOR_ARM_32) && (QT_POINTER_SIZE == 4)
# if defined(thumb2) || defined(__thumb2__) || ((defined(__thumb) || defined(__thumb__)) && __TARGET_ARCH_THUMB-0 == 4)
@@ -104,7 +101,7 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
# define V4_ENABLE_JIT
# endif
#elif defined(Q_PROCESSOR_ARM_64) && (QT_POINTER_SIZE == 8)
-# if defined(Q_OS_LINUX)
+# if defined(Q_OS_LINUX) || defined(Q_OS_QNX)
# define V4_ENABLE_JIT
# endif
//#elif defined(Q_PROCESSOR_MIPS_32) && defined(Q_OS_LINUX)
@@ -211,7 +208,6 @@ struct StringObject;
struct ArrayObject;
struct DateObject;
struct FunctionObject;
-struct BuiltinFunction;
struct ErrorObject;
struct ArgumentsObject;
struct Managed;
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 3214a716e8..f419ab53fe 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -375,12 +375,12 @@ ReturnedValue EvalFunction::evalCall(const Value *, const Value *argv, int argc,
if (function->isStrict() || isStrict) {
ScopedFunctionObject e(scope, FunctionObject::createScriptFunction(ctx, function));
ScopedValue thisObject(scope, directCall ? scope.engine->currentStackFrame->thisObject() : scope.engine->globalObject->asReturnedValue());
- return e->call(thisObject, 0, 0);
+ return e->call(thisObject, nullptr, 0);
}
ScopedValue thisObject(scope, scope.engine->currentStackFrame->thisObject());
- return function->call(thisObject, 0, 0, ctx);
+ return function->call(thisObject, nullptr, 0, ctx);
}
@@ -507,7 +507,7 @@ ReturnedValue GlobalFunctions::method_parseFloat(const FunctionObject *b, const
QByteArray ba = trimmed.toLatin1();
bool ok;
const char *begin = ba.constData();
- const char *end = 0;
+ const char *end = nullptr;
double d = qstrtod(begin, &end, &ok);
if (end - begin == 0)
RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN())); // 3
diff --git a/src/qml/jsruntime/qv4identifier.cpp b/src/qml/jsruntime/qv4identifier.cpp
index e35f72b820..c122bcb51a 100644
--- a/src/qml/jsruntime/qv4identifier.cpp
+++ b/src/qml/jsruntime/qv4identifier.cpp
@@ -75,13 +75,13 @@ IdentifierHashData::IdentifierHashData(IdentifierHashData *other)
memcpy(entries, other->entries, alloc*sizeof(IdentifierHashEntry));
}
-IdentifierHashBase::IdentifierHashBase(ExecutionEngine *engine)
+IdentifierHash::IdentifierHash(ExecutionEngine *engine)
{
d = new IdentifierHashData(3);
d->identifierTable = engine->identifierTable;
}
-void IdentifierHashBase::detach()
+void IdentifierHash::detach()
{
if (!d || d->refCount == 1)
return;
@@ -92,7 +92,7 @@ void IdentifierHashBase::detach()
}
-IdentifierHashEntry *IdentifierHashBase::addEntry(const Identifier *identifier)
+IdentifierHashEntry *IdentifierHash::addEntry(const Identifier *identifier)
{
// fill up to max 50%
bool grow = (d->alloc <= d->size*2);
@@ -129,16 +129,16 @@ IdentifierHashEntry *IdentifierHashBase::addEntry(const Identifier *identifier)
return d->entries + idx;
}
-const IdentifierHashEntry *IdentifierHashBase::lookup(const Identifier *identifier) const
+const IdentifierHashEntry *IdentifierHash::lookup(const Identifier *identifier) const
{
if (!d)
- return 0;
+ return nullptr;
Q_ASSERT(d->entries);
uint idx = identifier->hashValue % d->alloc;
while (1) {
if (!d->entries[idx].identifier)
- return 0;
+ return nullptr;
if (d->entries[idx].identifier == identifier)
return d->entries + idx;
++idx;
@@ -146,17 +146,17 @@ const IdentifierHashEntry *IdentifierHashBase::lookup(const Identifier *identifi
}
}
-const IdentifierHashEntry *IdentifierHashBase::lookup(const QString &str) const
+const IdentifierHashEntry *IdentifierHash::lookup(const QString &str) const
{
if (!d)
- return 0;
+ return nullptr;
Q_ASSERT(d->entries);
uint hash = String::createHashValue(str.constData(), str.length(), nullptr);
uint idx = hash % d->alloc;
while (1) {
if (!d->entries[idx].identifier)
- return 0;
+ return nullptr;
if (d->entries[idx].identifier->string == str)
return d->entries + idx;
++idx;
@@ -164,22 +164,22 @@ const IdentifierHashEntry *IdentifierHashBase::lookup(const QString &str) const
}
}
-const IdentifierHashEntry *IdentifierHashBase::lookup(String *str) const
+const IdentifierHashEntry *IdentifierHash::lookup(String *str) const
{
if (!d)
- return 0;
+ return nullptr;
if (str->d()->identifier)
return lookup(str->d()->identifier);
return lookup(str->toQString());
}
-const Identifier *IdentifierHashBase::toIdentifier(const QString &str) const
+const Identifier *IdentifierHash::toIdentifier(const QString &str) const
{
Q_ASSERT(d);
return d->identifierTable->identifier(str);
}
-const Identifier *IdentifierHashBase::toIdentifier(Heap::String *str) const
+const Identifier *IdentifierHash::toIdentifier(Heap::String *str) const
{
Q_ASSERT(d);
return d->identifierTable->identifier(str);
diff --git a/src/qml/jsruntime/qv4identifier_p.h b/src/qml/jsruntime/qv4identifier_p.h
index 2695bbc875..82346d5f68 100644
--- a/src/qml/jsruntime/qv4identifier_p.h
+++ b/src/qml/jsruntime/qv4identifier_p.h
@@ -73,13 +73,7 @@ struct Identifier
struct IdentifierHashEntry {
const Identifier *identifier;
- union {
- int value;
- void *pointer;
- };
- static int get(const IdentifierHashEntry *This, int *) { return This ? This->value : -1; }
- static bool get(const IdentifierHashEntry *This, bool *) { return This != 0; }
- static void *get(const IdentifierHashEntry *This, void **) { return This ? This->pointer : 0; }
+ int value;
};
struct IdentifierHashData
@@ -98,26 +92,30 @@ struct IdentifierHashData
IdentifierHashEntry *entries;
};
-struct IdentifierHashBase
+struct IdentifierHash
{
- IdentifierHashData *d;
+ IdentifierHashData *d = nullptr;
- IdentifierHashBase() : d(0) {}
- IdentifierHashBase(ExecutionEngine *engine);
- inline IdentifierHashBase(const IdentifierHashBase &other);
- inline ~IdentifierHashBase();
- inline IdentifierHashBase &operator=(const IdentifierHashBase &other);
+ IdentifierHash() {}
+ IdentifierHash(ExecutionEngine *engine);
+ inline IdentifierHash(const IdentifierHash &other);
+ inline ~IdentifierHash();
+ inline IdentifierHash &operator=(const IdentifierHash &other);
bool isEmpty() const { return !d; }
inline int count() const;
- bool contains(const Identifier *i) const;
- bool contains(const QString &str) const;
- bool contains(String *str) const;
void detach();
+ void add(const QString &str, int value);
+ void add(Heap::String *str, int value);
+
+ inline int value(const QString &str) const;
+ inline int value(String *str) const;
+ QString findId(int value) const;
+
protected:
IdentifierHashEntry *addEntry(const Identifier *i);
const IdentifierHashEntry *lookup(const Identifier *identifier) const;
@@ -128,43 +126,20 @@ protected:
};
-template<typename T>
-struct IdentifierHash : public IdentifierHashBase
-{
- IdentifierHash()
- : IdentifierHashBase() {}
- IdentifierHash(ExecutionEngine *engine)
- : IdentifierHashBase(engine) {}
- inline IdentifierHash(const IdentifierHash<T> &other)
- : IdentifierHashBase(other) {}
- inline ~IdentifierHash() {}
- inline IdentifierHash &operator=(const IdentifierHash<T> &other) {
- IdentifierHashBase::operator =(other);
- return *this;
- }
-
- void add(const QString &str, const T &value);
- void add(Heap::String *str, const T &value);
-
- inline T value(const QString &str) const;
- inline T value(String *str) const;
- QString findId(T value) const;
-};
-
-inline IdentifierHashBase::IdentifierHashBase(const IdentifierHashBase &other)
+inline IdentifierHash::IdentifierHash(const IdentifierHash &other)
{
d = other.d;
if (d)
d->refCount.ref();
}
-inline IdentifierHashBase::~IdentifierHashBase()
+inline IdentifierHash::~IdentifierHash()
{
if (d && !d->refCount.deref())
delete d;
}
-IdentifierHashBase &IdentifierHashBase::operator=(const IdentifierHashBase &other)
+IdentifierHash &IdentifierHash::operator=(const IdentifierHash &other)
{
if (other.d)
other.d->refCount.ref();
@@ -174,60 +149,45 @@ IdentifierHashBase &IdentifierHashBase::operator=(const IdentifierHashBase &othe
return *this;
}
-inline int IdentifierHashBase::count() const
+inline int IdentifierHash::count() const
{
return d ? d->size : 0;
}
-inline bool IdentifierHashBase::contains(const Identifier *i) const
-{
- return lookup(i) != 0;
-}
-
-inline bool IdentifierHashBase::contains(const QString &str) const
-{
- return lookup(str) != 0;
-}
-
-inline bool IdentifierHashBase::contains(String *str) const
-{
- return lookup(str) != 0;
-}
-
-template<typename T>
-void IdentifierHash<T>::add(const QString &str, const T &value)
+inline
+void IdentifierHash::add(const QString &str, int value)
{
IdentifierHashEntry *e = addEntry(toIdentifier(str));
e->value = value;
}
-template<typename T>
-void IdentifierHash<T>::add(Heap::String *str, const T &value)
+inline
+void IdentifierHash::add(Heap::String *str, int value)
{
IdentifierHashEntry *e = addEntry(toIdentifier(str));
e->value = value;
}
-template<typename T>
-inline T IdentifierHash<T>::value(const QString &str) const
+inline int IdentifierHash::value(const QString &str) const
{
- return IdentifierHashEntry::get(lookup(str), (T*)0);
+ const IdentifierHashEntry *e = lookup(str);
+ return e ? e->value : -1;
}
-template<typename T>
-inline T IdentifierHash<T>::value(String *str) const
+inline int IdentifierHash::value(String *str) const
{
- return IdentifierHashEntry::get(lookup(str), (T*)0);
+ const IdentifierHashEntry *e = lookup(str);
+ return e ? e->value : -1;
}
-template<typename T>
-QString IdentifierHash<T>::findId(T value) const
+inline
+QString IdentifierHash::findId(int value) const
{
IdentifierHashEntry *e = d->entries;
IdentifierHashEntry *end = e + d->alloc;
while (e < end) {
- if (e->identifier && IdentifierHashEntry::get(e, (T*)0) == value)
+ if (e->identifier && e->value == value)
return e->identifier->string;
++e;
}
diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp
index 3def6defbf..b77f9478d3 100644
--- a/src/qml/jsruntime/qv4identifiertable.cpp
+++ b/src/qml/jsruntime/qv4identifiertable.cpp
@@ -142,7 +142,7 @@ Identifier *IdentifierTable::identifierImpl(const Heap::String *str)
return str->identifier;
uint hash = str->hashValue();
if (str->subtype == Heap::String::StringType_ArrayIndex)
- return 0;
+ return nullptr;
uint idx = hash % alloc;
while (Heap::String *e = entries[idx]) {
@@ -161,7 +161,7 @@ Identifier *IdentifierTable::identifierImpl(const Heap::String *str)
Heap::String *IdentifierTable::stringFromIdentifier(Identifier *i)
{
if (!i)
- return 0;
+ return nullptr;
uint idx = i->hashValue % alloc;
while (1) {
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 3e04ed63df..aaf5e3b857 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -61,7 +61,7 @@ QV4Include::QV4Include(const QUrl &url, QV4::ExecutionEngine *engine,
QV4::QmlContext *qmlContext, const QV4::Value &callback)
: v4(engine), m_url(url)
#if QT_CONFIG(qml_network)
- , m_redirectCount(0), m_network(0) , m_reply(0)
+ , m_redirectCount(0), m_network(nullptr) , m_reply(nullptr)
#endif
{
if (qmlContext)
@@ -88,7 +88,7 @@ QV4Include::~QV4Include()
{
#if QT_CONFIG(qml_network)
delete m_reply;
- m_reply = 0;
+ m_reply = nullptr;
#endif
}
@@ -196,10 +196,10 @@ void QV4Include::finished()
/*
Documented in qv8engine.cpp
*/
-QV4::ReturnedValue QV4Include::method_include(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+QV4::ReturnedValue QV4Include::method_include(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- if (!callData->argc())
+ if (!argc)
RETURN_UNDEFINED();
QQmlContextData *context = scope.engine->callingQmlContext();
@@ -208,11 +208,11 @@ QV4::ReturnedValue QV4Include::method_include(const QV4::BuiltinFunction *b, QV4
RETURN_RESULT(scope.engine->throwError(QString::fromUtf8("Qt.include(): Can only be called from JavaScript files")));
QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue());
- if (callData->argc() >= 2 && callData->args[1].as<QV4::FunctionObject>())
- callbackFunction = callData->args[1];
+ if (argc >= 2 && argv[1].as<QV4::FunctionObject>())
+ callbackFunction = argv[1];
#if QT_CONFIG(qml_network)
- QUrl url(scope.engine->resolvedUrl(callData->args[0].toQStringNoThrow()));
+ QUrl url(scope.engine->resolvedUrl(argv[0].toQStringNoThrow()));
if (scope.engine->qmlEngine() && scope.engine->qmlEngine()->urlInterceptor())
url = scope.engine->qmlEngine()->urlInterceptor()->intercept(url, QQmlAbstractUrlInterceptor::JavaScriptFile);
@@ -227,21 +227,7 @@ QV4::ReturnedValue QV4Include::method_include(const QV4::BuiltinFunction *b, QV4
} else {
QScopedPointer<QV4::Script> script;
-
- if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url)) {
- QV4::CompiledData::CompilationUnit *jsUnit = cachedUnit->createCompilationUnit();
- script.reset(new QV4::Script(scope.engine, qmlcontext, jsUnit));
- } else {
- QFile f(localFile);
-
- if (f.open(QIODevice::ReadOnly)) {
- QByteArray data = f.readAll();
- QString code = QString::fromUtf8(data);
- QmlIR::Document::removeScriptPragmas(code);
-
- script.reset(new QV4::Script(scope.engine, qmlcontext, code, url.toString()));
- }
- }
+ script.reset(QV4::Script::createFromFileOrCache(scope.engine, qmlcontext, localFile, url));
if (!script.isNull()) {
script->parse();
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index 68537ba2e8..8015722afc 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -77,7 +77,7 @@ public:
Exception = 3
};
- static QV4::ReturnedValue method_include(const QV4::BuiltinFunction *, QV4::CallData *callData);
+ static QV4::ReturnedValue method_include(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
private Q_SLOTS:
void finished();
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index d439884ca2..9da854e7d7 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -105,10 +105,10 @@ void PropertyHash::addEntry(const PropertyHash::Entry &entry, int classSize)
InternalClass::InternalClass(ExecutionEngine *engine)
: engine(engine)
- , vtable(0)
- , prototype(0)
- , m_sealed(0)
- , m_frozen(0)
+ , vtable(nullptr)
+ , prototype(nullptr)
+ , m_sealed(nullptr)
+ , m_frozen(nullptr)
, size(0)
, extensible(true)
{
@@ -124,8 +124,8 @@ InternalClass::InternalClass(const QV4::InternalClass &other)
, propertyTable(other.propertyTable)
, nameMap(other.nameMap)
, propertyData(other.propertyData)
- , m_sealed(0)
- , m_frozen(0)
+ , m_sealed(nullptr)
+ , m_frozen(nullptr)
, size(other.size)
, extensible(other.extensible)
, isUsedAsProto(other.isUsedAsProto)
@@ -149,6 +149,9 @@ static void removeFromPropertyData(Object *object, int idx, bool accessor = fals
int size = o->internalClass->size;
for (int i = idx; i < size; ++i)
o->setProperty(v4, i, *o->propertyData(i + (accessor ? 2 : 1)));
+ o->setProperty(v4, size, Primitive::undefinedValue());
+ if (accessor)
+ o->setProperty(v4, size + 1, Primitive::undefinedValue());
}
void InternalClass::changeMember(Object *object, String *string, PropertyAttributes data, uint *index)
@@ -220,7 +223,7 @@ InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto)
Q_ASSERT(prototype != proto);
Q_ASSERT(!proto || proto->internalClass->isUsedAsProto);
- Transition temp = { { nullptr }, 0, Transition::PrototypeChange };
+ Transition temp = { { nullptr }, nullptr, Transition::PrototypeChange };
temp.prototype = proto;
Transition &t = lookupOrInsertTransition(temp);
@@ -484,7 +487,7 @@ void InternalClass::destroy()
destroyStack.pop_back();
if (!next->engine)
continue;
- next->engine = 0;
+ next->engine = nullptr;
next->propertyTable.~PropertyHash();
next->nameMap.~SharedInternalClassData<Identifier *>();
next->propertyData.~SharedInternalClassData<PropertyAttributes>();
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index 546073dcf5..b689272006 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -277,10 +277,10 @@ struct InternalClass : public QQmlJS::Managed {
}
static void addMember(Object *object, String *string, PropertyAttributes data, uint *index);
- Q_REQUIRED_RESULT InternalClass *addMember(String *string, PropertyAttributes data, uint *index = 0);
- Q_REQUIRED_RESULT InternalClass *addMember(Identifier *identifier, PropertyAttributes data, uint *index = 0);
- Q_REQUIRED_RESULT InternalClass *changeMember(Identifier *identifier, PropertyAttributes data, uint *index = 0);
- static void changeMember(Object *object, String *string, PropertyAttributes data, uint *index = 0);
+ Q_REQUIRED_RESULT InternalClass *addMember(String *string, PropertyAttributes data, uint *index = nullptr);
+ Q_REQUIRED_RESULT InternalClass *addMember(Identifier *identifier, PropertyAttributes data, uint *index = nullptr);
+ Q_REQUIRED_RESULT InternalClass *changeMember(Identifier *identifier, PropertyAttributes data, uint *index = nullptr);
+ static void changeMember(Object *object, String *string, PropertyAttributes data, uint *index = nullptr);
static void removeMember(Object *object, Identifier *id);
uint find(const String *string);
uint find(const Identifier *id)
diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h
index 6d641bf9c5..c676b57c51 100644
--- a/src/qml/jsruntime/qv4jscall_p.h
+++ b/src/qml/jsruntime/qv4jscall_p.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct JSCallData {
- JSCallData(const Scope &scope, int argc = 0, const Value *argv = 0, const Value *thisObject = 0)
+ JSCallData(const Scope &scope, int argc = 0, const Value *argv = nullptr, const Value *thisObject = nullptr)
: scope(scope), argc(argc)
{
if (thisObject)
@@ -124,7 +124,7 @@ struct ScopedStackFrame {
return;
frame.jsFrame = reinterpret_cast<CallData *>(scope.alloc(sizeof(CallData)/sizeof(Value)));
frame.jsFrame->context = context;
- frame.v4Function = frame.parent ? frame.parent->v4Function : 0;
+ frame.v4Function = frame.parent ? frame.parent->v4Function : nullptr;
scope.engine->currentStackFrame = &frame;
}
~ScopedStackFrame() {
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 5e580b8b4d..99666806be 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -634,7 +634,7 @@ struct Stringify
return false;
}
- Stringify(ExecutionEngine *e) : v4(e), replacerFunction(0), propertyList(0), propertyListSize(0) {}
+ Stringify(ExecutionEngine *e) : v4(e), replacerFunction(nullptr), propertyList(nullptr), propertyListSize(0) {}
QString Str(const QString &key, const Value &v);
QString JA(ArrayObject *a);
@@ -884,12 +884,12 @@ void Heap::JsonObject::init()
}
-ReturnedValue JsonObject::method_parse(const BuiltinFunction *b, CallData *callData)
+ReturnedValue JsonObject::method_parse(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
ExecutionEngine *v4 = b->engine();
QString jtext;
- if (callData->argc() > 0)
- jtext = callData->args[0].toQString();
+ if (argc > 0)
+ jtext = argv[0].toQString();
DEBUG << "parsing source = " << jtext;
JsonParser parser(v4, jtext.constData(), jtext.length());
@@ -903,12 +903,12 @@ ReturnedValue JsonObject::method_parse(const BuiltinFunction *b, CallData *callD
return result;
}
-ReturnedValue JsonObject::method_stringify(const BuiltinFunction *b, CallData *callData)
+ReturnedValue JsonObject::method_stringify(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
Scope scope(b);
Stringify stringify(scope.engine);
- ScopedObject o(scope, callData->argument(1));
+ ScopedObject o(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
if (o) {
stringify.replacerFunction = o->as<FunctionObject>();
if (o->isArrayObject()) {
@@ -920,11 +920,11 @@ ReturnedValue JsonObject::method_stringify(const BuiltinFunction *b, CallData *c
if (v->as<NumberObject>() || v->as<StringObject>() || v->isNumber())
*v = v->toString(scope.engine);
if (!v->isString()) {
- v->setM(0);
+ v->setM(nullptr);
} else {
for (uint j = 0; j <i; ++j) {
if (stringify.propertyList[j].m() == v->m()) {
- v->setM(0);
+ v->setM(nullptr);
break;
}
}
@@ -933,7 +933,7 @@ ReturnedValue JsonObject::method_stringify(const BuiltinFunction *b, CallData *c
}
}
- ScopedValue s(scope, callData->argument(2));
+ ScopedValue s(scope, argc > 2 ? argv[2] : Primitive::undefinedValue());
if (NumberObject *n = s->as<NumberObject>())
s = Encode(n->value());
else if (StringObject *so = s->as<StringObject>())
@@ -946,7 +946,7 @@ ReturnedValue JsonObject::method_stringify(const BuiltinFunction *b, CallData *c
}
- ScopedValue arg0(scope, callData->argument(0));
+ ScopedValue arg0(scope, argc ? argv[0] : Primitive::undefinedValue());
QString result = stringify.Str(QString(), arg0);
if (result.isEmpty() || scope.engine->hasException)
RETURN_UNDEFINED();
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index 19dba14aef..7d9f204910 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -88,8 +88,8 @@ private:
typedef QSet<ObjectItem> V4ObjectSet;
public:
- static ReturnedValue method_parse(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_stringify(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_parse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_stringify(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value);
static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object);
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index 200380eda0..b50e5f0355 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -46,7 +46,7 @@ using namespace QV4;
const VTable Managed::static_vtbl =
{
- 0,
+ nullptr,
0,
0,
Managed::IsExecutionContext,
@@ -58,15 +58,15 @@ const VTable Managed::static_vtbl =
0,
Managed::MyType,
"Managed",
- 0,
- 0 /*markObjects*/,
+ nullptr,
+ nullptr /*markObjects*/,
isEqualTo
};
QString Managed::className() const
{
- const char *s = 0;
+ const char *s = nullptr;
switch (Type(d()->vtable()->type)) {
case Type_Invalid:
case Type_String:
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index f81dcf9479..092c61b81c 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -93,7 +93,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
dptr->_checkIsInitialized(); \
return dptr; \
} \
- V4_ASSERT_IS_TRIVIAL(QV4::Heap::DataClass)
+ Q_STATIC_ASSERT(std::is_trivial< QV4::Heap::DataClass >::value);
#define V4_MANAGED(DataClass, superClass) \
private: \
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index 252ec345d9..0c18d908de 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -277,7 +277,7 @@ ReturnedValue MathObject::method_pow(const FunctionObject *, const Value *, cons
ReturnedValue MathObject::method_random(const FunctionObject *, const Value *, const Value *, int)
{
- RETURN_RESULT(Encode(QRandomGenerator::getReal()));
+ RETURN_RESULT(Encode(QRandomGenerator::global()->generateDouble()));
}
ReturnedValue MathObject::method_round(const FunctionObject *, const Value *, const Value *argv, int argc)
diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h
index 3e231d693b..ac9671254d 100644
--- a/src/qml/jsruntime/qv4memberdata_p.h
+++ b/src/qml/jsruntime/qv4memberdata_p.h
@@ -65,7 +65,7 @@ namespace Heap {
DECLARE_HEAP_OBJECT(MemberData, Base) {
DECLARE_MARKOBJECTS(MemberData);
};
-V4_ASSERT_IS_TRIVIAL(MemberData)
+Q_STATIC_ASSERT(std::is_trivial< MemberData >::value);
}
@@ -79,7 +79,7 @@ struct MemberData : Managed
Value *slot;
void set(EngineBase *e, Value newVal) {
- WriteBarrier::write(e, base, slot, newVal);
+ WriteBarrier::write(e, base, slot->data_ptr(), newVal.asReturnedValue());
}
const Value *operator->() const { return slot; }
const Value &operator*() const { return *slot; }
@@ -93,7 +93,7 @@ struct MemberData : Managed
inline uint size() const { return d()->values.size; }
- static Heap::MemberData *allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old = 0);
+ static Heap::MemberData *allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old = nullptr);
};
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index b4034fd196..8e9bf794a9 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -94,7 +94,7 @@ void Heap::Object::setUsedAsProto()
bool Object::setPrototype(Object *proto)
{
- Heap::Object *p = proto ? proto->d() : 0;
+ Heap::Object *p = proto ? proto->d() : nullptr;
Heap::Object *pp = p;
while (pp) {
if (pp == d())
@@ -156,34 +156,13 @@ void Object::defineDefaultProperty(const QString &name, const Value &value)
defineDefaultProperty(s, value);
}
-void Object::defineDefaultProperty(const QString &name, ReturnedValue (*code)(const BuiltinFunction *, CallData *), int argumentCount)
-{
- ExecutionEngine *e = engine();
- Scope scope(e);
- ScopedString s(scope, e->newIdentifier(name));
- ExecutionContext *global = e->rootContext();
- ScopedFunctionObject function(scope, BuiltinFunction::create(global, s, code));
- function->defineReadonlyConfigurableProperty(e->id_length(), Primitive::fromInt32(argumentCount));
- defineDefaultProperty(s, function);
-}
-
-void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(const BuiltinFunction *, CallData *), int argumentCount)
-{
- ExecutionEngine *e = engine();
- Scope scope(e);
- ExecutionContext *global = e->rootContext();
- ScopedFunctionObject function(scope, BuiltinFunction::create(global, name, code));
- function->defineReadonlyConfigurableProperty(e->id_length(), Primitive::fromInt32(argumentCount));
- defineDefaultProperty(name, function);
-}
-
void Object::defineDefaultProperty(const QString &name, ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc), int argumentCount)
{
ExecutionEngine *e = engine();
Scope scope(e);
ScopedString s(scope, e->newIdentifier(name));
ExecutionContext *global = e->rootContext();
- ScopedFunctionObject function(scope, BuiltinFunction::create(global, s, code));
+ ScopedFunctionObject function(scope, FunctionObject::createBuiltinFunction(global, s, code));
function->defineReadonlyConfigurableProperty(e->id_length(), Primitive::fromInt32(argumentCount));
defineDefaultProperty(s, function);
}
@@ -193,32 +172,11 @@ void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(const Fun
ExecutionEngine *e = engine();
Scope scope(e);
ExecutionContext *global = e->rootContext();
- ScopedFunctionObject function(scope, BuiltinFunction::create(global, name, code));
+ ScopedFunctionObject function(scope, FunctionObject::createBuiltinFunction(global, name, code));
function->defineReadonlyConfigurableProperty(e->id_length(), Primitive::fromInt32(argumentCount));
defineDefaultProperty(name, function);
}
-void Object::defineAccessorProperty(const QString &name, ReturnedValue (*getter)(const BuiltinFunction *, CallData *),
- ReturnedValue (*setter)(const BuiltinFunction *, CallData *))
-{
- ExecutionEngine *e = engine();
- Scope scope(e);
- ScopedString s(scope, e->newIdentifier(name));
- defineAccessorProperty(s, getter, setter);
-}
-
-void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(const BuiltinFunction *, CallData *),
- ReturnedValue (*setter)(const BuiltinFunction *, CallData *))
-{
- ExecutionEngine *v4 = engine();
- QV4::Scope scope(v4);
- ScopedProperty p(scope);
- ExecutionContext *global = v4->rootContext();
- p->setGetter(ScopedFunctionObject(scope, (getter ? BuiltinFunction::create(global, name, getter) : 0)));
- p->setSetter(ScopedFunctionObject(scope, (setter ? BuiltinFunction::create(global, name, setter) : 0)));
- insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
-}
-
void Object::defineAccessorProperty(const QString &name, ReturnedValue (*getter)(const FunctionObject *, const Value *, const Value *, int),
ReturnedValue (*setter)(const FunctionObject *, const Value *, const Value *, int))
{
@@ -235,8 +193,8 @@ void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(const
QV4::Scope scope(v4);
ScopedProperty p(scope);
ExecutionContext *global = v4->rootContext();
- p->setGetter(ScopedFunctionObject(scope, (getter ? BuiltinFunction::create(global, name, getter) : 0)));
- p->setSetter(ScopedFunctionObject(scope, (setter ? BuiltinFunction::create(global, name, setter) : 0)));
+ p->setGetter(ScopedFunctionObject(scope, (getter ? FunctionObject::createBuiltinFunction(global, name, getter) : nullptr)));
+ p->setSetter(ScopedFunctionObject(scope, (setter ? FunctionObject::createBuiltinFunction(global, name, setter) : nullptr)));
insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
@@ -268,11 +226,6 @@ void Object::defineReadonlyConfigurableProperty(String *name, const Value &value
insertMember(name, value, Attr_ReadOnly_ButConfigurable);
}
-void Object::markObjects(Heap::Base *base, MarkStack *stack)
-{
- Heap::Object::markObjects(base, stack);
-}
-
void Heap::Object::markObjects(Heap::Base *b, MarkStack *stack)
{
Object *o = static_cast<Object *>(b);
@@ -368,7 +321,7 @@ MemberData::Index Object::getValueOrSetter(String *name, PropertyAttributes *att
o = o->prototype();
}
*attrs = Attr_Invalid;
- return { 0, 0 };
+ return { nullptr, nullptr };
}
ArrayData::Index Object::getValueOrSetter(uint index, PropertyAttributes *attrs)
@@ -393,7 +346,7 @@ ArrayData::Index Object::getValueOrSetter(uint index, PropertyAttributes *attrs)
o = o->prototype();
}
*attrs = Attr_Invalid;
- return { 0, 0 };
+ return { nullptr, 0 };
}
bool Object::hasProperty(String *name) const
@@ -531,7 +484,7 @@ bool Object::deleteIndexedProperty(Managed *m, uint index)
void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *pd, PropertyAttributes *attrs)
{
Object *o = static_cast<Object *>(m);
- name->setM(0);
+ name->setM(nullptr);
*index = UINT_MAX;
if (o->arrayData()) {
@@ -555,7 +508,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *
return;
}
}
- it->arrayNode = 0;
+ it->arrayNode = nullptr;
it->arrayIndex = UINT_MAX;
}
// dense arrays
@@ -675,7 +628,7 @@ bool Object::internalPut(String *name, const Value &value)
name->makeIdentifier();
Identifier *id = name->identifier();
- MemberData::Index memberIndex{0, 0};
+ MemberData::Index memberIndex{nullptr, nullptr};
uint member = internalClass()->find(id);
PropertyAttributes attrs;
if (member < UINT_MAX) {
@@ -751,7 +704,7 @@ bool Object::internalPutIndexed(uint index, const Value &value)
PropertyAttributes attrs;
- ArrayData::Index arrayIndex = arrayData() ? arrayData()->getValueOrSetter(index, &attrs) : ArrayData::Index{ 0, 0 };
+ ArrayData::Index arrayIndex = arrayData() ? arrayData()->getValueOrSetter(index, &attrs) : ArrayData::Index{ nullptr, 0 };
if (arrayIndex.isNull() && isStringObject()) {
if (index < static_cast<StringObject *>(this)->length())
@@ -945,7 +898,7 @@ bool Object::defineOwnProperty2(ExecutionEngine *engine, uint index, const Prope
return true;
}
- return __defineOwnProperty__(engine, index, 0, p, attrs);
+ return __defineOwnProperty__(engine, index, nullptr, p, attrs);
}
bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *member, const Property *p, PropertyAttributes attrs)
@@ -996,8 +949,8 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *
Q_ASSERT(arrayData());
setArrayAttributes(index, cattrs);
}
- current->setGetter(0);
- current->setSetter(0);
+ current->setGetter(nullptr);
+ current->setSetter(nullptr);
} else {
// 9c
cattrs.setType(PropertyAttributes::Data);
@@ -1069,7 +1022,6 @@ void Object::copyArrayData(Object *other)
Heap::ArrayData *od = other->d()->arrayData;
Heap::ArrayData *dd = d()->arrayData;
dd->sparse = new SparseArray(*od->sparse);
- dd->freeList = od->freeList;
} else {
Heap::ArrayData *dd = d()->arrayData;
dd->values.size = other->d()->arrayData->values.size;
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 66177617f7..1731ae3c76 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -64,8 +64,6 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-struct BuiltinFunction;
-
namespace Heap {
#define ObjectMembers(class, Member) \
@@ -87,12 +85,12 @@ DECLARE_EXPORTED_HEAP_OBJECT(Object, Base) {
void setInlineProperty(ExecutionEngine *e, uint index, Value v) {
Q_ASSERT(index < vtable()->nInlineProperties);
Value *prop = reinterpret_cast<Value *>(this) + vtable()->inlinePropertyOffset + index;
- WriteBarrier::write(e, this, prop, v);
+ WriteBarrier::write(e, this, prop->data_ptr(), v.asReturnedValue());
}
void setInlineProperty(ExecutionEngine *e, uint index, Heap::Base *b) {
Q_ASSERT(index < vtable()->nInlineProperties);
Value *prop = reinterpret_cast<Value *>(this) + vtable()->inlinePropertyOffset + index;
- WriteBarrier::write(e, this, prop, b);
+ WriteBarrier::write(e, this, prop->data_ptr(), b->asReturnedValue());
}
QV4::MemberData::Index writablePropertyData(uint index) {
@@ -153,7 +151,7 @@ DECLARE_EXPORTED_HEAP_OBJECT(Object, Base) {
dptr->_checkIsInitialized(); \
return dptr; \
} \
- V4_ASSERT_IS_TRIVIAL(QV4::Heap::DataClass);
+ Q_STATIC_ASSERT(std::is_trivial< QV4::Heap::DataClass >::value);
#define V4_PROTOTYPE(p) \
static QV4::Object *defaultPrototype(QV4::ExecutionEngine *e) \
@@ -238,8 +236,8 @@ struct Q_QML_EXPORT Object: Managed {
Heap::Object *prototype() const { return d()->prototype(); }
bool setPrototype(Object *proto);
- void getOwnProperty(String *name, PropertyAttributes *attrs, Property *p = 0);
- void getOwnProperty(uint index, PropertyAttributes *attrs, Property *p = 0);
+ void getOwnProperty(String *name, PropertyAttributes *attrs, Property *p = nullptr);
+ void getOwnProperty(uint index, PropertyAttributes *attrs, Property *p = nullptr);
MemberData::Index getValueOrSetter(String *name, PropertyAttributes *attrs);
ArrayData::Index getValueOrSetter(uint index, PropertyAttributes *attrs);
@@ -273,16 +271,8 @@ struct Q_QML_EXPORT Object: Managed {
insertMember(name, value, Attr_Data|Attr_NotEnumerable);
}
void defineDefaultProperty(const QString &name, const Value &value);
- // old calling convention
- void defineDefaultProperty(const QString &name, ReturnedValue (*code)(const BuiltinFunction *, CallData *), int argumentCount = 0);
- void defineDefaultProperty(String *name, ReturnedValue (*code)(const BuiltinFunction *, CallData *), int argumentCount = 0);
- // new calling convention
void defineDefaultProperty(const QString &name, ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc), int argumentCount = 0);
void defineDefaultProperty(String *name, ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc), int argumentCount = 0);
- void defineAccessorProperty(const QString &name, ReturnedValue (*getter)(const BuiltinFunction *, CallData *),
- ReturnedValue (*setter)(const BuiltinFunction *, CallData *));
- void defineAccessorProperty(String *name, ReturnedValue (*getter)(const BuiltinFunction *, CallData *),
- ReturnedValue (*setter)(const BuiltinFunction *, CallData *));
void defineAccessorProperty(const QString &name, ReturnedValue (*getter)(const FunctionObject *, const Value *, const Value *, int),
ReturnedValue (*setter)(const FunctionObject *, const Value *, const Value *, int));
void defineAccessorProperty(String *name, ReturnedValue (*getter)(const FunctionObject *, const Value *, const Value *, int),
@@ -308,8 +298,6 @@ struct Q_QML_EXPORT Object: Managed {
// Array handling
public:
- static void markObjects(Heap::Base *base, MarkStack *stack);
-
void copyArrayData(Object *other);
bool setArrayLength(uint newLen);
@@ -358,8 +346,8 @@ public:
}
void initSparseArray();
- SparseArrayNode *sparseBegin() { return arrayType() == Heap::ArrayData::Sparse ? d()->arrayData->sparse->begin() : 0; }
- SparseArrayNode *sparseEnd() { return arrayType() == Heap::ArrayData::Sparse ? d()->arrayData->sparse->end() : 0; }
+ SparseArrayNode *sparseBegin() { return arrayType() == Heap::ArrayData::Sparse ? d()->arrayData->sparse->begin() : nullptr; }
+ SparseArrayNode *sparseEnd() { return arrayType() == Heap::ArrayData::Sparse ? d()->arrayData->sparse->end() : nullptr; }
inline bool protoHasArray() {
Scope scope(engine());
@@ -372,9 +360,9 @@ public:
return false;
}
- inline ReturnedValue get(String *name, bool *hasProperty = 0) const
+ inline ReturnedValue get(String *name, bool *hasProperty = nullptr) const
{ return vtable()->get(this, name, hasProperty); }
- inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0) const
+ inline ReturnedValue getIndexed(uint idx, bool *hasProperty = nullptr) const
{ return vtable()->getIndexed(this, idx, hasProperty); }
// use the set variants instead, to customize throw behavior
@@ -563,7 +551,7 @@ inline void Object::arraySet(uint index, const Value &value)
template<>
inline const ArrayObject *Value::as() const {
- return isManaged() && m()->vtable()->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : 0;
+ return isManaged() && m()->vtable()->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : nullptr;
}
#ifndef V4_BOOTSTRAP
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index 0394c704f9..7bf7e1aa04 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -47,8 +47,8 @@ using namespace QV4;
void ObjectIterator::init(const Object *o)
{
- object->setM(o ? o->m() : 0);
- current->setM(o ? o->m() : 0);
+ object->setM(o ? o->m() : nullptr);
+ current->setM(o ? o->m() : nullptr);
if (object->as<ArgumentsObject>()) {
Scope scope(engine);
@@ -58,7 +58,7 @@ void ObjectIterator::init(const Object *o)
void ObjectIterator::next(Value *name, uint *index, Property *pd, PropertyAttributes *attrs)
{
- name->setM(0);
+ name->setM(nullptr);
*index = UINT_MAX;
if (!object->as<Object>()) {
@@ -100,7 +100,7 @@ void ObjectIterator::next(Value *name, uint *index, Property *pd, PropertyAttrib
if (flags & WithProtoChain)
current->setM(co->prototype());
else
- current->setM(0);
+ current->setM(nullptr);
arrayIndex = 0;
memberIndex = 0;
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index 30a6ad3025..744d16301a 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -73,7 +73,7 @@ struct Q_QML_EXPORT ObjectIteratorData
uint memberIndex;
uint flags;
};
-V4_ASSERT_IS_TRIVIAL(ObjectIteratorData)
+Q_STATIC_ASSERT(std::is_trivial< ObjectIteratorData >::value);
struct Q_QML_EXPORT ObjectIterator: ObjectIteratorData
{
@@ -101,7 +101,7 @@ struct Q_QML_EXPORT ObjectIterator: ObjectIteratorData
init(o);
}
- void next(Value *name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
+ void next(Value *name, uint *index, Property *pd, PropertyAttributes *attributes = nullptr);
ReturnedValue nextPropertyName(Value *value);
ReturnedValue nextPropertyNameAsString(Value *value);
ReturnedValue nextPropertyNameAsString();
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 5eef757ce9..b998b78520 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -121,8 +121,8 @@ void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
ExecutionContext *global = v4->rootContext();
ScopedProperty p(scope);
- p->value = BuiltinFunction::create(global, v4->id___proto__(), method_get_proto);
- p->set = BuiltinFunction::create(global, v4->id___proto__(), method_set_proto);
+ p->value = FunctionObject::createBuiltinFunction(global, v4->id___proto__(), method_get_proto);
+ p->set = FunctionObject::createBuiltinFunction(global, v4->id___proto__(), method_set_proto);
insertMember(v4->id___proto__(), p, Attr_Accessor|Attr_NotEnumerable);
}
@@ -638,7 +638,7 @@ ReturnedValue ObjectPrototype::method_set_proto(const FunctionObject *b, const V
THROW_TYPE_ERROR();
if (argv[0].isNull()) {
- o->setPrototype(0);
+ o->setPrototype(nullptr);
RETURN_UNDEFINED();
}
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp
index 0b31c971f9..7fc74173e3 100644
--- a/src/qml/jsruntime/qv4persistent.cpp
+++ b/src/qml/jsruntime/qv4persistent.cpp
@@ -68,6 +68,22 @@ Page *getPage(Value *val) {
return reinterpret_cast<Page *>(reinterpret_cast<quintptr>(val) & ~((quintptr)(WTF::pageSize() - 1)));
}
+QML_NEARLY_ALWAYS_INLINE void insertInFront(PersistentValueStorage *storage, Page *p)
+{
+ p->header.next = reinterpret_cast<Page *>(storage->firstPage);
+ p->header.prev = reinterpret_cast<Page **>(&storage->firstPage);
+ if (p->header.next)
+ p->header.next->header.prev = &p->header.next;
+ storage->firstPage = p;
+}
+
+QML_NEARLY_ALWAYS_INLINE void unlink(Page *p)
+{
+ if (p->header.prev)
+ *p->header.prev = p->header.next;
+ if (p->header.next)
+ p->header.next->header.prev = p->header.prev;
+}
Page *allocatePage(PersistentValueStorage *storage)
{
@@ -78,19 +94,14 @@ Page *allocatePage(PersistentValueStorage *storage)
p->header.engine = storage->engine;
p->header.alloc = page;
- p->header.next = reinterpret_cast<Page *>(storage->firstPage);
- p->header.prev = reinterpret_cast<Page **>(&storage->firstPage);
p->header.refCount = 0;
p->header.freeList = 0;
- if (p->header.next)
- p->header.next->header.prev = &p->header.next;
+ insertInFront(storage, p);
for (int i = 0; i < kEntriesPerPage - 1; ++i) {
p->values[i].setEmpty(i + 1);
}
p->values[kEntriesPerPage - 1].setEmpty(-1);
- storage->firstPage = p;
-
return p;
}
@@ -161,7 +172,7 @@ Value &PersistentValueStorage::Iterator::operator *()
PersistentValueStorage::PersistentValueStorage(ExecutionEngine *engine)
: engine(engine),
- firstPage(0)
+ firstPage(nullptr)
{
}
@@ -174,9 +185,9 @@ PersistentValueStorage::~PersistentValueStorage()
p->values[i] = Encode::undefined();
}
Page *n = p->header.next;
- p->header.engine = 0;
- p->header.prev = 0;
- p->header.next = 0;
+ p->header.engine = nullptr;
+ p->header.prev = nullptr;
+ p->header.next = nullptr;
Q_ASSERT(p->header.refCount);
p = n;
}
@@ -195,6 +206,12 @@ Value *PersistentValueStorage::allocate()
Value *v = p->values + p->header.freeList;
p->header.freeList = v->int_32();
+
+ if (p->header.freeList != -1 && p != firstPage) {
+ unlink(p);
+ insertInFront(this, p);
+ }
+
++p->header.refCount;
v->setRawValue(Encode::undefined());
@@ -237,16 +254,13 @@ ExecutionEngine *PersistentValueStorage::getEngine(Value *v)
void PersistentValueStorage::freePage(void *page)
{
Page *p = static_cast<Page *>(page);
- if (p->header.prev)
- *p->header.prev = p->header.next;
- if (p->header.next)
- p->header.next->header.prev = p->header.prev;
+ unlink(p);
p->header.alloc.deallocate();
}
PersistentValue::PersistentValue(const PersistentValue &other)
- : val(0)
+ : val(nullptr)
{
if (other.val) {
val = other.engine()->memoryManager->m_persistentValues->allocate();
@@ -267,7 +281,7 @@ PersistentValue::PersistentValue(ExecutionEngine *engine, ReturnedValue value)
}
PersistentValue::PersistentValue(ExecutionEngine *engine, Object *object)
- : val(0)
+ : val(nullptr)
{
if (!object)
return;
@@ -344,7 +358,7 @@ void PersistentValue::set(ExecutionEngine *engine, Heap::Base *obj)
}
WeakValue::WeakValue(const WeakValue &other)
- : val(0)
+ : val(nullptr)
{
if (other.val) {
allocVal(other.engine());
@@ -404,6 +418,6 @@ void WeakValue::free()
PersistentValueStorage::free(val);
}
- val = 0;
+ val = nullptr;
}
diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h
index 1f838f5531..55e8eefcb7 100644
--- a/src/qml/jsruntime/qv4persistent_p.h
+++ b/src/qml/jsruntime/qv4persistent_p.h
@@ -81,7 +81,7 @@ struct Q_QML_EXPORT PersistentValueStorage
Value &operator *();
};
Iterator begin() { return Iterator(firstPage, 0); }
- Iterator end() { return Iterator(0, 0); }
+ Iterator end() { return Iterator(nullptr, 0); }
static ExecutionEngine *getEngine(Value *v);
@@ -94,7 +94,7 @@ private:
class Q_QML_EXPORT PersistentValue
{
public:
- PersistentValue() : val(0) {}
+ PersistentValue() {}
PersistentValue(const PersistentValue &other);
PersistentValue &operator=(const PersistentValue &other);
PersistentValue &operator=(const WeakValue &other);
@@ -117,19 +117,19 @@ public:
}
Managed *asManaged() const {
if (!val)
- return 0;
+ return nullptr;
return val->managed();
}
template<typename T>
T *as() const {
if (!val)
- return 0;
+ return nullptr;
return val->as<T>();
}
ExecutionEngine *engine() const {
if (!val)
- return 0;
+ return nullptr;
return PersistentValueStorage::getEngine(val);
}
@@ -137,18 +137,18 @@ public:
bool isNullOrUndefined() const { return !val || val->isNullOrUndefined(); }
void clear() {
PersistentValueStorage::free(val);
- val = 0;
+ val = nullptr;
}
bool isEmpty() { return !val; }
private:
- Value *val;
+ Value *val = nullptr;
};
class Q_QML_EXPORT WeakValue
{
public:
- WeakValue() : val(0) {}
+ WeakValue() {}
WeakValue(const WeakValue &other);
WeakValue(ExecutionEngine *engine, const Value &value);
WeakValue &operator=(const WeakValue &other);
@@ -183,19 +183,19 @@ public:
}
Managed *asManaged() const {
if (!val)
- return 0;
+ return nullptr;
return val->managed();
}
template <typename T>
T *as() const {
if (!val)
- return 0;
+ return nullptr;
return val->as<T>();
}
ExecutionEngine *engine() const {
if (!val)
- return 0;
+ return nullptr;
return PersistentValueStorage::getEngine(val);
}
@@ -206,7 +206,7 @@ public:
void markOnce(MarkStack *markStack);
private:
- Value *val;
+ Value *val = nullptr;
private:
Q_NEVER_INLINE void allocVal(ExecutionEngine *engine);
diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp
index bedcb5b164..5fd200efc1 100644
--- a/src/qml/jsruntime/qv4profiling.cpp
+++ b/src/qml/jsruntime/qv4profiling.cpp
@@ -120,7 +120,8 @@ void Profiler::startProfiling(quint64 features)
if (features & (1 << FeatureMemoryAllocation)) {
qint64 timestamp = m_timer.nsecsElapsed();
MemoryAllocationProperties heap = {timestamp,
- (qint64)m_engine->memoryManager->getAllocatedMem(),
+ (qint64)m_engine->memoryManager->getAllocatedMem() -
+ (qint64)m_engine->memoryManager->getLargeItemsMem(),
HeapPage};
m_memory_data.append(heap);
MemoryAllocationProperties small = {timestamp,
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index 8a24c71815..e8c154e4e7 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -59,12 +59,18 @@
#if !QT_CONFIG(qml_debug)
+#define Q_V4_PROFILE_ALLOC(engine, size, type) (!engine)
+#define Q_V4_PROFILE_DEALLOC(engine, size, type) (!engine)
QT_BEGIN_NAMESPACE
namespace QV4 {
namespace Profiling {
class Profiler {};
+class FunctionCallProfiler {
+public:
+ FunctionCallProfiler(ExecutionEngine *, Function *) {}
+};
}
}
@@ -72,6 +78,16 @@ QT_END_NAMESPACE
#else
+#define Q_V4_PROFILE_ALLOC(engine, size, type)\
+ (engine->profiler() &&\
+ (engine->profiler()->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\
+ engine->profiler()->trackAlloc(size, type) : false)
+
+#define Q_V4_PROFILE_DEALLOC(engine, size, type) \
+ (engine->profiler() &&\
+ (engine->profiler()->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\
+ engine->profiler()->trackDealloc(size, type) : false)
+
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -123,7 +139,7 @@ struct MemoryAllocationProperties {
class FunctionCall {
public:
- FunctionCall() : m_function(0), m_start(0), m_end(0)
+ FunctionCall() : m_function(nullptr), m_start(0), m_end(0)
{ Q_ASSERT_X(false, Q_FUNC_INFO, "Cannot construct a function call without function"); }
FunctionCall(Function *function, qint64 start, qint64 end) :
@@ -211,16 +227,24 @@ public:
bool trackAlloc(size_t size, MemoryType type)
{
- MemoryAllocationProperties allocation = {m_timer.nsecsElapsed(), (qint64)size, type};
- m_memory_data.append(allocation);
- return true;
+ if (size) {
+ MemoryAllocationProperties allocation = {m_timer.nsecsElapsed(), (qint64)size, type};
+ m_memory_data.append(allocation);
+ return true;
+ } else {
+ return false;
+ }
}
bool trackDealloc(size_t size, MemoryType type)
{
- MemoryAllocationProperties allocation = {m_timer.nsecsElapsed(), -(qint64)size, type};
- m_memory_data.append(allocation);
- return true;
+ if (size) {
+ MemoryAllocationProperties allocation = {m_timer.nsecsElapsed(), -(qint64)size, type};
+ m_memory_data.append(allocation);
+ return true;
+ } else {
+ return false;
+ }
}
quint64 featuresEnabled;
@@ -252,7 +276,7 @@ public:
// It's enough to ref() the function in the destructor as it will probably not disappear while
// it's executing ...
FunctionCallProfiler(ExecutionEngine *engine, Function *f)
- : profiler(0)
+ : profiler(nullptr)
{
Profiler *p = engine->profiler();
if (Q_UNLIKELY(p) && (p->featuresEnabled & (1 << Profiling::FeatureFunctionCall))) {
diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h
index 2a5b6f7f74..7cb106c424 100644
--- a/src/qml/jsruntime/qv4property_p.h
+++ b/src/qml/jsruntime/qv4property_p.h
@@ -84,7 +84,7 @@ struct Property {
inline Heap::FunctionObject *getter() const { return reinterpret_cast<Heap::FunctionObject *>(value.heapObject()); }
inline Heap::FunctionObject *setter() const { return reinterpret_cast<Heap::FunctionObject *>(set.heapObject()); }
inline void setGetter(FunctionObject *g) { value = reinterpret_cast<Managed *>(g); }
- inline void setSetter(FunctionObject *s) { set = (s ? reinterpret_cast<Managed *>(s) : 0); }
+ inline void setSetter(FunctionObject *s) { set = (s ? reinterpret_cast<Managed *>(s) : nullptr); }
void copy(const Property *other, PropertyAttributes attrs) {
value = other->value;
@@ -92,7 +92,7 @@ struct Property {
set = other->set;
}
- explicit Property() { value = Encode::undefined(); set = Value::fromHeapObject(0); }
+ explicit Property() { value = Encode::undefined(); set = Value::fromHeapObject(nullptr); }
Property(Heap::FunctionObject *getter, Heap::FunctionObject *setter) {
value.setM(reinterpret_cast<Heap::Base *>(getter));
set.setM(reinterpret_cast<Heap::Base *>(setter));
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index 5a165b2309..040f060476 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -108,8 +108,8 @@ ReturnedValue QQmlContextWrapper::get(const Managed *m, String *name, bool *hasP
return result->asReturnedValue();
}
- // Its possible we could delay the calculation of the "actual" context (in the case
- // of sub contexts) until it is definately needed.
+ // It's possible we could delay the calculation of the "actual" context (in the case
+ // of sub contexts) until it is definitely needed.
QQmlContextData *context = resource->getContext();
QQmlContextData *expressionContext = context;
@@ -138,7 +138,9 @@ ReturnedValue QQmlContextWrapper::get(const Managed *m, String *name, bool *hasP
*hasProperty = true;
if (r.scriptIndex != -1) {
QV4::ScopedObject scripts(scope, context->importedScripts.valueRef());
- return scripts->getIndexed(r.scriptIndex);
+ if (scripts)
+ return scripts->getIndexed(r.scriptIndex);
+ return QV4::Encode::null();
} else if (r.type.isValid()) {
return QQmlTypeWrapper::create(v4, scopeObject, r.type);
} else if (r.importNamespace) {
@@ -154,7 +156,7 @@ ReturnedValue QQmlContextWrapper::get(const Managed *m, String *name, bool *hasP
while (context) {
// Search context properties
- const QV4::IdentifierHash<int> &properties = context->propertyNames();
+ const QV4::IdentifierHash &properties = context->propertyNames();
if (properties.count()) {
int propertyIdx = properties.value(name);
@@ -200,7 +202,7 @@ ReturnedValue QQmlContextWrapper::get(const Managed *m, String *name, bool *hasP
return result->asReturnedValue();
}
}
- scopeObject = 0;
+ scopeObject = nullptr;
// Search context object
@@ -248,8 +250,8 @@ bool QQmlContextWrapper::put(Managed *m, String *name, const Value &value)
return Object::put(m, name, value);
}
- // Its possible we could delay the calculation of the "actual" context (in the case
- // of sub contexts) until it is definately needed.
+ // It's possible we could delay the calculation of the "actual" context (in the case
+ // of sub contexts) until it is definitely needed.
QQmlContextData *context = wrapper->getContext();
QQmlContextData *expressionContext = context;
@@ -261,7 +263,7 @@ bool QQmlContextWrapper::put(Managed *m, String *name, const Value &value)
QObject *scopeObject = wrapper->getScopeObject();
while (context) {
- const QV4::IdentifierHash<int> &properties = context->propertyNames();
+ const QV4::IdentifierHash &properties = context->propertyNames();
// Search context properties
if (properties.count() && properties.value(name) != -1)
return false;
@@ -270,7 +272,7 @@ bool QQmlContextWrapper::put(Managed *m, String *name, const Value &value)
if (scopeObject &&
QV4::QObjectWrapper::setQmlProperty(v4, context, scopeObject, name, QV4::QObjectWrapper::CheckRevision, value))
return true;
- scopeObject = 0;
+ scopeObject = nullptr;
// Search context object
if (context->contextObject &&
@@ -310,7 +312,7 @@ Heap::QmlContext *QmlContext::createWorkerContext(ExecutionContext *parent, cons
context->isInternal = true;
context->isJSContext = true;
- Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QQmlContextWrapper>(context, (QObject*)0));
+ Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QQmlContextWrapper>(context, (QObject*)nullptr));
qml->d()->isNullWrapper = true;
qml->setReadOnly(false);
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index a1df5cb95f..647bef7fc1 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -91,6 +91,7 @@ struct Q_QML_EXPORT QQmlContextWrapper : Object
{
V4_OBJECT2(QQmlContextWrapper, Object)
V4_NEEDS_DESTROY
+ V4_INTERNALCLASS(QmlContextWrapper)
inline QObject *getScopeObject() const { return d()->scopeObject; }
inline QQmlContextData *getContext() const { return *d()->context; }
@@ -104,6 +105,7 @@ struct Q_QML_EXPORT QQmlContextWrapper : Object
struct Q_QML_EXPORT QmlContext : public ExecutionContext
{
V4_MANAGED(QmlContext, ExecutionContext)
+ V4_INTERNALCLASS(QmlContext)
static Heap::QmlContext *createWorkerContext(QV4::ExecutionContext *parent, const QUrl &source, Value *sendFunction);
static Heap::QmlContext *create(QV4::ExecutionContext *parent, QQmlContextData *context, QObject *scopeObject);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 6d7d929b61..c1bbe2a330 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -99,7 +99,7 @@ QPair<QObject *, int> QObjectMethod::extractQtMethod(const QV4::FunctionObject *
return qMakePair(method->object(), method->methodIndex());
}
- return qMakePair((QObject *)0, -1);
+ return qMakePair((QObject *)nullptr, -1);
}
static QPair<QObject *, int> extractQtSignal(const Value &value)
@@ -116,7 +116,7 @@ static QPair<QObject *, int> extractQtSignal(const Value &value)
return qMakePair(handler->object(), handler->signalIndex());
}
- return qMakePair((QObject *)0, -1);
+ return qMakePair((QObject *)nullptr, -1);
}
static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object,
@@ -126,7 +126,7 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object
QV4::Scope scope(v4);
if (property.isQObject()) {
- QObject *rv = 0;
+ QObject *rv = nullptr;
property.readProperty(object, &rv);
return QV4::QObjectWrapper::wrap(v4, rv);
} else if (property.isQList()) {
@@ -194,7 +194,7 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object
"'%s::%s'", p.typeName(), object->metaObject()->className(), p.name());
return QV4::Encode::undefined();
} else {
- QVariant v(property.propType(), (void *)0);
+ QVariant v(property.propType(), (void *)nullptr);
property.readProperty(object, v.data());
return scope.engine->fromVariant(v);
}
@@ -217,7 +217,7 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QObject
Q_UNUSED(revisionMode);
QQmlData *ddata = QQmlData::get(o, false);
- QQmlPropertyData *result = 0;
+ QQmlPropertyData *result = nullptr;
if (ddata && ddata->propertyCache)
result = ddata->propertyCache->property(name, o, qmlContext);
else
@@ -249,7 +249,7 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje
}
}
- QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
+ QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : nullptr;
if (captureRequired && ep && ep->propertyCapture && !property->isConstant())
ep->propertyCapture->captureProperty(object, property->coreIndex(), property->notifyIndex());
@@ -335,6 +335,11 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje
if (!ddata)
return QV4::Encode::undefined();
+ if (Q_UNLIKELY(!ddata->propertyCache)) {
+ ddata->propertyCache = QQmlEnginePrivate::get(engine)->cache(object->metaObject());
+ ddata->propertyCache->addref();
+ }
+
QQmlPropertyCache *cache = ddata->propertyCache;
Q_ASSERT(cache);
QQmlPropertyData *property = cache->property(propertyIndex);
@@ -434,7 +439,7 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
return;
}
- QQmlBinding *newBinding = 0;
+ QQmlBinding *newBinding = nullptr;
QV4::Scope scope(engine);
QV4::ScopedFunctionObject f(scope, value);
if (f) {
@@ -496,9 +501,9 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
QMetaObject::metacall(object, QMetaObject::WriteProperty, property->coreIndex(), argv);
if (value.isNull() && property->isQObject()) {
- PROPERTY_STORE(QObject*, 0);
+ PROPERTY_STORE(QObject*, nullptr);
} else if (value.isUndefined() && property->isResettable()) {
- void *a[] = { 0 };
+ void *a[] = { nullptr };
QMetaObject::metacall(object, QMetaObject::ResetProperty, property->coreIndex(), a);
} else if (value.isUndefined() && property->propType() == qMetaTypeId<QVariant>()) {
PROPERTY_STORE(QVariant, QVariant());
@@ -531,7 +536,7 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
Q_ASSERT(vmemo);
vmemo->setVMEProperty(property->coreIndex(), value);
} else if (property->propType() == qMetaTypeId<QQmlScriptString>() && (value.isUndefined() || value.isPrimitive())) {
- QQmlScriptString ss(value.toQStringNoThrow(), 0 /* context */, object);
+ QQmlScriptString ss(value.toQStringNoThrow(), nullptr /* context */, object);
if (value.isNumber()) {
ss.d->numberValue = value.toNumber();
ss.d->isNumberLiteral = true;
@@ -549,7 +554,7 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
QQmlContextData *callingQmlContext = scope.engine->callingQmlContext();
if (!QQmlPropertyPrivate::write(object, *property, v, callingQmlContext)) {
- const char *valueType = 0;
+ const char *valueType = nullptr;
if (v.userType() == QVariant::Invalid) valueType = "null";
else valueType = QMetaType::typeName(v.userType());
@@ -590,7 +595,7 @@ ReturnedValue QObjectWrapper::wrap_slowPath(ExecutionEngine *engine, QObject *ob
} else {
// If this object is tainted, we have to check to see if it is in our
// tainted object list
- ScopedObject alternateWrapper(scope, (Object *)0);
+ ScopedObject alternateWrapper(scope, (Object *)nullptr);
if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object)
alternateWrapper = engine->m_multiplyWrappedQObjects->value(object);
@@ -715,6 +720,10 @@ bool QObjectWrapper::put(Managed *m, String *name, const Value &value)
PropertyAttributes QObjectWrapper::query(const Managed *m, String *name)
{
const QObjectWrapper *that = static_cast<const QObjectWrapper*>(m);
+ const QObject *thatObject = that->d()->object();
+ if (QQmlData::wasDeleted(thatObject))
+ return QV4::Object::query(m, name);
+
ExecutionEngine *engine = that->engine();
QQmlContextData *qmlContext = engine->callingQmlContext();
QQmlPropertyData local;
@@ -732,7 +741,7 @@ void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value *name
static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal("destroyed()");
static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot("deleteLater()");
- name->setM(0);
+ name->setM(nullptr);
*index = UINT_MAX;
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
@@ -809,7 +818,7 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
break;
QQmlMetaObject::ArgTypeStorage storage;
- int *argsTypes = QQmlMetaObject(r).methodParameterTypes(This->signalIndex, &storage, 0);
+ int *argsTypes = QQmlMetaObject(r).methodParameterTypes(This->signalIndex, &storage, nullptr);
int argCount = argsTypes ? argsTypes[0]:0;
@@ -838,7 +847,7 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
QQmlEnginePrivate::get(qmlEngine)->warning(error);
} else {
QMessageLogger(error.url().toString().toLatin1().constData(),
- error.line(), 0).warning().noquote()
+ error.line(), nullptr).warning().noquote()
<< error.toString();
}
}
@@ -900,14 +909,14 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
} // namespace QV4
-ReturnedValue QObjectWrapper::method_connect(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QObjectWrapper::method_connect(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() == 0)
+ if (argc == 0)
THROW_GENERIC_ERROR("Function.prototype.connect: no arguments given");
- QPair<QObject *, int> signalInfo = extractQtSignal(callData->thisObject);
+ QPair<QObject *, int> signalInfo = extractQtSignal(*thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second; // in method range, not signal range!
@@ -921,25 +930,25 @@ ReturnedValue QObjectWrapper::method_connect(const BuiltinFunction *b, CallData
THROW_GENERIC_ERROR("Function.prototype.connect: this object is not a signal");
QV4::ScopedFunctionObject f(scope);
- QV4::ScopedValue thisObject (scope, QV4::Encode::undefined());
+ QV4::ScopedValue object (scope, QV4::Encode::undefined());
- if (callData->argc() == 1) {
- f = callData->args[0];
- } else if (callData->argc() >= 2) {
- thisObject = callData->args[0];
- f = callData->args[1];
+ if (argc == 1) {
+ f = argv[0];
+ } else if (argc >= 2) {
+ object = argv[0];
+ f = argv[1];
}
if (!f)
THROW_GENERIC_ERROR("Function.prototype.connect: target is not a function");
- if (!thisObject->isUndefined() && !thisObject->isObject())
+ if (!object->isUndefined() && !object->isObject())
THROW_GENERIC_ERROR("Function.prototype.connect: target this is not an object");
QV4::QObjectSlotDispatcher *slot = new QV4::QObjectSlotDispatcher;
slot->signalIndex = signalIndex;
- slot->thisObject.set(scope.engine, thisObject);
+ slot->thisObject.set(scope.engine, object);
slot->function.set(scope.engine, f);
if (QQmlData *ddata = QQmlData::get(signalObject)) {
@@ -952,14 +961,14 @@ ReturnedValue QObjectWrapper::method_connect(const BuiltinFunction *b, CallData
RETURN_UNDEFINED();
}
-ReturnedValue QObjectWrapper::method_disconnect(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QObjectWrapper::method_disconnect(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() == 0)
+ if (argc == 0)
THROW_GENERIC_ERROR("Function.prototype.disconnect: no arguments given");
- QPair<QObject *, int> signalInfo = extractQtSignal(callData->thisObject);
+ QPair<QObject *, int> signalInfo = extractQtSignal(*thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second;
@@ -975,11 +984,11 @@ ReturnedValue QObjectWrapper::method_disconnect(const BuiltinFunction *b, CallDa
QV4::ScopedFunctionObject functionValue(scope);
QV4::ScopedValue functionThisValue(scope, QV4::Encode::undefined());
- if (callData->argc() == 1) {
- functionValue = callData->args[0];
- } else if (callData->argc() >= 2) {
- functionThisValue = callData->args[0];
- functionValue = callData->args[1];
+ if (argc == 1) {
+ functionValue = argv[0];
+ } else if (argc >= 2) {
+ functionThisValue = argv[0];
+ functionValue = argv[1];
}
if (!functionValue)
@@ -1048,8 +1057,8 @@ void QObjectWrapper::destroyObject(bool lastCall)
if (ddata && ddata->ownContext) {
Q_ASSERT(ddata->ownContext == ddata->context);
ddata->ownContext->emitDestruction();
- ddata->ownContext = 0;
- ddata->context = 0;
+ ddata->ownContext = nullptr;
+ ddata->context = nullptr;
}
// This object is notionally destroyed now
ddata->isQueuedForDeletion = true;
@@ -1177,14 +1186,14 @@ static QV4::ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index
} else {
- void *args[] = { 0 };
+ void *args[] = { nullptr };
object.metacall(callType, index, args);
return Encode::undefined();
}
}
-/*!
+/*
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.
@@ -1341,7 +1350,7 @@ static inline int QMetaObject_methods(const QMetaObject *metaObject)
return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount;
}
-/*!
+/*
Returns the next related method, if one, or 0.
*/
static const QQmlPropertyData * RelatedMethod(const QQmlObjectOrGadget &object,
@@ -1350,7 +1359,7 @@ static const QQmlPropertyData * RelatedMethod(const QQmlObjectOrGadget &object,
const QQmlPropertyCache *propertyCache)
{
if (!current->isOverload())
- return 0;
+ return nullptr;
Q_ASSERT(!current->overrideIndexIsProperty());
@@ -1368,7 +1377,7 @@ static const QQmlPropertyData * RelatedMethod(const QQmlObjectOrGadget &object,
// If we've been called before with the same override index, then
// we can't go any further...
if (&dummy == current && dummy.coreIndex() == current->overrideIndex())
- return 0;
+ return nullptr;
QMetaMethod method = mo->method(current->overrideIndex());
dummy.load(method);
@@ -1403,7 +1412,7 @@ static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQ
if (data.hasArguments()) {
- int *args = 0;
+ int *args = nullptr;
QQmlMetaObject::ArgTypeStorage storage;
if (data.isConstructor())
@@ -1426,12 +1435,12 @@ static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQ
} else {
- return CallMethod(object, data.coreIndex(), returnType, 0, 0, engine, callArgs, callType);
+ return CallMethod(object, data.coreIndex(), returnType, 0, nullptr, engine, callArgs, callType);
}
}
-/*!
+/*
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
@@ -1463,9 +1472,9 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const
do {
QQmlMetaObject::ArgTypeStorage storage;
int methodArgumentCount = 0;
- int *methodArgTypes = 0;
+ int *methodArgTypes = nullptr;
if (attempt->hasArguments()) {
- int *args = object.methodParameterTypes(attempt->coreIndex(), &storage, 0);
+ int *args = object.methodParameterTypes(attempt->coreIndex(), &storage, nullptr);
if (!args) // Must be an unknown argument
continue;
@@ -1493,7 +1502,7 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const
if (bestParameterScore == 0 && bestMatchScore == 0)
break; // We can't get better than that
- } while ((attempt = RelatedMethod(object, attempt, dummy, propertyCache)) != 0);
+ } while ((attempt = RelatedMethod(object, attempt, dummy, propertyCache)) != nullptr);
if (best.isValid()) {
return CallPrecise(object, best, engine, callArgs, callType);
@@ -1560,7 +1569,7 @@ void *CallArgument::dataPtr()
return stdVectorQModelIndexPtr;
else if (type != 0)
return (void *)&allocData;
- return 0;
+ return nullptr;
}
void CallArgument::initAsType(int callType)
@@ -1578,7 +1587,7 @@ void CallArgument::initAsType(int callType)
callType == QMetaType::Float) {
type = callType;
} else if (callType == QMetaType::QObjectStar) {
- qobjectPtr = 0;
+ qobjectPtr = nullptr;
type = callType;
} else if (callType == QMetaType::QString) {
qstringPtr = new (&allocData) QString();
@@ -1603,7 +1612,7 @@ void CallArgument::initAsType(int callType)
jsonValuePtr = new (&allocData) QJsonValue();
} else {
type = -1;
- qvariantPtr = new (&allocData) QVariant(callType, (void *)0);
+ qvariantPtr = new (&allocData) QVariant(callType, (void *)nullptr);
}
}
@@ -1655,7 +1664,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
qstringPtr = new (&allocData) QString(value.toQStringNoThrow());
type = callType;
} else if (callType == QMetaType::QObjectStar) {
- qobjectPtr = 0;
+ qobjectPtr = nullptr;
if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
qobjectPtr = qobjectWrapper->object();
else if (const QV4::QQmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QQmlTypeWrapper>())
@@ -1672,14 +1681,14 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
uint length = array->getLength();
for (uint ii = 0; ii < length; ++ii) {
- QObject *o = 0;
+ QObject *o = nullptr;
qobjectWrapper = array->getIndexed(ii);
if (!!qobjectWrapper)
o = qobjectWrapper->object();
qlistPtr->append(o);
}
} else {
- QObject *o = 0;
+ QObject *o = nullptr;
if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
o = qobjectWrapper->object();
qlistPtr->append(o);
@@ -1736,7 +1745,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
qvariantPtr = new (&allocData) QVariant();
type = -1;
- QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
+ QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : nullptr;
QVariant v = scope.engine->toVariant(value, callType);
if (v.userType() == callType) {
@@ -1749,12 +1758,12 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
if (!mo.isNull()) {
QObject *obj = ep->toQObject(v);
- if (obj != 0 && !QQmlMetaObject::canConvert(obj, mo))
- obj = 0;
+ if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo))
+ obj = nullptr;
*qvariantPtr = QVariant(callType, &obj);
} else {
- *qvariantPtr = QVariant(callType, (void *)0);
+ *qvariantPtr = QVariant(callType, (void *)nullptr);
}
}
}
@@ -1953,7 +1962,7 @@ ReturnedValue QObjectMethod::callInternal(const Value *thisObject, const Value *
QQmlV4Function func(callData, rv, v4);
QQmlV4Function *funcptr = &func;
- void *args[] = { 0, &funcptr };
+ void *args[] = { nullptr, &funcptr };
object.metacall(QMetaObject::InvokeMetaMethod, method.coreIndex(), args);
return rv->asReturnedValue();
@@ -2083,11 +2092,11 @@ ReturnedValue QMetaObjectWrapper::callOverloadedConstructor(QV4::ExecutionEngine
for (int i = 0; i < numberOfConstructors; i++) {
const QQmlPropertyData & attempt = d()->constructors[i];
+ QQmlMetaObject::ArgTypeStorage storage;
int methodArgumentCount = 0;
- int *methodArgTypes = 0;
+ int *methodArgTypes = nullptr;
if (attempt.hasArguments()) {
- QQmlMetaObject::ArgTypeStorage storage;
- int *args = object.constructorParameterTypes(attempt.coreIndex(), &storage, 0);
+ int *args = object.constructorParameterTypes(attempt.coreIndex(), &storage, nullptr);
if (!args) // Must be an unknown argument
continue;
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index c00e82e4fa..1455acc1b3 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -166,8 +166,8 @@ struct Q_QML_EXPORT QObjectWrapper : public Object
QObject *object() const { return d()->object(); }
- ReturnedValue getQmlProperty(QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false) const;
- static ReturnedValue getQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0);
+ ReturnedValue getQmlProperty(QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = nullptr, bool includeImports = false) const;
+ static ReturnedValue getQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = nullptr);
static bool setQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value);
@@ -198,8 +198,8 @@ protected:
static PropertyAttributes query(const Managed *, String *name);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static ReturnedValue method_connect(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_disconnect(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_connect(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_disconnect(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
private:
Q_NEVER_INLINE static ReturnedValue wrap_slowPath(ExecutionEngine *engine, QObject *object);
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index fb49def317..d99536829b 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -48,7 +48,7 @@ RegExpCache::~RegExpCache()
{
for (RegExpCache::Iterator it = begin(), e = end(); it != e; ++it) {
if (RegExp *re = it.value().as<RegExp>())
- re->d()->cache = 0;
+ re->d()->cache = nullptr;
}
}
@@ -82,7 +82,7 @@ Heap::RegExp *RegExp::create(ExecutionEngine* engine, const QString& pattern, bo
return result->d();
Scope scope(engine);
- Scoped<RegExp> result(scope, engine->memoryManager->alloc<RegExp>(pattern, ignoreCase, multiline, global));
+ Scoped<RegExp> result(scope, engine->memoryManager->alloc<RegExp>(engine, pattern, ignoreCase, multiline, global));
result->d()->cache = cache;
cachedValue.set(engine, result);
@@ -90,7 +90,7 @@ Heap::RegExp *RegExp::create(ExecutionEngine* engine, const QString& pattern, bo
return result->d();
}
-void Heap::RegExp::init(const QString &pattern, bool ignoreCase, bool multiline, bool global)
+void Heap::RegExp::init(ExecutionEngine *engine, const QString &pattern, bool ignoreCase, bool multiline, bool global)
{
Base::init();
this->pattern = new QString(pattern);
@@ -100,13 +100,13 @@ void Heap::RegExp::init(const QString &pattern, bool ignoreCase, bool multiline,
valid = false;
- const char* error = 0;
+ const char* error = nullptr;
JSC::Yarr::YarrPattern yarrPattern(WTF::String(pattern), ignoreCase, multiLine, &error);
if (error)
return;
subPatternCount = yarrPattern.m_numSubpatterns;
#if ENABLE(YARR_JIT)
- if (!yarrPattern.m_containsBackreferences) {
+ if (!yarrPattern.m_containsBackreferences && engine->canJIT()) {
jitCode = new JSC::Yarr::YarrCodeBlock;
JSC::JSGlobalData dummy(internalClass->engine->regExpAllocator);
JSC::Yarr::jitCompile(yarrPattern, JSC::Yarr::Char16, &dummy, *jitCode);
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index 498468e165..56454f73d3 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -76,7 +76,7 @@ struct RegExpCacheKey;
namespace Heap {
struct RegExp : Base {
- void init(const QString& pattern, bool ignoreCase, bool multiline, bool global);
+ void init(ExecutionEngine *engine, const QString& pattern, bool ignoreCase, bool multiline, bool global);
void destroy();
QString *pattern;
@@ -100,7 +100,7 @@ struct RegExp : Base {
int captureCount() const { return subPatternCount + 1; }
};
-V4_ASSERT_IS_TRIVIAL(RegExp)
+Q_STATIC_ASSERT(std::is_trivial< RegExp >::value);
}
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index f95719b25f..000e2c3a7e 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -283,25 +283,25 @@ void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(2));
// Properties deprecated in the spec but required by "the web" :(
- ctor->defineAccessorProperty(QStringLiteral("lastMatch"), method_get_lastMatch_n<0>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$&"), method_get_lastMatch_n<0>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$1"), method_get_lastMatch_n<1>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$2"), method_get_lastMatch_n<2>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$3"), method_get_lastMatch_n<3>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$4"), method_get_lastMatch_n<4>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$5"), method_get_lastMatch_n<5>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$6"), method_get_lastMatch_n<6>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$7"), method_get_lastMatch_n<7>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$8"), method_get_lastMatch_n<8>, 0);
- ctor->defineAccessorProperty(QStringLiteral("$9"), method_get_lastMatch_n<9>, 0);
- ctor->defineAccessorProperty(QStringLiteral("lastParen"), method_get_lastParen, 0);
- ctor->defineAccessorProperty(QStringLiteral("$+"), method_get_lastParen, 0);
- ctor->defineAccessorProperty(QStringLiteral("input"), method_get_input, 0);
- ctor->defineAccessorProperty(QStringLiteral("$_"), method_get_input, 0);
- ctor->defineAccessorProperty(QStringLiteral("leftContext"), method_get_leftContext, 0);
- ctor->defineAccessorProperty(QStringLiteral("$`"), method_get_leftContext, 0);
- ctor->defineAccessorProperty(QStringLiteral("rightContext"), method_get_rightContext, 0);
- ctor->defineAccessorProperty(QStringLiteral("$'"), method_get_rightContext, 0);
+ ctor->defineAccessorProperty(QStringLiteral("lastMatch"), method_get_lastMatch_n<0>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$&"), method_get_lastMatch_n<0>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$1"), method_get_lastMatch_n<1>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$2"), method_get_lastMatch_n<2>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$3"), method_get_lastMatch_n<3>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$4"), method_get_lastMatch_n<4>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$5"), method_get_lastMatch_n<5>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$6"), method_get_lastMatch_n<6>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$7"), method_get_lastMatch_n<7>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$8"), method_get_lastMatch_n<8>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$9"), method_get_lastMatch_n<9>, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("lastParen"), method_get_lastParen, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$+"), method_get_lastParen, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("input"), method_get_input, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$_"), method_get_input, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("leftContext"), method_get_leftContext, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$`"), method_get_leftContext, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("rightContext"), method_get_rightContext, nullptr);
+ ctor->defineAccessorProperty(QStringLiteral("$'"), method_get_rightContext, nullptr);
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
defineDefaultProperty(QStringLiteral("exec"), method_exec, 1);
@@ -343,7 +343,7 @@ ReturnedValue RegExpPrototype::execFirstMatch(const FunctionObject *b, const Val
if (r->value()->captureCount()) {
int start = matchOffsets[0];
int end = matchOffsets[1];
- retVal = (start != -1) ? scope.engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
+ retVal = (start != -1) ? scope.engine->memoryManager->alloc<ComplexString>(str->d(), start, end - start)->asReturnedValue() : Encode::undefined();
}
RegExpCtor::Data *dd = regExpCtor->d();
@@ -394,7 +394,7 @@ ReturnedValue RegExpPrototype::method_exec(const FunctionObject *b, const Value
for (int i = 0; i < len; ++i) {
int start = matchOffsets[i * 2];
int end = matchOffsets[i * 2 + 1];
- v = (start != -1) ? scope.engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
+ v = (start != -1) ? scope.engine->memoryManager->alloc<ComplexString>(str->d(), start, end - start)->asReturnedValue() : Encode::undefined();
array->arrayPut(i, v);
}
array->setArrayLengthUnchecked(len);
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 240fba7905..04cad8ddb7 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -382,11 +382,11 @@ double RuntimeHelpers::stringToNumber(const QString &string)
{
const QStringRef s = QStringRef(&string).trimmed();
if (s.startsWith(QLatin1String("0x")) || s.startsWith(QLatin1String("0X")))
- return s.toLong(0, 16);
+ return s.toLong(nullptr, 16);
bool ok;
QByteArray ba = s.toLatin1();
const char *begin = ba.constData();
- const char *end = 0;
+ const char *end = nullptr;
double d = qstrtod(begin, &end, &ok);
if (end - begin != ba.size()) {
if (ba == "Infinity" || ba == "+Infinity")
@@ -457,7 +457,7 @@ Heap::Object *RuntimeHelpers::convertToObject(ExecutionEngine *engine, const Val
case Value::Undefined_Type:
case Value::Null_Type:
engine->throwTypeError();
- return 0;
+ return nullptr;
case Value::Boolean_Type:
return engine->newBooleanObject(value.booleanValue());
case Value::Managed_Type:
@@ -532,7 +532,7 @@ QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionEngine *engine, const Valu
if (!sright->d()->length())
return sleft->asReturnedValue();
MemoryManager *mm = engine->memoryManager;
- return (mm->alloc<String>(sleft->d(), sright->d()))->asReturnedValue();
+ return (mm->alloc<ComplexString>(sleft->d(), sright->d()))->asReturnedValue();
}
double x = RuntimeHelpers::toNumber(pleft);
double y = RuntimeHelpers::toNumber(pright);
@@ -604,6 +604,14 @@ static Q_NEVER_INLINE ReturnedValue getElementFallback(ExecutionEngine *engine,
return o->get(name);
}
+/* load element:
+
+ Managed *m = object.heapObject();
+ if (m)
+ return m->internalClass->getIndexed(m, index);
+ return getIndexedFallback(object, index);
+*/
+
ReturnedValue Runtime::method_loadElement(ExecutionEngine *engine, const Value &object, const Value &index)
{
uint idx = 0;
@@ -672,7 +680,7 @@ bool Runtime::method_storeElement(ExecutionEngine *engine, const Value &object,
ReturnedValue Runtime::method_foreachIterator(ExecutionEngine *engine, const Value &in)
{
Scope scope(engine);
- ScopedObject o(scope, (Object *)0);
+ ScopedObject o(scope, (Object *)nullptr);
if (!in.isNullOrUndefined())
o = in.toObject(engine);
return engine->newForEachIteratorObject(o)->asReturnedValue();
@@ -1090,6 +1098,37 @@ ReturnedValue Runtime::method_callValue(ExecutionEngine *engine, const Value &fu
return static_cast<const FunctionObject &>(func).call(nullptr, argv, argc);
}
+ReturnedValue Runtime::method_callQmlScopeObjectProperty(ExecutionEngine *engine, Value *base,
+ int propertyIndex, Value *argv, int argc)
+{
+ Scope scope(engine);
+ ScopedFunctionObject fo(scope, method_loadQmlScopeObjectProperty(engine, *base, propertyIndex,
+ /*captureRequired*/true));
+ if (!fo) {
+ QString error = QStringLiteral("Property '%1' of scope object is not a function").arg(propertyIndex);
+ return engine->throwTypeError(error);
+ }
+
+ QObject *qmlScopeObj = static_cast<QmlContext *>(base)->d()->qml()->scopeObject;
+ ScopedValue qmlScopeValue(scope, QObjectWrapper::wrap(engine, qmlScopeObj));
+ return fo->call(qmlScopeValue, argv, argc);
+}
+
+ReturnedValue Runtime::method_callQmlContextObjectProperty(ExecutionEngine *engine, Value *base,
+ int propertyIndex, Value *argv, int argc)
+{
+ Scope scope(engine);
+ ScopedFunctionObject fo(scope, method_loadQmlContextObjectProperty(engine, *base, propertyIndex,
+ /*captureRequired*/true));
+ if (!fo) {
+ QString error = QStringLiteral("Property '%1' of context object is not a function").arg(propertyIndex);
+ return engine->throwTypeError(error);
+ }
+
+ QObject *qmlContextObj = static_cast<QmlContext *>(base)->d()->qml()->context->contextData()->contextObject;
+ ScopedValue qmlContextValue(scope, QObjectWrapper::wrap(engine, qmlContextObj));
+ return fo->call(qmlContextValue, argv, argc);
+}
ReturnedValue Runtime::method_construct(ExecutionEngine *engine, const Value &function, Value *argv, int argc)
{
@@ -1160,7 +1199,7 @@ ReturnedValue Runtime::method_createCatchContext(ExecutionContext *parent, int e
{
ExecutionEngine *e = parent->engine();
return parent->newCatchContext(e->currentStackFrame->v4Function->compilationUnit->runtimeStrings[exceptionVarNameIndex],
- e->catchException(0))->asReturnedValue();
+ e->catchException(nullptr))->asReturnedValue();
}
void Runtime::method_declareVar(ExecutionEngine *engine, bool deletable, int nameIndex)
@@ -1260,7 +1299,7 @@ ReturnedValue Runtime::method_loadQmlIdObject(ExecutionEngine *engine, const Val
if (!context || index >= (uint)context->idValueCount)
return Encode::undefined();
- QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
+ QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : nullptr;
if (ep && ep->propertyCapture)
ep->propertyCapture->captureProperty(&context->idValues[index].bindings);
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index ea31dfd08b..2956a4a463 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -188,6 +188,8 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
F(ReturnedValue, loadQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
F(ReturnedValue, loadQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
F(ReturnedValue, loadQmlIdObject, (ExecutionEngine *engine, const Value &context, uint index)) \
+ F(ReturnedValue, callQmlScopeObjectProperty, (ExecutionEngine *engine, Value *base, int propertyIndex, Value *argv, int argc)) \
+ F(ReturnedValue, callQmlContextObjectProperty, (ExecutionEngine *engine, Value *base, int propertyIndex, Value *argv, int argc)) \
\
F(void, storeQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
F(void, storeQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
diff --git a/src/qml/jsruntime/qv4runtimecodegen.cpp b/src/qml/jsruntime/qv4runtimecodegen.cpp
index 9c115099b5..fe18ddf9ed 100644
--- a/src/qml/jsruntime/qv4runtimecodegen.cpp
+++ b/src/qml/jsruntime/qv4runtimecodegen.cpp
@@ -49,15 +49,16 @@ void RuntimeCodegen::generateFromFunctionExpression(const QString &fileName,
{
_module = module;
_module->fileName = fileName;
- _context = 0;
+ _module->finalUrl = fileName;
+ _context = nullptr;
Compiler::ScanFunctions scan(this, sourceCode, Compiler::GlobalCode);
// fake a global environment
- scan.enterEnvironment(0, Compiler::FunctionCode);
+ scan.enterEnvironment(nullptr, Compiler::FunctionCode);
scan(ast);
scan.leaveEnvironment();
- int index = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : 0);
+ int index = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : nullptr);
_module->rootContext = _module->functions.at(index);
}
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index afb5c21d36..bb20f384b3 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -209,7 +209,7 @@ struct Scoped
enum ConvertType { Convert };
QML_NEARLY_ALWAYS_INLINE void setPointer(const Managed *p) {
- ptr->setM(p ? p->m() : 0);
+ ptr->setM(p ? p->m() : nullptr);
}
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope)
@@ -244,7 +244,7 @@ struct Scoped
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, const Value *v)
{
ptr = scope.engine->jsAlloca(1);
- setPointer(v ? v->as<T>() : 0);
+ setPointer(v ? v->as<T>() : nullptr);
}
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, T *t)
@@ -290,7 +290,7 @@ struct Scoped
return *this;
}
Scoped<T> &operator=(Value *v) {
- setPointer(v ? v->as<T>() : 0);
+ setPointer(v ? v->as<T>() : nullptr);
return *this;
}
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 901f2574da..bb6608bec0 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -62,14 +62,14 @@ using namespace QV4;
Script::Script(ExecutionEngine *v4, QmlContext *qml, CompiledData::CompilationUnit *compilationUnit)
: line(1), column(0), context(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false)
- , compilationUnit(compilationUnit), vmFunction(0), parseAsBinding(true)
+ , compilationUnit(compilationUnit), vmFunction(nullptr), parseAsBinding(true)
{
if (qml)
qmlContext.set(v4, *qml);
parsed = true;
- vmFunction = compilationUnit ? compilationUnit->linkToEngine(v4) : 0;
+ vmFunction = compilationUnit ? compilationUnit->linkToEngine(v4) : nullptr;
}
Script::~Script()
@@ -88,7 +88,7 @@ void Script::parse()
ExecutionEngine *v4 = context->engine();
Scope valueScope(v4);
- Module module(v4->debugger() != 0);
+ Module module(v4->debugger() != nullptr);
Engine ee, *engine = &ee;
Lexer lexer(engine);
@@ -121,7 +121,7 @@ void Script::parse()
RuntimeCodegen cg(v4, &jsGenerator, strictMode);
if (inheritContext)
cg.setUseFastLookups(false);
- cg.generateFromProgram(sourceFile, sourceCode, program, &module, compilationMode);
+ cg.generateFromProgram(sourceFile, sourceFile, sourceCode, program, &module, compilationMode);
if (v4->hasException)
return;
@@ -149,10 +149,10 @@ ReturnedValue Script::run()
if (qmlContext.isUndefined()) {
TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, vmFunction);
- return vmFunction->call(engine->globalObject, 0, 0, context);
+ return vmFunction->call(engine->globalObject, nullptr, 0, context);
} else {
Scoped<QmlContext> qml(valueScope, qmlContext.value());
- return vmFunction->call(0, 0, 0, qml);
+ return vmFunction->call(nullptr, nullptr, 0, qml);
}
}
@@ -164,8 +164,8 @@ Function *Script::function()
}
QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(QV4::Compiler::Module *module, Compiler::JSUnitGenerator *unitGenerator,
- const QUrl &url, const QString &source, QList<QQmlError> *reportedErrors,
- Directives *directivesCollector)
+ const QString &fileName, const QString &finalUrl, const QString &source,
+ QList<QQmlError> *reportedErrors, Directives *directivesCollector)
{
using namespace QV4::Compiler;
using namespace QQmlJS::AST;
@@ -184,12 +184,12 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(QV4::Compi
const auto diagnosticMessages = parser.diagnosticMessages();
for (const DiagnosticMessage &m : diagnosticMessages) {
if (m.isWarning()) {
- qWarning("%s:%d : %s", qPrintable(url.toString()), m.loc.startLine, qPrintable(m.message));
+ qWarning("%s:%d : %s", qPrintable(fileName), m.loc.startLine, qPrintable(m.message));
continue;
}
QQmlError error;
- error.setUrl(url);
+ error.setUrl(QUrl(fileName));
error.setDescription(m.message);
error.setLine(m.loc.startLine);
error.setColumn(m.loc.startColumn);
@@ -199,29 +199,50 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(QV4::Compi
if (!errors.isEmpty()) {
if (reportedErrors)
*reportedErrors << errors;
- return 0;
+ return nullptr;
}
Program *program = AST::cast<Program *>(parser.rootNode());
if (!program) {
// if parsing was successful, and we have no program, then
// we're done...:
- return 0;
+ return nullptr;
}
Codegen cg(unitGenerator, /*strict mode*/false);
cg.setUseFastLookups(false);
- cg.generateFromProgram(url.toString(), source, program, module, GlobalCode);
+ cg.generateFromProgram(fileName, finalUrl, source, program, module, GlobalCode);
errors = cg.qmlErrors();
if (!errors.isEmpty()) {
if (reportedErrors)
*reportedErrors << errors;
- return 0;
+ return nullptr;
}
return cg.generateCompilationUnit(/*generate unit data*/false);
}
+Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl)
+{
+ if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl)) {
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> jsUnit;
+ jsUnit.adopt(new QV4::CompiledData::CompilationUnit(cachedUnit));
+ return new QV4::Script(engine, qmlContext, jsUnit);
+ }
+
+ QFile f(fileName);
+ if (!f.open(QIODevice::ReadOnly))
+ return nullptr;
+
+ QByteArray data = f.readAll();
+ QString sourceCode = QString::fromUtf8(data);
+ QmlIR::Document::removeScriptPragmas(sourceCode);
+
+ auto result = new QV4::Script(engine, qmlContext, sourceCode, originalUrl.toString());
+ result->parse();
+ return result;
+}
+
QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext)
{
QV4::Scope scope(engine);
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index 158d21c69d..24291b9aa6 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -68,11 +68,11 @@ struct Q_QML_EXPORT Script {
Script(ExecutionContext *scope, QV4::Compiler::CompilationMode mode, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
: sourceFile(source), line(line), column(column), sourceCode(sourceCode)
, context(scope), strictMode(false), inheritContext(false), parsed(false), compilationMode(mode)
- , vmFunction(0), parseAsBinding(false) {}
+ , vmFunction(nullptr), parseAsBinding(false) {}
Script(ExecutionEngine *engine, QmlContext *qml, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
: sourceFile(source), line(line), column(column), sourceCode(sourceCode)
, context(engine->rootContext()), strictMode(false), inheritContext(true), parsed(false)
- , vmFunction(0), parseAsBinding(true) {
+ , vmFunction(nullptr), parseAsBinding(true) {
if (qml)
qmlContext.set(engine, *qml);
}
@@ -97,8 +97,11 @@ struct Q_QML_EXPORT Script {
Function *function();
- static QQmlRefPointer<CompiledData::CompilationUnit> precompile(QV4::Compiler::Module *module, Compiler::JSUnitGenerator *unitGenerator, const QUrl &url, const QString &source,
- QList<QQmlError> *reportedErrors = 0, QQmlJS::Directives *directivesCollector = 0);
+ static QQmlRefPointer<CompiledData::CompilationUnit> precompile(
+ QV4::Compiler::Module *module, Compiler::JSUnitGenerator *unitGenerator,
+ const QString &fileName, const QString &finalUrl, const QString &source,
+ QList<QQmlError> *reportedErrors = nullptr, QQmlJS::Directives *directivesCollector = nullptr);
+ static Script *createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl);
static ReturnedValue evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext);
};
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 78cd7529d8..7d29d0b517 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -340,7 +340,7 @@ public:
void containerAdvanceIterator(ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
{
- name->setM(0);
+ name->setM(nullptr);
*index = UINT_MAX;
if (d()->isReference) {
@@ -420,11 +420,10 @@ public:
ScopedFunctionObject compare(scope, m_compareFn);
if (!compare)
return m_v4->throwTypeError();
- JSCallData jsCallData(scope, 2);
- jsCallData->args[0] = convertElementToValue(m_v4, lhs);
- jsCallData->args[1] = convertElementToValue(m_v4, rhs);
- *jsCallData->thisObject = m_v4->globalObject;
- QV4::ScopedValue result(scope, compare->call(jsCallData));
+ Value *argv = scope.alloc(2);
+ argv[0] = convertElementToValue(m_v4, lhs);
+ argv[1] = convertElementToValue(m_v4, rhs);
+ QV4::ScopedValue result(scope, compare->call(m_v4->globalObject, argv, 2));
return result->toNumber() < 0;
}
@@ -433,7 +432,7 @@ public:
const QV4::Value *m_compareFn;
};
- void sort(const BuiltinFunction *, Scope &scope, CallData *callData)
+ void sort(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
if (d()->isReference) {
if (!d()->object)
@@ -441,8 +440,8 @@ public:
loadReference();
}
- if (callData->argc() == 1 && callData->args[0].as<FunctionObject>()) {
- CompareFunctor cf(scope.engine, callData->args[0]);
+ if (argc == 1 && argv[0].as<FunctionObject>()) {
+ CompareFunctor cf(f->engine(), argv[0]);
std::sort(d()->container->begin(), d()->container->end(), cf);
} else {
DefaultCompareFunctor cf;
@@ -453,10 +452,10 @@ public:
storeReference();
}
- static QV4::ReturnedValue method_get_length(const BuiltinFunction *b, CallData *callData)
+ static QV4::ReturnedValue method_get_length(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >());
+ QV4::Scoped<QQmlSequence<Container>> This(scope, thisObject->as<QQmlSequence<Container> >());
if (!This)
THROW_TYPE_ERROR();
@@ -468,14 +467,14 @@ public:
RETURN_RESULT(Encode(qint32(This->d()->container->size())));
}
- static QV4::ReturnedValue method_set_length(const BuiltinFunction *b, CallData *callData)
+ static QV4::ReturnedValue method_set_length(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
- QV4::Scope scope(b);
- QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >());
+ QV4::Scope scope(f);
+ QV4::Scoped<QQmlSequence<Container>> This(scope, thisObject->as<QQmlSequence<Container> >());
if (!This)
THROW_TYPE_ERROR();
- quint32 newLength = callData->args[0].toUInt32();
+ quint32 newLength = argc ? argv[0].toUInt32() : 0;
/* Qt containers have int (rather than uint) allowable indexes. */
if (newLength > INT_MAX) {
generateWarning(scope.engine, QLatin1String("Index out of range during length set"));
@@ -536,7 +535,7 @@ public:
{
Q_ASSERT(d()->object);
Q_ASSERT(d()->isReference);
- void *a[] = { d()->container, 0 };
+ void *a[] = { d()->container, nullptr };
QMetaObject::metacall(d()->object, QMetaObject::ReadProperty, d()->propertyIndex, a);
}
@@ -546,7 +545,7 @@ public:
Q_ASSERT(d()->isReference);
int status = -1;
QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding;
- void *a[] = { d()->container, 0, &status, &flags };
+ void *a[] = { d()->container, nullptr, &status, &flags };
QMetaObject::metacall(d()->object, QMetaObject::WriteProperty, d()->propertyIndex, a);
}
@@ -652,24 +651,24 @@ void SequencePrototype::init()
}
#undef REGISTER_QML_SEQUENCE_METATYPE
-ReturnedValue SequencePrototype::method_valueOf(const BuiltinFunction *f, CallData *callData)
+ReturnedValue SequencePrototype::method_valueOf(const FunctionObject *f, const Value *thisObject, const Value *, int)
{
- return Encode(callData->thisObject.toString(f->engine()));
+ return Encode(thisObject->toString(f->engine()));
}
-ReturnedValue SequencePrototype::method_sort(const BuiltinFunction *b, CallData *callData)
+ReturnedValue SequencePrototype::method_sort(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- QV4::ScopedObject o(scope, callData->thisObject);
+ QV4::ScopedObject o(scope, thisObject);
if (!o || !o->isListType())
THROW_TYPE_ERROR();
- if (callData->argc() >= 2)
+ if (argc >= 2)
return o.asReturnedValue();
#define CALL_SORT(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue) \
if (QQml##SequenceElementTypeName##List *s = o->as<QQml##SequenceElementTypeName##List>()) { \
- s->sort(b, scope, callData); \
+ s->sort(b, thisObject, argv, argc); \
} else
FOREACH_QML_SEQUENCE_TYPE(CALL_SORT)
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index 169a48c2f9..e9bef2f604 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -68,8 +68,8 @@ struct SequencePrototype : public QV4::Object
V4_PROTOTYPE(arrayPrototype)
void init();
- static ReturnedValue method_valueOf(const BuiltinFunction *f, CallData *callData);
- static ReturnedValue method_sort(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_sort(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static bool isSequenceType(int sequenceTypeId);
static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
diff --git a/src/qml/jsruntime/qv4sparsearray.cpp b/src/qml/jsruntime/qv4sparsearray.cpp
index 8f6aa6723c..2a3e28bf63 100644
--- a/src/qml/jsruntime/qv4sparsearray.cpp
+++ b/src/qml/jsruntime/qv4sparsearray.cpp
@@ -89,20 +89,20 @@ const SparseArrayNode *SparseArrayNode::previousNode() const
SparseArrayNode *SparseArrayNode::copy(SparseArray *d) const
{
- SparseArrayNode *n = d->createNode(size_left, 0, false);
+ SparseArrayNode *n = d->createNode(size_left, nullptr, false);
n->value = value;
n->setColor(color());
if (left) {
n->left = left->copy(d);
n->left->setParent(n);
} else {
- n->left = 0;
+ n->left = nullptr;
}
if (right) {
n->right = right->copy(d);
n->right->setParent(n);
} else {
- n->right = 0;
+ n->right = nullptr;
}
return n;
}
@@ -119,7 +119,7 @@ void SparseArray::rotateLeft(SparseArrayNode *x)
SparseArrayNode *&root = header.left;
SparseArrayNode *y = x->right;
x->right = y->left;
- if (y->left != 0)
+ if (y->left != nullptr)
y->left->setParent(x);
y->setParent(x->parent());
if (x == root)
@@ -146,7 +146,7 @@ void SparseArray::rotateRight(SparseArrayNode *x)
SparseArrayNode *&root = header.left;
SparseArrayNode *y = x->left;
x->left = y->right;
- if (y->right != 0)
+ if (y->right != nullptr)
y->right->setParent(x);
y->setParent(x->parent());
if (x == root)
@@ -209,7 +209,7 @@ void SparseArray::deleteNode(SparseArrayNode *z)
SparseArrayNode *y = z;
SparseArrayNode *x;
SparseArrayNode *x_parent;
- if (y->left == 0) {
+ if (y->left == nullptr) {
x = y->right;
if (y == mostLeftNode) {
if (x)
@@ -217,11 +217,11 @@ void SparseArray::deleteNode(SparseArrayNode *z)
else
mostLeftNode = y->parent();
}
- } else if (y->right == 0) {
+ } else if (y->right == nullptr) {
x = y->left;
} else {
y = y->right;
- while (y->left != 0)
+ while (y->left != nullptr)
y = y->left;
x = y->right;
}
@@ -261,7 +261,7 @@ void SparseArray::deleteNode(SparseArrayNode *z)
y->size_left = 0;
}
if (y->color() != SparseArrayNode::Red) {
- while (x != root && (x == 0 || x->color() == SparseArrayNode::Black)) {
+ while (x != root && (x == nullptr || x->color() == SparseArrayNode::Black)) {
if (x == x_parent->left) {
SparseArrayNode *w = x_parent->right;
if (w->color() == SparseArrayNode::Red) {
@@ -270,13 +270,13 @@ void SparseArray::deleteNode(SparseArrayNode *z)
rotateLeft(x_parent);
w = x_parent->right;
}
- if ((w->left == 0 || w->left->color() == SparseArrayNode::Black) &&
- (w->right == 0 || w->right->color() == SparseArrayNode::Black)) {
+ if ((w->left == nullptr || w->left->color() == SparseArrayNode::Black) &&
+ (w->right == nullptr || w->right->color() == SparseArrayNode::Black)) {
w->setColor(SparseArrayNode::Red);
x = x_parent;
x_parent = x_parent->parent();
} else {
- if (w->right == 0 || w->right->color() == SparseArrayNode::Black) {
+ if (w->right == nullptr || w->right->color() == SparseArrayNode::Black) {
if (w->left)
w->left->setColor(SparseArrayNode::Black);
w->setColor(SparseArrayNode::Red);
@@ -298,13 +298,13 @@ void SparseArray::deleteNode(SparseArrayNode *z)
rotateRight(x_parent);
w = x_parent->left;
}
- if ((w->right == 0 || w->right->color() == SparseArrayNode::Black) &&
- (w->left == 0 || w->left->color() == SparseArrayNode::Black)) {
+ if ((w->right == nullptr || w->right->color() == SparseArrayNode::Black) &&
+ (w->left == nullptr || w->left->color() == SparseArrayNode::Black)) {
w->setColor(SparseArrayNode::Red);
x = x_parent;
x_parent = x_parent->parent();
} else {
- if (w->left == 0 || w->left->color() == SparseArrayNode::Black) {
+ if (w->left == nullptr || w->left->color() == SparseArrayNode::Black) {
if (w->right)
w->right->setColor(SparseArrayNode::Black);
w->setColor(SparseArrayNode::Red);
@@ -363,8 +363,8 @@ SparseArrayNode *SparseArray::createNode(uint sl, SparseArrayNode *parent, bool
Q_CHECK_PTR(node);
node->p = (quintptr)parent;
- node->left = 0;
- node->right = 0;
+ node->left = nullptr;
+ node->right = nullptr;
node->size_left = sl;
node->value = UINT_MAX;
++numEntries;
@@ -395,21 +395,23 @@ void SparseArray::freeTree(SparseArrayNode *root, int alignment)
SparseArray::SparseArray()
: numEntries(0)
{
+ freeList = Primitive::emptyValue(UINT_MAX).asReturnedValue();
header.p = 0;
- header.left = 0;
- header.right = 0;
+ header.left = nullptr;
+ header.right = nullptr;
mostLeftNode = &header;
}
SparseArray::SparseArray(const SparseArray &other)
{
header.p = 0;
- header.right = 0;
+ header.right = nullptr;
if (other.header.left) {
header.left = other.header.left->copy(this);
header.left->setParent(&header);
recalcMostLeftNode();
}
+ freeList = other.freeList;
}
SparseArrayNode *SparseArray::insert(uint akey)
diff --git a/src/qml/jsruntime/qv4sparsearray_p.h b/src/qml/jsruntime/qv4sparsearray_p.h
index 2e4ac883f2..51869b259f 100644
--- a/src/qml/jsruntime/qv4sparsearray_p.h
+++ b/src/qml/jsruntime/qv4sparsearray_p.h
@@ -109,7 +109,7 @@ struct SparseArrayNode
inline SparseArrayNode *SparseArrayNode::lowerBound(uint akey)
{
SparseArrayNode *n = this;
- SparseArrayNode *last = 0;
+ SparseArrayNode *last = nullptr;
while (n) {
if (akey <= n->size_left) {
last = n;
@@ -126,7 +126,7 @@ inline SparseArrayNode *SparseArrayNode::lowerBound(uint akey)
inline SparseArrayNode *SparseArrayNode::upperBound(uint akey)
{
SparseArrayNode *n = this;
- SparseArrayNode *last = 0;
+ SparseArrayNode *last = nullptr;
while (n) {
if (akey < n->size_left) {
last = n;
@@ -150,6 +150,8 @@ struct Q_QML_EXPORT SparseArray
}
SparseArray(const SparseArray &other);
+
+ ReturnedValue freeList;
private:
SparseArray &operator=(const SparseArray &other);
@@ -221,7 +223,7 @@ inline SparseArrayNode *SparseArray::findNode(uint akey) const
}
}
- return 0;
+ return nullptr;
}
inline uint SparseArray::pop_front()
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index b38b01c9f7..447992ebec 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -55,9 +55,16 @@ using namespace QV4;
void Heap::String::markObjects(Heap::Base *that, MarkStack *markStack)
{
String *s = static_cast<String *>(that);
- if (s->largestSubLength) {
- s->left->mark(markStack);
- s->right->mark(markStack);
+ if (s->subtype < StringType_Complex)
+ return;
+
+ ComplexString *cs = static_cast<ComplexString *>(s);
+ if (cs->subtype == StringType_AddedString) {
+ cs->left->mark(markStack);
+ cs->right->mark(markStack);
+ } else {
+ Q_ASSERT(cs->subtype == StringType_SubString);
+ cs->left->mark(markStack);
}
}
@@ -84,37 +91,45 @@ void Heap::String::init(const QString &t)
text = const_cast<QString &>(t).data_ptr();
text->ref.ref();
- identifier = 0;
- stringHash = UINT_MAX;
- largestSubLength = 0;
- len = text->size;
}
-void Heap::String::init(String *l, String *r)
+void Heap::ComplexString::init(String *l, String *r)
{
Base::init();
- subtype = String::StringType_Unknown;
+ subtype = String::StringType_AddedString;
left = l;
right = r;
- stringHash = UINT_MAX;
- largestSubLength = qMax(l->largestSubLength, r->largestSubLength);
- len = l->len + r->len;
- Q_ASSERT(largestSubLength <= len);
-
- if (!l->largestSubLength && l->len > largestSubLength)
- largestSubLength = l->len;
- if (!r->largestSubLength && r->len > largestSubLength)
- largestSubLength = r->len;
+ len = left->length() + right->length();
+ if (left->subtype >= StringType_Complex)
+ largestSubLength = static_cast<ComplexString *>(left)->largestSubLength;
+ else
+ largestSubLength = left->length();
+ if (right->subtype >= StringType_Complex)
+ largestSubLength = qMax(largestSubLength, static_cast<ComplexString *>(right)->largestSubLength);
+ else
+ largestSubLength = qMax(largestSubLength, right->length());
// make sure we don't get excessive depth in our strings
if (len > 256 && len >= 2*largestSubLength)
simplifyString();
}
+void Heap::ComplexString::init(Heap::String *ref, int from, int len)
+{
+ Q_ASSERT(ref->length() >= from + len);
+ Base::init();
+
+ subtype = String::StringType_SubString;
+
+ left = ref;
+ this->from = from;
+ this->len = len;
+}
+
void Heap::String::destroy() {
- if (!largestSubLength) {
+ if (text) {
internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(-text->size) * (int)sizeof(QChar));
if (!text->ref.deref())
QStringData::deallocate(text);
@@ -126,7 +141,7 @@ uint String::toUInt(bool *ok) const
{
*ok = true;
- if (subtype() == Heap::String::StringType_Unknown)
+ if (subtype() >= Heap::String::StringType_Unknown)
d()->createHashValue();
if (subtype() == Heap::String::StringType_ArrayIndex)
return d()->stringHash;
@@ -142,15 +157,15 @@ uint String::toUInt(bool *ok) const
void String::makeIdentifierImpl() const
{
- if (d()->largestSubLength)
+ if (!d()->text)
d()->simplifyString();
- Q_ASSERT(!d()->largestSubLength);
+ Q_ASSERT(d()->text);
engine()->identifierTable->identifier(this);
}
void Heap::String::simplifyString() const
{
- Q_ASSERT(largestSubLength);
+ Q_ASSERT(!text);
int l = length();
QString result(l, Qt::Uninitialized);
@@ -158,9 +173,33 @@ void Heap::String::simplifyString() const
append(this, ch);
text = result.data_ptr();
text->ref.ref();
- identifier = 0;
- largestSubLength = 0;
+ const ComplexString *cs = static_cast<const ComplexString *>(this);
+ identifier = nullptr;
+ cs->left = cs->right = nullptr;
+
internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(text->size) * (qptrdiff)sizeof(QChar));
+ subtype = StringType_Unknown;
+}
+
+bool Heap::String::startsWithUpper() const
+{
+ if (subtype == StringType_AddedString)
+ return static_cast<const Heap::ComplexString *>(this)->left->startsWithUpper();
+
+ const Heap::String *str = this;
+ int offset = 0;
+ if (subtype == StringType_SubString) {
+ const ComplexString *cs = static_cast<const Heap::ComplexString *>(this);
+ if (!cs->len)
+ return false;
+ // simplification here is not ideal, but hopefully not a common case.
+ if (cs->left->subtype >= Heap::String::StringType_Complex)
+ cs->left->simplifyString();
+ str = cs->left;
+ offset = cs->from;
+ }
+ Q_ASSERT(str->subtype < Heap::String::StringType_Complex);
+ return str->text->size > offset && QChar::isUpper(str->text->data()[offset]);
}
void Heap::String::append(const String *data, QChar *ch)
@@ -173,11 +212,16 @@ void Heap::String::append(const String *data, QChar *ch)
const String *item = worklist.back();
worklist.pop_back();
- if (item->largestSubLength) {
- worklist.push_back(item->right);
- worklist.push_back(item->left);
+ if (item->subtype == StringType_AddedString) {
+ const ComplexString *cs = static_cast<const ComplexString *>(item);
+ worklist.push_back(cs->right);
+ worklist.push_back(cs->left);
+ } else if (item->subtype == StringType_SubString) {
+ const ComplexString *cs = static_cast<const ComplexString *>(item);
+ memcpy(ch, cs->left->toQString().constData() + cs->from, cs->len*sizeof(QChar));
+ ch += cs->len;
} else {
- memcpy(ch, item->text->data(), item->text->size * sizeof(QChar));
+ memcpy(static_cast<void *>(ch), static_cast<const void *>(item->text->data()), item->text->size * sizeof(QChar));
ch += item->text->size;
}
}
@@ -185,9 +229,9 @@ void Heap::String::append(const String *data, QChar *ch)
void Heap::String::createHashValue() const
{
- if (largestSubLength)
+ if (!text)
simplifyString();
- Q_ASSERT(!largestSubLength);
+ Q_ASSERT(text);
const QChar *ch = reinterpret_cast<const QChar *>(text->data());
const QChar *end = ch + text->size;
stringHash = QV4::String::calculateHashValue(ch, end, &subtype);
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 85345aca4d..5466cc274d 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -67,35 +67,32 @@ namespace Heap {
struct Q_QML_PRIVATE_EXPORT String : Base {
static void markObjects(Heap::Base *that, MarkStack *markStack);
enum StringType {
- StringType_Unknown,
StringType_Regular,
- StringType_ArrayIndex
+ StringType_ArrayIndex,
+ StringType_Unknown,
+ StringType_AddedString,
+ StringType_SubString,
+ StringType_Complex = StringType_AddedString
};
#ifndef V4_BOOTSTRAP
void init(const QString &text);
- void init(String *l, String *n);
void destroy();
void simplifyString() const;
- int length() const {
- Q_ASSERT((largestSubLength &&
- (len == left->len + right->len)) ||
- len == (uint)text->size);
- return len;
- }
+ int length() const;
std::size_t retainedTextSize() const {
- return largestSubLength ? 0 : (std::size_t(text->size) * sizeof(QChar));
+ return subtype >= StringType_Complex ? 0 : (std::size_t(text->size) * sizeof(QChar));
}
void createHashValue() const;
inline unsigned hashValue() const {
- if (subtype == StringType_Unknown)
+ if (subtype >= StringType_Unknown)
createHashValue();
- Q_ASSERT(!largestSubLength);
+ Q_ASSERT(subtype < StringType_Complex);
return stringHash;
}
inline QString toQString() const {
- if (largestSubLength)
+ if (subtype >= StringType_Complex)
simplifyString();
QStringDataPtr ptr = { text };
text->ref.ref();
@@ -106,7 +103,7 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
return true;
if (hashValue() != other->hashValue())
return false;
- Q_ASSERT(!largestSubLength);
+ Q_ASSERT(subtype < StringType_Complex);
if (identifier && identifier == other->identifier)
return true;
if (subtype == Heap::String::StringType_ArrayIndex && other->subtype == Heap::String::StringType_ArrayIndex)
@@ -115,23 +112,37 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
return toQString() == other->toQString();
}
- union {
- mutable QStringData *text;
- mutable String *left;
- };
- union {
- mutable Identifier *identifier;
- mutable String *right;
- };
+ bool startsWithUpper() const;
+
+ mutable QStringData *text;
+ mutable Identifier *identifier;
mutable uint subtype;
mutable uint stringHash;
- mutable uint largestSubLength;
- uint len;
private:
static void append(const String *data, QChar *ch);
#endif
};
-V4_ASSERT_IS_TRIVIAL(String)
+Q_STATIC_ASSERT(std::is_trivial< String >::value);
+
+#ifndef V4_BOOTSTRAP
+struct ComplexString : String {
+ void init(String *l, String *n);
+ void init(String *ref, int from, int len);
+ mutable String *left;
+ mutable String *right;
+ union {
+ mutable int largestSubLength;
+ int from;
+ };
+ int len;
+};
+Q_STATIC_ASSERT(std::is_trivial< ComplexString >::value);
+
+inline
+int String::length() const {
+ return text ? text->size : static_cast<const ComplexString *>(this)->len;
+}
+#endif
}
@@ -167,9 +178,9 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
return d()->hashValue();
}
uint asArrayIndex() const {
- if (subtype() == Heap::String::StringType_Unknown)
+ if (subtype() >= Heap::String::StringType_Unknown)
d()->createHashValue();
- Q_ASSERT(!d()->largestSubLength);
+ Q_ASSERT(d()->subtype < Heap::String::StringType_Complex);
if (subtype() == Heap::String::StringType_ArrayIndex)
return d()->stringHash;
return UINT_MAX;
@@ -197,12 +208,7 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
return calculateHashValue(ch, end, subtype);
}
- bool startsWithUpper() const {
- const String::Data *l = d();
- while (l->largestSubLength)
- l = l->left;
- return l->text->size && QChar::isUpper(l->text->data()[0]);
- }
+ bool startsWithUpper() const { return d()->startsWithUpper(); }
Identifier *identifier() const { return d()->identifier; }
@@ -216,7 +222,7 @@ public:
private:
static inline uint toUInt(const QChar *ch) { return ch->unicode(); }
- static inline uint toUInt(const char *ch) { return *ch; }
+ static inline uint toUInt(const char *ch) { return static_cast<unsigned char>(*ch); }
template <typename T>
static inline uint toArrayIndex(const T *ch, const T *end)
@@ -263,12 +269,22 @@ public:
}
};
+#ifndef V4_BOOTSTRAP
+struct ComplexString : String {
+ typedef QV4::Heap::ComplexString Data;
+ QV4::Heap::ComplexString *d_unchecked() const { return static_cast<QV4::Heap::ComplexString *>(m()); }
+ QV4::Heap::ComplexString *d() const {
+ QV4::Heap::ComplexString *dptr = d_unchecked();
+ dptr->_checkIsInitialized();
+ return dptr;
+ }
+};
+
template<>
inline const String *Value::as() const {
- return isManaged() && m()->vtable()->isString ? static_cast<const String *>(this) : 0;
+ return isManaged() && m()->vtable()->isString ? static_cast<const String *>(this) : nullptr;
}
-#ifndef V4_BOOTSTRAP
template<>
inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
{
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index efab51ec53..e5a02fdc22 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -86,13 +86,13 @@ Heap::String *Heap::StringObject::getIndex(uint index) const
{
QString str = string->toQString();
if (index >= (uint)str.length())
- return 0;
+ return nullptr;
return internalClass->engine->newString(str.mid(index, 1));
}
uint Heap::StringObject::length() const
{
- return string->len;
+ return string->length();
}
bool StringObject::deleteIndexedProperty(Managed *m, uint index)
@@ -109,7 +109,7 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index)
void StringObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
{
- name->setM(0);
+ name->setM(nullptr);
StringObject *s = static_cast<StringObject *>(m);
uint slen = s->d()->string->toQString().length();
if (it->arrayIndex <= slen) {
@@ -200,6 +200,15 @@ void StringPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("trim"), method_trim);
}
+static Heap::String *thisAsString(ExecutionEngine *v4, const Value *thisObject)
+{
+ if (String *s = thisObject->stringValue())
+ return s->d();
+ if (const StringObject *thisString = thisObject->as<StringObject>())
+ return thisString->d()->string;
+ return thisObject->toString(v4);
+}
+
static QString getThisString(ExecutionEngine *v4, const Value *thisObject)
{
if (String *s = thisObject->stringValue())
@@ -649,11 +658,13 @@ ReturnedValue StringPrototype::method_search(const FunctionObject *b, const Valu
ReturnedValue StringPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
ExecutionEngine *v4 = b->engine();
- const QString text = getThisString(v4, thisObject);
+ Scope scope(v4);
+ ScopedString s(scope, thisAsString(v4, thisObject));
if (v4->hasException)
return QV4::Encode::undefined();
+ Q_ASSERT(s);
- const double length = text.length();
+ const double length = s->d()->length();
double start = argc ? argv[0].toInteger() : 0;
double end = (argc < 2 || argv[1].isUndefined())
@@ -673,7 +684,7 @@ ReturnedValue StringPrototype::method_slice(const FunctionObject *b, const Value
const int intEnd = int(end);
int count = qMax(0, intEnd - intStart);
- return Encode(v4->newString(text.mid(intStart, count)));
+ return Encode(v4->memoryManager->alloc<ComplexString>(s->d(), intStart, count));
}
ReturnedValue StringPrototype::method_split(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
@@ -706,7 +717,7 @@ ReturnedValue StringPrototype::method_split(const FunctionObject *b, const Value
Scoped<RegExpObject> re(scope, separatorValue);
if (re) {
if (re->value()->pattern->isEmpty()) {
- re = (RegExpObject *)0;
+ re = (RegExpObject *)nullptr;
separatorValue = scope.engine->newString();
}
}
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 4ba31f9b6e..ea1532b8ce 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -399,10 +399,10 @@ void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor)
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
ctor->defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement));
defineDefaultProperty(engine->id_constructor(), (o = ctor));
- defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, 0);
- defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, 0);
- defineAccessorProperty(QStringLiteral("byteOffset"), method_get_byteOffset, 0);
- defineAccessorProperty(QStringLiteral("length"), method_get_length, 0);
+ defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, nullptr);
+ defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, nullptr);
+ defineAccessorProperty(QStringLiteral("byteOffset"), method_get_byteOffset, nullptr);
+ defineAccessorProperty(QStringLiteral("length"), method_get_length, nullptr);
defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement));
defineDefaultProperty(QStringLiteral("set"), method_set, 1);
@@ -514,7 +514,7 @@ ReturnedValue TypedArrayPrototype::method_set(const FunctionObject *b, const Val
RETURN_UNDEFINED();
}
- char *srcCopy = 0;
+ char *srcCopy = nullptr;
if (buffer->d() == srcBuffer->d()) {
// same buffer, need to take a temporary copy, to not run into problems
srcCopy = new char[srcTypedArray->d()->byteLength];
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 52d9f23afd..97ed13cd91 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -57,6 +57,8 @@
#include "qv4global_p.h"
#include <private/qv4heap_p.h>
+#include <private/qnumeric_p.h>
+
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -322,6 +324,8 @@ public:
return d;
}
QML_NEARLY_ALWAYS_INLINE void setDouble(double d) {
+ if (qt_is_nan(d))
+ d = qt_qnan();
memcpy(&_val, &d, 8);
_val ^= NaNEncodeMask;
Q_ASSERT(isDouble());
@@ -422,7 +426,7 @@ public:
template <typename T>
const T *as() const {
if (!isManaged())
- return 0;
+ return nullptr;
Q_ASSERT(m()->vtable());
#if !defined(QT_NO_QOBJECT_CHECK)
@@ -434,7 +438,7 @@ public:
return static_cast<const T *>(this);
vt = vt->parent;
}
- return 0;
+ return nullptr;
}
template <typename T>
T *as() {
@@ -457,6 +461,7 @@ public:
uint asArrayLength(bool *ok) const;
#endif
+ ReturnedValue *data_ptr() { return &_val; }
ReturnedValue asReturnedValue() const { return _val; }
static Value fromReturnedValue(ReturnedValue val) { Value v; v._val = val; return v; }
@@ -469,7 +474,7 @@ public:
Value &operator=(ReturnedValue v) { _val = v; return *this; }
Value &operator=(Managed *m) {
if (!m) {
- setM(0);
+ setM(nullptr);
} else {
_val = reinterpret_cast<Value *>(m)->_val;
}
@@ -483,7 +488,7 @@ public:
template<typename T>
Value &operator=(const Scoped<T> &t);
};
-V4_ASSERT_IS_TRIVIAL(Value)
+Q_STATIC_ASSERT(std::is_trivial< Value >::value);
inline void Value::mark(MarkStack *markStack)
{
@@ -792,6 +797,94 @@ inline double Value::toInteger() const
}
+template <size_t o>
+struct HeapValue : Value {
+ static Q_CONSTEXPR size_t offset = o;
+ Heap::Base *base() {
+ Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
+ Q_ASSERT(base->inUse());
+ return base;
+ }
+
+ void set(EngineBase *e, const Value &newVal) {
+ WriteBarrier::write(e, base(), data_ptr(), newVal.asReturnedValue());
+ }
+ void set(EngineBase *e, Heap::Base *b) {
+ WriteBarrier::write(e, base(), data_ptr(), b->asReturnedValue());
+ }
+};
+
+template <size_t o>
+struct ValueArray {
+ static Q_CONSTEXPR size_t offset = o;
+ uint size;
+ uint alloc;
+ Value values[1];
+
+ Heap::Base *base() {
+ Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
+ Q_ASSERT(base->inUse());
+ return base;
+ }
+
+ void set(EngineBase *e, uint index, Value v) {
+ WriteBarrier::write(e, base(), values[index].data_ptr(), v.asReturnedValue());
+ }
+ void set(EngineBase *e, uint index, Heap::Base *b) {
+ WriteBarrier::write(e, base(), values[index].data_ptr(), b->asReturnedValue());
+ }
+ inline const Value &operator[] (uint index) const {
+ Q_ASSERT(index < alloc);
+ return values[index];
+ }
+ inline const Value *data() const {
+ return values;
+ }
+
+ void insertData(EngineBase *e, uint index, Value v) {
+ for (uint i = size - 1; i > index; --i) {
+ values[i] = values[i - 1];
+ }
+ set(e, index, v);
+ }
+ void removeData(EngineBase *e, uint index, int n = 1) {
+ Q_UNUSED(e);
+ for (uint i = index; i < size - n; ++i) {
+ values[i] = values[i + n];
+ }
+ }
+
+ void mark(MarkStack *markStack) {
+ Value *v = values;
+ const Value *end = v + alloc;
+ if (alloc > 32*1024) {
+ // drain from time to time to avoid overflows in the js stack
+ Heap::Base **currentBase = markStack->top;
+ while (v < end) {
+ v->mark(markStack);
+ ++v;
+ if (markStack->top >= currentBase + 32*1024) {
+ Heap::Base **oldBase = markStack->base;
+ markStack->base = currentBase;
+ markStack->drain();
+ markStack->base = oldBase;
+ }
+ }
+ } else {
+ while (v < end) {
+ v->mark(markStack);
+ ++v;
+ }
+ }
+ }
+};
+
+// It's really important that the offset of values in this structure is
+// constant across all architecture, otherwise JIT cross-compiled code will
+// have wrong offsets between host and target.
+Q_STATIC_ASSERT(offsetof(ValueArray<0>, values) == 8);
+
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index 00be90b3c2..bee17e0390 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -113,17 +113,17 @@ void VariantPrototype::init()
defineDefaultProperty(engine()->id_toString(), method_toString, 0);
}
-ReturnedValue VariantPrototype::method_preserve(const BuiltinFunction *, CallData *callData)
+ReturnedValue VariantPrototype::method_preserve(const FunctionObject *, const Value *thisObject, const Value *, int)
{
- VariantObject *o = callData->thisObject.as<QV4::VariantObject>();
+ const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (o && o->d()->isScarce())
o->d()->addVmePropertyReference();
RETURN_UNDEFINED();
}
-ReturnedValue VariantPrototype::method_destroy(const BuiltinFunction *, CallData *callData)
+ReturnedValue VariantPrototype::method_destroy(const FunctionObject *, const Value *thisObject, const Value *, int)
{
- VariantObject *o = callData->thisObject.as<QV4::VariantObject>();
+ const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (o) {
if (o->d()->isScarce())
o->d()->addVmePropertyReference();
@@ -132,10 +132,10 @@ ReturnedValue VariantPrototype::method_destroy(const BuiltinFunction *, CallData
RETURN_UNDEFINED();
}
-ReturnedValue VariantPrototype::method_toString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue VariantPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
ExecutionEngine *v4 = b->engine();
- VariantObject *o = callData->thisObject.as<QV4::VariantObject>();
+ const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (!o)
RETURN_UNDEFINED();
QString result = o->d()->data().toString();
@@ -147,9 +147,9 @@ ReturnedValue VariantPrototype::method_toString(const BuiltinFunction *b, CallDa
return Encode(v4->newString(result));
}
-ReturnedValue VariantPrototype::method_valueOf(const BuiltinFunction *b, CallData *callData)
+ReturnedValue VariantPrototype::method_valueOf(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- VariantObject *o = callData->thisObject.as<QV4::VariantObject>();
+ const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (o) {
QVariant v = o->d()->data();
switch (v.type()) {
@@ -170,7 +170,7 @@ ReturnedValue VariantPrototype::method_valueOf(const BuiltinFunction *b, CallDat
break;
}
}
- return callData->thisObject.asReturnedValue();
+ return thisObject->asReturnedValue();
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index 07b3310e91..62fa7ff9a8 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -108,10 +108,10 @@ public:
V4_PROTOTYPE(objectPrototype)
void init();
- static ReturnedValue method_preserve(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_destroy(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_valueOf(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_preserve(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_destroy(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index bc1cb8caa7..bd07473176 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -492,6 +492,7 @@ static bool compareEqualInt(Value &accumulator, Value lhs, int rhs)
if (val.isDouble()) \
d = val.doubleValue(); \
else { \
+ STORE_ACC(); \
d = val.toNumberImpl(); \
CHECK_EXCEPTION; \
} \
@@ -552,17 +553,17 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
Profiling::FunctionCallProfiler profiler(engine, function); // start execution profiling
QV4::Debugging::Debugger *debugger = engine->debugger();
-
- const uchar *exceptionHandler = 0;
+ const uchar *exceptionHandler = nullptr;
QV4::Value &accumulator = frame.jsFrame->accumulator;
QV4::ReturnedValue acc = Encode::undefined();
#ifdef V4_ENABLE_JIT
- static const bool forceInterpreter = qEnvironmentVariableIsSet("QV4_FORCE_INTERPRETER");
- if (function->jittedCode == nullptr) {
- if (ExecutionEngine::canJIT() && debugger == nullptr && !forceInterpreter)
+ if (function->jittedCode == nullptr && debugger == nullptr) {
+ if (engine->canJIT(function))
QV4::JIT::BaselineJIT(function).generate();
+ else
+ ++function->interpreterCallCount;
}
#endif // V4_ENABLE_JIT
@@ -634,7 +635,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
MOTH_BEGIN_INSTR(StoreLocal)
CHECK_EXCEPTION;
auto cc = static_cast<Heap::CallContext *>(stack[CallData::Context].m());
- QV4::WriteBarrier::write(engine, cc, cc->locals.values + index, ACC);
+ QV4::WriteBarrier::write(engine, cc, cc->locals.values[index].data_ptr(), acc);
MOTH_END_INSTR(StoreLocal)
MOTH_BEGIN_INSTR(LoadScopedLocal)
@@ -645,7 +646,7 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
MOTH_BEGIN_INSTR(StoreScopedLocal)
CHECK_EXCEPTION;
auto cc = getScope(stack, scope);
- QV4::WriteBarrier::write(engine, cc, cc->locals.values + index, ACC);
+ QV4::WriteBarrier::write(engine, cc, cc->locals.values[index].data_ptr(), acc);
MOTH_END_INSTR(StoreScopedLocal)
MOTH_BEGIN_INSTR(LoadRuntimeString)
@@ -839,6 +840,18 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
CHECK_EXCEPTION;
MOTH_END_INSTR(CallGlobalLookup)
+ MOTH_BEGIN_INSTR(CallScopeObjectProperty)
+ STORE_IP();
+ acc = Runtime::method_callQmlScopeObjectProperty(engine, stack + base, name, stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CallScopeObjectProperty)
+
+ MOTH_BEGIN_INSTR(CallContextObjectProperty)
+ STORE_IP();
+ acc = Runtime::method_callQmlContextObjectProperty(engine, stack + base, name, stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CallContextObjectProperty)
+
MOTH_BEGIN_INSTR(SetExceptionHandler)
exceptionHandler = offset ? code + offset : nullptr;
MOTH_END_INSTR(SetExceptionHandler)
@@ -1145,14 +1158,13 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
MOTH_BEGIN_INSTR(CmpInstanceOf)
// 11.8.6, 5: rval must be an Object
- const Object *rhs = Primitive::fromReturnedValue(acc).as<Object>();
- if (Q_UNLIKELY(!rhs)) {
+ if (Q_UNLIKELY(!Primitive::fromReturnedValue(acc).isObject())) {
acc = engine->throwTypeError();
goto catchException;
}
// 11.8.6, 7: call "HasInstance", which we term instanceOf, and return the result.
- acc = rhs->instanceOf(STACK_VALUE(lhs));
+ acc = Primitive::fromReturnedValue(acc).objectValue()->instanceOf(STACK_VALUE(lhs));
CHECK_EXCEPTION;
MOTH_END_INSTR(CmpInstanceOf)
@@ -1294,9 +1306,9 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
MOTH_END_INSTR(BitXor)
MOTH_BEGIN_INSTR(UShr)
- uint l = STACK_VALUE(lhs).toUInt32();
+ VALUE_TO_INT(l, STACK_VALUE(lhs));
VALUE_TO_INT(a, ACC);
- acc = Encode(l >> uint(a & 0x1f));
+ acc = Encode(static_cast<uint>(l) >> uint(a & 0x1f));
MOTH_END_INSTR(UShr)
MOTH_BEGIN_INSTR(Shr)
@@ -1345,12 +1357,12 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
goto functionExit;
MOTH_END_INSTR(Ret)
-#if QT_CONFIG(qml_debug)
MOTH_BEGIN_INSTR(Debug)
+#if QT_CONFIG(qml_debug)
STORE_IP();
debug_slowPath(engine);
- MOTH_END_INSTR(Debug)
#endif // QT_CONFIG(qml_debug)
+ MOTH_END_INSTR(Debug)
MOTH_BEGIN_INSTR(LoadQmlContext)
STACK_VALUE(result) = Runtime::method_loadQmlContext(static_cast<QV4::NoThrowEngine*>(engine));
diff --git a/src/qml/jsruntime/qv4vme_moth_p.h b/src/qml/jsruntime/qv4vme_moth_p.h
index dbf9ed3550..3b7723ca7e 100644
--- a/src/qml/jsruntime/qv4vme_moth_p.h
+++ b/src/qml/jsruntime/qv4vme_moth_p.h
@@ -53,8 +53,6 @@
#include <private/qv4global_p.h>
-QT_REQUIRE_CONFIG(qml_interpreter);
-
QT_BEGIN_NAMESPACE
namespace QV4 {
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index d6cb661d19..63d6b0a609 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -53,6 +53,7 @@
#include <QtCore/QString>
#include <private/qv4global_p.h>
#include <private/qv4mmdefs_p.h>
+#include <private/qv4writebarrier_p.h>
#include <private/qv4internalclass_p.h>
#include <QSharedPointer>
@@ -60,12 +61,6 @@
// parent's init all up the inheritance chain), define QML_CHECK_INIT_DESTROY_CALLS below.
#undef QML_CHECK_INIT_DESTROY_CALLS
-#if defined(_MSC_VER) && (_MSC_VER < 1900) // broken compilers:
-# define V4_ASSERT_IS_TRIVIAL(x)
-#else // working compilers:
-# define V4_ASSERT_IS_TRIVIAL(x) Q_STATIC_ASSERT(std::is_trivial< x >::value);
-#endif
-
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -188,7 +183,7 @@ struct Q_QML_EXPORT Base {
Q_ALWAYS_INLINE void _setDestroyed() {}
#endif
};
-V4_ASSERT_IS_TRIVIAL(Base)
+Q_STATIC_ASSERT(std::is_trivial< Base >::value);
// This class needs to consist only of pointer sized members to allow
// for a size/offset translation when cross-compiling between 32- and
// 64-bit.
@@ -214,6 +209,39 @@ void Heap::Base::mark(QV4::MarkStack *markStack)
}
}
+namespace Heap {
+
+template <typename T, size_t o>
+struct Pointer {
+ static Q_CONSTEXPR size_t offset = o;
+ T operator->() const { return get(); }
+ operator T () const { return get(); }
+
+ Heap::Base *base() {
+ Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
+ Q_ASSERT(base->inUse());
+ return base;
+ }
+
+ void set(EngineBase *e, T newVal) {
+ WriteBarrier::write(e, base(), &ptr, reinterpret_cast<Heap::Base *>(newVal));
+ }
+
+ T get() const { return reinterpret_cast<T>(ptr); }
+
+ template <typename Type>
+ Type *cast() { return static_cast<Type *>(ptr); }
+
+ Heap::Base *heapObject() const { return ptr; }
+
+private:
+ Heap::Base *ptr;
+};
+typedef Pointer<char *, 0> V4PointerCheck;
+Q_STATIC_ASSERT(std::is_trivial< V4PointerCheck >::value);
+
+}
+
#ifdef QT_NO_QOBJECT
template <class T>
struct QQmlQPointer {
@@ -266,7 +294,7 @@ private:
QtSharedPointer::ExternalRefCountData *d;
QObject *qObject;
};
-V4_ASSERT_IS_TRIVIAL(QQmlQPointer<QObject>)
+Q_STATIC_ASSERT(std::is_trivial< QQmlQPointer<QObject> >::value);
#endif
}
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 3ea7908e9d..4e83abebdf 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -44,6 +44,7 @@
#include "qv4qobjectwrapper_p.h"
#include <QtCore/qalgorithms.h>
#include <QtCore/private/qnumeric_p.h>
+#include <QtCore/qloggingcategory.h>
#include <qqmlengine.h>
#include "PageReservation.h"
#include "PageAllocation.h"
@@ -91,6 +92,11 @@
#define MIN_UNMANAGED_HEAPSIZE_GC_LIMIT std::size_t(128 * 1024)
+Q_LOGGING_CATEGORY(lcGcStats, "qt.qml.gc.statistics")
+Q_DECLARE_LOGGING_CATEGORY(lcGcStats)
+Q_LOGGING_CATEGORY(lcGcAllocatorStats, "qt.qml.gc.allocatorStats")
+Q_DECLARE_LOGGING_CATEGORY(lcGcAllocatorStats)
+
using namespace WTF;
QT_BEGIN_NAMESPACE
@@ -180,7 +186,7 @@ struct MemorySegment {
}
PageReservation pageReservation;
- Chunk *base = 0;
+ Chunk *base = nullptr;
quint64 allocatedMap = 0;
size_t availableBytes = 0;
uint nChunks = 0;
@@ -197,14 +203,14 @@ Chunk *MemorySegment::allocate(size_t size)
}
size_t requiredChunks = (size + sizeof(Chunk) - 1)/sizeof(Chunk);
uint sequence = 0;
- Chunk *candidate = 0;
+ Chunk *candidate = nullptr;
for (uint i = 0; i < nChunks; ++i) {
if (!testBit(i)) {
if (!candidate)
candidate = base + i;
++sequence;
} else {
- candidate = 0;
+ candidate = nullptr;
sequence = 0;
}
if (sequence == requiredChunks) {
@@ -215,7 +221,7 @@ Chunk *MemorySegment::allocate(size_t size)
return candidate;
}
}
- return 0;
+ return nullptr;
}
struct ChunkAllocator {
@@ -290,7 +296,8 @@ static void increaseFreedCountForClass(const char *className)
(*freedObjectStatsGlobal())[className]++;
}
-bool Chunk::sweep(ClassDestroyStatsCallback classCountPtr)
+//bool Chunk::sweep(ClassDestroyStatsCallback classCountPtr)
+bool Chunk::sweep(ExecutionEngine *engine)
{
bool hasUsedSlots = false;
SDUMP() << "sweeping chunk" << this;
@@ -329,13 +336,19 @@ bool Chunk::sweep(ClassDestroyStatsCallback classCountPtr)
HeapItem *itemToFree = o + index;
Heap::Base *b = *itemToFree;
const VTable *v = b->vtable();
- if (Q_UNLIKELY(classCountPtr))
- classCountPtr(v->className);
+// if (Q_UNLIKELY(classCountPtr))
+// classCountPtr(v->className);
if (v->destroy) {
v->destroy(b);
b->_checkIsDestroyed();
}
+#ifdef V4_USE_HEAPTRACK
+ heaptrack_report_free(itemToFree);
+#endif
}
+ Q_V4_PROFILE_DEALLOC(engine, qPopulationCount((objectBitmap[i] | extendsBitmap[i])
+ - (blackBitmap[i] | e)) * Chunk::SlotSize,
+ Profiling::SmallItem);
objectBitmap[i] = blackBitmap[i];
grayBitmap[i] = 0;
hasUsedSlots |= (blackBitmap[i] != 0);
@@ -350,7 +363,7 @@ bool Chunk::sweep(ClassDestroyStatsCallback classCountPtr)
return hasUsedSlots;
}
-void Chunk::freeAll()
+void Chunk::freeAll(ExecutionEngine *engine)
{
// DEBUG << "sweeping chunk" << this << (*freeList);
HeapItem *o = realBase();
@@ -380,7 +393,12 @@ void Chunk::freeAll()
b->vtable()->destroy(b);
b->_checkIsDestroyed();
}
+#ifdef V4_USE_HEAPTRACK
+ heaptrack_report_free(itemToFree);
+#endif
}
+ Q_V4_PROFILE_DEALLOC(engine, (qPopulationCount(objectBitmap[i]|extendsBitmap[i])
+ - qPopulationCount(e)) * Chunk::SlotSize, Profiling::SmallItem);
objectBitmap[i] = 0;
grayBitmap[i] = 0;
extendsBitmap[i] = e;
@@ -498,9 +516,9 @@ void Chunk::sortIntoBins(HeapItem **bins, uint nBins)
HeapItem *BlockAllocator::allocate(size_t size, bool forceAllocation) {
Q_ASSERT((size % Chunk::SlotSize) == 0);
size_t slotsRequired = size >> Chunk::SlotSizeShift;
-#if MM_DEBUG
- ++allocations[bin];
-#endif
+
+ if (allocationStats)
+ ++allocationStats[binForSlots(slotsRequired)];
HeapItem **last;
@@ -576,8 +594,9 @@ HeapItem *BlockAllocator::allocate(size_t size, bool forceAllocation) {
if (!m) {
if (!forceAllocation)
- return 0;
+ return nullptr;
Chunk *newChunk = chunkAllocator->allocate();
+ Q_V4_PROFILE_ALLOC(engine, Chunk::DataSize, Profiling::HeapPage);
chunks.push_back(newChunk);
nextFree = newChunk->first();
nFree = Chunk::AvailableSlots;
@@ -588,26 +607,31 @@ HeapItem *BlockAllocator::allocate(size_t size, bool forceAllocation) {
done:
m->setAllocatedSlots(slotsRequired);
+ Q_V4_PROFILE_ALLOC(engine, slotsRequired * Chunk::SlotSize, Profiling::SmallItem);
+#ifdef V4_USE_HEAPTRACK
+ heaptrack_report_alloc(m, slotsRequired * Chunk::SlotSize);
+#endif
// DEBUG << " " << hex << m->chunk() << m->chunk()->objectBitmap[0] << m->chunk()->extendsBitmap[0] << (m - m->chunk()->realBase());
return m;
}
-void BlockAllocator::sweep(ClassDestroyStatsCallback classCountPtr)
+void BlockAllocator::sweep()
{
- nextFree = 0;
+ nextFree = nullptr;
nFree = 0;
memset(freeBins, 0, sizeof(freeBins));
// qDebug() << "BlockAlloc: sweep";
usedSlotsAfterLastSweep = 0;
- auto isFree = [this, classCountPtr] (Chunk *c) {
- bool isUsed = c->sweep(classCountPtr);
+ auto isFree = [this] (Chunk *c) {
+ bool isUsed = c->sweep(engine);
if (isUsed) {
c->sortIntoBins(freeBins, NumBins);
usedSlotsAfterLastSweep += c->nUsedSlots();
} else {
+ Q_V4_PROFILE_DEALLOC(engine, Chunk::DataSize, Profiling::HeapPage);
chunkAllocator->free(c);
}
return !isUsed;
@@ -620,7 +644,8 @@ void BlockAllocator::sweep(ClassDestroyStatsCallback classCountPtr)
void BlockAllocator::freeAll()
{
for (auto c : chunks) {
- c->freeAll();
+ c->freeAll(engine);
+ Q_V4_PROFILE_DEALLOC(engine, Chunk::DataSize, Profiling::HeapPage);
chunkAllocator->free(c);
}
}
@@ -638,41 +663,27 @@ void BlockAllocator::collectGrayItems(MarkStack *markStack)
}
-#if MM_DEBUG
-void BlockAllocator::stats() {
- DEBUG << "MM stats:";
- QString s;
- for (int i = 0; i < 10; ++i) {
- uint c = 0;
- HeapItem *item = freeBins[i];
- while (item) {
- ++c;
- item = item->freeData.next;
- }
- s += QString::number(c) + QLatin1String(", ");
- }
- HeapItem *item = freeBins[NumBins - 1];
- uint c = 0;
- while (item) {
- ++c;
- item = item->freeData.next;
- }
- s += QLatin1String("..., ") + QString::number(c);
- DEBUG << "bins:" << s;
- QString a;
- for (int i = 0; i < 10; ++i)
- a += QString::number(allocations[i]) + QLatin1String(", ");
- a += QLatin1String("..., ") + QString::number(allocations[NumBins - 1]);
- DEBUG << "allocs:" << a;
- memset(allocations, 0, sizeof(allocations));
-}
-#endif
-
-
HeapItem *HugeItemAllocator::allocate(size_t size) {
- Chunk *c = chunkAllocator->allocate(size);
- chunks.push_back(HugeChunk{c, size});
+ MemorySegment *m = nullptr;
+ Chunk *c = nullptr;
+ if (size >= MemorySegment::SegmentSize/2) {
+ // too large to handle through the ChunkAllocator, let's get our own memory segement
+ size_t segmentSize = size + Chunk::HeaderSize; // space required for the Chunk header
+ size_t pageSize = WTF::pageSize();
+ segmentSize = (segmentSize + pageSize - 1) & ~(pageSize - 1); // align to page sizes
+ m = new MemorySegment(segmentSize);
+ size = (size + pageSize - 1) & ~(pageSize - 1); // align to page sizes
+ c = m->allocate(size);
+ } else {
+ c = chunkAllocator->allocate(size);
+ }
+ Q_ASSERT(c);
+ chunks.push_back(HugeChunk{m, c, size});
Chunk::setBit(c->objectBitmap, c->first() - c->realBase());
+ Q_V4_PROFILE_ALLOC(engine, size, Profiling::LargeItem);
+#ifdef V4_USE_HEAPTRACK
+ heaptrack_report_alloc(c, size);
+#endif
return c->first();
}
@@ -688,15 +699,27 @@ static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocato
v->destroy(b);
b->_checkIsDestroyed();
}
- chunkAllocator->free(c.chunk, c.size);
+ if (c.segment) {
+ // own memory segment
+ c.segment->free(c.chunk, c.size);
+ delete c.segment;
+ } else {
+ chunkAllocator->free(c.chunk, c.size);
+ }
+#ifdef V4_USE_HEAPTRACK
+ heaptrack_report_free(c.chunk);
+#endif
}
void HugeItemAllocator::sweep(ClassDestroyStatsCallback classCountPtr)
{
auto isBlack = [this, classCountPtr] (const HugeChunk &c) {
bool b = c.chunk->first()->isBlack();
- if (!b)
+ Chunk::clearBit(c.chunk->blackBitmap, c.chunk->first() - c.chunk->realBase());
+ if (!b) {
+ Q_V4_PROFILE_DEALLOC(engine, c.size, Profiling::LargeItem);
freeHugeChunk(chunkAllocator, c, classCountPtr);
+ }
return !b;
};
@@ -725,6 +748,7 @@ void HugeItemAllocator::collectGrayItems(MarkStack *markStack)
void HugeItemAllocator::freeAll()
{
for (auto &c : chunks) {
+ Q_V4_PROFILE_DEALLOC(engine, c.size, Profiling::LargeItem);
freeHugeChunk(chunkAllocator, c, nullptr);
}
}
@@ -733,17 +757,21 @@ void HugeItemAllocator::freeAll()
MemoryManager::MemoryManager(ExecutionEngine *engine)
: engine(engine)
, chunkAllocator(new ChunkAllocator)
- , blockAllocator(chunkAllocator)
- , hugeItemAllocator(chunkAllocator)
+ , blockAllocator(chunkAllocator, engine)
+ , hugeItemAllocator(chunkAllocator, engine)
, m_persistentValues(new PersistentValueStorage(engine))
, m_weakValues(new PersistentValueStorage(engine))
, unmanagedHeapSizeGCLimit(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT)
, aggressiveGC(!qEnvironmentVariableIsEmpty("QV4_MM_AGGRESSIVE_GC"))
- , gcStats(!qEnvironmentVariableIsEmpty(QV4_MM_STATS))
+ , gcStats(lcGcStats().isDebugEnabled())
+ , gcCollectorStats(lcGcAllocatorStats().isDebugEnabled())
{
#ifdef V4_USE_VALGRIND
VALGRIND_CREATE_MEMPOOL(this, 0, true);
#endif
+ memset(statistics.allocations, 0, sizeof(statistics.allocations));
+ if (gcStats)
+ blockAllocator.allocationStats = statistics.allocations;
}
#ifdef MM_STATS
@@ -803,9 +831,6 @@ Heap::Base *MemoryManager::allocData(std::size_t size)
runGC();
didRunGC = true;
}
-#ifdef DETAILED_MM_STATS
- willAllocate(size);
-#endif // DETAILED_MM_STATS
Q_ASSERT(size >= Chunk::SlotSize);
Q_ASSERT(size % Chunk::SlotSize == 0);
@@ -992,7 +1017,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
}
}
- blockAllocator.sweep(classCountPtr);
+ blockAllocator.sweep();
hugeItemAllocator.sweep(classCountPtr);
}
@@ -1006,9 +1031,10 @@ bool MemoryManager::shouldRunGC() const
size_t dumpBins(BlockAllocator *b, bool printOutput = true)
{
+ const QLoggingCategory &stats = lcGcAllocatorStats();
size_t totalSlotMem = 0;
if (printOutput)
- qDebug() << "Slot map:";
+ qDebug(stats) << "Slot map:";
for (uint i = 0; i < BlockAllocator::NumBins; ++i) {
uint nEntries = 0;
HeapItem *h = b->freeBins[i];
@@ -1018,7 +1044,7 @@ size_t dumpBins(BlockAllocator *b, bool printOutput = true)
h = h->freeData.next;
}
if (printOutput)
- qDebug() << " number of entries in slot" << i << ":" << nEntries;
+ qDebug(stats) << " number of entries in slot" << i << ":" << nEntries;
}
SDUMP() << " large slot map";
HeapItem *h = b->freeBins[BlockAllocator::NumBins - 1];
@@ -1028,7 +1054,7 @@ size_t dumpBins(BlockAllocator *b, bool printOutput = true)
}
if (printOutput)
- qDebug() << " total mem in bins" << totalSlotMem*Chunk::SlotSize;
+ qDebug(stats) << " total mem in bins" << totalSlotMem*Chunk::SlotSize;
return totalSlotMem*Chunk::SlotSize;
}
@@ -1042,27 +1068,32 @@ void MemoryManager::runGC()
QScopedValueRollback<bool> gcBlocker(gcBlocked, true);
// qDebug() << "runGC";
- if (!gcStats) {
-// uint oldUsed = allocator.usedMem();
+ if (gcStats) {
+ statistics.maxReservedMem = qMax(statistics.maxReservedMem, getAllocatedMem());
+ statistics.maxAllocatedMem = qMax(statistics.maxAllocatedMem, getUsedMem() + getLargeItemsMem());
+ }
+
+ if (!gcCollectorStats) {
mark();
sweep();
-// DEBUG << "RUN GC: allocated:" << allocator.allocatedMem() << "used before" << oldUsed << "used now" << allocator.usedMem();
} else {
bool triggeredByUnmanagedHeap = (unmanagedHeapSize > unmanagedHeapSizeGCLimit);
size_t oldUnmanagedSize = unmanagedHeapSize;
+
const size_t totalMem = getAllocatedMem();
const size_t usedBefore = getUsedMem();
const size_t largeItemsBefore = getLargeItemsMem();
- qDebug() << "========== GC ==========";
+ const QLoggingCategory &stats = lcGcAllocatorStats();
+ qDebug(stats) << "========== GC ==========";
#ifdef MM_STATS
- qDebug() << " Triggered by alloc request of" << lastAllocRequestedSlots << "slots.";
- qDebug() << " Allocations since last GC" << allocationCount;
+ qDebug(stats) << " Triggered by alloc request of" << lastAllocRequestedSlots << "slots.";
+ qDebug(stats) << " Allocations since last GC" << allocationCount;
allocationCount = 0;
#endif
size_t oldChunks = blockAllocator.chunks.size();
- qDebug() << "Allocated" << totalMem << "bytes in" << oldChunks << "chunks";
- qDebug() << "Fragmented memory before GC" << (totalMem - usedBefore);
+ qDebug(stats) << "Allocated" << totalMem << "bytes in" << oldChunks << "chunks";
+ qDebug(stats) << "Fragmented memory before GC" << (totalMem - usedBefore);
dumpBins(&blockAllocator);
#ifdef MM_STATS
@@ -1080,15 +1111,15 @@ void MemoryManager::runGC()
qint64 sweepTime = t.nsecsElapsed()/1000;
if (triggeredByUnmanagedHeap) {
- qDebug() << "triggered by unmanaged heap:";
- qDebug() << " old unmanaged heap size:" << oldUnmanagedSize;
- qDebug() << " new unmanaged heap:" << unmanagedHeapSize;
- qDebug() << " unmanaged heap limit:" << unmanagedHeapSizeGCLimit;
+ qDebug(stats) << "triggered by unmanaged heap:";
+ qDebug(stats) << " old unmanaged heap size:" << oldUnmanagedSize;
+ qDebug(stats) << " new unmanaged heap:" << unmanagedHeapSize;
+ qDebug(stats) << " unmanaged heap limit:" << unmanagedHeapSizeGCLimit;
}
size_t memInBins = dumpBins(&blockAllocator);
- qDebug() << "Marked object in" << markTime << "us.";
- qDebug() << " " << markStackSize << "objects marked";
- qDebug() << "Sweeped object in" << sweepTime << "us.";
+ qDebug(stats) << "Marked object in" << markTime << "us.";
+ qDebug(stats) << " " << markStackSize << "objects marked";
+ qDebug(stats) << "Sweeped object in" << sweepTime << "us.";
// sort our object types by number of freed instances
MMStatsHash freedObjectStats;
@@ -1103,26 +1134,29 @@ void MemoryManager::runGC()
return a.second > b.second && strcmp(a.first, b.first) < 0;
});
- qDebug() << "Used memory before GC:" << usedBefore;
- qDebug() << "Used memory after GC:" << usedAfter;
- qDebug() << "Freed up bytes :" << (usedBefore - usedAfter);
- qDebug() << "Freed up chunks :" << (oldChunks - blockAllocator.chunks.size());
+ qDebug(stats) << "Used memory before GC:" << usedBefore;
+ qDebug(stats) << "Used memory after GC:" << usedAfter;
+ qDebug(stats) << "Freed up bytes :" << (usedBefore - usedAfter);
+ qDebug(stats) << "Freed up chunks :" << (oldChunks - blockAllocator.chunks.size());
size_t lost = blockAllocator.allocatedMem() - memInBins - usedAfter;
if (lost)
- qDebug() << "!!!!!!!!!!!!!!!!!!!!! LOST MEM:" << lost << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
+ qDebug(stats) << "!!!!!!!!!!!!!!!!!!!!! LOST MEM:" << lost << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
if (largeItemsBefore || largeItemsAfter) {
- qDebug() << "Large item memory before GC:" << largeItemsBefore;
- qDebug() << "Large item memory after GC:" << largeItemsAfter;
- qDebug() << "Large item memory freed up:" << (largeItemsBefore - largeItemsAfter);
+ qDebug(stats) << "Large item memory before GC:" << largeItemsBefore;
+ qDebug(stats) << "Large item memory after GC:" << largeItemsAfter;
+ qDebug(stats) << "Large item memory freed up:" << (largeItemsBefore - largeItemsAfter);
}
for (auto it = freedObjectsSorted.cbegin(); it != freedObjectsSorted.cend(); ++it) {
- qDebug().noquote() << QString::fromLatin1("Freed JS type: %1 (%2 instances)").arg(QString::fromLatin1(it->first), QString::number(it->second));
+ qDebug(stats).noquote() << QString::fromLatin1("Freed JS type: %1 (%2 instances)").arg(QString::fromLatin1(it->first), QString::number(it->second));
}
- qDebug() << "======== End GC ========";
+ qDebug(stats) << "======== End GC ========";
}
+ if (gcStats)
+ statistics.maxUsedMem = qMax(statistics.maxUsedMem, getUsedMem() + getLargeItemsMem());
+
if (aggressiveGC) {
// ensure we don't 'loose' any memory
Q_ASSERT(blockAllocator.allocatedMem() == getUsedMem() + dumpBins(&blockAllocator, false));
@@ -1154,6 +1188,8 @@ MemoryManager::~MemoryManager()
{
delete m_persistentValues;
+ dumpStats();
+
sweep(/*lastSweep*/true);
blockAllocator.freeAll();
hugeItemAllocator.freeAll();
@@ -1168,30 +1204,20 @@ MemoryManager::~MemoryManager()
void MemoryManager::dumpStats() const
{
-#ifdef DETAILED_MM_STATS
- std::cerr << "=================" << std::endl;
- std::cerr << "Allocation stats:" << std::endl;
- std::cerr << "Requests for each chunk size:" << std::endl;
- for (int i = 0; i < allocSizeCounters.size(); ++i) {
- if (unsigned count = allocSizeCounters[i]) {
- std::cerr << "\t" << (i << 4) << " bytes chunks: " << count << std::endl;
- }
- }
-#endif // DETAILED_MM_STATS
-}
+ if (!gcStats)
+ return;
-#ifdef DETAILED_MM_STATS
-void MemoryManager::willAllocate(std::size_t size)
-{
- unsigned alignedSize = (size + 15) >> 4;
- QVector<unsigned> &counters = allocSizeCounters;
- if ((unsigned) counters.size() < alignedSize + 1)
- counters.resize(alignedSize + 1);
- counters[alignedSize]++;
+ const QLoggingCategory &stats = lcGcStats();
+ qDebug(stats) << "Qml GC memory allocation statistics:";
+ qDebug(stats) << "Total memory allocated:" << statistics.maxReservedMem;
+ qDebug(stats) << "Max memory used before a GC run:" << statistics.maxAllocatedMem;
+ qDebug(stats) << "Max memory used after a GC run:" << statistics.maxUsedMem;
+ qDebug(stats) << "Requests for different item sizes:";
+ for (int i = 1; i < BlockAllocator::NumBins - 1; ++i)
+ qDebug(stats) << " <" << (i << Chunk::SlotSizeShift) << " bytes: " << statistics.allocations[i];
+ qDebug(stats) << " >=" << ((BlockAllocator::NumBins - 1) << Chunk::SlotSizeShift) << " bytes: " << statistics.allocations[BlockAllocator::NumBins - 1];
}
-#endif // DETAILED_MM_STATS
-
void MemoryManager::collectFromJSStack(MarkStack *markStack) const
{
Value *v = engine->jsStackBase;
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index 921fea3956..40670bcdc7 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -58,8 +58,6 @@
#include <private/qv4mmdefs_p.h>
#include <QVector>
-//#define DETAILED_MM_STATS
-
#define QV4_MM_MAXBLOCK_SHIFT "QV4_MM_MAXBLOCK_SHIFT"
#define QV4_MM_MAX_CHUNK_SIZE "QV4_MM_MAX_CHUNK_SIZE"
#define QV4_MM_STATS "QV4_MM_STATS"
@@ -71,15 +69,13 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct ChunkAllocator;
+struct MemorySegment;
struct BlockAllocator {
- BlockAllocator(ChunkAllocator *chunkAllocator)
- : chunkAllocator(chunkAllocator)
+ BlockAllocator(ChunkAllocator *chunkAllocator, ExecutionEngine *engine)
+ : chunkAllocator(chunkAllocator), engine(engine)
{
memset(freeBins, 0, sizeof(freeBins));
-#if MM_DEBUG
- memset(allocations, 0, sizeof(allocations));
-#endif
}
enum { NumBins = 8 };
@@ -88,10 +84,6 @@ struct BlockAllocator {
return nSlots >= NumBins ? NumBins - 1 : nSlots;
}
-#if MM_DEBUG
- void stats();
-#endif
-
HeapItem *allocate(size_t size, bool forceAllocation = false);
size_t totalSlots() const {
@@ -108,26 +100,25 @@ struct BlockAllocator {
return used;
}
- void sweep(ClassDestroyStatsCallback classCountPtr);
+ void sweep();
void freeAll();
void resetBlackBits();
void collectGrayItems(MarkStack *markStack);
// bump allocations
- HeapItem *nextFree = 0;
+ HeapItem *nextFree = nullptr;
size_t nFree = 0;
size_t usedSlotsAfterLastSweep = 0;
HeapItem *freeBins[NumBins];
ChunkAllocator *chunkAllocator;
+ ExecutionEngine *engine;
std::vector<Chunk *> chunks;
-#if MM_DEBUG
- uint allocations[NumBins];
-#endif
+ uint *allocationStats = nullptr;
};
struct HugeItemAllocator {
- HugeItemAllocator(ChunkAllocator *chunkAllocator)
- : chunkAllocator(chunkAllocator)
+ HugeItemAllocator(ChunkAllocator *chunkAllocator, ExecutionEngine *engine)
+ : chunkAllocator(chunkAllocator), engine(engine)
{}
HeapItem *allocate(size_t size);
@@ -144,7 +135,9 @@ struct HugeItemAllocator {
}
ChunkAllocator *chunkAllocator;
+ ExecutionEngine *engine;
struct HugeChunk {
+ MemorySegment *segment;
Chunk *chunk;
size_t size;
};
@@ -169,7 +162,7 @@ public:
template<typename ManagedType>
inline typename ManagedType::Data *allocManaged(std::size_t size)
{
- V4_ASSERT_IS_TRIVIAL(typename ManagedType::Data)
+ Q_STATIC_ASSERT(std::is_trivial< typename ManagedType::Data >::value);
size = align(size);
Heap::Base *o = allocData(size);
InternalClass *ic = ManagedType::defaultInternalClass(engine);
@@ -182,7 +175,7 @@ public:
template<typename ManagedType>
inline typename ManagedType::Data *allocManaged(std::size_t size, InternalClass *ic)
{
- V4_ASSERT_IS_TRIVIAL(typename ManagedType::Data)
+ Q_STATIC_ASSERT(std::is_trivial< typename ManagedType::Data >::value);
size = align(size);
Heap::Base *o = allocData(size);
o->internalClass = ic;
@@ -238,7 +231,7 @@ public:
{
Scope scope(engine);
Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : 0));
+ Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
Q_UNUSED(prototype);
t->d_unchecked()->init();
return t->d();
@@ -249,7 +242,7 @@ public:
{
Scope scope(engine);
Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : 0));
+ Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
Q_UNUSED(prototype);
t->d_unchecked()->init(arg1);
return t->d();
@@ -260,7 +253,7 @@ public:
{
Scope scope(engine);
Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : 0));
+ Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
Q_UNUSED(prototype);
t->d_unchecked()->init(arg1, arg2);
return t->d();
@@ -271,7 +264,7 @@ public:
{
Scope scope(engine);
Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : 0));
+ Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
Q_UNUSED(prototype);
t->d_unchecked()->init(arg1, arg2, arg3);
return t->d();
@@ -282,7 +275,7 @@ public:
{
Scope scope(engine);
Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : 0));
+ Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
Q_UNUSED(prototype);
t->d_unchecked()->init(arg1, arg2, arg3, arg4);
return t->d();
@@ -405,10 +398,6 @@ protected:
Heap::Base *allocData(std::size_t size);
Heap::Object *allocObjectWithMemberData(const QV4::VTable *vtable, uint nMembers);
-#ifdef DETAILED_MM_STATS
- void willAllocate(std::size_t size);
-#endif // DETAILED_MM_STATS
-
private:
void collectFromJSStack(MarkStack *markStack) const;
void mark();
@@ -432,6 +421,14 @@ public:
bool gcBlocked = false;
bool aggressiveGC = false;
bool gcStats = false;
+ bool gcCollectorStats = false;
+
+ struct {
+ size_t maxReservedMem = 0;
+ size_t maxAllocatedMem = 0;
+ size_t maxUsedMem = 0;
+ uint allocations[BlockAllocator::NumBins];
+ } statistics;
};
}
diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h
index 6d911e69f6..3e2bae46c2 100644
--- a/src/qml/memory/qv4mmdefs_p.h
+++ b/src/qml/memory/qv4mmdefs_p.h
@@ -187,9 +187,10 @@ struct Chunk {
}
bool sweep(ClassDestroyStatsCallback classCountPtr);
- void freeAll();
void resetBlackBits();
void collectGrayItems(QV4::MarkStack *markStack);
+ bool sweep(ExecutionEngine *engine);
+ void freeAll(ExecutionEngine *engine);
void sortIntoBins(HeapItem **bins, uint nBins);
};
@@ -271,9 +272,9 @@ Q_STATIC_ASSERT((1 << Chunk::BitShift) == Chunk::Bits);
struct MarkStack {
MarkStack(ExecutionEngine *engine);
- Heap::Base **top = 0;
- Heap::Base **base = 0;
- Heap::Base **limit = 0;
+ Heap::Base **top = nullptr;
+ Heap::Base **base = nullptr;
+ Heap::Base **limit = nullptr;
ExecutionEngine *engine;
void push(Heap::Base *m) {
*top = m;
diff --git a/src/qml/memory/qv4writebarrier_p.h b/src/qml/memory/qv4writebarrier_p.h
index c0f4b0b29a..8b04aa6cb1 100644
--- a/src/qml/memory/qv4writebarrier_p.h
+++ b/src/qml/memory/qv4writebarrier_p.h
@@ -51,7 +51,7 @@
//
#include <private/qv4global_p.h>
-#include <private/qv4value_p.h>
+#include <private/qv4enginebase_p.h>
QT_BEGIN_NAMESPACE
@@ -84,14 +84,7 @@ static Q_CONSTEXPR inline bool isRequired() {
return false;
}
-inline void write(EngineBase *engine, Heap::Base *base, Value *slot, Value value)
-{
- Q_UNUSED(engine);
- Q_UNUSED(base);
- *slot = value;
-}
-
-inline void write(EngineBase *engine, Heap::Base *base, Value *slot, Heap::Base *value)
+inline void write(EngineBase *engine, Heap::Base *base, ReturnedValue *slot, ReturnedValue value)
{
Q_UNUSED(engine);
Q_UNUSED(base);
@@ -109,126 +102,6 @@ inline void write(EngineBase *engine, Heap::Base *base, Heap::Base **slot, Heap:
}
-namespace Heap {
-
-template <typename T, size_t o>
-struct Pointer {
- static Q_CONSTEXPR size_t offset = o;
- T operator->() const { return get(); }
- operator T () const { return get(); }
-
- Heap::Base *base() {
- Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
- Q_ASSERT(base->inUse());
- return base;
- }
-
- void set(EngineBase *e, T newVal) {
- WriteBarrier::write(e, base(), &ptr, reinterpret_cast<Heap::Base *>(newVal));
- }
-
- T get() const { return reinterpret_cast<T>(ptr); }
-
- template <typename Type>
- Type *cast() { return static_cast<Type *>(ptr); }
-
- Heap::Base *heapObject() const { return ptr; }
-
-private:
- Heap::Base *ptr;
-};
-typedef Pointer<char *, 0> V4PointerCheck;
-V4_ASSERT_IS_TRIVIAL(V4PointerCheck)
-
-}
-
-template <size_t o>
-struct HeapValue : Value {
- static Q_CONSTEXPR size_t offset = o;
- Heap::Base *base() {
- Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
- Q_ASSERT(base->inUse());
- return base;
- }
-
- void set(EngineBase *e, const Value &newVal) {
- WriteBarrier::write(e, base(), this, newVal);
- }
- void set(EngineBase *e, Heap::Base *b) {
- WriteBarrier::write(e, base(), this, b);
- }
-};
-
-template <size_t o>
-struct ValueArray {
- static Q_CONSTEXPR size_t offset = o;
- uint size;
- uint alloc;
- Value values[1];
-
- Heap::Base *base() {
- Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
- Q_ASSERT(base->inUse());
- return base;
- }
-
- void set(EngineBase *e, uint index, Value v) {
- WriteBarrier::write(e, base(), values + index, v);
- }
- void set(EngineBase *e, uint index, Heap::Base *b) {
- WriteBarrier::write(e, base(), values + index, b);
- }
- inline const Value &operator[] (uint index) const {
- Q_ASSERT(index < alloc);
- return values[index];
- }
- inline const Value *data() const {
- return values;
- }
-
- void insertData(EngineBase *e, uint index, Value v) {
- for (uint i = size - 1; i > index; --i) {
- values[i] = values[i - 1];
- }
- set(e, index, v);
- }
- void removeData(EngineBase *e, uint index, int n = 1) {
- Q_UNUSED(e);
- for (uint i = index; i < size - n; ++i) {
- values[i] = values[i + n];
- }
- }
-
- void mark(MarkStack *markStack) {
- Value *v = values;
- const Value *end = v + alloc;
- if (alloc > 32*1024) {
- // drain from time to time to avoid overflows in the js stack
- Heap::Base **currentBase = markStack->top;
- while (v < end) {
- v->mark(markStack);
- ++v;
- if (markStack->top >= currentBase + 32*1024) {
- Heap::Base **oldBase = markStack->base;
- markStack->base = currentBase;
- markStack->drain();
- markStack->base = oldBase;
- }
- }
- } else {
- while (v < end) {
- v->mark(markStack);
- ++v;
- }
- }
- }
-};
-
-// It's really important that the offset of values in this structure is
-// constant across all architecture, otherwise JIT cross-compiled code will
-// have wrong offsets between host and target.
-Q_STATIC_ASSERT(offsetof(ValueArray<0>, values) == 8);
-
}
QT_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 2433522f42..34657a7d48 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -61,22 +61,22 @@ void Node::accept(Node *node, Visitor *visitor)
ExpressionNode *Node::expressionCast()
{
- return 0;
+ return nullptr;
}
BinaryExpression *Node::binaryExpressionCast()
{
- return 0;
+ return nullptr;
}
Statement *Node::statementCast()
{
- return 0;
+ return nullptr;
}
UiObjectMember *Node::uiObjectMemberCast()
{
- return 0;
+ return nullptr;
}
ExpressionNode *ExpressionNode::expressionCast()
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 7291cf0d3d..ed3c83badf 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -224,8 +224,7 @@ public:
Kind_UiEnumMemberList
};
- inline Node()
- : kind(Kind_Undefined) {}
+ inline Node() {}
// NOTE: node destructors are never called,
// instead we block free the memory
@@ -248,7 +247,7 @@ public:
virtual SourceLocation lastSourceLocation() const = 0;
// attributes
- int kind;
+ int kind = Kind_Undefined;
};
class QML_PARSER_EXPORT ExpressionNode: public Node
@@ -457,11 +456,11 @@ public:
QQMLJS_DECLARE_AST_NODE(ArrayLiteral)
ArrayLiteral(Elision *e):
- elements (0), elision (e)
+ elements (nullptr), elision (e)
{ kind = K; }
ArrayLiteral(ElementList *elts):
- elements (elts), elision (0)
+ elements (elts), elision (nullptr)
{ kind = K; }
ArrayLiteral(ElementList *elts, Elision *e):
@@ -489,8 +488,8 @@ class QML_PARSER_EXPORT ObjectLiteral: public ExpressionNode
public:
QQMLJS_DECLARE_AST_NODE(ObjectLiteral)
- ObjectLiteral():
- properties (0) { kind = K; }
+ ObjectLiteral()
+ { kind = K; }
ObjectLiteral(PropertyAssignmentList *plist):
properties (plist) { kind = K; }
@@ -504,7 +503,7 @@ public:
{ return rbraceToken; }
// attributes
- PropertyAssignmentList *properties;
+ PropertyAssignmentList *properties = nullptr;
SourceLocation lbraceToken;
SourceLocation rbraceToken;
};
@@ -535,7 +534,7 @@ public:
inline Elision *finish ()
{
Elision *front = next;
- next = 0;
+ next = nullptr;
return front;
}
@@ -564,7 +563,7 @@ public:
inline ElementList *finish ()
{
ElementList *front = next;
- next = 0;
+ next = nullptr;
return front;
}
@@ -641,7 +640,7 @@ public:
inline PropertyAssignmentList *finish ()
{
PropertyAssignmentList *front = next;
- next = 0;
+ next = nullptr;
return front;
}
@@ -693,7 +692,7 @@ public:
};
PropertyGetterSetter(PropertyName *n, FunctionBody *b)
- : PropertyAssignment(n), type(Getter), formals(0), functionBody (b)
+ : PropertyAssignment(n), type(Getter), formals(nullptr), functionBody (b)
{ kind = K; }
PropertyGetterSetter(PropertyName *n, FormalParameterList *f, FunctionBody *b)
@@ -917,7 +916,7 @@ public:
inline ArgumentList *finish ()
{
ArgumentList *front = next;
- next = 0;
+ next = nullptr;
return front;
}
@@ -1281,7 +1280,7 @@ public:
inline StatementList *finish ()
{
StatementList *front = next;
- next = 0;
+ next = nullptr;
return front;
}
@@ -1377,9 +1376,9 @@ public:
inline VariableDeclarationList *finish(VariableDeclaration::VariableScope s)
{
VariableDeclarationList *front = next;
- next = 0;
+ next = nullptr;
VariableDeclarationList *vdl;
- for (vdl = front; vdl != 0; vdl = vdl->next) {
+ for (vdl = front; vdl != nullptr; vdl = vdl->next) {
vdl->declaration->scope = s;
}
return front;
@@ -1436,7 +1435,7 @@ class QML_PARSER_EXPORT IfStatement: public Statement
public:
QQMLJS_DECLARE_AST_NODE(IfStatement)
- IfStatement(ExpressionNode *e, Statement *t, Statement *f = 0):
+ IfStatement(ExpressionNode *e, Statement *t, Statement *f = nullptr):
expression (e), ok (t), ko (f)
{ kind = K; }
@@ -1727,7 +1726,7 @@ class QML_PARSER_EXPORT CaseBlock: public Node
public:
QQMLJS_DECLARE_AST_NODE(CaseBlock)
- CaseBlock(CaseClauses *c, DefaultClause *d = 0, CaseClauses *r = 0):
+ CaseBlock(CaseClauses *c, DefaultClause *d = nullptr, CaseClauses *r = nullptr):
clauses (c), defaultClause (d), moreClauses (r)
{ kind = K; }
@@ -1824,7 +1823,7 @@ public:
inline CaseClauses *finish ()
{
CaseClauses *front = next;
- next = 0;
+ next = nullptr;
return front;
}
@@ -1960,11 +1959,11 @@ public:
{ kind = K; }
TryStatement(Statement *stmt, Finally *f):
- statement (stmt), catchExpression (0), finallyExpression (f)
+ statement (stmt), catchExpression (nullptr), finallyExpression (f)
{ kind = K; }
TryStatement(Statement *stmt, Catch *c):
- statement (stmt), catchExpression (c), finallyExpression (0)
+ statement (stmt), catchExpression (c), finallyExpression (nullptr)
{ kind = K; }
void accept0(Visitor *visitor) override;
@@ -2058,7 +2057,7 @@ public:
inline FormalParameterList *finish ()
{
FormalParameterList *front = next;
- next = 0;
+ next = nullptr;
return front;
}
@@ -2106,7 +2105,7 @@ public:
inline SourceElements *finish ()
{
SourceElements *front = next;
- next = 0;
+ next = nullptr;
return front;
}
@@ -2240,7 +2239,7 @@ public:
UiQualifiedId *finish()
{
UiQualifiedId *head = next;
- next = 0;
+ next = nullptr;
return head;
}
@@ -2264,7 +2263,7 @@ public:
QQMLJS_DECLARE_AST_NODE(UiImport)
UiImport(const QStringRef &fileName)
- : fileName(fileName), importUri(0)
+ : fileName(fileName), importUri(nullptr)
{ kind = K; }
UiImport(UiQualifiedId *uri)
@@ -2328,7 +2327,7 @@ public:
UiObjectMemberList *finish()
{
UiObjectMemberList *head = next;
- next = 0;
+ next = nullptr;
return head;
}
@@ -2357,7 +2356,7 @@ public:
UiQualifiedPragmaId *finish()
{
UiQualifiedPragmaId *head = next;
- next = 0;
+ next = nullptr;
return head;
}
@@ -2430,7 +2429,7 @@ public:
UiHeaderItemList *finish()
{
UiHeaderItemList *head = next;
- next = 0;
+ next = nullptr;
return head;
}
@@ -2509,7 +2508,7 @@ public:
UiArrayMemberList *finish()
{
UiArrayMemberList *head = next;
- next = 0;
+ next = nullptr;
return head;
}
@@ -2570,7 +2569,7 @@ public:
inline UiParameterList *finish ()
{
UiParameterList *front = next;
- next = 0;
+ next = nullptr;
return front;
}
@@ -2590,13 +2589,13 @@ public:
UiPublicMember(UiQualifiedId *memberType,
const QStringRef &name)
- : type(Property), memberType(memberType), name(name), statement(0), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
+ : type(Property), memberType(memberType), name(name), statement(nullptr), binding(nullptr), isDefaultMember(false), isReadonlyMember(false), parameters(nullptr)
{ kind = K; }
UiPublicMember(UiQualifiedId *memberType,
const QStringRef &name,
Statement *statement)
- : type(Property), memberType(memberType), name(name), statement(statement), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
+ : type(Property), memberType(memberType), name(name), statement(statement), binding(nullptr), isDefaultMember(false), isReadonlyMember(false), parameters(nullptr)
{ kind = K; }
void accept0(Visitor *visitor) override;
@@ -2825,7 +2824,7 @@ public:
UiEnumMemberList *finish()
{
UiEnumMemberList *head = next;
- next = 0;
+ next = nullptr;
return head;
}
diff --git a/src/qml/parser/qqmljsengine_p.cpp b/src/qml/parser/qqmljsengine_p.cpp
index 7a6d9c3826..b4f0debf85 100644
--- a/src/qml/parser/qqmljsengine_p.cpp
+++ b/src/qml/parser/qqmljsengine_p.cpp
@@ -120,7 +120,7 @@ double integerFromString(const QString &str, int radix)
Engine::Engine()
- : _lexer(0), _directives(0)
+ : _lexer(nullptr), _directives(nullptr)
{ }
Engine::~Engine()
diff --git a/src/qml/parser/qqmljsengine_p.h b/src/qml/parser/qqmljsengine_p.h
index 8cbe69a0ba..af26bac0ff 100644
--- a/src/qml/parser/qqmljsengine_p.h
+++ b/src/qml/parser/qqmljsengine_p.h
@@ -71,8 +71,7 @@ class QML_PARSER_EXPORT DiagnosticMessage
public:
enum Kind { Warning, Error };
- DiagnosticMessage()
- : kind(Error) {}
+ DiagnosticMessage() {}
DiagnosticMessage(Kind kind, const AST::SourceLocation &loc, const QString &message)
: kind(kind), loc(loc), message(message) {}
@@ -83,7 +82,7 @@ public:
bool isError() const
{ return kind == Error; }
- Kind kind;
+ Kind kind = Error;
AST::SourceLocation loc;
QString message;
};
diff --git a/src/qml/parser/qqmljsgrammar.cpp b/src/qml/parser/qqmljsgrammar.cpp
index f345990ff9..2aaeb385e3 100644
--- a/src/qml/parser/qqmljsgrammar.cpp
+++ b/src/qml/parser/qqmljsgrammar.cpp
@@ -49,11 +49,11 @@ const char *const QQmlJSGrammar::spell [] = {
"if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=",
"-", "-=", "--", "new", "!", "!=", "!==", "numeric literal", "|", "|=",
"||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return",
- ")", ";", 0, "*", "*=", "string literal", "property", "signal", "readonly", "switch",
+ ")", ";", nullptr, "*", "*=", "string literal", "property", "signal", "readonly", "switch",
"this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^",
"^=", "null", "true", "false", "const", "let", "debugger", "reserved word", "multiline string literal", "comment",
- 0, "enum", "public", "import", "pragma", "as", "on", "get", "set", 0,
- 0, 0, 0, 0, 0, 0, 0, 0
+ nullptr, "enum", "public", "import", "pragma", "as", "on", "get", "set", nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
};
const short QQmlJSGrammar::lhs [] = {
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index 78ed5e3b2c..aab9025a08 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -85,11 +85,11 @@ static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
Lexer::Lexer(Engine *engine)
: _engine(engine)
- , _codePtr(0)
- , _endPtr(0)
- , _lastLinePtr(0)
- , _tokenLinePtr(0)
- , _tokenStartPtr(0)
+ , _codePtr(nullptr)
+ , _endPtr(nullptr)
+ , _lastLinePtr(nullptr)
+ , _tokenLinePtr(nullptr)
+ , _tokenStartPtr(nullptr)
, _char(QLatin1Char('\n'))
, _errorCode(NoError)
, _currentLineNumber(0)
@@ -589,7 +589,7 @@ again:
chars.append('\0');
const char *begin = chars.constData();
- const char *end = 0;
+ const char *end = nullptr;
bool ok = false;
_tokenValue = qstrtod(begin, &end, &ok);
@@ -773,7 +773,7 @@ again:
u = QLatin1Char('\0');
break;
}
- // fall through
+ Q_FALLTHROUGH();
case '1':
case '2':
case '3':
@@ -915,7 +915,7 @@ int Lexer::scanNumber(QChar ch)
scanChar();
}
buf.append('\0');
- _tokenValue = strtod(buf.constData(), 0);
+ _tokenValue = strtod(buf.constData(), nullptr);
return T_NUMERIC_LITERAL;
}
} else if (_char.isDigit() && !qmlMode()) {
@@ -1010,7 +1010,7 @@ int Lexer::scanNumber(QChar ch)
chars.append('\0');
const char *begin = chars.constData();
- const char *end = 0;
+ const char *end = nullptr;
bool ok = false;
_tokenValue = qstrtod(begin, &end, &ok);
diff --git a/src/qml/parser/qqmljsmemorypool_p.h b/src/qml/parser/qqmljsmemorypool_p.h
index 536f5d4239..ef443d96bc 100644
--- a/src/qml/parser/qqmljsmemorypool_p.h
+++ b/src/qml/parser/qqmljsmemorypool_p.h
@@ -71,13 +71,7 @@ class QML_PARSER_EXPORT MemoryPool : public QSharedData
void operator =(const MemoryPool &other);
public:
- MemoryPool()
- : _blocks(0),
- _allocatedBlocks(0),
- _blockCount(-1),
- _ptr(0),
- _end(0)
- { }
+ MemoryPool() {}
~MemoryPool()
{
@@ -105,7 +99,7 @@ public:
void reset()
{
_blockCount = -1;
- _ptr = _end = 0;
+ _ptr = _end = nullptr;
}
template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); }
@@ -125,7 +119,7 @@ private:
Q_CHECK_PTR(_blocks);
for (int index = _blockCount; index < _allocatedBlocks; ++index)
- _blocks[index] = 0;
+ _blocks[index] = nullptr;
}
char *&block = _blocks[_blockCount];
@@ -144,11 +138,11 @@ private:
}
private:
- char **_blocks;
- int _allocatedBlocks;
- int _blockCount;
- char *_ptr;
- char *_end;
+ char **_blocks = nullptr;
+ int _allocatedBlocks = 0;
+ int _blockCount = -1;
+ char *_ptr = nullptr;
+ char *_end = nullptr;
enum
{
diff --git a/src/qml/parser/qqmljsparser.cpp b/src/qml/parser/qqmljsparser.cpp
index df16a24bcc..24b04b02f9 100644
--- a/src/qml/parser/qqmljsparser.cpp
+++ b/src/qml/parser/qqmljsparser.cpp
@@ -79,7 +79,7 @@ void Parser::reallocateStack()
sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value)));
state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int)));
location_stack = reinterpret_cast<AST::SourceLocation*> (realloc(location_stack, stack_size * sizeof(AST::SourceLocation)));
- string_stack = reinterpret_cast<QStringRef*> (realloc(string_stack, stack_size * sizeof(QStringRef)));
+ string_stack = reinterpret_cast<QStringRef*> (realloc(static_cast<void *>(string_stack), stack_size * sizeof(QStringRef)));
}
Parser::Parser(Engine *engine):
@@ -87,14 +87,14 @@ Parser::Parser(Engine *engine):
pool(engine->pool()),
tos(0),
stack_size(0),
- sym_stack(0),
- state_stack(0),
- location_stack(0),
- string_stack(0),
- program(0),
+ sym_stack(nullptr),
+ state_stack(nullptr),
+ location_stack(nullptr),
+ string_stack(nullptr),
+ program(nullptr),
yylval(0),
- first_token(0),
- last_token(0)
+ first_token(nullptr),
+ last_token(nullptr)
{
}
@@ -143,7 +143,7 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
return currentId->finish();
}
- return 0;
+ return nullptr;
}
AST::UiQualifiedPragmaId *Parser::reparseAsQualifiedPragmaId(AST::ExpressionNode *expr)
@@ -155,7 +155,7 @@ AST::UiQualifiedPragmaId *Parser::reparseAsQualifiedPragmaId(AST::ExpressionNode
return q->finish();
}
- return 0;
+ return nullptr;
}
@@ -188,7 +188,7 @@ bool Parser::parse(int startToken)
}
tos = -1;
- program = 0;
+ program = nullptr;
do {
if (++tos == stack_size)
@@ -315,7 +315,7 @@ case 24: {
} break;
case 25: {
- AST::UiPragma *node = 0;
+ AST::UiPragma *node = nullptr;
if (AST::UiQualifiedPragmaId *qualifiedId = reparseAsQualifiedPragmaId(sym(2).Expression)) {
node = new (pool) AST::UiPragma(qualifiedId);
@@ -334,7 +334,7 @@ case 25: {
} break;
case 26: {
- AST::UiImport *node = 0;
+ AST::UiImport *node = nullptr;
if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) {
node = new (pool) AST::UiImport(importIdLiteral->value);
@@ -357,7 +357,7 @@ case 26: {
} break;
case 27: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 28: {
@@ -386,7 +386,7 @@ case 32: {
} break;
case 33: {
- AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0);
+ AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)nullptr);
node->lbraceToken = loc(1);
node->rbraceToken = loc(2);
sym(1).Node = node;
@@ -462,7 +462,7 @@ case 51: {
} break;
case 52: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 53: {
@@ -594,7 +594,7 @@ case 71: {
AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6));
propertyName->identifierToken = loc(6);
- propertyName->next = 0;
+ propertyName->next = nullptr;
AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(
propertyName, sym(9).UiArrayMemberList->finish());
@@ -616,7 +616,7 @@ case 72: {
AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3));
propertyName->identifierToken = loc(3);
- propertyName->next = 0;
+ propertyName->next = nullptr;
AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer);
@@ -638,7 +638,7 @@ case 73: {
AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4));
propertyName->identifierToken = loc(4);
- propertyName->next = 0;
+ propertyName->next = nullptr;
AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer);
@@ -770,7 +770,7 @@ case 97: {
} break;
case 98: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) nullptr);
node->lbracketToken = loc(1);
node->rbracketToken = loc(2);
sym(1).Node = node;
@@ -792,7 +792,7 @@ case 100: {
case 101: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
- (AST::Elision *) 0);
+ (AST::Elision *) nullptr);
node->lbracketToken = loc(1);
node->commaToken = loc(3);
node->rbracketToken = loc(4);
@@ -809,7 +809,7 @@ case 102: {
} break;
case 103: {
- AST::ObjectLiteral *node = 0;
+ AST::ObjectLiteral *node = nullptr;
if (sym(2).Node)
node = new (pool) AST::ObjectLiteral(
sym(2).PropertyAssignmentList->finish ());
@@ -846,7 +846,7 @@ case 106: {
if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) {
sym(1).UiQualifiedId = qualifiedId;
} else {
- sym(1).UiQualifiedId = 0;
+ sym(1).UiQualifiedId = nullptr;
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1),
QLatin1String("Expected a qualified name id")));
@@ -856,7 +856,7 @@ case 106: {
} break;
case 107: {
- sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
+ sym(1).Node = new (pool) AST::ElementList((AST::Elision *) nullptr, sym(1).Expression);
} break;
case 108: {
@@ -865,7 +865,7 @@ case 108: {
case 109: {
AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
- (AST::Elision *) 0, sym(3).Expression);
+ (AST::Elision *) nullptr, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
@@ -1010,7 +1010,7 @@ case 167: {
} break;
case 168: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 169: {
@@ -1437,7 +1437,7 @@ case 262: {
} break;
case 263: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 266: {
@@ -1447,7 +1447,7 @@ case 266: {
} break;
case 267: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 284: {
@@ -1466,7 +1466,7 @@ case 286: {
} break;
case 287: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 288: {
@@ -1537,7 +1537,7 @@ case 300: {
} break;
case 301: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 303: {
@@ -1546,7 +1546,7 @@ case 303: {
} break;
case 304: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 306: {
@@ -1718,7 +1718,7 @@ case 334: {
} break;
case 335: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 336: {
@@ -1840,7 +1840,7 @@ case 354: {
} break;
case 355: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 356: {
@@ -1848,7 +1848,7 @@ case 356: {
} break;
case 357: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
case 359: {
@@ -1876,7 +1876,7 @@ case 365: {
} break;
case 366: {
- sym(1).Node = 0;
+ sym(1).Node = nullptr;
} break;
} // switch
diff --git a/src/qml/parser/qqmljsparser_p.h b/src/qml/parser/qqmljsparser_p.h
index 9dfee70f3a..b4aecd2f08 100644
--- a/src/qml/parser/qqmljsparser_p.h
+++ b/src/qml/parser/qqmljsparser_p.h
@@ -146,7 +146,7 @@ public:
AST::Statement *statement() const
{
if (! program)
- return 0;
+ return nullptr;
return program->statementCast();
}
@@ -154,7 +154,7 @@ public:
AST::ExpressionNode *expression() const
{
if (! program)
- return 0;
+ return nullptr;
return program->expressionCast();
}
@@ -162,7 +162,7 @@ public:
AST::UiObjectMember *uiObjectMember() const
{
if (! program)
- return 0;
+ return nullptr;
return program->uiObjectMemberCast();
}
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index c13227d8fe..f75bfa0313 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -6,7 +6,7 @@ qtConfig(qml-network): \
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x66000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x66000000
win32-msvc*:DEFINES *= _CRT_SECURE_NO_WARNINGS
win32:!winrt:LIBS += -lshell32
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
@@ -16,17 +16,28 @@ gcc:isEqual(QT_ARCH, "mips"): QMAKE_CXXFLAGS += -fno-reorder-blocks
DEFINES += QT_NO_FOREACH
-tagFile=$$PWD/../../.tag
-tag=
-exists($$tagFile) {
- tag=$$cat($$tagFile, singleline)
- QMAKE_INTERNAL_INCLUDED_FILES += $$tagFile
-}
-!equals(tag, "$${LITERAL_DOLLAR}Format:%H$${LITERAL_DOLLAR}") {
- DEFINES += QML_COMPILE_HASH="$$tag"
-} else:exists($$PWD/../../.git) {
- commit=$$system(git describe --tags --always --long --dirty)
- DEFINES += QML_COMPILE_HASH="$$commit"
+!build_pass {
+ # Create a header containing a hash that describes this library. For a
+ # released version of Qt, we'll use the .tag file that is updated by git
+ # archive with the commit hash. For unreleased versions, we'll ask git
+ # describe. Note that it won't update unless qmake is run again, even if
+ # the commit change also changed something in this library.
+ tagFile = $$PWD/../../.tag
+ tag =
+ exists($$tagFile) {
+ tag = $$cat($$tagFile, singleline)
+ QMAKE_INTERNAL_INCLUDED_FILES += $$tagFile
+ }
+ !equals(tag, "$${LITERAL_DOLLAR}Format:%H$${LITERAL_DOLLAR}") {
+ QML_COMPILE_HASH = $$tag
+ } else:exists($$PWD/../../.git) {
+ commit = $$system(git describe --tags --always --long --dirty)
+ QML_COMPILE_HASH = $$commit
+ }
+ compile_hash_contents = \
+ "// Generated file, DO NOT EDIT" \
+ "$${LITERAL_HASH}define QML_COMPILE_HASH \"$$QML_COMPILE_HASH\""
+ write_file("$$OUT_PWD/qml_compile_hash_p.h", compile_hash_contents)|error()
}
exists("qqml_enable_gcov") {
diff --git a/src/qml/qml/ftw/qbitfield_p.h b/src/qml/qml/ftw/qbitfield_p.h
index 8f35842249..92017580d6 100644
--- a/src/qml/qml/ftw/qbitfield_p.h
+++ b/src/qml/qml/ftw/qbitfield_p.h
@@ -77,12 +77,12 @@ private:
};
QBitField::QBitField()
-: bits(0), ownData(0), data(0)
+: bits(0), ownData(nullptr), data(nullptr)
{
}
QBitField::QBitField(const quint32 *bitData, int bitCount)
-: bits((quint32)bitCount), ownData(0), data(bitData)
+: bits((quint32)bitCount), ownData(nullptr), data(bitData)
{
}
diff --git a/src/qml/qml/ftw/qfieldlist_p.h b/src/qml/qml/ftw/qfieldlist_p.h
index d83d708b5e..2bf07fb20d 100644
--- a/src/qml/qml/ftw/qfieldlist_p.h
+++ b/src/qml/qml/ftw/qfieldlist_p.h
@@ -141,7 +141,7 @@ N *QForwardFieldList<N, nextMember>::takeFirst()
N *value = *_first;
if (value) {
_first = next(value);
- value->*nextMember = 0;
+ value->*nextMember = nullptr;
}
return value;
}
@@ -149,7 +149,7 @@ N *QForwardFieldList<N, nextMember>::takeFirst()
template<class N, N *N::*nextMember>
void QForwardFieldList<N, nextMember>::prepend(N *v)
{
- Q_ASSERT(v->*nextMember == 0);
+ Q_ASSERT(v->*nextMember == nullptr);
v->*nextMember = *_first;
_first = v;
}
@@ -229,7 +229,7 @@ void QForwardFieldList<N, nextMember>::setFlag2Value(bool v)
template<class N, N *N::*nextMember>
QFieldList<N, nextMember>::QFieldList()
-: _first(0), _last(0), _flag(0), _count(0)
+: _first(nullptr), _last(nullptr), _flag(0), _count(0)
{
}
@@ -246,10 +246,10 @@ N *QFieldList<N, nextMember>::takeFirst()
if (value) {
_first = next(value);
if (_last == value) {
- Q_ASSERT(_first == 0);
- _last = 0;
+ Q_ASSERT(_first == nullptr);
+ _last = nullptr;
}
- value->*nextMember = 0;
+ value->*nextMember = nullptr;
--_count;
}
return value;
@@ -258,7 +258,7 @@ N *QFieldList<N, nextMember>::takeFirst()
template<class N, N *N::*nextMember>
void QFieldList<N, nextMember>::append(N *v)
{
- Q_ASSERT(v->*nextMember == 0);
+ Q_ASSERT(v->*nextMember == nullptr);
if (isEmpty()) {
_first = v;
_last = v;
@@ -272,7 +272,7 @@ void QFieldList<N, nextMember>::append(N *v)
template<class N, N *N::*nextMember>
void QFieldList<N, nextMember>::prepend(N *v)
{
- Q_ASSERT(v->*nextMember == 0);
+ Q_ASSERT(v->*nextMember == nullptr);
if (isEmpty()) {
_first = v;
_last = v;
@@ -375,7 +375,7 @@ void QFieldList<N, nextMember>::copyAndClear(QFieldList<N, nextMember> &o)
_first = o._first;
_last = o._last;
_count = o._count;
- o._first = o._last = 0;
+ o._first = o._last = nullptr;
o._count = 0;
}
@@ -391,8 +391,8 @@ void QFieldList<N, nextMember>::copyAndClearAppend(QForwardFieldList<N, nextMemb
template<class N, N *N::*nextMember>
void QFieldList<N, nextMember>::copyAndClearPrepend(QForwardFieldList<N, nextMember> &o)
{
- _first = 0;
- _last = 0;
+ _first = nullptr;
+ _last = nullptr;
_count = 0;
while (N *n = o.takeFirst()) prepend(n);
}
diff --git a/src/qml/qml/ftw/qfinitestack_p.h b/src/qml/qml/ftw/qfinitestack_p.h
index f1f1a551d5..9a74199137 100644
--- a/src/qml/qml/ftw/qfinitestack_p.h
+++ b/src/qml/qml/ftw/qfinitestack_p.h
@@ -81,7 +81,7 @@ private:
template<typename T>
QFiniteStack<T>::QFiniteStack()
-: _array(0), _alloc(0), _size(0)
+: _array(nullptr), _alloc(0), _size(0)
{
}
@@ -156,7 +156,7 @@ T &QFiniteStack<T>::operator[](int index)
template<typename T>
void QFiniteStack<T>::allocate(int size)
{
- Q_ASSERT(_array == 0);
+ Q_ASSERT(_array == nullptr);
Q_ASSERT(_alloc == 0);
Q_ASSERT(_size == 0);
@@ -177,7 +177,7 @@ void QFiniteStack<T>::deallocate()
free(_array);
- _array = 0;
+ _array = nullptr;
_alloc = 0;
_size = 0;
}
diff --git a/src/qml/qml/ftw/qflagpointer_p.h b/src/qml/qml/ftw/qflagpointer_p.h
index 6954a8f09c..91ce74bec9 100644
--- a/src/qml/qml/ftw/qflagpointer_p.h
+++ b/src/qml/qml/ftw/qflagpointer_p.h
@@ -83,7 +83,7 @@ public:
inline T *data() const;
private:
- quintptr ptr_value;
+ quintptr ptr_value = 0;
static const quintptr FlagBit = 0x1;
static const quintptr Flag2Bit = 0x2;
@@ -115,7 +115,7 @@ public:
inline T2 *asT2() const;
private:
- quintptr ptr_value;
+ quintptr ptr_value = 0;
static const quintptr FlagBit = 0x1;
static const quintptr Flag2Bit = 0x2;
@@ -124,7 +124,6 @@ private:
template<typename T>
QFlagPointer<T>::QFlagPointer()
-: ptr_value(0)
{
}
@@ -233,7 +232,6 @@ T *QFlagPointer<T>::data() const
template<typename T, typename T2>
QBiPointer<T, T2>::QBiPointer()
-: ptr_value(0)
{
}
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index 956805d696..2d6c25bdd3 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -94,7 +94,7 @@ private:
friend class QStringHashNode;
inline void computeHash() const;
- mutable quint32 m_hash;
+ mutable quint32 m_hash = 0;
};
class QHashedCStringRef;
@@ -142,9 +142,9 @@ private:
inline void computeHash() const;
- const QChar *m_data;
- int m_length;
- mutable quint32 m_hash;
+ const QChar *m_data = nullptr;
+ int m_length = 0;
+ mutable quint32 m_hash = 0;
};
class Q_AUTOTEST_EXPORT QHashedCStringRef
@@ -169,9 +169,9 @@ private:
inline void computeHash() const;
- const char *m_data;
- int m_length;
- mutable quint32 m_hash;
+ const char *m_data = nullptr;
+ int m_length = 0;
+ mutable quint32 m_hash = 0;
};
class QStringHashData;
@@ -179,7 +179,7 @@ class Q_AUTOTEST_EXPORT QStringHashNode
{
public:
QStringHashNode()
- : length(0), hash(0), symbolId(0), ckey(0)
+ : ckey(nullptr)
{
}
@@ -210,9 +210,9 @@ public:
QFlagPointer<QStringHashNode> next;
- qint32 length;
- quint32 hash;
- quint32 symbolId;
+ qint32 length = 0;
+ quint32 hash = 0;
+ quint32 symbolId = 0;
union {
const char *ckey;
@@ -276,25 +276,20 @@ public:
class Q_AUTOTEST_EXPORT QStringHashData
{
public:
- QStringHashData()
- : buckets(0), numBuckets(0), size(0), numBits(0)
-#ifdef QSTRINGHASH_LINK_DEBUG
- , linkCount(0)
-#endif
- {}
+ QStringHashData() {}
- QStringHashNode **buckets;
- int numBuckets;
- int size;
- short numBits;
+ QStringHashNode **buckets = nullptr;
+ int numBuckets = 0;
+ int size = 0;
+ short numBits = 0;
#ifdef QSTRINGHASH_LINK_DEBUG
- int linkCount;
+ int linkCount = 0;
#endif
struct IteratorData {
- IteratorData() : n(0), p(0) {}
- QStringHashNode *n;
- void *p;
+ IteratorData() {}
+ QStringHashNode *n = nullptr;
+ void *p = nullptr;
};
void rehashToBits(short);
void rehashToSize(int);
@@ -362,17 +357,17 @@ public:
T value;
};
struct NewedNode : public Node {
- NewedNode(const QHashedString &key, const T &value) : Node(key, value), nextNewed(0) {}
- NewedNode(const QHashedCStringRef &key, const T &value) : Node(key, value), nextNewed(0) {}
- NewedNode(const Node &o) : Node(o), nextNewed(0) {}
+ NewedNode(const QHashedString &key, const T &value) : Node(key, value), nextNewed(nullptr) {}
+ NewedNode(const QHashedCStringRef &key, const T &value) : Node(key, value), nextNewed(nullptr) {}
+ NewedNode(const Node &o) : Node(o), nextNewed(nullptr) {}
NewedNode *nextNewed;
};
struct ReservedNodePool
{
- ReservedNodePool() : count(0), used(0), nodes(0) {}
+ ReservedNodePool() : nodes(nullptr) {}
~ReservedNodePool() { delete [] nodes; }
- int count;
- int used;
+ int count = 0;
+ int used = 0;
Node *nodes;
};
@@ -475,13 +470,13 @@ public:
template<class T>
QStringHash<T>::QStringHash()
-: newedNodes(0), nodePool(0), link(0)
+: newedNodes(nullptr), nodePool(nullptr), link(nullptr)
{
}
template<class T>
QStringHash<T>::QStringHash(const QStringHash<T> &other)
-: newedNodes(0), nodePool(0), link(0)
+: newedNodes(nullptr), nodePool(nullptr), link(nullptr)
{
data.numBits = other.data.numBits;
data.size = other.data.size;
@@ -579,14 +574,14 @@ void QStringHash<T>::clear()
if (nodePool) delete nodePool;
delete [] data.buckets;
- data.buckets = 0;
+ data.buckets = nullptr;
data.numBuckets = 0;
data.numBits = 0;
data.size = 0;
- newedNodes = 0;
- nodePool = 0;
- link = 0;
+ newedNodes = nullptr;
+ nodePool = nullptr;
+ link = nullptr;
}
template<class T>
@@ -716,16 +711,16 @@ QStringHash<T>::iterateNext(const QStringHashData::IteratorData &d)
node < (This->nodePool->nodes + This->nodePool->used)) {
node--;
if (node < This->nodePool->nodes)
- node = 0;
+ node = nullptr;
} else {
NewedNode *nn = (NewedNode *)node;
node = nn->nextNewed;
- if (node == 0 && This->nodePool && This->nodePool->used)
+ if (node == nullptr && This->nodePool && This->nodePool->used)
node = This->nodePool->nodes + This->nodePool->used - 1;
}
- if (node == 0 && This->link)
+ if (node == nullptr && This->link)
return This->link->iterateFirst();
QStringHashData::IteratorData rv;
@@ -737,13 +732,13 @@ QStringHash<T>::iterateNext(const QStringHashData::IteratorData &d)
template<class T>
QStringHashData::IteratorData QStringHash<T>::iterateFirst() const
{
- Node *n = 0;
+ Node *n = nullptr;
if (newedNodes)
n = newedNodes;
else if (nodePool && nodePool->used)
n = nodePool->nodes + nodePool->used - 1;
- if (n == 0 && link)
+ if (n == nullptr && link)
return link->iterateFirst();
QStringHashData::IteratorData rv;
@@ -822,7 +817,7 @@ void QStringHash<T>::insert(const K &key, const T &value)
{
// If this is a linked hash, we can't rely on owning the node, so we always
// create a new one.
- Node *n = link?0:findNode(key);
+ Node *n = link?nullptr:findNode(key);
if (n) n->value = value;
else createNode(key, value);
}
@@ -837,7 +832,7 @@ template<class T>
template<class K>
typename QStringHash<T>::Node *QStringHash<T>::findNode(const K &key) const
{
- QStringHashNode *node = data.numBuckets?data.buckets[hashOf(key) % data.numBuckets]:0;
+ QStringHashNode *node = data.numBuckets?data.buckets[hashOf(key) % data.numBuckets]:nullptr;
typename HashedForm<K>::Type hashedKey(hashedString(key));
while (node && !node->equals(hashedKey))
@@ -851,7 +846,7 @@ template<class K>
T *QStringHash<T>::value(const K &key) const
{
Node *n = findNode(key);
- return n?&n->value:0;
+ return n?&n->value:nullptr;
}
template<class T>
@@ -865,14 +860,14 @@ template<class T>
T *QStringHash<T>::value(const QV4::String *string) const
{
Node *n = findNode(string);
- return n?&n->value:0;
+ return n?&n->value:nullptr;
}
template<class T>
template<class K>
bool QStringHash<T>::contains(const K &key) const
{
- return 0 != value(key);
+ return nullptr != value(key);
}
template<class T>
@@ -1038,7 +1033,7 @@ inline uint qHash(const QHashedStringRef &string)
}
QHashedString::QHashedString()
-: QString(), m_hash(0)
+: QString()
{
}
@@ -1089,7 +1084,6 @@ quint32 QHashedString::existingHash() const
}
QHashedStringRef::QHashedStringRef()
-: m_data(0), m_length(0), m_hash(0)
{
}
@@ -1236,7 +1230,6 @@ quint32 QHashedStringRef::hash() const
}
QHashedCStringRef::QHashedCStringRef()
-: m_data(0), m_length(0), m_hash(0)
{
}
diff --git a/src/qml/qml/ftw/qintrusivelist_p.h b/src/qml/qml/ftw/qintrusivelist_p.h
index 3d749e697e..8992be9f93 100644
--- a/src/qml/qml/ftw/qintrusivelist_p.h
+++ b/src/qml/qml/ftw/qintrusivelist_p.h
@@ -95,7 +95,7 @@ public:
private:
static inline N *nodeToN(QIntrusiveListNode *node);
- QIntrusiveListNode *__first;
+ QIntrusiveListNode *__first = nullptr;
};
class QIntrusiveListNode
@@ -107,13 +107,13 @@ public:
inline void remove();
inline bool isInList() const;
- QIntrusiveListNode *_next;
- QIntrusiveListNode**_prev;
+ QIntrusiveListNode *_next = nullptr;
+ QIntrusiveListNode**_prev = nullptr;
};
template<class N, QIntrusiveListNode N::*member>
QIntrusiveList<N, member>::iterator::iterator()
-: _value(0)
+: _value(nullptr)
{
}
@@ -165,7 +165,7 @@ typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterato
template<class N, QIntrusiveListNode N::*member>
QIntrusiveList<N, member>::QIntrusiveList()
-: __first(0)
+
{
}
@@ -178,7 +178,7 @@ QIntrusiveList<N, member>::~QIntrusiveList()
template<class N, QIntrusiveListNode N::*member>
bool QIntrusiveList<N, member>::isEmpty() const
{
- return __first == 0;
+ return __first == nullptr;
}
template<class N, QIntrusiveListNode N::*member>
@@ -215,14 +215,14 @@ 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;
+ return __first?nodeToN(__first):nullptr;
}
template<class N, QIntrusiveListNode N::*member>
N *QIntrusiveList<N, member>::next(N *current)
{
QIntrusiveListNode *nextnode = (current->*member)._next;
- N *nextstruct = nextnode?nodeToN(nextnode):0;
+ N *nextstruct = nextnode?nodeToN(nextnode):nullptr;
return nextstruct;
}
@@ -241,11 +241,10 @@ typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::end()
template<class N, QIntrusiveListNode N::*member>
N *QIntrusiveList<N, member>::nodeToN(QIntrusiveListNode *node)
{
- return (N *)((char *)node - ((char *)&(((N *)0)->*member) - (char *)0));
+ return (N *)((char *)node - ((char *)&(((N *)nullptr)->*member) - (char *)nullptr));
}
QIntrusiveListNode::QIntrusiveListNode()
-: _next(0), _prev(0)
{
}
@@ -258,13 +257,13 @@ void QIntrusiveListNode::remove()
{
if (_prev) *_prev = _next;
if (_next) _next->_prev = _prev;
- _prev = 0;
- _next = 0;
+ _prev = nullptr;
+ _next = nullptr;
}
bool QIntrusiveListNode::isInList() const
{
- return _prev != 0;
+ return _prev != nullptr;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/ftw/qpodvector_p.h b/src/qml/qml/ftw/qpodvector_p.h
index cafe3367de..b2fb481793 100644
--- a/src/qml/qml/ftw/qpodvector_p.h
+++ b/src/qml/qml/ftw/qpodvector_p.h
@@ -61,7 +61,7 @@ class QPODVector
{
public:
QPODVector()
- : m_count(0), m_capacity(0), m_data(0) {}
+ : m_count(0), m_capacity(0), m_data(nullptr) {}
~QPODVector() { if (m_data) ::free(m_data); }
const T &at(int idx) const {
@@ -87,11 +87,11 @@ public:
void insert(int idx, const T &v) {
if (m_count == m_capacity) {
m_capacity += Increment;
- m_data = (T *)realloc(m_data, m_capacity * sizeof(T));
+ m_data = (T *)realloc(static_cast<void *>(m_data), m_capacity * sizeof(T));
}
int moveCount = m_count - idx;
if (moveCount)
- ::memmove(m_data + idx + 1, m_data + idx, moveCount * sizeof(T));
+ ::memmove(static_cast<void *>(m_data + idx + 1), static_cast<const void *>(m_data + idx), moveCount * sizeof(T));
m_count++;
m_data[idx] = v;
}
@@ -99,7 +99,7 @@ public:
void reserve(int count) {
if (count >= m_capacity) {
m_capacity = (count + (Increment-1)) & (0xFFFFFFFF - Increment + 1);
- m_data = (T *)realloc(m_data, m_capacity * sizeof(T));
+ m_data = (T *)realloc(static_cast<void *>(m_data), m_capacity * sizeof(T));
}
}
@@ -108,7 +108,7 @@ public:
reserve(newSize);
int moveCount = m_count - idx;
if (moveCount)
- ::memmove(m_data + idx + count, m_data + idx,
+ ::memmove(static_cast<void *>(m_data + idx + count), static_cast<const void *>(m_data + idx),
moveCount * sizeof(T));
m_count = newSize;
}
@@ -116,7 +116,7 @@ public:
void remove(int idx, int count = 1) {
int moveCount = m_count - (idx + count);
if (moveCount)
- ::memmove(m_data + idx, m_data + idx + count,
+ ::memmove(static_cast<void *>(m_data + idx), static_cast<const void *>(m_data + idx + count),
moveCount * sizeof(T));
m_count -= count;
}
@@ -154,7 +154,7 @@ public:
other.m_data = m_data;
m_count = 0;
m_capacity = 0;
- m_data = 0;
+ m_data = nullptr;
}
QPODVector<T,Increment> &operator<<(const T &v) { append(v); return *this; }
diff --git a/src/qml/qml/ftw/qqmlnullablevalue_p.h b/src/qml/qml/ftw/qqmlnullablevalue_p.h
index 7a9e4d7b8a..5b3d2fc456 100644
--- a/src/qml/qml/ftw/qqmlnullablevalue_p.h
+++ b/src/qml/qml/ftw/qqmlnullablevalue_p.h
@@ -57,7 +57,7 @@ template<typename T>
struct QQmlNullableValue
{
QQmlNullableValue()
- : isNull(true), value(T()) {}
+ : value(T()) {}
QQmlNullableValue(const QQmlNullableValue<T> &o)
: isNull(o.isNull), value(o.value) {}
QQmlNullableValue(const T &t)
@@ -70,7 +70,7 @@ struct QQmlNullableValue
void invalidate() { isNull = true; }
bool isValid() const { return !isNull; }
- bool isNull;
+ bool isNull = true;
T value;
};
diff --git a/src/qml/qml/ftw/qqmlrefcount_p.h b/src/qml/qml/ftw/qqmlrefcount_p.h
index 225e18156c..3cfb345b30 100644
--- a/src/qml/qml/ftw/qqmlrefcount_p.h
+++ b/src/qml/qml/ftw/qqmlrefcount_p.h
@@ -137,7 +137,7 @@ void QQmlRefCount::destroy()
template<class T>
QQmlRefPointer<T>::QQmlRefPointer()
-: o(0)
+: o(nullptr)
{
}
diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp
index bf62d7a99a..322d3281c7 100644
--- a/src/qml/qml/ftw/qqmlthread.cpp
+++ b/src/qml/qml/ftw/qqmlthread.cpp
@@ -129,7 +129,7 @@ bool QQmlThreadPrivate::MainObject::event(QEvent *e)
QQmlThreadPrivate::QQmlThreadPrivate(QQmlThread *q)
: q(q), m_threadProcessing(false), m_mainProcessing(false), m_shutdown(false),
- m_mainThreadWaiting(false), mainSync(0), m_mainObject(this)
+ m_mainThreadWaiting(false), mainSync(nullptr), m_mainObject(this)
{
setObjectName(QStringLiteral("QQmlThread"));
}
@@ -161,7 +161,7 @@ void QQmlThreadPrivate::mainEvent()
m_mainProcessing = true;
while (!mainList.isEmpty() || mainSync) {
- bool isSync = mainSync != 0;
+ bool isSync = mainSync != nullptr;
QQmlThread::Message *message = isSync?mainSync:mainList.takeFirst();
unlock();
@@ -171,7 +171,7 @@ void QQmlThreadPrivate::mainEvent()
lock();
if (isSync) {
- mainSync = 0;
+ mainSync = nullptr;
wakeOne();
}
}
@@ -339,7 +339,7 @@ void QQmlThread::internalCallMethodInThread(Message *message)
message->call(this);
delete message;
lock();
- d->mainSync = 0;
+ d->mainSync = nullptr;
wakeOne();
} else {
d->wait();
@@ -356,7 +356,7 @@ void QQmlThread::internalCallMethodInMain(Message *message)
d->lock();
- Q_ASSERT(d->mainSync == 0);
+ Q_ASSERT(d->mainSync == nullptr);
d->mainSync = message;
if (d->m_mainThreadWaiting) {
@@ -370,7 +370,7 @@ void QQmlThread::internalCallMethodInMain(Message *message)
while (d->mainSync) {
if (d->m_shutdown) {
delete d->mainSync;
- d->mainSync = 0;
+ d->mainSync = nullptr;
break;
}
d->wait();
@@ -418,7 +418,7 @@ void QQmlThread::waitForNextMessage()
message->call(this);
delete message;
lock();
- d->mainSync = 0;
+ d->mainSync = nullptr;
wakeOne();
} else {
d->wait();
diff --git a/src/qml/qml/ftw/qqmlthread_p.h b/src/qml/qml/ftw/qqmlthread_p.h
index 295235e255..0ed12a2972 100644
--- a/src/qml/qml/ftw/qqmlthread_p.h
+++ b/src/qml/qml/ftw/qqmlthread_p.h
@@ -124,7 +124,7 @@ private:
friend class QQmlThreadPrivate;
struct Message {
- Message() : next(0) {}
+ Message() : next(nullptr) {}
virtual ~Message() {}
Message *next;
virtual void call(QQmlThread *) = 0;
diff --git a/src/qml/qml/ftw/qrecursionwatcher_p.h b/src/qml/qml/ftw/qrecursionwatcher_p.h
index 99228b9583..56b714f922 100644
--- a/src/qml/qml/ftw/qrecursionwatcher_p.h
+++ b/src/qml/qml/ftw/qrecursionwatcher_p.h
@@ -74,7 +74,7 @@ private:
};
QRecursionNode::QRecursionNode()
-: _r(0)
+: _r(nullptr)
{
}
@@ -89,7 +89,7 @@ QRecursionWatcher<T, Node>::QRecursionWatcher(T *t)
template<class T, QRecursionNode T::*Node>
QRecursionWatcher<T, Node>::~QRecursionWatcher()
{
- if ((_t->*Node)._r == &_r) (_t->*Node)._r = 0;
+ if ((_t->*Node)._r == &_r) (_t->*Node)._r = nullptr;
}
template<class T, QRecursionNode T::*Node>
diff --git a/src/qml/qml/ftw/qrecyclepool_p.h b/src/qml/qml/ftw/qrecyclepool_p.h
index 42a2f13729..39f4f88512 100644
--- a/src/qml/qml/ftw/qrecyclepool_p.h
+++ b/src/qml/qml/ftw/qrecyclepool_p.h
@@ -61,7 +61,7 @@ class QRecyclePoolPrivate
public:
QRecyclePoolPrivate()
: recyclePoolHold(true), outstandingItems(0), cookie(QRECYCLEPOOLCOOKIE),
- currentPage(0), nextAllocated(0)
+ currentPage(nullptr), nextAllocated(nullptr)
{
}
@@ -178,7 +178,7 @@ void QRecyclePoolPrivate<T, Step>::releaseIfPossible()
template<typename T, int Step>
T *QRecyclePoolPrivate<T, Step>::allocate()
{
- PoolType *rv = 0;
+ PoolType *rv = nullptr;
if (nextAllocated) {
rv = nextAllocated;
nextAllocated = rv->nextAllocated;
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 219df264be..213f23cd98 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -354,7 +354,7 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
sizeof(T), QQmlPrivate::createInto<T>,
QString(),
- uri, versionMajor, versionMinor, 0, &T::staticMetaObject,
+ uri, versionMajor, versionMinor, nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp
index b1c320afd4..42891c1a8e 100644
--- a/src/qml/qml/qqmlabstractbinding.cpp
+++ b/src/qml/qml/qqmlabstractbinding.cpp
@@ -83,7 +83,7 @@ void QQmlAbstractBinding::addToObject()
// Value type
// Find the value type proxy (if there is one)
- QQmlValueTypeProxyBinding *proxy = 0;
+ QQmlValueTypeProxyBinding *proxy = nullptr;
if (data->hasBindingBit(coreIndex)) {
QQmlAbstractBinding *b = data->bindings;
while (b && (b->targetPropertyIndex().coreIndex() != coreIndex ||
@@ -137,7 +137,7 @@ void QQmlAbstractBinding::removeFromObject()
QQmlAbstractBinding::Ptr next;
next = nextBinding();
- setNextBinding(0);
+ setNextBinding(nullptr);
int coreIndex = targetPropertyIndex().coreIndex();
if (targetPropertyIndex().hasValueTypeIndex()) {
diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h
index bea2d253e4..fc53be3e7b 100644
--- a/src/qml/qml/qqmlabstractbinding_p.h
+++ b/src/qml/qml/qqmlabstractbinding_p.h
@@ -95,8 +95,8 @@ public:
{ return m_nextBinding.flag2(); }
struct RefCount {
- RefCount() : refCount(0) {}
- int refCount;
+ RefCount() {}
+ int refCount = 0;
void ref() { ++refCount; }
int deref() { return --refCount; }
operator int() const { return refCount; }
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index faab8bf926..a0517e4558 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -128,7 +128,7 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
case QQmlComponent::Error:
qWarning() << "QQmlApplicationEngine failed to load component";
qWarning() << qPrintable(c->errorString());
- q->objectCreated(0, c->url());
+ q->objectCreated(nullptr, c->url());
break;
case QQmlComponent::Ready: {
auto newObj = c->create();
diff --git a/src/qml/qml/qqmlapplicationengine.h b/src/qml/qml/qqmlapplicationengine.h
index d0f9e6d319..bb5d6b5d68 100644
--- a/src/qml/qml/qqmlapplicationengine.h
+++ b/src/qml/qml/qqmlapplicationengine.h
@@ -56,7 +56,7 @@ public:
QQmlApplicationEngine(QObject *parent = nullptr);
QQmlApplicationEngine(const QUrl &url, QObject *parent = nullptr);
QQmlApplicationEngine(const QString &filePath, QObject *parent = nullptr);
- ~QQmlApplicationEngine();
+ ~QQmlApplicationEngine() override;
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QList<QObject*> rootObjects(); // ### Qt 6: remove
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 56ab259229..ca3bff43a4 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -70,7 +70,7 @@ QQmlBinding *QQmlBinding::create(const QQmlPropertyData *property, const QQmlScr
return b;
QString url;
- QV4::Function *runtimeFunction = 0;
+ QV4::Function *runtimeFunction = nullptr;
QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context);
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(scriptPrivate->context->engine());
@@ -84,7 +84,7 @@ QQmlBinding *QQmlBinding::create(const QQmlPropertyData *property, const QQmlScr
b->QQmlJavaScriptExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context));
b->setScopeObject(obj ? obj : scriptPrivate->scope);
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::get(b->context()->engine)->v4engine();
+ QV4::ExecutionEngine *v4 = b->context()->engine->handle();
if (runtimeFunction) {
QV4::Scope scope(v4);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxtdata, b->scopeObject()));
@@ -150,7 +150,7 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
QQmlPropertyData vtd;
getPropertyData(&d, &vtd);
Q_ASSERT(d);
- QQmlProperty p = QQmlPropertyPrivate::restore(targetObject(), *d, &vtd, 0);
+ QQmlProperty p = QQmlPropertyPrivate::restore(targetObject(), *d, &vtd, nullptr);
QQmlAbstractBinding::printBindingLoopError(p);
return;
}
@@ -158,13 +158,13 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
DeleteWatcher watcher(this);
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
- QV4::Scope scope(ep->v4engine());
+ QQmlEngine *engine = context()->engine;
+ QV4::Scope scope(engine->handle());
if (canUseAccessor())
flags.setFlag(QQmlPropertyData::BypassInterceptor);
- QQmlBindingProfiler prof(ep->profiler, function());
+ QQmlBindingProfiler prof(QQmlEnginePrivate::get(engine)->profiler, function());
doUpdate(watcher, flags, scope);
if (!watcher.wasDeleted())
@@ -306,7 +306,7 @@ public:
}
void doUpdate(const DeleteWatcher &watcher,
- QQmlPropertyData::WriteFlags flags, QV4::Scope &) override final
+ QQmlPropertyData::WriteFlags flags, QV4::Scope &scope) override final
{
if (watcher.wasDeleted())
return;
@@ -322,7 +322,12 @@ public:
QQmlPropertyData vpd;
getPropertyData(&pd, &vpd);
Q_ASSERT(pd);
- doStore(result, pd, flags);
+ if (pd->propType() == QMetaType::QString) {
+ doStore(result, pd, flags);
+ } else {
+ QV4::ScopedString value(scope, scope.engine->newString(result));
+ slowWrite(*pd, vpd, value, /*isUndefined*/false, flags);
+ }
}
private:
@@ -346,7 +351,7 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
bool isUndefined, QQmlPropertyData::WriteFlags flags)
{
QQmlEngine *engine = context()->engine;
- QV8Engine *v8engine = QQmlEnginePrivate::getV8Engine(engine);
+ QV4::ExecutionEngine *v4engine = engine->handle();
int type = valueTypeData.isValid() ? valueTypeData.propType() : core.propType();
@@ -357,13 +362,13 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
if (isUndefined) {
} else if (core.isQList()) {
- value = QV8Engine::getV4(v8engine)->toVariant(result, qMetaTypeId<QList<QObject *> >());
+ value = v4engine->toVariant(result, qMetaTypeId<QList<QObject *> >());
} else if (result.isNull() && core.isQObject()) {
- value = QVariant::fromValue((QObject *)0);
+ value = QVariant::fromValue((QObject *)nullptr);
} else if (core.propType() == qMetaTypeId<QList<QUrl> >()) {
- value = QQmlPropertyPrivate::resolvedUrlSequence(QV8Engine::getV4(v8engine)->toVariant(result, qMetaTypeId<QList<QUrl> >()), context());
+ value = QQmlPropertyPrivate::resolvedUrlSequence(v4engine->toVariant(result, qMetaTypeId<QList<QUrl> >()), context());
} else if (!isVarProperty && type != qMetaTypeId<QJSValue>()) {
- value = QV8Engine::getV4(v8engine)->toVariant(result, type);
+ value = v4engine->toVariant(result, type);
}
if (hasError()) {
@@ -381,7 +386,7 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
Q_ASSERT(vmemo);
vmemo->setVMEProperty(core.coreIndex(), result);
} else if (isUndefined && core.isResettable()) {
- void *args[] = { 0 };
+ void *args[] = { nullptr };
QMetaObject::metacall(m_target.data(), QMetaObject::ResetProperty, core.coreIndex(), args);
} else if (isUndefined && type == qMetaTypeId<QVariant>()) {
QQmlPropertyPrivate::writeValueProperty(m_target.data(), core, valueTypeData, QVariant(), context(), flags);
@@ -392,7 +397,7 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
return false;
}
QQmlPropertyPrivate::writeValueProperty(m_target.data(), core, valueTypeData, QVariant::fromValue(
- QJSValue(QV8Engine::getV4(v8engine), result.asReturnedValue())),
+ QJSValue(v4engine, result.asReturnedValue())),
context(), flags);
} else if (isUndefined) {
const QLatin1String typeName(QMetaType::typeName(type)
@@ -412,8 +417,8 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
if (watcher.wasDeleted())
return true;
- const char *valueType = 0;
- const char *propertyType = 0;
+ const char *valueType = nullptr;
+ const char *propertyType = nullptr;
const int userType = value.userType();
if (userType == QMetaType::QObjectStar) {
@@ -450,12 +455,13 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
QVariant QQmlBinding::evaluate()
{
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
+ QQmlEngine *engine = context()->engine;
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
ep->referenceScarceResources();
bool isUndefined = false;
- QV4::Scope scope(ep->v4engine());
+ QV4::Scope scope(engine->handle());
QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined));
ep->dereferenceScarceResources();
@@ -524,7 +530,7 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const
int aValueTypeIndex;
if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) {
- m_target = 0;
+ m_target = nullptr;
m_targetIndex = QQmlPropertyIndex();
return;
}
@@ -533,7 +539,7 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const
QQmlData *data = QQmlData::get(object, false);
if (!data || !data->propertyCache) {
- m_target = 0;
+ m_target = nullptr;
m_targetIndex = QQmlPropertyIndex();
return;
}
diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h
index 8bc9554a42..19ec3f5d4f 100644
--- a/src/qml/qml/qqmlbinding_p.h
+++ b/src/qml/qml/qqmlbinding_p.h
@@ -79,7 +79,7 @@ public:
QObject *obj, QQmlContextData *ctxt, QV4::ExecutionContext *scope);
static QQmlBinding *createTranslationBinding(QV4::CompiledData::CompilationUnit *unit, const QV4::CompiledData::Binding *binding,
QObject *obj, QQmlContextData *ctxt);
- ~QQmlBinding();
+ ~QQmlBinding() override;
void setTarget(const QQmlProperty &);
void setTarget(QObject *, const QQmlPropertyData &, const QQmlPropertyData *valueType);
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 1d7a37fc99..060706ac50 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -74,8 +74,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
{
init(ctxt, scope);
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine());
- QV4::ExecutionEngine *v4 = ep->v4engine();
+ QV4::ExecutionEngine *v4 = engine()->handle();
QString function;
@@ -123,7 +122,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
// It's important to call init first, because m_index gets remapped in case of cloned signals.
init(ctxt, scope);
- QV4::ExecutionEngine *engine = QQmlEnginePrivate::getV4Engine(ctxt->engine);
+ QV4::ExecutionEngine *engine = ctxt->engine->handle();
QList<QByteArray> signalParameters = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).parameterNames();
if (!signalParameters.isEmpty()) {
@@ -182,15 +181,17 @@ void QQmlBoundSignalExpression::evaluate(void **a)
if (!expressionFunctionValid())
return;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine());
- QV4::Scope scope(ep->v4engine());
+ QQmlEngine *qmlengine = engine();
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlengine);
+ QV4::ExecutionEngine *v4 = qmlengine->handle();
+ QV4::Scope scope(v4);
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
QQmlMetaObject::ArgTypeStorage storage;
//TODO: lookup via signal index rather than method index as an optimization
int methodIndex = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).methodIndex();
- int *argsTypes = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, &storage, 0);
+ int *argsTypes = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, &storage, nullptr);
int argCount = argsTypes ? *argsTypes : 0;
QV4::JSCallData jsCall(scope, argCount);
@@ -215,13 +216,13 @@ void QQmlBoundSignalExpression::evaluate(void **a)
if (!*reinterpret_cast<void* const *>(a[ii + 1]))
jsCall->args[ii] = QV4::Primitive::nullValue();
else
- jsCall->args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1]));
+ jsCall->args[ii] = QV4::QObjectWrapper::wrap(v4, *reinterpret_cast<QObject* const *>(a[ii + 1]));
} else {
jsCall->args[ii] = scope.engine->fromVariant(QVariant(type, a[ii + 1]));
}
}
- QQmlJavaScriptExpression::evaluate(jsCall.callData(), 0);
+ QQmlJavaScriptExpression::evaluate(jsCall.callData(), nullptr);
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}
@@ -233,8 +234,9 @@ void QQmlBoundSignalExpression::evaluate(const QList<QVariant> &args)
if (!expressionFunctionValid())
return;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine());
- QV4::Scope scope(ep->v4engine());
+ QQmlEngine *qmlengine = engine();
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlengine);
+ QV4::Scope scope(qmlengine->handle());
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
@@ -243,7 +245,7 @@ void QQmlBoundSignalExpression::evaluate(const QList<QVariant> &args)
jsCall->args[ii] = scope.engine->fromVariant(args[ii]);
}
- QQmlJavaScriptExpression::evaluate(jsCall.callData(), 0);
+ QQmlJavaScriptExpression::evaluate(jsCall.callData(), nullptr);
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}
@@ -258,8 +260,8 @@ void QQmlBoundSignalExpression::evaluate(const QList<QVariant> &args)
QQmlBoundSignal::QQmlBoundSignal(QObject *target, int signal, QObject *owner,
QQmlEngine *engine)
: QQmlNotifierEndpoint(QQmlNotifierEndpoint::QQmlBoundSignal),
- m_prevSignal(0), m_nextSignal(0),
- m_enabled(true), m_expression(0)
+ m_prevSignal(nullptr), m_nextSignal(nullptr),
+ m_enabled(true), m_expression(nullptr)
{
addToObject(owner);
@@ -296,8 +298,8 @@ void QQmlBoundSignal::removeFromObject()
if (m_prevSignal) {
*m_prevSignal = m_nextSignal;
if (m_nextSignal) m_nextSignal->m_prevSignal = m_prevSignal;
- m_prevSignal = 0;
- m_nextSignal = 0;
+ m_prevSignal = nullptr;
+ m_nextSignal = nullptr;
}
}
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index 3a0b8aed59..01094a11f7 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -89,14 +89,14 @@ public:
QString expression() const;
QObject *target() const { return m_target; }
- QQmlEngine *engine() const { return context() ? context()->engine : 0; }
+ QQmlEngine *engine() const { return context() ? context()->engine : nullptr; }
private:
- ~QQmlBoundSignalExpression();
+ ~QQmlBoundSignalExpression() override;
void init(QQmlContextData *ctxt, QObject *scope);
- bool expressionFunctionValid() const { return function() != 0; }
+ bool expressionFunctionValid() const { return function() != nullptr; }
int m_index;
QObject *m_target;
diff --git a/src/qml/qml/qqmlboundsignalexpressionpointer_p.h b/src/qml/qml/qqmlboundsignalexpressionpointer_p.h
index de651315f8..eabe6666b4 100644
--- a/src/qml/qml/qqmlboundsignalexpressionpointer_p.h
+++ b/src/qml/qml/qqmlboundsignalexpressionpointer_p.h
@@ -58,7 +58,7 @@ class QQmlBoundSignalExpression;
class Q_QML_PRIVATE_EXPORT QQmlBoundSignalExpressionPointer
{
public:
- inline QQmlBoundSignalExpressionPointer() : o(0) {}
+ inline QQmlBoundSignalExpressionPointer() {}
QQmlBoundSignalExpressionPointer(QQmlBoundSignalExpression *);
QQmlBoundSignalExpressionPointer(const QQmlBoundSignalExpressionPointer &);
~QQmlBoundSignalExpressionPointer();
@@ -73,7 +73,7 @@ public:
QQmlBoundSignalExpressionPointer &take(QQmlBoundSignalExpression *);
private:
- QQmlBoundSignalExpression *o;
+ QQmlBoundSignalExpression *o = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcleanup.cpp b/src/qml/qml/qqmlcleanup.cpp
index 708537a303..0d57ef5fe8 100644
--- a/src/qml/qml/qqmlcleanup.cpp
+++ b/src/qml/qml/qqmlcleanup.cpp
@@ -58,7 +58,7 @@ called by QQmlEngine just before it destroys the context.
Create a QQmlCleanup that is not associated with any engine.
*/
QQmlCleanup::QQmlCleanup()
-: prev(0), next(0), engine(0)
+: prev(nullptr), next(nullptr), engine(nullptr)
{
}
@@ -66,7 +66,7 @@ QQmlCleanup::QQmlCleanup()
Create a QQmlCleanup for \a engine
*/
QQmlCleanup::QQmlCleanup(QQmlEngine *engine)
-: prev(0), next(0), engine(0)
+: prev(nullptr), next(nullptr), engine(nullptr)
{
if (!engine)
return;
@@ -109,8 +109,8 @@ QQmlCleanup::~QQmlCleanup()
if (prev) *prev = next;
if (next) next->prev = prev;
- prev = 0;
- next = 0;
+ prev = nullptr;
+ next = nullptr;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcleanup_p.h b/src/qml/qml/qqmlcleanup_p.h
index a1db656477..0e15c28b9d 100644
--- a/src/qml/qml/qqmlcleanup_p.h
+++ b/src/qml/qml/qqmlcleanup_p.h
@@ -64,7 +64,7 @@ public:
QQmlCleanup(QQmlEngine *);
virtual ~QQmlCleanup();
- bool hasEngine() const { return prev != 0; }
+ bool hasEngine() const { return prev != nullptr; }
void addToEngine(QQmlEngine *);
protected:
virtual void clear() = 0;
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 5a03f2dd93..3174bbecd3 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -241,6 +241,9 @@ V4_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension);
\li main.qml
\li \snippet qml/component/main.qml 0
\endtable
+
+ It is important that the lifetime of the creation context outlive any created objects. See
+ \l{Maintaining Dynamically Created Objects} for more details.
*/
/*!
@@ -315,7 +318,7 @@ void QQmlComponentPrivate::typeDataReady(QQmlTypeData *)
Q_ASSERT(typeData);
fromTypeData(typeData);
- typeData = 0;
+ typeData = nullptr;
progress = 1.0;
emit q->statusChanged(q->status());
@@ -349,7 +352,7 @@ void QQmlComponentPrivate::clear()
if (typeData) {
typeData->unregisterCallback(this);
typeData->release();
- typeData = 0;
+ typeData = nullptr;
}
compilationUnit = nullptr;
@@ -497,8 +500,7 @@ QQmlComponent::QQmlComponent(QQmlEngine *engine, QObject *parent)
Create a QQmlComponent from the given \a url and give it the
specified \a parent and \a engine.
- Ensure that the URL provided is full and correct, in particular, use
- \l QUrl::fromLocalFile() when loading a file from the local filesystem.
+ \include qqmlcomponent.qdoc url-note
\sa loadUrl()
*/
@@ -512,8 +514,7 @@ QQmlComponent::QQmlComponent(QQmlEngine *engine, const QUrl &url, QObject *paren
specified \a parent and \a engine. If \a mode is \l Asynchronous,
the component will be loaded and compiled asynchronously.
- Ensure that the URL provided is full and correct, in particular, use
- \l QUrl::fromLocalFile() when loading a file from the local filesystem.
+ \include qqmlcomponent.qdoc url-note
\sa loadUrl()
*/
@@ -549,7 +550,7 @@ QQmlComponent::QQmlComponent(QQmlEngine *engine, const QString &fileName,
: QQmlComponent(engine, parent)
{
Q_D(QQmlComponent);
- const QUrl url = QDir::isAbsolutePath(fileName) ? QUrl::fromLocalFile(fileName) : d->engine->baseUrl().resolved(QUrl(fileName));
+ const QUrl url = QDir::isAbsolutePath(fileName) ? QUrl::fromLocalFile(fileName) : QUrl(fileName);
d->loadUrl(url, mode);
}
@@ -562,7 +563,7 @@ QQmlComponent::QQmlComponent(QQmlEngine *engine, QV4::CompiledData::CompilationU
Q_D(QQmlComponent);
d->compilationUnit = compilationUnit;
d->start = start;
- d->url = compilationUnit->url();
+ d->url = compilationUnit->finalUrl();
d->progress = 1.0;
}
@@ -609,8 +610,7 @@ QQmlContext *QQmlComponent::creationContext() const
/*!
Load the QQmlComponent from the provided \a url.
- Ensure that the URL provided is full and correct, in particular, use
- \l QUrl::fromLocalFile() when loading a file from the local filesystem.
+ \include qqmlcomponent.qdoc url-note
*/
void QQmlComponent::loadUrl(const QUrl &url)
{
@@ -622,8 +622,7 @@ void QQmlComponent::loadUrl(const QUrl &url)
Load the QQmlComponent from the provided \a url.
If \a mode is \l Asynchronous, the component will be loaded and compiled asynchronously.
- Ensure that the URL provided is full and correct, in particular, use
- \l QUrl::fromLocalFile() when loading a file from the local filesystem.
+ \include qqmlcomponent.qdoc url-note
*/
void QQmlComponent::loadUrl(const QUrl &url, QQmlComponent::CompilationMode mode)
{
@@ -636,11 +635,21 @@ void QQmlComponentPrivate::loadUrl(const QUrl &newUrl, QQmlComponent::Compilatio
Q_Q(QQmlComponent);
clear();
- if ((newUrl.isRelative() && !newUrl.isEmpty())
- || newUrl.scheme() == QLatin1String("file")) // Workaround QTBUG-11929
- url = engine->baseUrl().resolved(newUrl);
- else
+ if (newUrl.isRelative()) {
+ // The new URL is a relative URL like QUrl("main.qml").
+ url = engine->baseUrl().resolved(QUrl(newUrl.toString()));
+ } else if (engine->baseUrl().isLocalFile() && newUrl.isLocalFile() && !QDir::isAbsolutePath(newUrl.toLocalFile())) {
+ // The new URL is a file on disk but it's a relative path; e.g.:
+ // QUrl::fromLocalFile("main.qml") or QUrl("file:main.qml")
+ // We need to remove the scheme so that it becomes a relative URL with a relative path:
+ QUrl fixedUrl(newUrl);
+ fixedUrl.setScheme(QString());
+ // Then, turn it into an absolute URL with an absolute path by resolving it against the engine's baseUrl().
+ // This is a compatibility hack for QTBUG-58837.
+ url = engine->baseUrl().resolved(fixedUrl);
+ } else {
url = newUrl;
+ }
if (newUrl.isEmpty()) {
QQmlError error;
@@ -814,27 +823,27 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
Q_Q(QQmlComponent);
if (!context) {
qWarning("QQmlComponent: Cannot create a component in a null context");
- return 0;
+ return nullptr;
}
if (!context->isValid()) {
qWarning("QQmlComponent: Cannot create a component in an invalid context");
- return 0;
+ return nullptr;
}
if (context->engine != engine) {
qWarning("QQmlComponent: Must create component in context from the same QQmlEngine");
- return 0;
+ return nullptr;
}
if (state.completePending) {
qWarning("QQmlComponent: Cannot create new component instance before completing the previous");
- return 0;
+ return nullptr;
}
if (!q->isReady()) {
qWarning("QQmlComponent: Component is not ready");
- return 0;
+ return nullptr;
}
// Do not create infinite recursion in object creation
@@ -842,7 +851,7 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
if (++creationDepth.localData() >= maxCreationDepth) {
qWarning("QQmlComponent: Component creation is recursing - aborting");
--creationDepth.localData();
- return 0;
+ return nullptr;
}
Q_ASSERT(creationDepth.localData() >= 1);
depthIncreased = true;
@@ -854,7 +863,7 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
state.completePending = true;
enginePriv->referenceScarceResources();
- QObject *rv = 0;
+ QObject *rv = nullptr;
state.creator.reset(new QQmlObjectCreator(context, compilationUnit, creationContext));
rv = state.creator->create(start);
if (!rv)
@@ -959,7 +968,7 @@ void QQmlComponentPrivate::completeCreate()
}
QQmlComponentAttached::QQmlComponentAttached(QObject *parent)
-: QObject(parent), prev(0), next(0)
+: QObject(parent), prev(nullptr), next(nullptr)
{
}
@@ -967,8 +976,8 @@ QQmlComponentAttached::~QQmlComponentAttached()
{
if (prev) *prev = next;
if (next) next->prev = prev;
- prev = 0;
- next = 0;
+ prev = nullptr;
+ next = nullptr;
}
/*!
@@ -1074,7 +1083,6 @@ void QQmlComponentPrivate::incubateObject(
QQmlComponentPrivate *componentPriv = QQmlComponentPrivate::get(component);
incubatorPriv->compilationUnit = componentPriv->compilationUnit;
- incubatorPriv->compilationUnit->addref();
incubatorPriv->enginePriv = enginePriv;
incubatorPriv->creator.reset(new QQmlObjectCreator(context, componentPriv->compilationUnit, componentPriv->creationContext));
incubatorPriv->subComponentToCreate = componentPriv->start;
@@ -1111,11 +1119,11 @@ struct QmlIncubatorObject : public QV4::Object
V4_OBJECT2(QmlIncubatorObject, Object)
V4_NEEDS_DESTROY
- static ReturnedValue method_get_statusChanged(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_set_statusChanged(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_get_status(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_get_object(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_forceCompletion(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_get_statusChanged(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_set_statusChanged(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_status(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_object(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_forceCompletion(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
void statusChanged(QQmlIncubator::Status);
void setInitialState(QObject *);
@@ -1264,7 +1272,7 @@ void QQmlComponent::createObject(QQmlV4Function *args)
Q_ASSERT(d->engine);
Q_ASSERT(args);
- QObject *parent = 0;
+ QObject *parent = nullptr;
QV4::ExecutionEngine *v4 = args->v4engine();
QV4::Scope scope(v4);
QV4::ScopedValue valuemap(scope, QV4::Primitive::undefinedValue());
@@ -1381,7 +1389,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
QV4::ExecutionEngine *v4 = args->v4engine();
QV4::Scope scope(v4);
- QObject *parent = 0;
+ QObject *parent = nullptr;
QV4::ScopedValue valuemap(scope, QV4::Primitive::undefinedValue());
QQmlIncubator::IncubationMode mode = QQmlIncubator::Asynchronous;
@@ -1436,8 +1444,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
// XXX used by QSGLoader
void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate)
{
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- QV4::ExecutionEngine *v4engine = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4engine = engine->handle();
QV4::Scope scope(v4engine);
QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, toCreate));
@@ -1453,27 +1460,27 @@ QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4)
QV4::ScopedObject proto(scope, v4->newObject());
proto->defineAccessorProperty(QStringLiteral("onStatusChanged"),
QV4::QmlIncubatorObject::method_get_statusChanged, QV4::QmlIncubatorObject::method_set_statusChanged);
- proto->defineAccessorProperty(QStringLiteral("status"), QV4::QmlIncubatorObject::method_get_status, 0);
- proto->defineAccessorProperty(QStringLiteral("object"), QV4::QmlIncubatorObject::method_get_object, 0);
+ proto->defineAccessorProperty(QStringLiteral("status"), QV4::QmlIncubatorObject::method_get_status, nullptr);
+ proto->defineAccessorProperty(QStringLiteral("object"), QV4::QmlIncubatorObject::method_get_object, nullptr);
proto->defineDefaultProperty(QStringLiteral("forceCompletion"), QV4::QmlIncubatorObject::method_forceCompletion);
incubationProto.set(v4, proto);
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_object(const BuiltinFunction *b, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_object(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
if (!o)
THROW_TYPE_ERROR();
return QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object());
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_forceCompletion(const BuiltinFunction *b, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_forceCompletion(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
if (!o)
THROW_TYPE_ERROR();
@@ -1482,34 +1489,34 @@ QV4::ReturnedValue QV4::QmlIncubatorObject::method_forceCompletion(const Builtin
RETURN_UNDEFINED();
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_status(const BuiltinFunction *b, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_status(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
if (!o)
THROW_TYPE_ERROR();
return QV4::Encode(o->d()->incubator->status());
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_statusChanged(const BuiltinFunction *b, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_statusChanged(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
if (!o)
THROW_TYPE_ERROR();
return QV4::Encode(o->d()->statusChanged);
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_set_statusChanged(const BuiltinFunction *b, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_set_statusChanged(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
QV4::Scope scope(b);
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
- if (!o || callData->argc() < 1)
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
+ if (!o || argc < 1)
THROW_TYPE_ERROR();
- o->d()->statusChanged.set(scope.engine, callData->args[0]);
+ o->d()->statusChanged.set(scope.engine, argv[0]);
RETURN_UNDEFINED();
}
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index b8cc556e4a..444b3ec46c 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -83,7 +83,7 @@ public:
QQmlComponent(QQmlEngine *, const QString &fileName, CompilationMode mode, QObject *parent = nullptr);
QQmlComponent(QQmlEngine *, const QUrl &url, QObject *parent = nullptr);
QQmlComponent(QQmlEngine *, const QUrl &url, CompilationMode mode, QObject *parent = nullptr);
- virtual ~QQmlComponent();
+ ~QQmlComponent() override;
enum Status { Null, Ready, Loading, Error };
Q_ENUM(Status)
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 8a58a1ada0..2a8d36f317 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -79,7 +79,7 @@ class Q_QML_PRIVATE_EXPORT QQmlComponentPrivate : public QObjectPrivate, public
public:
QQmlComponentPrivate()
- : typeData(0), progress(0.), start(-1), engine(0), creationContext(0), depthIncreased(false) {}
+ : typeData(nullptr), progress(0.), start(-1), engine(nullptr), creationContext(nullptr), depthIncreased(false) {}
void loadUrl(const QUrl &newUrl, QQmlComponent::CompilationMode mode = QQmlComponent::PreferSynchronous);
diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h
index 8236aac1af..e3bca18857 100644
--- a/src/qml/qml/qqmlcomponentattached_p.h
+++ b/src/qml/qml/qqmlcomponentattached_p.h
@@ -62,7 +62,7 @@ class Q_QML_PRIVATE_EXPORT QQmlComponentAttached : public QObject
{
Q_OBJECT
public:
- QQmlComponentAttached(QObject *parent = 0);
+ QQmlComponentAttached(QObject *parent = nullptr);
~QQmlComponentAttached();
void add(QQmlComponentAttached **a) {
@@ -72,7 +72,7 @@ public:
void rem() {
if (next) next->prev = prev;
*prev = next;
- next = 0; prev = 0;
+ next = nullptr; prev = nullptr;
}
QQmlComponentAttached **prev;
QQmlComponentAttached *next;
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 37cb328b36..6e43bc735f 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -56,7 +56,7 @@
QT_BEGIN_NAMESPACE
QQmlContextPrivate::QQmlContextPrivate()
-: data(0), notifyIndex(-1)
+: data(nullptr), notifyIndex(-1)
{
}
@@ -177,7 +177,7 @@ QQmlContext::QQmlContext(QQmlEngine *engine, QObject *parent)
d->data = new QQmlContextData(this);
++d->data->refCount;
- d->data->setParent(engine?QQmlContextData::get(engine->rootContext()):0);
+ d->data->setParent(engine?QQmlContextData::get(engine->rootContext()):nullptr);
}
/*!
@@ -191,14 +191,14 @@ QQmlContext::QQmlContext(QQmlContext *parentContext, QObject *parent)
d->data = new QQmlContextData(this);
++d->data->refCount;
- d->data->setParent(parentContext?QQmlContextData::get(parentContext):0);
+ d->data->setParent(parentContext?QQmlContextData::get(parentContext):nullptr);
}
/*!
\internal
*/
QQmlContext::QQmlContext(QQmlContextData *data)
-: QObject(*(new QQmlContextPrivate), 0)
+: QObject(*(new QQmlContextPrivate), nullptr)
{
Q_D(QQmlContext);
d->data = data;
@@ -216,7 +216,7 @@ QQmlContext::~QQmlContext()
{
Q_D(QQmlContext);
- d->data->publicContext = 0;
+ d->data->publicContext = nullptr;
if (!--d->data->refCount)
d->data->destroy();
}
@@ -250,7 +250,7 @@ QQmlEngine *QQmlContext::engine() const
QQmlContext *QQmlContext::parentContext() const
{
Q_D(const QQmlContext);
- return d->data->parent?d->data->parent->asQQmlContext():0;
+ return d->data->parent?d->data->parent->asQQmlContext():nullptr;
}
/*!
@@ -306,16 +306,7 @@ void QQmlContext::setContextProperty(const QString &name, const QVariant &value)
return;
}
- if (data->engine) {
- bool ok;
- QObject *o = QQmlEnginePrivate::get(data->engine)->toQObject(value, &ok);
- if (ok) {
- setContextProperty(name, o);
- return;
- }
- }
-
- QV4::IdentifierHash<int> &properties = data->detachedPropertyNames();
+ QV4::IdentifierHash &properties = data->detachedPropertyNames();
int idx = properties.value(name);
if (idx == -1) {
properties.add(name, data->idValueCount + d->propertyValues.count());
@@ -324,7 +315,7 @@ void QQmlContext::setContextProperty(const QString &name, const QVariant &value)
data->refreshExpressions();
} else {
d->propertyValues[idx] = value;
- QMetaObject::activate(this, d->notifyIndex, idx, 0);
+ QMetaObject::activate(this, d->notifyIndex, idx, nullptr);
}
}
@@ -335,37 +326,54 @@ void QQmlContext::setContextProperty(const QString &name, const QVariant &value)
*/
void QQmlContext::setContextProperty(const QString &name, QObject *value)
{
- Q_D(QQmlContext);
- if (d->notifyIndex == -1)
- d->notifyIndex = QMetaObjectPrivate::absoluteSignalCount(&QQmlContext::staticMetaObject);
+ setContextProperty(name, QVariant::fromValue(value));
+}
+
+/*!
+ \since 5.11
+
+ Set a batch of \a properties on this context.
+
+ Setting all properties in one batch avoids unnecessary
+ refreshing expressions, and is therefore recommended
+ instead of calling \l setContextProperty() for each individual property.
+
+ \sa QQmlContext::setContextProperty()
+*/
+void QQmlContext::setContextProperties(const QVector<PropertyPair> &properties)
+{
+ Q_D(const QQmlContext);
QQmlContextData *data = d->data;
- if (data->isInternal) {
- qWarning("QQmlContext: Cannot set property on internal context.");
- return;
- }
+ QQmlJavaScriptExpression *expressions = data->expressions;
+ QQmlContextData *childContexts = data->childContexts;
- if (!isValid()) {
- qWarning("QQmlContext: Cannot set property on invalid context.");
- return;
- }
+ data->expressions = nullptr;
+ data->childContexts = nullptr;
- QV4::IdentifierHash<int> &properties = data->detachedPropertyNames();
- int idx = properties.value(name);
+ for (auto property : properties)
+ setContextProperty(property.name, property.value);
- if (idx == -1) {
- properties.add(name, data->idValueCount + d->propertyValues.count());
- d->propertyValues.append(QVariant::fromValue(value));
+ data->expressions = expressions;
+ data->childContexts = childContexts;
- data->refreshExpressions();
- } else {
- d->propertyValues[idx] = QVariant::fromValue(value);
- QMetaObject::activate(this, d->notifyIndex, idx, 0);
- }
+ data->refreshExpressions();
}
/*!
+ \since 5.11
+
+ \class QQmlContext::PropertyPair
+ \inmodule QtQml
+
+ This struct contains a property name and a property value.
+ It is used as a parameter for the \c setContextProperties function.
+
+ \sa QQmlContext::setContextProperties()
+*/
+
+/*!
Returns the value of the \a name property for this context
as a QVariant.
*/
@@ -377,7 +385,7 @@ QVariant QQmlContext::contextProperty(const QString &name) const
QQmlContextData *data = d->data;
- const QV4::IdentifierHash<int> &properties = data->propertyNames();
+ const QV4::IdentifierHash &properties = data->propertyNames();
if (properties.count())
idx = properties.value(name);
@@ -513,7 +521,7 @@ QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, int ind
int contextProperty = (int)(quintptr)prop->data;
if (d->propertyValues.at(contextProperty).userType() != qMetaTypeId<QList<QObject*> >()) {
- return 0;
+ return nullptr;
} else {
return ((const QList<QObject*> *)d->propertyValues.at(contextProperty).constData())->at(index);
}
@@ -526,12 +534,12 @@ QQmlContextData::QQmlContextData()
}
QQmlContextData::QQmlContextData(QQmlContext *ctxt)
- : engine(0), isInternal(false), isJSContext(false),
+ : engine(nullptr), isInternal(false), isJSContext(false),
isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false),
- publicContext(ctxt), incubator(0), componentObjectIndex(-1),
- contextObject(0), nextChild(0), prevChild(0),
- expressions(0), contextObjects(0), idValues(0), idValueCount(0),
- componentAttached(0)
+ publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
+ contextObject(nullptr), nextChild(nullptr), prevChild(nullptr),
+ expressions(nullptr), contextObjects(nullptr), idValues(nullptr), idValueCount(0),
+ componentAttached(nullptr)
{
}
@@ -548,8 +556,8 @@ void QQmlContextData::emitDestruction()
componentAttached = a->next;
if (componentAttached) componentAttached->prev = &componentAttached;
- a->next = 0;
- a->prev = 0;
+ a->next = nullptr;
+ a->prev = nullptr;
emit a->destruction();
}
@@ -575,12 +583,14 @@ void QQmlContextData::invalidate()
if (prevChild) {
*prevChild = nextChild;
if (nextChild) nextChild->prevChild = prevChild;
- nextChild = 0;
- prevChild = 0;
+ nextChild = nullptr;
+ prevChild = nullptr;
}
- engine = 0;
- parent = 0;
+ importedScripts.clear();
+
+ engine = nullptr;
+ parent = nullptr;
}
void QQmlContextData::clearContext()
@@ -591,20 +601,20 @@ void QQmlContextData::clearContext()
while (expression) {
QQmlJavaScriptExpression *nextExpression = expression->m_nextExpression;
- expression->m_prevExpression = 0;
- expression->m_nextExpression = 0;
+ expression->m_prevExpression = nullptr;
+ expression->m_nextExpression = nullptr;
- expression->setContext(0);
+ expression->setContext(nullptr);
expression = nextExpression;
}
- expressions = 0;
+ expressions = nullptr;
}
void QQmlContextData::destroy()
{
Q_ASSERT(refCount == 0);
- linkedContext = 0;
+ linkedContext = nullptr;
// avoid recursion
++refCount;
@@ -619,26 +629,26 @@ void QQmlContextData::destroy()
QQmlData *co = contextObjects;
contextObjects = contextObjects->nextContextObject;
- co->context = 0;
- co->outerContext = 0;
- co->nextContextObject = 0;
- co->prevContextObject = 0;
+ co->context = nullptr;
+ co->outerContext = nullptr;
+ co->nextContextObject = nullptr;
+ co->prevContextObject = nullptr;
}
Q_ASSERT(refCount == 1);
QQmlGuardedContextData *contextGuard = contextGuards;
while (contextGuard) {
QQmlGuardedContextData *next = contextGuard->m_next;
- contextGuard->m_next = 0;
- contextGuard->m_prev = 0;
- contextGuard->m_contextData = 0;
+ contextGuard->m_next = nullptr;
+ contextGuard->m_prev = nullptr;
+ contextGuard->m_contextData = nullptr;
contextGuard = next;
}
- contextGuards = 0;
+ contextGuards = nullptr;
Q_ASSERT(refCount == 1);
delete [] idValues;
- idValues = 0;
+ idValues = nullptr;
Q_ASSERT(refCount == 1);
if (publicContext) {
@@ -736,7 +746,7 @@ void QQmlContextData::refreshExpressionsRecursive(bool isGlobal)
// *structure* (not values) changes.
void QQmlContextData::refreshExpressions()
{
- bool isGlobal = (parent == 0);
+ bool isGlobal = (parent == nullptr);
// For efficiency, we try and minimize the number of guards we have to create
if (expressions_to_run(this, isGlobal) && childContexts) {
@@ -762,7 +772,7 @@ void QQmlContextData::addObject(QObject *o)
{
QQmlData *data = QQmlData::get(o, true);
- Q_ASSERT(data->context == 0);
+ Q_ASSERT(data->context == nullptr);
data->context = this;
data->outerContext = this;
@@ -782,7 +792,7 @@ void QQmlContextData::setIdProperty(int idx, QObject *obj)
QString QQmlContextData::findObjectId(const QObject *obj) const
{
- const QV4::IdentifierHash<int> &properties = propertyNames();
+ const QV4::IdentifierHash &properties = propertyNames();
if (propertyNameCache.isEmpty())
return QString();
@@ -824,18 +834,18 @@ void QQmlContextData::initFromTypeCompilationUnit(const QQmlRefPointer<QV4::Comp
idValues = new ContextGuard[idValueCount];
}
-const QV4::IdentifierHash<int> &QQmlContextData::propertyNames() const
+const QV4::IdentifierHash &QQmlContextData::propertyNames() const
{
if (propertyNameCache.isEmpty()) {
if (typeCompilationUnit)
propertyNameCache = typeCompilationUnit->namedObjectsPerComponent(componentObjectIndex);
else
- propertyNameCache = QV4::IdentifierHash<int>(QV8Engine::getV4(engine));
+ propertyNameCache = QV4::IdentifierHash(engine->handle());
}
return propertyNameCache;
}
-QV4::IdentifierHash<int> &QQmlContextData::detachedPropertyNames()
+QV4::IdentifierHash &QQmlContextData::detachedPropertyNames()
{
propertyNames();
propertyNameCache.detach();
@@ -845,14 +855,14 @@ QV4::IdentifierHash<int> &QQmlContextData::detachedPropertyNames()
QUrl QQmlContextData::url() const
{
if (typeCompilationUnit)
- return typeCompilationUnit->url();
+ return typeCompilationUnit->finalUrl();
return baseUrl;
}
QString QQmlContextData::urlString() const
{
if (typeCompilationUnit)
- return typeCompilationUnit->fileName();
+ return typeCompilationUnit->finalUrlString();
return baseUrlString;
}
diff --git a/src/qml/qml/qqmlcontext.h b/src/qml/qml/qqmlcontext.h
index b2b95b7573..7ed70c7619 100644
--- a/src/qml/qml/qqmlcontext.h
+++ b/src/qml/qml/qqmlcontext.h
@@ -42,6 +42,8 @@
#include <QtCore/qurl.h>
#include <QtCore/qobject.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qpair.h>
#include <QtQml/qjsvalue.h>
#include <QtCore/qmetatype.h>
#include <QtCore/qvariant.h>
@@ -62,9 +64,11 @@ class Q_QML_EXPORT QQmlContext : public QObject
Q_DECLARE_PRIVATE(QQmlContext)
public:
+ struct PropertyPair { QString name; QVariant value; };
+
QQmlContext(QQmlEngine *parent, QObject *objParent = nullptr);
QQmlContext(QQmlContext *parent, QObject *objParent = nullptr);
- virtual ~QQmlContext();
+ ~QQmlContext() override;
bool isValid() const;
@@ -77,6 +81,7 @@ public:
QVariant contextProperty(const QString &) const;
void setContextProperty(const QString &, QObject *);
void setContextProperty(const QString &, const QVariant &);
+ void setContextProperties(const QVector<PropertyPair> &properties);
// ### Qt 6: no need for a mutable object, this should become a const QObject pointer
QString nameForObject(QObject *) const;
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index d01820a430..ff36d6c9a8 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -158,9 +158,9 @@ public:
void initFromTypeCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit, int subComponentIndex);
// flag indicates whether the context owns the cache (after mutation) or not.
- mutable QV4::IdentifierHash<int> propertyNameCache;
- const QV4::IdentifierHash<int> &propertyNames() const;
- QV4::IdentifierHash<int> &detachedPropertyNames();
+ mutable QV4::IdentifierHash propertyNameCache;
+ const QV4::IdentifierHash &propertyNames() const;
+ QV4::IdentifierHash &detachedPropertyNames();
// Context object
QObject *contextObject;
@@ -178,7 +178,7 @@ public:
QQmlRefPointer<QQmlTypeNameCache> imports;
// My children
- QQmlContextData *childContexts = 0;
+ QQmlContextData *childContexts = nullptr;
// My peers in parent's childContexts list
QQmlContextData *nextChild;
@@ -191,7 +191,7 @@ public:
QQmlData *contextObjects;
// Doubly-linked list of context guards (XXX merge with contextObjects)
- QQmlGuardedContextData *contextGuards = 0;
+ QQmlGuardedContextData *contextGuards = nullptr;
// id guards
struct ContextGuard : public QQmlGuard<QObject>
@@ -261,9 +261,9 @@ private:
inline void clear();
- QQmlContextData *m_contextData = 0;
- QQmlGuardedContextData *m_next = 0;
- QQmlGuardedContextData **m_prev = 0;
+ QQmlContextData *m_contextData = nullptr;
+ QQmlGuardedContextData *m_next = nullptr;
+ QQmlGuardedContextData **m_prev = nullptr;
};
@@ -287,14 +287,14 @@ void QQmlGuardedContextData::clear()
if (m_prev) {
*m_prev = m_next;
if (m_next) m_next->m_prev = m_prev;
- m_contextData = 0;
- m_next = 0;
- m_prev = 0;
+ m_contextData = nullptr;
+ m_next = nullptr;
+ m_prev = nullptr;
}
}
QQmlContextDataRef::QQmlContextDataRef()
- : m_contextData(0)
+ : m_contextData(nullptr)
{
}
@@ -338,7 +338,7 @@ void QQmlContextDataRef::clear()
{
if (m_contextData && !--m_contextData->refCount)
m_contextData->destroy();
- m_contextData = 0;
+ m_contextData = nullptr;
}
QQmlContextDataRef &
@@ -356,7 +356,7 @@ QQmlContextDataRef::operator=(const QQmlContextDataRef &other)
}
QQmlContextData::ContextGuard::ContextGuard()
-: context(0)
+: context(nullptr)
{
}
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index cc6e75a39c..5cf87f5264 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -138,7 +138,7 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
QQmlType type;
if (imports.isT1()) {
- imports.asT1()->resolveType(scope, &type, 0, 0, 0);
+ imports.asT1()->resolveType(scope, &type, nullptr, nullptr, nullptr);
} else {
QQmlTypeNameCache::Result result = imports.asT2()->query(scope);
if (result.isValid())
@@ -178,7 +178,7 @@ const QMetaObject *QQmlCustomParser::resolveType(const QString& name) const
if (!imports.isT1())
return nullptr;
QQmlType qmltype;
- if (!imports.asT1()->resolveType(name, &qmltype, 0, 0, 0))
+ if (!imports.asT1()->resolveType(name, &qmltype, nullptr, nullptr, nullptr))
return nullptr;
return qmltype.metaObject();
}
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index 5eb409990d..2a0f805014 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -74,8 +74,8 @@ public:
};
Q_DECLARE_FLAGS(Flags, Flag)
- QQmlCustomParser() : engine(0), validator(0), m_flags(NoFlag) {}
- QQmlCustomParser(Flags f) : engine(0), validator(0), m_flags(f) {}
+ QQmlCustomParser() : engine(nullptr), validator(nullptr), m_flags(NoFlag) {}
+ QQmlCustomParser(Flags f) : engine(nullptr), validator(nullptr), m_flags(f) {}
virtual ~QQmlCustomParser() {}
void clearErrors();
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index d692feb975..20b96d2c4b 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -56,6 +56,7 @@
#include <private/qqmlpropertyindex_p.h>
#include <private/qv4value_p.h>
#include <private/qv4persistent_p.h>
+#include <private/qqmlrefcount_p.h>
#include <qjsengine.h>
#include <qvector.h>
@@ -76,6 +77,7 @@ class QQmlNotifierEndpoint;
namespace QV4 {
namespace CompiledData {
struct CompilationUnit;
+struct Binding;
}
}
@@ -115,6 +117,7 @@ class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData
{
public:
QQmlData();
+ ~QQmlData();
static inline void init() {
static bool initialized = false;
@@ -155,18 +158,21 @@ public:
quint32 hasInterceptorMetaObject:1;
quint32 hasVMEMetaObject:1;
quint32 parentFrozen:1;
- quint32 dummy:22;
+ quint32 dummy:6;
// When bindingBitsSize < sizeof(ptr), we store the binding bit flags inside
// bindingBitsValue. When we need more than sizeof(ptr) bits, we allocated
// sufficient space and use bindingBits to point to it.
- int bindingBitsSize;
+ quint32 bindingBitsArraySize : 16;
typedef quintptr BindingBitsType;
+ enum {
+ BitsPerType = sizeof(BindingBitsType) * 8,
+ InlineBindingArraySize = 2
+ };
union {
BindingBitsType *bindingBits;
- BindingBitsType bindingBitsValue;
+ BindingBitsType bindingBitsValue[InlineBindingArraySize];
};
- enum { MaxInlineBits = sizeof(BindingBitsType) * 8 };
struct NotifyList {
quint64 connectionMask;
@@ -189,9 +195,9 @@ public:
void disconnectNotifiers();
// The context that created the C++ object
- QQmlContextData *context = 0;
+ QQmlContextData *context = nullptr;
// The outermost context in which this object lives
- QQmlContextData *outerContext = 0;
+ QQmlContextData *outerContext = nullptr;
QQmlContextDataRef ownContext;
QQmlAbstractBinding *bindings;
@@ -215,13 +221,18 @@ public:
quint32 jsEngineId; // id of the engine that created the jsWrapper
struct DeferredData {
+ DeferredData();
+ ~DeferredData();
unsigned int deferredIdx;
- QV4::CompiledData::CompilationUnit *compilationUnit;//Not always the same as the other compilation unit
+ QMultiHash<int, const QV4::CompiledData::Binding *> bindings;
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;//Not always the same as the other compilation unit
QQmlContextData *context;//Could be either context or outerContext
+ Q_DISABLE_COPY(DeferredData);
};
- QV4::CompiledData::CompilationUnit *compilationUnit;
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
QVector<DeferredData *> deferredData;
+ void deferData(int objectIndex, QV4::CompiledData::CompilationUnit *, QQmlContextData *);
void releaseDeferredData();
QV4::WeakValue jsWrapper;
@@ -236,13 +247,13 @@ public:
// to be avoided because QObjectPrivate::currentChildBeingDeleted is in use.
if (priv->isDeletingChildren || priv->wasDeleted) {
Q_ASSERT(!create);
- return 0;
+ return nullptr;
} else if (priv->declarativeData) {
return static_cast<QQmlData *>(priv->declarativeData);
} else if (create) {
return createQQmlData(priv);
} else {
- return 0;
+ return nullptr;
}
}
@@ -253,10 +264,10 @@ public:
return false;
}
- bool hasExtendedData() const { return extendedData != 0; }
+ bool hasExtendedData() const { return extendedData != nullptr; }
QHash<int, QObject *> *attachedProperties() const;
- static inline bool wasDeleted(QObject *);
+ static inline bool wasDeleted(const QObject *);
static void markAsDeleted(QObject *);
static void setQueuedForDeletion(QObject *);
@@ -272,6 +283,9 @@ public:
return createPropertyCache(engine, object);
}
+ Q_ALWAYS_INLINE static uint offsetForBit(int bit) { return static_cast<uint>(bit) / BitsPerType; }
+ Q_ALWAYS_INLINE static BindingBitsType bitFlagForBit(int bit) { return BindingBitsType(1) << (static_cast<uint>(bit) & (BitsPerType - 1)); }
+
private:
// For attachedProperties
mutable QQmlDataExtended *extendedData;
@@ -283,26 +297,26 @@ private:
Q_ALWAYS_INLINE bool hasBitSet(int bit) const
{
- if (bindingBitsSize <= bit)
+ uint offset = offsetForBit(bit);
+ if (bindingBitsArraySize <= offset)
return false;
- if (bindingBitsSize == MaxInlineBits)
- return bindingBitsValue & (BindingBitsType(1) << bit);
- else
- return bindingBits[bit / MaxInlineBits] & (BindingBitsType(1) << (bit % MaxInlineBits));
+ const BindingBitsType *bits = (bindingBitsArraySize == InlineBindingArraySize) ? bindingBitsValue : bindingBits;
+ return bits[offset] & bitFlagForBit(bit);
}
+ Q_DISABLE_COPY(QQmlData);
};
-bool QQmlData::wasDeleted(QObject *object)
+bool QQmlData::wasDeleted(const QObject *object)
{
if (!object)
return true;
- QObjectPrivate *priv = QObjectPrivate::get(object);
+ const QObjectPrivate *priv = QObjectPrivate::get(object);
if (!priv || priv->wasDeleted)
return true;
- QQmlData *ddata = QQmlData::get(object);
+ const QQmlData *ddata = QQmlData::get(object);
return ddata && ddata->isQueuedForDeletion;
}
@@ -311,7 +325,7 @@ QQmlNotifierEndpoint *QQmlData::notify(int index)
Q_ASSERT(index <= 0xFFFF);
if (!notifyList || !(notifyList->connectionMask & (1ULL << quint64(index % 64)))) {
- return 0;
+ return nullptr;
} else if (index < notifyList->notifiesSize) {
return notifyList->notifies[index];
} else if (index <= notifyList->maximumTodoIndex) {
@@ -321,7 +335,7 @@ QQmlNotifierEndpoint *QQmlData::notify(int index)
if (index < notifyList->notifiesSize) {
return notifyList->notifies[index];
} else {
- return 0;
+ return nullptr;
}
}
diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp
index df4030e522..5bcf5cd586 100644
--- a/src/qml/qml/qqmldelayedcallqueue.cpp
+++ b/src/qml/qml/qqmldelayedcallqueue.cpp
@@ -89,7 +89,7 @@ void QQmlDelayedCallQueue::DelayedFunctionCall::execute(QV4::ExecutionEngine *en
//
QQmlDelayedCallQueue::QQmlDelayedCallQueue()
- : QObject(0), m_engine(0), m_callbackOutstanding(false)
+ : QObject(nullptr), m_engine(nullptr), m_callbackOutstanding(false)
{
}
@@ -106,18 +106,19 @@ void QQmlDelayedCallQueue::init(QV4::ExecutionEngine* engine)
m_tickedMethod = metaObject.method(methodIndex);
}
-QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() == 0)
+ if (argc == 0)
THROW_GENERIC_ERROR("Qt.callLater: no arguments given");
- const QV4::FunctionObject *func = callData->args[0].as<QV4::FunctionObject>();
+ const QV4::FunctionObject *func = argv[0].as<QV4::FunctionObject>();
if (!func)
THROW_GENERIC_ERROR("Qt.callLater: first argument not a function or signal");
QPair<QObject *, int> functionData = QV4::QObjectMethod::extractQtMethod(func);
+ QV4::ReturnedValue arg0 = argc ? argv[0].asReturnedValue() : QV4::Encode::undefined();
QVector<DelayedFunctionCall>::Iterator iter;
if (functionData.second != -1) {
@@ -136,7 +137,7 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::B
iter = m_delayedFunctionCalls.begin();
while (iter != m_delayedFunctionCalls.end()) {
DelayedFunctionCall& dfc = *iter;
- if (callData->argument(0) == dfc.m_function.value()) {
+ if (arg0 == dfc.m_function.value()) {
break; // Already stored!
}
++iter;
@@ -149,7 +150,7 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::B
m_delayedFunctionCalls.erase(iter);
m_delayedFunctionCalls.append(dfc);
} else {
- m_delayedFunctionCalls.append(QV4::PersistentValue(m_engine, callData->argument(0)));
+ m_delayedFunctionCalls.append(QV4::PersistentValue(m_engine, arg0));
}
DelayedFunctionCall& dfc = m_delayedFunctionCalls.last();
@@ -165,7 +166,7 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::B
dfc.m_guarded = true;
}
}
- storeAnyArguments(dfc, callData, 1, m_engine);
+ storeAnyArguments(dfc, argv, argc, 1, m_engine);
if (!m_callbackOutstanding) {
m_tickedMethod.invoke(this, Qt::QueuedConnection);
@@ -174,9 +175,9 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::B
return QV4::Encode::undefined();
}
-void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4::CallData *callData, int offset, QV4::ExecutionEngine *engine)
+void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4::Value *argv, int argc, int offset, QV4::ExecutionEngine *engine)
{
- const int length = callData->argc() - offset;
+ const int length = argc - offset;
if (length == 0) {
dfc.m_args.clear();
return;
@@ -184,8 +185,8 @@ void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4
QV4::Scope scope(engine);
QV4::ScopedArrayObject array(scope, engine->newArrayObject(length));
uint i = 0;
- for (int j = offset, ej = callData->argc(); j < ej; ++i, ++j)
- array->putIndexed(i, callData->args[j]);
+ for (int j = offset, ej = argc; j < ej; ++i, ++j)
+ array->putIndexed(i, argv[j]);
dfc.m_args.set(engine, array);
}
diff --git a/src/qml/qml/qqmldelayedcallqueue_p.h b/src/qml/qml/qqmldelayedcallqueue_p.h
index 5b3043cfed..7962318561 100644
--- a/src/qml/qml/qqmldelayedcallqueue_p.h
+++ b/src/qml/qml/qqmldelayedcallqueue_p.h
@@ -60,17 +60,16 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
class QQmlDelayedCallQueue : public QObject
{
Q_OBJECT
public:
QQmlDelayedCallQueue();
- ~QQmlDelayedCallQueue();
+ ~QQmlDelayedCallQueue() override;
void init(QV4::ExecutionEngine *);
- QV4::ReturnedValue addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::CallData *callData);
+ QV4::ReturnedValue addUniquelyAndExecuteLater(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
public Q_SLOTS:
void ticked();
@@ -90,7 +89,7 @@ private:
bool m_guarded;
};
- void storeAnyArguments(DelayedFunctionCall& dfc, const QV4::CallData *callData, int offset, QV4::ExecutionEngine *engine);
+ void storeAnyArguments(DelayedFunctionCall& dfc, const QV4::Value *argv, int argc, int offset, QV4::ExecutionEngine *engine);
void executeAllExpired_Later();
QV4::ExecutionEngine *m_engine;
diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qml/qqmldirparser_p.h
index 1530b7a6cf..95370398ad 100644
--- a/src/qml/qml/qqmldirparser_p.h
+++ b/src/qml/qml/qqmldirparser_p.h
@@ -91,8 +91,7 @@ public:
struct Component
{
- Component()
- : majorVersion(0), minorVersion(0), internal(false), singleton(false) {}
+ Component() {}
Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
: typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
@@ -100,24 +99,23 @@ public:
QString typeName;
QString fileName;
- int majorVersion;
- int minorVersion;
- bool internal;
- bool singleton;
+ int majorVersion = 0;
+ int minorVersion = 0;
+ bool internal = false;
+ bool singleton = false;
};
struct Script
{
- Script()
- : majorVersion(0), minorVersion(0) {}
+ Script() {}
Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion)
: nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {}
QString nameSpace;
QString fileName;
- int majorVersion;
- int minorVersion;
+ int majorVersion = 0;
+ int minorVersion = 0;
};
QHash<QString,Component> components() const;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 9ef47b2c2e..4054d2f0be 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -110,7 +110,10 @@ Q_DECLARE_METATYPE(QQmlProperty)
QT_BEGIN_NAMESPACE
typedef QQmlData::BindingBitsType BindingBitsType;
-enum { MaxInlineBits = QQmlData::MaxInlineBits };
+enum {
+ BitsPerType = QQmlData::BitsPerType,
+ InlineBindingArraySize = QQmlData::InlineBindingArraySize
+};
void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
{
@@ -666,19 +669,19 @@ the same object as is returned from the Qt.include() call.
// Qt.include() is implemented in qv4include.cpp
QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
-: propertyCapture(0), rootContext(0),
+: propertyCapture(nullptr), rootContext(nullptr),
#if QT_CONFIG(qml_debug)
- profiler(0),
+ profiler(nullptr),
#endif
outputWarningsToMsgLog(true),
- cleanup(0), erroredBindings(0), inProgressCreations(0),
- workerScriptEngine(0),
- activeObjectCreator(0),
+ cleanup(nullptr), erroredBindings(nullptr), inProgressCreations(0),
+ workerScriptEngine(nullptr),
+ activeObjectCreator(nullptr),
#if QT_CONFIG(qml_network)
- networkAccessManager(0), networkAccessManagerFactory(0),
+ networkAccessManager(nullptr), networkAccessManagerFactory(nullptr),
#endif
- urlInterceptor(0), scarceResourcesRefCount(0), importDatabase(e), typeLoader(e),
- uniqueId(1), incubatorCount(0), incubationController(0)
+ urlInterceptor(nullptr), scarceResourcesRefCount(0), importDatabase(e), typeLoader(e),
+ uniqueId(1), incubatorCount(0), incubationController(nullptr)
{
}
@@ -691,15 +694,15 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
QQmlCleanup *c = cleanup;
cleanup = c->next;
if (cleanup) cleanup->prev = &cleanup;
- c->next = 0;
- c->prev = 0;
+ c->next = nullptr;
+ c->prev = nullptr;
c->clear();
}
doDeleteInEngineThread();
- if (incubationController) incubationController->d = 0;
- incubationController = 0;
+ if (incubationController) incubationController->d = nullptr;
+ incubationController = nullptr;
QQmlMetaType::freeUnusedTypesAndCaches();
@@ -720,13 +723,16 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o)
{
if (QQmlData *d = QQmlData::get(o)) {
if (d->ownContext) {
- for (QQmlContextData *lc = d->ownContext->linkedContext; lc; lc = lc->linkedContext)
+ for (QQmlContextData *lc = d->ownContext->linkedContext; lc; lc = lc->linkedContext) {
lc->invalidate();
+ if (lc->contextObject == o)
+ lc->contextObject = nullptr;
+ }
d->ownContext->invalidate();
if (d->ownContext->contextObject == o)
d->ownContext->contextObject = nullptr;
- d->ownContext = 0;
- d->context = 0;
+ d->ownContext = nullptr;
+ d->context = nullptr;
}
// Mark this object as in the process of deletion to
@@ -744,14 +750,19 @@ QQmlData::QQmlData()
: ownedByQml1(false), ownMemory(true), indestructible(true), explicitIndestructibleSet(false),
hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false),
hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false),
- bindingBitsSize(MaxInlineBits), bindingBitsValue(0), notifyList(0),
- bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0),
- lineNumber(0), columnNumber(0), jsEngineId(0), compilationUnit(0),
- propertyCache(0), guards(0), extendedData(0)
+ bindingBitsArraySize(InlineBindingArraySize), notifyList(nullptr),
+ bindings(nullptr), signalHandlers(nullptr), nextContextObject(nullptr), prevContextObject(nullptr),
+ lineNumber(0), columnNumber(0), jsEngineId(0),
+ propertyCache(nullptr), guards(nullptr), extendedData(nullptr)
{
+ memset(bindingBitsValue, 0, sizeof(bindingBitsValue));
init();
}
+QQmlData::~QQmlData()
+{
+}
+
void QQmlData::destroyed(QAbstractDeclarativeData *d, QObject *o)
{
QQmlData *ddata = static_cast<QQmlData *>(d);
@@ -815,7 +826,7 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
void **args = (void **) malloc((parameterTypes.count() + 1) *sizeof(void *));
types[0] = 0; // return type
- args[0] = 0; // return value
+ args[0] = nullptr; // return value
for (int ii = 0; ii < parameterTypes.count(); ++ii) {
const QByteArray &typeName = parameterTypes.at(ii);
@@ -836,7 +847,7 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
args[ii + 1] = QMetaType::create(types[ii + 1], a[ii + 1]);
}
- QMetaCallEvent *ev = new QMetaCallEvent(m.methodIndex(), 0, 0, object, index,
+ QMetaCallEvent *ev = new QMetaCallEvent(m.methodIndex(), 0, nullptr, object, index,
parameterTypes.count() + 1, types, args);
QQmlThreadNotifierProxyObject *mpo = new QQmlThreadNotifierProxyObject;
@@ -897,8 +908,10 @@ void QQmlData::setQueuedForDeletion(QObject *object)
if (ddata->ownContext) {
Q_ASSERT(ddata->ownContext == ddata->context);
ddata->context->emitDestruction();
- ddata->ownContext = 0;
- ddata->context = 0;
+ if (ddata->ownContext->contextObject == object)
+ ddata->ownContext->contextObject = nullptr;
+ ddata->ownContext = nullptr;
+ ddata->context = nullptr;
}
ddata->isQueuedForDeletion = true;
}
@@ -921,6 +934,14 @@ void QQmlData::flushPendingBindingImpl(QQmlPropertyIndex index)
QQmlPropertyData::DontRemoveBinding);
}
+QQmlData::DeferredData::DeferredData()
+{
+}
+
+QQmlData::DeferredData::~DeferredData()
+{
+}
+
bool QQmlEnginePrivate::baseModulesUninitialized = true;
void QQmlEnginePrivate::init()
{
@@ -1041,7 +1062,7 @@ QQmlEngine::~QQmlEngine()
currType.singletonInstanceInfo()->destroy(this);
delete d->rootContext;
- d->rootContext = 0;
+ d->rootContext = nullptr;
}
/*! \fn void QQmlEngine::quit()
@@ -1154,7 +1175,7 @@ void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index)
if (activeObjectCreator) {
activeObjectCreator->finalizeCallbacks()->append(qMakePair(QPointer<QObject>(obj), index));
} else {
- void *args[] = { 0 };
+ void *args[] = { nullptr };
QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, index, args);
}
}
@@ -1371,13 +1392,13 @@ void QQmlEngine::retranslate()
QQmlContext *QQmlEngine::contextForObject(const QObject *object)
{
if(!object)
- return 0;
+ return nullptr;
QQmlData *data = QQmlData::get(object);
if (data && data->outerContext)
return data->outerContext->asQQmlContext();
- return 0;
+ return nullptr;
}
/*!
@@ -1525,7 +1546,7 @@ QQmlEngine *qmlEngine(const QObject *obj)
{
QQmlData *data = QQmlData::get(obj, false);
if (!data || !data->context)
- return 0;
+ return nullptr;
return data->context->engine;
}
@@ -1533,7 +1554,7 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre
{
QQmlData *data = QQmlData::get(object, create);
if (!data)
- return 0; // Attached properties are only on objects created by QML, unless explicitly requested (create==true)
+ return nullptr; // Attached properties are only on objects created by QML, unless explicitly requested (create==true)
QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
if (rv || !create)
@@ -1542,7 +1563,7 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(data->context);
QQmlAttachedPropertiesFunc pf = QQmlMetaType::attachedPropertiesFuncById(engine, id);
if (!pf)
- return 0;
+ return nullptr;
rv = pf(const_cast<QObject *>(object));
@@ -1556,12 +1577,12 @@ QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
const QMetaObject *attachedMetaObject, bool create)
{
if (*idCache == -1) {
- QQmlEngine *engine = object ? qmlEngine(object) : 0;
- *idCache = QQmlMetaType::attachedPropertiesFuncId(engine ? QQmlEnginePrivate::get(engine) : 0, attachedMetaObject);
+ QQmlEngine *engine = object ? qmlEngine(object) : nullptr;
+ *idCache = QQmlMetaType::attachedPropertiesFuncId(engine ? QQmlEnginePrivate::get(engine) : nullptr, attachedMetaObject);
}
if (*idCache == -1 || !object)
- return 0;
+ return nullptr;
return qmlAttachedPropertiesObjectById(*idCache, object, create);
}
@@ -1621,7 +1642,7 @@ void QQmlData::NotifyList::layout(QQmlNotifierEndpoint *endpoint)
{
// Add a temporary sentinel at beginning of list. This will be overwritten
// when the end point is inserted into the notifies further down.
- endpoint->prev = 0;
+ endpoint->prev = nullptr;
while (endpoint->next) {
Q_ASSERT(reinterpret_cast<QQmlNotifierEndpoint *>(endpoint->next->prev) == endpoint);
@@ -1667,16 +1688,41 @@ void QQmlData::NotifyList::layout()
}
maximumTodoIndex = 0;
- todo = 0;
+ todo = nullptr;
+}
+
+void QQmlData::deferData(int objectIndex, QV4::CompiledData::CompilationUnit *compilationUnit, QQmlContextData *context)
+{
+ QQmlData::DeferredData *deferData = new QQmlData::DeferredData;
+ deferData->deferredIdx = objectIndex;
+ deferData->compilationUnit = compilationUnit;
+ deferData->context = context;
+
+ const QV4::CompiledData::Object *compiledObject = compilationUnit->objectAt(objectIndex);
+ const QV4::CompiledData::BindingPropertyData &propertyData = compilationUnit->bindingPropertyDataPerObject.at(objectIndex);
+
+ const QV4::CompiledData::Binding *binding = compiledObject->bindingTable();
+ for (quint32 i = 0; i < compiledObject->nBindings; ++i, ++binding) {
+ const QQmlPropertyData *property = propertyData.at(i);
+ if (property && binding->flags & QV4::CompiledData::Binding::IsDeferredBinding)
+ deferData->bindings.insert(property->coreIndex(), binding);
+ }
+
+ deferredData.append(deferData);
}
void QQmlData::releaseDeferredData()
{
- for (DeferredData *deferData : qAsConst(deferredData)) {
- deferData->compilationUnit->release();
- delete deferData;
+ auto it = deferredData.begin();
+ while (it != deferredData.end()) {
+ DeferredData *deferData = *it;
+ if (deferData->bindings.isEmpty()) {
+ delete deferData;
+ it = deferredData.erase(it);
+ } else {
+ ++it;
+ }
}
- deferredData.clear();
}
void QQmlData::addNotify(int index, QQmlNotifierEndpoint *endpoint)
@@ -1686,8 +1732,8 @@ void QQmlData::addNotify(int index, QQmlNotifierEndpoint *endpoint)
notifyList->connectionMask = 0;
notifyList->maximumTodoIndex = 0;
notifyList->notifiesSize = 0;
- notifyList->todo = 0;
- notifyList->notifies = 0;
+ notifyList->todo = nullptr;
+ notifyList->notifies = nullptr;
}
Q_ASSERT(!endpoint->isConnected());
@@ -1723,7 +1769,7 @@ void QQmlData::disconnectNotifiers()
}
free(notifyList->notifies);
free(notifyList);
- notifyList = 0;
+ notifyList = nullptr;
}
}
@@ -1748,12 +1794,10 @@ void QQmlData::destroyed(QObject *object)
if (bindings && !bindings->ref.deref())
delete bindings;
- if (compilationUnit) {
- compilationUnit->release();
- compilationUnit = 0;
- }
+ compilationUnit = nullptr;
- releaseDeferredData();
+ qDeleteAll(deferredData);
+ deferredData.clear();
QQmlBoundSignal *signalHandler = signalHandlers;
while (signalHandler) {
@@ -1787,23 +1831,23 @@ void QQmlData::destroyed(QObject *object)
}
QQmlBoundSignal *next = signalHandler->m_nextSignal;
- signalHandler->m_prevSignal = 0;
- signalHandler->m_nextSignal = 0;
+ signalHandler->m_prevSignal = nullptr;
+ signalHandler->m_nextSignal = nullptr;
delete signalHandler;
signalHandler = next;
}
- if (bindingBitsSize > MaxInlineBits)
+ if (bindingBitsArraySize > InlineBindingArraySize)
free(bindingBits);
if (propertyCache)
propertyCache->release();
- ownContext = 0;
+ ownContext = nullptr;
while (guards) {
QQmlGuard<QObject> *guard = static_cast<QQmlGuard<QObject> *>(guards);
- *guard = (QObject *)0;
+ *guard = (QObject *)nullptr;
guard->objectDestroyed(object);
}
@@ -1842,47 +1886,35 @@ void QQmlData::parentChanged(QObject *object, QObject *parent)
static void QQmlData_setBit(QQmlData *data, QObject *obj, int bit)
{
- if (Q_UNLIKELY(data->bindingBitsSize <= bit)) {
+ uint offset = QQmlData::offsetForBit(bit);
+ BindingBitsType *bits = (data->bindingBitsArraySize == InlineBindingArraySize) ? data->bindingBitsValue : data->bindingBits;
+ if (Q_UNLIKELY(data->bindingBitsArraySize <= offset)) {
int props = QQmlMetaObject(obj).propertyCount();
Q_ASSERT(bit < 2 * props);
- int arraySize = (2 * props + MaxInlineBits - 1) / MaxInlineBits;
- Q_ASSERT(arraySize > 1);
-
- // special handling for 32 here is to make sure we wipe the first byte
- // when going from bindingBitsValue to bindingBits, and preserve the old
- // set bits so we can restore them after the allocation
- int oldArraySize = data->bindingBitsSize > MaxInlineBits ? data->bindingBitsSize / MaxInlineBits : 0;
- quintptr oldValue = data->bindingBitsSize == MaxInlineBits ? data->bindingBitsValue : 0;
+ uint arraySize = (2 * static_cast<uint>(props) + BitsPerType - 1) / BitsPerType;
+ Q_ASSERT(arraySize > InlineBindingArraySize && arraySize > data->bindingBitsArraySize);
- data->bindingBits = static_cast<BindingBitsType *>(realloc((data->bindingBitsSize == MaxInlineBits) ? 0 : data->bindingBits,
- arraySize * sizeof(BindingBitsType)));
+ BindingBitsType *newBits = static_cast<BindingBitsType *>(malloc(arraySize*sizeof(BindingBitsType)));
+ memcpy(newBits, bits, data->bindingBitsArraySize * sizeof(BindingBitsType));
+ memset(newBits + data->bindingBitsArraySize, 0, sizeof(BindingBitsType) * (arraySize - data->bindingBitsArraySize));
- memset(data->bindingBits + oldArraySize,
- 0x00,
- sizeof(BindingBitsType) * (arraySize - oldArraySize));
-
- data->bindingBitsSize = arraySize * MaxInlineBits;
-
- // reinstate bindingBitsValue after we dropped it
- if (oldValue) {
- memcpy(data->bindingBits, &oldValue, sizeof(oldValue));
- }
+ if (data->bindingBitsArraySize > InlineBindingArraySize)
+ free(bits);
+ data->bindingBits = newBits;
+ bits = newBits;
+ data->bindingBitsArraySize = arraySize;
}
-
- if (data->bindingBitsSize == MaxInlineBits)
- data->bindingBitsValue |= BindingBitsType(1) << bit;
- else
- data->bindingBits[bit / MaxInlineBits] |= (BindingBitsType(1) << (bit % MaxInlineBits));
+ Q_ASSERT(offset < data->bindingBitsArraySize);
+ bits[offset] |= QQmlData::bitFlagForBit(bit);
}
static void QQmlData_clearBit(QQmlData *data, int bit)
{
- if (data->bindingBitsSize > bit) {
- if (data->bindingBitsSize == MaxInlineBits)
- data->bindingBitsValue &= ~(BindingBitsType(1) << (bit % MaxInlineBits));
- else
- data->bindingBits[bit / MaxInlineBits] &= ~(BindingBitsType(1) << (bit % MaxInlineBits));
+ uint offset = QQmlData::offsetForBit(bit);
+ if (data->bindingBitsArraySize > offset) {
+ BindingBitsType *bits = (data->bindingBitsArraySize == InlineBindingArraySize) ? data->bindingBitsValue : data->bindingBits;
+ bits[offset] &= ~QQmlData::bitFlagForBit(bit);
}
}
@@ -1953,23 +1985,23 @@ static void dumpwarning(const QQmlError &error)
switch (error.messageType()) {
case QtDebugMsg:
QMessageLogger(error.url().toString().toLatin1().constData(),
- error.line(), 0).debug().nospace()
+ error.line(), nullptr).debug().nospace()
<< qPrintable(error.toString());
break;
case QtInfoMsg:
QMessageLogger(error.url().toString().toLatin1().constData(),
- error.line(), 0).info().nospace()
+ error.line(), nullptr).info().nospace()
<< qPrintable(error.toString());
break;
case QtWarningMsg:
case QtFatalMsg: // fatal does not support streaming, and furthermore, is actually fatal. Probably not desirable for QML.
QMessageLogger(error.url().toString().toLatin1().constData(),
- error.line(), 0).warning().nospace()
+ error.line(), nullptr).warning().nospace()
<< qPrintable(error.toString());
break;
case QtCriticalMsg:
QMessageLogger(error.url().toString().toLatin1().constData(),
- error.line(), 0).critical().nospace()
+ error.line(), nullptr).critical().nospace()
<< qPrintable(error.toString());
break;
}
@@ -2048,7 +2080,7 @@ void QQmlEnginePrivate::cleanupScarceResources()
// note that the actual SRD is owned by the JS engine,
// so we cannot delete the SRD; but we can free the
// memory used by the variant in the SRD.
- QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine());
+ QV4::ExecutionEngine *engine = v4engine();
while (QV4::ExecutionEngine::ScarceResourceData *sr = engine->scarceResources.first()) {
sr->data = QVariant();
engine->scarceResources.remove(sr);
@@ -2306,11 +2338,11 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t)
} else {
QQmlType type = QQmlMetaType::qmlType(t);
locker.unlock();
- return type.isValid() ? cache(type.metaObject()) : 0;
+ return type.isValid() ? cache(type.metaObject()) : nullptr;
}
}
-QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
+QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVersion)
{
Locker locker(this);
auto iter = m_compositeTypes.constFind(t);
@@ -2319,7 +2351,11 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
} else {
QQmlType type = QQmlMetaType::qmlType(t);
locker.unlock();
- return type.isValid() ? cache(type.baseMetaObject()) : 0;
+
+ if (minorVersion >= 0)
+ return type.isValid() ? cache(type, minorVersion) : nullptr;
+ else
+ return type.isValid() ? cache(type.baseMetaObject()) : nullptr;
}
}
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h
index 937920e191..73ad2754c8 100644
--- a/src/qml/qml/qqmlengine.h
+++ b/src/qml/qml/qqmlengine.h
@@ -97,7 +97,7 @@ class Q_QML_EXPORT QQmlEngine : public QJSEngine
Q_OBJECT
public:
explicit QQmlEngine(QObject *p = nullptr);
- virtual ~QQmlEngine();
+ ~QQmlEngine() override;
QQmlContext *rootContext() const;
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 791660cac7..d6110c6699 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -122,7 +122,7 @@ class Q_QML_PRIVATE_EXPORT QQmlEnginePrivate : public QJSEnginePrivate
Q_DECLARE_PUBLIC(QQmlEngine)
public:
QQmlEnginePrivate(QQmlEngine *);
- ~QQmlEnginePrivate();
+ ~QQmlEnginePrivate() override;
void init();
// No mutex protecting baseModulesUninitialized, because use outside QQmlEngine
@@ -150,8 +150,8 @@ public:
QQmlDelayedError *erroredBindings;
int inProgressCreations;
- QV8Engine *v8engine() const { return q_func()->handle(); }
- QV4::ExecutionEngine *v4engine() const { return QV8Engine::getV4(q_func()->handle()); }
+ QV8Engine *v8engine() const { return q_func()->handle()->v8Engine; }
+ QV4::ExecutionEngine *v4engine() const { return q_func()->handle(); }
QQuickWorkerScriptEngine *getWorkerScriptEngine();
QQuickWorkerScriptEngine *workerScriptEngine;
@@ -213,14 +213,14 @@ public:
// These methods may be called from the loader thread
bool isQObject(int);
- QObject *toQObject(const QVariant &, bool *ok = 0) const;
+ QObject *toQObject(const QVariant &, bool *ok = nullptr) const;
QQmlMetaType::TypeCategory typeCategory(int) const;
bool isList(int) const;
int listType(int) const;
QQmlMetaObject rawMetaObjectForType(int) const;
QQmlMetaObject metaObjectForType(int) const;
QQmlPropertyCache *propertyCacheForType(int);
- QQmlPropertyCache *rawPropertyCacheForType(int);
+ QQmlPropertyCache *rawPropertyCacheForType(int, int minorVersion = -1);
void registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit);
void unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit);
@@ -265,7 +265,7 @@ private:
static bool s_designerMode;
// These members is protected by the full QQmlEnginePrivate::mutex mutex
- struct Deletable { Deletable():next(0) {} virtual ~Deletable() {} Deletable *next; };
+ struct Deletable { Deletable():next(nullptr) {} virtual ~Deletable() {} Deletable *next; };
QFieldList<Deletable, &Deletable::next> toDeleteInEngineThread;
void doDeleteInEngineThread();
@@ -295,7 +295,7 @@ inline void QQmlEnginePrivate::dereferenceScarceResources()
// expression must have completed. We can safely release the
// scarce resources.
if (Q_LIKELY(scarceResourcesRefCount == 0)) {
- QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine());
+ QV4::ExecutionEngine *engine = v4engine();
if (Q_UNLIKELY(!engine->scarceResources.isEmpty())) {
cleanupScarceResources();
}
@@ -341,7 +341,7 @@ void QQmlEnginePrivate::deleteInEngineThread(T *value)
} else {
struct I : public Deletable {
I(T *value) : value(value) {}
- ~I() { delete value; }
+ ~I() override { delete value; }
T *value;
};
I *i = new I(value);
@@ -385,14 +385,14 @@ QV8Engine *QQmlEnginePrivate::getV8Engine(QQmlEngine *e)
{
Q_ASSERT(e);
- return e->d_func()->v8engine();
+ return e->handle()->v8Engine;
}
QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e)
{
Q_ASSERT(e);
- return e->d_func()->v4engine();
+ return e->handle();
}
QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlEngine *e)
@@ -411,12 +411,12 @@ const QQmlEnginePrivate *QQmlEnginePrivate::get(const QQmlEngine *e)
QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlContext *c)
{
- return (c && c->engine()) ? QQmlEnginePrivate::get(c->engine()) : 0;
+ return (c && c->engine()) ? QQmlEnginePrivate::get(c->engine()) : nullptr;
}
QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlContextData *c)
{
- return (c && c->engine) ? QQmlEnginePrivate::get(c->engine) : 0;
+ return (c && c->engine) ? QQmlEnginePrivate::get(c->engine) : nullptr;
}
QQmlEngine *QQmlEnginePrivate::get(QQmlEnginePrivate *p)
@@ -428,11 +428,9 @@ QQmlEngine *QQmlEnginePrivate::get(QQmlEnginePrivate *p)
QQmlEnginePrivate *QQmlEnginePrivate::get(QV4::ExecutionEngine *e)
{
- if (!e->v8Engine)
- return 0;
- QQmlEngine *qmlEngine = e->v8Engine->engine();
+ QQmlEngine *qmlEngine = e->qmlEngine();
if (!qmlEngine)
- return 0;
+ return nullptr;
return get(qmlEngine);
}
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 64f008cd32..fc5b186b29 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -99,7 +99,7 @@ QQmlErrorPrivate::QQmlErrorPrivate()
Creates an empty error object.
*/
QQmlError::QQmlError()
-: d(0)
+: d(nullptr)
{
}
@@ -107,7 +107,7 @@ QQmlError::QQmlError()
Creates a copy of \a other.
*/
QQmlError::QQmlError(const QQmlError &other)
-: d(0)
+: d(nullptr)
{
*this = other;
}
@@ -119,7 +119,7 @@ QQmlError &QQmlError::operator=(const QQmlError &other)
{
if (!other.d) {
delete d;
- d = 0;
+ d = nullptr;
} else {
if (!d)
d = new QQmlErrorPrivate;
@@ -138,7 +138,7 @@ QQmlError &QQmlError::operator=(const QQmlError &other)
*/
QQmlError::~QQmlError()
{
- delete d; d = 0;
+ delete d; d = nullptr;
}
/*!
@@ -146,7 +146,7 @@ QQmlError::~QQmlError()
*/
bool QQmlError::isValid() const
{
- return d != 0;
+ return d != nullptr;
}
/*!
@@ -239,7 +239,7 @@ QObject *QQmlError::object() const
{
if (d)
return d->object;
- return 0;
+ return nullptr;
}
/*!
@@ -268,7 +268,7 @@ QtMsgType QQmlError::messageType() const
\since 5.9
Sets the \a messageType for this message. The message type determines which
- QDebug handlers are responsible for recieving the message.
+ QDebug handlers are responsible for receiving the message.
*/
void QQmlError::setMessageType(QtMsgType messageType)
{
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index 35dbaccbbe..59cc9bb09f 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -74,7 +74,7 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr, QOb
void QQmlExpressionPrivate::init(QQmlContextData *ctxt, QV4::Function *runtimeFunction, QObject *me)
{
expressionFunctionValid = true;
- QV4::ExecutionEngine *engine = QQmlEnginePrivate::getV4Engine(ctxt->engine);
+ QV4::ExecutionEngine *engine = ctxt->engine->handle();
QV4::Scope scope(engine);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(engine->rootContext(), ctxt, me));
setupFunction(qmlContext, runtimeFunction);
@@ -121,7 +121,7 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, QV4::Function *runtimeFu
null expression object and its value will always be an invalid QVariant.
*/
QQmlExpression::QQmlExpression()
-: QObject(*new QQmlExpressionPrivate, 0)
+: QObject(*new QQmlExpressionPrivate, nullptr)
{
}
@@ -147,7 +147,7 @@ QQmlExpression::QQmlExpression(const QQmlScriptString &script, QQmlContext *ctxt
QQmlContextData *evalCtxtData = QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context);
QObject *scopeObject = scope ? scope : scriptPrivate->scope;
- QV4::Function *runtimeFunction = 0;
+ QV4::Function *runtimeFunction = nullptr;
if (scriptPrivate->context) {
QQmlContextData *ctxtdata = QQmlContextData::get(scriptPrivate->context);
@@ -191,7 +191,7 @@ QQmlExpression::QQmlExpression(QQmlContext *ctxt,
*/
QQmlExpression::QQmlExpression(QQmlContextData *ctxt, QObject *scope,
const QString &expression)
-: QObject(*new QQmlExpressionPrivate, 0)
+: QObject(*new QQmlExpressionPrivate, nullptr)
{
Q_D(QQmlExpression);
d->init(ctxt, expression, scope);
@@ -211,7 +211,7 @@ QQmlExpression::~QQmlExpression()
QQmlEngine *QQmlExpression::engine() const
{
Q_D(const QQmlExpression);
- return d->context()?d->context()->engine:0;
+ return d->context()?d->context()->engine:nullptr;
}
/*!
@@ -222,7 +222,7 @@ QQmlContext *QQmlExpression::context() const
{
Q_D(const QQmlExpression);
QQmlContextData *data = d->context();
- return data?data->asQQmlContext():0;
+ return data?data->asQQmlContext():nullptr;
}
/*!
@@ -266,13 +266,14 @@ QVariant QQmlExpressionPrivate::value(bool *isUndefined)
return QVariant();
}
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(q->engine());
+ QQmlEngine *engine = q->engine();
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
QVariant rv;
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
{
- QV4::Scope scope(QV8Engine::getV4(ep->v8engine()));
+ QV4::Scope scope(engine->handle());
QV4::ScopedValue result(scope, v4value(isUndefined));
if (!hasError())
rv = scope.engine->toVariant(result, -1);
diff --git a/src/qml/qml/qqmlexpression.h b/src/qml/qml/qqmlexpression.h
index e9c8770e92..0eceeb12e1 100644
--- a/src/qml/qml/qqmlexpression.h
+++ b/src/qml/qml/qqmlexpression.h
@@ -62,7 +62,7 @@ public:
QQmlExpression();
QQmlExpression(QQmlContext *, QObject *, const QString &, QObject * = nullptr);
explicit QQmlExpression(const QQmlScriptString &, QQmlContext * = nullptr, QObject * = nullptr, QObject * = nullptr);
- virtual ~QQmlExpression();
+ ~QQmlExpression() override;
QQmlEngine *engine() const;
QQmlContext *context() const;
diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h
index a94ca0fc2d..da10b31b2c 100644
--- a/src/qml/qml/qqmlexpression_p.h
+++ b/src/qml/qml/qqmlexpression_p.h
@@ -68,14 +68,14 @@ class QQmlExpressionPrivate : public QObjectPrivate,
Q_DECLARE_PUBLIC(QQmlExpression)
public:
QQmlExpressionPrivate();
- ~QQmlExpressionPrivate();
+ ~QQmlExpressionPrivate() override;
void init(QQmlContextData *, const QString &, QObject *);
void init(QQmlContextData *, QV4::Function *runtimeFunction, QObject *);
- QVariant value(bool *isUndefined = 0);
+ QVariant value(bool *isUndefined = nullptr);
- QV4::ReturnedValue v4value(bool *isUndefined = 0);
+ QV4::ReturnedValue v4value(bool *isUndefined = nullptr);
static inline QQmlExpressionPrivate *get(QQmlExpression *expr);
static inline QQmlExpression *get(QQmlExpressionPrivate *expr);
diff --git a/src/qml/qml/qqmlextensioninterface.h b/src/qml/qml/qqmlextensioninterface.h
index 62b9b26569..c2d20ef0a3 100644
--- a/src/qml/qml/qqmlextensioninterface.h
+++ b/src/qml/qml/qqmlextensioninterface.h
@@ -58,7 +58,7 @@ public:
class Q_QML_EXPORT QQmlExtensionInterface : public QQmlTypesExtensionInterface
{
public:
- virtual ~QQmlExtensionInterface() {}
+ ~QQmlExtensionInterface() override {}
virtual void initializeEngine(QQmlEngine *engine, const char *uri) = 0;
};
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index b0e6a24616..818ff7c34f 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -121,7 +121,9 @@ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
\class QQmlExtensionInterface
\internal
\inmodule QtQml
+*/
+/*!
\class QQmlTypesExtensionInterface
\internal
\inmodule QtQml
diff --git a/src/qml/qml/qqmlextensionplugin.h b/src/qml/qml/qqmlextensionplugin.h
index 84a46fb93e..55e9b89dae 100644
--- a/src/qml/qml/qqmlextensionplugin.h
+++ b/src/qml/qml/qqmlextensionplugin.h
@@ -59,7 +59,7 @@ class Q_QML_EXPORT QQmlExtensionPlugin
Q_INTERFACES(QQmlTypesExtensionInterface)
public:
explicit QQmlExtensionPlugin(QObject *parent = nullptr);
- ~QQmlExtensionPlugin();
+ ~QQmlExtensionPlugin() override;
QUrl baseUrl() const;
diff --git a/src/qml/qml/qqmlfile.cpp b/src/qml/qml/qqmlfile.cpp
index 93c3e8e00c..99031e1e74 100644
--- a/src/qml/qml/qqmlfile.cpp
+++ b/src/qml/qml/qqmlfile.cpp
@@ -131,7 +131,7 @@ int QQmlFileNetworkReply::replyFinishedIndex = -1;
int QQmlFileNetworkReply::replyDownloadProgressIndex = -1;
QQmlFileNetworkReply::QQmlFileNetworkReply(QQmlEngine *e, QQmlFilePrivate *p, const QUrl &url)
-: m_engine(e), m_p(p), m_redirectCount(0), m_reply(0)
+: m_engine(e), m_p(p), m_redirectCount(0), m_reply(nullptr)
{
if (finishedIndex == -1) {
finishedIndex = QMetaMethod::fromSignal(&QQmlFileNetworkReply::finished).methodIndex();
@@ -194,9 +194,9 @@ void QQmlFileNetworkReply::networkFinished()
}
m_reply->deleteLater();
- m_reply = 0;
+ m_reply = nullptr;
- m_p->reply = 0;
+ m_p->reply = nullptr;
emit finished();
delete this;
}
@@ -210,7 +210,7 @@ void QQmlFileNetworkReply::networkDownloadProgress(qint64 a, qint64 b)
QQmlFilePrivate::QQmlFilePrivate()
: error(None)
#if QT_CONFIG(qml_network)
-, reply(0)
+, reply(nullptr)
#endif
{
}
@@ -237,7 +237,7 @@ QQmlFile::~QQmlFile()
delete d->reply;
#endif
delete d;
- d = 0;
+ d = nullptr;
}
bool QQmlFile::isNull() const
diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp
index be6216d3ff..8666144096 100644
--- a/src/qml/qml/qqmlfileselector.cpp
+++ b/src/qml/qml/qqmlfileselector.cpp
@@ -115,8 +115,8 @@ QQmlFileSelector::~QQmlFileSelector()
{
Q_D(QQmlFileSelector);
if (d->engine && QQmlFileSelector::get(d->engine) == this) {
- d->engine->setUrlInterceptor(0);
- d->engine = 0;
+ d->engine->setUrlInterceptor(nullptr);
+ d->engine = nullptr;
}
interceptorInstances()->remove(d->myInstance.data());
}
@@ -200,7 +200,7 @@ QQmlFileSelector* QQmlFileSelector::get(QQmlEngine* engine)
QQmlAbstractUrlInterceptor* current = engine->urlInterceptor();
if (current && interceptorInstances()->contains(current))
return interceptorInstances()->value(current);
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/qml/qml/qqmlfileselector.h b/src/qml/qml/qqmlfileselector.h
index 4eaf92c918..9b70e3936d 100644
--- a/src/qml/qml/qqmlfileselector.h
+++ b/src/qml/qml/qqmlfileselector.h
@@ -55,7 +55,7 @@ class Q_QML_EXPORT QQmlFileSelector : public QObject
Q_DECLARE_PRIVATE(QQmlFileSelector)
public:
explicit QQmlFileSelector(QQmlEngine *engine, QObject *parent = nullptr);
- ~QQmlFileSelector();
+ ~QQmlFileSelector() override;
QFileSelector *selector() const Q_DECL_NOTHROW;
void setSelector(QFileSelector *selector);
void setExtraSelectors(QStringList &strings); // TODO Qt6: remove
diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp
index 6418812bae..1d60c518c4 100644
--- a/src/qml/qml/qqmlglobal.cpp
+++ b/src/qml/qml/qqmlglobal.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
QQmlValueTypeProvider::QQmlValueTypeProvider()
- : next(0)
+ : next(nullptr)
{
}
@@ -65,7 +65,7 @@ const QMetaObject *QQmlValueTypeProvider::metaObjectForMetaType(int type)
return mo;
} while ((p = p->next));
- return 0;
+ return nullptr;
}
bool QQmlValueTypeProvider::initValueType(int type, QVariant& dst)
@@ -218,7 +218,7 @@ bool QQmlValueTypeProvider::writeValueType(int type, const void *src, QVariant&
return false;
}
-const QMetaObject *QQmlValueTypeProvider::getMetaObjectForMetaType(int) { return 0; }
+const QMetaObject *QQmlValueTypeProvider::getMetaObjectForMetaType(int) { return nullptr; }
bool QQmlValueTypeProvider::init(int, QVariant&) { return false; }
bool QQmlValueTypeProvider::create(int, int, const void *[], QVariant *) { return false; }
bool QQmlValueTypeProvider::createFromString(int, const QString &, void *, size_t) { return false; }
@@ -232,11 +232,11 @@ bool QQmlValueTypeProvider::read(const QVariant&, void *, int) { return false; }
bool QQmlValueTypeProvider::write(int, const void *, QVariant&) { return false; }
Q_GLOBAL_STATIC(QQmlValueTypeProvider, nullValueTypeProvider)
-static QQmlValueTypeProvider *valueTypeProvider = 0;
+static QQmlValueTypeProvider *valueTypeProvider = nullptr;
static QQmlValueTypeProvider **getValueTypeProvider(void)
{
- if (valueTypeProvider == 0) {
+ if (valueTypeProvider == nullptr) {
valueTypeProvider = nullValueTypeProvider;
}
@@ -294,7 +294,7 @@ QVariant QQmlColorProvider::lighter(const QVariant &, qreal) { return QVariant()
QVariant QQmlColorProvider::darker(const QVariant &, qreal) { return QVariant(); }
QVariant QQmlColorProvider::tint(const QVariant &, const QVariant &) { return QVariant(); }
-static QQmlColorProvider *colorProvider = 0;
+static QQmlColorProvider *colorProvider = nullptr;
Q_QML_PRIVATE_EXPORT QQmlColorProvider *QQml_setColorProvider(QQmlColorProvider *newProvider)
{
@@ -305,7 +305,7 @@ Q_QML_PRIVATE_EXPORT QQmlColorProvider *QQml_setColorProvider(QQmlColorProvider
static QQmlColorProvider **getColorProvider(void)
{
- if (colorProvider == 0) {
+ if (colorProvider == nullptr) {
qWarning() << "Warning: QQml_colorProvider: no color provider has been set!";
static QQmlColorProvider nullColorProvider;
colorProvider = &nullColorProvider;
@@ -345,7 +345,7 @@ QObject *QQmlGuiProvider::styleHints()
QString QQmlGuiProvider::pluginName() const { return QString(); }
-static QQmlGuiProvider *guiProvider = 0;
+static QQmlGuiProvider *guiProvider = nullptr;
Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *newProvider)
{
@@ -356,7 +356,7 @@ Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *newPr
static QQmlGuiProvider **getGuiProvider(void)
{
- if (guiProvider == 0) {
+ if (guiProvider == nullptr) {
static QQmlGuiProvider nullGuiProvider; //Still provides an application with no GUI support
guiProvider = &nullGuiProvider;
}
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index a6c113f5a7..302fdd56c4 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -193,16 +193,6 @@ do { \
return QObjectPrivate::get(sender)->isSignalConnected(signalIdx); \
} while (0)
-struct QQmlGraphics_DerivedObject : public QObject
-{
- void setParent_noEvent(QObject *parent) {
- bool sce = d_ptr->sendChildEvents;
- d_ptr->sendChildEvents = false;
- setParent(parent);
- d_ptr->sendChildEvents = sce;
- }
-};
-
/*!
Returns true if the case of \a fileName is equivalent to the file case of
\a fileName on disk, and false otherwise.
@@ -230,7 +220,11 @@ bool QQml_isFileCaseCorrect(const QString &fileName, int length = -1);
*/
inline void QQml_setParent_noEvent(QObject *object, QObject *parent)
{
- static_cast<QQmlGraphics_DerivedObject *>(object)->setParent_noEvent(parent);
+ QObjectPrivate *d_ptr = QObjectPrivate::get(object);
+ bool sce = d_ptr->sendChildEvents;
+ d_ptr->sendChildEvents = false;
+ object->setParent(parent);
+ d_ptr->sendChildEvents = sce;
}
class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider
@@ -329,7 +323,7 @@ class Q_QML_PRIVATE_EXPORT QQmlApplication : public QObject
Q_PROPERTY(QString organization READ organization WRITE setOrganization NOTIFY organizationChanged)
Q_PROPERTY(QString domain READ domain WRITE setDomain NOTIFY domainChanged)
public:
- QQmlApplication(QObject* parent=0);
+ QQmlApplication(QObject* parent=nullptr);
QStringList args();
@@ -353,7 +347,7 @@ Q_SIGNALS:
void domainChanged();
protected:
- QQmlApplication(QQmlApplicationPrivate &dd, QObject* parent=0);
+ QQmlApplication(QQmlApplicationPrivate &dd, QObject* parent=nullptr);
private:
Q_DISABLE_COPY(QQmlApplication)
@@ -374,12 +368,12 @@ public:
struct QQmlSourceLocation
{
- QQmlSourceLocation() : line(0), column(0) {}
+ QQmlSourceLocation() {}
QQmlSourceLocation(const QString &sourceFile, quint16 line, quint16 column)
: sourceFile(sourceFile), line(line), column(column) {}
QString sourceFile;
- quint16 line;
- quint16 column;
+ quint16 line = 0;
+ quint16 column = 0;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlguard_p.h b/src/qml/qml/qqmlguard_p.h
index 52526276be..808bf4c709 100644
--- a/src/qml/qml/qqmlguard_p.h
+++ b/src/qml/qml/qqmlguard_p.h
@@ -65,9 +65,9 @@ public:
inline QQmlGuardImpl(const QQmlGuardImpl &);
inline ~QQmlGuardImpl();
- QObject *o;
- QQmlGuardImpl *next;
- QQmlGuardImpl **prev;
+ QObject *o = nullptr;
+ QQmlGuardImpl *next = nullptr;
+ QQmlGuardImpl **prev = nullptr;
inline void addGuard();
inline void remGuard();
@@ -113,18 +113,17 @@ Q_DECLARE_METATYPE(QQmlGuard<QObject>)
QT_BEGIN_NAMESPACE
QQmlGuardImpl::QQmlGuardImpl()
-: o(0), next(0), prev(0)
{
}
QQmlGuardImpl::QQmlGuardImpl(QObject *g)
-: o(g), next(0), prev(0)
+: o(g)
{
if (o) addGuard();
}
QQmlGuardImpl::QQmlGuardImpl(const QQmlGuardImpl &g)
-: o(g.o), next(0), prev(0)
+: o(g.o)
{
if (o) addGuard();
}
@@ -132,7 +131,7 @@ QQmlGuardImpl::QQmlGuardImpl(const QQmlGuardImpl &g)
QQmlGuardImpl::~QQmlGuardImpl()
{
if (prev) remGuard();
- o = 0;
+ o = nullptr;
}
void QQmlGuardImpl::addGuard()
@@ -155,8 +154,8 @@ void QQmlGuardImpl::remGuard()
if (next) next->prev = prev;
*prev = next;
- next = 0;
- prev = 0;
+ next = nullptr;
+ prev = nullptr;
}
template<class T>
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 0fbe934bb9..92cecf9f0d 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -728,7 +728,7 @@ bool QQmlImports::resolveType(QQmlImportNamespace *ns, const QHashedStringRef &t
QQmlType *type_return, int *vmaj, int *vmin,
QQmlType::RegistrationType registrationType) const
{
- return ns->resolveType(d->typeLoader, type, vmaj, vmin, type_return, 0, 0, registrationType);
+ return ns->resolveType(d->typeLoader, type, vmaj, vmin, type_return, nullptr, nullptr, registrationType);
}
bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
@@ -803,7 +803,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
int major = vmajor ? *vmajor : -1;
int minor = vminor ? *vminor : -1;
QQmlType returnType = fetchOrCreateTypeForUrl(componentUrl, type, isCompositeSingleton,
- 0, major, minor);
+ nullptr, major, minor);
if (type_return)
*type_return = returnType;
return returnType.isValid();
@@ -831,7 +831,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
*typeRecursionDetected = true;
} else {
QQmlType returnType = fetchOrCreateTypeForUrl(
- qmlUrl, type, registrationType == QQmlType::CompositeSingletonType, 0);
+ qmlUrl, type, registrationType == QQmlType::CompositeSingletonType, nullptr);
if (type_return)
*type_return = returnType;
return returnType.isValid();
@@ -847,7 +847,7 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor,
QQmlType::RegistrationType registrationType,
QQmlImport::RecursionRestriction recursionRestriction)
{
- QQmlImportNamespace *s = 0;
+ QQmlImportNamespace *s = nullptr;
int dot = type.indexOf(Dot);
if (dot >= 0) {
QHashedStringRef namespaceName(type.constData(), dot);
@@ -978,10 +978,10 @@ QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QHashedStr
if (prefix == ns->prefix)
return ns;
}
- return 0;
+ return nullptr;
}
-/*!
+/*
Returns the list of possible versioned URI combinations. For example, if \a uri is
QtQml.Models, \a vmaj is 2, and \a vmin is 0, this method returns the following:
[QtQml.Models.2.0, QtQml.2.0.Models, QtQml.Models.2, QtQml.2.Models, QtQml.Models]
@@ -1017,7 +1017,7 @@ static QVector<QStaticPlugin> makePlugins()
return plugins;
}
-/*!
+/*
Get all static plugins that are QML plugins and has a meta data URI that matches with one of
\a versionUris, which is a list of all possible versioned URI combinations - see versionUriList()
above.
@@ -1059,7 +1059,7 @@ static inline QString msgCannotLoadPlugin(const QString &uri, const QString &why
}
#endif
-/*!
+/*
Import an extension defined by a qmldir file.
\a qmldirFilePath is a raw file path.
@@ -1231,10 +1231,12 @@ QString QQmlImportsPrivate::resolvedUri(const QString &dir_arg, QQmlImportDataba
stableRelativePath.replace(Backslash, Slash);
// remove optional versioning in dot notation from uri
- int lastSlash = stableRelativePath.lastIndexOf(Slash);
- if (lastSlash >= 0) {
- int versionDot = stableRelativePath.indexOf(Dot, lastSlash);
- if (versionDot >= 0)
+ int versionDot = stableRelativePath.lastIndexOf(Dot);
+ if (versionDot >= 0) {
+ int nextSlash = stableRelativePath.indexOf(Slash, versionDot);
+ if (nextSlash >= 0)
+ stableRelativePath.remove(versionDot, nextSlash - versionDot);
+ else
stableRelativePath = stableRelativePath.left(versionDot);
}
@@ -1255,7 +1257,7 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
// Check cache first
- QQmlImportDatabase::QmldirCache *cacheHead = 0;
+ QQmlImportDatabase::QmldirCache *cacheHead = nullptr;
{
QQmlImportDatabase::QmldirCache **cachePtr = database->qmldirCache.value(uri);
if (cachePtr) {
@@ -1274,10 +1276,19 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
QQmlTypeLoader &typeLoader = QQmlEnginePrivate::get(database->engine)->typeLoader;
+ // Interceptor might redirect remote files to local ones.
+ QQmlAbstractUrlInterceptor *interceptor = typeLoader.engine()->urlInterceptor();
+ QStringList localImportPaths = database->importPathList(
+ interceptor ? QQmlImportDatabase::LocalOrRemote : QQmlImportDatabase::Local);
// Search local import paths for a matching version
- QStringList localImportPaths = database->importPathList(QQmlImportDatabase::Local);
const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(uri, localImportPaths, vmaj, vmin);
- for (const QString &qmldirPath : qmlDirPaths) {
+ for (QString qmldirPath : qmlDirPaths) {
+ if (interceptor) {
+ qmldirPath = QQmlFile::urlToLocalFileOrQrc(
+ interceptor->intercept(QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
+ QQmlAbstractUrlInterceptor::QmldirFile));
+ }
+
QString absoluteFilePath = typeLoader.absoluteFilePath(qmldirPath);
if (!absoluteFilePath.isEmpty()) {
QString url;
@@ -1377,7 +1388,7 @@ bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent
QQmlImportNamespace *QQmlImportsPrivate::importNamespace(const QString &prefix) const
{
- QQmlImportNamespace *nameSpace = 0;
+ QQmlImportNamespace *nameSpace = nullptr;
if (prefix.isEmpty()) {
nameSpace = &unqualifiedset;
@@ -1434,7 +1445,7 @@ bool QQmlImportsPrivate::addLibraryImport(const QString& uri, const QString &pre
Q_ASSERT(inserted);
if (!incomplete) {
- const QQmlTypeLoaderQmldirContent *qmldir = 0;
+ const QQmlTypeLoaderQmldirContent *qmldir = nullptr;
if (!qmldirIdentifier.isEmpty()) {
if (!getQmldirContent(qmldirIdentifier, uri, &qmldir, errors))
@@ -1486,6 +1497,10 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix
QString qmldirUrl = resolveLocalUrl(base, importUri + (importUri.endsWith(Slash)
? String_qmldir
: Slash_qmldir));
+ if (QQmlAbstractUrlInterceptor *interceptor = typeLoader->engine()->urlInterceptor()) {
+ qmldirUrl = interceptor->intercept(QUrl(qmldirUrl),
+ QQmlAbstractUrlInterceptor::QmldirFile).toString();
+ }
QString qmldirIdentifier;
if (QQmlFile::isLocalFile(qmldirUrl)) {
@@ -1538,7 +1553,7 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix
if (isImplicitImport) {
for (QList<QQmlImportInstance *>::const_iterator it = nameSpace->imports.constBegin();
it != nameSpace->imports.constEnd(); ++it) {
- if ((*it)->uri == importUri) {
+ if ((*it)->url == url) {
(*it)->implicitlyImported = true;
return true;
}
@@ -1549,7 +1564,7 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix
Q_ASSERT(inserted);
if (!incomplete && !qmldirIdentifier.isEmpty()) {
- const QQmlTypeLoaderQmldirContent *qmldir = 0;
+ const QQmlTypeLoaderQmldirContent *qmldir = nullptr;
if (!getQmldirContent(qmldirIdentifier, importUri, &qmldir, errors))
return false;
@@ -1573,7 +1588,7 @@ bool QQmlImportsPrivate::updateQmldirContent(const QString &uri, const QString &
Q_ASSERT(nameSpace);
if (QQmlImportInstance *import = nameSpace->findImport(uri)) {
- const QQmlTypeLoaderQmldirContent *qmldir = 0;
+ const QQmlTypeLoaderQmldirContent *qmldir = nullptr;
if (!getQmldirContent(qmldirIdentifier, uri, &qmldir, errors))
return false;
@@ -1585,8 +1600,8 @@ bool QQmlImportsPrivate::updateQmldirContent(const QString &uri, const QString &
if (import->setQmldirContent(qmldirUrl, qmldir, nameSpace, errors)) {
if (import->qmlDirComponents.isEmpty() && import->qmlDirScripts.isEmpty()) {
- // The implicit import qmldir can be empty
- if (uri != QLatin1String(".")) {
+ // The implicit import qmldir can be empty, and plugins have no extra versions
+ if (uri != QLatin1String(".") && !QQmlMetaType::isModule(uri, vmaj, vmin)) {
QQmlError error;
if (QQmlMetaType::isAnyModule(uri))
error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri).arg(vmaj).arg(vmin));
@@ -1714,6 +1729,16 @@ bool QQmlImports::isLocal(const QUrl &url)
return !QQmlFile::urlToLocalFileOrQrc(url).isEmpty();
}
+QUrl QQmlImports::urlFromLocalFileOrQrcOrUrl(const QString &file)
+{
+ QUrl url(QLatin1String(file.at(0) == Colon ? "qrc" : "") + file);
+
+ // We don't support single character schemes as those conflict with windows drive letters.
+ if (url.scheme().length() < 2)
+ return QUrl::fromLocalFile(file);
+ return url;
+}
+
void QQmlImports::setDesignerSupportRequired(bool b)
{
designerSupportRequired = b;
@@ -2060,29 +2085,38 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba
// Dynamic plugins are differentiated by their filepath. For static plugins we
// don't have that information so we use their address as key instead.
const QString uniquePluginID = QString::asprintf("%p", instance);
- StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
- QMutexLocker lock(&plugins->mutex);
+ {
+ StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
+ QMutexLocker lock(&plugins->mutex);
- // Plugin types are global across all engines and should only be
- // registered once. But each engine still needs to be initialized.
- bool typesRegistered = plugins->contains(uniquePluginID);
- bool engineInitialized = initializedPlugins.contains(uniquePluginID);
+ // Plugin types are global across all engines and should only be
+ // registered once. But each engine still needs to be initialized.
+ bool typesRegistered = plugins->contains(uniquePluginID);
- if (typesRegistered) {
- Q_ASSERT_X(plugins->value(uniquePluginID).uri == uri,
- "QQmlImportDatabase::importStaticPlugin",
- "Internal error: Static plugin imported previously with different uri");
- } else {
- RegisteredPlugin plugin;
- plugin.uri = uri;
- plugin.loader = 0;
- plugins->insert(uniquePluginID, plugin);
+ if (typesRegistered) {
+ Q_ASSERT_X(plugins->value(uniquePluginID).uri == uri,
+ "QQmlImportDatabase::importStaticPlugin",
+ "Internal error: Static plugin imported previously with different uri");
+ } else {
+ RegisteredPlugin plugin;
+ plugin.uri = uri;
+ plugin.loader = nullptr;
+ plugins->insert(uniquePluginID, plugin);
- if (!registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors))
- return false;
+ if (!registerPluginTypes(instance, basePath, uri, typeNamespace, vmaj, errors))
+ return false;
+ }
+
+ // Release the lock on plugins early as we're done with the global part. Releasing the lock
+ // also allows other QML loader threads to acquire the lock while this thread is blocking
+ // in the initializeEngine call to the gui thread (which in turn may be busy waiting for
+ // other QML loader threads and thus not process the initializeEngine call).
}
- if (!engineInitialized) {
+ // The plugin's per-engine initialization does not need lock protection, as this function is
+ // only called from the engine specific loader thread and importDynamicPlugin as well as
+ // importStaticPlugin are the only places of access.
+ if (!initializedPlugins.contains(uniquePluginID)) {
initializedPlugins.insert(uniquePluginID);
if (QQmlExtensionInterface *eiface = qobject_cast<QQmlExtensionInterface *>(instance)) {
@@ -2104,68 +2138,77 @@ bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QStr
QFileInfo fileInfo(filePath);
const QString absoluteFilePath = fileInfo.absoluteFilePath();
+ QObject *instance = nullptr;
bool engineInitialized = initializedPlugins.contains(absoluteFilePath);
- StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
- QMutexLocker lock(&plugins->mutex);
- bool typesRegistered = plugins->contains(absoluteFilePath);
-
- if (typesRegistered) {
- Q_ASSERT_X(plugins->value(absoluteFilePath).uri == uri,
- "QQmlImportDatabase::importDynamicPlugin",
- "Internal error: Plugin imported previously with different uri");
- }
-
- if (!engineInitialized || !typesRegistered) {
- if (!QQml_isFileCaseCorrect(absoluteFilePath)) {
- if (errors) {
- QQmlError error;
- error.setDescription(tr("File name case mismatch for \"%1\"").arg(absoluteFilePath));
- errors->prepend(error);
- }
- return false;
+ {
+ StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
+ QMutexLocker lock(&plugins->mutex);
+ bool typesRegistered = plugins->contains(absoluteFilePath);
+
+ if (typesRegistered) {
+ Q_ASSERT_X(plugins->value(absoluteFilePath).uri == uri,
+ "QQmlImportDatabase::importDynamicPlugin",
+ "Internal error: Plugin imported previously with different uri");
}
- QPluginLoader* loader = 0;
- if (!typesRegistered) {
- loader = new QPluginLoader(absoluteFilePath);
-
- if (!loader->load()) {
+ if (!engineInitialized || !typesRegistered) {
+ if (!QQml_isFileCaseCorrect(absoluteFilePath)) {
if (errors) {
QQmlError error;
- error.setDescription(loader->errorString());
+ error.setDescription(tr("File name case mismatch for \"%1\"").arg(absoluteFilePath));
errors->prepend(error);
}
- delete loader;
return false;
}
- } else {
- loader = plugins->value(absoluteFilePath).loader;
- }
- QObject *instance = loader->instance();
+ QPluginLoader* loader = nullptr;
+ if (!typesRegistered) {
+ loader = new QPluginLoader(absoluteFilePath);
- if (!typesRegistered) {
- RegisteredPlugin plugin;
- plugin.uri = uri;
- plugin.loader = loader;
- plugins->insert(absoluteFilePath, plugin);
+ if (!loader->load()) {
+ if (errors) {
+ QQmlError error;
+ error.setDescription(loader->errorString());
+ errors->prepend(error);
+ }
+ delete loader;
+ return false;
+ }
+ } else {
+ loader = plugins->value(absoluteFilePath).loader;
+ }
- // Continue with shared code path for dynamic and static plugins:
- if (!registerPluginTypes(instance, fileInfo.absolutePath(), uri, typeNamespace, vmaj, errors))
- return false;
+ instance = loader->instance();
+
+ if (!typesRegistered) {
+ RegisteredPlugin plugin;
+ plugin.uri = uri;
+ plugin.loader = loader;
+ plugins->insert(absoluteFilePath, plugin);
+
+ // Continue with shared code path for dynamic and static plugins:
+ if (!registerPluginTypes(instance, fileInfo.absolutePath(), uri, typeNamespace, vmaj, errors))
+ return false;
+ }
}
- if (!engineInitialized) {
- // things on the engine (eg. adding new global objects) have to be done for every
- // engine.
- // XXX protect against double initialization
- initializedPlugins.insert(absoluteFilePath);
-
- if (QQmlExtensionInterface *eiface = qobject_cast<QQmlExtensionInterface *>(instance)) {
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- ep->typeLoader.initializeEngine(eiface, uri.toUtf8().constData());
- }
- }
+ // Release the lock on plugins early as we're done with the global part. Releasing the lock
+ // also allows other QML loader threads to acquire the lock while this thread is blocking
+ // in the initializeEngine call to the gui thread (which in turn may be busy waiting for
+ // other QML loader threads and thus not process the initializeEngine call).
+ }
+
+
+ if (!engineInitialized) {
+ // The plugin's per-engine initialization does not need lock protection, as this function is
+ // only called from the engine specific loader thread and importDynamicPlugin as well as
+ // importStaticPlugin are the only places of access.
+ initializedPlugins.insert(absoluteFilePath);
+
+ if (QQmlExtensionInterface *eiface = qobject_cast<QQmlExtensionInterface *>(instance)) {
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
+ ep->typeLoader.initializeEngine(eiface, uri.toUtf8().constData());
+ }
}
return true;
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index a7b65c1048..b70bb5253c 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -92,7 +92,7 @@ struct QQmlImportInstance
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
int *vmajor, int *vminor, QQmlType* type_return,
- QString *base = 0, bool *typeRecursionDetected = 0,
+ QString *base = nullptr, bool *typeRecursionDetected = nullptr,
QQmlType::RegistrationType = QQmlType::AnyRegistrationType,
QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion) const;
};
@@ -100,7 +100,7 @@ struct QQmlImportInstance
class QQmlImportNamespace
{
public:
- QQmlImportNamespace() : nextNamespace(0) {}
+ QQmlImportNamespace() : nextNamespace(nullptr) {}
~QQmlImportNamespace() { qDeleteAll(imports); }
QList<QQmlImportInstance *> imports;
@@ -109,7 +109,7 @@ public:
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
int *vmajor, int *vminor, QQmlType* type_return,
- QString *base = 0, QList<QQmlError> *errors = 0,
+ QString *base = nullptr, QList<QQmlError> *errors = nullptr,
QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion);
@@ -137,7 +137,7 @@ public:
QQmlType *type_return,
int *version_major, int *version_minor,
QQmlImportNamespace **ns_return,
- QList<QQmlError> *errors = 0,
+ QList<QQmlError> *errors = nullptr,
QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
QQmlImport::RecursionRestriction recursionRestriction
= QQmlImport::PreventRecursion) const;
@@ -191,6 +191,7 @@ public:
static bool isLocal(const QString &url);
static bool isLocal(const QUrl &url);
+ static QUrl urlFromLocalFileOrQrcOrUrl(const QString &);
static void setDesignerSupportRequired(bool b);
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 6d0e4b915a..4546a4423f 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -110,7 +110,7 @@ void QQmlEngine::setIncubationController(QQmlIncubationController *controller)
{
Q_D(QQmlEngine);
if (d->incubationController)
- d->incubationController->d = 0;
+ d->incubationController->d = nullptr;
d->incubationController = controller;
if (controller) controller->d = d;
}
@@ -128,7 +128,7 @@ QQmlIncubationController *QQmlEngine::incubationController() const
QQmlIncubatorPrivate::QQmlIncubatorPrivate(QQmlIncubator *q, QQmlIncubator::IncubationMode m)
: q(q), status(QQmlIncubator::Null), mode(m), isAsynchronous(false), progress(Execute),
- result(0), enginePriv(0), waitingOnMe(0)
+ result(nullptr), enginePriv(nullptr), waitingOnMe(nullptr)
{
}
@@ -147,16 +147,16 @@ void QQmlIncubatorPrivate::clear()
if (controller)
controller->incubatingObjectCountChanged(enginePriv->incubatorCount);
}
- enginePriv = 0;
+ enginePriv = nullptr;
if (!rootContext.isNull()) {
- rootContext->incubator = 0;
- rootContext = 0;
+ rootContext->incubator = nullptr;
+ rootContext = nullptr;
}
if (nextWaitingFor.isInList()) {
Q_ASSERT(waitingOnMe);
nextWaitingFor.remove();
- waitingOnMe = 0;
+ waitingOnMe = nullptr;
}
// if we're waiting on any incubators then they should be cleared too.
@@ -171,7 +171,7 @@ void QQmlIncubatorPrivate::clear()
vmeGuard.clear();
if (creator && guardOk)
creator->clear();
- creator.reset(0);
+ creator.reset(nullptr);
}
/*!
@@ -218,15 +218,15 @@ than a static amount like 5 milliseconds - while not disturbing the application.
Create a new incubation controller.
*/
QQmlIncubationController::QQmlIncubationController()
-: d(0)
+: d(nullptr)
{
}
/*! \internal */
QQmlIncubationController::~QQmlIncubationController()
{
- if (d) QQmlEnginePrivate::get(d)->setIncubationController(0);
- d = 0;
+ if (d) QQmlEnginePrivate::get(d)->setIncubationController(nullptr);
+ d = nullptr;
}
/*!
@@ -272,7 +272,7 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
if (!compilationUnit)
return;
- QML_MEMORY_SCOPE_URL(compilationUnit->url());
+ QML_MEMORY_SCOPE_URL(compilationUnit->finalUrl());
QExplicitlySharedDataPointer<QQmlIncubatorPrivate> protectThis(this);
@@ -294,8 +294,8 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
if (progress == QQmlIncubatorPrivate::Execute) {
enginePriv->referenceScarceResources();
- QObject *tresult = 0;
- tresult = creator->create(subComponentToCreate, /*parent*/0, &i);
+ QObject *tresult = nullptr;
+ tresult = creator->create(subComponentToCreate, /*parent*/nullptr, &i);
if (!tresult)
errors = creator->errors;
enginePriv->dereferenceScarceResources();
@@ -304,7 +304,7 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
return;
result = tresult;
- if (errors.isEmpty() && result == 0)
+ if (errors.isEmpty() && result == nullptr)
goto finishIncubate;
if (result) {
@@ -340,7 +340,7 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
if (watcher.hasRecursed())
return;
- QQmlContextData *ctxt = 0;
+ QQmlContextData *ctxt = nullptr;
ctxt = creator->finalize(i);
if (ctxt) {
rootContext = ctxt;
@@ -377,23 +377,6 @@ finishIncubate:
}
}
-void QQmlIncubatorPrivate::cancel(QObject *object, QQmlContext *context)
-{
- if (!context)
- context = qmlContext(object);
- if (!context)
- return;
-
- QQmlContextData *data = QQmlContextData::get(context);
- QQmlIncubatorPrivate *p = data->incubator;
- if (!p)
- return;
-
- p->vmeGuard.unguard(object);
- if (!p->creator.isNull())
- p->creator->cancel(object);
-}
-
/*!
Incubate objects for \a msecs, or until there are no more objects to incubate.
*/
@@ -523,12 +506,12 @@ QQmlIncubator::QQmlIncubator(IncubationMode mode)
/*! \internal */
QQmlIncubator::~QQmlIncubator()
{
- d->q = 0;
+ d->q = nullptr;
if (!d->ref.deref()) {
delete d;
}
- d = 0;
+ d = nullptr;
}
/*!
@@ -574,18 +557,18 @@ void QQmlIncubator::clear()
if (s == Loading) {
Q_ASSERT(d->compilationUnit);
if (d->result) d->result->deleteLater();
- d->result = 0;
+ d->result = nullptr;
}
d->clear();
Q_ASSERT(d->compilationUnit.isNull());
- Q_ASSERT(d->waitingOnMe.data() == 0);
+ Q_ASSERT(d->waitingOnMe.data() == nullptr);
Q_ASSERT(d->waitingFor.isEmpty());
d->errors.clear();
d->progress = QQmlIncubatorPrivate::Execute;
- d->result = 0;
+ d->result = nullptr;
if (s == Loading) {
Q_ASSERT(enginePriv);
@@ -674,7 +657,7 @@ Return the incubated object if the status is Ready, otherwise 0.
QObject *QQmlIncubator::object() const
{
if (status() != Ready)
- return 0;
+ return nullptr;
else
return d->result;
}
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h
index 758e0a29f6..676ba1a29a 100644
--- a/src/qml/qml/qqmlincubator_p.h
+++ b/src/qml/qml/qqmlincubator_p.h
@@ -102,9 +102,6 @@ public:
void forceCompletion(QQmlInstantiationInterrupt &i);
void incubate(QQmlInstantiationInterrupt &i);
-
- // used by Qt Quick Controls 2
- Q_QML_PRIVATE_EXPORT static void cancel(QObject *object, QQmlContext *context = 0);
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp
index dae15e2eca..c8f5ba506f 100644
--- a/src/qml/qml/qqmlinfo.cpp
+++ b/src/qml/qml/qqmlinfo.cpp
@@ -182,7 +182,7 @@ QQmlInfo::~QQmlInfo()
if (0 == --d->ref) {
QList<QQmlError> errors = d->errors;
- QQmlEngine *engine = 0;
+ QQmlEngine *engine = nullptr;
if (!d->buffer.isEmpty()) {
QQmlError error;
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 006611e089..74148e3ca4 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -93,12 +93,12 @@ void QQmlDelayedError::catchJavaScriptException(QV4::ExecutionEngine *engine)
QQmlJavaScriptExpression::QQmlJavaScriptExpression()
- : m_error(0),
- m_context(0),
- m_prevExpression(0),
- m_nextExpression(0),
- m_v4Function(0),
- m_sourceLocation(0)
+ : m_error(nullptr),
+ m_context(nullptr),
+ m_prevExpression(nullptr),
+ m_nextExpression(nullptr),
+ m_v4Function(nullptr),
+ m_sourceLocation(nullptr)
{
}
@@ -114,7 +114,7 @@ QQmlJavaScriptExpression::~QQmlJavaScriptExpression()
clearPermanentGuards();
clearError();
if (m_scopeObject.isT2()) // notify DeleteWatcher of our deletion.
- m_scopeObject.asT2()->_s = 0;
+ m_scopeObject.asT2()->_s = nullptr;
delete m_sourceLocation;
}
@@ -157,8 +157,8 @@ void QQmlJavaScriptExpression::setContext(QQmlContextData *context)
*m_prevExpression = m_nextExpression;
if (m_nextExpression)
m_nextExpression->m_prevExpression = m_prevExpression;
- m_prevExpression = 0;
- m_nextExpression = 0;
+ m_prevExpression = nullptr;
+ m_nextExpression = nullptr;
}
m_context = context;
@@ -183,7 +183,7 @@ void QQmlJavaScriptExpression::refresh()
QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(bool *isUndefined)
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_context->engine);
+ QV4::ExecutionEngine *v4 = m_context->engine->handle();
QV4::Scope scope(v4);
QV4::JSCallData jsCall(scope);
@@ -211,13 +211,13 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
QQmlPropertyCapture capture(m_context->engine, this, &watcher);
QQmlPropertyCapture *lastPropertyCapture = ep->propertyCapture;
- ep->propertyCapture = notifyOnValueChanged() ? &capture : 0;
+ ep->propertyCapture = notifyOnValueChanged() ? &capture : nullptr;
if (notifyOnValueChanged())
capture.guards.copyAndClearPrepend(activeGuards);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4 = m_context->engine->handle();
callData->thisObject = v4->globalObject;
if (scopeObject()) {
QV4::ReturnedValue scope = QV4::QObjectWrapper::wrap(v4, scopeObject());
@@ -253,7 +253,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
for (int ii = 0; ii < capture.errorString->count(); ++ii)
qWarning("%s", qPrintable(capture.errorString->at(ii)));
delete capture.errorString;
- capture.errorString = 0;
+ capture.errorString = nullptr;
}
while (QQmlJavaScriptExpressionGuard *g = capture.guards.takeFirst())
@@ -274,7 +274,7 @@ void QQmlPropertyCapture::captureProperty(QQmlNotifier *n, Duration duration)
while (!guards.isEmpty() && !guards.first()->isConnected(n))
guards.takeFirst()->Delete();
- QQmlJavaScriptExpressionGuard *g = 0;
+ QQmlJavaScriptExpressionGuard *g = nullptr;
if (!guards.isEmpty()) {
g = guards.takeFirst();
g->cancelNotify();
@@ -323,7 +323,7 @@ void QQmlPropertyCapture::captureProperty(QObject *o, int c, int n, Duration dur
while (!guards.isEmpty() && !guards.first()->isConnected(o, n))
guards.takeFirst()->Delete();
- QQmlJavaScriptExpressionGuard *g = 0;
+ QQmlJavaScriptExpressionGuard *g = nullptr;
if (!guards.isEmpty()) {
g = guards.takeFirst();
g->cancelNotify();
@@ -414,7 +414,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scopeObje
QQmlEngine *engine = ctxt->engine;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4 = engine->handle();
QV4::Scope scope(v4);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxt, scopeObject));
@@ -444,7 +444,7 @@ void QQmlJavaScriptExpression::createQmlBinding(QQmlContextData *ctxt, QObject *
QQmlEngine *engine = ctxt->engine;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4 = engine->handle();
QV4::Scope scope(v4);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxt, qmlScope));
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index 1cb6d7bfd1..a028850074 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -62,7 +62,7 @@ struct QQmlSourceLocation;
class QQmlDelayedError
{
public:
- inline QQmlDelayedError() : nextError(0), prevError(0) {}
+ inline QQmlDelayedError() : nextError(nullptr), prevError(nullptr) {}
inline ~QQmlDelayedError() { removeError(); }
bool addError(QQmlEnginePrivate *);
@@ -71,8 +71,8 @@ public:
if (!prevError) return;
if (nextError) nextError->prevError = prevError;
*prevError = nextError;
- nextError = 0;
- prevError = 0;
+ nextError = nullptr;
+ prevError = nullptr;
}
inline bool isValid() const { return m_error.isValid(); }
@@ -117,7 +117,7 @@ public:
QQmlSourceLocation sourceLocation() const;
void setSourceLocation(const QQmlSourceLocation &location);
- bool isValid() const { return context() != 0; }
+ bool isValid() const { return context() != nullptr; }
QQmlContextData *context() const { return m_context; }
void setContext(QQmlContextData *context);
@@ -193,11 +193,11 @@ class QQmlPropertyCapture
{
public:
QQmlPropertyCapture(QQmlEngine *engine, QQmlJavaScriptExpression *e, QQmlJavaScriptExpression::DeleteWatcher *w)
- : engine(engine), expression(e), watcher(w), errorString(0) { }
+ : engine(engine), expression(e), watcher(w), errorString(nullptr) { }
~QQmlPropertyCapture() {
Q_ASSERT(guards.isEmpty());
- Q_ASSERT(errorString == 0);
+ Q_ASSERT(errorString == nullptr);
}
enum Duration {
@@ -217,7 +217,7 @@ public:
};
QQmlJavaScriptExpression::DeleteWatcher::DeleteWatcher(QQmlJavaScriptExpression *e)
-: _c(0), _w(0), _s(e)
+: _c(nullptr), _w(nullptr), _s(e)
{
if (e->m_scopeObject.isT1()) {
_w = &_s;
@@ -231,14 +231,14 @@ QQmlJavaScriptExpression::DeleteWatcher::DeleteWatcher(QQmlJavaScriptExpression
QQmlJavaScriptExpression::DeleteWatcher::~DeleteWatcher()
{
- Q_ASSERT(*_w == 0 || (*_w == _s && _s->m_scopeObject.isT2()));
+ Q_ASSERT(*_w == nullptr || (*_w == _s && _s->m_scopeObject.isT2()));
if (*_w && _s->m_scopeObject.asT2() == this)
_s->m_scopeObject = _c;
}
bool QQmlJavaScriptExpression::DeleteWatcher::wasDeleted() const
{
- return *_w == 0;
+ return *_w == nullptr;
}
bool QQmlJavaScriptExpression::notifyOnValueChanged() const
@@ -272,12 +272,12 @@ inline void QQmlJavaScriptExpression::clearError()
{
if (m_error)
delete m_error;
- m_error = 0;
+ m_error = nullptr;
}
QQmlJavaScriptExpressionGuard::QQmlJavaScriptExpressionGuard(QQmlJavaScriptExpression *e)
: QQmlNotifierEndpoint(QQmlNotifierEndpoint::QQmlJavaScriptExpressionGuard),
- expression(e), next(0)
+ expression(e), next(nullptr)
{
}
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index 71be2e82a3..ac6e3695fe 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -55,7 +55,7 @@ QQmlListReference QQmlListReferencePrivate::init(const QQmlListProperty<QObject>
if (!prop.object) return rv;
- QQmlEnginePrivate *p = engine?QQmlEnginePrivate::get(engine):0;
+ QQmlEnginePrivate *p = engine?QQmlEnginePrivate::get(engine):nullptr;
int listType = p?p->listType(propType):QQmlMetaType::listType(propType);
if (listType == -1) return rv;
@@ -117,7 +117,7 @@ The \l {Qt Quick 1} version of this class is named QDeclarativeListReference.
Constructs an invalid instance.
*/
QQmlListReference::QQmlListReference()
-: d(0)
+: d(nullptr)
{
}
@@ -131,17 +131,17 @@ Passing \a engine is required to access some QML created list properties. If in
is available, pass it.
*/
QQmlListReference::QQmlListReference(QObject *object, const char *property, QQmlEngine *engine)
-: d(0)
+: d(nullptr)
{
if (!object || !property) return;
QQmlPropertyData local;
QQmlPropertyData *data =
- QQmlPropertyCache::property(engine, object, QLatin1String(property), 0, local);
+ QQmlPropertyCache::property(engine, object, QLatin1String(property), nullptr, local);
if (!data || !data->isQList()) return;
- QQmlEnginePrivate *p = engine?QQmlEnginePrivate::get(engine):0;
+ QQmlEnginePrivate *p = engine?QQmlEnginePrivate::get(engine):nullptr;
int listType = p?p->listType(data->propType()):QQmlMetaType::listType(data->propType());
if (listType == -1) return;
@@ -151,7 +151,7 @@ QQmlListReference::QQmlListReference(QObject *object, const char *property, QQml
d->elementType = p ? p->rawMetaObjectForType(listType) : QQmlMetaType::qmlType(listType).baseMetaObject();
d->propertyType = data->propType();
- void *args[] = { &d->property, 0 };
+ void *args[] = { &d->property, nullptr };
QMetaObject::metacall(object, QMetaObject::ReadProperty, data->coreIndex(), args);
}
@@ -191,7 +191,7 @@ Returns the list property's object. Returns 0 if the reference is invalid.
QObject *QQmlListReference::object() const
{
if (isValid()) return d->object;
- else return 0;
+ else return nullptr;
}
/*!
@@ -204,7 +204,7 @@ to a list.
const QMetaObject *QQmlListReference::listElementType() const
{
if (isValid()) return d->elementType.metaObject();
- else return 0;
+ else return nullptr;
}
/*!
@@ -301,7 +301,7 @@ Returns the list element at \a index, or 0 if the operation failed.
*/
QObject *QQmlListReference::at(int index) const
{
- if (!canAt()) return 0;
+ if (!canAt()) return nullptr;
return d->property.at(&d->property, index);
}
@@ -374,12 +374,12 @@ The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty.
*/
/*!
-\fn QQmlListProperty::QQmlListProperty()
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty()
\internal
*/
/*!
-\fn QQmlListProperty::QQmlListProperty(QObject *object, QList<T *> &list)
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, QList<T *> &list)
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
@@ -391,7 +391,7 @@ can be very useful while prototyping.
*/
/*!
-\fn QQmlListProperty::QQmlListProperty(QObject *object, void *data,
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, void *data,
CountFunction count, AtFunction at)
Construct a readonly QQmlListProperty from a set of operation functions
@@ -401,7 +401,7 @@ remains valid while \a object exists.
*/
/*!
-\fn QQmlListProperty::QQmlListProperty(QObject *object, void *data, AppendFunction append,
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, void *data, AppendFunction append,
CountFunction count, AtFunction at,
ClearFunction clear)
@@ -432,7 +432,7 @@ Return the number of elements in the list \a property.
*/
/*!
-\fn bool QQmlListProperty::operator==(const QQmlListProperty &other) const
+\fn template<typename T> bool QQmlListProperty<T>::operator==(const QQmlListProperty &other) const
Returns true if this QQmlListProperty is equal to \a other, otherwise false.
*/
diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h
index 4c6ae0cb8f..90ec57c911 100644
--- a/src/qml/qml/qqmllist.h
+++ b/src/qml/qml/qqmllist.h
@@ -61,20 +61,15 @@ public:
typedef void (*ClearFunction)(QQmlListProperty<T> *);
QQmlListProperty()
- : object(nullptr),
- data(nullptr),
- append(nullptr),
+ : append(nullptr),
count(nullptr),
at(nullptr),
- clear(nullptr),
- dummy1(nullptr),
- dummy2(nullptr)
+ clear(nullptr)
{}
QQmlListProperty(QObject *o, QList<T *> &list)
: object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
- clear(qlist_clear),
- dummy1(nullptr),
- dummy2(nullptr)
+ clear(qlist_clear)
+
{}
QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t,
ClearFunction r )
@@ -83,18 +78,15 @@ public:
append(a),
count(c),
at(t),
- clear(r),
- dummy1(nullptr),
- dummy2(nullptr)
+ clear(r)
+
{}
QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction t)
: object(o),
data(d),
append(nullptr),
count(c), at(t),
- clear(nullptr),
- dummy1(nullptr),
- dummy2(nullptr)
+ clear(nullptr)
{}
bool operator==(const QQmlListProperty &o) const {
return object == o.object &&
@@ -105,8 +97,8 @@ public:
clear == o.clear;
}
- QObject *object;
- void *data;
+ QObject *object = nullptr;
+ void *data = nullptr;
AppendFunction append;
@@ -115,8 +107,8 @@ public:
ClearFunction clear;
- void *dummy1;
- void *dummy2;
+ void *dummy1 = nullptr;
+ void *dummy2 = nullptr;
private:
static void qlist_append(QQmlListProperty *p, T *v) {
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index b4be83a156..3fbe3df2ab 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -77,7 +77,7 @@ ReturnedValue QmlListWrapper::create(ExecutionEngine *engine, QObject *object, i
Scoped<QmlListWrapper> r(scope, engine->memoryManager->allocObject<QmlListWrapper>());
r->d()->object = object;
r->d()->propertyType = propType;
- void *args[] = { &r->d()->property(), 0 };
+ void *args[] = { &r->d()->property(), nullptr };
QMetaObject::metacall(object, QMetaObject::ReadProperty, propId, args);
return r.asReturnedValue();
}
@@ -151,7 +151,7 @@ bool QmlListWrapper::put(Managed *m, String *name, const Value &value)
void QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
{
- name->setM(0);
+ name->setM(nullptr);
*index = UINT_MAX;
Q_ASSERT(m->as<QmlListWrapper>());
QmlListWrapper *w = static_cast<QmlListWrapper *>(m);
@@ -171,10 +171,10 @@ void PropertyListPrototype::init(ExecutionEngine *)
defineDefaultProperty(QStringLiteral("push"), method_push, 1);
}
-ReturnedValue PropertyListPrototype::method_push(const BuiltinFunction *b, CallData *callData)
+ReturnedValue PropertyListPrototype::method_push(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
QmlListWrapper *w = instance->as<QmlListWrapper>();
@@ -184,9 +184,9 @@ ReturnedValue PropertyListPrototype::method_push(const BuiltinFunction *b, CallD
THROW_GENERIC_ERROR("List doesn't define an Append function");
QV4::ScopedObject so(scope);
- for (int i = 0, ei = callData->argc(); i < ei; ++i)
+ for (int i = 0, ei = argc; i < ei; ++i)
{
- so = callData->args[i].toObject(scope.engine);
+ so = argv[i].toObject(scope.engine);
if (QV4::QObjectWrapper *wrapper = so->as<QV4::QObjectWrapper>())
w->d()->property().append(&w->d()->property(), wrapper->object() );
}
diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h
index 0b53395d2b..e02831c8d1 100644
--- a/src/qml/qml/qqmllistwrapper_p.h
+++ b/src/qml/qml/qqmllistwrapper_p.h
@@ -103,7 +103,7 @@ struct PropertyListPrototype : Object
{
void init(ExecutionEngine *engine);
- static ReturnedValue method_push(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_push(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
}
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 3f2a373966..2a5c58b47b 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -86,37 +86,37 @@ void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine)
engine->dateCtor()->defineDefaultProperty(QStringLiteral("timeZoneUpdated"), method_timeZoneUpdated);
}
-ReturnedValue QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlDateExtension::method_toLocaleString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
Scope scope(b);
- if (callData->argc() > 2)
- return QV4::DatePrototype::method_toLocaleString(b, &callData->thisObject, callData->args, callData->argc());
+ if (argc > 2)
+ return QV4::DatePrototype::method_toLocaleString(b, thisObject, argv, argc);
- QV4::DateObject *date = callData->thisObject.as<DateObject>();
+ const QV4::DateObject *date = thisObject->as<DateObject>();
if (!date)
- return QV4::DatePrototype::method_toLocaleString(b, &callData->thisObject, callData->args, callData->argc());
+ return QV4::DatePrototype::method_toLocaleString(b, thisObject, argv, argc);
QDateTime dt = date->toQDateTime();
- if (callData->argc() == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(dt)));
}
- if (!isLocaleObject(callData->args[0]))
- return QV4::DatePrototype::method_toLocaleString(b, &callData->thisObject, callData->args, callData->argc()); // Use the default Date toLocaleString()
+ if (!isLocaleObject(argv[0]))
+ return QV4::DatePrototype::method_toLocaleString(b, thisObject, argv, argc); // Use the default Date toLocaleString()
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedDt;
- if (callData->argc() == 2) {
- if (String *s = callData->args[1].stringValue()) {
+ if (argc == 2) {
+ if (String *s = argv[1].stringValue()) {
QString format = s->toQString();
formattedDt = r->d()->locale->toString(dt, format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].toNumber();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDt = r->d()->locale->toString(dt, format);
} else {
@@ -129,38 +129,38 @@ ReturnedValue QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b,
RETURN_RESULT(scope.engine->newString(formattedDt));
}
-ReturnedValue QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlDateExtension::method_toLocaleTimeString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
Scope scope(b);
- if (callData->argc() > 2)
- return QV4::DatePrototype::method_toLocaleTimeString(b, &callData->thisObject, callData->args, callData->argc());
+ if (argc > 2)
+ return QV4::DatePrototype::method_toLocaleTimeString(b, thisObject, argv, argc);
- QV4::DateObject *date = callData->thisObject.as<DateObject>();
+ const QV4::DateObject *date = thisObject->as<DateObject>();
if (!date)
- return QV4::DatePrototype::method_toLocaleTimeString(b, &callData->thisObject, callData->args, callData->argc());
+ return QV4::DatePrototype::method_toLocaleTimeString(b, thisObject, argv, argc);
QDateTime dt = date->toQDateTime();
QTime time = dt.time();
- if (callData->argc() == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(time)));
}
- if (!isLocaleObject(callData->args[0]))
- return QV4::DatePrototype::method_toLocaleTimeString(b, &callData->thisObject, callData->args, callData->argc()); // Use the default Date toLocaleTimeString()
+ if (!isLocaleObject(argv[0]))
+ return QV4::DatePrototype::method_toLocaleTimeString(b, thisObject, argv, argc); // Use the default Date toLocaleTimeString()
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedTime;
- if (callData->argc() == 2) {
- if (String *s = callData->args[1].stringValue()) {
+ if (argc == 2) {
+ if (String *s = argv[1].stringValue()) {
QString format = s->toQString();
formattedTime = r->d()->locale->toString(time, format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].toNumber();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedTime = r->d()->locale->toString(time, format);
} else {
@@ -173,38 +173,38 @@ ReturnedValue QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction
RETURN_RESULT(scope.engine->newString(formattedTime));
}
-ReturnedValue QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlDateExtension::method_toLocaleDateString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
Scope scope(b);
- if (callData->argc() > 2)
- return QV4::DatePrototype::method_toLocaleDateString(b, &callData->thisObject, callData->args, callData->argc());
+ if (argc > 2)
+ return QV4::DatePrototype::method_toLocaleDateString(b, thisObject, argv, argc);
- QV4::DateObject *dateObj = callData->thisObject.as<DateObject>();
+ const QV4::DateObject *dateObj = thisObject->as<DateObject>();
if (!dateObj)
- return QV4::DatePrototype::method_toLocaleDateString(b, &callData->thisObject, callData->args, callData->argc());
+ return QV4::DatePrototype::method_toLocaleDateString(b, thisObject, argv, argc);
QDateTime dt = dateObj->toQDateTime();
QDate date = dt.date();
- if (callData->argc() == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(date)));
}
- if (!isLocaleObject(callData->args[0]))
- return QV4::DatePrototype::method_toLocaleDateString(b, &callData->thisObject, callData->args, callData->argc()); // Use the default Date toLocaleDateString()
+ if (!isLocaleObject(argv[0]))
+ return QV4::DatePrototype::method_toLocaleDateString(b, thisObject, argv, argc); // Use the default Date toLocaleDateString()
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedDate;
- if (callData->argc() == 2) {
- if (String *s = callData->args[1].stringValue()) {
+ if (argc == 2) {
+ if (String *s = argv[1].stringValue()) {
QString format = s->toQString();
formattedDate = r->d()->locale->toString(date, format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].toNumber();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDate = r->d()->locale->toString(date, format);
} else {
@@ -217,12 +217,12 @@ ReturnedValue QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction
RETURN_RESULT(scope.engine->newString(formattedDate));
}
-ReturnedValue QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlDateExtension::method_fromLocaleString(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
QV4::ExecutionEngine * const engine = scope.engine;
- if (callData->argc() == 1) {
- if (String *s = callData->args[0].stringValue()) {
+ if (argc == 1) {
+ if (String *s = argv[0].stringValue()) {
QLocale locale;
QString dateString = s->toQString();
QDateTime dt = locale.toDateTime(dateString);
@@ -230,20 +230,20 @@ ReturnedValue QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *
}
}
- if (callData->argc() < 1 || callData->argc() > 3 || !isLocaleObject(callData->args[0]))
+ if (argc < 1 || argc > 3 || !isLocaleObject(argv[0]))
THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDateTime dt;
- QString dateString = callData->args[1].toQStringNoThrow();
- if (callData->argc() == 3) {
- if (String *s = callData->args[2].stringValue()) {
+ QString dateString = argv[1].toQStringNoThrow();
+ if (argc == 3) {
+ if (String *s = argv[2].stringValue()) {
QString format = s->toQString();
dt = r->d()->locale->toDateTime(dateString, format);
- } else if (callData->args[2].isNumber()) {
- quint32 intFormat = callData->args[2].toNumber();
+ } else if (argv[2].isNumber()) {
+ quint32 intFormat = argv[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale->toDateTime(dateString, format);
} else {
@@ -256,13 +256,13 @@ ReturnedValue QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *
RETURN_RESULT(engine->newDateObject(dt));
}
-ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
QV4::ExecutionEngine * const engine = scope.engine;
- if (callData->argc() == 1) {
- if (String *s = callData->args[0].stringValue()) {
+ if (argc == 1) {
+ if (String *s = argv[0].stringValue()) {
QLocale locale;
QString timeString = s->toQString();
QTime time = locale.toTime(timeString);
@@ -272,20 +272,20 @@ ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFuncti
}
}
- if (callData->argc() < 1 || callData->argc() > 3 || !isLocaleObject(callData->args[0]))
+ if (argc < 1 || argc > 3 || !isLocaleObject(argv[0]))
THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QTime tm;
- QString dateString = callData->args[1].toQStringNoThrow();
- if (callData->argc() == 3) {
- if (String *s = callData->args[2].stringValue()) {
+ QString dateString = argv[1].toQStringNoThrow();
+ if (argc == 3) {
+ if (String *s = argv[2].stringValue()) {
QString format = s->toQString();
tm = r->d()->locale->toTime(dateString, format);
- } else if (callData->args[2].isNumber()) {
- quint32 intFormat = callData->args[2].toNumber();
+ } else if (argv[2].isNumber()) {
+ quint32 intFormat = argv[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
tm = r->d()->locale->toTime(dateString, format);
} else {
@@ -304,13 +304,13 @@ ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFuncti
RETURN_RESULT(engine->newDateObject(dt));
}
-ReturnedValue QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlDateExtension::method_fromLocaleDateString(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
QV4::ExecutionEngine * const engine = scope.engine;
- if (callData->argc() == 1) {
- if (String *s = callData->args[0].stringValue()) {
+ if (argc == 1) {
+ if (String *s = argv[0].stringValue()) {
QLocale locale;
QString dateString = s->toQString();
QDate date = locale.toDate(dateString);
@@ -318,20 +318,20 @@ ReturnedValue QQmlDateExtension::method_fromLocaleDateString(const BuiltinFuncti
}
}
- if (callData->argc() < 1 || callData->argc() > 3 || !isLocaleObject(callData->args[0]))
+ if (argc < 1 || argc > 3 || !isLocaleObject(argv[0]))
THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDate dt;
- QString dateString = callData->args[1].toQStringNoThrow();
- if (callData->argc() == 3) {
- if (String *s = callData->args[2].stringValue()) {
+ QString dateString = argv[1].toQStringNoThrow();
+ if (argc == 3) {
+ if (String *s = argv[2].stringValue()) {
QString format = s->toQString();
dt = r->d()->locale->toDate(dateString, format);
- } else if (callData->args[2].isNumber()) {
- quint32 intFormat = callData->args[2].toNumber();
+ } else if (argv[2].isNumber()) {
+ quint32 intFormat = argv[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale->toDate(dateString, format);
} else {
@@ -344,10 +344,10 @@ ReturnedValue QQmlDateExtension::method_fromLocaleDateString(const BuiltinFuncti
RETURN_RESULT(engine->newDateObject(QDateTime(dt)));
}
-ReturnedValue QQmlDateExtension::method_timeZoneUpdated(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlDateExtension::method_timeZoneUpdated(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 0)
+ if (argc != 0)
THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments");
QV4::DatePrototype::timezoneUpdated();
@@ -365,92 +365,92 @@ void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine)
engine->numberCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
}
-QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(const BuiltinFunction *b, CallData *callData)
+QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() > 3)
+ if (argc > 3)
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- double number = callData->thisObject.toNumber();
+ double number = thisObject->toNumber();
- if (callData->argc() == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(number)));
}
- if (!isLocaleObject(callData->args[0]))
- return QV4::NumberPrototype::method_toLocaleString(b, &callData->thisObject, callData->args, callData->argc()); // Use the default Number toLocaleString()
+ if (!isLocaleObject(argv[0]))
+ return QV4::NumberPrototype::method_toLocaleString(b, thisObject, argv, argc); // Use the default Number toLocaleString()
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
quint16 format = 'f';
- if (callData->argc() > 1) {
- if (!callData->args[1].isString())
+ if (argc > 1) {
+ if (!argv[1].isString())
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- QString fs = callData->args[1].toQString();
+ QString fs = argv[1].toQString();
if (fs.length())
format = fs.at(0).unicode();
}
int prec = 2;
- if (callData->argc() > 2) {
- if (!callData->args[2].isNumber())
+ if (argc > 2) {
+ if (!argv[2].isNumber())
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- prec = callData->args[2].toInt32();
+ prec = argv[2].toInt32();
}
RETURN_RESULT(scope.engine->newString(r->d()->locale->toString(number, (char)format, prec)));
}
-ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() > 2)
+ if (argc > 2)
THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
- double number = callData->thisObject.toNumber();
+ double number = thisObject->toNumber();
- if (callData->argc() == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(number)));
}
- if (!isLocaleObject(callData->args[0]))
+ if (!isLocaleObject(argv[0]))
THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QString symbol;
- if (callData->argc() > 1) {
- if (!callData->args[1].isString())
+ if (argc > 1) {
+ if (!argv[1].isString())
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- symbol = callData->args[1].toQStringNoThrow();
+ symbol = argv[1].toQStringNoThrow();
}
RETURN_RESULT(scope.engine->newString(r->d()->locale->toCurrencyString(number, symbol)));
}
-ReturnedValue QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlNumberExtension::method_fromLocaleString(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 1 || callData->argc() > 2)
+ if (argc < 1 || argc > 2)
THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
int numberIdx = 0;
QLocale locale;
- if (callData->argc() == 2) {
- if (!isLocaleObject(callData->args[0]))
+ if (argc == 2) {
+ if (!isLocaleObject(argv[0]))
THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
locale = *r->d()->locale;
numberIdx = 1;
}
- QString ns = callData->args[numberIdx].toQString();
+ QString ns = argv[numberIdx].toQString();
if (!ns.length())
RETURN_RESULT(QV4::Encode(Q_QNAN));
@@ -466,10 +466,10 @@ ReturnedValue QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction
//--------------
// Locale object
-ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
- QLocale *locale = getThisLocale(scope, callData);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
return Encode::undefined();
int fdow = int(locale->firstDayOfWeek());
@@ -478,29 +478,29 @@ ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(const BuiltinFunction *b
RETURN_RESULT(fdow);
}
-ReturnedValue QQmlLocaleData::method_get_measurementSystem(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_measurementSystem(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
- QLocale *locale = getThisLocale(scope, callData);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
return Encode::undefined();
return QV4::Encode(locale->measurementSystem());
}
-ReturnedValue QQmlLocaleData::method_get_textDirection(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_textDirection(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
- QLocale *locale = getThisLocale(scope, callData);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
return Encode::undefined();
return QV4::Encode(locale->textDirection());
}
-ReturnedValue QQmlLocaleData::method_get_weekDays(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_weekDays(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
- QLocale *locale = getThisLocale(scope, callData);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
return Encode::undefined();
@@ -519,10 +519,10 @@ ReturnedValue QQmlLocaleData::method_get_weekDays(const BuiltinFunction *b, Call
return result.asReturnedValue();
}
-ReturnedValue QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_uiLanguages(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
- QLocale *locale = getThisLocale(scope, callData);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
return Encode::undefined();
@@ -538,19 +538,19 @@ ReturnedValue QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *b, C
return result.asReturnedValue();
}
-ReturnedValue QQmlLocaleData::method_currencySymbol(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlLocaleData::method_currencySymbol(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- QLocale *locale = getThisLocale(scope, callData);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
return Encode::undefined();
- if (callData->argc() > 1)
+ if (argc > 1)
THROW_ERROR("Locale: currencySymbol(): Invalid arguments");
QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol;
- if (callData->argc() == 1) {
- quint32 intFormat = callData->args[0].toNumber();
+ if (argc == 1) {
+ quint32 intFormat = argv[0].toNumber();
format = QLocale::CurrencySymbolFormat(intFormat);
}
@@ -558,16 +558,16 @@ ReturnedValue QQmlLocaleData::method_currencySymbol(const BuiltinFunction *b, Ca
}
#define LOCALE_FORMAT(FUNC) \
-ReturnedValue QQmlLocaleData::method_ ##FUNC (const BuiltinFunction *b, CallData *callData) { \
+ReturnedValue QQmlLocaleData::method_ ##FUNC (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { \
QV4::Scope scope(b); \
- QLocale *locale = getThisLocale(scope, callData); \
+ const QLocale *locale = getThisLocale(scope, thisObject); \
if (!locale) \
return Encode::undefined(); \
- if (callData->argc() > 1) \
+ if (argc > 1) \
THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
QLocale::FormatType format = QLocale::LongFormat;\
- if (callData->argc() == 1) { \
- quint32 intFormat = callData->args[0].toUInt32(); \
+ if (argc == 1) { \
+ quint32 intFormat = argv[0].toUInt32(); \
format = QLocale::FormatType(intFormat); \
} \
RETURN_RESULT(scope.engine->newString(locale-> FUNC (format))); \
@@ -579,21 +579,21 @@ LOCALE_FORMAT(dateFormat)
// +1 added to idx because JS is 0-based, whereas QLocale months begin at 1.
#define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \
-ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *b, CallData *callData) {\
+ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) {\
Scope scope(b); \
- QLocale *locale = getThisLocale(scope, callData); \
+ const QLocale *locale = getThisLocale(scope, thisObject); \
if (!locale) \
return Encode::undefined(); \
- if (callData->argc() < 1 || callData->argc() > 2) \
+ if (argc < 1 || argc > 2) \
THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
QLocale::FormatType enumFormat = QLocale::LongFormat; \
- int idx = callData->args[0].toInt32() + 1; \
+ int idx = argv[0].toInt32() + 1; \
if (idx < 1 || idx > 12) \
THROW_ERROR("Locale: Invalid month"); \
QString name; \
- if (callData->argc() == 2) { \
- if (callData->args[1].isNumber()) { \
- quint32 intFormat = callData->args[1].toUInt32(); \
+ if (argc == 2) { \
+ if (argv[1].isNumber()) { \
+ quint32 intFormat = argv[1].toUInt32(); \
QLocale::FormatType format = QLocale::FormatType(intFormat); \
name = locale-> VARIABLE(idx, format); \
} else { \
@@ -607,22 +607,22 @@ ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *b, Cal
// 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date
#define LOCALE_FORMATTED_DAYNAME(VARIABLE) \
-ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *b, CallData *callData) {\
+ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) {\
Scope scope(b); \
- QLocale *locale = getThisLocale(scope, callData); \
+ const QLocale *locale = getThisLocale(scope, thisObject); \
if (!locale) \
return Encode::undefined(); \
- if (callData->argc() < 1 || callData->argc() > 2) \
+ if (argc < 1 || argc > 2) \
THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
QLocale::FormatType enumFormat = QLocale::LongFormat; \
- int idx = callData->args[0].toInt32(); \
+ int idx = argv[0].toInt32(); \
if (idx < 0 || idx > 7) \
THROW_ERROR("Locale: Invalid day"); \
if (idx == 0) idx = 7; \
QString name; \
- if (callData->argc() == 2) { \
- if (callData->args[1].isNumber()) { \
- quint32 intFormat = callData->args[1].toUInt32(); \
+ if (argc == 2) { \
+ if (argv[1].isNumber()) { \
+ quint32 intFormat = argv[1].toUInt32(); \
QLocale::FormatType format = QLocale::FormatType(intFormat); \
name = locale-> VARIABLE(idx, format); \
} else { \
@@ -640,10 +640,10 @@ LOCALE_FORMATTED_DAYNAME(dayName)
LOCALE_FORMATTED_DAYNAME(standaloneDayName)
#define LOCALE_STRING_PROPERTY(VARIABLE) \
-ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (const BuiltinFunction *b, CallData *callData) \
+ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
{ \
Scope scope(b); \
- QLocale *locale = getThisLocale(scope, callData); \
+ const QLocale *locale = getThisLocale(scope, thisObject); \
if (!locale) \
return Encode::undefined(); \
RETURN_RESULT(scope.engine->newString(locale-> VARIABLE()));\
@@ -684,23 +684,23 @@ QV4LocaleDataDeletable::QV4LocaleDataDeletable(QV4::ExecutionEngine *engine)
o->defineDefaultProperty(QStringLiteral("monthName"), QQmlLocaleData::method_monthName, 0);
o->defineDefaultProperty(QStringLiteral("currencySymbol"), QQmlLocaleData::method_currencySymbol, 0);
o->defineDefaultProperty(QStringLiteral("dateTimeFormat"), QQmlLocaleData::method_dateTimeFormat, 0);
- o->defineAccessorProperty(QStringLiteral("name"), QQmlLocaleData::method_get_name, 0);
- o->defineAccessorProperty(QStringLiteral("positiveSign"), QQmlLocaleData::method_get_positiveSign, 0);
- o->defineAccessorProperty(QStringLiteral("uiLanguages"), QQmlLocaleData::method_get_uiLanguages, 0);
- o->defineAccessorProperty(QStringLiteral("firstDayOfWeek"), QQmlLocaleData::method_get_firstDayOfWeek, 0);
- o->defineAccessorProperty(QStringLiteral("pmText"), QQmlLocaleData::method_get_pmText, 0);
- o->defineAccessorProperty(QStringLiteral("percent"), QQmlLocaleData::method_get_percent, 0);
- o->defineAccessorProperty(QStringLiteral("textDirection"), QQmlLocaleData::method_get_textDirection, 0);
- o->defineAccessorProperty(QStringLiteral("weekDays"), QQmlLocaleData::method_get_weekDays, 0);
- o->defineAccessorProperty(QStringLiteral("negativeSign"), QQmlLocaleData::method_get_negativeSign, 0);
- o->defineAccessorProperty(QStringLiteral("groupSeparator"), QQmlLocaleData::method_get_groupSeparator, 0);
- o->defineAccessorProperty(QStringLiteral("decimalPoint"), QQmlLocaleData::method_get_decimalPoint, 0);
- o->defineAccessorProperty(QStringLiteral("nativeLanguageName"), QQmlLocaleData::method_get_nativeLanguageName, 0);
- o->defineAccessorProperty(QStringLiteral("nativeCountryName"), QQmlLocaleData::method_get_nativeCountryName, 0);
- o->defineAccessorProperty(QStringLiteral("zeroDigit"), QQmlLocaleData::method_get_zeroDigit, 0);
- o->defineAccessorProperty(QStringLiteral("amText"), QQmlLocaleData::method_get_amText, 0);
- o->defineAccessorProperty(QStringLiteral("measurementSystem"), QQmlLocaleData::method_get_measurementSystem, 0);
- o->defineAccessorProperty(QStringLiteral("exponential"), QQmlLocaleData::method_get_exponential, 0);
+ o->defineAccessorProperty(QStringLiteral("name"), QQmlLocaleData::method_get_name, nullptr);
+ o->defineAccessorProperty(QStringLiteral("positiveSign"), QQmlLocaleData::method_get_positiveSign, nullptr);
+ o->defineAccessorProperty(QStringLiteral("uiLanguages"), QQmlLocaleData::method_get_uiLanguages, nullptr);
+ o->defineAccessorProperty(QStringLiteral("firstDayOfWeek"), QQmlLocaleData::method_get_firstDayOfWeek, nullptr);
+ o->defineAccessorProperty(QStringLiteral("pmText"), QQmlLocaleData::method_get_pmText, nullptr);
+ o->defineAccessorProperty(QStringLiteral("percent"), QQmlLocaleData::method_get_percent, nullptr);
+ o->defineAccessorProperty(QStringLiteral("textDirection"), QQmlLocaleData::method_get_textDirection, nullptr);
+ o->defineAccessorProperty(QStringLiteral("weekDays"), QQmlLocaleData::method_get_weekDays, nullptr);
+ o->defineAccessorProperty(QStringLiteral("negativeSign"), QQmlLocaleData::method_get_negativeSign, nullptr);
+ o->defineAccessorProperty(QStringLiteral("groupSeparator"), QQmlLocaleData::method_get_groupSeparator, nullptr);
+ o->defineAccessorProperty(QStringLiteral("decimalPoint"), QQmlLocaleData::method_get_decimalPoint, nullptr);
+ o->defineAccessorProperty(QStringLiteral("nativeLanguageName"), QQmlLocaleData::method_get_nativeLanguageName, nullptr);
+ o->defineAccessorProperty(QStringLiteral("nativeCountryName"), QQmlLocaleData::method_get_nativeCountryName, nullptr);
+ o->defineAccessorProperty(QStringLiteral("zeroDigit"), QQmlLocaleData::method_get_zeroDigit, nullptr);
+ o->defineAccessorProperty(QStringLiteral("amText"), QQmlLocaleData::method_get_amText, nullptr);
+ o->defineAccessorProperty(QStringLiteral("measurementSystem"), QQmlLocaleData::method_get_measurementSystem, nullptr);
+ o->defineAccessorProperty(QStringLiteral("exponential"), QQmlLocaleData::method_get_exponential, nullptr);
prototype.set(engine, o);
}
@@ -837,16 +837,16 @@ void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine)
engine->stringPrototype()->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare);
}
-ReturnedValue QQmlLocale::method_localeCompare(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- if (callData->argc() != 1 || (!callData->args[0].isString() && !callData->args[0].as<StringObject>()))
- return QV4::StringPrototype::method_localeCompare(b, &callData->thisObject, callData->args, callData->argc());
+ if (argc != 1 || (!argv[0].isString() && !argv[0].as<StringObject>()))
+ return QV4::StringPrototype::method_localeCompare(b, thisObject, argv, argc);
- if (!callData->thisObject.isString() && !callData->thisObject.as<StringObject>())
- return QV4::StringPrototype::method_localeCompare(b, &callData->thisObject, callData->args, callData->argc());
+ if (!thisObject->isString() && !thisObject->as<StringObject>())
+ return QV4::StringPrototype::method_localeCompare(b, thisObject, argv, argc);
- QString thisString = callData->thisObject.toQStringNoThrow();
- QString thatString = callData->args[0].toQStringNoThrow();
+ QString thisString = thisObject->toQStringNoThrow();
+ QString thatString = argv[0].toQStringNoThrow();
return QV4::Encode(QString::localeAwareCompare(thisString, thatString));
}
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index a81fe07b8e..8341b1f555 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -67,13 +67,13 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static QV4::ReturnedValue method_toLocaleString(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_toLocaleTimeString(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_toLocaleDateString(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_fromLocaleString(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_fromLocaleTimeString(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_fromLocaleDateString(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_timeZoneUpdated(const QV4::BuiltinFunction *, QV4::CallData *callData);
+ static QV4::ReturnedValue method_toLocaleString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_toLocaleTimeString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_toLocaleDateString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fromLocaleString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fromLocaleTimeString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fromLocaleDateString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_timeZoneUpdated(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
@@ -83,9 +83,9 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static QV4::ReturnedValue method_toLocaleString(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_fromLocaleString(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_toLocaleCurrencyString(const QV4::BuiltinFunction *, QV4::CallData *callData);
+ static QV4::ReturnedValue method_toLocaleString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fromLocaleString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_toLocaleCurrencyString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
@@ -135,7 +135,7 @@ public:
private:
QQmlLocale();
- static QV4::ReturnedValue method_localeCompare(const QV4::BuiltinFunction *, QV4::CallData *callData);
+ static QV4::ReturnedValue method_localeCompare(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
namespace QV4 {
@@ -158,43 +158,43 @@ struct QQmlLocaleData : public QV4::Object
V4_OBJECT2(QQmlLocaleData, Object)
V4_NEEDS_DESTROY
- static QLocale *getThisLocale(QV4::Scope &scope, QV4::CallData *callData) {
- QV4::Object *o = callData->thisObject.as<Object>();
- QQmlLocaleData *thisObject = o ? o->as<QQmlLocaleData>() : 0;
- if (!thisObject) {
+ static QLocale *getThisLocale(QV4::Scope &scope, const QV4::Value *thisObject) {
+ const QV4::Object *o = thisObject->as<Object>();
+ const QQmlLocaleData *data = o ? o->as<QQmlLocaleData>() : nullptr;
+ if (!data) {
scope.engine->throwTypeError();
- return 0;
+ return nullptr;
}
- return thisObject->d()->locale;
+ return data->d()->locale;
}
- static QV4::ReturnedValue method_currencySymbol(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_dateTimeFormat(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_timeFormat(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_dateFormat(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_monthName(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_standaloneMonthName(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_dayName(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_standaloneDayName(const QV4::BuiltinFunction *, QV4::CallData *callData);
-
- static QV4::ReturnedValue method_get_firstDayOfWeek(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_measurementSystem(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_textDirection(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_weekDays(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_uiLanguages(const QV4::BuiltinFunction *, QV4::CallData *callData);
-
- static QV4::ReturnedValue method_get_name(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_nativeLanguageName(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_nativeCountryName(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_decimalPoint(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_groupSeparator(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_percent(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_zeroDigit(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_negativeSign(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_positiveSign(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_exponential(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_amText(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue method_get_pmText(const QV4::BuiltinFunction *, QV4::CallData *callData);
+ static QV4::ReturnedValue method_currencySymbol(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_dateTimeFormat(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_timeFormat(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_dateFormat(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_monthName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_standaloneMonthName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_dayName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_standaloneDayName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+
+ static QV4::ReturnedValue method_get_firstDayOfWeek(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_measurementSystem(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_textDirection(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_weekDays(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_uiLanguages(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+
+ static QV4::ReturnedValue method_get_name(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_nativeLanguageName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_nativeCountryName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_decimalPoint(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_groupSeparator(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_percent(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_zeroDigit(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_negativeSign(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_positiveSign(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_exponential(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_amText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_pmText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
}
diff --git a/src/qml/qml/qqmlloggingcategory_p.h b/src/qml/qml/qqmlloggingcategory_p.h
index 2b7f2f5b53..544db1fe33 100644
--- a/src/qml/qml/qqmlloggingcategory_p.h
+++ b/src/qml/qml/qqmlloggingcategory_p.h
@@ -67,7 +67,7 @@ class QQmlLoggingCategory : public QObject, public QQmlParserStatus
Q_PROPERTY(QString name READ name WRITE setName)
public:
- QQmlLoggingCategory(QObject *parent = 0);
+ QQmlLoggingCategory(QObject *parent = nullptr);
virtual ~QQmlLoggingCategory();
QString name() const;
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 5836c85666..7754f0fddc 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -170,7 +170,7 @@ public:
~QQmlTypePrivate();
void init() const;
- void initEnums(const QQmlPropertyCache *cache = 0) const;
+ void initEnums(const QQmlPropertyCache *cache = nullptr) const;
void insertEnums(const QMetaObject *metaObject) const;
void insertEnumsFromPropertyCache(const QQmlPropertyCache *cache) const;
@@ -272,8 +272,10 @@ void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
QQmlData::ensurePropertyCache(e, o);
} else if (!url.isEmpty() && !qobjectApi(e)) {
QQmlComponent component(e, url, QQmlComponent::PreferSynchronous);
- QObject *o = component.create();
+ QObject *o = component.beginCreate(e->rootContext());
setQObjectApi(e, o);
+ if (o)
+ component.completeCreate();
}
}
@@ -313,31 +315,31 @@ QJSValue QQmlType::SingletonInstanceInfo::scriptApi(QQmlEngine *e) const
QHash<const QMetaObject *, int> QQmlTypePrivate::attachedPropertyIds;
QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
-: refCount(1), regType(type), iid(0), typeId(0), listId(0), revision(0),
- containsRevisionedAttributes(false), baseMetaObject(0),
+: refCount(1), regType(type), iid(nullptr), typeId(0), listId(0), revision(0),
+ containsRevisionedAttributes(false), baseMetaObject(nullptr),
index(-1), isSetup(false), isEnumSetup(false), haveSuperType(false)
{
switch (type) {
case QQmlType::CppType:
extraData.cd = new QQmlCppTypeData;
extraData.cd->allocationSize = 0;
- extraData.cd->newFunc = 0;
+ extraData.cd->newFunc = nullptr;
extraData.cd->parserStatusCast = -1;
- extraData.cd->extFunc = 0;
- extraData.cd->extMetaObject = 0;
- extraData.cd->customParser = 0;
- extraData.cd->attachedPropertiesFunc = 0;
- extraData.cd->attachedPropertiesType = 0;
+ extraData.cd->extFunc = nullptr;
+ extraData.cd->extMetaObject = nullptr;
+ extraData.cd->customParser = nullptr;
+ extraData.cd->attachedPropertiesFunc = nullptr;
+ extraData.cd->attachedPropertiesType = nullptr;
extraData.cd->propertyValueSourceCast = -1;
extraData.cd->propertyValueInterceptorCast = -1;
break;
case QQmlType::SingletonType:
case QQmlType::CompositeSingletonType:
extraData.sd = new QQmlSingletonTypeData;
- extraData.sd->singletonInstanceInfo = 0;
+ extraData.sd->singletonInstanceInfo = nullptr;
break;
case QQmlType::InterfaceType:
- extraData.cd = 0;
+ extraData.cd = nullptr;
break;
case QQmlType::CompositeType:
extraData.fd = new QQmlCompositeTypeData;
@@ -404,7 +406,7 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm
d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi;
d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
d->extraData.sd->singletonInstanceInfo->instanceMetaObject
- = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : 0;
+ = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : nullptr;
}
QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQmlPrivate::RegisterCompositeSingletonType &type)
@@ -476,7 +478,7 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm
}
QQmlType::QQmlType()
- : d(0)
+ : d(nullptr)
{
}
@@ -584,10 +586,10 @@ QQmlPropertyCache *QQmlType::compositePropertyCache(QQmlEnginePrivate *engine) c
// similar logic to resolveCompositeBaseType
Q_ASSERT(isComposite());
if (!engine)
- return 0;
+ return nullptr;
QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl()), QQmlRefPointer<QQmlTypeData>::Adopt);
if (td.isNull() || !td->isComplete())
- return 0;
+ return nullptr;
QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit();
return compilationUnit->rootPropertyCache();
}
@@ -737,7 +739,7 @@ void QQmlTypePrivate::init() const
// Check for revisioned details
{
- const QMetaObject *mo = 0;
+ const QMetaObject *mo = nullptr;
if (metaObjects.isEmpty())
mo = baseMetaObject;
else
@@ -790,7 +792,7 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
QMetaEnum e = metaObject->enumerator(ii);
const bool isScoped = e.isScoped();
- QStringHash<int> *scoped = isScoped ? new QStringHash<int>() : 0;
+ QStringHash<int> *scoped = isScoped ? new QStringHash<int>() : nullptr;
for (int jj = 0; jj < e.keyCount(); ++jj) {
const QString key = QString::fromUtf8(e.key(jj));
@@ -886,7 +888,7 @@ QString QQmlType::qmlTypeName() const
QObject *QQmlType::create() const
{
if (!d || !isCreatable())
- return 0;
+ return nullptr;
d->init();
@@ -919,25 +921,25 @@ void QQmlType::create(QObject **out, void **memory, size_t additionalMemory) con
QQmlType::SingletonInstanceInfo *QQmlType::singletonInstanceInfo() const
{
if (!d)
- return 0;
+ return nullptr;
if (d->regType != SingletonType && d->regType != CompositeSingletonType)
- return 0;
+ return nullptr;
return d->extraData.sd->singletonInstanceInfo;
}
QQmlCustomParser *QQmlType::customParser() const
{
if (!d)
- return 0;
+ return nullptr;
if (d->regType != CppType)
- return 0;
+ return nullptr;
return d->extraData.cd->customParser;
}
QQmlType::CreateFunc QQmlType::createFunction() const
{
if (!d || d->regType != CppType)
- return 0;
+ return nullptr;
return d->extraData.cd->newFunc;
}
@@ -1002,7 +1004,7 @@ int QQmlType::qListTypeId() const
const QMetaObject *QQmlType::metaObject() const
{
if (!d)
- return 0;
+ return nullptr;
d->init();
if (d->metaObjects.isEmpty())
@@ -1014,7 +1016,7 @@ const QMetaObject *QQmlType::metaObject() const
const QMetaObject *QQmlType::baseMetaObject() const
{
- return d ? d->baseMetaObject : 0;
+ return d ? d->baseMetaObject : nullptr;
}
bool QQmlType::containsRevisionedAttributes() const
@@ -1034,7 +1036,7 @@ int QQmlType::metaObjectRevision() const
QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivate *engine) const
{
if (!d)
- return 0;
+ return nullptr;
if (d->regType == CppType)
return d->extraData.cd->attachedPropertiesFunc;
@@ -1047,7 +1049,7 @@ QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivat
const QMetaObject *QQmlType::attachedPropertiesType(QQmlEnginePrivate *engine) const
{
if (!d)
- return 0;
+ return nullptr;
if (d->regType == CppType)
return d->extraData.cd->attachedPropertiesType;
@@ -1099,7 +1101,7 @@ int QQmlType::propertyValueInterceptorCast() const
const char *QQmlType::interfaceIId() const
{
if (!d || d->regType != InterfaceType)
- return 0;
+ return nullptr;
return d->iid;
}
@@ -1123,7 +1125,7 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &name,
{
Q_ASSERT(ok);
if (d) {
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr;
*ok = true;
@@ -1142,7 +1144,7 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &name
{
Q_ASSERT(ok);
if (d) {
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr;
*ok = true;
@@ -1161,7 +1163,7 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool
{
Q_ASSERT(ok);
if (d) {
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr;
*ok = true;
d->initEnums(cache);
@@ -1179,7 +1181,7 @@ int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *name
{
Q_ASSERT(ok);
if (d) {
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr;
*ok = true;
d->initEnums(cache);
@@ -1197,7 +1199,7 @@ int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QString &name, bo
{
Q_ASSERT(ok);
if (d) {
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr;
*ok = true;
d->initEnums(cache);
@@ -1249,7 +1251,7 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scope
{
Q_ASSERT(ok);
if (d) {
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr;
*ok = true;
d->initEnums(cache);
@@ -1272,7 +1274,7 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &scope
{
Q_ASSERT(ok);
if (d) {
- const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr;
*ok = true;
d->initEnums(cache);
@@ -1338,7 +1340,7 @@ QQmlTypeModule::QQmlTypeModule()
QQmlTypeModule::~QQmlTypeModule()
{
- delete d; d = 0;
+ delete d; d = nullptr;
}
QString QQmlTypeModule::module() const
@@ -1437,7 +1439,7 @@ void QQmlTypeModule::walkCompositeSingletons(const std::function<void(const QQml
}
QQmlTypeModuleVersion::QQmlTypeModuleVersion()
-: m_module(0), m_minor(0)
+: m_module(nullptr), m_minor(0)
{
}
@@ -1564,6 +1566,12 @@ QString registrationTypeString(QQmlType::RegistrationType typeType)
bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, const char *uri, const QString &typeName, int majorVersion = -1)
{
if (!typeName.isEmpty()) {
+ if (typeName.at(0).isLower()) {
+ QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\"; type names must begin with an uppercase letter"));
+ data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName));
+ return false;
+ }
+
int typeNameLen = typeName.length();
for (int ii = 0; ii < typeNameLen; ++ii) {
if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == '_')) {
@@ -1577,15 +1585,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
if (uri && !typeName.isEmpty()) {
QString nameSpace = QString::fromUtf8(uri);
- if (!data->typeRegistrationNamespace.isEmpty()) {
- // We can only install types into the registered namespace
- if (nameSpace != data->typeRegistrationNamespace) {
- QString failure(QCoreApplication::translate("qmlRegisterType",
- "Cannot install %1 '%2' into unregistered namespace '%3'"));
- data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace));
- return false;
- }
- } else if (data->typeRegistrationNamespace != nameSpace) {
+ if (data->typeRegistrationNamespace.isEmpty() && !nameSpace.isEmpty()) {
// Is the target namespace protected against further registrations?
if (data->protectedNamespaces.contains(nameSpace)) {
QString failure(QCoreApplication::translate("qmlRegisterType",
@@ -1699,7 +1699,7 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe
bool fileImport = false;
if (*(type.uri) == '\0')
fileImport = true;
- if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? 0 : type.uri, typeName))
+ if (!checkRegistration(QQmlType::CompositeSingletonType, data, fileImport ? nullptr : type.uri, typeName))
return QQmlType();
QQmlType dtype(data, typeName, type);
@@ -1721,7 +1721,7 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit
bool fileImport = false;
if (*(type.uri) == '\0')
fileImport = true;
- if (!checkRegistration(QQmlType::CompositeType, data, fileImport?0:type.uri, typeName, type.versionMajor))
+ if (!checkRegistration(QQmlType::CompositeType, data, fileImport?nullptr:type.uri, typeName, type.versionMajor))
return QQmlType();
QQmlType dtype(data, typeName, type);
@@ -1745,13 +1745,13 @@ void QQmlMetaType::registerInternalCompositeType(QV4::CompiledData::CompilationU
QtMetaTypePrivate::QMetaTypeFunctionHelper<QObject*>::Construct,
sizeof(QObject*),
static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QObject*>::Flags),
- 0);
+ nullptr);
int lst_type = QMetaType::registerNormalizedType(lst,
QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Destruct,
QtMetaTypePrivate::QMetaTypeFunctionHelper<QQmlListProperty<QObject> >::Construct,
sizeof(QQmlListProperty<QObject>),
static_cast<QFlags<QMetaType::TypeFlag> >(QtPrivate::QMetaTypeTypeFlags<QQmlListProperty<QObject> >::Flags),
- static_cast<QMetaObject*>(0));
+ static_cast<QMetaObject*>(nullptr));
compilationUnit->metaTypeId = ptr_type;
compilationUnit->listMetaTypeId = lst_type;
@@ -1809,6 +1809,9 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
else
return -1;
+ if (!dtype.isValid())
+ return -1;
+
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *typeData = metaTypeData();
typeData->undeletableTypes.insert(dtype);
@@ -1961,7 +1964,7 @@ QObject *QQmlMetaType::toQObject(const QVariant &v, bool *ok)
{
if (!isQObject(v.userType())) {
if (ok) *ok = false;
- return 0;
+ return nullptr;
}
if (ok) *ok = true;
@@ -2011,7 +2014,7 @@ int QQmlMetaType::attachedPropertiesFuncId(QQmlEnginePrivate *engine, const QMet
QQmlAttachedPropertiesFunc QQmlMetaType::attachedPropertiesFuncById(QQmlEnginePrivate *engine, int id)
{
if (id < 0)
- return 0;
+ return nullptr;
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
return data->types.at(id).attachedPropertiesFunction(engine);
@@ -2104,7 +2107,7 @@ const char *QQmlMetaType::interfaceIId(int userType)
if (type.isInterface() && type.typeId() == userType)
return type.interfaceIId();
else
- return 0;
+ return nullptr;
}
bool QQmlMetaType::isList(int userType)
@@ -2397,6 +2400,27 @@ QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, int minorVe
return data->propertyCache(type, minorVersion);
}
+void qmlUnregisterType(int typeIndex)
+{
+ QMutexLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+ {
+ const QQmlTypePrivate *d = data->types.value(typeIndex).priv();
+ if (d) {
+ removeQQmlTypePrivate(data->idToType, d);
+ removeQQmlTypePrivate(data->nameToType, d);
+ removeQQmlTypePrivate(data->urlToType, d);
+ removeQQmlTypePrivate(data->urlToNonFileImportType, d);
+ removeQQmlTypePrivate(data->metaObjectToType, d);
+ for (QQmlMetaTypeData::TypeModules::Iterator module = data->uriToModule.begin(); module != data->uriToModule.end(); ++module) {
+ QQmlTypeModulePrivate *modulePrivate = (*module)->priv();
+ modulePrivate->remove(d);
+ }
+ data->types[typeIndex] = QQmlType();
+ }
+ }
+}
+
void QQmlMetaType::freeUnusedTypesAndCaches()
{
QMutexLocker lock(metaTypeDataLock());
@@ -2515,16 +2539,16 @@ QList<QQmlType> QQmlMetaType::qmlSingletonTypes()
return retn;
}
-const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(const QUrl &uri)
+const QV4::CompiledData::Unit *QQmlMetaType::findCachedCompilationUnit(const QUrl &uri)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
for (const auto lookup : qAsConst(data->lookupCachedQmlUnit)) {
if (const QQmlPrivate::CachedQmlUnit *unit = lookup(uri))
- return unit;
+ return unit->qmlData;
}
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 85ee4d7b97..07bef526ba 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -75,6 +75,8 @@ class QQmlCompiledData;
namespace QV4 { struct String; }
+void Q_QML_PRIVATE_EXPORT qmlUnregisterType(int type);
+
class Q_QML_PRIVATE_EXPORT QQmlMetaType
{
public:
@@ -107,7 +109,7 @@ public:
static QMetaMethod defaultMethod(QObject *);
static bool isQObject(int);
- static QObject *toQObject(const QVariant &, bool *ok = 0);
+ static QObject *toQObject(const QVariant &, bool *ok = nullptr);
static int listType(int);
static int attachedPropertiesFuncId(QQmlEnginePrivate *engine, const QMetaObject *);
@@ -131,7 +133,7 @@ public:
static QList<QQmlPrivate::AutoParentFunction> parentFunctions();
- static const QQmlPrivate::CachedQmlUnit *findCachedCompilationUnit(const QUrl &uri);
+ static const QV4::CompiledData::Unit *findCachedCompilationUnit(const QUrl &uri);
static bool namespaceContainsRegistrations(const QString &, int majorVersion);
@@ -161,7 +163,7 @@ public:
return d == other.d;
}
- bool isValid() const { return d != 0; }
+ bool isValid() const { return d != nullptr; }
const QQmlTypePrivate *key() const { return d; }
QByteArray typeName() const;
@@ -216,7 +218,7 @@ public:
{
public:
SingletonInstanceInfo()
- : scriptCallback(0), qobjectCallback(0), instanceMetaObject(0) {}
+ : scriptCallback(nullptr), qobjectCallback(nullptr), instanceMetaObject(nullptr) {}
QJSValue (*scriptCallback)(QQmlEngine *, QJSEngine *);
QObject *(*qobjectCallback)(QQmlEngine *, QJSEngine *);
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index e068ad174a..ac247ae0ad 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -51,7 +51,7 @@ void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **);
void QQmlVMEMetaObjectEndpoint_callback(QQmlNotifierEndpoint *, void **);
static Callback QQmlNotifier_callbacks[] = {
- 0,
+ nullptr,
QQmlBoundSignal_callback,
QQmlJavaScriptExpressionGuard_callback,
QQmlVMEMetaObjectEndpoint_callback
@@ -59,9 +59,9 @@ static Callback QQmlNotifier_callbacks[] = {
namespace {
struct NotifyListTraversalData {
- NotifyListTraversalData(QQmlNotifierEndpoint *ep = 0)
+ NotifyListTraversalData(QQmlNotifierEndpoint *ep = nullptr)
: originalSenderPtr(0)
- , disconnectWatch(0)
+ , disconnectWatch(nullptr)
, endpoint(ep)
{}
diff --git a/src/qml/qml/qqmlnotifier_p.h b/src/qml/qml/qqmlnotifier_p.h
index a99b13f155..d77e314de5 100644
--- a/src/qml/qml/qqmlnotifier_p.h
+++ b/src/qml/qml/qqmlnotifier_p.h
@@ -73,7 +73,7 @@ private:
friend class QQmlThreadNotifierProxyObject;
static void emitNotify(QQmlNotifierEndpoint *, void **a);
- QQmlNotifierEndpoint *endpoints;
+ QQmlNotifierEndpoint *endpoints = nullptr;
};
class QQmlEngine;
@@ -129,7 +129,6 @@ private:
};
QQmlNotifier::QQmlNotifier()
-: endpoints(0)
{
}
@@ -142,22 +141,22 @@ QQmlNotifier::~QQmlNotifier()
if (n->isNotifying()) *((qintptr *)(n->senderPtr & ~0x1)) = 0;
- n->next = 0;
- n->prev = 0;
+ n->next = nullptr;
+ n->prev = nullptr;
n->senderPtr = 0;
n->sourceSignal = -1;
}
- endpoints = 0;
+ endpoints = nullptr;
}
void QQmlNotifier::notify()
{
- void *args[] = { 0 };
+ void *args[] = { nullptr };
if (endpoints) emitNotify(endpoints, args);
}
QQmlNotifierEndpoint::QQmlNotifierEndpoint(Callback callback)
-: next(0), prev(0), senderPtr(0), callback(callback), needsConnectNotify(false), sourceSignal(-1)
+: next(nullptr), prev(nullptr), senderPtr(0), callback(callback), needsConnectNotify(false), sourceSignal(-1)
{
}
@@ -168,7 +167,7 @@ QQmlNotifierEndpoint::~QQmlNotifierEndpoint()
bool QQmlNotifierEndpoint::isConnected() const
{
- return prev != 0;
+ return prev != nullptr;
}
/*! \internal
@@ -212,8 +211,8 @@ void QQmlNotifierEndpoint::disconnect()
}
if (isNotifying()) *((qintptr *)(senderPtr & ~0x1)) = 0;
- next = 0;
- prev = 0;
+ next = nullptr;
+ prev = nullptr;
senderPtr = 0;
sourceSignal = -1;
}
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index d009536767..36e56a01f8 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -82,13 +82,13 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::Compil
{
init(parentContext);
- sharedState->componentAttached = 0;
+ sharedState->componentAttached = nullptr;
sharedState->allCreatedBindings.allocate(compilationUnit->totalBindingsCount);
sharedState->allParserStatusCallbacks.allocate(compilationUnit->totalParserStatusCount);
sharedState->allCreatedObjects.allocate(compilationUnit->totalObjectCount);
- sharedState->allJavaScriptObjects = 0;
+ sharedState->allJavaScriptObjects = nullptr;
sharedState->creationContext = creationContext;
- sharedState->rootContext = 0;
+ sharedState->rootContext = nullptr;
if (auto profiler = QQmlEnginePrivate::get(engine)->profiler) {
Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler,
@@ -105,7 +105,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::Compil
, propertyCaches(&compilationUnit->propertyCaches)
, sharedState(inheritedSharedState)
, topLevelCreator(false)
- , incubator(0)
+ , incubator(nullptr)
{
init(parentContext);
}
@@ -114,23 +114,23 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
{
parentContext = providedParentContext;
engine = parentContext->engine;
- v4 = QV8Engine::getV4(engine);
+ v4 = engine->handle();
if (compilationUnit && !compilationUnit->engine)
compilationUnit->linkToEngine(v4);
qmlUnit = compilationUnit->data;
- context = 0;
- _qobject = 0;
- _scopeObject = 0;
- _bindingTarget = 0;
- _valueTypeProperty = 0;
- _compiledObject = 0;
+ context = nullptr;
+ _qobject = nullptr;
+ _scopeObject = nullptr;
+ _bindingTarget = nullptr;
+ _valueTypeProperty = nullptr;
+ _compiledObject = nullptr;
_compiledObjectIndex = -1;
- _ddata = 0;
- _propertyCache = 0;
- _vmeMetaObject = 0;
- _qmlContext = 0;
+ _ddata = nullptr;
+ _propertyCache = nullptr;
+ _vmeMetaObject = nullptr;
+ _qmlContext = nullptr;
}
QQmlObjectCreator::~QQmlObjectCreator()
@@ -142,7 +142,7 @@ QQmlObjectCreator::~QQmlObjectCreator()
for (int i = 0; i < sharedState->allParserStatusCallbacks.count(); ++i) {
QQmlParserStatus *ps = sharedState->allParserStatusCallbacks.at(i);
if (ps)
- ps->d = 0;
+ ps->d = nullptr;
}
while (sharedState->componentAttached) {
QQmlComponentAttached *a = sharedState->componentAttached;
@@ -203,19 +203,16 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
if (instance) {
QQmlData *ddata = QQmlData::get(instance);
Q_ASSERT(ddata);
- if (ddata->compilationUnit)
- ddata->compilationUnit->release();
ddata->compilationUnit = compilationUnit;
- ddata->compilationUnit->addref();
}
if (topLevelCreator)
- sharedState->allJavaScriptObjects = 0;
+ sharedState->allJavaScriptObjects = nullptr;
phase = CreatingObjectsPhase2;
if (interrupt && interrupt->shouldInterrupt())
- return 0;
+ return nullptr;
phase = ObjectsCreated;
@@ -233,6 +230,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
return instance;
}
+// ### unify or keep in sync with populateDeferredBinding()
bool QQmlObjectCreator::populateDeferredProperties(QObject *instance, QQmlData::DeferredData *deferredData)
{
QQmlData *declarativeData = QQmlData::get(instance);
@@ -283,6 +281,80 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance, QQmlData::
qSwap(_qmlContext, qmlContext);
qSwap(_scopeObject, scopeObject);
+ deferredData->bindings.clear();
+ phase = ObjectsCreated;
+
+ return errors.isEmpty();
+}
+
+// ### unify or keep in sync with populateDeferredProperties()
+bool QQmlObjectCreator::populateDeferredBinding(const QQmlProperty &qmlProperty, QQmlData::DeferredData *deferredData, const QV4::CompiledData::Binding *binding)
+{
+ Q_ASSERT(binding->flags & QV4::CompiledData::Binding::IsDeferredBinding);
+
+ QObject *instance = qmlProperty.object();
+ QQmlData *declarativeData = QQmlData::get(instance);
+ context = deferredData->context;
+ sharedState->rootContext = context;
+
+ QObject *bindingTarget = instance;
+
+ QQmlRefPointer<QQmlPropertyCache> cache = declarativeData->propertyCache;
+ QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(instance);
+
+ QObject *scopeObject = instance;
+ qSwap(_scopeObject, scopeObject);
+
+ QV4::Scope valueScope(v4);
+
+ Q_ASSERT(topLevelCreator);
+ if (!sharedState->allJavaScriptObjects)
+ sharedState->allJavaScriptObjects = valueScope.alloc(compilationUnit->totalObjectCount);
+
+ QV4::QmlContext *qmlContext = static_cast<QV4::QmlContext *>(valueScope.alloc(1));
+
+ qSwap(_qmlContext, qmlContext);
+
+ qSwap(_propertyCache, cache);
+ qSwap(_qobject, instance);
+
+ int objectIndex = deferredData->deferredIdx;
+ qSwap(_compiledObjectIndex, objectIndex);
+
+ const QV4::CompiledData::Object *obj = qmlUnit->objectAt(_compiledObjectIndex);
+ qSwap(_compiledObject, obj);
+
+ qSwap(_ddata, declarativeData);
+ qSwap(_bindingTarget, bindingTarget);
+ qSwap(_vmeMetaObject, vmeMetaObject);
+
+ QQmlListProperty<void> savedList;
+ qSwap(_currentList, savedList);
+
+ const QQmlPropertyData &property = QQmlPropertyPrivate::get(qmlProperty)->core;
+
+ if (property.isQList()) {
+ void *argv[1] = { (void*)&_currentList };
+ QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property.coreIndex(), argv);
+ } else if (_currentList.object) {
+ _currentList = QQmlListProperty<void>();
+ }
+
+ setPropertyBinding(&property, binding);
+
+ qSwap(_currentList, savedList);
+
+ qSwap(_vmeMetaObject, vmeMetaObject);
+ qSwap(_bindingTarget, bindingTarget);
+ qSwap(_ddata, declarativeData);
+ qSwap(_compiledObject, obj);
+ qSwap(_compiledObjectIndex, objectIndex);
+ qSwap(_qobject, instance);
+ qSwap(_propertyCache, cache);
+
+ qSwap(_qmlContext, qmlContext);
+ qSwap(_scopeObject, scopeObject);
+
phase = ObjectsCreated;
return errors.isEmpty();
@@ -370,7 +442,7 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
QString string = binding->valueAsString(qmlUnit);
// Encoded dir-separators defeat QUrl processing - decode them first
string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
- QUrl value = string.isEmpty() ? QUrl() : compilationUnit->url().resolved(QUrl(string));
+ QUrl value = string.isEmpty() ? QUrl() : compilationUnit->finalUrl().resolved(QUrl(string));
// Apply URL interceptor
if (engine->urlInterceptor())
value = engine->urlInterceptor()->intercept(value, QQmlAbstractUrlInterceptor::UrlString);
@@ -568,7 +640,8 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const
} else if (property->propType() == qMetaTypeId<QList<QUrl> >()) {
Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String);
QString urlString = binding->valueAsString(qmlUnit);
- QUrl u = urlString.isEmpty() ? QUrl() : compilationUnit->url().resolved(QUrl(urlString));
+ QUrl u = urlString.isEmpty() ? QUrl()
+ : compilationUnit->finalUrl().resolved(QUrl(urlString));
QList<QUrl> value;
value.append(u);
property->writeProperty(_qobject, &value, propertyWriteFlags);
@@ -723,7 +796,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
}
const int id = attachedType.attachedPropertiesId(QQmlEnginePrivate::get(engine));
QObject *qmlObject = qmlAttachedPropertiesObjectById(id, _qobject);
- if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject, /*value type property*/0))
+ if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject, /*value type property*/nullptr))
return false;
return true;
}
@@ -741,12 +814,12 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor |
QQmlPropertyData::RemoveBindingOnAliasWrite;
int propertyWriteStatus = -1;
- void *argv[] = { &ss, 0, &propertyWriteStatus, &propertyWriteFlags };
+ void *argv[] = { &ss, nullptr, &propertyWriteStatus, &propertyWriteFlags };
QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex(), argv);
return true;
}
- QObject *createdSubObject = 0;
+ QObject *createdSubObject = nullptr;
if (binding->type == QV4::CompiledData::Binding::Type_Object) {
createdSubObject = createInstance(binding->value.objectIndex, _bindingTarget);
if (!createdSubObject)
@@ -760,9 +833,9 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(binding->value.objectIndex);
if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) {
- QObject *groupObject = 0;
- QQmlValueType *valueType = 0;
- const QQmlPropertyData *valueTypeProperty = 0;
+ QObject *groupObject = nullptr;
+ QQmlValueType *valueType = nullptr;
+ const QQmlPropertyData *valueTypeProperty = nullptr;
QObject *bindingTarget = _bindingTarget;
if (QQmlValueTypeFactory::isValueType(property->propType())) {
@@ -935,7 +1008,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor |
QQmlPropertyData::RemoveBindingOnAliasWrite;
int propertyWriteStatus = -1;
- void *argv[] = { 0, 0, &propertyWriteStatus, &propertyWriteFlags };
+ void *argv[] = { nullptr, nullptr, &propertyWriteStatus, &propertyWriteFlags };
if (const char *iid = QQmlMetaType::interfaceIId(property->propType())) {
void *ptr = createdSubObject->qt_metacast(iid);
@@ -949,7 +1022,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
} else if (property->propType() == QMetaType::QVariant) {
if (property->isVarProperty()) {
QV4::Scope scope(v4);
- QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), createdSubObject));
+ QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(engine->handle(), createdSubObject));
_vmeMetaObject->setVMEProperty(property->coreIndex(), wrappedObject);
} else {
QVariant value = QVariant::fromValue(createdSubObject);
@@ -961,7 +1034,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
void *itemToAdd = createdSubObject;
- const char *iid = 0;
+ const char *iid = nullptr;
int listItemType = QQmlEnginePrivate::get(engine)->listType(property->propType());
if (listItemType != -1)
iid = QQmlMetaType::interfaceIId(listItemType);
@@ -1028,12 +1101,9 @@ void QQmlObjectCreator::registerObjectWithContextById(const QV4::CompiledData::O
context->setIdProperty(object->id, instance);
}
-QV4::QmlContext *QQmlObjectCreator::currentQmlContext()
+void QQmlObjectCreator::createQmlContext()
{
- if (!_qmlContext->isManaged())
- _qmlContext->setM(QV4::QmlContext::create(v4->rootContext(), context, _scopeObject));
-
- return _qmlContext;
+ _qmlContext->setM(QV4::QmlContext::create(v4->rootContext(), context, _scopeObject));
}
QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject)
@@ -1044,10 +1114,10 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
bool isComponent = false;
- QObject *instance = 0;
- QQmlData *ddata = 0;
- QQmlCustomParser *customParser = 0;
- QQmlParserStatus *parserStatus = 0;
+ QObject *instance = nullptr;
+ QQmlData *ddata = nullptr;
+ QQmlCustomParser *customParser = nullptr;
+ QQmlParserStatus *parserStatus = nullptr;
bool installPropertyCache = true;
if (obj->flags & QV4::CompiledData::Object::IsComponent) {
@@ -1067,11 +1137,11 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
Q_QML_OC_PROFILE(sharedState->profiler, profiler.update(
compilationUnit, obj, type.qmlTypeName(), context->url()));
- void *ddataMemory = 0;
+ void *ddataMemory = nullptr;
type.create(&instance, &ddataMemory, sizeof(QQmlData));
if (!instance) {
recordError(obj->location, tr("Unable to create object of type %1").arg(stringAt(obj->inheritedTypeNameIndex)));
- return 0;
+ return nullptr;
}
{
@@ -1103,14 +1173,14 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
if (typeRef->compilationUnit->data->isSingleton())
{
recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
- return 0;
+ return nullptr;
}
QQmlObjectCreator subCreator(context, typeRef->compilationUnit, sharedState.data());
instance = subCreator.create();
if (!instance) {
errors += subCreator.errors;
- return 0;
+ return nullptr;
}
}
if (instance->isWidgetType()) {
@@ -1174,8 +1244,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
}
customParser->applyBindings(instance, compilationUnit, bindings);
- customParser->engine = 0;
- customParser->imports = (QQmlTypeNameCache*)0;
+ customParser->engine = nullptr;
+ customParser->imports = (QQmlTypeNameCache*)nullptr;
}
if (isComponent) {
@@ -1204,12 +1274,12 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
qSwap(_qmlContext, qmlContext);
- bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/0);
+ bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/nullptr);
qSwap(_qmlContext, qmlContext);
qSwap(_scopeObject, scopeObject);
- return result ? instance : 0;
+ return result ? instance : nullptr;
}
QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
@@ -1233,7 +1303,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
QQmlPropertyData::DontRemoveBinding);
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
- return 0;
+ return nullptr;
}
if (QQmlVME::componentCompleteEnabled()) { // the qml designer does the component complete later
@@ -1242,12 +1312,12 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
QQmlParserStatus *status = sharedState->allParserStatusCallbacks.pop();
if (status && status->d) {
- status->d = 0;
+ status->d = nullptr;
status->componentComplete();
}
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
- return 0;
+ return nullptr;
}
}
@@ -1255,11 +1325,11 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
QQmlEnginePrivate::FinalizeCallback callback = sharedState->finalizeCallbacks.at(ii);
QObject *obj = callback.first;
if (obj) {
- void *args[] = { 0 };
+ void *args[] = { nullptr };
QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, callback.second, args);
}
if (watcher.hasRecursed())
- return 0;
+ return nullptr;
}
sharedState->finalizeCallbacks.clear();
@@ -1274,7 +1344,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
emit a->completed();
if (watcher.hasRecursed() || interrupt.shouldInterrupt())
- return 0;
+ return nullptr;
}
phase = Done;
@@ -1282,21 +1352,6 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
return sharedState->rootContext;
}
-void QQmlObjectCreator::cancel(QObject *object)
-{
- int last = sharedState->allCreatedObjects.count() - 1;
- int i = last;
- while (i >= 0) {
- if (sharedState->allCreatedObjects.at(i) == object) {
- if (i < last)
- qSwap(sharedState->allCreatedObjects[i], sharedState->allCreatedObjects[last]);
- sharedState->allCreatedObjects.pop();
- break;
- }
- --i;
- }
-}
-
void QQmlObjectCreator::clear()
{
if (phase == Done || phase == Finalizing || phase == Startup)
@@ -1331,7 +1386,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches->at(_compiledObjectIndex);
- QQmlVMEMetaObject *vmeMetaObject = 0;
+ QQmlVMEMetaObject *vmeMetaObject = nullptr;
if (propertyCaches->needsVMEMetaObject(_compiledObjectIndex)) {
Q_ASSERT(!cache.isNull());
// install on _object
@@ -1350,14 +1405,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
qSwap(_propertyCache, cache);
qSwap(_vmeMetaObject, vmeMetaObject);
- if (_compiledObject->flags & QV4::CompiledData::Object::HasDeferredBindings) {
- QQmlData::DeferredData *deferData = new QQmlData::DeferredData;
- deferData->deferredIdx = _compiledObjectIndex;
- deferData->compilationUnit = compilationUnit;
- deferData->compilationUnit->addref();
- deferData->context = context;
- _ddata->deferredData.append(deferData);
- }
+ if (_compiledObject->flags & QV4::CompiledData::Object::HasDeferredBindings)
+ _ddata->deferData(_compiledObjectIndex, compilationUnit, context);
if (_compiledObject->nFunctions > 0)
setupFunctions();
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index aa0165ec06..399a5f6d4a 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -81,17 +81,17 @@ struct QQmlObjectCreatorSharedState : public QSharedData
QRecursionNode recursionNode;
};
-class QQmlObjectCreator
+class Q_QML_PRIVATE_EXPORT QQmlObjectCreator
{
Q_DECLARE_TR_FUNCTIONS(QQmlObjectCreator)
public:
- QQmlObjectCreator(QQmlContextData *parentContext, QV4::CompiledData::CompilationUnit *compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator = 0);
+ QQmlObjectCreator(QQmlContextData *parentContext, QV4::CompiledData::CompilationUnit *compilationUnit, QQmlContextData *creationContext, QQmlIncubatorPrivate *incubator = nullptr);
~QQmlObjectCreator();
- QObject *create(int subComponentIndex = -1, QObject *parent = 0, QQmlInstantiationInterrupt *interrupt = 0);
+ QObject *create(int subComponentIndex = -1, QObject *parent = nullptr, QQmlInstantiationInterrupt *interrupt = nullptr);
bool populateDeferredProperties(QObject *instance, QQmlData::DeferredData *deferredData);
+ bool populateDeferredBinding(const QQmlProperty &qmlProperty, QQmlData::DeferredData *deferredData, const QV4::CompiledData::Binding *binding);
QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
- void cancel(QObject *object);
void clear();
QQmlComponentAttached **componentAttachment() const { return &sharedState->componentAttached; }
@@ -108,7 +108,7 @@ private:
void init(QQmlContextData *parentContext);
- QObject *createInstance(int index, QObject *parent = 0, bool isContextObject = false);
+ QObject *createInstance(int index, QObject *parent = nullptr, bool isContextObject = false);
bool populateInstance(int index, QObject *instance,
QObject *bindingTarget, const QQmlPropertyData *valueTypeProperty);
@@ -123,7 +123,8 @@ private:
void registerObjectWithContextById(const QV4::CompiledData::Object *object, QObject *instance) const;
- QV4::QmlContext *currentQmlContext();
+ inline QV4::QmlContext *currentQmlContext();
+ Q_NEVER_INLINE void createQmlContext();
enum Phase {
Startup,
@@ -136,7 +137,7 @@ private:
QQmlEngine *engine;
QV4::ExecutionEngine *v4;
- QV4::CompiledData::CompilationUnit *compilationUnit;
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
const QV4::CompiledData::Unit *qmlUnit;
QQmlGuardedContextData parentContext;
QQmlContextData *context;
@@ -173,6 +174,14 @@ private:
QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher;
};
+QV4::QmlContext *QQmlObjectCreator::currentQmlContext()
+{
+ if (!_qmlContext->isManaged())
+ _qmlContext->setM(QV4::QmlContext::create(v4->rootContext(), context, _scopeObject));
+
+ return _qmlContext;
+}
+
QT_END_NAMESPACE
#endif // QQMLOBJECTCREATOR_P_H
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index fc85030b3d..1b44bbdda3 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
class QQmlOpenMetaObjectTypePrivate
{
public:
- QQmlOpenMetaObjectTypePrivate() : mem(0), cache(0), engine(0) {}
+ QQmlOpenMetaObjectTypePrivate() : mem(nullptr), cache(nullptr), engine(nullptr) {}
void init(const QMetaObject *metaObj);
@@ -83,7 +83,7 @@ QQmlOpenMetaObjectType::~QQmlOpenMetaObjectType()
void QQmlOpenMetaObjectType::clear()
{
- d->engine = 0;
+ d->engine = nullptr;
}
int QQmlOpenMetaObjectType::propertyOffset() const
@@ -182,7 +182,7 @@ class QQmlOpenMetaObjectPrivate
{
public:
QQmlOpenMetaObjectPrivate(QQmlOpenMetaObject *_q)
- : q(_q), parent(0), type(0), cacheProperties(false) {}
+ : q(_q), parent(nullptr), type(nullptr), cacheProperties(false) {}
inline QPair<QVariant, bool> &getDataRef(int idx) {
while (data.count() <= idx)
@@ -220,7 +220,7 @@ QQmlOpenMetaObject::QQmlOpenMetaObject(QObject *obj, const QMetaObject *base, bo
d->autoCreate = automatic;
d->object = obj;
- d->type = new QQmlOpenMetaObjectType(base ? base : obj->metaObject(), 0);
+ d->type = new QQmlOpenMetaObjectType(base ? base : obj->metaObject(), nullptr);
d->type->d->referers.insert(this);
QObjectPrivate *op = QObjectPrivate::get(obj);
@@ -264,7 +264,7 @@ void QQmlOpenMetaObject::emitPropertyNotification(const QByteArray &propertyName
QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.constFind(propertyName);
if (iter == d->type->d->names.constEnd())
return;
- activate(d->object, *iter + d->type->d->signalOffset, 0);
+ activate(d->object, *iter + d->type->d->signalOffset, nullptr);
}
int QQmlOpenMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void **a)
@@ -284,7 +284,7 @@ int QQmlOpenMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void *
prop.first = propertyWriteValue(propId, *reinterpret_cast<QVariant *>(a[0]));
prop.second = true;
propertyWritten(propId);
- activate(o, d->type->d->signalOffset + propId, 0);
+ activate(o, d->type->d->signalOffset + propId, nullptr);
}
}
return -1;
@@ -311,7 +311,7 @@ void QQmlOpenMetaObject::setValue(int id, const QVariant &value)
QPair<QVariant, bool> &prop = d->getDataRef(id);
prop.first = propertyWriteValue(id, value);
prop.second = true;
- activate(d->object, id + d->type->d->signalOffset, 0);
+ activate(d->object, id + d->type->d->signalOffset, nullptr);
}
QVariant QQmlOpenMetaObject::value(const QByteArray &name) const
@@ -353,7 +353,7 @@ bool QQmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val)
return false;
dataVal = val;
- activate(d->object, id + d->type->d->signalOffset, 0);
+ activate(d->object, id + d->type->d->signalOffset, nullptr);
return true;
}
@@ -382,7 +382,7 @@ void QQmlOpenMetaObject::setCached(bool c)
} else {
if (d->type->d->cache)
d->type->d->cache->release();
- qmldata->propertyCache = 0;
+ qmldata->propertyCache = nullptr;
}
}
@@ -395,7 +395,7 @@ int QQmlOpenMetaObject::createProperty(const char *name, const char *)
if (QQmlData *ddata = QQmlData::get(d->object, /*create*/false)) {
if (ddata->propertyCache) {
ddata->propertyCache->release();
- ddata->propertyCache = 0;
+ ddata->propertyCache = nullptr;
}
}
diff --git a/src/qml/qml/qqmlopenmetaobject_p.h b/src/qml/qml/qqmlopenmetaobject_p.h
index 4bb92489a5..4905190b75 100644
--- a/src/qml/qml/qqmlopenmetaobject_p.h
+++ b/src/qml/qml/qqmlopenmetaobject_p.h
@@ -69,7 +69,7 @@ class Q_QML_PRIVATE_EXPORT QQmlOpenMetaObjectType : public QQmlRefCount, public
{
public:
QQmlOpenMetaObjectType(const QMetaObject *base, QQmlEngine *engine);
- ~QQmlOpenMetaObjectType();
+ ~QQmlOpenMetaObjectType() override;
void createProperties(const QVector<QByteArray> &names);
int createProperty(const QByteArray &name);
@@ -95,9 +95,9 @@ class QQmlOpenMetaObjectPrivate;
class Q_QML_PRIVATE_EXPORT QQmlOpenMetaObject : public QAbstractDynamicMetaObject
{
public:
- QQmlOpenMetaObject(QObject *, const QMetaObject * = 0, bool = true);
+ QQmlOpenMetaObject(QObject *, const QMetaObject * = nullptr, bool = true);
QQmlOpenMetaObject(QObject *, QQmlOpenMetaObjectType *, bool = true);
- ~QQmlOpenMetaObject();
+ ~QQmlOpenMetaObject() override;
QVariant value(const QByteArray &) const;
bool setValue(const QByteArray &, const QVariant &);
diff --git a/src/qml/qml/qqmlparserstatus.cpp b/src/qml/qml/qqmlparserstatus.cpp
index ad07cac7ef..1082c318cb 100644
--- a/src/qml/qml/qqmlparserstatus.cpp
+++ b/src/qml/qml/qqmlparserstatus.cpp
@@ -87,7 +87,7 @@ QT_BEGIN_NAMESPACE
/*! \internal */
QQmlParserStatus::QQmlParserStatus()
-: d(0)
+: d(nullptr)
{
}
@@ -95,7 +95,7 @@ QQmlParserStatus::QQmlParserStatus()
QQmlParserStatus::~QQmlParserStatus()
{
if(d)
- (*d) = 0;
+ (*d) = nullptr;
}
/*!
diff --git a/src/qml/qml/qqmlplatform_p.h b/src/qml/qml/qqmlplatform_p.h
index 6246ca7105..af33dffca3 100644
--- a/src/qml/qml/qqmlplatform_p.h
+++ b/src/qml/qml/qqmlplatform_p.h
@@ -64,7 +64,7 @@ class Q_QML_PRIVATE_EXPORT QQmlPlatform : public QObject
Q_PROPERTY(QString pluginName READ pluginName CONSTANT)
public:
- explicit QQmlPlatform(QObject *parent = 0);
+ explicit QQmlPlatform(QObject *parent = nullptr);
virtual ~QQmlPlatform();
static QString os();
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index eeb5b4c302..fabdcacc36 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -69,7 +69,6 @@ namespace CompiledData {
struct Unit;
struct CompilationUnit;
}
-typedef CompiledData::CompilationUnit *(*CompilationUnitFactoryFunction)();
}
namespace QmlIR {
struct Document;
@@ -99,7 +98,7 @@ namespace QQmlPrivate
class QQmlElement : public T
{
public:
- virtual ~QQmlElement() {
+ ~QQmlElement() override {
QQmlPrivate::qdeclarativeelement_destructor(this);
}
};
@@ -168,8 +167,8 @@ namespace QQmlPrivate
class AttachedPropertySelector
{
public:
- static inline QQmlAttachedPropertiesFunc func() { return 0; }
- static inline const QMetaObject *metaObject() { return 0; }
+ static inline QQmlAttachedPropertiesFunc func() { return nullptr; }
+ static inline const QMetaObject *metaObject() { return nullptr; }
};
template<typename T>
class AttachedPropertySelector<T, 1>
@@ -284,8 +283,8 @@ namespace QQmlPrivate
struct CachedQmlUnit {
const QV4::CompiledData::Unit *qmlData;
- QV4::CompilationUnitFactoryFunction createCompilationUnit;
- QmlIR::IRLoaderFunction loadIR;
+ void *unused1;
+ void *unused2;
};
typedef const CachedQmlUnit *(*QmlUnitCacheLookupFunction)(const QUrl &url);
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 9a138dcf80..ebf296b29d 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -119,7 +119,7 @@ The \l {Qt Quick 1} version of this class was named QDeclarativeProperty.
Create an invalid QQmlProperty.
*/
QQmlProperty::QQmlProperty()
-: d(0)
+: d(nullptr)
{
}
@@ -128,7 +128,7 @@ QQmlProperty::~QQmlProperty()
{
if (d)
d->release();
- d = 0;
+ d = nullptr;
}
/*!
@@ -150,8 +150,8 @@ QQmlProperty::QQmlProperty(QObject *obj)
QQmlProperty::QQmlProperty(QObject *obj, QQmlContext *ctxt)
: d(new QQmlPropertyPrivate)
{
- d->context = ctxt?QQmlContextData::get(ctxt):0;
- d->engine = ctxt?ctxt->engine():0;
+ d->context = ctxt?QQmlContextData::get(ctxt):nullptr;
+ d->engine = ctxt?ctxt->engine():nullptr;
d->initDefault(obj);
}
@@ -164,7 +164,7 @@ QQmlProperty::QQmlProperty(QObject *obj, QQmlContext *ctxt)
QQmlProperty::QQmlProperty(QObject *obj, QQmlEngine *engine)
: d(new QQmlPropertyPrivate)
{
- d->context = 0;
+ d->context = nullptr;
d->engine = engine;
d->initDefault(obj);
}
@@ -190,7 +190,7 @@ QQmlProperty::QQmlProperty(QObject *obj, const QString &name)
: d(new QQmlPropertyPrivate)
{
d->initProperty(obj, name);
- if (!isValid()) d->object = 0;
+ if (!isValid()) d->object = nullptr;
}
/*!
@@ -203,10 +203,10 @@ QQmlProperty::QQmlProperty(QObject *obj, const QString &name)
QQmlProperty::QQmlProperty(QObject *obj, const QString &name, QQmlContext *ctxt)
: d(new QQmlPropertyPrivate)
{
- d->context = ctxt?QQmlContextData::get(ctxt):0;
- d->engine = ctxt?ctxt->engine():0;
+ d->context = ctxt?QQmlContextData::get(ctxt):nullptr;
+ d->engine = ctxt?ctxt->engine():nullptr;
d->initProperty(obj, name);
- if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; }
+ if (!isValid()) { d->object = nullptr; d->context = nullptr; d->engine = nullptr; }
}
/*!
@@ -217,14 +217,30 @@ QQmlProperty::QQmlProperty(QObject *obj, const QString &name, QQmlContext *ctxt)
QQmlProperty::QQmlProperty(QObject *obj, const QString &name, QQmlEngine *engine)
: d(new QQmlPropertyPrivate)
{
- d->context = 0;
+ d->context = nullptr;
d->engine = engine;
d->initProperty(obj, name);
- if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; }
+ if (!isValid()) { d->object = nullptr; d->context = nullptr; d->engine = nullptr; }
+}
+
+QQmlProperty QQmlPropertyPrivate::create(QObject *target, const QString &propertyName, QQmlContextData *context)
+{
+ QQmlProperty result;
+ auto d = new QQmlPropertyPrivate;
+ result.d = d;
+ d->context = context;
+ d->engine = context ? context->engine : nullptr;
+ d->initProperty(target, propertyName);
+ if (!result.isValid()) {
+ d->object = nullptr;
+ d->context = nullptr;
+ d->engine = nullptr;
+ }
+ return result;
}
QQmlPropertyPrivate::QQmlPropertyPrivate()
-: context(0), engine(0), object(0), isNameCached(false)
+: context(nullptr), engine(nullptr), object(nullptr), isNameCached(false)
{
}
@@ -232,98 +248,104 @@ QQmlContextData *QQmlPropertyPrivate::effectiveContext() const
{
if (context) return context;
else if (engine) return QQmlContextData::get(engine->rootContext());
- else return 0;
+ else return nullptr;
}
void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
{
if (!obj) return;
- QQmlTypeNameCache *typeNameCache = context?context->imports:0;
-
- const auto path = name.splitRef(QLatin1Char('.'));
- if (path.isEmpty()) return;
+ QQmlTypeNameCache *typeNameCache = context?context->imports:nullptr;
QObject *currentObject = obj;
-
- // Everything up to the last property must be an "object type" property
- for (int ii = 0; ii < path.count() - 1; ++ii) {
- const QStringRef &pathName = path.at(ii);
-
- if (typeNameCache) {
- QQmlTypeNameCache::Result r = typeNameCache->query(pathName);
- if (r.isValid()) {
- if (r.type.isValid()) {
- QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
- QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate);
- if (!func) return; // Not an attachable type
-
- currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject);
- if (!currentObject) return; // Something is broken with the attachable type
- } else if (r.importNamespace) {
- if ((ii + 1) == path.count()) return; // No type following the namespace
-
- ++ii; r = typeNameCache->query(path.at(ii), r.importNamespace);
- if (!r.type.isValid()) return; // Invalid type in namespace
-
- QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
- QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate);
- if (!func) return; // Not an attachable type
-
- currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject);
- if (!currentObject) return; // Something is broken with the attachable type
-
- } else if (r.scriptIndex != -1) {
- return; // Not a type
- } else {
- Q_ASSERT(!"Unreachable");
+ QVector<QStringRef> path;
+ QStringRef terminal(&name);
+
+ if (name.contains(QLatin1Char('.'))) {
+ path = name.splitRef(QLatin1Char('.'));
+ if (path.isEmpty()) return;
+
+ // Everything up to the last property must be an "object type" property
+ for (int ii = 0; ii < path.count() - 1; ++ii) {
+ const QStringRef &pathName = path.at(ii);
+
+ // Types must begin with an uppercase letter (see checkRegistration()
+ // in qqmlmetatype.cpp for the enforcement of this).
+ if (typeNameCache && !pathName.isEmpty() && pathName.at(0).isUpper()) {
+ QQmlTypeNameCache::Result r = typeNameCache->query(pathName);
+ if (r.isValid()) {
+ if (r.type.isValid()) {
+ QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
+ QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate);
+ if (!func) return; // Not an attachable type
+
+ currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject);
+ if (!currentObject) return; // Something is broken with the attachable type
+ } else if (r.importNamespace) {
+ if ((ii + 1) == path.count()) return; // No type following the namespace
+
+ ++ii; r = typeNameCache->query(path.at(ii), r.importNamespace);
+ if (!r.type.isValid()) return; // Invalid type in namespace
+
+ QQmlEnginePrivate *enginePrivate = QQmlEnginePrivate::get(engine);
+ QQmlAttachedPropertiesFunc func = r.type.attachedPropertiesFunction(enginePrivate);
+ if (!func) return; // Not an attachable type
+
+ currentObject = qmlAttachedPropertiesObjectById(r.type.attachedPropertiesId(enginePrivate), currentObject);
+ if (!currentObject) return; // Something is broken with the attachable type
+
+ } else if (r.scriptIndex != -1) {
+ return; // Not a type
+ } else {
+ Q_ASSERT(!"Unreachable");
+ }
+ continue;
}
- continue;
+
}
- }
+ QQmlPropertyData local;
+ QQmlPropertyData *property =
+ QQmlPropertyCache::property(engine, currentObject, pathName, context, local);
- QQmlPropertyData local;
- QQmlPropertyData *property =
- QQmlPropertyCache::property(engine, currentObject, pathName, context, local);
+ if (!property) return; // Not a property
+ if (property->isFunction())
+ return; // Not an object property
- if (!property) return; // Not a property
- if (property->isFunction())
- return; // Not an object property
+ if (ii == (path.count() - 2) && QQmlValueTypeFactory::isValueType(property->propType())) {
+ // We're now at a value type property
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType());
+ if (!valueTypeMetaObject) return; // Not a value type
- if (ii == (path.count() - 2) && QQmlValueTypeFactory::isValueType(property->propType())) {
- // We're now at a value type property
- const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType());
- if (!valueTypeMetaObject) return; // Not a value type
+ int idx = valueTypeMetaObject->indexOfProperty(path.last().toUtf8().constData());
+ if (idx == -1) return; // Value type property does not exist
- int idx = valueTypeMetaObject->indexOfProperty(path.last().toUtf8().constData());
- if (idx == -1) return; // Value type property does not exist
+ QMetaProperty vtProp = valueTypeMetaObject->property(idx);
- QMetaProperty vtProp = valueTypeMetaObject->property(idx);
+ Q_ASSERT(vtProp.userType() <= 0x0000FFFF);
+ Q_ASSERT(idx <= 0x0000FFFF);
- Q_ASSERT(vtProp.userType() <= 0x0000FFFF);
- Q_ASSERT(idx <= 0x0000FFFF);
+ object = currentObject;
+ core = *property;
+ valueTypeData.setFlags(QQmlPropertyData::flagsForProperty(vtProp));
+ valueTypeData.setPropType(vtProp.userType());
+ valueTypeData.setCoreIndex(idx);
- object = currentObject;
- core = *property;
- valueTypeData.setFlags(QQmlPropertyData::flagsForProperty(vtProp));
- valueTypeData.setPropType(vtProp.userType());
- valueTypeData.setCoreIndex(idx);
+ return;
+ } else {
+ if (!property->isQObject())
+ return; // Not an object property
- return;
- } else {
- if (!property->isQObject())
- return; // Not an object property
+ property->readProperty(currentObject, &currentObject);
+ if (!currentObject) return; // No value
- property->readProperty(currentObject, &currentObject);
- if (!currentObject) return; // No value
+ }
}
+ terminal = path.last();
}
- const QStringRef &terminal = path.last();
-
if (terminal.count() >= 3 &&
terminal.at(0) == QLatin1Char('o') &&
terminal.at(1) == QLatin1Char('n') &&
@@ -467,7 +489,7 @@ QQmlPropertyPrivate::propertyTypeCategory() const
const char *QQmlProperty::propertyTypeName() const
{
if (!d)
- return 0;
+ return nullptr;
if (d->isValueType()) {
const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType());
Q_ASSERT(valueTypeMetaObject);
@@ -475,7 +497,7 @@ const char *QQmlProperty::propertyTypeName() const
} else if (d->object && type() & Property && d->core.isValid()) {
return d->object->metaObject()->property(d->core.coreIndex()).typeName();
} else {
- return 0;
+ return nullptr;
}
}
@@ -559,7 +581,7 @@ bool QQmlProperty::isSignalProperty() const
*/
QObject *QQmlProperty::object() const
{
- return d ? d->object : 0;
+ return d ? d->object : nullptr;
}
/*!
@@ -697,7 +719,7 @@ QQmlAbstractBinding *
QQmlPropertyPrivate::binding(const QQmlProperty &that)
{
if (!that.d || !that.isProperty() || !that.d->object)
- return 0;
+ return nullptr;
QQmlPropertyIndex thatIndex(that.d->core.coreIndex(), that.d->valueTypeData.coreIndex());
return binding(that.d->object, thatIndex);
@@ -759,7 +781,7 @@ static void removeOldBinding(QObject *object, QQmlPropertyIndex index, QQmlPrope
return;
if (!(flags & QQmlPropertyPrivate::DontEnable))
- oldBinding->setEnabled(false, 0);
+ oldBinding->setEnabled(false, nullptr);
oldBinding->removeFromObject();
}
@@ -793,13 +815,13 @@ QQmlPropertyPrivate::binding(QObject *object, QQmlPropertyIndex index)
QQmlData *data = QQmlData::get(object);
if (!data)
- return 0;
+ return nullptr;
const int coreIndex = index.coreIndex();
const int valueTypeIndex = index.valueTypeIndex();
if (coreIndex < 0 || !data->hasBindingBit(coreIndex))
- return 0;
+ return nullptr;
QQmlAbstractBinding *binding = data->bindings;
while (binding && (binding->targetPropertyIndex().coreIndex() != coreIndex ||
@@ -825,11 +847,11 @@ void QQmlPropertyPrivate::findAliasTarget(QObject *object, QQmlPropertyIndex bin
int valueTypeIndex = bindingIndex.valueTypeIndex();
QQmlPropertyData *propertyData =
- data->propertyCache?data->propertyCache->property(coreIndex):0;
+ data->propertyCache?data->propertyCache->property(coreIndex):nullptr;
if (propertyData && propertyData->isAlias()) {
QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
- QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
+ QObject *aObject = nullptr; int aCoreIndex = -1; int aValueTypeIndex = -1;
if (vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
// This will either be a value type sub-reference or an alias to a value-type sub-reference not both
Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1);
@@ -884,11 +906,11 @@ QQmlBoundSignalExpression *
QQmlPropertyPrivate::signalExpression(const QQmlProperty &that)
{
if (!(that.type() & QQmlProperty::SignalProperty))
- return 0;
+ return nullptr;
QQmlData *data = QQmlData::get(that.d->object);
if (!data)
- return 0;
+ return nullptr;
QQmlBoundSignal *signalHandler = data->signalHandlers;
@@ -898,7 +920,7 @@ QQmlPropertyPrivate::signalExpression(const QQmlProperty &that)
if (signalHandler)
return signalHandler->expression();
- return 0;
+ return nullptr;
}
/*!
@@ -925,7 +947,7 @@ void QQmlPropertyPrivate::takeSignalExpression(const QQmlProperty &that,
return;
}
- QQmlData *data = QQmlData::get(that.d->object, 0 != expr);
+ QQmlData *data = QQmlData::get(that.d->object, nullptr != expr);
if (!data)
return;
@@ -1032,7 +1054,7 @@ QVariant QQmlPropertyPrivate::readValueProperty()
} else if (core.isQObject()) {
- QObject *rv = 0;
+ QObject *rv = nullptr;
core.readProperty(object, &rv);
return QVariant::fromValue(rv);
@@ -1043,11 +1065,11 @@ QVariant QQmlPropertyPrivate::readValueProperty()
QVariant value;
int status = -1;
- void *args[] = { 0, &value, &status };
+ void *args[] = { nullptr, &value, &status };
if (core.propType() == QMetaType::QVariant) {
args[0] = &value;
} else {
- value = QVariant(core.propType(), (void*)0);
+ value = QVariant(core.propType(), (void*)nullptr);
args[0] = value.data();
}
core.readPropertyWithArgs(object, args);
@@ -1406,7 +1428,7 @@ QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engi
*/
bool QQmlProperty::write(const QVariant &value) const
{
- return QQmlPropertyPrivate::write(*this, value, 0);
+ return QQmlPropertyPrivate::write(*this, value, nullptr);
}
/*!
@@ -1475,7 +1497,7 @@ bool QQmlProperty::write(QObject *object, const QString &name, const QVariant &v
bool QQmlProperty::reset() const
{
if (isResettable()) {
- void *args[] = { 0 };
+ void *args[] = { nullptr };
QMetaObject::metacall(d->object, QMetaObject::ResetProperty, d->core.coreIndex(), args);
return true;
} else {
diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h
index 53062a2f13..544eab4c7f 100644
--- a/src/qml/qml/qqmlproperty_p.h
+++ b/src/qml/qml/qqmlproperty_p.h
@@ -104,9 +104,9 @@ public:
static bool writeValueProperty(QObject *,
const QQmlPropertyData &, const QQmlPropertyData &valueTypeData,
const QVariant &, QQmlContextData *,
- QQmlPropertyData::WriteFlags flags = 0);
+ QQmlPropertyData::WriteFlags flags = nullptr);
static bool write(QObject *, const QQmlPropertyData &, const QVariant &,
- QQmlContextData *, QQmlPropertyData::WriteFlags flags = 0);
+ QQmlContextData *, QQmlPropertyData::WriteFlags flags = nullptr);
static void findAliasTarget(QObject *, QQmlPropertyIndex, QObject **, QQmlPropertyIndex *);
enum BindingFlag {
@@ -140,10 +140,12 @@ public:
static QMetaMethod findSignalByName(const QMetaObject *mo, const QByteArray &);
static bool connect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index,
- int type = 0, int *types = 0);
+ int type = 0, int *types = nullptr);
static void flushSignal(const QObject *sender, int signal_index);
static QVariant resolvedUrlSequence(const QVariant &value, QQmlContextData *context);
+ static QQmlProperty create(QObject *target, const QString &propertyName, QQmlContextData *context);
+
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyPrivate::BindingFlags)
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 7178dffa8b..88eda9c020 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -243,9 +243,9 @@ void QQmlPropertyData::lazyLoad(const QMetaMethod &m)
Creates a new empty QQmlPropertyCache.
*/
QQmlPropertyCache::QQmlPropertyCache()
- : _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
+ : _parent(nullptr), propertyIndexCacheStart(0), methodIndexCacheStart(0),
signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false),
- _metaObject(0), argumentsCache(0), _jsFactoryMethodIndex(-1)
+ _metaObject(nullptr), argumentsCache(nullptr), _jsFactoryMethodIndex(-1)
{
}
@@ -277,8 +277,8 @@ QQmlPropertyCache::~QQmlPropertyCache()
if (_parent) _parent->release();
if (_ownMetaObject) free(const_cast<QMetaObject *>(_metaObject));
- _metaObject = 0;
- _parent = 0;
+ _metaObject = nullptr;
+ _parent = nullptr;
}
QQmlPropertyCache *QQmlPropertyCache::copy(int reserve)
@@ -310,7 +310,7 @@ QQmlPropertyCache *QQmlPropertyCache::copyAndReserve(int propertyCount, int meth
rv->methodIndexCache.reserve(methodCount);
rv->signalHandlerIndexCache.reserve(signalCount);
rv->enumCache.reserve(enumCount);
- rv->_metaObject = 0;
+ rv->_metaObject = nullptr;
return rv;
}
@@ -321,13 +321,14 @@ QQmlPropertyCache *QQmlPropertyCache::copyAndReserve(int propertyCount, int meth
This is different from QMetaMethod::methodIndex().
*/
void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Flags flags,
- int coreIndex, int propType, int notifyIndex)
+ int coreIndex, int propType, int minorVersion, int notifyIndex)
{
QQmlPropertyData data;
data.setPropType(propType);
data.setCoreIndex(coreIndex);
data.setNotifyIndex(notifyIndex);
data.setFlags(flags);
+ data.setTypeMinorVersion(minorVersion);
QQmlPropertyData *old = findNamedProperty(name);
if (old)
@@ -336,7 +337,7 @@ void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Fl
int index = propertyIndexCache.count();
propertyIndexCache.append(data);
- setNamedProperty(name, index + propertyOffset(), propertyIndexCache.data() + index, (old != 0));
+ setNamedProperty(name, index + propertyOffset(), propertyIndexCache.data() + index, (old != nullptr));
}
void QQmlPropertyCache::appendSignal(const QString &name, QQmlPropertyData::Flags flags,
@@ -373,8 +374,8 @@ void QQmlPropertyCache::appendSignal(const QString &name, QQmlPropertyData::Flag
QString handlerName = QLatin1String("on") + name;
handlerName[2] = handlerName.at(2).toUpper();
- setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex, (old != 0));
- setNamedProperty(handlerName, signalHandlerIndex + signalOffset(), signalHandlerIndexCache.data() + signalHandlerIndex, (old != 0));
+ setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex, (old != nullptr));
+ setNamedProperty(handlerName, signalHandlerIndex + signalOffset(), signalHandlerIndexCache.data() + signalHandlerIndex, (old != nullptr));
}
void QQmlPropertyCache::appendMethod(const QString &name, QQmlPropertyData::Flags flags,
@@ -401,7 +402,7 @@ void QQmlPropertyCache::appendMethod(const QString &name, QQmlPropertyData::Flag
int methodIndex = methodIndexCache.count();
methodIndexCache.append(data);
- setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex, (old != 0));
+ setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex, (old != nullptr));
}
void QQmlPropertyCache::appendEnum(const QString &name, const QVector<QQmlEnumValue> &values)
@@ -429,7 +430,7 @@ const QMetaObject *QQmlPropertyCache::createMetaObject()
QQmlPropertyData *QQmlPropertyCache::defaultProperty() const
{
- return property(defaultPropertyName(), 0, 0);
+ return property(defaultPropertyName(), nullptr, nullptr);
}
void QQmlPropertyCache::setParent(QQmlPropertyCache *newParent)
@@ -542,7 +543,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
}
QQmlPropertyData *data = &methodIndexCache[ii - methodIndexCacheStart];
- QQmlPropertyData *sigdata = 0;
+ QQmlPropertyData *sigdata = nullptr;
if (m.methodType() == QMetaMethod::Signal)
data->setFlags(signalFlags);
@@ -561,24 +562,24 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
sigdata->_flags.isSignalHandler = true;
}
- QQmlPropertyData *old = 0;
+ QQmlPropertyData *old = nullptr;
if (utf8) {
QHashedString methodName(QString::fromUtf8(rawName, cptr - rawName));
if (StringCache::mapped_type *it = stringCache.value(methodName))
old = it->second;
- setNamedProperty(methodName, ii, data, (old != 0));
+ setNamedProperty(methodName, ii, data, (old != nullptr));
if (data->isSignal()) {
QHashedString on(QLatin1String("on") % methodName.at(0).toUpper() % methodName.midRef(1));
- setNamedProperty(on, ii, sigdata, (old != 0));
+ setNamedProperty(on, ii, sigdata, (old != nullptr));
++signalHandlerIndex;
}
} else {
QHashedCStringRef methodName(rawName, cptr - rawName);
if (StringCache::mapped_type *it = stringCache.value(methodName))
old = it->second;
- setNamedProperty(methodName, ii, data, (old != 0));
+ setNamedProperty(methodName, ii, data, (old != nullptr));
if (data->isSignal()) {
int length = methodName.length();
@@ -592,7 +593,7 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
str[length + 2] = '\0';
QHashedString on(QString::fromLatin1(str.data()));
- setNamedProperty(on, ii, data, (old != 0));
+ setNamedProperty(on, ii, data, (old != nullptr));
++signalHandlerIndex;
}
}
@@ -635,18 +636,18 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
Q_ASSERT((allowedRevisionCache.count() - 1) < Q_INT16_MAX);
data->setMetaObjectOffset(allowedRevisionCache.count() - 1);
- QQmlPropertyData *old = 0;
+ QQmlPropertyData *old = nullptr;
if (utf8) {
QHashedString propName(QString::fromUtf8(str, cptr - str));
if (StringCache::mapped_type *it = stringCache.value(propName))
old = it->second;
- setNamedProperty(propName, ii, data, (old != 0));
+ setNamedProperty(propName, ii, data, (old != nullptr));
} else {
QHashedCStringRef propName(str, cptr - str);
if (StringCache::mapped_type *it = stringCache.value(propName))
old = it->second;
- setNamedProperty(propName, ii, data, (old != 0));
+ setNamedProperty(propName, ii, data, (old != nullptr));
}
bool isGadget = true;
@@ -749,7 +750,7 @@ void QQmlPropertyCache::invalidate(const QMetaObject *metaObject)
signalHandlerIndexCache.clear();
_hasPropertyOverrides = false;
- argumentsCache = 0;
+ argumentsCache = nullptr;
int pc = metaObject->propertyCount();
int mc = metaObject->methodCount();
@@ -772,8 +773,8 @@ void QQmlPropertyCache::invalidate(const QMetaObject *metaObject)
QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it, QObject *object, QQmlContextData *context) const
{
- QQmlData *data = (object ? QQmlData::get(object) : 0);
- const QQmlVMEMetaObject *vmemo = 0;
+ QQmlData *data = (object ? QQmlData::get(object) : nullptr);
+ const QQmlVMEMetaObject *vmemo = nullptr;
if (data && data->hasVMEMetaObject) {
QObjectPrivate *op = QObjectPrivate::get(object);
vmemo = static_cast<const QQmlVMEMetaObject *>(op->metaObject);
@@ -848,7 +849,7 @@ QQmlPropertyData *QQmlPropertyCache::findProperty(StringCache::ConstIterator it,
return ensureResolved(result);
}
- return 0;
+ return nullptr;
}
QString QQmlPropertyData::name(QObject *object) const
@@ -918,9 +919,9 @@ QQmlPropertyCacheMethodArguments *QQmlPropertyCache::createArgumentsObject(int a
A *args = static_cast<A *>(malloc(sizeof(A) + (argc) * sizeof(int)));
args->arguments[0] = argc;
args->argumentsValid = false;
- args->signalParameterStringForJS = 0;
+ args->signalParameterStringForJS = nullptr;
args->parameterError = false;
- args->names = argc ? new QList<QByteArray>(names) : 0;
+ args->names = argc ? new QList<QByteArray>(names) : nullptr;
args->next = argumentsCache;
argumentsCache = args;
return args;
@@ -1026,10 +1027,10 @@ static QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, c
}
/* If the "cmo" variable didn't change, set it to 0 to
* avoid running into an infinite loop */
- if (!changed) cmo = 0;
+ if (!changed) cmo = nullptr;
}
} else {
- cmo = 0;
+ cmo = nullptr;
}
}
}
@@ -1056,7 +1057,7 @@ QQmlPropertyData *
qQmlPropertyCacheProperty(QJSEngine *engine, QObject *obj, T name,
QQmlContextData *context, QQmlPropertyData &local)
{
- QQmlPropertyCache *cache = 0;
+ QQmlPropertyCache *cache = nullptr;
QQmlData *ddata = QQmlData::get(obj, false);
@@ -1072,7 +1073,7 @@ qQmlPropertyCacheProperty(QJSEngine *engine, QObject *obj, T name,
}
}
- QQmlPropertyData *rv = 0;
+ QQmlPropertyData *rv = nullptr;
if (cache) {
rv = cache->property(name, obj, context);
@@ -1213,7 +1214,7 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder)
// '+=' reserves extra capacity. Follow-up appending will be probably free.
signature += methods.at(ii).first.toUtf8() + '(';
- QQmlPropertyCacheMethodArguments *arguments = 0;
+ QQmlPropertyCacheMethodArguments *arguments = nullptr;
if (data->hasArguments()) {
arguments = (QQmlPropertyCacheMethodArguments *)data->arguments();
Q_ASSERT(arguments->argumentsValid);
@@ -1251,7 +1252,7 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder)
}
if (!_defaultPropertyName.isEmpty()) {
- QQmlPropertyData *dp = property(_defaultPropertyName, 0, 0);
+ QQmlPropertyData *dp = property(_defaultPropertyName, nullptr, nullptr);
if (dp && dp->coreIndex() >= propertyIndexCacheStart) {
Q_ASSERT(!dp->isFunction());
builder.addClassInfo("DefaultProperty", _defaultPropertyName.toUtf8());
@@ -1576,7 +1577,7 @@ void QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(QMetaObject::Call type,
QQmlPropertyCache *QQmlMetaObject::propertyCache(QQmlEnginePrivate *e) const
{
- if (_m.isNull()) return 0;
+ if (_m.isNull()) return nullptr;
if (_m.isT1()) return _m.asT1();
else return e->cache(_m.asT2());
}
@@ -1587,7 +1588,7 @@ int QQmlMetaObject::methodReturnType(const QQmlPropertyData &data, QByteArray *u
int type = data.propType();
- const char *propTypeName = 0;
+ const char *propTypeName = nullptr;
if (type == QMetaType::UnknownType) {
// Find the return type name from the method info
@@ -1675,7 +1676,7 @@ int *QQmlMetaObject::methodParameterTypes(int index, ArgTypeStorage *argStorage,
}
if (type == QMetaType::UnknownType) {
if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
- return 0;
+ return nullptr;
}
args->arguments[ii + 1] = type;
}
@@ -1714,7 +1715,7 @@ int *QQmlMetaObject::methodParameterTypes(const QMetaMethod &m, ArgTypeStorage *
}
if (type == QMetaType::UnknownType) {
if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
- return 0;
+ return nullptr;
}
argStorage->operator[](ii + 1) = type;
}
@@ -1726,7 +1727,7 @@ void QQmlObjectOrGadget::metacall(QMetaObject::Call type, int index, void **argv
{
if (ptr.isNull()) {
const QMetaObject *metaObject = _m.asT2();
- metaObject->d.static_metacall(0, type, index, argv);
+ metaObject->d.static_metacall(nullptr, type, index, argv);
}
else if (ptr.isT1()) {
QMetaObject::metacall(ptr.asT1(), type, index, argv);
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 6f4879baa2..5553fe6b80 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -245,12 +245,36 @@ public:
_coreIndex = qint16(idx);
}
- int revision() const { return _revision; }
- void setRevision(int rev)
+ quint8 revision() const { return _revision; }
+ void setRevision(quint8 rev)
{
- Q_ASSERT(rev >= std::numeric_limits<qint16>::min());
- Q_ASSERT(rev <= std::numeric_limits<qint16>::max());
- _revision = qint16(rev);
+ Q_ASSERT(rev <= std::numeric_limits<quint8>::max());
+ _revision = quint8(rev);
+ }
+
+ /* If a property is a C++ type, then we store the minor
+ * version of this type.
+ * This is required to resolve property or signal revisions
+ * if this property is used as a grouped property.
+ *
+ * Test.qml
+ * property TextEdit someTextEdit: TextEdit {}
+ *
+ * Test {
+ * someTextEdit.preeditText: "test" //revision 7
+ * someTextEdit.onEditingFinished: console.log("test") //revision 6
+ * }
+ *
+ * To determine if these properties with revisions are available we need
+ * the minor version of TextEdit as imported in Test.qml.
+ *
+ */
+
+ quint8 typeMinorVersion() const { return _typeMinorVersion; }
+ void setTypeMinorVersion(quint8 rev)
+ {
+ Q_ASSERT(rev <= std::numeric_limits<quint8>::max());
+ _typeMinorVersion = quint8(rev);
}
QQmlPropertyCacheMethodArguments *arguments() const { return _arguments; }
@@ -284,7 +308,8 @@ private:
qint16 _notifyIndex;
qint16 _overrideIndex;
- qint16 _revision;
+ quint8 _revision;
+ quint8 _typeMinorVersion;
qint16 _metaObjectOffset;
QQmlPropertyCacheMethodArguments *_arguments;
@@ -325,7 +350,7 @@ public:
inline void readProperty(QObject *target, void *property) const
{
- void *args[] = { property, 0 };
+ void *args[] = { property, nullptr };
readPropertyWithArgs(target, args);
}
@@ -342,7 +367,7 @@ public:
bool writeProperty(QObject *target, void *value, WriteFlags flags) const
{
int status = -1;
- void *argv[] = { value, 0, &status, &flags };
+ void *argv[] = { value, nullptr, &status, &flags };
if (flags.testFlag(BypassInterceptor) && hasStaticMetaCallFunction())
staticMetaCallFunction()(target, QMetaObject::WriteProperty, relativePropertyIndex(), argv);
else if (flags.testFlag(BypassInterceptor) && isDirect())
@@ -378,10 +403,10 @@ private:
struct QQmlEnumValue
{
- QQmlEnumValue() : value(-1) {}
+ QQmlEnumValue() {}
QQmlEnumValue(const QString &n, int v) : namedValue(n), value(v) {}
QString namedValue;
- int value;
+ int value = -1;
};
struct QQmlEnumData
@@ -396,7 +421,7 @@ class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount
public:
QQmlPropertyCache();
QQmlPropertyCache(const QMetaObject *);
- virtual ~QQmlPropertyCache();
+ ~QQmlPropertyCache() override;
void update(const QMetaObject *);
void invalidate(const QMetaObject *);
@@ -417,9 +442,9 @@ public:
QQmlPropertyCache *copyAndReserve(int propertyCount,
int methodCount, int signalCount, int enumCount);
void appendProperty(const QString &, QQmlPropertyRawData::Flags flags, int coreIndex,
- int propType, int notifyIndex);
+ int propType, int revision, int notifyIndex);
void appendSignal(const QString &, QQmlPropertyRawData::Flags, int coreIndex,
- const int *types = 0, const QList<QByteArray> &names = QList<QByteArray>());
+ const int *types = nullptr, const QList<QByteArray> &names = QList<QByteArray>());
void appendMethod(const QString &, QQmlPropertyData::Flags flags, int coreIndex,
const QList<QByteArray> &names = QList<QByteArray>());
void appendEnum(const QString &, const QVector<QQmlEnumValue> &);
@@ -467,7 +492,7 @@ public:
static int originalClone(QObject *, int index);
QList<QByteArray> signalParameterNames(int index) const;
- static QString signalParameterStringForJS(QV4::ExecutionEngine *engine, const QList<QByteArray> &parameterNameList, QString *errorString = 0);
+ static QString signalParameterStringForJS(QV4::ExecutionEngine *engine, const QList<QByteArray> &parameterNameList, QString *errorString = nullptr);
const char *className() const;
@@ -741,7 +766,7 @@ inline const QMetaObject *QQmlPropertyCache::metaObject() const
// QML
inline const QMetaObject *QQmlPropertyCache::firstCppMetaObject() const
{
- while (_parent && (_metaObject == 0 || _ownMetaObject))
+ while (_parent && (_metaObject == nullptr || _ownMetaObject))
return _parent->firstCppMetaObject();
return _metaObject;
}
@@ -749,7 +774,7 @@ inline const QMetaObject *QQmlPropertyCache::firstCppMetaObject() const
inline QQmlPropertyData *QQmlPropertyCache::property(int index) const
{
if (index < 0 || index >= (propertyIndexCacheStart + propertyIndexCache.count()))
- return 0;
+ return nullptr;
if (index < propertyIndexCacheStart)
return _parent->property(index);
@@ -761,7 +786,7 @@ inline QQmlPropertyData *QQmlPropertyCache::property(int index) const
inline QQmlPropertyData *QQmlPropertyCache::method(int index) const
{
if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.count()))
- return 0;
+ return nullptr;
if (index < methodIndexCacheStart)
return _parent->method(index);
@@ -777,7 +802,7 @@ inline QQmlPropertyData *QQmlPropertyCache::method(int index) const
inline QQmlPropertyData *QQmlPropertyCache::signal(int index) const
{
if (index < 0 || index >= (signalHandlerIndexCacheStart + signalHandlerIndexCache.count()))
- return 0;
+ return nullptr;
if (index < signalHandlerIndexCacheStart)
return _parent->signal(index);
@@ -790,7 +815,7 @@ inline QQmlPropertyData *QQmlPropertyCache::signal(int index) const
inline QQmlEnumData *QQmlPropertyCache::qmlEnum(int index) const
{
if (index < 0 || index >= enumCache.count())
- return 0;
+ return nullptr;
return const_cast<QQmlEnumData *>(&enumCache.at(index));
}
@@ -821,7 +846,7 @@ QQmlPropertyData *
QQmlPropertyCache::overrideData(QQmlPropertyData *data) const
{
if (!data->hasOverride())
- return 0;
+ return nullptr;
if (data->overrideIndexIsProperty())
return property(data->overrideIndex());
@@ -923,7 +948,7 @@ bool QQmlMetaObject::isNull() const
const char *QQmlMetaObject::className() const
{
if (_m.isNull()) {
- return 0;
+ return nullptr;
} else if (_m.isT1()) {
return _m.asT1()->className();
} else {
@@ -949,7 +974,7 @@ bool QQmlMetaObject::hasMetaObject() const
const QMetaObject *QQmlMetaObject::metaObject() const
{
- if (_m.isNull()) return 0;
+ if (_m.isNull()) return nullptr;
if (_m.isT1()) return _m.asT1()->createMetaObject();
else return _m.asT2();
}
diff --git a/src/qml/qml/qqmlpropertyvalueinterceptor.cpp b/src/qml/qml/qqmlpropertyvalueinterceptor.cpp
index 52c003ab59..603245f29d 100644
--- a/src/qml/qml/qqmlpropertyvalueinterceptor.cpp
+++ b/src/qml/qml/qqmlpropertyvalueinterceptor.cpp
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
/*!
Constructs a QQmlPropertyValueInterceptor.
*/
-QQmlPropertyValueInterceptor::QQmlPropertyValueInterceptor() : m_next(0)
+QQmlPropertyValueInterceptor::QQmlPropertyValueInterceptor() : m_next(nullptr)
{
}
diff --git a/src/qml/qml/qqmlproxymetaobject.cpp b/src/qml/qml/qqmlproxymetaobject.cpp
index 27e3c13ff8..e1500f70fb 100644
--- a/src/qml/qml/qqmlproxymetaobject.cpp
+++ b/src/qml/qml/qqmlproxymetaobject.cpp
@@ -43,7 +43,7 @@
QT_BEGIN_NAMESPACE
QQmlProxyMetaObject::QQmlProxyMetaObject(QObject *obj, QList<ProxyData> *mList)
-: metaObjects(mList), proxies(0), parent(0), object(obj)
+: metaObjects(mList), proxies(nullptr), parent(nullptr), object(obj)
{
*static_cast<QMetaObject *>(this) = *metaObjects->constFirst().metaObject;
@@ -58,11 +58,11 @@ QQmlProxyMetaObject::~QQmlProxyMetaObject()
{
if (parent)
delete parent;
- parent = 0;
+ parent = nullptr;
if (proxies)
delete [] proxies;
- proxies = 0;
+ proxies = nullptr;
}
int QQmlProxyMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void **a)
diff --git a/src/qml/qml/qqmlscriptstring_p.h b/src/qml/qml/qqmlscriptstring_p.h
index 2dfb817186..fd8ccd5d53 100644
--- a/src/qml/qml/qqmlscriptstring_p.h
+++ b/src/qml/qml/qqmlscriptstring_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class Q_AUTOTEST_EXPORT QQmlScriptStringPrivate : public QSharedData
{
public:
- QQmlScriptStringPrivate() : context(0), scope(0), bindingId(-1), lineNumber(0), columnNumber(0),
+ QQmlScriptStringPrivate() : context(nullptr), scope(nullptr), bindingId(-1), lineNumber(0), columnNumber(0),
numberValue(0), isStringLiteral(false), isNumberLiteral(false) {}
//for testing
diff --git a/src/qml/qml/qqmlstringconverters_p.h b/src/qml/qml/qqmlstringconverters_p.h
index af344e3344..215f0c0aaf 100644
--- a/src/qml/qml/qqmlstringconverters_p.h
+++ b/src/qml/qml/qqmlstringconverters_p.h
@@ -67,19 +67,19 @@ class QByteArray;
namespace QQmlStringConverters
{
Q_QML_PRIVATE_EXPORT QVariant variantFromString(const QString &);
- Q_QML_PRIVATE_EXPORT QVariant variantFromString(const QString &, int preferredType, bool *ok = 0);
+ Q_QML_PRIVATE_EXPORT QVariant variantFromString(const QString &, int preferredType, bool *ok = nullptr);
- Q_QML_PRIVATE_EXPORT QVariant colorFromString(const QString &, bool *ok = 0);
- Q_QML_PRIVATE_EXPORT unsigned rgbaFromString(const QString &, bool *ok = 0);
+ Q_QML_PRIVATE_EXPORT QVariant colorFromString(const QString &, bool *ok = nullptr);
+ Q_QML_PRIVATE_EXPORT unsigned rgbaFromString(const QString &, bool *ok = nullptr);
#if QT_CONFIG(datestring)
- Q_QML_PRIVATE_EXPORT QDate dateFromString(const QString &, bool *ok = 0);
- Q_QML_PRIVATE_EXPORT QTime timeFromString(const QString &, bool *ok = 0);
- Q_QML_PRIVATE_EXPORT QDateTime dateTimeFromString(const QString &, bool *ok = 0);
+ Q_QML_PRIVATE_EXPORT QDate dateFromString(const QString &, bool *ok = nullptr);
+ Q_QML_PRIVATE_EXPORT QTime timeFromString(const QString &, bool *ok = nullptr);
+ Q_QML_PRIVATE_EXPORT QDateTime dateTimeFromString(const QString &, bool *ok = nullptr);
#endif
- Q_QML_PRIVATE_EXPORT QPointF pointFFromString(const QString &, bool *ok = 0);
- Q_QML_PRIVATE_EXPORT QSizeF sizeFFromString(const QString &, bool *ok = 0);
- Q_QML_PRIVATE_EXPORT QRectF rectFFromString(const QString &, bool *ok = 0);
+ Q_QML_PRIVATE_EXPORT QPointF pointFFromString(const QString &, bool *ok = nullptr);
+ Q_QML_PRIVATE_EXPORT QSizeF sizeFFromString(const QString &, bool *ok = nullptr);
+ Q_QML_PRIVATE_EXPORT QRectF rectFFromString(const QString &, bool *ok = nullptr);
Q_QML_PRIVATE_EXPORT bool createFromString(int, const QString &, void *, size_t);
}
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 9285328892..5212b49670 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -156,8 +156,8 @@ public:
void loadAsync(QQmlDataBlob *b);
void loadWithStaticData(QQmlDataBlob *b, const QByteArray &);
void loadWithStaticDataAsync(QQmlDataBlob *b, const QByteArray &);
- void loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
- void loadWithCachedUnitAsync(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
+ void loadWithCachedUnit(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
+ void loadWithCachedUnitAsync(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
void callCompleted(QQmlDataBlob *b);
void callDownloadProgressChanged(QQmlDataBlob *b, qreal p);
void initializeEngine(QQmlExtensionInterface *, const char *);
@@ -168,7 +168,7 @@ protected:
private:
void loadThread(QQmlDataBlob *b);
void loadWithStaticDataThread(QQmlDataBlob *b, const QByteArray &);
- void loadWithCachedUnitThread(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
+ void loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
void callCompletedMain(QQmlDataBlob *b);
void callDownloadProgressChangedMain(QQmlDataBlob *b, qreal p);
void initializeEngineMain(QQmlExtensionInterface *iface, const char *uri);
@@ -317,7 +317,8 @@ Returns true if the status is WaitingForDependencies.
*/
bool QQmlDataBlob::isWaiting() const
{
- return status() == WaitingForDependencies;
+ return status() == WaitingForDependencies ||
+ status() == ResolvingDependencies;
}
/*!
@@ -356,8 +357,10 @@ qreal QQmlDataBlob::progress() const
}
/*!
-Returns the blob url passed to the constructor. If a network redirect
-happens while fetching the data, this url remains the same.
+Returns the physical url of the data. Initially this is the same as
+finalUrl(), but if a network redirect happens while fetching the data, this url
+is updated to reflect the new location. Also, if a URL interceptor is set, it
+will work on this URL and leave finalUrl() alone.
\sa finalUrl()
*/
@@ -366,16 +369,25 @@ QUrl QQmlDataBlob::url() const
return m_url;
}
+QString QQmlDataBlob::urlString() const
+{
+ if (m_urlString.isEmpty())
+ m_urlString = m_url.toString();
+
+ return m_urlString;
+}
+
/*!
-Returns the final url of the data. Initially this is the same as
-url(), but if a network redirect happens while fetching the data, this url
-is updated to reflect the new location.
+Returns the logical URL to be used for resolving further URLs referred to in
+the code.
-May only be called from the load thread, or after the blob isCompleteOrError().
+This is the blob url passed to the constructor. If a network redirect
+happens while fetching the data, this url remains the same.
+
+\sa url()
*/
QUrl QQmlDataBlob::finalUrl() const
{
- Q_ASSERT(isCompleteOrError() || (m_typeLoader && m_typeLoader->m_thread->isThisThread()));
return m_finalUrl;
}
@@ -384,7 +396,6 @@ Returns the finalUrl() as a string.
*/
QString QQmlDataBlob::finalUrlString() const
{
- Q_ASSERT(isCompleteOrError() || (m_typeLoader && m_typeLoader->m_thread->isThisThread()));
if (m_finalUrlString.isEmpty())
m_finalUrlString = m_finalUrl.toString();
@@ -433,7 +444,7 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors)
m_data.setStatus(Error);
if (dumpErrors()) {
- qWarning().nospace() << "Errors for " << m_finalUrl.toString();
+ qWarning().nospace() << "Errors for " << urlString();
for (int ii = 0; ii < errors.count(); ++ii)
qWarning().nospace() << " " << qPrintable(errors.at(ii).toString());
}
@@ -472,7 +483,7 @@ void QQmlDataBlob::setError(const QString &description)
{
QQmlError e;
e.setDescription(description);
- e.setUrl(finalUrl());
+ e.setUrl(url());
setError(e);
}
@@ -538,9 +549,9 @@ void QQmlDataBlob::networkError(QNetworkReply::NetworkError networkError)
Q_UNUSED(networkError);
QQmlError error;
- error.setUrl(m_finalUrl);
+ error.setUrl(m_url);
- const char *errorString = 0;
+ const char *errorString = nullptr;
switch (networkError) {
default:
errorString = "Network error";
@@ -610,6 +621,7 @@ The default implementation does nothing.
*/
void QQmlDataBlob::allDependenciesDone()
{
+ m_data.setStatus(QQmlDataBlob::ResolvingDependencies);
}
/*!
@@ -654,7 +666,7 @@ void QQmlDataBlob::tryDone()
addref();
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataBlob::done() %s", qPrintable(url().toString()));
+ qWarning("QQmlDataBlob::done() %s", qPrintable(urlString()));
#endif
done();
@@ -780,7 +792,7 @@ void QQmlDataBlob::ThreadData::setProgress(quint8 v)
QQmlTypeLoaderThread::QQmlTypeLoaderThread(QQmlTypeLoader *loader)
: m_loader(loader)
#if QT_CONFIG(qml_network)
-, m_networkAccessManager(0), m_networkReplyProxy(0)
+, m_networkAccessManager(nullptr), m_networkReplyProxy(nullptr)
#endif // qml_network
{
// Do that after initializing all the members.
@@ -792,7 +804,7 @@ QNetworkAccessManager *QQmlTypeLoaderThread::networkAccessManager() const
{
Q_ASSERT(isThisThread());
if (!m_networkAccessManager) {
- m_networkAccessManager = QQmlEnginePrivate::get(m_loader->engine())->createNetworkAccessManager(0);
+ m_networkAccessManager = QQmlEnginePrivate::get(m_loader->engine())->createNetworkAccessManager(nullptr);
m_networkReplyProxy = new QQmlTypeLoaderNetworkReplyProxy(m_loader);
}
@@ -831,13 +843,13 @@ void QQmlTypeLoaderThread::loadWithStaticDataAsync(QQmlDataBlob *b, const QByteA
postMethodToThread(&This::loadWithStaticDataThread, b, d);
}
-void QQmlTypeLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
{
b->addref();
callMethodInThread(&This::loadWithCachedUnitThread, b, unit);
}
-void QQmlTypeLoaderThread::loadWithCachedUnitAsync(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoaderThread::loadWithCachedUnitAsync(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
{
b->addref();
postMethodToThread(&This::loadWithCachedUnitThread, b, unit);
@@ -865,9 +877,9 @@ void QQmlTypeLoaderThread::shutdownThread()
{
#if QT_CONFIG(qml_network)
delete m_networkAccessManager;
- m_networkAccessManager = 0;
+ m_networkAccessManager = nullptr;
delete m_networkReplyProxy;
- m_networkReplyProxy = 0;
+ m_networkReplyProxy = nullptr;
#endif // qml_network
}
@@ -883,7 +895,7 @@ void QQmlTypeLoaderThread::loadWithStaticDataThread(QQmlDataBlob *b, const QByte
b->release();
}
-void QQmlTypeLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
{
m_loader->loadWithCachedUnitThread(b, unit);
b->release();
@@ -893,7 +905,7 @@ void QQmlTypeLoaderThread::callCompletedMain(QQmlDataBlob *b)
{
QML_MEMORY_SCOPE_URL(b->url());
#ifdef DATABLOB_DEBUG
- qWarning("QQmlTypeLoaderThread: %s completed() callback", qPrintable(b->url().toString()));
+ qWarning("QQmlTypeLoaderThread: %s completed() callback", qPrintable(b->urlString()));
#endif
b->completed();
b->release();
@@ -903,7 +915,7 @@ void QQmlTypeLoaderThread::callDownloadProgressChangedMain(QQmlDataBlob *b, qrea
{
#ifdef DATABLOB_DEBUG
qWarning("QQmlTypeLoaderThread: %s downloadProgressChanged(%f) callback",
- qPrintable(b->url().toString()), p);
+ qPrintable(b->urlString()), p);
#endif
b->downloadProgressChanged(p);
b->release();
@@ -951,7 +963,7 @@ void QQmlTypeLoader::invalidate()
if (m_thread) {
shutdownThread();
delete m_thread;
- m_thread = 0;
+ m_thread = nullptr;
}
#if QT_CONFIG(qml_network)
@@ -1021,8 +1033,8 @@ struct StaticLoader {
};
struct CachedLoader {
- const QQmlPrivate::CachedQmlUnit *unit;
- CachedLoader(const QQmlPrivate::CachedQmlUnit *unit) : unit(unit) {}
+ const QV4::CompiledData::Unit *unit;
+ CachedLoader(const QV4::CompiledData::Unit *unit) : unit(unit) {}
void loadThread(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
{
@@ -1042,7 +1054,7 @@ template<typename Loader>
void QQmlTypeLoader::doLoad(const Loader &loader, QQmlDataBlob *blob, Mode mode)
{
#ifdef DATABLOB_DEBUG
- qWarning("QQmlTypeLoader::doLoad(%s): %s thread", qPrintable(blob->m_url.toString()),
+ qWarning("QQmlTypeLoader::doLoad(%s): %s thread", qPrintable(blob->urlString()),
m_thread->isThisThread()?"Compile":"Engine");
#endif
#ifdef Q_OS_HTML5
@@ -1095,7 +1107,7 @@ void QQmlTypeLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &da
doLoad(StaticLoader(data), blob, mode);
}
-void QQmlTypeLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode)
+void QQmlTypeLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit, Mode mode)
{
doLoad(CachedLoader(unit), blob, mode);
}
@@ -1107,7 +1119,7 @@ void QQmlTypeLoader::loadWithStaticDataThread(QQmlDataBlob *blob, const QByteArr
setData(blob, data);
}
-void QQmlTypeLoader::loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoader::loadWithCachedUnitThread(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
{
ASSERT_LOADTHREAD();
@@ -1165,7 +1177,7 @@ void QQmlTypeLoader::loadThread(QQmlDataBlob *blob)
}
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataBlob: requested %s", qPrintable(blob->url().toString()));
+ qWarning("QQmlDataBlob: requested %s", qPrintable(blob->urlString()));
#endif // DATABLOB_DEBUG
#endif // qml_network
}
@@ -1191,14 +1203,15 @@ void QQmlTypeLoader::networkReplyFinished(QNetworkReply *reply)
QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
QUrl url = reply->url().resolved(redirect.toUrl());
- blob->m_finalUrl = url;
+ blob->m_url = url;
+ blob->m_urlString.clear();
QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(url));
QObject *nrp = m_thread->networkReplyProxy();
QObject::connect(reply, SIGNAL(finished()), nrp, SLOT(finished()));
m_networkReplies.insert(reply, blob);
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->m_finalUrl.toString()));
+ qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->urlString()));
#endif
return;
}
@@ -1294,7 +1307,7 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeD
blob->tryDone();
}
-void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
{
QML_MEMORY_SCOPE_URL(blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
@@ -1354,7 +1367,7 @@ bool QQmlTypeLoader::Blob::fetchQmldir(const QUrl &url, const QV4::CompiledData:
bool QQmlTypeLoader::Blob::updateQmldir(QQmlQmldirData *data, const QV4::CompiledData::Import *import, QList<QQmlError> *errors)
{
- QString qmldirIdentifier = data->url().toString();
+ QString qmldirIdentifier = data->urlString();
QString qmldirUrl = qmldirIdentifier.left(qmldirIdentifier.lastIndexOf(QLatin1Char('/')) + 1);
typeLoader()->setQmldirContent(qmldirIdentifier, data->content());
@@ -1442,8 +1455,13 @@ bool QQmlTypeLoader::Blob::addImport(const QV4::CompiledData::Import *import, QL
// We haven't yet resolved this import
m_unresolvedImports.insert(import, 0);
- // Query any network import paths for this library
- QStringList remotePathList = importDatabase->importPathList(QQmlImportDatabase::Remote);
+ QQmlAbstractUrlInterceptor *interceptor = typeLoader()->engine()->urlInterceptor();
+
+ // Query any network import paths for this library.
+ // Interceptor might redirect local paths.
+ QStringList remotePathList = importDatabase->importPathList(
+ interceptor ? QQmlImportDatabase::LocalOrRemote
+ : QQmlImportDatabase::Remote);
if (!remotePathList.isEmpty()) {
// Add this library and request the possible locations for it
if (!m_importCache.addLibraryImport(importDatabase, importUri, importQualifier, import->majorVersion,
@@ -1454,8 +1472,18 @@ bool QQmlTypeLoader::Blob::addImport(const QV4::CompiledData::Import *import, QL
int priority = 0;
const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(importUri, remotePathList, import->majorVersion, import->minorVersion);
for (const QString &qmldirPath : qmlDirPaths) {
- if (!fetchQmldir(QUrl(qmldirPath), import, ++priority, errors))
+ if (interceptor) {
+ QUrl url = interceptor->intercept(
+ QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
+ QQmlAbstractUrlInterceptor::QmldirFile);
+ if (!QQmlFile::isLocalFile(url)
+ && !fetchQmldir(url, import, ++priority, errors)) {
+ return false;
+ }
+ } else if (!fetchQmldir(QUrl(qmldirPath), import, ++priority, errors)) {
return false;
+ }
+
}
}
}
@@ -1514,7 +1542,7 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob)
bool QQmlTypeLoader::Blob::isDebugging() const
{
- return QV8Engine::getV4(typeLoader()->engine())->debugger() != 0;
+ return typeLoader()->engine()->handle()->debugger() != nullptr;
}
bool QQmlTypeLoader::Blob::qmldirDataAvailable(QQmlQmldirData *data, QList<QQmlError> *errors)
@@ -1522,7 +1550,7 @@ bool QQmlTypeLoader::Blob::qmldirDataAvailable(QQmlQmldirData *data, QList<QQmlE
bool resolve = true;
const QV4::CompiledData::Import *import = data->import(this);
- data->setImport(this, 0);
+ data->setImport(this, nullptr);
int priority = data->priority(this);
data->setPriority(this, 0);
@@ -1656,7 +1684,7 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode)
typeData = new QQmlTypeData(url, this);
// TODO: if (compiledData == 0), is it safe to omit this insertion?
m_typeCache.insert(url, typeData);
- if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(typeData->url())) {
+ if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(typeData->url())) {
QQmlTypeLoader::loadWithCachedUnit(typeData, cachedUnit, mode);
} else {
QQmlTypeLoader::load(typeData, mode);
@@ -1717,7 +1745,7 @@ QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &url)
scriptBlob = new QQmlScriptBlob(url, this);
m_scriptCache.insert(url, scriptBlob);
- if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(scriptBlob->url())) {
+ if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(scriptBlob->url())) {
QQmlTypeLoader::loadWithCachedUnit(scriptBlob, cachedUnit);
} else {
QQmlTypeLoader::load(scriptBlob);
@@ -1805,7 +1833,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
if (!m_importDirCache.contains(dirPath)) {
bool exists = QDir(dirPath).exists();
- QCache<QString, bool> *entry = exists ? new QCache<QString, bool> : 0;
+ QCache<QString, bool> *entry = exists ? new QCache<QString, bool> : nullptr;
m_importDirCache.insert(dirPath, entry);
}
QCache<QString, bool> *fileSet = m_importDirCache.object(dirPath);
@@ -1868,12 +1896,12 @@ bool QQmlTypeLoader::directoryExists(const QString &path)
if (!m_importDirCache.contains(dirPath)) {
bool exists = QDir(dirPath).exists();
- QCache<QString, bool> *files = exists ? new QCache<QString, bool> : 0;
+ QCache<QString, bool> *files = exists ? new QCache<QString, bool> : nullptr;
m_importDirCache.insert(dirPath, files);
}
QCache<QString, bool> *fileSet = m_importDirCache.object(dirPath);
- return fileSet != 0;
+ return fileSet != nullptr;
}
@@ -1886,19 +1914,22 @@ It can also be a remote path for a remote directory import, but it will have bee
*/
const QQmlTypeLoaderQmldirContent *QQmlTypeLoader::qmldirContent(const QString &filePathIn)
{
- QUrl url(filePathIn); //May already contain http scheme
- if (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("https"))
- return *(m_importQmlDirCache.value(filePathIn)); //Can't load the remote here, but should be cached
- else
- url = QUrl::fromLocalFile(filePathIn);
- if (engine() && engine()->urlInterceptor())
- url = engine()->urlInterceptor()->intercept(url, QQmlAbstractUrlInterceptor::QmldirFile);
- Q_ASSERT(url.scheme() == QLatin1String("file"));
QString filePath;
- if (url.scheme() == QLatin1String("file"))
- filePath = url.toLocalFile();
- else
- filePath = url.path();
+
+ // Try to guess if filePathIn is already a URL. This is necessarily fragile, because
+ // - paths can contain ':', which might make them appear as URLs with schemes.
+ // - windows drive letters appear as schemes (thus "< 2" below).
+ // - a "file:" URL is equivalent to the respective file, but will be treated differently.
+ // Yet, this heuristic is the best we can do until we pass more structured information here,
+ // for example a QUrl also for local files.
+ QUrl url(filePathIn);
+ if (url.scheme().length() < 2) {
+ filePath = filePathIn;
+ } else {
+ filePath = QQmlFile::urlToLocalFileOrQrc(url);
+ if (filePath.isEmpty()) // Can't load the remote here, but should be cached
+ return *(m_importQmlDirCache.value(filePathIn));
+ }
QQmlTypeLoaderQmldirContent *qmldir;
QQmlTypeLoaderQmldirContent **val = m_importQmlDirCache.value(filePath);
@@ -2092,7 +2123,7 @@ bool QQmlTypeData::tryLoadFromDiskCache()
if (isDebugging())
return false;
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(typeLoader()->engine());
+ QV4::ExecutionEngine *v4 = typeLoader()->engine()->handle();
if (!v4)
return false;
@@ -2100,7 +2131,7 @@ bool QQmlTypeData::tryLoadFromDiskCache()
{
QString error;
if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) {
- qCDebug(DBG_DISK_CACHE) << "Error loading" << url().toString() << "from disk cache:" << error;
+ qCDebug(DBG_DISK_CACHE) << "Error loading" << urlString() << "from disk cache:" << error;
return false;
}
}
@@ -2171,8 +2202,12 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeName
QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine());
+ QQmlPendingGroupPropertyBindings pendingGroupPropertyBindings;
+
{
- QQmlPropertyCacheCreator<QV4::CompiledData::CompilationUnit> propertyCacheCreator(&m_compiledData->propertyCaches, engine, m_compiledData, &m_importCache);
+ QQmlPropertyCacheCreator<QV4::CompiledData::CompilationUnit> propertyCacheCreator(&m_compiledData->propertyCaches,
+ &pendingGroupPropertyBindings,
+ engine, m_compiledData, &m_importCache);
QQmlCompileError error = propertyCacheCreator.buildMetaObjects();
if (error.isSet()) {
setError(error);
@@ -2182,6 +2217,8 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeName
QQmlPropertyCacheAliasCreator<QV4::CompiledData::CompilationUnit> aliasCreator(&m_compiledData->propertyCaches, m_compiledData);
aliasCreator.appendAliasPropertiesToMetaObjects();
+
+ pendingGroupPropertyBindings.resolveMissingPropertyCaches(engine, &m_compiledData->propertyCaches);
}
static bool addTypeReferenceChecksumsToHash(const QList<QQmlTypeData::TypeReference> &typeRefs, QCryptographicHash *hash, QQmlEngine *engine)
@@ -2220,10 +2257,10 @@ void QQmlTypeData::done()
if (script.script->isError()) {
QList<QQmlError> errors = script.script->errors();
QQmlError error;
- error.setUrl(finalUrl());
+ error.setUrl(url());
error.setLine(script.location.line);
error.setColumn(script.location.column);
- error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->url().toString()));
+ error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString()));
errors.prepend(error);
setError(errors);
return;
@@ -2240,7 +2277,7 @@ void QQmlTypeData::done()
QList<QQmlError> errors = type.typeData->errors();
QQmlError error;
- error.setUrl(finalUrl());
+ error.setUrl(url());
error.setLine(type.location.line);
error.setColumn(type.location.column);
error.setDescription(QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName));
@@ -2259,7 +2296,7 @@ void QQmlTypeData::done()
QList<QQmlError> errors = type.typeData->errors();
QQmlError error;
- error.setUrl(finalUrl());
+ error.setUrl(url());
error.setLine(type.location.line);
error.setColumn(type.location.column);
error.setDescription(QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName));
@@ -2289,7 +2326,7 @@ void QQmlTypeData::done()
// verify if any dependencies changed if we're using a cache
if (m_document.isNull() && !m_compiledData->verifyChecksum(dependencyHasher)) {
- qCDebug(DBG_DISK_CACHE) << "Checksum mismatch for cached version of" << m_compiledData->url().toString();
+ qCDebug(DBG_DISK_CACHE) << "Checksum mismatch for cached version of" << m_compiledData->fileName();
if (!loadFromSource())
return;
m_backupSourceCode = SourceCodeData();
@@ -2420,10 +2457,14 @@ void QQmlTypeData::dataReceived(const SourceCodeData &data)
continueLoadFromIR();
}
-void QQmlTypeData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeData::initializeFromCachedUnit(const QV4::CompiledData::Unit *unit)
{
m_document.reset(new QmlIR::Document(isDebugging()));
- unit->loadIR(m_document.data(), unit);
+ QmlIR::IRLoader loader(unit, m_document.data());
+ loader.load();
+ m_document->jsModule.fileName = urlString();
+ m_document->jsModule.finalUrl = finalUrlString();
+ m_document->javaScriptCompilationUnit.adopt(new QV4::CompiledData::CompilationUnit(unit));
continueLoadFromIR();
}
@@ -2432,7 +2473,7 @@ bool QQmlTypeData::loadFromSource()
m_document.reset(new QmlIR::Document(isDebugging()));
m_document->jsModule.sourceTimeStamp = m_backupSourceCode.sourceTimeStamp();
QQmlEngine *qmlEngine = typeLoader()->engine();
- QmlIR::IRBuilder compiler(QV8Engine::get(qmlEngine)->illegalNames());
+ QmlIR::IRBuilder compiler(qmlEngine->handle()->v8Engine->illegalNames());
QString sourceError;
const QString source = m_backupSourceCode.readAll(&sourceError);
@@ -2446,7 +2487,7 @@ bool QQmlTypeData::loadFromSource()
errors.reserve(compiler.errors.count());
for (const QQmlJS::DiagnosticMessage &msg : qAsConst(compiler.errors)) {
QQmlError e;
- e.setUrl(finalUrl());
+ e.setUrl(url());
e.setLine(msg.loc.startLine);
e.setColumn(msg.loc.startColumn);
e.setDescription(msg.message);
@@ -2463,7 +2504,8 @@ void QQmlTypeData::restoreIR(QQmlRefPointer<QV4::CompiledData::CompilationUnit>
m_document.reset(new QmlIR::Document(isDebugging()));
QmlIR::IRLoader loader(unit->data, m_document.data());
loader.load();
- m_document->jsModule.fileName = finalUrlString();
+ m_document->jsModule.fileName = urlString();
+ m_document->jsModule.finalUrl = finalUrlString();
m_document->javaScriptCompilationUnit = unit;
continueLoadFromIR();
}
@@ -2515,6 +2557,8 @@ void QQmlTypeData::continueLoadFromIR()
void QQmlTypeData::allDependenciesDone()
{
+ QQmlTypeLoader::Blob::allDependenciesDone();
+
if (!m_typesResolved) {
// Check that all imports were resolved
QList<QQmlError> errors;
@@ -2584,7 +2628,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach
// ignore error, keep using the in-memory compilation unit.
}
} else {
- qCDebug(DBG_DISK_CACHE) << "Error saving cached version of" << m_compiledData->url().toString() << "to disk:" << errorString;
+ qCDebug(DBG_DISK_CACHE) << "Error saving cached version of" << m_compiledData->fileName() << "to disk:" << errorString;
}
}
}
@@ -2634,6 +2678,10 @@ void QQmlTypeData::resolveTypes()
if (ref.type.isCompositeSingleton()) {
ref.typeData = typeLoader()->getType(ref.type.sourceUrl());
+ if (ref.typeData->status() == QQmlDataBlob::ResolvingDependencies) {
+ // TODO: give an error message? If so, we should record and show the path of the cycle.
+ continue;
+ }
addDependency(ref.typeData);
ref.prefix = csRef.prefix;
@@ -2737,7 +2785,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &
TypeReference &ref, int lineNumber, int columnNumber,
bool reportErrors, QQmlType::RegistrationType registrationType)
{
- QQmlImportNamespace *typeNamespace = 0;
+ QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
bool typeFound = m_importCache.resolveType(typeName, &ref.type, &majorVersion, &minorVersion,
@@ -2797,9 +2845,9 @@ void QQmlTypeData::scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData:
}
QQmlScriptData::QQmlScriptData()
- : typeNameCache(0)
+ : typeNameCache(nullptr)
, m_loaded(false)
- , m_program(0)
+ , m_program(nullptr)
{
}
@@ -2814,11 +2862,9 @@ void QQmlScriptData::initialize(QQmlEngine *engine)
Q_ASSERT(engine);
Q_ASSERT(!hasEngine());
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- QV8Engine *v8engine = ep->v8engine();
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8engine);
+ QV4::ExecutionEngine *v4 = engine->handle();
- m_program = new QV4::Script(v4, 0, m_precompiledScript);
+ m_program = new QV4::Script(v4, nullptr, m_precompiledScript);
addToEngine(engine);
@@ -2832,14 +2878,14 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent
Q_ASSERT(parentCtxt && parentCtxt->engine);
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(parentCtxt->engine);
+ QV4::ExecutionEngine *v4 = parentCtxt->engine->handle();
QV4::Scope scope(v4);
bool shared = m_precompiledScript->data->flags & QV4::CompiledData::Unit::IsSharedLibrary;
QQmlContextData *effectiveCtxt = parentCtxt;
if (shared)
- effectiveCtxt = 0;
+ effectiveCtxt = nullptr;
// Create the script context if required
QQmlContextDataRef ctxt(new QQmlContextData);
@@ -2887,10 +2933,11 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent
return QV4::Encode::undefined();
}
- QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxt, 0));
+ QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxt, nullptr));
m_program->qmlContext.set(scope.engine, qmlContext);
m_program->run();
+ m_program->qmlContext.clear();
if (scope.engine->hasException) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
if (error.isValid())
@@ -2910,7 +2957,7 @@ void QQmlScriptData::clear()
{
if (typeNameCache) {
typeNameCache->release();
- typeNameCache = 0;
+ typeNameCache = nullptr;
}
for (int ii = 0; ii < scripts.count(); ++ii)
@@ -2922,7 +2969,7 @@ void QQmlScriptData::clear()
}
QQmlScriptBlob::QQmlScriptBlob(const QUrl &url, QQmlTypeLoader *loader)
-: QQmlTypeLoader::Blob(url, JavaScriptFile, loader), m_scriptData(0)
+: QQmlTypeLoader::Blob(url, JavaScriptFile, loader), m_scriptData(nullptr)
{
}
@@ -2930,7 +2977,7 @@ QQmlScriptBlob::~QQmlScriptBlob()
{
if (m_scriptData) {
m_scriptData->release();
- m_scriptData = 0;
+ m_scriptData = nullptr;
}
}
@@ -2948,7 +2995,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
initializeFromCompilationUnit(unit);
return;
} else {
- qCDebug(DBG_DISK_CACHE()) << "Error loading" << url().toString() << "from disk cache:" << error;
+ qCDebug(DBG_DISK_CACHE()) << "Error loading" << urlString() << "from disk cache:" << error;
}
}
@@ -2966,7 +3013,9 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
QmlIR::ScriptDirectivesCollector collector(&irUnit.jsParserEngine, &irUnit.jsGenerator);
QList<QQmlError> errors;
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Script::precompile(&irUnit.jsModule, &irUnit.jsGenerator, finalUrl(), source, &errors, &collector);
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Script::precompile(
+ &irUnit.jsModule, &irUnit.jsGenerator, urlString(), finalUrlString(),
+ source, &errors, &collector);
// No need to addref on unit, it's initial refcount is 1
source.clear();
if (!errors.isEmpty()) {
@@ -2987,19 +3036,21 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
// The js unit owns the data and will free the qml unit.
unit->data = unitData;
- if (!disableDiskCache() || forceDiskCache()) {
+ if ((!disableDiskCache() || forceDiskCache()) && !isDebugging()) {
QString errorString;
if (!unit->saveToDisk(url(), &errorString)) {
- qCDebug(DBG_DISK_CACHE()) << "Error saving cached version of" << unit->url().toString() << "to disk:" << errorString;
+ qCDebug(DBG_DISK_CACHE()) << "Error saving cached version of" << unit->fileName() << "to disk:" << errorString;
}
}
initializeFromCompilationUnit(unit);
}
-void QQmlScriptBlob::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlScriptBlob::initializeFromCachedUnit(const QV4::CompiledData::Unit *unit)
{
- initializeFromCompilationUnit(unit->createCompilationUnit());
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
+ compilationUnit.adopt(new QV4::CompiledData::CompilationUnit(unit));
+ initializeFromCompilationUnit(compilationUnit);
}
void QQmlScriptBlob::done()
@@ -3014,10 +3065,10 @@ void QQmlScriptBlob::done()
if (script.script->isError()) {
QList<QQmlError> errors = script.script->errors();
QQmlError error;
- error.setUrl(finalUrl());
+ error.setUrl(url());
error.setLine(script.location.line);
error.setColumn(script.location.column);
- error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->url().toString()));
+ error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString()));
errors.prepend(error);
setError(errors);
return;
@@ -3061,7 +3112,7 @@ void QQmlScriptBlob::scriptImported(QQmlScriptBlob *blob, const QV4::CompiledDat
m_scripts << ref;
}
-void QQmlScriptBlob::initializeFromCompilationUnit(QV4::CompiledData::CompilationUnit *unit)
+void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit)
{
Q_ASSERT(!m_scriptData);
m_scriptData = new QQmlScriptData();
@@ -3105,7 +3156,7 @@ const QV4::CompiledData::Import *QQmlQmldirData::import(QQmlTypeLoader::Blob *bl
QHash<QQmlTypeLoader::Blob *, const QV4::CompiledData::Import *>::const_iterator it =
m_imports.find(blob);
if (it == m_imports.end())
- return 0;
+ return nullptr;
return *it;
}
@@ -3137,7 +3188,7 @@ void QQmlQmldirData::dataReceived(const SourceCodeData &data)
}
}
-void QQmlQmldirData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *)
+void QQmlQmldirData::initializeFromCachedUnit(const QV4::CompiledData::Unit *)
{
Q_UNIMPLEMENTED();
}
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 7218858726..e1a7ac7f06 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -98,6 +98,7 @@ public:
Null, // Prior to QQmlTypeLoader::load()
Loading, // Prior to data being received and dataReceived() being called
WaitingForDependencies, // While there are outstanding addDependency()s
+ ResolvingDependencies, // While resolving outstanding dependencies, to detect cycles
Complete, // Finished
Error // Error
};
@@ -109,7 +110,7 @@ public:
};
QQmlDataBlob(const QUrl &, Type, QQmlTypeLoader* manager);
- virtual ~QQmlDataBlob();
+ ~QQmlDataBlob() override;
void startLoading();
@@ -128,6 +129,7 @@ public:
qreal progress() const;
QUrl url() const;
+ QString urlString() const;
QUrl finalUrl() const;
QString finalUrlString() const;
@@ -156,7 +158,7 @@ protected:
// Callbacks made in load thread
virtual void dataReceived(const SourceCodeData &) = 0;
- virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) = 0;
+ virtual void initializeFromCachedUnit(const QV4::CompiledData::Unit*) = 0;
virtual void done();
#if QT_CONFIG(qml_network)
virtual void networkError(QNetworkReply::NetworkError);
@@ -206,6 +208,7 @@ private:
QUrl m_url;
QUrl m_finalUrl;
+ mutable QString m_urlString;
mutable QString m_finalUrlString;
// List of QQmlDataBlob's that are waiting for me to complete.
@@ -265,7 +268,7 @@ public:
{
public:
Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader);
- ~Blob();
+ ~Blob() override;
const QQmlImports &imports() const { return m_importCache; }
@@ -321,7 +324,7 @@ public:
void load(QQmlDataBlob *, Mode = PreferSynchronous);
void loadWithStaticData(QQmlDataBlob *, const QByteArray &, Mode = PreferSynchronous);
- void loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode = PreferSynchronous);
+ void loadWithCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit, Mode mode = PreferSynchronous);
QQmlEngine *engine() const;
void initializeEngine(QQmlExtensionInterface *, const char *);
@@ -347,7 +350,7 @@ private:
void loadThread(QQmlDataBlob *);
void loadWithStaticDataThread(QQmlDataBlob *, const QByteArray &);
- void loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
+ void loadWithCachedUnitThread(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit);
#if QT_CONFIG(qml_network)
void networkReplyFinished(QNetworkReply *);
void networkReplyProgress(QNetworkReply *, qint64, qint64);
@@ -358,7 +361,7 @@ private:
void setData(QQmlDataBlob *, const QByteArray &);
void setData(QQmlDataBlob *, const QString &fileName);
void setData(QQmlDataBlob *, const QQmlDataBlob::SourceCodeData &);
- void setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
+ void setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit);
template<typename T>
struct TypedCallback
@@ -414,7 +417,7 @@ class Q_AUTOTEST_EXPORT QQmlTypeData : public QQmlTypeLoader::Blob
public:
struct TypeReference
{
- TypeReference() : majorVersion(0), minorVersion(0), typeData(0), needsCreation(true) {}
+ TypeReference() : majorVersion(0), minorVersion(0), typeData(nullptr), needsCreation(true) {}
QV4::CompiledData::Location location;
QQmlType type;
@@ -428,7 +431,7 @@ public:
struct ScriptReference
{
- ScriptReference() : script(0) {}
+ ScriptReference() : script(nullptr) {}
QV4::CompiledData::Location location;
QString qualifier;
@@ -441,7 +444,7 @@ private:
QQmlTypeData(const QUrl &, QQmlTypeLoader *);
public:
- ~QQmlTypeData();
+ ~QQmlTypeData() override;
const QList<ScriptReference> &resolvedScripts() const;
@@ -460,7 +463,7 @@ protected:
void done() override;
void completed() override;
void dataReceived(const SourceCodeData &) override;
- void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override;
+ void initializeFromCachedUnit(const QV4::CompiledData::Unit *unit) override;
void allDependenciesDone() override;
void downloadProgressChanged(qreal) override;
@@ -526,7 +529,7 @@ private:
QQmlScriptData();
public:
- ~QQmlScriptData();
+ ~QQmlScriptData() override;
QUrl url;
QString urlString;
@@ -557,11 +560,11 @@ private:
QQmlScriptBlob(const QUrl &, QQmlTypeLoader *);
public:
- ~QQmlScriptBlob();
+ ~QQmlScriptBlob() override;
struct ScriptReference
{
- ScriptReference() : script(0) {}
+ ScriptReference() : script(nullptr) {}
QV4::CompiledData::Location location;
QString qualifier;
@@ -573,14 +576,14 @@ public:
protected:
void dataReceived(const SourceCodeData &) override;
- void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override;
+ void initializeFromCachedUnit(const QV4::CompiledData::Unit *unit) override;
void done() override;
QString stringAt(int index) const override;
private:
void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override;
- void initializeFromCompilationUnit(QV4::CompiledData::CompilationUnit *unit);
+ void initializeFromCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit);
QList<ScriptReference> m_scripts;
QQmlScriptData *m_scriptData;
@@ -604,7 +607,7 @@ public:
protected:
void dataReceived(const SourceCodeData &) override;
- void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) override;
+ void initializeFromCachedUnit(const QV4::CompiledData::Unit *) override;
private:
QString m_content;
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index 32b0fa16c4..8f1a61e6ad 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -56,7 +56,7 @@ void QQmlTypeNameCache::add(const QHashedString &name, const QUrl &url, const QH
{
if (nameSpace.length() != 0) {
QQmlImportRef *i = m_namedImports.value(nameSpace);
- Q_ASSERT(i != 0);
+ Q_ASSERT(i != nullptr);
i->compositeSingletons.insert(name, url);
return;
}
@@ -75,7 +75,7 @@ void QQmlTypeNameCache::add(const QHashedString &name, int importedScriptIndex,
if (nameSpace.length() != 0) {
QQmlImportRef *i = m_namedImports.value(nameSpace);
- Q_ASSERT(i != 0);
+ Q_ASSERT(i != nullptr);
m_namespacedImports[i].insert(name, import);
return;
}
@@ -98,10 +98,10 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name)
if (!result.isValid()) {
// Look up anonymous types from the imports of this document
- QQmlImportNamespace *typeNamespace = 0;
+ QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
QQmlType t;
- bool typeFound = m_imports.resolveType(name, &t, 0, 0, &typeNamespace, &errors);
+ bool typeFound = m_imports.resolveType(name, &t, nullptr, nullptr, &typeNamespace, &errors);
if (typeFound) {
return Result(t);
}
@@ -126,10 +126,10 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name,
// ### it would be nice if QQmlImports allowed us to resolve a namespace
// first, and then types on it.
QString qualifiedTypeName = importNamespace->m_qualifier + QLatin1Char('.') + name.toString();
- QQmlImportNamespace *typeNamespace = 0;
+ QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
QQmlType t;
- bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, 0, 0, &typeNamespace, &errors);
+ bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, nullptr, &typeNamespace, &errors);
if (typeFound) {
return Result(t);
}
@@ -151,10 +151,10 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, QQml
if (!result.isValid()) {
// Look up anonymous types from the imports of this document
QString typeName = name->toQStringNoThrow();
- QQmlImportNamespace *typeNamespace = 0;
+ QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
QQmlType t;
- bool typeFound = m_imports.resolveType(typeName, &t, 0, 0, &typeNamespace, &errors,
+ bool typeFound = m_imports.resolveType(typeName, &t, nullptr, nullptr, &typeNamespace, &errors,
QQmlType::AnyRegistrationType, recursionRestriction);
if (typeFound) {
return Result(t);
@@ -186,10 +186,10 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, cons
// ### it would be nice if QQmlImports allowed us to resolve a namespace
// first, and then types on it.
QString qualifiedTypeName = importNamespace->m_qualifier + QLatin1Char('.') + name->toQStringNoThrow();
- QQmlImportNamespace *typeNamespace = 0;
+ QQmlImportNamespace *typeNamespace = nullptr;
QList<QQmlError> errors;
QQmlType t;
- bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, 0, 0, &typeNamespace, &errors);
+ bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, nullptr, nullptr, &typeNamespace, &errors);
if (typeFound) {
return Result(t);
}
diff --git a/src/qml/qml/qqmltypenamecache_p.h b/src/qml/qml/qqmltypenamecache_p.h
index 8ac25c4fbe..28b5e7f0ad 100644
--- a/src/qml/qml/qqmltypenamecache_p.h
+++ b/src/qml/qml/qqmltypenamecache_p.h
@@ -85,7 +85,7 @@ class Q_QML_PRIVATE_EXPORT QQmlTypeNameCache : public QQmlRefCount
{
public:
QQmlTypeNameCache(const QQmlImports &imports);
- virtual ~QQmlTypeNameCache();
+ ~QQmlTypeNameCache() override;
inline bool isEmpty() const;
@@ -162,7 +162,7 @@ private:
};
QQmlTypeNameCache::Result::Result()
-: importNamespace(0), scriptIndex(-1)
+: importNamespace(nullptr), scriptIndex(-1)
{
}
@@ -172,12 +172,12 @@ QQmlTypeNameCache::Result::Result(const QQmlImportRef *importNamespace)
}
QQmlTypeNameCache::Result::Result(const QQmlType &type)
-: type(type), importNamespace(0), scriptIndex(-1)
+: type(type), importNamespace(nullptr), scriptIndex(-1)
{
}
QQmlTypeNameCache::Result::Result(int scriptIndex)
-: importNamespace(0), scriptIndex(scriptIndex)
+: importNamespace(nullptr), scriptIndex(scriptIndex)
{
}
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 404bc0612e..6dbf6ad8c1 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -85,7 +85,7 @@ bool QQmlTypeWrapper::isSingleton() const
QObject* QQmlTypeWrapper::singletonObject() const
{
if (!isSingleton())
- return 0;
+ return nullptr;
QQmlEngine *e = engine()->qmlEngine();
QQmlType::SingletonInstanceInfo *siinfo = d()->type().singletonInstanceInfo();
@@ -134,11 +134,11 @@ ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o,
}
static int enumForSingleton(QV4::ExecutionEngine *v4, String *name, QObject *qobjectSingleton,
- const QQmlType &type)
+ const QQmlType &type, bool *ok)
{
- bool ok;
- int value = type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
- if (ok)
+ Q_ASSERT(ok != nullptr);
+ int value = type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, ok);
+ if (*ok)
return value;
// ### Optimize
@@ -146,10 +146,11 @@ static int enumForSingleton(QV4::ExecutionEngine *v4, String *name, QObject *qob
const QMetaObject *metaObject = qobjectSingleton->metaObject();
for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
QMetaEnum e = metaObject->enumerator(ii);
- value = e.keyToValue(enumName.constData(), &ok);
- if (ok)
+ value = e.keyToValue(enumName.constData(), ok);
+ if (*ok)
return value;
}
+ *ok = false;
return -1;
}
@@ -192,8 +193,9 @@ ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProp
// check for enum value
const bool includeEnums = w->d()->mode == Heap::QQmlTypeWrapper::IncludeEnums;
if (includeEnums && name->startsWithUpper()) {
- const int value = enumForSingleton(v4, name, qobjectSingleton, type);
- if (value != -1)
+ bool ok = false;
+ const int value = enumForSingleton(v4, name, qobjectSingleton, type, &ok);
+ if (ok)
return QV4::Primitive::fromInt32(value).asReturnedValue();
}
@@ -205,8 +207,8 @@ ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProp
// Warn when attempting to access a lowercased enum value, singleton case
if (!ok && includeEnums && !name->startsWithUpper()) {
- const int value = enumForSingleton(v4, name, qobjectSingleton, type);
- if (value != -1)
+ enumForSingleton(v4, name, qobjectSingleton, type, &ok);
+ if (ok)
return throwLowercaseEnumError(v4, name, type);
}
diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp
index 520f512b1a..270414a676 100644
--- a/src/qml/qml/qqmlvaluetype.cpp
+++ b/src/qml/qml/qqmlvaluetype.cpp
@@ -68,7 +68,7 @@ struct QQmlValueTypeFactoryImpl
QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl()
{
for (unsigned int ii = 0; ii < QVariant::UserType; ++ii)
- valueTypes[ii] = 0;
+ valueTypes[ii] = nullptr;
// See types wrapped in qqmlmodelindexvaluetype_p.h
qRegisterMetaType<QItemSelectionRange>();
@@ -83,7 +83,7 @@ QQmlValueTypeFactoryImpl::~QQmlValueTypeFactoryImpl()
bool QQmlValueTypeFactoryImpl::isValueType(int idx)
{
if (idx >= (int)QVariant::UserType) {
- return (valueType(idx) != 0);
+ return (valueType(idx) != nullptr);
} else if (idx >= 0
&& idx != QVariant::StringList
&& idx != QMetaType::QObjectStar
@@ -130,7 +130,7 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t)
QMetaType metaType(t);
if (metaType.flags() & QMetaType::IsGadget)
return metaType.metaObject();
- return 0;
+ return nullptr;
}
QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
@@ -141,7 +141,7 @@ QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
QHash<int, QQmlValueType *>::iterator it = userTypes.find(idx);
if (it == userTypes.end()) {
- QQmlValueType *vt = 0;
+ QQmlValueType *vt = nullptr;
if (const QMetaObject *mo = metaObjectForMetaType(idx))
vt = new QQmlValueType(idx, mo);
it = userTypes.insert(idx, vt);
@@ -209,14 +209,14 @@ QQmlValueType::~QQmlValueType()
{
QObjectPrivate *op = QObjectPrivate::get(this);
Q_ASSERT(op->metaObject == this);
- op->metaObject = 0;
+ op->metaObject = nullptr;
::free(const_cast<QMetaObject *>(_metaObject));
metaType.destroy(gadgetPtr);
}
void QQmlValueType::read(QObject *obj, int idx)
{
- void *a[] = { gadgetPtr, 0 };
+ void *a[] = { gadgetPtr, nullptr };
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
@@ -224,7 +224,7 @@ void QQmlValueType::write(QObject *obj, int idx, QQmlPropertyData::WriteFlags fl
{
Q_ASSERT(gadgetPtr);
int status = -1;
- void *a[] = { gadgetPtr, 0, &status, &flags };
+ void *a[] = { gadgetPtr, nullptr, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h
index 0502a5d665..4ea71e8955 100644
--- a/src/qml/qml/qqmlvaluetype_p.h
+++ b/src/qml/qml/qqmlvaluetype_p.h
@@ -67,7 +67,7 @@ class Q_QML_PRIVATE_EXPORT QQmlValueType : public QObject, public QAbstractDynam
{
public:
QQmlValueType(int userType, const QMetaObject *metaObject);
- ~QQmlValueType();
+ ~QQmlValueType() override;
void read(QObject *, int);
void write(QObject *, int, QQmlPropertyData::WriteFlags flags);
QVariant value();
@@ -272,19 +272,19 @@ int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMino
QQmlPrivate::RegisterType type = {
0,
- qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, 0, 0,
+ qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, 0, nullptr,
QString(),
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
- 0, 0,
+ nullptr, nullptr,
0, 0, 0,
- 0, 0,
+ nullptr, nullptr,
- 0,
+ nullptr,
0
};
diff --git a/src/qml/qml/qqmlvaluetypeproxybinding.cpp b/src/qml/qml/qqmlvaluetypeproxybinding.cpp
index 7a3e4b2df4..d5cff26444 100644
--- a/src/qml/qml/qqmlvaluetypeproxybinding.cpp
+++ b/src/qml/qml/qqmlvaluetypeproxybinding.cpp
@@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE
QQmlValueTypeProxyBinding::QQmlValueTypeProxyBinding(QObject *o, QQmlPropertyIndex index)
: QQmlAbstractBinding(),
- m_bindings(0)
+ m_bindings(nullptr)
{
m_target = o;
m_targetIndex = index;
@@ -93,7 +93,7 @@ Removes a collection of bindings, corresponding to the set bits in \a mask.
void QQmlValueTypeProxyBinding::removeBindings(quint32 mask)
{
QQmlAbstractBinding *binding = m_bindings.data();
- QQmlAbstractBinding *lastBinding = 0;
+ QQmlAbstractBinding *lastBinding = nullptr;
while (binding) {
const int valueTypeIndex = binding->targetPropertyIndex().valueTypeIndex();
@@ -102,7 +102,7 @@ void QQmlValueTypeProxyBinding::removeBindings(quint32 mask)
remove->setAddedToObject(false);
binding = remove->nextBinding();
- if (lastBinding == 0)
+ if (lastBinding == nullptr)
m_bindings = remove->nextBinding();
else
lastBinding->setNextBinding(remove->nextBinding());
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 90ca08537c..a28115d192 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -98,6 +98,8 @@ void Heap::QQmlValueTypeWrapper::destroy()
valueType->metaType.destruct(gadgetPtr);
::operator delete(gadgetPtr);
}
+ if (_propertyCache)
+ _propertyCache->release();
Object::destroy();
}
@@ -129,7 +131,7 @@ bool QQmlValueTypeReference::readReferenceValue() const
// variant-containing-value-type reference
QVariant variantReferenceValue;
- void *a[] = { &variantReferenceValue, 0 };
+ void *a[] = { &variantReferenceValue, nullptr };
QMetaObject::metacall(d()->object, QMetaObject::ReadProperty, d()->property, a);
int variantReferenceType = variantReferenceValue.userType();
@@ -139,14 +141,14 @@ bool QQmlValueTypeReference::readReferenceValue() const
// We need to modify this reference to the updated value type, if
// possible, or return false if it is not a value type.
if (QQmlValueTypeFactory::isValueType(variantReferenceType)) {
- QQmlPropertyCache *cache = 0;
+ QQmlPropertyCache *cache = nullptr;
if (const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(variantReferenceType))
cache = QJSEnginePrivate::get(engine())->cache(mo);
if (d()->gadgetPtr) {
d()->valueType->metaType.destruct(d()->gadgetPtr);
::operator delete(d()->gadgetPtr);
}
- d()->gadgetPtr =0;
+ d()->gadgetPtr =nullptr;
d()->setPropertyCache(cache);
d()->valueType = QQmlValueTypeFactory::valueType(variantReferenceType);
if (!cache)
@@ -159,10 +161,10 @@ bool QQmlValueTypeReference::readReferenceValue() const
} else {
if (!d()->gadgetPtr) {
d()->gadgetPtr = ::operator new(d()->valueType->metaType.sizeOf());
- d()->valueType->metaType.construct(d()->gadgetPtr, 0);
+ d()->valueType->metaType.construct(d()->gadgetPtr, nullptr);
}
// value-type reference
- void *args[] = { d()->gadgetPtr, 0 };
+ void *args[] = { d()->gadgetPtr, nullptr };
QMetaObject::metacall(d()->object, QMetaObject::ReadProperty, d()->property, args);
}
return true;
@@ -189,7 +191,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *obj
r->d()->property = property;
r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject));
r->d()->valueType = QQmlValueTypeFactory::valueType(typeId);
- r->d()->gadgetPtr = 0;
+ r->d()->gadgetPtr = nullptr;
return r->asReturnedValue();
}
@@ -201,7 +203,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, const QVaria
Scoped<QQmlValueTypeWrapper> r(scope, engine->memoryManager->allocObject<QQmlValueTypeWrapper>());
r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject));
r->d()->valueType = QQmlValueTypeFactory::valueType(typeId);
- r->d()->gadgetPtr = 0;
+ r->d()->gadgetPtr = nullptr;
r->d()->setValue(value);
return r->asReturnedValue();
}
@@ -244,13 +246,13 @@ PropertyAttributes QQmlValueTypeWrapper::query(const Managed *m, String *name)
Q_ASSERT(m->as<const QQmlValueTypeWrapper>());
const QQmlValueTypeWrapper *r = static_cast<const QQmlValueTypeWrapper *>(m);
- QQmlPropertyData *result = r->d()->propertyCache()->property(name, 0, 0);
+ QQmlPropertyData *result = r->d()->propertyCache()->property(name, nullptr, nullptr);
return result ? Attr_Data : Attr_Invalid;
}
void QQmlValueTypeWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes)
{
- name->setM(0);
+ name->setM(nullptr);
*index = UINT_MAX;
QQmlValueTypeWrapper *that = static_cast<QQmlValueTypeWrapper*>(m);
@@ -297,7 +299,7 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
if (!d()->gadgetPtr) {
Q_ALLOCA_ASSIGN(void, gadget, d()->valueType->metaType.sizeOf());
d()->gadgetPtr = gadget;
- d()->valueType->metaType.construct(d()->gadgetPtr, 0);
+ d()->valueType->metaType.construct(d()->gadgetPtr, nullptr);
destructGadgetOnExit = true;
}
if (!ref->readReferenceValue())
@@ -306,27 +308,26 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
int flags = 0;
int status = -1;
- void *a[] = { d()->gadgetPtr, 0, &status, &flags };
+ void *a[] = { d()->gadgetPtr, nullptr, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty, propertyIndex, a);
if (destructGadgetOnExit) {
d()->valueType->metaType.destruct(d()->gadgetPtr);
- d()->gadgetPtr = 0;
+ d()->gadgetPtr = nullptr;
}
return true;
}
-ReturnedValue QQmlValueTypeWrapper::method_toString(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QQmlValueTypeWrapper::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scope scope(b);
- Object *o = callData->thisObject.as<Object>();
+ const Object *o = thisObject->as<Object>();
if (!o)
- THROW_TYPE_ERROR();
- QQmlValueTypeWrapper *w = o->as<QQmlValueTypeWrapper>();
+ return b->engine()->throwTypeError();
+ const QQmlValueTypeWrapper *w = o->as<QQmlValueTypeWrapper>();
if (!w)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
- if (QQmlValueTypeReference *ref = w->as<QQmlValueTypeReference>())
+ if (const QQmlValueTypeReference *ref = w->as<QQmlValueTypeReference>())
if (!ref->readReferenceValue())
RETURN_UNDEFINED();
@@ -351,7 +352,7 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(const BuiltinFunction *b, Ca
}
result += QLatin1Char(')');
}
- return Encode(scope.engine->newString(result));
+ return Encode(b->engine()->newString(result));
}
ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *hasProperty)
@@ -366,7 +367,7 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha
return Primitive::undefinedValue().asReturnedValue();
}
- QQmlPropertyData *result = r->d()->propertyCache()->property(name, 0, 0);
+ QQmlPropertyData *result = r->d()->propertyCache()->property(name, nullptr, nullptr);
if (!result)
return Object::get(m, name, hasProperty);
@@ -435,7 +436,7 @@ bool QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
}
const QMetaObject *metaObject = r->d()->propertyCache()->metaObject();
- const QQmlPropertyData *pd = r->d()->propertyCache()->property(name, 0, 0);
+ const QQmlPropertyData *pd = r->d()->propertyCache()->property(name, nullptr, nullptr);
if (!pd)
return false;
@@ -504,13 +505,13 @@ bool QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
int flags = 0;
int status = -1;
- void *a[] = { &variantReferenceValue, 0, &status, &flags };
+ void *a[] = { &variantReferenceValue, nullptr, &status, &flags };
QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a);
} else {
int flags = 0;
int status = -1;
- void *a[] = { r->d()->gadgetPtr, 0, &status, &flags };
+ void *a[] = { r->d()->gadgetPtr, nullptr, &status, &flags };
QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a);
}
}
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index da03af6dbc..f99d207d68 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -112,7 +112,7 @@ public:
static PropertyAttributes query(const Managed *, String *name);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static ReturnedValue method_toString(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_toString(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static void initProto(ExecutionEngine *v4);
};
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index c60f4edc80..018769948d 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -96,7 +96,7 @@ bool QQmlVME::componentCompleteEnabled()
}
QQmlVMEGuard::QQmlVMEGuard()
-: m_objectCount(0), m_objects(0), m_contextCount(0), m_contexts(0)
+: m_objectCount(0), m_objects(nullptr), m_contextCount(0), m_contexts(nullptr)
{
}
@@ -120,27 +120,15 @@ void QQmlVMEGuard::guard(QQmlObjectCreator *creator)
m_contexts[0] = creator->parentContextData();
}
-void QQmlVMEGuard::unguard(QObject *object)
-{
- for (int ii = 0; ii < m_objectCount; ++ii) {
- if (m_objects[ii] == object) {
- if (ii < m_objectCount - 1)
- ::memmove((void *) m_objects[ii], (void *) m_objects[ii + 1], sizeof(QPointer<QObject> *));
- delete m_objects[--m_objectCount];
- break;
- }
- }
-}
-
void QQmlVMEGuard::clear()
{
delete [] m_objects;
delete [] m_contexts;
m_objectCount = 0;
- m_objects = 0;
+ m_objects = nullptr;
m_contextCount = 0;
- m_contexts = 0;
+ m_contexts = nullptr;
}
bool QQmlVMEGuard::isOK() const
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index 9585b5b6df..9a94ac6258 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -83,7 +83,7 @@ namespace QQmlVMETypes {
struct State {
enum Flag { Deferred = 0x00000001 };
- State() : flags(0), context(0), instructionStream(0) {}
+ State() : flags(0), context(nullptr), instructionStream(nullptr) {}
quint32 flags;
QQmlContextData *context;
const char *instructionStream;
@@ -131,7 +131,6 @@ public:
~QQmlVMEGuard();
void guard(QQmlObjectCreator *);
- void unguard(QObject *);
void clear();
bool isOK() const;
@@ -144,7 +143,7 @@ private:
};
QQmlInstantiationInterrupt::QQmlInstantiationInterrupt()
- : mode(None), nsecs(0), runWhile(0)
+ : mode(None), nsecs(0), runWhile(nullptr)
{
}
@@ -154,7 +153,7 @@ QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(volatile bool *runWhile,
}
QQmlInstantiationInterrupt::QQmlInstantiationInterrupt(int nsecs)
- : mode(Time), nsecs(nsecs), runWhile(0)
+ : mode(Time), nsecs(nsecs), runWhile(nullptr)
{
}
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 281d64ac79..c1d3980b58 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -64,7 +64,7 @@ static void list_append(QQmlListProperty<QObject> *prop, QObject *o)
{
QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
list->append(o);
- static_cast<QQmlVMEMetaObject *>(prop->dummy1)->activate(prop->object, reinterpret_cast<quintptr>(prop->dummy2), 0);
+ static_cast<QQmlVMEMetaObject *>(prop->dummy1)->activate(prop->object, reinterpret_cast<quintptr>(prop->dummy2), nullptr);
}
static int list_count(QQmlListProperty<QObject> *prop)
@@ -83,11 +83,11 @@ static void list_clear(QQmlListProperty<QObject> *prop)
{
QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
list->clear();
- static_cast<QQmlVMEMetaObject *>(prop->dummy1)->activate(prop->object, reinterpret_cast<quintptr>(prop->dummy2), 0);
+ static_cast<QQmlVMEMetaObject *>(prop->dummy1)->activate(prop->object, reinterpret_cast<quintptr>(prop->dummy2), nullptr);
}
QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr()
- : QQmlGuard<QObject>(0), m_target(0), m_index(-1)
+ : QQmlGuard<QObject>(nullptr), m_target(nullptr), m_index(-1)
{
}
@@ -111,7 +111,7 @@ void QQmlVMEVariantQObjectPtr::objectDestroyed(QObject *)
}
}
- m_target->activate(m_target->object, m_target->methodOffset() + m_index, 0);
+ m_target->activate(m_target->object, m_target->methodOffset() + m_index, nullptr);
}
}
@@ -150,7 +150,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
if (metaObject.flag()) {
// This is actually notify
int sigIdx = metaObject->methodOffset() + aliasId + metaObject->compiledObject->nProperties;
- metaObject->activate(metaObject->object, sigIdx, 0);
+ metaObject->activate(metaObject->object, sigIdx, nullptr);
} else {
const QV4::CompiledData::Alias *aliasData = &metaObject->compiledObject->aliasTable()[aliasId];
if (!aliasData->isObjectAlias()) {
@@ -179,7 +179,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
QQmlInterceptorMetaObject::QQmlInterceptorMetaObject(QObject *obj, QQmlPropertyCache *cache)
: object(obj),
cache(cache),
- interceptors(0),
+ interceptors(nullptr),
hasAssignedMetaObjectData(false)
{
QObjectPrivate *op = QObjectPrivate::get(obj);
@@ -320,7 +320,7 @@ QQmlVMEMetaObject::QQmlVMEMetaObject(QV4::ExecutionEngine *engine,
: QQmlInterceptorMetaObject(obj, cache),
engine(engine),
ctxt(QQmlData::get(obj, true)->outerContext),
- aliasEndpoints(0), compilationUnit(qmlCompilationUnit), compiledObject(0)
+ aliasEndpoints(nullptr), compilationUnit(qmlCompilationUnit), compiledObject(nullptr)
{
Q_ASSERT(engine);
QQmlData::get(obj)->hasVMEMetaObject = true;
@@ -358,7 +358,7 @@ QV4::MemberData *QQmlVMEMetaObject::propertyAndMethodStorageAsMemberData() const
// such as the varProperties array) will have been cleaned up, but the
// QObject ptr will not yet have been deleted (eg, waiting on deleteLater).
// In this situation, return 0.
- return 0;
+ return nullptr;
}
return static_cast<QV4::MemberData*>(propertyAndMethodStorage.asManaged());
@@ -575,13 +575,13 @@ QObject* QQmlVMEMetaObject::readPropertyAsQObject(int id) const
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
- return 0;
+ return nullptr;
QV4::Scope scope(engine);
QV4::ScopedValue sv(scope, *(md->data() + id));
const QV4::QObjectWrapper *wrapper = sv->as<QV4::QObjectWrapper>();
if (!wrapper)
- return 0;
+ return nullptr;
return wrapper->object();
}
@@ -589,7 +589,7 @@ QList<QObject *> *QQmlVMEMetaObject::readPropertyAsList(int id) const
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
- return 0;
+ return nullptr;
QV4::Scope scope(engine);
QV4::Scoped<QV4::VariantObject> v(scope, *(md->data() + id));
@@ -643,7 +643,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
if (t == QV4::CompiledData::Property::Var) {
// the context can be null if accessing var properties from cpp after re-parenting an item.
- QQmlEnginePrivate *ep = (ctxt == 0 || ctxt->engine == 0) ? 0 : QQmlEnginePrivate::get(ctxt->engine);
+ QQmlEnginePrivate *ep = (ctxt == nullptr || ctxt->engine == nullptr) ? nullptr : QQmlEnginePrivate::get(ctxt->engine);
if (ep) {
if (c == QMetaObject::ReadProperty) {
*reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
@@ -836,7 +836,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
}
if (c == QMetaObject::WriteProperty && needActivate) {
- activate(object, methodOffset() + id, 0);
+ activate(object, methodOffset() + id, nullptr);
}
return -1;
@@ -848,7 +848,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[id];
if ((aliasData->flags & QV4::CompiledData::Alias::AliasPointsToPointerObject) && c == QMetaObject::ReadProperty)
- *reinterpret_cast<void **>(a[0]) = 0;
+ *reinterpret_cast<void **>(a[0]) = nullptr;
if (!ctxt) return -1;
@@ -899,7 +899,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
if (c == QMetaObject::WriteProperty)
- valueType->write(target, coreIndex, 0x00);
+ valueType->write(target, coreIndex, nullptr);
return rv;
@@ -926,12 +926,14 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
id -= plainSignals;
if (id < methodCount) {
- if (!ctxt->engine)
+ QQmlEngine *engine = ctxt->engine;
+ if (!engine)
return -1; // We can't run the method
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(ctxt->engine);
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
+ QV4::ExecutionEngine *v4 = engine->handle();
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
- QV4::Scope scope(ep->v4engine());
+ QV4::Scope scope(v4);
QV4::ScopedFunctionObject function(scope, method(id));
@@ -951,7 +953,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
const unsigned int parameterCount = function->formalParameterCount();
QV4::JSCallData jsCallData(scope, parameterCount);
- *jsCallData->thisObject = ep->v8engine()->global();
+ *jsCallData->thisObject = v4->global();
for (uint ii = 0; ii < parameterCount; ++ii)
jsCallData->args[ii] = scope.engine->fromVariant(*(QVariant *)a[ii + 1]);
@@ -1035,7 +1037,7 @@ void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
if (oldVariant)
oldVariant->removeVmePropertyReference();
- QObject *valueObject = 0;
+ QObject *valueObject = nullptr;
QQmlVMEVariantQObjectPtr *guard = getQObjectGuardForProperty(id);
// And, if the new value is a scarce resource, we need to ensure that it does not get
@@ -1058,7 +1060,7 @@ void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
// Write the value and emit change signal as appropriate.
md->set(engine, id, value);
- activate(object, methodOffset() + id, 0);
+ activate(object, methodOffset() + id, nullptr);
}
void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
@@ -1086,7 +1088,7 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
QVariant currentValue = readPropertyAsVariant(id);
md->set(engine, id, newv);
if ((currentValue.userType() != value.userType() || currentValue != value))
- activate(object, methodOffset() + id, 0);
+ activate(object, methodOffset() + id, nullptr);
} else {
bool needActivate = false;
if (value.userType() == QMetaType::QObjectStar) {
@@ -1109,7 +1111,7 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
}
if (needActivate)
- activate(object, methodOffset() + id, 0);
+ activate(object, methodOffset() + id, nullptr);
}
}
@@ -1185,7 +1187,7 @@ bool QQmlVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex,
{
Q_ASSERT(compiledObject && (index >= propOffset() + int(compiledObject->nProperties)));
- *target = 0;
+ *target = nullptr;
*coreIndex = -1;
*valueTypeIndex = -1;
@@ -1287,7 +1289,7 @@ QQmlVMEVariantQObjectPtr *QQmlVMEMetaObject::getQObjectGuardForProperty(int inde
}
}
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index 27e638ceb4..0c82686d47 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -81,7 +81,7 @@ class QQmlVMEVariantQObjectPtr : public QQmlGuard<QObject>
{
public:
inline QQmlVMEVariantQObjectPtr();
- inline ~QQmlVMEVariantQObjectPtr();
+ inline ~QQmlVMEVariantQObjectPtr() override;
inline void objectDestroyed(QObject *) override;
inline void setGuardedValue(QObject *obj, QQmlVMEMetaObject *target, int index);
@@ -95,7 +95,7 @@ class Q_QML_PRIVATE_EXPORT QQmlInterceptorMetaObject : public QAbstractDynamicMe
{
public:
QQmlInterceptorMetaObject(QObject *obj, QQmlPropertyCache *cache);
- ~QQmlInterceptorMetaObject();
+ ~QQmlInterceptorMetaObject() override;
void registerInterceptor(QQmlPropertyIndex index, QQmlPropertyValueInterceptor *interceptor);
@@ -112,7 +112,7 @@ public:
if (it->m_propertyIndex == propertyIndex)
return true;
}
- if (auto parentInterceptor = ((parent.isT1() && parent.flag()) ? static_cast<QQmlInterceptorMetaObject *>(parent.asT1()) : 0))
+ if (auto parentInterceptor = ((parent.isT1() && parent.flag()) ? static_cast<QQmlInterceptorMetaObject *>(parent.asT1()) : nullptr))
return parentInterceptor->intercepts(propertyIndex);
return false;
}
@@ -139,7 +139,7 @@ inline QQmlInterceptorMetaObject *QQmlInterceptorMetaObject::get(QObject *obj)
}
}
- return 0;
+ return nullptr;
}
class QQmlVMEMetaObjectEndpoint;
@@ -147,7 +147,7 @@ class Q_QML_PRIVATE_EXPORT QQmlVMEMetaObject : public QQmlInterceptorMetaObject
{
public:
QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, QQmlPropertyCache *cache, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId);
- ~QQmlVMEMetaObject();
+ ~QQmlVMEMetaObject() override;
bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const;
QV4::ReturnedValue vmeMethod(int index) const;
@@ -241,7 +241,7 @@ QQmlVMEMetaObject *QQmlVMEMetaObject::get(QObject *obj)
}
}
- return 0;
+ return nullptr;
}
int QQmlVMEMetaObject::propOffset() const
@@ -269,7 +269,7 @@ QQmlVMEMetaObject *QQmlVMEMetaObject::parentVMEMetaObject() const
if (parent.isT1() && parent.flag())
return static_cast<QQmlVMEMetaObject *>(parent.asT1());
- return 0;
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 08842e714c..5673acec89 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -116,7 +116,7 @@ class DocumentImpl;
class NodeImpl
{
public:
- NodeImpl() : type(Element), document(0), parent(0) {}
+ NodeImpl() : type(Element), document(nullptr), parent(nullptr) {}
virtual ~NodeImpl() {
qDeleteAll(children);
qDeleteAll(attributes);
@@ -157,7 +157,7 @@ public:
class DocumentImpl : public QQmlRefCount, public NodeImpl
{
public:
- DocumentImpl() : root(0) { type = Document; }
+ DocumentImpl() : root(nullptr) { type = Document; }
virtual ~DocumentImpl() {
delete root;
}
@@ -276,25 +276,25 @@ public:
static void initClass(ExecutionEngine *engine);
// JS API
- static ReturnedValue method_get_nodeName(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_nodeValue(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_nodeType(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_namespaceUri(const BuiltinFunction *b, QV4::CallData *callData);
-
- static ReturnedValue method_get_parentNode(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_childNodes(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_firstChild(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_lastChild(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_previousSibling(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_nextSibling(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_attributes(const BuiltinFunction *b, QV4::CallData *callData);
-
- //static ReturnedValue ownerDocument(const BuiltinFunction *b, QV4::CallData *callData);
- //static ReturnedValue namespaceURI(const BuiltinFunction *b, QV4::CallData *callData);
- //static ReturnedValue prefix(const BuiltinFunction *b, QV4::CallData *callData);
- //static ReturnedValue localName(const BuiltinFunction *b, QV4::CallData *callData);
- //static ReturnedValue baseURI(const BuiltinFunction *b, QV4::CallData *callData);
- //static ReturnedValue textContent(const BuiltinFunction *b, QV4::CallData *callData);
+ static ReturnedValue method_get_nodeName(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_nodeValue(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_nodeType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_namespaceUri(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_get_parentNode(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_childNodes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_firstChild(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_lastChild(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_previousSibling(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_nextSibling(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_attributes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ //static ReturnedValue ownerDocument(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue namespaceURI(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue prefix(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue localName(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue baseURI(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue textContent(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue getProto(ExecutionEngine *v4);
@@ -306,18 +306,18 @@ void Heap::NodePrototype::init()
Scope scope(internalClass->engine);
ScopedObject o(scope, this);
- o->defineAccessorProperty(QStringLiteral("nodeName"), QV4::NodePrototype::method_get_nodeName, 0);
- o->defineAccessorProperty(QStringLiteral("nodeValue"), QV4::NodePrototype::method_get_nodeValue, 0);
- o->defineAccessorProperty(QStringLiteral("nodeType"), QV4::NodePrototype::method_get_nodeType, 0);
- o->defineAccessorProperty(QStringLiteral("namespaceUri"), QV4::NodePrototype::method_get_namespaceUri, 0);
+ o->defineAccessorProperty(QStringLiteral("nodeName"), QV4::NodePrototype::method_get_nodeName, nullptr);
+ o->defineAccessorProperty(QStringLiteral("nodeValue"), QV4::NodePrototype::method_get_nodeValue, nullptr);
+ o->defineAccessorProperty(QStringLiteral("nodeType"), QV4::NodePrototype::method_get_nodeType, nullptr);
+ o->defineAccessorProperty(QStringLiteral("namespaceUri"), QV4::NodePrototype::method_get_namespaceUri, nullptr);
- o->defineAccessorProperty(QStringLiteral("parentNode"), QV4::NodePrototype::method_get_parentNode, 0);
- o->defineAccessorProperty(QStringLiteral("childNodes"), QV4::NodePrototype::method_get_childNodes, 0);
- o->defineAccessorProperty(QStringLiteral("firstChild"), QV4::NodePrototype::method_get_firstChild, 0);
- o->defineAccessorProperty(QStringLiteral("lastChild"), QV4::NodePrototype::method_get_lastChild, 0);
- o->defineAccessorProperty(QStringLiteral("previousSibling"), QV4::NodePrototype::method_get_previousSibling, 0);
- o->defineAccessorProperty(QStringLiteral("nextSibling"), QV4::NodePrototype::method_get_nextSibling, 0);
- o->defineAccessorProperty(QStringLiteral("attributes"), QV4::NodePrototype::method_get_attributes, 0);
+ o->defineAccessorProperty(QStringLiteral("parentNode"), QV4::NodePrototype::method_get_parentNode, nullptr);
+ o->defineAccessorProperty(QStringLiteral("childNodes"), QV4::NodePrototype::method_get_childNodes, nullptr);
+ o->defineAccessorProperty(QStringLiteral("firstChild"), QV4::NodePrototype::method_get_firstChild, nullptr);
+ o->defineAccessorProperty(QStringLiteral("lastChild"), QV4::NodePrototype::method_get_lastChild, nullptr);
+ o->defineAccessorProperty(QStringLiteral("previousSibling"), QV4::NodePrototype::method_get_previousSibling, nullptr);
+ o->defineAccessorProperty(QStringLiteral("nextSibling"), QV4::NodePrototype::method_get_nextSibling, nullptr);
+ o->defineAccessorProperty(QStringLiteral("attributes"), QV4::NodePrototype::method_get_attributes, nullptr);
}
@@ -355,10 +355,10 @@ class Attr : public Node
{
public:
// JS API
- static ReturnedValue method_name(const BuiltinFunction *b, QV4::CallData *callData);
+ static ReturnedValue method_name(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// static void specified(CallContext *);
- static ReturnedValue method_value(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_ownerElement(const BuiltinFunction *b, QV4::CallData *callData);
+ static ReturnedValue method_value(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_ownerElement(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// static void schemaTypeInfo(CallContext *);
// static void isId(CallContext *c);
@@ -370,7 +370,7 @@ class CharacterData : public Node
{
public:
// JS API
- static ReturnedValue method_length(const BuiltinFunction *b, QV4::CallData *callData);
+ static ReturnedValue method_length(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// C++ API
static ReturnedValue prototype(ExecutionEngine *v4);
@@ -380,8 +380,8 @@ class Text : public CharacterData
{
public:
// JS API
- static ReturnedValue method_isElementContentWhitespace(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_wholeText(const BuiltinFunction *b, QV4::CallData *callData);
+ static ReturnedValue method_isElementContentWhitespace(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_wholeText(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -398,10 +398,10 @@ class Document : public Node
{
public:
// JS API
- static ReturnedValue method_xmlVersion(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_xmlEncoding(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_xmlStandalone(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_documentElement(const BuiltinFunction *b, QV4::CallData *callData);
+ static ReturnedValue method_xmlVersion(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_xmlEncoding(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_xmlStandalone(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_documentElement(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -420,10 +420,10 @@ void NodeImpl::release()
document->release();
}
-ReturnedValue NodePrototype::method_get_nodeName(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_nodeName(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -445,10 +445,10 @@ ReturnedValue NodePrototype::method_get_nodeName(const BuiltinFunction *b, QV4::
return Encode(scope.engine->newString(name));
}
-ReturnedValue NodePrototype::method_get_nodeValue(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_nodeValue(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -464,30 +464,30 @@ ReturnedValue NodePrototype::method_get_nodeValue(const BuiltinFunction *b, QV4:
return Encode(scope.engine->newString(r->d()->d->data));
}
-ReturnedValue NodePrototype::method_get_nodeType(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_nodeType(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
return Encode(r->d()->d->type);
}
-ReturnedValue NodePrototype::method_get_namespaceUri(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_namespaceUri(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
return Encode(scope.engine->newString(r->d()->d->namespaceUri));
}
-ReturnedValue NodePrototype::method_get_parentNode(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_parentNode(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -497,20 +497,20 @@ ReturnedValue NodePrototype::method_get_parentNode(const BuiltinFunction *b, QV4
return Encode::null();
}
-ReturnedValue NodePrototype::method_get_childNodes(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_childNodes(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
return NodeList::create(scope.engine, r->d()->d);
}
-ReturnedValue NodePrototype::method_get_firstChild(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_firstChild(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -520,10 +520,10 @@ ReturnedValue NodePrototype::method_get_firstChild(const BuiltinFunction *b, QV4
return Node::create(scope.engine, r->d()->d->children.constFirst());
}
-ReturnedValue NodePrototype::method_get_lastChild(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_lastChild(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -533,10 +533,10 @@ ReturnedValue NodePrototype::method_get_lastChild(const BuiltinFunction *b, QV4:
return Node::create(scope.engine, r->d()->d->children.constLast());
}
-ReturnedValue NodePrototype::method_get_previousSibling(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_previousSibling(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -555,10 +555,10 @@ ReturnedValue NodePrototype::method_get_previousSibling(const BuiltinFunction *b
return Encode::null();
}
-ReturnedValue NodePrototype::method_get_nextSibling(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_nextSibling(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -577,10 +577,10 @@ ReturnedValue NodePrototype::method_get_nextSibling(const BuiltinFunction *b, QV
return Encode::null();
}
-ReturnedValue NodePrototype::method_get_attributes(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_attributes(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -644,7 +644,7 @@ ReturnedValue Element::prototype(ExecutionEngine *engine)
ScopedObject p(scope, engine->newObject());
ScopedObject pp(scope);
p->setPrototype((pp = NodePrototype::getProto(engine)));
- p->defineAccessorProperty(QStringLiteral("tagName"), NodePrototype::method_get_nodeName, 0);
+ p->defineAccessorProperty(QStringLiteral("tagName"), NodePrototype::method_get_nodeName, nullptr);
d->elementPrototype.set(engine, p);
engine->v8Engine->freezeObject(p);
}
@@ -659,49 +659,49 @@ ReturnedValue Attr::prototype(ExecutionEngine *engine)
ScopedObject p(scope, engine->newObject());
ScopedObject pp(scope);
p->setPrototype((pp = NodePrototype::getProto(engine)));
- p->defineAccessorProperty(QStringLiteral("name"), method_name, 0);
- p->defineAccessorProperty(QStringLiteral("value"), method_value, 0);
- p->defineAccessorProperty(QStringLiteral("ownerElement"), method_ownerElement, 0);
+ p->defineAccessorProperty(QStringLiteral("name"), method_name, nullptr);
+ p->defineAccessorProperty(QStringLiteral("value"), method_value, nullptr);
+ p->defineAccessorProperty(QStringLiteral("ownerElement"), method_ownerElement, nullptr);
d->attrPrototype.set(engine, p);
engine->v8Engine->freezeObject(p);
}
return d->attrPrototype.value();
}
-ReturnedValue Attr::method_name(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue Attr::method_name(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
return Encode(scope.engine->newString(r->d()->d->name));
}
-ReturnedValue Attr::method_value(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue Attr::method_value(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
return Encode(scope.engine->newString(r->d()->d->data));
}
-ReturnedValue Attr::method_ownerElement(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue Attr::method_ownerElement(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
return Node::create(scope.engine, r->d()->d->parent);
}
-ReturnedValue CharacterData::method_length(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue CharacterData::method_length(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
@@ -716,28 +716,28 @@ ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
ScopedObject p(scope, v4->newObject());
ScopedObject pp(scope);
p->setPrototype((pp = NodePrototype::getProto(v4)));
- p->defineAccessorProperty(QStringLiteral("data"), NodePrototype::method_get_nodeValue, 0);
- p->defineAccessorProperty(QStringLiteral("length"), method_length, 0);
+ p->defineAccessorProperty(QStringLiteral("data"), NodePrototype::method_get_nodeValue, nullptr);
+ p->defineAccessorProperty(QStringLiteral("length"), method_length, nullptr);
d->characterDataPrototype.set(v4, p);
v4->v8Engine->freezeObject(p);
}
return d->characterDataPrototype.value();
}
-ReturnedValue Text::method_isElementContentWhitespace(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue Text::method_isElementContentWhitespace(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
return Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty());
}
-ReturnedValue Text::method_wholeText(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue Text::method_wholeText(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
@@ -752,8 +752,8 @@ ReturnedValue Text::prototype(ExecutionEngine *v4)
ScopedObject p(scope, v4->newObject());
ScopedObject pp(scope);
p->setPrototype((pp = CharacterData::prototype(v4)));
- p->defineAccessorProperty(QStringLiteral("isElementContentWhitespace"), method_isElementContentWhitespace, 0);
- p->defineAccessorProperty(QStringLiteral("wholeText"), method_wholeText, 0);
+ p->defineAccessorProperty(QStringLiteral("isElementContentWhitespace"), method_isElementContentWhitespace, nullptr);
+ p->defineAccessorProperty(QStringLiteral("wholeText"), method_wholeText, nullptr);
d->textPrototype.set(v4, p);
v4->v8Engine->freezeObject(p);
}
@@ -783,10 +783,10 @@ ReturnedValue Document::prototype(ExecutionEngine *v4)
ScopedObject p(scope, v4->newObject());
ScopedObject pp(scope);
p->setPrototype((pp = NodePrototype::getProto(v4)));
- p->defineAccessorProperty(QStringLiteral("xmlVersion"), method_xmlVersion, 0);
- p->defineAccessorProperty(QStringLiteral("xmlEncoding"), method_xmlEncoding, 0);
- p->defineAccessorProperty(QStringLiteral("xmlStandalone"), method_xmlStandalone, 0);
- p->defineAccessorProperty(QStringLiteral("documentElement"), method_documentElement, 0);
+ p->defineAccessorProperty(QStringLiteral("xmlVersion"), method_xmlVersion, nullptr);
+ p->defineAccessorProperty(QStringLiteral("xmlEncoding"), method_xmlEncoding, nullptr);
+ p->defineAccessorProperty(QStringLiteral("xmlStandalone"), method_xmlStandalone, nullptr);
+ p->defineAccessorProperty(QStringLiteral("documentElement"), method_documentElement, nullptr);
d->documentPrototype.set(v4, p);
v4->v8Engine->freezeObject(p);
}
@@ -797,7 +797,7 @@ ReturnedValue Document::load(ExecutionEngine *v4, const QByteArray &data)
{
Scope scope(v4);
- DocumentImpl *document = 0;
+ DocumentImpl *document = nullptr;
QStack<NodeImpl *> nodeStack;
QXmlStreamReader reader(data);
@@ -885,7 +885,7 @@ ReturnedValue Document::load(ExecutionEngine *v4, const QByteArray &data)
bool Node::isNull() const
{
- return d()->d == 0;
+ return d()->d == nullptr;
}
ReturnedValue NamedNodeMap::getIndexed(const Managed *m, uint index, bool *hasProperty)
@@ -967,40 +967,40 @@ ReturnedValue NodeList::create(ExecutionEngine *v4, NodeImpl *data)
return (v4->memoryManager->allocObject<NodeList>(data))->asReturnedValue();
}
-ReturnedValue Document::method_documentElement(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue Document::method_documentElement(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
RETURN_UNDEFINED();
return Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root);
}
-ReturnedValue Document::method_xmlStandalone(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue Document::method_xmlStandalone(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
RETURN_UNDEFINED();
return Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone);
}
-ReturnedValue Document::method_xmlVersion(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue Document::method_xmlVersion(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
RETURN_UNDEFINED();
return Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version));
}
-ReturnedValue Document::method_xmlEncoding(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue Document::method_xmlEncoding(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
RETURN_UNDEFINED();
@@ -1098,7 +1098,7 @@ private:
QQmlXMLHttpRequest::QQmlXMLHttpRequest(QNetworkAccessManager *manager)
: m_state(Unsent), m_errorFlag(false), m_sendFlag(false)
- , m_redirectCount(0), m_gotXml(false), m_textCodec(0), m_network(0), m_nam(manager)
+ , m_redirectCount(0), m_gotXml(false), m_textCodec(nullptr), m_network(nullptr), m_nam(manager)
, m_responseType()
, m_parsedDocument()
{
@@ -1443,7 +1443,7 @@ void QQmlXMLHttpRequest::finished()
dispatchCallback();
m_thisObject.clear();
- m_qmlContext.setContextData(0);
+ m_qmlContext.setContextData(nullptr);
}
@@ -1516,7 +1516,7 @@ QV4::ReturnedValue QQmlXMLHttpRequest::xmlResponseBody(QV4::ExecutionEngine* eng
#if QT_CONFIG(textcodec)
QTextCodec* QQmlXMLHttpRequest::findTextCodec() const
{
- QTextCodec *codec = 0;
+ QTextCodec *codec = nullptr;
if (!m_charset.isEmpty())
codec = QTextCodec::codecForName(m_charset);
@@ -1528,10 +1528,10 @@ QTextCodec* QQmlXMLHttpRequest::findTextCodec() const
}
if (!codec && m_mime == "text/html")
- codec = QTextCodec::codecForHtml(m_responseEntityBody, 0);
+ codec = QTextCodec::codecForHtml(m_responseEntityBody, nullptr);
if (!codec)
- codec = QTextCodec::codecForUtfText(m_responseEntityBody, 0);
+ codec = QTextCodec::codecForUtfText(m_responseEntityBody, nullptr);
if (!codec)
codec = QTextCodec::codecForName("UTF-8");
@@ -1595,7 +1595,7 @@ void QQmlXMLHttpRequest::destroyNetwork()
if (m_network) {
m_network->disconnect();
m_network->deleteLater();
- m_network = 0;
+ m_network = nullptr;
}
}
@@ -1653,21 +1653,21 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
void setupProto();
- static ReturnedValue method_open(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_setRequestHeader(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_send(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_abort(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_getResponseHeader(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_getAllResponseHeaders(const BuiltinFunction *b, QV4::CallData *callData);
-
- static ReturnedValue method_get_readyState(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_status(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_statusText(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_responseText(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_responseXML(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_response(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_get_responseType(const BuiltinFunction *b, QV4::CallData *callData);
- static ReturnedValue method_set_responseType(const BuiltinFunction *b, QV4::CallData *callData);
+ static ReturnedValue method_open(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setRequestHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_send(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_abort(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getResponseHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getAllResponseHeaders(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_get_readyState(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_status(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_statusText(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_responseText(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_responseXML(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_response(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_set_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
};
}
@@ -1709,12 +1709,12 @@ void QQmlXMLHttpRequestCtor::setupProto()
p->defineDefaultProperty(QStringLiteral("getAllResponseHeaders"), method_getAllResponseHeaders);
// Read-only properties
- p->defineAccessorProperty(QStringLiteral("readyState"), method_get_readyState, 0);
- p->defineAccessorProperty(QStringLiteral("status"),method_get_status, 0);
- p->defineAccessorProperty(QStringLiteral("statusText"),method_get_statusText, 0);
- p->defineAccessorProperty(QStringLiteral("responseText"),method_get_responseText, 0);
- p->defineAccessorProperty(QStringLiteral("responseXML"),method_get_responseXML, 0);
- p->defineAccessorProperty(QStringLiteral("response"),method_get_response, 0);
+ p->defineAccessorProperty(QStringLiteral("readyState"), method_get_readyState, nullptr);
+ p->defineAccessorProperty(QStringLiteral("status"),method_get_status, nullptr);
+ p->defineAccessorProperty(QStringLiteral("statusText"),method_get_statusText, nullptr);
+ p->defineAccessorProperty(QStringLiteral("responseText"),method_get_responseText, nullptr);
+ p->defineAccessorProperty(QStringLiteral("responseXML"),method_get_responseXML, nullptr);
+ p->defineAccessorProperty(QStringLiteral("response"),method_get_response, nullptr);
// Read-write properties
p->defineAccessorProperty(QStringLiteral("responseType"), method_get_responseType, method_set_responseType);
@@ -1729,19 +1729,19 @@ void QQmlXMLHttpRequestCtor::setupProto()
// XMLHttpRequest methods
-ReturnedValue QQmlXMLHttpRequestCtor::method_open(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_open(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc() < 2 || callData->argc() > 5)
+ if (argc < 2 || argc > 5)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
// Argument 0 - Method
- QString method = callData->args[0].toQStringNoThrow().toUpper();
+ QString method = argv[0].toQStringNoThrow().toUpper();
if (method != QLatin1String("GET") &&
method != QLatin1String("PUT") &&
method != QLatin1String("HEAD") &&
@@ -1753,23 +1753,23 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(const BuiltinFunction *b, QV4:
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type");
// Argument 1 - URL
- QUrl url = QUrl(callData->args[1].toQStringNoThrow());
+ QUrl url = QUrl(argv[1].toQStringNoThrow());
if (url.isRelative())
url = scope.engine->callingQmlContext()->resolvedUrl(url);
bool async = true;
// Argument 2 - async (optional)
- if (callData->argc() > 2) {
- async = callData->args[2].booleanValue();
+ if (argc > 2) {
+ async = argv[2].booleanValue();
}
// Argument 3/4 - user/pass (optional)
QString username, password;
- if (callData->argc() > 3)
- username = callData->args[3].toQStringNoThrow();
- if (callData->argc() > 4)
- password = callData->args[4].toQStringNoThrow();
+ if (argc > 3)
+ username = argv[3].toQStringNoThrow();
+ if (argc > 4)
+ password = argv[4].toQStringNoThrow();
// Clear the fragment (if any)
url.setFragment(QString());
@@ -1781,22 +1781,22 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(const BuiltinFunction *b, QV4:
return r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad);
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc() != 2)
+ if (argc != 2)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Opened || r->sendFlag())
THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- QString name = callData->args[0].toQStringNoThrow();
- QString value = callData->args[1].toQStringNoThrow();
+ QString name = argv[0].toQStringNoThrow();
+ QString value = argv[1].toQStringNoThrow();
// ### Check that name and value are well formed
@@ -1828,10 +1828,10 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(const BuiltinFunct
RETURN_UNDEFINED();
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_send(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_send(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1841,21 +1841,21 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_send(const BuiltinFunction *b, QV4:
THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
QByteArray data;
- if (callData->argc() > 0) {
- if (const ArrayBuffer *buffer = callData->args[0].as<ArrayBuffer>()) {
+ if (argc > 0) {
+ if (const ArrayBuffer *buffer = argv[0].as<ArrayBuffer>()) {
data = buffer->asByteArray();
} else {
- data = callData->args[0].toQStringNoThrow().toUtf8();
+ data = argv[0].toQStringNoThrow().toUtf8();
}
}
return r->send(w, scope.engine->callingQmlContext(), data);
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_abort(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_abort(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1863,15 +1863,15 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_abort(const BuiltinFunction *b, QV4
return r->abort(w, scope.engine->callingQmlContext());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc() != 1)
+ if (argc != 1)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
@@ -1879,18 +1879,18 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(const BuiltinFunc
r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- return Encode(scope.engine->newString(r->header(callData->args[0].toQStringNoThrow())));
+ return Encode(scope.engine->newString(r->header(argv[0].toQStringNoThrow())));
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const FunctionObject *b, const Value *thisObject, const Value *, int argc)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc() != 0)
+ if (argc != 0)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
@@ -1902,10 +1902,10 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const Builtin
}
// XMLHttpRequest properties
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1913,10 +1913,10 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(const BuiltinFunctio
return Encode(r->readyState());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1931,10 +1931,10 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(const BuiltinFunction *b
return Encode(r->replyStatus());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1949,10 +1949,10 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(const BuiltinFunctio
return Encode(scope.engine->newString(r->replyStatusText()));
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1964,10 +1964,10 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(const BuiltinFunct
return Encode(scope.engine->newString(r->responseBody()));
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1983,10 +1983,10 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(const BuiltinFuncti
}
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -2010,29 +2010,29 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(const BuiltinFunction
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseType(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseType(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
return Encode(scope.engine->newString(r->responseType()));
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(const BuiltinFunction *b, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(b);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc() < 1)
+ if (argc < 1)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
// Argument 0 - response type
- r->setResponseType(callData->args[0].toQStringNoThrow());
+ r->setResponseType(argv[0].toQStringNoThrow());
return Encode::undefined();
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 3627f29cb2..1371f1f041 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -151,10 +151,10 @@ void Heap::QtObject::init(QQmlEngine *qmlEngine)
o->defineDefaultProperty(QStringLiteral("createComponent"), QV4::QtObject::method_createComponent);
}
- o->defineAccessorProperty(QStringLiteral("platform"), QV4::QtObject::method_get_platform, 0);
- o->defineAccessorProperty(QStringLiteral("application"), QV4::QtObject::method_get_application, 0);
- o->defineAccessorProperty(QStringLiteral("inputMethod"), QV4::QtObject::method_get_inputMethod, 0);
- o->defineAccessorProperty(QStringLiteral("styleHints"), QV4::QtObject::method_get_styleHints, 0);
+ o->defineAccessorProperty(QStringLiteral("platform"), QV4::QtObject::method_get_platform, nullptr);
+ o->defineAccessorProperty(QStringLiteral("application"), QV4::QtObject::method_get_application, nullptr);
+ o->defineAccessorProperty(QStringLiteral("inputMethod"), QV4::QtObject::method_get_inputMethod, nullptr);
+ o->defineAccessorProperty(QStringLiteral("styleHints"), QV4::QtObject::method_get_styleHints, nullptr);
o->defineDefaultProperty(QStringLiteral("callLater"), QV4::QtObject::method_callLater);
}
@@ -228,12 +228,12 @@ void QtObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint
\qmlmethod bool Qt::isQtObject(object)
Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
*/
-ReturnedValue QtObject::method_isQtObject(const BuiltinFunction *, CallData *callData)
+ReturnedValue QtObject::method_isQtObject(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (callData->argc() == 0)
+ if (argc == 0)
RETURN_RESULT(QV4::Encode(false));
- return QV4::Encode(callData->args[0].as<QV4::QObjectWrapper>() != 0);
+ return QV4::Encode(argv[0].as<QV4::QObjectWrapper>() != nullptr);
}
/*!
@@ -242,17 +242,16 @@ ReturnedValue QtObject::method_isQtObject(const BuiltinFunction *, CallData *cal
Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-ReturnedValue QtObject::method_rgba(const BuiltinFunction *builtin, CallData *callData)
+ReturnedValue QtObject::method_rgba(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
- QV4::Scope scope(builtin);
- int argCount = callData->argc();
- if (argCount < 3 || argCount > 4)
+ QV4::Scope scope(f);
+ if (argc < 3 || argc > 4)
THROW_GENERIC_ERROR("Qt.rgba(): Invalid arguments");
- double r = callData->args[0].toNumber();
- double g = callData->args[1].toNumber();
- double b = callData->args[2].toNumber();
- double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
+ double r = argv[0].toNumber();
+ double g = argv[1].toNumber();
+ double b = argv[2].toNumber();
+ double a = (argc == 4) ? argv[3].toNumber() : 1;
if (r < 0.0) r=0.0;
if (r > 1.0) r=1.0;
@@ -272,17 +271,17 @@ ReturnedValue QtObject::method_rgba(const BuiltinFunction *builtin, CallData *ca
Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-ReturnedValue QtObject::method_hsla(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_hsla(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- int argCount = callData->argc();
+ int argCount = argc;
if (argCount < 3 || argCount > 4)
THROW_GENERIC_ERROR("Qt.hsla(): Invalid arguments");
- double h = callData->args[0].toNumber();
- double s = callData->args[1].toNumber();
- double l = callData->args[2].toNumber();
- double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
+ double h = argv[0].toNumber();
+ double s = argv[1].toNumber();
+ double l = argv[2].toNumber();
+ double a = (argCount == 4) ? argv[3].toNumber() : 1;
if (h < 0.0) h=0.0;
if (h > 1.0) h=1.0;
@@ -304,17 +303,17 @@ All components should be in the range 0-1 inclusive.
\since 5.5
*/
-ReturnedValue QtObject::method_hsva(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_hsva(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- int argCount = callData->argc();
+ int argCount = argc;
if (argCount < 3 || argCount > 4)
THROW_GENERIC_ERROR("Qt.hsva(): Invalid arguments");
- double h = callData->args[0].toNumber();
- double s = callData->args[1].toNumber();
- double v = callData->args[2].toNumber();
- double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
+ double h = argv[0].toNumber();
+ double s = argv[1].toNumber();
+ double v = argv[2].toNumber();
+ double a = (argCount == 4) ? argv[3].toNumber() : 1;
h = qBound(0.0, h, 1.0);
s = qBound(0.0, s, 1.0);
@@ -332,15 +331,15 @@ may be either color values or string values. If a string value is supplied it
must be convertible to a color, as described for the \l{colorbasictypedocs}{color}
basic type.
*/
-ReturnedValue QtObject::method_colorEqual(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_colorEqual(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 2)
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
bool ok = false;
- QVariant lhs = scope.engine->toVariant(callData->args[0], -1);
+ QVariant lhs = scope.engine->toVariant(argv[0], -1);
if (lhs.userType() == QVariant::String) {
lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok);
if (!ok) {
@@ -350,7 +349,7 @@ ReturnedValue QtObject::method_colorEqual(const BuiltinFunction *b, CallData *ca
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
- QVariant rhs = scope.engine->toVariant(callData->args[1], -1);
+ QVariant rhs = scope.engine->toVariant(argv[1], -1);
if (rhs.userType() == QVariant::String) {
rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok);
if (!ok) {
@@ -371,16 +370,16 @@ Returns a \c rect with the top-left corner at \c x, \c y and the specified \c wi
The returned object has \c x, \c y, \c width and \c height attributes with the given values.
*/
-ReturnedValue QtObject::method_rect(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_rect(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 4)
+ if (argc != 4)
THROW_GENERIC_ERROR("Qt.rect(): Invalid arguments");
- double x = callData->args[0].toNumber();
- double y = callData->args[1].toNumber();
- double w = callData->args[2].toNumber();
- double h = callData->args[3].toNumber();
+ double x = argv[0].toNumber();
+ double y = argv[1].toNumber();
+ double w = argv[2].toNumber();
+ double h = argv[3].toNumber();
return scope.engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
}
@@ -389,14 +388,14 @@ ReturnedValue QtObject::method_rect(const BuiltinFunction *b, CallData *callData
\qmlmethod point Qt::point(int x, int y)
Returns a Point with the specified \c x and \c y coordinates.
*/
-ReturnedValue QtObject::method_point(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_point(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 2)
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.point(): Invalid arguments");
- double x = callData->args[0].toNumber();
- double y = callData->args[1].toNumber();
+ double x = argv[0].toNumber();
+ double y = argv[1].toNumber();
return scope.engine->fromVariant(QVariant::fromValue(QPointF(x, y)));
}
@@ -405,14 +404,14 @@ ReturnedValue QtObject::method_point(const BuiltinFunction *b, CallData *callDat
\qmlmethod Qt::size(int width, int height)
Returns a Size with the specified \c width and \c height.
*/
-ReturnedValue QtObject::method_size(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_size(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 2)
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.size(): Invalid arguments");
- double w = callData->args[0].toNumber();
- double h = callData->args[1].toNumber();
+ double w = argv[0].toNumber();
+ double h = argv[1].toNumber();
return scope.engine->fromVariant(QVariant::fromValue(QSizeF(w, h)));
}
@@ -425,15 +424,15 @@ key-value pairs where valid keys are the \l{fontbasictypedocs}{font} type's
subproperty names, and the values are valid values for each subproperty.
Invalid keys will be ignored.
*/
-ReturnedValue QtObject::method_font(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_font(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1 || !callData->args[0].isObject())
+ if (argc != 1 || !argv[0].isObject())
THROW_GENERIC_ERROR("Qt.font(): Invalid arguments");
QV4::ExecutionEngine *v4 = scope.engine;
bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(callData->args[0]), v4, &ok);
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(argv[0]), v4, &ok);
if (!ok)
THROW_GENERIC_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
return scope.engine->fromVariant(v);
@@ -445,15 +444,15 @@ ReturnedValue QtObject::method_font(const BuiltinFunction *b, CallData *callData
\qmlmethod Qt::vector2d(real x, real y)
Returns a Vector2D with the specified \c x and \c y.
*/
-ReturnedValue QtObject::method_vector2d(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_vector2d(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 2)
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.vector2d(): Invalid arguments");
float xy[3]; // qvector2d uses float internally
- xy[0] = callData->args[0].toNumber();
- xy[1] = callData->args[1].toNumber();
+ xy[0] = argv[0].toNumber();
+ xy[1] = argv[1].toNumber();
const void *params[] = { xy };
return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
@@ -463,16 +462,16 @@ ReturnedValue QtObject::method_vector2d(const BuiltinFunction *b, CallData *call
\qmlmethod Qt::vector3d(real x, real y, real z)
Returns a Vector3D with the specified \c x, \c y and \c z.
*/
-ReturnedValue QtObject::method_vector3d(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_vector3d(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 3)
+ if (argc != 3)
THROW_GENERIC_ERROR("Qt.vector3d(): Invalid arguments");
float xyz[3]; // qvector3d uses float internally
- xyz[0] = callData->args[0].toNumber();
- xyz[1] = callData->args[1].toNumber();
- xyz[2] = callData->args[2].toNumber();
+ xyz[0] = argv[0].toNumber();
+ xyz[1] = argv[1].toNumber();
+ xyz[2] = argv[2].toNumber();
const void *params[] = { xyz };
return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
@@ -482,17 +481,17 @@ ReturnedValue QtObject::method_vector3d(const BuiltinFunction *b, CallData *call
\qmlmethod Qt::vector4d(real x, real y, real z, real w)
Returns a Vector4D with the specified \c x, \c y, \c z and \c w.
*/
-ReturnedValue QtObject::method_vector4d(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_vector4d(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 4)
+ if (argc != 4)
THROW_GENERIC_ERROR("Qt.vector4d(): Invalid arguments");
float xyzw[4]; // qvector4d uses float internally
- xyzw[0] = callData->args[0].toNumber();
- xyzw[1] = callData->args[1].toNumber();
- xyzw[2] = callData->args[2].toNumber();
- xyzw[3] = callData->args[3].toNumber();
+ xyzw[0] = argv[0].toNumber();
+ xyzw[1] = argv[1].toNumber();
+ xyzw[2] = argv[2].toNumber();
+ xyzw[3] = argv[3].toNumber();
const void *params[] = { xyzw };
return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
@@ -502,17 +501,17 @@ ReturnedValue QtObject::method_vector4d(const BuiltinFunction *b, CallData *call
\qmlmethod Qt::quaternion(real scalar, real x, real y, real z)
Returns a Quaternion with the specified \c scalar, \c x, \c y, and \c z.
*/
-ReturnedValue QtObject::method_quaternion(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_quaternion(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 4)
+ if (argc != 4)
THROW_GENERIC_ERROR("Qt.quaternion(): Invalid arguments");
qreal sxyz[4]; // qquaternion uses qreal internally
- sxyz[0] = callData->args[0].toNumber();
- sxyz[1] = callData->args[1].toNumber();
- sxyz[2] = callData->args[2].toNumber();
- sxyz[3] = callData->args[3].toNumber();
+ sxyz[0] = argv[0].toNumber();
+ sxyz[1] = argv[1].toNumber();
+ sxyz[2] = argv[2].toNumber();
+ sxyz[3] = argv[3].toNumber();
const void *params[] = { sxyz };
return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
@@ -527,42 +526,42 @@ matrix values.
Finally, the function may be called with no arguments and the resulting
matrix will be the identity matrix.
*/
-ReturnedValue QtObject::method_matrix4x4(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_matrix4x4(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() == 0) {
+ if (argc == 0) {
return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, nullptr));
}
- if (callData->argc() == 1 && callData->args[0].isObject()) {
+ if (argc == 1 && argv[0].isObject()) {
bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(callData->args[0]), scope.engine, &ok);
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(argv[0]), scope.engine, &ok);
if (!ok)
THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
return scope.engine->fromVariant(v);
}
- if (callData->argc() != 16)
+ if (argc != 16)
THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid arguments");
qreal vals[16]; // qmatrix4x4 uses qreal internally
- vals[0] = callData->args[0].toNumber();
- vals[1] = callData->args[1].toNumber();
- vals[2] = callData->args[2].toNumber();
- vals[3] = callData->args[3].toNumber();
- vals[4] = callData->args[4].toNumber();
- vals[5] = callData->args[5].toNumber();
- vals[6] = callData->args[6].toNumber();
- vals[7] = callData->args[7].toNumber();
- vals[8] = callData->args[8].toNumber();
- vals[9] = callData->args[9].toNumber();
- vals[10] = callData->args[10].toNumber();
- vals[11] = callData->args[11].toNumber();
- vals[12] = callData->args[12].toNumber();
- vals[13] = callData->args[13].toNumber();
- vals[14] = callData->args[14].toNumber();
- vals[15] = callData->args[15].toNumber();
+ vals[0] = argv[0].toNumber();
+ vals[1] = argv[1].toNumber();
+ vals[2] = argv[2].toNumber();
+ vals[3] = argv[3].toNumber();
+ vals[4] = argv[4].toNumber();
+ vals[5] = argv[5].toNumber();
+ vals[6] = argv[6].toNumber();
+ vals[7] = argv[7].toNumber();
+ vals[8] = argv[8].toNumber();
+ vals[9] = argv[9].toNumber();
+ vals[10] = argv[10].toNumber();
+ vals[11] = argv[11].toNumber();
+ vals[12] = argv[12].toNumber();
+ vals[13] = argv[13].toNumber();
+ vals[14] = argv[14].toNumber();
+ vals[15] = argv[15].toNumber();
const void *params[] = { vals };
return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
@@ -582,13 +581,13 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
*/
-ReturnedValue QtObject::method_lighter(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_lighter(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1 && callData->argc() != 2)
+ if (argc != 1 && argc != 2)
THROW_GENERIC_ERROR("Qt.lighter(): Invalid arguments");
- QVariant v = scope.engine->toVariant(callData->args[0], -1);
+ QVariant v = scope.engine->toVariant(argv[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
@@ -600,8 +599,8 @@ ReturnedValue QtObject::method_lighter(const BuiltinFunction *b, CallData *callD
}
qreal factor = 1.5;
- if (callData->argc() == 2)
- factor = callData->args[1].toNumber();
+ if (argc == 2)
+ factor = argv[1].toNumber();
return scope.engine->fromVariant(QQml_colorProvider()->lighter(v, factor));
}
@@ -621,13 +620,13 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
*/
-ReturnedValue QtObject::method_darker(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_darker(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1 && callData->argc() != 2)
+ if (argc != 1 && argc != 2)
THROW_GENERIC_ERROR("Qt.darker(): Invalid arguments");
- QVariant v = scope.engine->toVariant(callData->args[0], -1);
+ QVariant v = scope.engine->toVariant(argv[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
@@ -639,8 +638,8 @@ ReturnedValue QtObject::method_darker(const BuiltinFunction *b, CallData *callDa
}
qreal factor = 2.0;
- if (callData->argc() == 2)
- factor = callData->args[1].toNumber();
+ if (argc == 2)
+ factor = argv[1].toNumber();
return scope.engine->fromVariant(QQml_colorProvider()->darker(v, factor));
}
@@ -669,14 +668,14 @@ ReturnedValue QtObject::method_darker(const BuiltinFunction *b, CallData *callDa
Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color.
*/
-ReturnedValue QtObject::method_tint(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_tint(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 2)
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.tint(): Invalid arguments");
// base color
- QVariant v1 = scope.engine->toVariant(callData->args[0], -1);
+ QVariant v1 = scope.engine->toVariant(argv[0], -1);
if (v1.userType() == QVariant::String) {
bool ok = false;
v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
@@ -688,7 +687,7 @@ ReturnedValue QtObject::method_tint(const BuiltinFunction *b, CallData *callData
}
// tint color
- QVariant v2 = scope.engine->toVariant(callData->args[1], -1);
+ QVariant v2 = scope.engine->toVariant(argv[1], -1);
if (v2.userType() == QVariant::String) {
bool ok = false;
v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
@@ -718,22 +717,22 @@ If \a format is not specified, \a date is formatted using
\sa Locale
*/
-ReturnedValue QtObject::method_formatDate(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_formatDate(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 1 || callData->argc() > 2)
+ if (argc < 1 || argc > 2)
THROW_GENERIC_ERROR("Qt.formatDate(): Invalid arguments");
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDate date = scope.engine->toVariant(callData->args[0], -1).toDateTime().date();
+ QDate date = scope.engine->toVariant(argv[0], -1).toDateTime().date();
QString formattedDate;
- if (callData->argc() == 2) {
- QV4::ScopedString s(scope, callData->args[1]);
+ if (argc == 2) {
+ QV4::ScopedString s(scope, argv[1]);
if (s) {
QString format = s->toQString();
formattedDate = date.toString(format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].asDouble();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDate = date.toString(format);
} else {
@@ -761,28 +760,28 @@ If \a format is not specified, \a time is formatted using
\sa Locale
*/
-ReturnedValue QtObject::method_formatTime(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_formatTime(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 1 || callData->argc() > 2)
+ if (argc < 1 || argc > 2)
THROW_GENERIC_ERROR("Qt.formatTime(): Invalid arguments");
- QVariant argVariant = scope.engine->toVariant(callData->args[0], -1);
+ QVariant argVariant = scope.engine->toVariant(argv[0], -1);
QTime time;
- if (callData->args[0].as<DateObject>() || (argVariant.type() == QVariant::String))
+ if (argv[0].as<DateObject>() || (argVariant.type() == QVariant::String))
time = argVariant.toDateTime().time();
else // if (argVariant.type() == QVariant::Time), or invalid.
time = argVariant.toTime();
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
QString formattedTime;
- if (callData->argc() == 2) {
- QV4::ScopedString s(scope, callData->args[1]);
+ if (argc == 2) {
+ QV4::ScopedString s(scope, argv[1]);
if (s) {
QString format = s->toQString();
formattedTime = time.toString(format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].asDouble();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedTime = time.toString(format);
} else {
@@ -887,22 +886,22 @@ with the \a format values below to produce the following results:
\sa Locale
*/
-ReturnedValue QtObject::method_formatDateTime(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_formatDateTime(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 1 || callData->argc() > 2)
+ if (argc < 1 || argc > 2)
THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid arguments");
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDateTime dt = scope.engine->toVariant(callData->args[0], -1).toDateTime();
+ QDateTime dt = scope.engine->toVariant(argv[0], -1).toDateTime();
QString formattedDt;
- if (callData->argc() == 2) {
- QV4::ScopedString s(scope, callData->args[1]);
+ if (argc == 2) {
+ QV4::ScopedString s(scope, argv[1]);
if (s) {
QString format = s->toQString();
formattedDt = dt.toString(format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].asDouble();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDt = dt.toString(format);
} else {
@@ -926,14 +925,13 @@ ReturnedValue QtObject::method_formatDateTime(const BuiltinFunction *b, CallData
still fail to launch or fail to open the requested URL. This result will not be reported back
to the application.
*/
-ReturnedValue QtObject::method_openUrlExternally(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_openUrlExternally(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1) {
+ if (argc != 1)
return QV4::Encode(false);
- }
- ScopedValue result(scope, method_resolvedUrl(b, callData));
+ ScopedValue result(scope, method_resolvedUrl(b, thisObject, argv, argc));
QUrl url(result->toQStringNoThrow());
return scope.engine->fromVariant(QQml_guiProvider()->openUrlExternally(url));
}
@@ -942,13 +940,15 @@ ReturnedValue QtObject::method_openUrlExternally(const BuiltinFunction *b, CallD
\qmlmethod url Qt::resolvedUrl(url url)
Returns \a url resolved relative to the URL of the caller.
*/
-ReturnedValue QtObject::method_resolvedUrl(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_resolvedUrl(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
+ if (argc != 1)
+ return Encode::undefined();
- QUrl url = scope.engine->toVariant(callData->args[0], -1).toUrl();
+ QUrl url = scope.engine->toVariant(argv[0], -1).toUrl();
QQmlEngine *e = scope.engine->qmlEngine();
- QQmlEnginePrivate *p = 0;
+ QQmlEnginePrivate *p = nullptr;
if (e) p = QQmlEnginePrivate::get(e);
if (p) {
QQmlContextData *ctxt = scope.engine->callingQmlContext();
@@ -965,10 +965,10 @@ ReturnedValue QtObject::method_resolvedUrl(const BuiltinFunction *b, CallData *c
\qmlmethod list<string> Qt::fontFamilies()
Returns a list of the font families available to the application.
*/
-ReturnedValue QtObject::method_fontFamilies(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_fontFamilies(const FunctionObject *b, const Value *, const Value *, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 0)
+ if (argc != 0)
THROW_GENERIC_ERROR("Qt.fontFamilies(): Invalid arguments");
return scope.engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
@@ -978,13 +978,13 @@ ReturnedValue QtObject::method_fontFamilies(const BuiltinFunction *b, CallData *
\qmlmethod string Qt::md5(data)
Returns a hex string of the md5 hash of \c data.
*/
-ReturnedValue QtObject::method_md5(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_md5(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1)
+ if (argc != 1)
THROW_GENERIC_ERROR("Qt.md5(): Invalid arguments");
- QByteArray data = callData->args[0].toQStringNoThrow().toUtf8();
+ QByteArray data = argv[0].toQStringNoThrow().toUtf8();
QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
return Encode(scope.engine->newString(QLatin1String(result.toHex())));
}
@@ -993,13 +993,13 @@ ReturnedValue QtObject::method_md5(const BuiltinFunction *b, CallData *callData)
\qmlmethod string Qt::btoa(data)
Binary to ASCII - this function returns a base64 encoding of \c data.
*/
-ReturnedValue QtObject::method_btoa(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_btoa(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1)
+ if (argc != 1)
THROW_GENERIC_ERROR("Qt.btoa(): Invalid arguments");
- QByteArray data = callData->args[0].toQStringNoThrow().toUtf8();
+ QByteArray data = argv[0].toQStringNoThrow().toUtf8();
return Encode(scope.engine->newString(QLatin1String(data.toBase64())));
}
@@ -1008,13 +1008,13 @@ ReturnedValue QtObject::method_btoa(const BuiltinFunction *b, CallData *callData
\qmlmethod string Qt::atob(data)
ASCII to binary - this function decodes the base64 encoded \a data string and returns it.
*/
-ReturnedValue QtObject::method_atob(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_atob(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1)
+ if (argc != 1)
THROW_GENERIC_ERROR("Qt.atob(): Invalid arguments");
- QByteArray data = callData->args[0].toQStringNoThrow().toLatin1();
+ QByteArray data = argv[0].toQStringNoThrow().toLatin1();
return Encode(scope.engine->newString(QString::fromUtf8(QByteArray::fromBase64(data))));
}
@@ -1028,7 +1028,7 @@ QQmlEngine::quit() signal to the QCoreApplication::quit() slot.
\sa exit()
*/
-ReturnedValue QtObject::method_quit(const BuiltinFunction *b, CallData *)
+ReturnedValue QtObject::method_quit(const FunctionObject *b, const Value *, const Value *, int)
{
QQmlEnginePrivate::get(b->engine()->qmlEngine())->sendQuit();
return Encode::undefined();
@@ -1045,13 +1045,13 @@ ReturnedValue QtObject::method_quit(const BuiltinFunction *b, CallData *)
\sa quit()
*/
-ReturnedValue QtObject::method_exit(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_exit(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1)
+ if (argc != 1)
THROW_GENERIC_ERROR("Qt.exit(): Invalid arguments");
- int retCode = callData->args[0].toNumber();
+ int retCode = argv[0].toNumber();
QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendExit(retCode);
return QV4::Encode::undefined();
@@ -1081,10 +1081,10 @@ If this is the case, consider using \l{QtQml::Qt::createComponent()}{Qt.createCo
See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function.
*/
-ReturnedValue QtObject::method_createQmlObject(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 2 || callData->argc() > 3)
+ if (argc < 2 || argc > 3)
THROW_GENERIC_ERROR("Qt.createQmlObject(): Invalid arguments");
struct Error {
@@ -1116,33 +1116,37 @@ ReturnedValue QtObject::method_createQmlObject(const BuiltinFunction *b, CallDat
}
};
- QV8Engine *v8engine = scope.engine->v8Engine;
- QQmlEngine *engine = v8engine->engine();
+ QQmlEngine *engine = scope.engine->qmlEngine();
QQmlContextData *context = scope.engine->callingQmlContext();
+ if (!context) {
+ QQmlEngine *qmlEngine = scope.engine->qmlEngine();
+ if (qmlEngine)
+ context = QQmlContextData::get(QQmlEnginePrivate::get(qmlEngine)->rootContext);
+ }
Q_ASSERT(context);
- QQmlContext *effectiveContext = 0;
+ QQmlContext *effectiveContext = nullptr;
if (context->isPragmaLibraryContext)
effectiveContext = engine->rootContext();
else
effectiveContext = context->asQQmlContext();
Q_ASSERT(effectiveContext);
- QString qml = callData->args[0].toQStringNoThrow();
+ QString qml = argv[0].toQStringNoThrow();
if (qml.isEmpty())
RETURN_RESULT(Encode::null());
QUrl url;
- if (callData->argc() > 2)
- url = QUrl(callData->args[2].toQStringNoThrow());
+ if (argc > 2)
+ url = QUrl(argv[2].toQStringNoThrow());
else
url = QUrl(QLatin1String("inline"));
if (url.isValid() && url.isRelative())
url = context->resolvedUrl(url);
- QObject *parentArg = 0;
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, callData->args[1]);
+ QObject *parentArg = nullptr;
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, argv[1]);
if (!!qobjectWrapper)
parentArg = qobjectWrapper->object();
if (!parentArg)
@@ -1238,46 +1242,50 @@ See \l {Dynamic QML Object Creation from JavaScript} for more information on usi
To create a QML object from an arbitrary string of QML (instead of a file),
use \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}.
*/
-ReturnedValue QtObject::method_createComponent(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_createComponent(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 1 || callData->argc() > 3)
+ if (argc < 1 || argc > 3)
THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
- QV8Engine *v8engine = scope.engine->v8Engine;
- QQmlEngine *engine = v8engine->engine();
+ QQmlEngine *engine = scope.engine->qmlEngine();
QQmlContextData *context = scope.engine->callingQmlContext();
+ if (!context) {
+ QQmlEngine *qmlEngine = scope.engine->qmlEngine();
+ if (qmlEngine)
+ context = QQmlContextData::get(QQmlEnginePrivate::get(qmlEngine)->rootContext);
+ }
Q_ASSERT(context);
QQmlContextData *effectiveContext = context;
if (context->isPragmaLibraryContext)
- effectiveContext = 0;
+ effectiveContext = nullptr;
- QString arg = callData->args[0].toQStringNoThrow();
+ QString arg = argv[0].toQStringNoThrow();
if (arg.isEmpty())
RETURN_RESULT(QV4::Encode::null());
QQmlComponent::CompilationMode compileMode = QQmlComponent::PreferSynchronous;
- QObject *parentArg = 0;
+ QObject *parentArg = nullptr;
int consumedCount = 1;
- if (callData->argc() > 1) {
- ScopedValue lastArg(scope, callData->args[callData->argc()-1]);
+ if (argc > 1) {
+ ScopedValue lastArg(scope, argv[argc-1]);
// The second argument could be the mode enum
- if (callData->args[1].isInteger()) {
- int mode = callData->args[1].integerValue();
+ if (argv[1].isInteger()) {
+ int mode = argv[1].integerValue();
if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous))
THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
compileMode = QQmlComponent::CompilationMode(mode);
consumedCount += 1;
} else {
// The second argument could be the parent only if there are exactly two args
- if ((callData->argc() != 2) || !(lastArg->isObject() || lastArg->isNull()))
+ if ((argc != 2) || !(lastArg->isObject() || lastArg->isNull()))
THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
}
- if (consumedCount < callData->argc()) {
+ if (consumedCount < argc) {
if (lastArg->isObject()) {
Scoped<QObjectWrapper> qobjectWrapper(scope, lastArg);
if (qobjectWrapper)
@@ -1285,7 +1293,7 @@ ReturnedValue QtObject::method_createComponent(const BuiltinFunction *b, CallDat
if (!parentArg)
THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object");
} else if (lastArg->isNull()) {
- parentArg = 0;
+ parentArg = nullptr;
} else {
THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object");
}
@@ -1321,17 +1329,17 @@ ReturnedValue QtObject::method_createComponent(const BuiltinFunction *b, CallDat
\sa Locale
*/
-ReturnedValue QtObject::method_locale(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_locale(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
QString code;
- if (callData->argc() > 1)
+ if (argc > 1)
THROW_GENERIC_ERROR("locale() requires 0 or 1 argument");
- if (callData->argc() == 1 && !callData->args[0].isString())
+ if (argc == 1 && !argv[0].isString())
THROW_TYPE_ERROR_WITH_MESSAGE("locale(): argument (locale code) must be a string");
- if (callData->argc() == 1)
- code = callData->args[0].toQStringNoThrow();
+ if (argc == 1)
+ code = argv[0].toQStringNoThrow();
return QQmlLocale::locale(scope.engine, code);
}
@@ -1395,12 +1403,12 @@ DEFINE_OBJECT_VTABLE(QQmlBindingFunction);
\since 5.0
*/
-ReturnedValue QtObject::method_binding(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_binding(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1)
+ if (argc != 1)
THROW_GENERIC_ERROR("binding() requires 1 argument");
- const QV4::FunctionObject *f = callData->args[0].as<FunctionObject>();
+ const QV4::FunctionObject *f = argv[0].as<FunctionObject>();
if (!f)
THROW_TYPE_ERROR_WITH_MESSAGE("binding(): argument (binding expression) must be a function");
@@ -1408,14 +1416,14 @@ ReturnedValue QtObject::method_binding(const BuiltinFunction *b, CallData *callD
}
-ReturnedValue QtObject::method_get_platform(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_get_platform(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
// ### inefficient. Should be just a value based getter
- Object *o = callData->thisObject.as<Object>();
+ const Object *o = thisObject->as<Object>();
if (!o)
THROW_TYPE_ERROR();
- QtObject *qt = o->as<QtObject>();
+ const QtObject *qt = o->as<QtObject>();
if (!qt)
THROW_TYPE_ERROR();
@@ -1426,14 +1434,14 @@ ReturnedValue QtObject::method_get_platform(const BuiltinFunction *b, CallData *
return QV4::QObjectWrapper::wrap(scope.engine, qt->d()->platform);
}
-ReturnedValue QtObject::method_get_application(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_get_application(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
QV4::Scope scope(b);
// ### inefficient. Should be just a value based getter
- Object *o = callData->thisObject.as<Object>();
+ const Object *o = thisObject->as<Object>();
if (!o)
THROW_TYPE_ERROR();
- QtObject *qt = o->as<QtObject>();
+ const QtObject *qt = o->as<QtObject>();
if (!qt)
THROW_TYPE_ERROR();
@@ -1444,13 +1452,13 @@ ReturnedValue QtObject::method_get_application(const BuiltinFunction *b, CallDat
return QV4::QObjectWrapper::wrap(scope.engine, qt->d()->application);
}
-ReturnedValue QtObject::method_get_inputMethod(const BuiltinFunction *b, CallData *)
+ReturnedValue QtObject::method_get_inputMethod(const FunctionObject *b, const Value *, const Value *, int)
{
QObject *o = QQml_guiProvider()->inputMethod();
return QV4::QObjectWrapper::wrap(b->engine(), o);
}
-ReturnedValue QtObject::method_get_styleHints(const BuiltinFunction *b, CallData *)
+ReturnedValue QtObject::method_get_styleHints(const FunctionObject *b, const Value *, const Value *, int)
{
QObject *o = QQml_guiProvider()->styleHints();
return QV4::QObjectWrapper::wrap(b->engine(), o);
@@ -1513,17 +1521,17 @@ static QString jsStack(QV4::ExecutionEngine *engine) {
return stack;
}
-static ReturnedValue writeToConsole(const BuiltinFunction *b, CallData *callData,
+static ReturnedValue writeToConsole(const FunctionObject *b, const Value *, const Value *argv, int argc,
ConsoleLogTypes logType, bool printStack = false)
{
- QLoggingCategory *loggingCategory = 0;
+ QLoggingCategory *loggingCategory = nullptr;
QString result;
QV4::Scope scope(b);
QV4::ExecutionEngine *v4 = scope.engine;
int start = 0;
- if (callData->argc() > 0) {
- if (const QObjectWrapper* wrapper = callData->args[0].as<QObjectWrapper>()) {
+ if (argc > 0) {
+ if (const QObjectWrapper* wrapper = argv[0].as<QObjectWrapper>()) {
if (QQmlLoggingCategory* category = qobject_cast<QQmlLoggingCategory*>(wrapper->object())) {
if (category->category())
loggingCategory = category->category();
@@ -1535,14 +1543,14 @@ static ReturnedValue writeToConsole(const BuiltinFunction *b, CallData *callData
}
- for (int i = start, ei = callData->argc(); i < ei; ++i) {
+ for (int i = start, ei = argc; i < ei; ++i) {
if (i != start)
result.append(QLatin1Char(' '));
- if (callData->args[i].as<ArrayObject>())
- result += QLatin1Char('[') + callData->args[i].toQStringNoThrow() + QLatin1Char(']');
+ if (argv[i].as<ArrayObject>())
+ result += QLatin1Char('[') + argv[i].toQStringNoThrow() + QLatin1Char(']');
else
- result.append(callData->args[i].toQStringNoThrow());
+ result.append(argv[i].toQStringNoThrow());
}
if (printStack)
@@ -1584,25 +1592,25 @@ static ReturnedValue writeToConsole(const BuiltinFunction *b, CallData *callData
DEFINE_OBJECT_VTABLE(ConsoleObject);
-ReturnedValue ConsoleObject::method_error(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_error(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- return writeToConsole(b, callData, Error);
+ return writeToConsole(b, thisObject, argv, argc, Error);
}
-ReturnedValue ConsoleObject::method_log(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_log(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
//console.log
//console.debug
//print
- return writeToConsole(b, callData, Log);
+ return writeToConsole(b, thisObject, argv, argc, Log);
}
-ReturnedValue ConsoleObject::method_info(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_info(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- return writeToConsole(b, callData, Info);
+ return writeToConsole(b, thisObject, argv, argc, Info);
}
-ReturnedValue ConsoleObject::method_profile(const BuiltinFunction *b, CallData *)
+ReturnedValue ConsoleObject::method_profile(const FunctionObject *b, const Value *, const Value *, int)
{
QV4::Scope scope(b);
QV4::ExecutionEngine *v4 = scope.engine;
@@ -1622,7 +1630,7 @@ ReturnedValue ConsoleObject::method_profile(const BuiltinFunction *b, CallData *
return QV4::Encode::undefined();
}
-ReturnedValue ConsoleObject::method_profileEnd(const BuiltinFunction *b, CallData *)
+ReturnedValue ConsoleObject::method_profileEnd(const FunctionObject *b, const Value *, const Value *, int)
{
QV4::Scope scope(b);
QV4::ExecutionEngine *v4 = scope.engine;
@@ -1643,28 +1651,28 @@ ReturnedValue ConsoleObject::method_profileEnd(const BuiltinFunction *b, CallDat
return QV4::Encode::undefined();
}
-ReturnedValue ConsoleObject::method_time(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_time(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1)
+ if (argc != 1)
THROW_GENERIC_ERROR("console.time(): Invalid arguments");
QV8Engine *v8engine = scope.engine->v8Engine;
- QString name = callData->args[0].toQStringNoThrow();
+ QString name = argv[0].toQStringNoThrow();
v8engine->startTimer(name);
return QV4::Encode::undefined();
}
-ReturnedValue ConsoleObject::method_timeEnd(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_timeEnd(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1)
+ if (argc != 1)
THROW_GENERIC_ERROR("console.timeEnd(): Invalid arguments");
QV8Engine *v8engine = scope.engine->v8Engine;
- QString name = callData->args[0].toQStringNoThrow();
+ QString name = argv[0].toQStringNoThrow();
bool wasRunning;
qint64 elapsed = v8engine->stopTimer(name, &wasRunning);
if (wasRunning) {
@@ -1673,12 +1681,12 @@ ReturnedValue ConsoleObject::method_timeEnd(const BuiltinFunction *b, CallData *
return QV4::Encode::undefined();
}
-ReturnedValue ConsoleObject::method_count(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_count(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
// first argument: name to print. Ignore any additional arguments
QString name;
- if (callData->argc() > 0)
- name = callData->args[0].toQStringNoThrow();
+ if (argc > 0)
+ name = argv[0].toQStringNoThrow();
Scope scope(b);
QV4::ExecutionEngine *v4 = scope.engine;
@@ -1698,10 +1706,10 @@ ReturnedValue ConsoleObject::method_count(const BuiltinFunction *b, CallData *ca
return QV4::Encode::undefined();
}
-ReturnedValue ConsoleObject::method_trace(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_trace(const FunctionObject *b, const Value *, const Value *, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 0)
+ if (argc != 0)
THROW_GENERIC_ERROR("console.trace(): Invalid arguments");
QV4::ExecutionEngine *v4 = scope.engine;
@@ -1716,26 +1724,26 @@ ReturnedValue ConsoleObject::method_trace(const BuiltinFunction *b, CallData *ca
return QV4::Encode::undefined();
}
-ReturnedValue ConsoleObject::method_warn(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_warn(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- return writeToConsole(b, callData, Warn);
+ return writeToConsole(b, thisObject, argv, argc, Warn);
}
-ReturnedValue ConsoleObject::method_assert(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_assert(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() == 0)
+ if (argc == 0)
THROW_GENERIC_ERROR("console.assert(): Missing argument");
QV4::ExecutionEngine *v4 = scope.engine;
- if (!callData->args[0].toBoolean()) {
+ if (!argv[0].toBoolean()) {
QString message;
- for (int i = 1, ei = callData->argc(); i < ei; ++i) {
+ for (int i = 1, ei = argc; i < ei; ++i) {
if (i != 1)
message.append(QLatin1Char(' '));
- message.append(callData->args[i].toQStringNoThrow());
+ message.append(argv[i].toQStringNoThrow());
}
QString stack = jsStack(v4);
@@ -1749,13 +1757,13 @@ ReturnedValue ConsoleObject::method_assert(const BuiltinFunction *b, CallData *c
return QV4::Encode::undefined();
}
-ReturnedValue ConsoleObject::method_exception(const BuiltinFunction *b, CallData *callData)
+ReturnedValue ConsoleObject::method_exception(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() == 0)
+ if (argc == 0)
THROW_GENERIC_ERROR("console.exception(): Missing argument");
- return writeToConsole(b, callData, Error, true);
+ return writeToConsole(b, thisObject, argv, argc, Error, true);
}
@@ -1811,32 +1819,32 @@ void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions ext
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTranslate(const BuiltinFunction *b, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTranslate(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 2)
+ if (argc < 2)
THROW_GENERIC_ERROR("qsTranslate() requires at least two arguments");
- if (!callData->args[0].isString())
+ if (!argv[0].isString())
THROW_GENERIC_ERROR("qsTranslate(): first argument (context) must be a string");
- if (!callData->args[1].isString())
+ if (!argv[1].isString())
THROW_GENERIC_ERROR("qsTranslate(): second argument (sourceText) must be a string");
- if ((callData->argc() > 2) && !callData->args[2].isString())
+ if ((argc > 2) && !argv[2].isString())
THROW_GENERIC_ERROR("qsTranslate(): third argument (disambiguation) must be a string");
- QString context = callData->args[0].toQStringNoThrow();
- QString text = callData->args[1].toQStringNoThrow();
+ QString context = argv[0].toQStringNoThrow();
+ QString text = argv[1].toQStringNoThrow();
QString comment;
- if (callData->argc() > 2) comment = callData->args[2].toQStringNoThrow();
+ if (argc > 2) comment = argv[2].toQStringNoThrow();
int i = 3;
- if (callData->argc() > i && callData->args[i].isString()) {
+ if (argc > i && argv[i].isString()) {
qWarning("qsTranslate(): specifying the encoding as fourth argument is deprecated");
++i;
}
int n = -1;
- if (callData->argc() > i)
- n = callData->args[i].toInt32();
+ if (argc > i)
+ n = argv[i].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(),
text.toUtf8().constData(),
@@ -1868,13 +1876,13 @@ ReturnedValue GlobalExtensions::method_qsTranslate(const BuiltinFunction *b, Cal
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *b, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTranslateNoOp(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 2)
+ if (argc < 2)
return QV4::Encode::undefined();
else
- return callData->args[1].asReturnedValue();
+ return argv[1].asReturnedValue();
}
/*!
@@ -1894,16 +1902,16 @@ ReturnedValue GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *b,
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTr(const BuiltinFunction *b, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTr(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 1)
+ if (argc < 1)
THROW_GENERIC_ERROR("qsTr() requires at least one argument");
- if (!callData->args[0].isString())
+ if (!argv[0].isString())
THROW_GENERIC_ERROR("qsTr(): first argument (sourceText) must be a string");
- if ((callData->argc() > 1) && !callData->args[1].isString())
+ if ((argc > 1) && !argv[1].isString())
THROW_GENERIC_ERROR("qsTr(): second argument (disambiguation) must be a string");
- if ((callData->argc() > 2) && !callData->args[2].isNumber())
+ if ((argc > 2) && !argv[2].isNumber())
THROW_GENERIC_ERROR("qsTr(): third argument (n) must be a number");
QString context;
@@ -1933,13 +1941,13 @@ ReturnedValue GlobalExtensions::method_qsTr(const BuiltinFunction *b, CallData *
}
}
- QString text = callData->args[0].toQStringNoThrow();
+ QString text = argv[0].toQStringNoThrow();
QString comment;
- if (callData->argc() > 1)
- comment = callData->args[1].toQStringNoThrow();
+ if (argc > 1)
+ comment = argv[1].toQStringNoThrow();
int n = -1;
- if (callData->argc() > 2)
- n = callData->args[2].toInt32();
+ if (argc > 2)
+ n = argv[2].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(),
comment.toUtf8().constData(), n);
@@ -1969,12 +1977,12 @@ ReturnedValue GlobalExtensions::method_qsTr(const BuiltinFunction *b, CallData *
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTrNoOp(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (callData->argc() < 1)
+ if (argc < 1)
return QV4::Encode::undefined();
else
- return callData->args[0].asReturnedValue();
+ return argv[0].asReturnedValue();
}
/*!
@@ -2007,21 +2015,21 @@ ReturnedValue GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, CallDat
\sa QT_TRID_NOOP(), {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTrId(const BuiltinFunction *b, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTrId(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() < 1)
+ if (argc < 1)
THROW_GENERIC_ERROR("qsTrId() requires at least one argument");
- if (!callData->args[0].isString())
+ if (!argv[0].isString())
THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): first argument (id) must be a string");
- if (callData->argc() > 1 && !callData->args[1].isNumber())
+ if (argc > 1 && !argv[1].isNumber())
THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): second argument (n) must be a number");
int n = -1;
- if (callData->argc() > 1)
- n = callData->args[1].toInt32();
+ if (argc > 1)
+ n = argv[1].toInt32();
- return Encode(scope.engine->newString(qtTrId(callData->args[0].toQStringNoThrow().toUtf8().constData(), n)));
+ return Encode(scope.engine->newString(qtTrId(argv[0].toQStringNoThrow().toUtf8().constData(), n)));
}
/*!
@@ -2040,17 +2048,17 @@ ReturnedValue GlobalExtensions::method_qsTrId(const BuiltinFunction *b, CallData
\sa qsTrId(), {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTrIdNoOp(const BuiltinFunction *, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTrIdNoOp(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (callData->argc() < 1)
+ if (argc < 1)
return QV4::Encode::undefined();
else
- return callData->args[0].asReturnedValue();
+ return argv[0].asReturnedValue();
}
#endif // translation
-ReturnedValue GlobalExtensions::method_gc(const BuiltinFunction *b, CallData *)
+ReturnedValue GlobalExtensions::method_gc(const FunctionObject *b, const Value *, const Value *, int)
{
b->engine()->memoryManager->runGC();
@@ -2059,15 +2067,15 @@ ReturnedValue GlobalExtensions::method_gc(const BuiltinFunction *b, CallData *)
-ReturnedValue GlobalExtensions::method_string_arg(const BuiltinFunction *b, CallData *callData)
+ReturnedValue GlobalExtensions::method_string_arg(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
QV4::Scope scope(b);
- if (callData->argc() != 1)
+ if (argc != 1)
THROW_GENERIC_ERROR("String.arg(): Invalid arguments");
- QString value = callData->thisObject.toQString();
+ QString value = thisObject->toQString();
- QV4::ScopedValue arg(scope, callData->args[0]);
+ QV4::ScopedValue arg(scope, argv[0]);
if (arg->isInteger())
RETURN_RESULT(scope.engine->newString(value.arg(arg->integerValue())));
else if (arg->isDouble())
@@ -2098,10 +2106,10 @@ be passed on to the function invoked. Note that if redundant calls
are eliminated, then only the last set of arguments will be passed to the
function.
*/
-ReturnedValue QtObject::method_callLater(const BuiltinFunction *b, CallData *callData)
+ReturnedValue QtObject::method_callLater(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
QV8Engine *v8engine = b->engine()->v8Engine;
- return v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, callData);
+ return v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, thisObject, argv, argc);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index 7d61aa0ada..104dae5d79 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -93,45 +93,45 @@ struct QtObject : Object
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static ReturnedValue method_isQtObject(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_rgba(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_hsla(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_hsva(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_colorEqual(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_font(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_rect(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_point(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_size(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_vector2d(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_vector3d(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_vector4d(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_quaternion(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_matrix4x4(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_lighter(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_darker(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_tint(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_formatDate(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_formatTime(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_formatDateTime(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_openUrlExternally(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_fontFamilies(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_md5(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_btoa(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_atob(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_quit(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_exit(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_resolvedUrl(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_createQmlObject(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_createComponent(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_locale(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_binding(const BuiltinFunction *, CallData *callData);
-
- static ReturnedValue method_get_platform(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_get_application(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_get_inputMethod(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_get_styleHints(const BuiltinFunction *, CallData *callData);
-
- static ReturnedValue method_callLater(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_isQtObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_rgba(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_hsla(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_hsva(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_colorEqual(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_font(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_rect(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_point(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_size(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_vector2d(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_vector3d(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_vector4d(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_quaternion(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_matrix4x4(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_lighter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_darker(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_tint(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_formatDate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_formatTime(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_formatDateTime(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_openUrlExternally(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_fontFamilies(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_md5(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_btoa(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_atob(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_quit(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_exit(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_resolvedUrl(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_createQmlObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_createComponent(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_locale(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_binding(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_get_platform(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_application(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_inputMethod(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_styleHints(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_callLater(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
private:
void addAll();
@@ -142,18 +142,18 @@ struct ConsoleObject : Object
{
V4_OBJECT2(ConsoleObject, Object)
- static ReturnedValue method_error(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_log(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_info(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_profile(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_profileEnd(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_time(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_timeEnd(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_count(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_trace(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_warn(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_assert(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_exception(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_error(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_log(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_info(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_profile(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_profileEnd(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_time(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_timeEnd(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_count(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_trace(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_warn(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_assert(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_exception(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
};
@@ -161,17 +161,17 @@ struct Q_QML_PRIVATE_EXPORT GlobalExtensions {
static void init(Object *globalObject, QJSEngine::Extensions extensions);
#if QT_CONFIG(translation)
- static ReturnedValue method_qsTranslate(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_qsTranslateNoOp(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_qsTr(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_qsTrNoOp(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_qsTrId(const BuiltinFunction *, CallData *callData);
- static ReturnedValue method_qsTrIdNoOp(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_qsTranslate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTranslateNoOp(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTr(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTrNoOp(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTrId(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTrIdNoOp(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
#endif
- static ReturnedValue method_gc(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_gc(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// on String:prototype
- static ReturnedValue method_string_arg(const BuiltinFunction *, CallData *callData);
+ static ReturnedValue method_string_arg(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
};
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 624e222241..bdb066267a 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -123,11 +123,11 @@ static void restoreJSValue(QDataStream &stream, void *data)
}
}
-QV8Engine::QV8Engine(QJSEngine* qq)
+QV8Engine::QV8Engine(QJSEngine *qq, QV4::ExecutionEngine *v4)
: q(qq)
- , m_engine(0)
- , m_xmlHttpRequestData(0)
- , m_listModelData(0)
+ , m_engine(nullptr)
+ , m_v4Engine(v4)
+ , m_xmlHttpRequestData(nullptr)
{
#ifndef Q_OS_HTML5
#ifdef Q_PROCESSOR_X86_32
@@ -149,8 +149,6 @@ QV8Engine::QV8Engine(QJSEngine* qq)
QMetaType::registerConverter<QJSValue, QStringList>(convertJSValueToVariantType<QStringList>);
QMetaType::registerStreamOperators(qMetaTypeId<QJSValue>(), saveJSValue, restoreJSValue);
- m_v4Engine = new QV4::ExecutionEngine;
- m_v4Engine->v8Engine = this;
m_delayedCallQueue.init(m_v4Engine);
QV4::QObjectWrapper::initializeBindings(m_v4Engine);
@@ -163,13 +161,8 @@ QV8Engine::~QV8Engine()
#if QT_CONFIG(xmlstreamreader) && QT_CONFIG(qml_network)
qt_rem_qmlxmlhttprequest(m_v4Engine, m_xmlHttpRequestData);
- m_xmlHttpRequestData = 0;
+ m_xmlHttpRequestData = nullptr;
#endif
-
- delete m_listModelData;
- m_listModelData = 0;
-
- delete m_v4Engine;
}
#if QT_CONFIG(qml_network)
@@ -294,11 +287,6 @@ void QV8Engine::setEngine(QQmlEngine *engine)
initQmlGlobalObject();
}
-QV4::ReturnedValue QV8Engine::global()
-{
- return m_v4Engine->globalObject->asReturnedValue();
-}
-
void QV8Engine::startTimer(const QString &timerName)
{
if (!m_time.isValid())
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index a430fba0e6..b6a378667e 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -77,12 +77,6 @@ namespace QV4 {
struct QObjectMethod;
}
-#define V4THROW_ERROR(string) \
- return ctx->engine()->throwError(QString::fromUtf8(string));
-
-#define V4THROW_TYPE(string) \
- return ctx->engine()->throwTypeError(QStringLiteral(string));
-
#define V4_DEFINE_EXTENSION(dataclass, datafunction) \
static inline dataclass *datafunction(QV4::ExecutionEngine *engine) \
{ \
@@ -159,12 +153,11 @@ class Q_QML_PRIVATE_EXPORT QV8Engine
{
friend class QJSEngine;
public:
- static QV8Engine* get(QJSEngine* q) { Q_ASSERT(q); return q->handle(); }
// static QJSEngine* get(QV8Engine* d) { Q_ASSERT(d); return d->q; }
- static QV4::ExecutionEngine *getV4(QJSEngine *q) { return q->handle()->m_v4Engine; }
+ static QV4::ExecutionEngine *getV4(QJSEngine *q) { return q->handle(); }
static QV4::ExecutionEngine *getV4(QV8Engine *d) { return d->m_v4Engine; }
- QV8Engine(QJSEngine* qq);
+ QV8Engine(QJSEngine* qq, QV4::ExecutionEngine *v4);
virtual ~QV8Engine();
// This enum should be in sync with QQmlEngine::ObjectOwnership
@@ -178,14 +171,10 @@ public:
void setEngine(QQmlEngine *engine);
QQmlEngine *engine() { return m_engine; }
QJSEngine *publicEngine() { return q; }
- QV4::ReturnedValue global();
QQmlDelayedCallQueue *delayedCallQueue() { return &m_delayedCallQueue; }
void *xmlHttpRequestData() const { return m_xmlHttpRequestData; }
- Deletable *listModelData() const { return m_listModelData; }
- void setListModelData(Deletable *d) { if (m_listModelData) delete m_listModelData; m_listModelData = d; }
-
void freezeObject(const QV4::Value &value);
#if QT_CONFIG(qml_network)
@@ -222,7 +211,6 @@ protected:
void *m_xmlHttpRequestData;
QVector<Deletable *> m_extensionData;
- Deletable *m_listModelData;
QSet<QString> m_illegalNames;
@@ -242,7 +230,7 @@ inline QV8Engine::Deletable *QV8Engine::extensionData(int index) const
if (index < m_extensionData.count())
return m_extensionData[index];
else
- return 0;
+ return nullptr;
}
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index 91c5a50877..513f7f2997 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class QQmlBindPrivate : public QObjectPrivate
{
public:
- QQmlBindPrivate() : obj(0), componentComplete(true), delayed(false), pendingEval(false) {}
+ QQmlBindPrivate() : obj(nullptr), componentComplete(true), delayed(false), pendingEval(false) {}
~QQmlBindPrivate() { }
QQmlNullableValue<bool> when;
@@ -370,7 +370,7 @@ void QQmlBind::eval()
//restore any previous binding
if (d->prevBind) {
QQmlAbstractBinding::Ptr p = d->prevBind;
- d->prevBind = 0;
+ d->prevBind = nullptr;
QQmlPropertyPrivate::setBinding(p.data());
}
return;
diff --git a/src/qml/types/qqmlbind_p.h b/src/qml/types/qqmlbind_p.h
index c9dd14b58a..5bf9ef85c6 100644
--- a/src/qml/types/qqmlbind_p.h
+++ b/src/qml/types/qqmlbind_p.h
@@ -71,7 +71,7 @@ class Q_AUTOTEST_EXPORT QQmlBind : public QObject, public QQmlPropertyValueSourc
Q_PROPERTY(bool delayed READ delayed WRITE setDelayed REVISION 8)
public:
- QQmlBind(QObject *parent=0);
+ QQmlBind(QObject *parent=nullptr);
~QQmlBind();
bool when() const;
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index e218cdcfe4..a43562a7b8 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
class QQmlConnectionsPrivate : public QObjectPrivate
{
public:
- QQmlConnectionsPrivate() : target(0), enabled(true), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {}
+ QQmlConnectionsPrivate() : target(nullptr), enabled(true), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {}
QList<QQmlBoundSignal*> boundsignals;
QObject *target;
@@ -274,7 +274,7 @@ void QQmlConnections::connectSignals()
return;
QObject *target = this->target();
QQmlData *ddata = QQmlData::get(this);
- QQmlContextData *ctxtdata = ddata ? ddata->outerContext : 0;
+ QQmlContextData *ctxtdata = ddata ? ddata->outerContext : nullptr;
const QV4::CompiledData::Unit *qmlUnit = d->compilationUnit->data;
for (const QV4::CompiledData::Binding *binding : qAsConst(d->bindings)) {
@@ -290,7 +290,7 @@ void QQmlConnections::connectSignals()
QQmlBoundSignalExpression *expression = ctxtdata ?
new QQmlBoundSignalExpression(target, signalIndex,
- ctxtdata, this, d->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex]) : 0;
+ ctxtdata, this, d->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex]) : nullptr;
signal->takeExpression(expression);
d->boundsignals += signal;
} else {
diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h
index 580b6522de..50e2c59ac3 100644
--- a/src/qml/types/qqmlconnections_p.h
+++ b/src/qml/types/qqmlconnections_p.h
@@ -73,7 +73,7 @@ class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatu
Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals)
public:
- QQmlConnections(QObject *parent=0);
+ QQmlConnections(QObject *parent=nullptr);
~QQmlConnections();
QObject *target() const;
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 967f89971d..44166e4aa8 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -128,7 +128,8 @@ public:
QQmlDelegateModelEngineData(QV4::ExecutionEngine *v4);
~QQmlDelegateModelEngineData();
- QV4::ReturnedValue array(QV8Engine *engine, const QVector<QQmlChangeSet::Change> &changes);
+ QV4::ReturnedValue array(QV4::ExecutionEngine *engine,
+ const QVector<QQmlChangeSet::Change> &changes);
QV4::PersistentValue changeProto;
};
@@ -199,10 +200,10 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent)
*/
QQmlDelegateModelPrivate::QQmlDelegateModelPrivate(QQmlContext *ctxt)
- : m_delegate(0)
- , m_cacheMetaType(0)
+ : m_delegate(nullptr)
+ , m_cacheMetaType(nullptr)
, m_context(ctxt)
- , m_parts(0)
+ , m_parts(nullptr)
, m_filterGroup(QStringLiteral("items"))
, m_count(0)
, m_groupCount(Compositor::MinimumGroupCount)
@@ -213,9 +214,9 @@ QQmlDelegateModelPrivate::QQmlDelegateModelPrivate(QQmlContext *ctxt)
, m_transaction(false)
, m_incubatorCleanupScheduled(false)
, m_waitingToFetchMore(false)
- , m_cacheItems(0)
- , m_items(0)
- , m_persistedItems(0)
+ , m_cacheItems(nullptr)
+ , m_items(nullptr)
+ , m_persistedItems(nullptr)
{
}
@@ -267,10 +268,10 @@ QQmlDelegateModel::~QQmlDelegateModel()
if (cacheItem->object) {
delete cacheItem->object;
- cacheItem->object = 0;
+ cacheItem->object = nullptr;
cacheItem->contextData->invalidate();
Q_ASSERT(cacheItem->contextData->refCount == 1);
- cacheItem->contextData = 0;
+ cacheItem->contextData = nullptr;
cacheItem->scriptRef -= 1;
}
cacheItem->groups &= ~Compositor::UnresolvedFlag;
@@ -278,7 +279,7 @@ QQmlDelegateModel::~QQmlDelegateModel()
if (!cacheItem->isReferenced())
delete cacheItem;
else if (cacheItem->incubationTask)
- cacheItem->incubationTask->vdm = 0;
+ cacheItem->incubationTask->vdm = nullptr;
}
}
@@ -325,7 +326,7 @@ void QQmlDelegateModel::componentComplete()
}
d->m_cacheMetaType = new QQmlDelegateModelItemMetaType(
- QQmlEnginePrivate::getV8Engine(d->m_context->engine()), this, groupNames);
+ d->m_context->engine()->handle(), this, groupNames);
d->m_compositor.setGroupCount(d->m_groupCount);
d->m_compositor.setDefaultGroups(defaultGroups);
@@ -407,7 +408,7 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
qmlWarning(this) << tr("The delegate of a DelegateModel cannot be changed within onUpdated.");
return;
}
- bool wasValid = d->m_delegate != 0;
+ bool wasValid = d->m_delegate != nullptr;
d->m_delegate = delegate;
d->m_delegateValidated = false;
if (wasValid && d->m_complete) {
@@ -535,7 +536,7 @@ int QQmlDelegateModel::count() const
QQmlDelegateModel::ReleaseFlags QQmlDelegateModelPrivate::release(QObject *object)
{
- QQmlDelegateModel::ReleaseFlags stat = 0;
+ QQmlDelegateModel::ReleaseFlags stat = nullptr;
if (!object)
return stat;
@@ -545,7 +546,7 @@ QQmlDelegateModel::ReleaseFlags QQmlDelegateModelPrivate::release(QObject *objec
emitDestroyingItem(object);
if (cacheItem->incubationTask) {
releaseIncubator(cacheItem->incubationTask);
- cacheItem->incubationTask = 0;
+ cacheItem->incubationTask = nullptr;
}
cacheItem->Dispose();
stat |= QQmlInstanceModel::Destroyed;
@@ -581,7 +582,7 @@ void QQmlDelegateModel::cancel(int index)
if (cacheItem) {
if (cacheItem->incubationTask && !cacheItem->isObjectReferenced()) {
d->releaseIncubator(cacheItem->incubationTask);
- cacheItem->incubationTask = 0;
+ cacheItem->incubationTask = nullptr;
if (cacheItem->object) {
QObject *object = cacheItem->object;
@@ -630,7 +631,7 @@ QQmlDelegateModelGroup *QQmlDelegateModelPrivate::group_at(
QQmlDelegateModelPrivate *d = static_cast<QQmlDelegateModelPrivate *>(property->data);
return index >= 0 && index < d->m_groupCount - 1
? d->m_groups[index + 1]
- : 0;
+ : nullptr;
}
/*!
@@ -660,7 +661,7 @@ QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups()
QQmlDelegateModelPrivate::group_append,
QQmlDelegateModelPrivate::group_count,
QQmlDelegateModelPrivate::group_at,
- 0);
+ nullptr);
}
/*!
@@ -838,11 +839,11 @@ void QQDMIncubationTask::statusChanged(Status status)
Q_ASSERT(incubating);
// The model was deleted from under our feet, cleanup ourselves
delete incubating->object;
- incubating->object = 0;
+ incubating->object = nullptr;
if (incubating->contextData) {
incubating->contextData->invalidate();
Q_ASSERT(incubating->contextData->refCount == 1);
- incubating->contextData = 0;
+ incubating->contextData = nullptr;
}
incubating->scriptRef = 0;
incubating->deleteLater();
@@ -863,7 +864,7 @@ void QQmlDelegateModelPrivate::releaseIncubator(QQDMIncubationTask *incubationTa
void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem)
{
- int cidx = m_cache.indexOf(cacheItem);
+ int cidx = m_cache.lastIndexOf(cacheItem);
if (cidx >= 0) {
m_compositor.clearFlags(Compositor::Cache, cidx, 1, Compositor::CacheFlag);
m_cache.removeAt(cidx);
@@ -878,8 +879,8 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba
return;
QQmlDelegateModelItem *cacheItem = incubationTask->incubating;
- cacheItem->incubationTask = 0;
- incubationTask->incubating = 0;
+ cacheItem->incubationTask = nullptr;
+ incubationTask->incubating = nullptr;
releaseIncubator(incubationTask);
if (status == QQmlIncubator::Ready) {
@@ -899,13 +900,13 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba
else
emitDestroyingItem(cacheItem->object);
delete cacheItem->object;
- cacheItem->object = 0;
+ cacheItem->object = nullptr;
cacheItem->scriptRef -= 1;
if (cacheItem->contextData) {
cacheItem->contextData->invalidate();
Q_ASSERT(cacheItem->contextData->refCount == 1);
}
- cacheItem->contextData = 0;
+ cacheItem->contextData = nullptr;
if (!cacheItem->isReferenced()) {
removeCacheItem(cacheItem);
@@ -930,13 +931,13 @@ void QQmlDelegateModelPrivate::setInitialState(QQDMIncubationTask *incubationTas
emitInitItem(incubationTask, cacheItem->object);
}
-QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bool asynchronous)
+QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQmlIncubator::IncubationMode incubationMode)
{
if (!m_delegate || index < 0 || index >= m_compositor.count(group)) {
qWarning() << "DelegateModel::item: index out range" << index << m_compositor.count(group);
- return 0;
+ return nullptr;
} else if (!m_context || !m_context->isValid()) {
- return 0;
+ return nullptr;
}
Compositor::iterator it = m_compositor.find(group, index);
@@ -946,7 +947,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bo
if (!cacheItem) {
cacheItem = m_adaptorModel.createItem(m_cacheMetaType, it.modelIndex());
if (!cacheItem)
- return 0;
+ return nullptr;
cacheItem->groups = it->flags;
@@ -961,7 +962,8 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bo
cacheItem->referenceObject();
if (cacheItem->incubationTask) {
- if (!asynchronous && cacheItem->incubationTask->incubationMode() == QQmlIncubator::Asynchronous) {
+ bool sync = (incubationMode == QQmlIncubator::Synchronous || incubationMode == QQmlIncubator::AsynchronousIfNested);
+ if (sync && cacheItem->incubationTask->incubationMode() == QQmlIncubator::Asynchronous) {
// previously requested async - now needed immediately
cacheItem->incubationTask->forceCompletion();
}
@@ -970,7 +972,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bo
cacheItem->scriptRef += 1;
- cacheItem->incubationTask = new QQDMIncubationTask(this, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
+ cacheItem->incubationTask = new QQDMIncubationTask(this, incubationMode);
cacheItem->incubationTask->incubating = cacheItem;
cacheItem->incubationTask->clear();
@@ -1014,30 +1016,36 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bo
delete cacheItem;
}
- return 0;
+ return nullptr;
}
/*
If asynchronous is true or the component is being loaded asynchronously due
- to an ancestor being loaded asynchronously, item() may return 0. In this
- case createdItem() will be emitted when the item is available. The item
- at this stage does not have any references, so item() must be called again
- to ensure a reference is held. Any call to item() which returns a valid item
- must be matched by a call to release() in order to destroy the item.
+ to an ancestor being loaded asynchronously, object() may return 0. In this
+ case createdItem() will be emitted when the object is available. The object
+ at this stage does not have any references, so object() must be called again
+ to ensure a reference is held. Any call to object() which returns a valid object
+ must be matched by a call to release() in order to destroy the object.
*/
-QObject *QQmlDelegateModel::object(int index, bool asynchronous)
+QObject *QQmlDelegateModel::object(int index, QQmlIncubator::IncubationMode incubationMode)
{
Q_D(QQmlDelegateModel);
if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) {
qWarning() << "DelegateModel::item: index out range" << index << d->m_compositor.count(d->m_compositorGroup);
- return 0;
+ return nullptr;
}
- QObject *object = d->object(d->m_compositorGroup, index, asynchronous);
- if (!object)
- return 0;
+ return d->object(d->m_compositorGroup, index, incubationMode);
+}
+
+QQmlIncubator::Status QQmlDelegateModel::incubationStatus(int index)
+{
+ Q_D(QQmlDelegateModel);
+ Compositor::iterator it = d->m_compositor.find(d->m_compositorGroup, index);
+ if (!it->inCache())
+ return QQmlIncubator::Null;
- return object;
+ return d->m_cache.at(it.cacheIndex)->incubationTask->status();
}
QString QQmlDelegateModelPrivate::stringValue(Compositor::Group group, int index, const QString &name)
@@ -1339,7 +1347,7 @@ void QQmlDelegateModelPrivate::itemsRemoved(
if (QQDMIncubationTask *incubationTask = cacheItem->incubationTask) {
if (!cacheItem->isObjectReferenced()) {
releaseIncubator(cacheItem->incubationTask);
- cacheItem->incubationTask = 0;
+ cacheItem->incubationTask = nullptr;
if (cacheItem->object) {
QObject *object = cacheItem->object;
cacheItem->destroyObject();
@@ -1474,7 +1482,7 @@ void QQmlDelegateModelPrivate::emitChanges()
return;
m_transaction = true;
- QV8Engine *engine = QQmlEnginePrivate::getV8Engine(m_context->engine());
+ QV4::ExecutionEngine *engine = m_context->engine()->handle();
for (int i = 1; i < m_groupCount; ++i)
QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitChanges(engine);
m_transaction = false;
@@ -1660,7 +1668,7 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
// Must be before the new object is inserted into the cache or its indexes will be adjusted too.
itemsInserted(QVector<Compositor::Insert>(1, Compositor::Insert(before, 1, cacheItem->groups & ~Compositor::CacheFlag)));
- before = m_compositor.insert(before, 0, 0, 1, cacheItem->groups);
+ before = m_compositor.insert(before, nullptr, 0, 1, cacheItem->groups);
m_cache.insert(before.cacheIndex, cacheItem);
return true;
@@ -1669,11 +1677,11 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
//============================================================================
QQmlDelegateModelItemMetaType::QQmlDelegateModelItemMetaType(
- QV8Engine *engine, QQmlDelegateModel *model, const QStringList &groupNames)
+ QV4::ExecutionEngine *engine, QQmlDelegateModel *model, const QStringList &groupNames)
: model(model)
, groupCount(groupNames.count() + 1)
- , v8Engine(engine)
- , metaObject(0)
+ , v4Engine(engine)
+ , metaObject(nullptr)
, groupNames(groupNames)
{
}
@@ -1713,57 +1721,56 @@ void QQmlDelegateModelItemMetaType::initializeMetaObject()
void QQmlDelegateModelItemMetaType::initializePrototype()
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8Engine);
- QV4::Scope scope(v4);
+ QV4::Scope scope(v4Engine);
- QV4::ScopedObject proto(scope, v4->newObject());
- proto->defineAccessorProperty(QStringLiteral("model"), QQmlDelegateModelItem::get_model, 0);
+ QV4::ScopedObject proto(scope, v4Engine->newObject());
+ proto->defineAccessorProperty(QStringLiteral("model"), QQmlDelegateModelItem::get_model, nullptr);
proto->defineAccessorProperty(QStringLiteral("groups"), QQmlDelegateModelItem::get_groups, QQmlDelegateModelItem::set_groups);
QV4::ScopedString s(scope);
QV4::ScopedProperty p(scope);
- s = v4->newString(QStringLiteral("isUnresolved"));
+ s = v4Engine->newString(QStringLiteral("isUnresolved"));
QV4::ScopedFunctionObject f(scope);
QV4::ExecutionContext *global = scope.engine->rootContext();
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, 30, QQmlDelegateModelItem::get_member)));
- p->setSetter(0);
+ p->setSetter(nullptr);
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- s = v4->newString(QStringLiteral("inItems"));
+ s = v4Engine->newString(QStringLiteral("inItems"));
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::get_member)));
p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::set_member)));
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- s = v4->newString(QStringLiteral("inPersistedItems"));
+ s = v4Engine->newString(QStringLiteral("inPersistedItems"));
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_member)));
p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::set_member)));
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- s = v4->newString(QStringLiteral("itemsIndex"));
+ s = v4Engine->newString(QStringLiteral("itemsIndex"));
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::get_index)));
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- s = v4->newString(QStringLiteral("persistedItemsIndex"));
+ s = v4Engine->newString(QStringLiteral("persistedItemsIndex"));
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_index)));
- p->setSetter(0);
+ p->setSetter(nullptr);
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
for (int i = 2; i < groupNames.count(); ++i) {
QString propertyName = QLatin1String("in") + groupNames.at(i);
propertyName.replace(2, 1, propertyName.at(2).toUpper());
- s = v4->newString(propertyName);
+ s = v4Engine->newString(propertyName);
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::get_member)));
p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, 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) + QLatin1String("Index");
- s = v4->newString(propertyName);
+ s = v4Engine->newString(propertyName);
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::get_index)));
- p->setSetter(0);
+ p->setSetter(nullptr);
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
- modelItemProto.set(v4, proto);
+ modelItemProto.set(v4Engine, proto);
}
int QQmlDelegateModelItemMetaType::parseGroups(const QStringList &groups) const
@@ -1780,7 +1787,7 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QStringList &groups) const
int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const
{
int groupFlags = 0;
- QV4::Scope scope(QV8Engine::getV4(v8Engine));
+ QV4::Scope scope(v4Engine);
QV4::ScopedString s(scope, groups);
if (s) {
@@ -1806,10 +1813,10 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const
return groupFlags;
}
-QV4::ReturnedValue QQmlDelegateModelItem::get_model(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDelegateModelItem::get_model(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
return b->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
if (!o->d()->item->metaType->model)
@@ -1818,10 +1825,10 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_model(const QV4::BuiltinFunction *
return o->d()->item->get();
}
-QV4::ReturnedValue QQmlDelegateModelItem::get_groups(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDelegateModelItem::get_groups(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
@@ -1834,21 +1841,21 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_groups(const QV4::BuiltinFunction
return scope.engine->fromVariant(groups);
}
-QV4::ReturnedValue QQmlDelegateModelItem::set_groups(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDelegateModelItem::set_groups(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- if (!callData->argc())
+ if (!argc)
THROW_TYPE_ERROR();
if (!o->d()->item->metaType->model)
RETURN_UNDEFINED();
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(o->d()->item->metaType->model);
- const int groupFlags = model->m_cacheMetaType->parseGroups(callData->args[0]);
+ const int groupFlags = model->m_cacheMetaType->parseGroups(argv[0]);
const int cacheIndex = model->m_cache.indexOf(o->d()->item);
Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
model->setGroups(it, 1, Compositor::Cache, groupFlags);
@@ -1900,12 +1907,12 @@ void QV4::Heap::QQmlDelegateModelItemObject::destroy()
QQmlDelegateModelItem::QQmlDelegateModelItem(
QQmlDelegateModelItemMetaType *metaType, int modelIndex)
- : v4(QV8Engine::getV4(metaType->v8Engine))
+ : v4(metaType->v4Engine)
, metaType(metaType)
- , contextData(0)
- , object(0)
- , attached(0)
- , incubationTask(0)
+ , contextData(nullptr)
+ , object(nullptr)
+ , attached(nullptr)
+ , incubationTask(nullptr)
, objectRef(0)
, scriptRef(0)
, groups(0)
@@ -1953,39 +1960,41 @@ void QQmlDelegateModelItem::destroyObject()
Q_ASSERT(data);
if (data->ownContext) {
data->ownContext->clearContext();
- data->ownContext = 0;
- data->context = 0;
+ if (data->ownContext->contextObject == object)
+ data->ownContext->contextObject = nullptr;
+ data->ownContext = nullptr;
+ data->context = nullptr;
}
object->deleteLater();
if (attached) {
- attached->m_cacheItem = 0;
- attached = 0;
+ attached->m_cacheItem = nullptr;
+ attached = nullptr;
}
contextData->invalidate();
- contextData = 0;
- object = 0;
+ contextData = nullptr;
+ object = nullptr;
}
QQmlDelegateModelItem *QQmlDelegateModelItem::dataForObject(QObject *object)
{
QQmlData *d = QQmlData::get(object);
- QQmlContextData *context = d ? d->context : 0;
- for (context = context ? context->parent : 0; context; context = context->parent) {
+ QQmlContextData *context = d ? d->context : nullptr;
+ for (context = context ? context->parent : nullptr; context; context = context->parent) {
if (QQmlDelegateModelItem *cacheItem = qobject_cast<QQmlDelegateModelItem *>(
context->contextObject)) {
return cacheItem;
}
}
- return 0;
+ return nullptr;
}
int QQmlDelegateModelItem::groupIndex(Compositor::Group group)
{
if (QQmlDelegateModelPrivate * const model = metaType->model
? QQmlDelegateModelPrivate::get(metaType->model)
- : 0) {
+ : nullptr) {
return model->m_compositor.find(Compositor::Cache, model->m_cache.indexOf(this)).index[group];
}
return -1;
@@ -2058,7 +2067,7 @@ int QQmlDelegateModelAttachedMetaObject::metaCall(QObject *object, QMetaObject::
}
QQmlDelegateModelAttached::QQmlDelegateModelAttached(QObject *parent)
- : m_cacheItem(0)
+ : m_cacheItem(nullptr)
, m_previousGroups(0)
{
QQml_setParent_noEvent(this, parent);
@@ -2098,7 +2107,7 @@ QQmlDelegateModelAttached::QQmlDelegateModelAttached(
QQmlDelegateModel *QQmlDelegateModelAttached::model() const
{
- return m_cacheItem ? m_cacheItem->metaType->model : 0;
+ return m_cacheItem ? m_cacheItem->metaType->model : nullptr;
}
/*!
@@ -2210,11 +2219,11 @@ void QQmlDelegateModelAttached::emitChanges()
const QMetaObject *meta = metaObject();
for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
if (groupChanges & (1 << i))
- QMetaObject::activate(this, meta, notifierId, 0);
+ QMetaObject::activate(this, meta, notifierId, nullptr);
}
for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
if (indexChanges & (1 << i))
- QMetaObject::activate(this, meta, notifierId, 0);
+ QMetaObject::activate(this, meta, notifierId, nullptr);
}
if (groupChanges)
@@ -2236,13 +2245,13 @@ bool QQmlDelegateModelGroupPrivate::isChangedConnected()
IS_SIGNAL_CONNECTED(q, QQmlDelegateModelGroup, changed, (const QQmlV4Handle &,const QQmlV4Handle &));
}
-void QQmlDelegateModelGroupPrivate::emitChanges(QV8Engine *engine)
+void QQmlDelegateModelGroupPrivate::emitChanges(QV4::ExecutionEngine *v4)
{
Q_Q(QQmlDelegateModelGroup);
if (isChangedConnected() && !changeSet.isEmpty()) {
- QV4::Scope scope(QV8Engine::getV4(engine));
- QV4::ScopedValue removed(scope, engineData(scope.engine)->array(engine, changeSet.removes()));
- QV4::ScopedValue inserted(scope, engineData(scope.engine)->array(engine, changeSet.inserts()));
+ QV4::Scope scope(v4);
+ QV4::ScopedValue removed(scope, engineData(scope.engine)->array(v4, changeSet.removes()));
+ QV4::ScopedValue inserted(scope, engineData(scope.engine)->array(v4, changeSet.inserts()));
emit q->changed(QQmlV4Handle(removed), QQmlV4Handle(inserted));
}
if (changeSet.difference() != 0)
@@ -2471,8 +2480,7 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index)
if (model->m_cacheMetaType->modelItemProto.isUndefined())
model->m_cacheMetaType->initializePrototype();
- QV8Engine *v8 = model->m_cacheMetaType->v8Engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8);
+ QV4::ExecutionEngine *v4 = model->m_cacheMetaType->v4Engine;
QV4::Scope scope(v4);
QV4::ScopedObject o(scope, v4->memoryManager->allocObject<QQmlDelegateModelItemObject>(cacheItem));
QV4::ScopedObject p(scope, model->m_cacheMetaType->modelItemProto.value());
@@ -2500,7 +2508,7 @@ bool QQmlDelegateModelGroupPrivate::parseIndex(const QV4::Value &value, int *ind
QQmlDelegateModelItem * const cacheItem = object->d()->item;
if (QQmlDelegateModelPrivate *model = cacheItem->metaType->model
? QQmlDelegateModelPrivate::get(cacheItem->metaType->model)
- : 0) {
+ : nullptr) {
*index = model->m_cache.indexOf(cacheItem);
*group = Compositor::Cache;
return true;
@@ -2631,7 +2639,7 @@ void QQmlDelegateModelGroup::create(QQmlV4Function *args)
return;
}
- QObject *object = model->object(group, index, false);
+ QObject *object = model->object(group, index, QQmlIncubator::AsynchronousIfNested);
if (object) {
QVector<Compositor::Insert> inserts;
Compositor::iterator it = model->m_compositor.find(group, index);
@@ -3119,21 +3127,21 @@ bool QQmlPartsModel::isValid() const
return m_model->isValid();
}
-QObject *QQmlPartsModel::object(int index, bool asynchronous)
+QObject *QQmlPartsModel::object(int index, QQmlIncubator::IncubationMode incubationMode)
{
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
if (!model->m_delegate || index < 0 || index >= model->m_compositor.count(m_compositorGroup)) {
qWarning() << "DelegateModel::item: index out range" << index << model->m_compositor.count(m_compositorGroup);
- return 0;
+ return nullptr;
}
- QObject *object = model->object(m_compositorGroup, index, asynchronous);
+ QObject *object = model->object(m_compositorGroup, index, incubationMode);
if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object)) {
QObject *part = package->part(m_part);
if (!part)
- return 0;
+ return nullptr;
m_packaged.insertMulti(part, package);
return part;
}
@@ -3145,12 +3153,12 @@ QObject *QQmlPartsModel::object(int index, bool asynchronous)
model->m_delegateValidated = true;
}
- return 0;
+ return nullptr;
}
QQmlInstanceModel::ReleaseFlags QQmlPartsModel::release(QObject *item)
{
- QQmlInstanceModel::ReleaseFlags flags = 0;
+ QQmlInstanceModel::ReleaseFlags flags = nullptr;
QHash<QObject *, QQuickPackage *>::iterator it = m_packaged.find(item);
if (it != m_packaged.end()) {
@@ -3178,6 +3186,16 @@ void QQmlPartsModel::setWatchedRoles(const QList<QByteArray> &roles)
m_watchedRoles = roles;
}
+QQmlIncubator::Status QQmlPartsModel::incubationStatus(int index)
+{
+ QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model);
+ Compositor::iterator it = model->m_compositor.find(model->m_compositorGroup, index);
+ if (!it->inCache())
+ return QQmlIncubator::Null;
+
+ return model->m_cache.at(it.cacheIndex)->incubationTask->status();
+}
+
int QQmlPartsModel::indexOf(QObject *item, QObject *) const
{
QHash<QObject *, QQuickPackage *>::const_iterator it = m_packaged.find(item);
@@ -3222,23 +3240,23 @@ struct QQmlDelegateModelGroupChange : QV4::Object
return e->memoryManager->allocObject<QQmlDelegateModelGroupChange>();
}
- static QV4::ReturnedValue method_get_index(const QV4::BuiltinFunction *b, QV4::CallData *callData) {
+ static QV4::ReturnedValue method_get_index(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, thisObject->as<QQmlDelegateModelGroupChange>());
if (!that)
THROW_TYPE_ERROR();
return QV4::Encode(that->d()->change.index);
}
- static QV4::ReturnedValue method_get_count(const QV4::BuiltinFunction *b, QV4::CallData *callData) {
+ static QV4::ReturnedValue method_get_count(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, thisObject->as<QQmlDelegateModelGroupChange>());
if (!that)
THROW_TYPE_ERROR();
return QV4::Encode(that->d()->change.count);
}
- static QV4::ReturnedValue method_get_moveId(const QV4::BuiltinFunction *b, QV4::CallData *callData) {
+ static QV4::ReturnedValue method_get_moveId(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, thisObject->as<QQmlDelegateModelGroupChange>());
if (!that)
THROW_TYPE_ERROR();
if (that->d()->change.moveId < 0)
@@ -3318,9 +3336,9 @@ QQmlDelegateModelEngineData::QQmlDelegateModelEngineData(QV4::ExecutionEngine *v
QV4::Scope scope(v4);
QV4::ScopedObject proto(scope, v4->newObject());
- proto->defineAccessorProperty(QStringLiteral("index"), QQmlDelegateModelGroupChange::method_get_index, 0);
- proto->defineAccessorProperty(QStringLiteral("count"), QQmlDelegateModelGroupChange::method_get_count, 0);
- proto->defineAccessorProperty(QStringLiteral("moveId"), QQmlDelegateModelGroupChange::method_get_moveId, 0);
+ proto->defineAccessorProperty(QStringLiteral("index"), QQmlDelegateModelGroupChange::method_get_index, nullptr);
+ proto->defineAccessorProperty(QStringLiteral("count"), QQmlDelegateModelGroupChange::method_get_count, nullptr);
+ proto->defineAccessorProperty(QStringLiteral("moveId"), QQmlDelegateModelGroupChange::method_get_moveId, nullptr);
changeProto.set(v4, proto);
}
@@ -3328,9 +3346,9 @@ QQmlDelegateModelEngineData::~QQmlDelegateModelEngineData()
{
}
-QV4::ReturnedValue QQmlDelegateModelEngineData::array(QV8Engine *engine, const QVector<QQmlChangeSet::Change> &changes)
+QV4::ReturnedValue QQmlDelegateModelEngineData::array(QV4::ExecutionEngine *v4,
+ const QVector<QQmlChangeSet::Change> &changes)
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
QV4::ScopedObject o(scope, QQmlDelegateModelGroupChangeArray::create(v4, changes));
return o.asReturnedValue();
diff --git a/src/qml/types/qqmldelegatemodel_p.h b/src/qml/types/qqmldelegatemodel_p.h
index 186144d107..b894df8f82 100644
--- a/src/qml/types/qqmldelegatemodel_p.h
+++ b/src/qml/types/qqmldelegatemodel_p.h
@@ -54,6 +54,7 @@
#include <private/qtqmlglobal_p.h>
#include <private/qqmllistcompositor_p.h>
#include <private/qqmlobjectmodel_p.h>
+#include <private/qqmlincubator_p.h>
#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qstringlist.h>
@@ -89,7 +90,7 @@ class Q_QML_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, public
Q_INTERFACES(QQmlParserStatus)
public:
QQmlDelegateModel();
- QQmlDelegateModel(QQmlContext *, QObject *parent=0);
+ QQmlDelegateModel(QQmlContext *, QObject *parent=nullptr);
~QQmlDelegateModel();
void classBegin() override;
@@ -108,12 +109,13 @@ public:
Q_INVOKABLE QVariant parentModelIndex() const;
int count() const override;
- bool isValid() const override { return delegate() != 0; }
- QObject *object(int index, bool asynchronous = false) override;
+ bool isValid() const override { return delegate() != nullptr; }
+ QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
ReleaseFlags release(QObject *object) override;
void cancel(int index) override;
QString stringValue(int index, const QString &role) override;
void setWatchedRoles(const QList<QByteArray> &roles) override;
+ QQmlIncubator::Status incubationStatus(int index) override;
int indexOf(QObject *object, QObject *objectContext) const override;
@@ -162,8 +164,8 @@ class Q_QML_PRIVATE_EXPORT QQmlDelegateModelGroup : public QObject
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged)
public:
- QQmlDelegateModelGroup(QObject *parent = 0);
- QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = 0);
+ QQmlDelegateModelGroup(QObject *parent = nullptr);
+ QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = nullptr);
~QQmlDelegateModelGroup();
QString name() const;
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index e0416e93ee..68b987a5fa 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -69,7 +69,7 @@ class QQmlDelegateModelAttachedMetaObject;
class QQmlDelegateModelItemMetaType : public QQmlRefCount
{
public:
- QQmlDelegateModelItemMetaType(QV8Engine *engine, QQmlDelegateModel *model, const QStringList &groupNames);
+ QQmlDelegateModelItemMetaType(QV4::ExecutionEngine *engine, QQmlDelegateModel *model, const QStringList &groupNames);
~QQmlDelegateModelItemMetaType();
void initializeMetaObject();
@@ -80,7 +80,7 @@ public:
QPointer<QQmlDelegateModel> model;
const int groupCount;
- QV8Engine * const v8Engine;
+ QV4::ExecutionEngine * const v4Engine;
QQmlDelegateModelAttachedMetaObject *metaObject;
const QStringList groupNames;
QV4::PersistentValue modelItemProto;
@@ -126,9 +126,9 @@ public:
virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; }
- static QV4::ReturnedValue get_model(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue get_groups(const QV4::BuiltinFunction *, QV4::CallData *callData);
- static QV4::ReturnedValue set_groups(const QV4::BuiltinFunction *, QV4::CallData *callData);
+ static QV4::ReturnedValue get_model(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue get_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue set_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &);
static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
@@ -182,7 +182,7 @@ class QQDMIncubationTask : public QQmlIncubator
public:
QQDMIncubationTask(QQmlDelegateModelPrivate *l, IncubationMode mode)
: QQmlIncubator(mode)
- , incubating(0)
+ , incubating(nullptr)
, vdm(l) {}
void statusChanged(Status) override;
@@ -220,7 +220,7 @@ public:
void setModel(QQmlDelegateModel *model, Compositor::Group group);
bool isChangedConnected();
- void emitChanges(QV8Engine *engine);
+ void emitChanges(QV4::ExecutionEngine *engine);
void emitModelUpdated(bool reset);
void createdPackage(int index, QQuickPackage *package);
@@ -256,7 +256,7 @@ public:
void connectModel(QQmlAdaptorModel *model);
void requestMoreIfNecessary();
- QObject *object(Compositor::Group group, int index, bool asynchronous);
+ QObject *object(Compositor::Group group, int index, QQmlIncubator::IncubationMode incubationMode);
QQmlDelegateModel::ReleaseFlags release(QObject *object);
QString stringValue(Compositor::Group group, int index, const QString &name);
void emitCreatedPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
@@ -278,12 +278,12 @@ public:
void itemsInserted(
const QVector<Compositor::Insert> &inserts,
QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedInserts,
- QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = 0);
+ QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = nullptr);
void itemsInserted(const QVector<Compositor::Insert> &inserts);
void itemsRemoved(
const QVector<Compositor::Remove> &removes,
QVarLengthArray<QVector<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedRemoves,
- QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = 0);
+ QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = nullptr);
void itemsRemoved(const QVector<Compositor::Remove> &removes);
void itemsMoved(
const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts);
@@ -341,7 +341,7 @@ class QQmlPartsModel : public QQmlInstanceModel, public QQmlDelegateModelGroupEm
Q_OBJECT
Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
public:
- QQmlPartsModel(QQmlDelegateModel *model, const QString &part, QObject *parent = 0);
+ QQmlPartsModel(QQmlDelegateModel *model, const QString &part, QObject *parent = nullptr);
~QQmlPartsModel();
QString filterGroup() const;
@@ -352,11 +352,12 @@ public:
int count() const override;
bool isValid() const override;
- QObject *object(int index, bool asynchronous = false) override;
+ QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
ReleaseFlags release(QObject *item) override;
QString stringValue(int index, const QString &role) override;
QList<QByteArray> watchedRoles() const { return m_watchedRoles; }
void setWatchedRoles(const QList<QByteArray> &roles) override;
+ QQmlIncubator::Status incubationStatus(int index) override;
int indexOf(QObject *item, QObject *objectContext) const override;
diff --git a/src/qml/types/qqmlinstantiator.cpp b/src/qml/types/qqmlinstantiator.cpp
index 2de5875deb..213bef7879 100644
--- a/src/qml/types/qqmlinstantiator.cpp
+++ b/src/qml/types/qqmlinstantiator.cpp
@@ -56,8 +56,8 @@ QQmlInstantiatorPrivate::QQmlInstantiatorPrivate()
, ownModel(false)
, requestedIndex(-1)
, model(QVariant(1))
- , instanceModel(0)
- , delegate(0)
+ , instanceModel(nullptr)
+ , delegate(nullptr)
{
}
@@ -85,7 +85,7 @@ void QQmlInstantiatorPrivate::clear()
QObject *QQmlInstantiatorPrivate::modelObject(int index, bool async)
{
requestedIndex = index;
- QObject *o = instanceModel->object(index, async);
+ QObject *o = instanceModel->object(index, async ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
requestedIndex = -1;
return o;
}
@@ -123,7 +123,7 @@ void QQmlInstantiatorPrivate::_q_createdItem(int idx, QObject* item)
if (objects.contains(item)) //Case when it was created synchronously in regenerate
return;
if (requestedIndex != idx) // Asynchronous creation, reference the object
- (void)instanceModel->object(idx, false);
+ (void)instanceModel->object(idx);
item->setParent(q);
if (objects.size() < idx + 1) {
int modelCount = instanceModel->count();
@@ -183,7 +183,7 @@ void QQmlInstantiatorPrivate::_q_modelUpdated(const QQmlChangeSet &changeSet, bo
objects = objects.mid(0, index) + movedObjects + objects.mid(index);
} else {
if (insert.index <= objects.size())
- objects.insert(insert.index, insert.count, 0);
+ objects.insert(insert.index, insert.count, nullptr);
for (int i = 0; i < insert.count; ++i) {
int modelIndex = index + i;
QObject* obj = modelObject(modelIndex, async);
@@ -396,11 +396,11 @@ void QQmlInstantiator::setModel(const QVariant &v)
QQmlInstanceModel *prevModel = d->instanceModel;
QObject *object = qvariant_cast<QObject*>(v);
- QQmlInstanceModel *vim = 0;
+ QQmlInstanceModel *vim = nullptr;
if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) {
if (d->ownModel) {
delete d->instanceModel;
- prevModel = 0;
+ prevModel = nullptr;
d->ownModel = false;
}
d->instanceModel = vim;
@@ -444,7 +444,7 @@ QObject *QQmlInstantiator::object() const
Q_D(const QQmlInstantiator);
if (d->objects.count())
return d->objects[0];
- return 0;
+ return nullptr;
}
/*!
@@ -457,7 +457,7 @@ QObject *QQmlInstantiator::objectAt(int index) const
Q_D(const QQmlInstantiator);
if (index >= 0 && index < d->objects.count())
return d->objects[index];
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/qml/types/qqmlinstantiator_p.h b/src/qml/types/qqmlinstantiator_p.h
index ee18daa48c..5727c4d1e1 100644
--- a/src/qml/types/qqmlinstantiator_p.h
+++ b/src/qml/types/qqmlinstantiator_p.h
@@ -71,7 +71,7 @@ class Q_AUTOTEST_EXPORT QQmlInstantiator : public QObject, public QQmlParserStat
Q_CLASSINFO("DefaultProperty", "delegate")
public:
- QQmlInstantiator(QObject *parent = 0);
+ QQmlInstantiator(QObject *parent = nullptr);
~QQmlInstantiator();
bool isActive() const;
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index e32e0c75f3..d4fc02cd3e 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -100,7 +100,7 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(const QString &key, Role::Da
if (node) {
const Role &r = *node->value;
if (type != r.type)
- qmlWarning(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
+ qmlWarning(nullptr) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
return r;
}
@@ -113,7 +113,7 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(QV4::String *key, Role::Data
if (node) {
const Role &r = *node->value;
if (type != r.type)
- qmlWarning(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
+ qmlWarning(nullptr) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type));
return r;
}
@@ -134,7 +134,7 @@ const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::R
if (type == Role::List) {
r->subLayout = new ListLayout;
} else {
- r->subLayout = 0;
+ r->subLayout = nullptr;
}
int dataSize = dataSizes[type];
@@ -203,7 +203,7 @@ ListLayout::Role::Role(const Role *other)
if (other->subLayout)
subLayout = new ListLayout(other->subLayout);
else
- subLayout = 0;
+ subLayout = nullptr;
}
ListLayout::Role::~Role()
@@ -236,8 +236,8 @@ const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QV
}
if (type == Role::Invalid) {
- qmlWarning(0) << "Can't create role for unsupported data type";
- return 0;
+ qmlWarning(nullptr) << "Can't create role for unsupported data type";
+ return nullptr;
}
return &getRoleOrCreate(key, type);
@@ -245,7 +245,7 @@ const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QV
const ListLayout::Role *ListLayout::getExistingRole(const QString &key) const
{
- Role *r = 0;
+ Role *r = nullptr;
QStringHash<Role *>::Node *node = roleHash.findNode(key);
if (node)
r = node->value;
@@ -254,7 +254,7 @@ const ListLayout::Role *ListLayout::getExistingRole(const QString &key) const
const ListLayout::Role *ListLayout::getExistingRole(QV4::String *key) const
{
- Role *r = 0;
+ Role *r = nullptr;
QStringHash<Role *>::Node *node = roleHash.findNode(key);
if (node)
r = node->value;
@@ -264,30 +264,35 @@ const ListLayout::Role *ListLayout::getExistingRole(QV4::String *key) const
QObject *ListModel::getOrCreateModelObject(QQmlListModel *model, int elementIndex)
{
ListElement *e = elements[elementIndex];
- if (e->m_objectCache == 0) {
- e->m_objectCache = new QObject;
+ if (e->m_objectCache == nullptr) {
+ void *memory = operator new(sizeof(QObject) + sizeof(QQmlData));
+ void *ddataMemory = ((char *)memory) + sizeof(QObject);
+ e->m_objectCache = new (memory) QObject;
+ QQmlData *ddata = new (ddataMemory) QQmlData;
+ ddata->ownMemory = false;
+ QObjectPrivate::get(e->m_objectCache)->declarativeData = ddata;
(void)new ModelNodeMetaObject(e->m_objectCache, model, elementIndex);
}
return e->m_objectCache;
}
-void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *> *targetModelHash)
+bool ListModel::sync(ListModel *src, ListModel *target)
{
// Sanity check
- target->m_uid = src->m_uid;
- if (targetModelHash)
- targetModelHash->insert(target->m_uid, target);
+
+ bool hasChanges = false;
// Build hash of elements <-> uid for each of the lists
QHash<int, ElementSync> elementHash;
- for (int i=0 ; i < target->elements.count() ; ++i) {
+ for (int i = 0; i < target->elements.count(); ++i) {
ListElement *e = target->elements.at(i);
int uid = e->getUid();
ElementSync sync;
sync.target = e;
+ sync.targetIndex = i;
elementHash.insert(uid, sync);
}
- for (int i=0 ; i < src->elements.count() ; ++i) {
+ for (int i = 0; i < src->elements.count(); ++i) {
ListElement *e = src->elements.at(i);
int uid = e->getUid();
@@ -295,24 +300,39 @@ void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *>
if (it == elementHash.end()) {
ElementSync sync;
sync.src = e;
+ sync.srcIndex = i;
elementHash.insert(uid, sync);
} else {
ElementSync &sync = it.value();
sync.src = e;
+ sync.srcIndex = i;
}
}
+ QQmlListModel *targetModel = target->m_modelCache;
+
// Get list of elements that are in the target but no longer in the source. These get deleted first.
- QHash<int, ElementSync>::iterator it = elementHash.begin();
- QHash<int, ElementSync>::iterator end = elementHash.end();
- while (it != end) {
- const ElementSync &s = it.value();
- if (s.src == 0) {
+ int rowsRemoved = 0;
+ for (int i = 0 ; i < target->elements.count() ; ++i) {
+ ListElement *element = target->elements.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.targetIndex >= 0);
+ // need to update the targetIndex, to keep it correct after removals
+ s.targetIndex -= rowsRemoved;
+ if (s.src == nullptr) {
+ Q_ASSERT(s.targetIndex == i);
+ hasChanges = true;
+ if (targetModel)
+ targetModel->beginRemoveRows(QModelIndex(), i, i);
s.target->destroy(target->m_layout);
target->elements.removeOne(s.target);
delete s.target;
+ if (targetModel)
+ targetModel->endRemoveRows();
+ ++rowsRemoved;
+ --i;
+ continue;
}
- ++it;
}
// Sync the layouts
@@ -320,15 +340,15 @@ void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *>
// Clear the target list, and append in correct order from the source
target->elements.clear();
- for (int i=0 ; i < src->elements.count() ; ++i) {
+ for (int i = 0; i < src->elements.count(); ++i) {
ListElement *srcElement = src->elements.at(i);
- it = elementHash.find(srcElement->getUid());
- const ElementSync &s = it.value();
+ ElementSync &s = elementHash.find(srcElement->getUid()).value();
+ Q_ASSERT(s.srcIndex >= 0);
ListElement *targetElement = s.target;
- if (targetElement == 0) {
+ if (targetElement == nullptr) {
targetElement = new ListElement(srcElement->getUid());
}
- ListElement::sync(srcElement, src->m_layout, targetElement, target->m_layout, targetModelHash);
+ s.changedRoles = ListElement::sync(srcElement, src->m_layout, targetElement, target->m_layout);
target->elements.append(targetElement);
}
@@ -340,13 +360,43 @@ void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *>
if (ModelNodeMetaObject *mo = e->objectCache())
mo->updateValues();
}
+
+ // now emit the change notifications required. This can be safely done, as we're only emitting changes, moves and inserts,
+ // so the model indices can't be out of bounds
+ //
+ // to ensure things are kept in the correct order, emit inserts and moves first. This shouls ensure all persistent
+ // model indices are updated correctly
+ int rowsInserted = 0;
+ for (int i = 0 ; i < target->elements.count() ; ++i) {
+ ListElement *element = target->elements.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.srcIndex >= 0);
+ s.srcIndex += rowsInserted;
+ if (s.srcIndex != s.targetIndex) {
+ if (targetModel) {
+ if (s.targetIndex == -1) {
+ targetModel->beginInsertRows(QModelIndex(), i, i);
+ targetModel->endInsertRows();
+ } else {
+ targetModel->beginMoveRows(QModelIndex(), i, i, QModelIndex(), s.srcIndex);
+ targetModel->endMoveRows();
+ }
+ }
+ hasChanges = true;
+ ++rowsInserted;
+ }
+ if (s.targetIndex != -1 && !s.changedRoles.isEmpty()) {
+ QModelIndex idx = targetModel->createIndex(i, 0);
+ if (targetModel)
+ targetModel->dataChanged(idx, idx, s.changedRoles);
+ hasChanges = true;
+ }
+ }
+ return hasChanges;
}
-ListModel::ListModel(ListLayout *layout, QQmlListModel *modelCache, int uid) : m_layout(layout), m_modelCache(modelCache)
+ListModel::ListModel(ListLayout *layout, QQmlListModel *modelCache) : m_layout(layout), m_modelCache(modelCache)
{
- if (uid == -1)
- uid = uidCounter.fetchAndAddOrdered(1);
- m_uid = uid;
}
void ListModel::destroy()
@@ -354,11 +404,10 @@ void ListModel::destroy()
for (const auto &destroyer : remove(0, elements.count()))
destroyer();
- m_uid = -1;
- m_layout = 0;
+ m_layout = nullptr;
if (m_modelCache && m_modelCache->m_primary == false)
delete m_modelCache;
- m_modelCache = 0;
+ m_modelCache = nullptr;
}
int ListModel::appendElement()
@@ -459,7 +508,7 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles)
roleIndex = e->setDoubleProperty(r, propertyValue->asDouble());
} else if (QV4::ArrayObject *a = propertyValue->as<QV4::ArrayObject>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
- ListModel *subModel = new ListModel(r.subLayout, 0, -1);
+ ListModel *subModel = new ListModel(r.subLayout, nullptr);
int arrayLength = a->getLength();
for (int j=0 ; j < arrayLength ; ++j) {
@@ -540,7 +589,7 @@ void ListModel::set(int elementIndex, QV4::Object *object)
} else if (QV4::ArrayObject *a = propertyValue->as<QV4::ArrayObject>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
if (r.type == ListLayout::Role::List) {
- ListModel *subModel = new ListModel(r.subLayout, 0, -1);
+ ListModel *subModel = new ListModel(r.subLayout, nullptr);
int arrayLength = a->getLength();
for (int j=0 ; j < arrayLength ; ++j) {
@@ -649,7 +698,7 @@ inline char *ListElement::getPropertyMemory(const ListLayout::Role &role)
ListElement *e = this;
int blockIndex = 0;
while (blockIndex < role.blockIndex) {
- if (e->next == 0) {
+ if (e->next == nullptr) {
e->next = new ListElement;
e->next->uid = uid;
}
@@ -664,7 +713,7 @@ inline char *ListElement::getPropertyMemory(const ListLayout::Role &role)
ModelNodeMetaObject *ListElement::objectCache()
{
if (!m_objectCache)
- return 0;
+ return nullptr;
return ModelNodeMetaObject::get(m_objectCache);
}
@@ -672,7 +721,7 @@ QString *ListElement::getStringProperty(const ListLayout::Role &role)
{
char *mem = getPropertyMemory(role);
QString *s = reinterpret_cast<QString *>(mem);
- return s->data_ptr() ? s : 0;
+ return s->data_ptr() ? s : nullptr;
}
QObject *ListElement::getQObjectProperty(const ListLayout::Role &role)
@@ -684,7 +733,7 @@ QObject *ListElement::getQObjectProperty(const ListLayout::Role &role)
QVariantMap *ListElement::getVariantMapProperty(const ListLayout::Role &role)
{
- QVariantMap *map = 0;
+ QVariantMap *map = nullptr;
char *mem = getPropertyMemory(role);
if (isMemoryUsed<QVariantMap>(mem))
@@ -695,7 +744,7 @@ QVariantMap *ListElement::getVariantMapProperty(const ListLayout::Role &role)
QDateTime *ListElement::getDateTimeProperty(const ListLayout::Role &role)
{
- QDateTime *dt = 0;
+ QDateTime *dt = nullptr;
char *mem = getPropertyMemory(role);
if (isMemoryUsed<QDateTime>(mem))
@@ -706,7 +755,7 @@ QDateTime *ListElement::getDateTimeProperty(const ListLayout::Role &role)
QJSValue *ListElement::getFunctionProperty(const ListLayout::Role &role)
{
- QJSValue *f = 0;
+ QJSValue *f = nullptr;
char *mem = getPropertyMemory(role);
if (isMemoryUsed<QJSValue>(mem))
@@ -727,7 +776,7 @@ QPointer<QObject> *ListElement::getGuardProperty(const ListLayout::Role &role)
}
}
- QPointer<QObject> *o = 0;
+ QPointer<QObject> *o = nullptr;
if (existingGuard)
o = reinterpret_cast<QPointer<QObject> *>(mem);
@@ -758,7 +807,7 @@ QVariant ListElement::getProperty(const ListLayout::Role &role, const QQmlListMo
case ListLayout::Role::String:
{
QString *value = reinterpret_cast<QString *>(mem);
- if (value->data_ptr() != 0)
+ if (value->data_ptr() != nullptr)
data = *value;
}
break;
@@ -774,7 +823,7 @@ QVariant ListElement::getProperty(const ListLayout::Role &role, const QQmlListMo
ListModel *model = *value;
if (model) {
- if (model->m_modelCache == 0) {
+ if (model->m_modelCache == nullptr) {
model->m_modelCache = new QQmlListModel(owner, model, eng);
QQmlEngine::setContextForObject(model->m_modelCache, QQmlEngine::contextForObject(owner));
}
@@ -831,7 +880,7 @@ int ListElement::setStringProperty(const ListLayout::Role &role, const QString &
char *mem = getPropertyMemory(role);
QString *c = reinterpret_cast<QString *>(mem);
bool changed;
- if (c->data_ptr() == 0) {
+ if (c->data_ptr() == nullptr) {
new (mem) QString(s);
changed = true;
} else {
@@ -949,7 +998,11 @@ int ListElement::setVariantMapProperty(const ListLayout::Role &role, QVariantMap
char *mem = getPropertyMemory(role);
if (isMemoryUsed<QVariantMap>(mem)) {
QVariantMap *map = reinterpret_cast<QVariantMap *>(mem);
+ if (m && map->isSharedWith(*m))
+ return roleIndex;
map->~QMap();
+ } else if (!m) {
+ return roleIndex;
}
if (m)
new (mem) QVariantMap(*m);
@@ -1061,16 +1114,16 @@ void ListElement::clearProperty(const ListLayout::Role &role)
setBoolProperty(role, false);
break;
case ListLayout::Role::List:
- setListProperty(role, 0);
+ setListProperty(role, nullptr);
break;
case ListLayout::Role::QObject:
- setQObjectProperty(role, 0);
+ setQObjectProperty(role, nullptr);
break;
case ListLayout::Role::DateTime:
setDateTimeProperty(role, QDateTime());
break;
case ListLayout::Role::VariantMap:
- setVariantMapProperty(role, (QVariantMap *)0);
+ setVariantMapProperty(role, (QVariantMap *)nullptr);
break;
case ListLayout::Role::Function:
setFunctionProperty(role, QJSValue());
@@ -1082,17 +1135,17 @@ void ListElement::clearProperty(const ListLayout::Role &role)
ListElement::ListElement()
{
- m_objectCache = 0;
+ m_objectCache = nullptr;
uid = uidCounter.fetchAndAddOrdered(1);
- next = 0;
+ next = nullptr;
memset(data, 0, sizeof(data));
}
ListElement::ListElement(int existingUid)
{
- m_objectCache = 0;
+ m_objectCache = nullptr;
uid = existingUid;
- next = 0;
+ next = nullptr;
memset(data, 0, sizeof(data));
}
@@ -1101,12 +1154,14 @@ ListElement::~ListElement()
delete next;
}
-void ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout, QHash<int, ListModel *> *targetModelHash)
+QVector<int> ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout)
{
+ QVector<int> changedRoles;
for (int i=0 ; i < srcLayout->roleCount() ; ++i) {
const ListLayout::Role &srcRole = srcLayout->getExistingRole(i);
const ListLayout::Role &targetRole = targetLayout->getExistingRole(i);
+ int roleIndex = -1;
switch (srcRole.type) {
case ListLayout::Role::List:
{
@@ -1114,18 +1169,19 @@ void ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *tar
ListModel *targetSubModel = target->getListProperty(targetRole);
if (srcSubModel) {
- if (targetSubModel == 0) {
- targetSubModel = new ListModel(targetRole.subLayout, 0, srcSubModel->getUid());
+ if (targetSubModel == nullptr) {
+ targetSubModel = new ListModel(targetRole.subLayout, nullptr);
target->setListPropertyFast(targetRole, targetSubModel);
}
- ListModel::sync(srcSubModel, targetSubModel, targetModelHash);
+ if (ListModel::sync(srcSubModel, targetSubModel))
+ roleIndex = targetRole.index;
}
}
break;
case ListLayout::Role::QObject:
{
QObject *object = src->getQObjectProperty(srcRole);
- target->setQObjectProperty(targetRole, object);
+ roleIndex = target->setQObjectProperty(targetRole, object);
}
break;
case ListLayout::Role::String:
@@ -1134,21 +1190,24 @@ void ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *tar
case ListLayout::Role::DateTime:
case ListLayout::Role::Function:
{
- QVariant v = src->getProperty(srcRole, 0, 0);
- target->setVariantProperty(targetRole, v);
+ QVariant v = src->getProperty(srcRole, nullptr, nullptr);
+ roleIndex = target->setVariantProperty(targetRole, v);
}
break;
case ListLayout::Role::VariantMap:
{
QVariantMap *map = src->getVariantMapProperty(srcRole);
- target->setVariantMapProperty(targetRole, map);
+ roleIndex = target->setVariantMapProperty(targetRole, map);
}
break;
default:
break;
}
+ if (roleIndex >= 0)
+ changedRoles << roleIndex;
}
+ return changedRoles;
}
void ListElement::destroy(ListLayout *layout)
@@ -1212,7 +1271,7 @@ void ListElement::destroy(ListLayout *layout)
}
if (next)
- next->destroy(0);
+ next->destroy(nullptr);
uid = -1;
}
@@ -1270,7 +1329,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
QV4::Scope scope(a->engine());
QV4::ScopedObject o(scope);
- ListModel *subModel = new ListModel(role.subLayout, 0, -1);
+ ListModel *subModel = new ListModel(role.subLayout, nullptr);
int arrayLength = a->getLength();
for (int j=0 ; j < arrayLength ; ++j) {
o = a->getIndexed(j);
@@ -1278,7 +1337,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
}
roleIndex = setListProperty(role, subModel);
} else {
- qmlWarning(0) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List));
+ qmlWarning(nullptr) << QStringLiteral("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List));
}
} else if (d.isBoolean()) {
roleIndex = setBoolProperty(role, d.booleanValue());
@@ -1420,7 +1479,7 @@ bool ModelObject::put(Managed *m, String *name, const Value &value)
ModelObject *that = static_cast<ModelObject*>(m);
ExecutionEngine *eng = that->engine();
- const int elementIndex = that->d()->m_elementIndex;
+ const int elementIndex = that->d()->elementIndex();
const QString propName = name->toQString();
int roleIndex = that->d()->m_model->m_listModel->setExistingProperty(elementIndex, propName, value, eng);
if (roleIndex != -1)
@@ -1448,7 +1507,7 @@ ReturnedValue ModelObject::get(const Managed *m, String *name, bool *hasProperty
QQmlPropertyCapture::OnlyOnce, false);
}
- const int elementIndex = that->d()->m_elementIndex;
+ const int elementIndex = that->d()->elementIndex();
QVariant value = that->d()->m_model->data(elementIndex, role->index);
return that->engine()->fromVariant(value);
}
@@ -1457,7 +1516,7 @@ void ModelObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, u
{
ModelObject *that = static_cast<ModelObject*>(m);
ExecutionEngine *v4 = that->engine();
- name->setM(0);
+ name->setM(nullptr);
*index = UINT_MAX;
if (it->arrayIndex < uint(that->d()->m_model->m_listModel->roleCount())) {
Scope scope(that->engine());
@@ -1466,7 +1525,7 @@ void ModelObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, u
ScopedString roleName(scope, v4->newString(role.name));
name->setM(roleName->d());
*attributes = QV4::Attr_Data;
- QVariant value = that->d()->m_model->data(that->d()->m_elementIndex, role.index);
+ QVariant value = that->d()->m_model->data(that->d()->elementIndex(), role.index);
p->value = v4->fromVariant(value);
return;
}
@@ -1493,20 +1552,22 @@ DynamicRoleModelNode *DynamicRoleModelNode::create(const QVariantMap &obj, QQmlL
return object;
}
-void DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQmlListModel *> *targetModelHash)
+QVector<int> DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target)
{
- for (int i=0 ; i < src->m_meta->count() ; ++i) {
+ QVector<int> changedRoles;
+ for (int i = 0; i < src->m_meta->count(); ++i) {
const QByteArray &name = src->m_meta->name(i);
QVariant value = src->m_meta->value(i);
QQmlListModel *srcModel = qobject_cast<QQmlListModel *>(value.value<QObject *>());
QQmlListModel *targetModel = qobject_cast<QQmlListModel *>(target->m_meta->value(i).value<QObject *>());
+ bool modelHasChanges = false;
if (srcModel) {
- if (targetModel == 0)
+ if (targetModel == nullptr)
targetModel = QQmlListModel::createWithOwner(target->m_owner);
- QQmlListModel::sync(srcModel, targetModel, targetModelHash);
+ modelHasChanges = QQmlListModel::sync(srcModel, targetModel);
QObject *targetModelObject = targetModel;
value = QVariant::fromValue(targetModelObject);
@@ -1514,8 +1575,10 @@ void DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode
delete targetModel;
}
- target->setValue(name, value);
+ if (target->setValue(name, value) || modelHasChanges)
+ changedRoles << target->m_owner->m_roles.indexOf(QString::fromUtf8(name));
}
+ return changedRoles;
}
void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int> &roles)
@@ -1724,14 +1787,13 @@ QQmlListModel::QQmlListModel(QObject *parent)
{
m_mainThread = true;
m_primary = true;
- m_agent = 0;
- m_uid = uidCounter.fetchAndAddOrdered(1);
+ m_agent = nullptr;
m_dynamicRoles = false;
m_layout = new ListLayout;
- m_listModel = new ListModel(m_layout, this, -1);
+ m_listModel = new ListModel(m_layout, this);
- m_engine = 0;
+ m_engine = nullptr;
}
QQmlListModel::QQmlListModel(const QQmlListModel *owner, ListModel *data, QV4::ExecutionEngine *engine, QObject *parent)
@@ -1743,7 +1805,7 @@ QQmlListModel::QQmlListModel(const QQmlListModel *owner, ListModel *data, QV4::E
Q_ASSERT(owner->m_dynamicRoles == false);
m_dynamicRoles = false;
- m_layout = 0;
+ m_layout = nullptr;
m_listModel = data;
m_engine = engine;
@@ -1758,14 +1820,14 @@ QQmlListModel::QQmlListModel(QQmlListModel *orig, QQmlListModelWorkerAgent *agen
m_dynamicRoles = orig->m_dynamicRoles;
m_layout = new ListLayout(orig->m_layout);
- m_listModel = new ListModel(m_layout, this, orig->m_listModel->getUid());
+ m_listModel = new ListModel(m_layout, this);
if (m_dynamicRoles)
- sync(orig, this, 0);
+ sync(orig, this);
else
- ListModel::sync(orig->m_listModel, m_listModel, 0);
+ ListModel::sync(orig->m_listModel, m_listModel);
- m_engine = 0;
+ m_engine = nullptr;
}
QQmlListModel::~QQmlListModel()
@@ -1782,10 +1844,10 @@ QQmlListModel::~QQmlListModel()
}
}
- m_listModel = 0;
+ m_listModel = nullptr;
delete m_layout;
- m_layout = 0;
+ m_layout = nullptr;
}
QQmlListModel *QQmlListModel::createWithOwner(QQmlListModel *newOwner)
@@ -1807,32 +1869,32 @@ QQmlListModel *QQmlListModel::createWithOwner(QQmlListModel *newOwner)
QV4::ExecutionEngine *QQmlListModel::engine() const
{
- if (m_engine == 0) {
- m_engine = QQmlEnginePrivate::get(qmlEngine(this))->v4engine();
+ if (m_engine == nullptr) {
+ m_engine = qmlEngine(this)->handle();
}
return m_engine;
}
-void QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target, QHash<int, QQmlListModel *> *targetModelHash)
+bool QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target)
{
Q_ASSERT(src->m_dynamicRoles && target->m_dynamicRoles);
- target->m_uid = src->m_uid;
- if (targetModelHash)
- targetModelHash->insert(target->m_uid, target);
+ bool hasChanges = false;
+
target->m_roles = src->m_roles;
// Build hash of elements <-> uid for each of the lists
QHash<int, ElementSync> elementHash;
- for (int i=0 ; i < target->m_modelObjects.count() ; ++i) {
+ for (int i = 0 ; i < target->m_modelObjects.count(); ++i) {
DynamicRoleModelNode *e = target->m_modelObjects.at(i);
int uid = e->getUid();
ElementSync sync;
sync.target = e;
+ sync.targetIndex = i;
elementHash.insert(uid, sync);
}
- for (int i=0 ; i < src->m_modelObjects.count() ; ++i) {
+ for (int i = 0 ; i < src->m_modelObjects.count(); ++i) {
DynamicRoleModelNode *e = src->m_modelObjects.at(i);
int uid = e->getUid();
@@ -1840,118 +1902,102 @@ void QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target, QHash<int, Q
if (it == elementHash.end()) {
ElementSync sync;
sync.src = e;
+ sync.srcIndex = i;
elementHash.insert(uid, sync);
} else {
ElementSync &sync = it.value();
sync.src = e;
+ sync.srcIndex = i;
}
}
// Get list of elements that are in the target but no longer in the source. These get deleted first.
- QHash<int, ElementSync>::iterator it = elementHash.begin();
- QHash<int, ElementSync>::iterator end = elementHash.end();
- while (it != end) {
- const ElementSync &s = it.value();
- if (s.src == 0) {
- int targetIndex = target->m_modelObjects.indexOf(s.target);
- target->m_modelObjects.remove(targetIndex, 1);
+ int rowsRemoved = 0;
+ for (int i = 0 ; i < target->m_modelObjects.count() ; ++i) {
+ DynamicRoleModelNode *element = target->m_modelObjects.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.targetIndex >= 0);
+ // need to update the targetIndex, to keep it correct after removals
+ s.targetIndex -= rowsRemoved;
+ if (s.src == nullptr) {
+ Q_ASSERT(s.targetIndex == i);
+ hasChanges = true;
+ target->beginRemoveRows(QModelIndex(), i, i);
+ target->m_modelObjects.remove(i, 1);
+ target->endRemoveRows();
delete s.target;
+ ++rowsRemoved;
+ --i;
+ continue;
}
- ++it;
}
// Clear the target list, and append in correct order from the source
target->m_modelObjects.clear();
- for (int i=0 ; i < src->m_modelObjects.count() ; ++i) {
- DynamicRoleModelNode *srcElement = src->m_modelObjects.at(i);
- it = elementHash.find(srcElement->getUid());
- const ElementSync &s = it.value();
+ for (int i = 0 ; i < src->m_modelObjects.count() ; ++i) {
+ DynamicRoleModelNode *element = src->m_modelObjects.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.srcIndex >= 0);
DynamicRoleModelNode *targetElement = s.target;
- if (targetElement == 0) {
- targetElement = new DynamicRoleModelNode(target, srcElement->getUid());
+ if (targetElement == nullptr) {
+ targetElement = new DynamicRoleModelNode(target, element->getUid());
}
- DynamicRoleModelNode::sync(srcElement, targetElement, targetModelHash);
+ s.changedRoles = DynamicRoleModelNode::sync(element, targetElement);
target->m_modelObjects.append(targetElement);
}
-}
-void QQmlListModel::emitItemsChanged(int index, int count, const QVector<int> &roles)
-{
- if (count <= 0)
- return;
-
- if (m_mainThread) {
- emit dataChanged(createIndex(index, 0), createIndex(index + count - 1, 0), roles);;
- } else {
- int uid = m_dynamicRoles ? getUid() : m_listModel->getUid();
- m_agent->data.changedChange(uid, index, count, roles);
+ // now emit the change notifications required. This can be safely done, as we're only emitting changes, moves and inserts,
+ // so the model indices can't be out of bounds
+ //
+ // to ensure things are kept in the correct order, emit inserts and moves first. This shouls ensure all persistent
+ // model indices are updated correctly
+ int rowsInserted = 0;
+ for (int i = 0 ; i < target->m_modelObjects.count() ; ++i) {
+ DynamicRoleModelNode *element = target->m_modelObjects.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.srcIndex >= 0);
+ s.srcIndex += rowsInserted;
+ if (s.srcIndex != s.targetIndex) {
+ if (s.targetIndex == -1) {
+ target->beginInsertRows(QModelIndex(), i, i);
+ target->endInsertRows();
+ } else {
+ target->beginMoveRows(QModelIndex(), i, i, QModelIndex(), s.srcIndex);
+ target->endMoveRows();
+ }
+ hasChanges = true;
+ ++rowsInserted;
+ }
+ if (s.targetIndex != -1 && !s.changedRoles.isEmpty()) {
+ QModelIndex idx = target->createIndex(i, 0);
+ emit target->dataChanged(idx, idx, s.changedRoles);
+ hasChanges = true;
+ }
}
+ return hasChanges;
}
-void QQmlListModel::emitItemsAboutToBeRemoved(int index, int count)
-{
- if (count <= 0 || !m_mainThread)
- return;
-
- beginRemoveRows(QModelIndex(), index, index + count - 1);
-}
-
-void QQmlListModel::emitItemsRemoved(int index, int count)
+void QQmlListModel::emitItemsChanged(int index, int count, const QVector<int> &roles)
{
if (count <= 0)
return;
- if (m_mainThread) {
- endRemoveRows();
- emit countChanged();
- } else {
- int uid = m_dynamicRoles ? getUid() : m_listModel->getUid();
- if (index == 0 && count == this->count())
- m_agent->data.clearChange(uid);
- m_agent->data.removeChange(uid, index, count);
- }
+ if (m_mainThread)
+ emit dataChanged(createIndex(index, 0), createIndex(index + count - 1, 0), roles);;
}
void QQmlListModel::emitItemsAboutToBeInserted(int index, int count)
{
- if (count <= 0 || !m_mainThread)
- return;
-
- beginInsertRows(QModelIndex(), index, index + count - 1);
+ Q_ASSERT(index >= 0 && count >= 0);
+ if (m_mainThread)
+ beginInsertRows(QModelIndex(), index, index + count - 1);
}
-void QQmlListModel::emitItemsInserted(int index, int count)
+void QQmlListModel::emitItemsInserted()
{
- if (count <= 0)
- return;
-
if (m_mainThread) {
endInsertRows();
emit countChanged();
- } else {
- int uid = m_dynamicRoles ? getUid() : m_listModel->getUid();
- m_agent->data.insertChange(uid, index, count);
- }
-}
-
-void QQmlListModel::emitItemsAboutToBeMoved(int from, int to, int n)
-{
- if (n <= 0 || !m_mainThread)
- return;
-
- beginMoveRows(QModelIndex(), from, from + n - 1, QModelIndex(), to > from ? to + n : to);
-}
-
-void QQmlListModel::emitItemsMoved(int from, int to, int n)
-{
- if (n <= 0)
- return;
-
- if (m_mainThread) {
- endMoveRows();
- } else {
- int uid = m_dynamicRoles ? getUid() : m_listModel->getUid();
- m_agent->data.moveChange(uid, from, n, to);
}
}
@@ -2065,7 +2111,7 @@ QHash<int, QByteArray> QQmlListModel::roleNames() const
*/
void QQmlListModel::setDynamicRoles(bool enableDynamicRoles)
{
- if (m_mainThread && m_agent == 0) {
+ if (m_mainThread && m_agent == nullptr) {
if (enableDynamicRoles) {
if (m_layout->roleCount())
qmlWarning(this) << tr("unable to enable dynamic roles as this model is not empty");
@@ -2133,7 +2179,13 @@ void QQmlListModel::remove(QQmlV4Function *args)
void QQmlListModel::removeElements(int index, int removeCount)
{
- emitItemsAboutToBeRemoved(index, removeCount);
+ Q_ASSERT(index >= 0 && removeCount >= 0);
+
+ if (!removeCount)
+ return;
+
+ if (m_mainThread)
+ beginRemoveRows(QModelIndex(), index, index + removeCount - 1);
QVector<std::function<void()>> toDestroy;
if (m_dynamicRoles) {
@@ -2148,7 +2200,10 @@ void QQmlListModel::removeElements(int index, int removeCount)
toDestroy = m_listModel->remove(index, removeCount);
}
- emitItemsRemoved(index, removeCount);
+ if (m_mainThread) {
+ endRemoveRows();
+ emit countChanged();
+ }
for (const auto &destroyer : toDestroy)
destroyer();
}
@@ -2197,7 +2252,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
m_listModel->insert(index+i, argObject);
}
}
- emitItemsInserted(index, objectArrayLength);
+ emitItemsInserted();
} else if (argObject) {
emitItemsAboutToBeInserted(index, 1);
@@ -2207,7 +2262,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
m_listModel->insert(index, argObject);
}
- emitItemsInserted(index, 1);
+ emitItemsInserted();
} else {
qmlWarning(this) << tr("insert: value is not an object");
}
@@ -2232,14 +2287,15 @@ void QQmlListModel::insert(QQmlV4Function *args)
*/
void QQmlListModel::move(int from, int to, int n)
{
- if (n==0 || from==to)
+ if (n == 0 || from == to)
return;
if (!canMove(from, to, n)) {
qmlWarning(this) << tr("move: out of range");
return;
}
- emitItemsAboutToBeMoved(from, to, n);
+ if (m_mainThread)
+ beginMoveRows(QModelIndex(), from, from + n - 1, QModelIndex(), to > from ? to + n : to);
if (m_dynamicRoles) {
@@ -2268,7 +2324,8 @@ void QQmlListModel::move(int from, int to, int n)
m_listModel->move(from, to, n);
}
- emitItemsMoved(from, to, n);
+ if (m_mainThread)
+ endMoveRows();
}
/*!
@@ -2308,7 +2365,7 @@ void QQmlListModel::append(QQmlV4Function *args)
}
}
- emitItemsInserted(index, objectArrayLength);
+ emitItemsInserted();
} else if (argObject) {
int index;
@@ -2322,7 +2379,7 @@ void QQmlListModel::append(QQmlV4Function *args)
m_listModel->append(argObject);
}
- emitItemsInserted(index, 1);
+ emitItemsInserted();
} else {
qmlWarning(this) << tr("append: value is not an object");
}
@@ -2374,10 +2431,14 @@ QQmlV4Handle QQmlListModel::get(int index) const
result = QV4::QObjectWrapper::wrap(scope.engine, object);
} else {
QObject *object = m_listModel->getOrCreateModelObject(const_cast<QQmlListModel *>(this), index);
- result = scope.engine->memoryManager->allocObject<QV4::ModelObject>(object, const_cast<QQmlListModel *>(this), index);
- // Keep track of the QObjectWrapper in persistent value storage
- QV4::Value *val = scope.engine->memoryManager->m_weakValues->allocate();
- *val = result;
+ QQmlData *ddata = QQmlData::get(object);
+ if (ddata->jsWrapper.isNullOrUndefined()) {
+ result = scope.engine->memoryManager->allocObject<QV4::ModelObject>(object, const_cast<QQmlListModel *>(this));
+ // Keep track of the QObjectWrapper in persistent value storage
+ ddata->jsWrapper.set(scope.engine, result);
+ } else {
+ result = ddata->jsWrapper.value();
+ }
}
}
@@ -2424,7 +2485,7 @@ void QQmlListModel::set(int index, const QQmlV4Handle &handle)
m_listModel->insert(index, object);
}
- emitItemsInserted(index, 1);
+ emitItemsInserted();
} else {
QVector<int> roles;
@@ -2544,15 +2605,15 @@ bool QQmlListModelParser::applyProperty(QV4::CompiledData::CompilationUnit *comp
const quint32 targetObjectIndex = binding->value.objectIndex;
const QV4::CompiledData::Object *target = qmlUnit->objectAt(targetObjectIndex);
- ListModel *subModel = 0;
+ ListModel *subModel = nullptr;
if (outterElementIndex == -1) {
subModel = model;
} else {
const ListLayout::Role &role = model->getOrCreateListRole(elementName);
if (role.type == ListLayout::Role::List) {
subModel = model->getListProperty(outterElementIndex, role);
- if (subModel == 0) {
- subModel = new ListModel(role.subLayout, 0, -1);
+ if (subModel == nullptr) {
+ subModel = new ListModel(role.subLayout, nullptr);
QVariant vModel = QVariant::fromValue(subModel);
model->setOrCreateProperty(outterElementIndex, elementName, vModel);
}
@@ -2579,7 +2640,7 @@ bool QQmlListModelParser::applyProperty(QV4::CompiledData::CompilationUnit *comp
QString scriptStr = binding->valueAsScriptString(qmlUnit);
if (definesEmptyList(scriptStr)) {
const ListLayout::Role &role = model->getOrCreateListRole(elementName);
- ListModel *emptyModel = new ListModel(role.subLayout, 0, -1);
+ ListModel *emptyModel = new ListModel(role.subLayout, nullptr);
value = QVariant::fromValue(emptyModel);
} else if (binding->isFunctionExpression()) {
QQmlBinding::Identifier id = binding->value.compiledScriptIndex;
@@ -2630,7 +2691,7 @@ void QQmlListModelParser::applyBindings(QObject *obj, QV4::CompiledData::Compila
{
QQmlListModel *rv = static_cast<QQmlListModel *>(obj);
- rv->m_engine = QV8Engine::getV4(qmlEngine(rv));
+ rv->m_engine = qmlEngine(rv)->handle();
const QV4::CompiledData::Unit *qmlUnit = compilationUnit->data;
diff --git a/src/qml/types/qqmllistmodel_p.h b/src/qml/types/qqmllistmodel_p.h
index 499a113504..0c0859dc80 100644
--- a/src/qml/types/qqmllistmodel_p.h
+++ b/src/qml/types/qqmllistmodel_p.h
@@ -82,7 +82,7 @@ class Q_QML_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel
Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles)
public:
- QQmlListModel(QObject *parent=0);
+ QQmlListModel(QObject *parent=nullptr);
~QQmlListModel();
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
@@ -125,7 +125,7 @@ private:
// Constructs a flat list model for a worker agent
QQmlListModel(QQmlListModel *orig, QQmlListModelWorkerAgent *agent);
- QQmlListModel(const QQmlListModel *owner, ListModel *data, QV4::ExecutionEngine *engine, QObject *parent=0);
+ QQmlListModel(const QQmlListModel *owner, ListModel *data, QV4::ExecutionEngine *engine, QObject *parent=nullptr);
QV4::ExecutionEngine *engine() const;
@@ -143,28 +143,22 @@ private:
QVector<class DynamicRoleModelNode *> m_modelObjects;
QVector<QString> m_roles;
- int m_uid;
struct ElementSync
{
- ElementSync() : src(0), target(0) {}
-
- DynamicRoleModelNode *src;
- DynamicRoleModelNode *target;
+ DynamicRoleModelNode *src = nullptr;
+ DynamicRoleModelNode *target = nullptr;
+ int srcIndex = -1;
+ int targetIndex = -1;
+ QVector<int> changedRoles;
};
- int getUid() const { return m_uid; }
-
- static void sync(QQmlListModel *src, QQmlListModel *target, QHash<int, QQmlListModel *> *targetModelHash);
+ static bool sync(QQmlListModel *src, QQmlListModel *target);
static QQmlListModel *createWithOwner(QQmlListModel *newOwner);
void emitItemsChanged(int index, int count, const QVector<int> &roles);
- void emitItemsAboutToBeRemoved(int index, int count);
- void emitItemsRemoved(int index, int count);
void emitItemsAboutToBeInserted(int index, int count);
- void emitItemsInserted(int index, int count);
- void emitItemsAboutToBeMoved(int from, int to, int n);
- void emitItemsMoved(int from, int to, int n);
+ void emitItemsInserted();
void removeElements(int index, int removeCount);
};
diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h
index dea1ef2eb3..ad5e94c909 100644
--- a/src/qml/types/qqmllistmodel_p_p.h
+++ b/src/qml/types/qqmllistmodel_p_p.h
@@ -108,7 +108,7 @@ public:
return m_uid;
}
- static void sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQmlListModel *> *targetModelHash);
+ static QVector<int> sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target);
private:
QQmlListModel *m_owner;
@@ -164,15 +164,17 @@ namespace QV4 {
namespace Heap {
struct ModelObject : public QObjectWrapper {
- void init(QObject *object, QQmlListModel *model, int elementIndex)
+ void init(QObject *object, QQmlListModel *model)
{
QObjectWrapper::init(object);
m_model = model;
- m_elementIndex = elementIndex;
+ QObjectPrivate *op = QObjectPrivate::get(object);
+ m_nodeModelMetaObject = static_cast<ModelNodeMetaObject *>(op->metaObject);
}
void destroy() { QObjectWrapper::destroy(); }
+ int elementIndex() const { return m_nodeModelMetaObject->m_elementIndex; }
QQmlListModel *m_model;
- int m_elementIndex;
+ ModelNodeMetaObject *m_nodeModelMetaObject;
};
}
@@ -261,7 +263,7 @@ public:
ListElement(int existingUid);
~ListElement();
- static void sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout, QHash<int, ListModel *> *targetModelHash);
+ static QVector<int> sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout);
enum
{
@@ -328,7 +330,7 @@ class ListModel
{
public:
- ListModel(ListLayout *layout, QQmlListModel *modelCache, int uid);
+ ListModel(ListLayout *layout, QQmlListModel *modelCache);
~ListModel() {}
void destroy();
@@ -377,25 +379,23 @@ public:
void move(int from, int to, int n);
- int getUid() const { return m_uid; }
-
- static void sync(ListModel *src, ListModel *target, QHash<int, ListModel *> *srcModelHash);
+ static bool sync(ListModel *src, ListModel *target);
QObject *getOrCreateModelObject(QQmlListModel *model, int elementIndex);
private:
QPODVector<ListElement *, 4> elements;
ListLayout *m_layout;
- int m_uid;
QQmlListModel *m_modelCache;
struct ElementSync
{
- ElementSync() : src(0), target(0) {}
-
- ListElement *src;
- ListElement *target;
+ ListElement *src = nullptr;
+ ListElement *target = nullptr;
+ int srcIndex = -1;
+ int targetIndex = -1;
+ QVector<int> changedRoles;
};
void newElement(int index);
diff --git a/src/qml/types/qqmllistmodelworkeragent.cpp b/src/qml/types/qqmllistmodelworkeragent.cpp
index 0a5adbf292..fe3eaa3198 100644
--- a/src/qml/types/qqmllistmodelworkeragent.cpp
+++ b/src/qml/types/qqmllistmodelworkeragent.cpp
@@ -50,39 +50,8 @@
QT_BEGIN_NAMESPACE
-
-void QQmlListModelWorkerAgent::Data::clearChange(int uid)
-{
- for (int i=0 ; i < changes.count() ; ++i) {
- if (changes[i].modelUid == uid) {
- changes.removeAt(i);
- --i;
- }
- }
-}
-
-void QQmlListModelWorkerAgent::Data::insertChange(int uid, int index, int count)
+QQmlListModelWorkerAgent::Sync::~Sync()
{
- Change c = { uid, Change::Inserted, index, count, 0, QVector<int>() };
- changes << c;
-}
-
-void QQmlListModelWorkerAgent::Data::removeChange(int uid, int index, int count)
-{
- Change c = { uid, Change::Removed, index, count, 0, QVector<int>() };
- changes << c;
-}
-
-void QQmlListModelWorkerAgent::Data::moveChange(int uid, int index, int count, int to)
-{
- Change c = { uid, Change::Moved, index, count, to, QVector<int>() };
- changes << c;
-}
-
-void QQmlListModelWorkerAgent::Data::changedChange(int uid, int index, int count, const QVector<int> &roles)
-{
- Change c = { uid, Change::Changed, index, count, 0, roles };
- changes << c;
}
QQmlListModelWorkerAgent::QQmlListModelWorkerAgent(QQmlListModel *model)
@@ -117,7 +86,7 @@ void QQmlListModelWorkerAgent::release()
void QQmlListModelWorkerAgent::modelDestroyed()
{
- m_orig = 0;
+ m_orig = nullptr;
}
int QQmlListModelWorkerAgent::count() const
@@ -167,8 +136,7 @@ void QQmlListModelWorkerAgent::move(int from, int to, int count)
void QQmlListModelWorkerAgent::sync()
{
- Sync *s = new Sync(data, m_copy);
- data.changes.clear();
+ Sync *s = new Sync(m_copy);
mutex.lock();
QCoreApplication::postEvent(this, s);
@@ -183,61 +151,14 @@ bool QQmlListModelWorkerAgent::event(QEvent *e)
QMutexLocker locker(&mutex);
if (m_orig) {
Sync *s = static_cast<Sync *>(e);
- const QList<Change> &changes = s->data.changes;
- cc = m_orig->count() != s->list->count();
-
- QHash<int, QQmlListModel *> targetModelDynamicHash;
- QHash<int, ListModel *> targetModelStaticHash;
+ cc = (m_orig->count() != s->list->count());
Q_ASSERT(m_orig->m_dynamicRoles == s->list->m_dynamicRoles);
if (m_orig->m_dynamicRoles)
- QQmlListModel::sync(s->list, m_orig, &targetModelDynamicHash);
+ QQmlListModel::sync(s->list, m_orig);
else
- ListModel::sync(s->list->m_listModel, m_orig->m_listModel, &targetModelStaticHash);
-
- for (int ii = 0; ii < changes.count(); ++ii) {
- const Change &change = changes.at(ii);
-
- QQmlListModel *model = 0;
- if (m_orig->m_dynamicRoles) {
- model = targetModelDynamicHash.value(change.modelUid);
- } else {
- ListModel *lm = targetModelStaticHash.value(change.modelUid);
- if (lm)
- model = lm->m_modelCache;
- }
-
- if (model) {
- switch (change.type) {
- case Change::Inserted:
- model->beginInsertRows(
- QModelIndex(), change.index, change.index + change.count - 1);
- model->endInsertRows();
- break;
- case Change::Removed:
- model->beginRemoveRows(
- QModelIndex(), change.index, change.index + change.count - 1);
- model->endRemoveRows();
- break;
- case Change::Moved:
- model->beginMoveRows(
- QModelIndex(),
- change.index,
- change.index + change.count - 1,
- QModelIndex(),
- change.to > change.index ? change.to + change.count : change.to);
- model->endMoveRows();
- break;
- case Change::Changed:
- emit model->dataChanged(
- model->createIndex(change.index, 0),
- model->createIndex(change.index + change.count - 1, 0),
- change.roles);
- break;
- }
- }
- }
+ ListModel::sync(s->list->m_listModel, m_orig->m_listModel);
}
syncDone.wakeAll();
diff --git a/src/qml/types/qqmllistmodelworkeragent_p.h b/src/qml/types/qqmllistmodelworkeragent_p.h
index 5a39651bf7..2120f25744 100644
--- a/src/qml/types/qqmllistmodelworkeragent_p.h
+++ b/src/qml/types/qqmllistmodelworkeragent_p.h
@@ -91,7 +91,7 @@ public:
struct VariantRef
{
- VariantRef() : a(0) {}
+ VariantRef() : a(nullptr) {}
VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); }
VariantRef(QQmlListModelWorkerAgent *_a) : a(_a) { if (a) a->addref(); }
~VariantRef() { if (a) a->release(); }
@@ -114,35 +114,12 @@ private:
friend class QQuickWorkerScriptEnginePrivate;
friend class QQmlListModel;
- struct Change
- {
- int modelUid;
- enum { Inserted, Removed, Moved, Changed } type;
- int index; // Inserted/Removed/Moved/Changed
- int count; // Inserted/Removed/Moved/Changed
- int to; // Moved
- QVector<int> roles;
- };
-
- struct Data
- {
- QList<Change> changes;
-
- void clearChange(int uid);
- void insertChange(int uid, int index, int count);
- void removeChange(int uid, int index, int count);
- void moveChange(int uid, int index, int count, int to);
- void changedChange(int uid, int index, int count, const QVector<int> &roles);
- };
- Data data;
-
struct Sync : public QEvent {
- Sync(const Data &d, QQmlListModel *l)
+ Sync(QQmlListModel *l)
: QEvent(QEvent::User)
- , data(d)
, list(l)
{}
- Data data;
+ ~Sync();
QQmlListModel *list;
};
diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp
index dcd0360199..08740b4a6f 100644
--- a/src/qml/types/qqmlobjectmodel.cpp
+++ b/src/qml/types/qqmlobjectmodel.cpp
@@ -267,7 +267,7 @@ bool QQmlObjectModel::isValid() const
return true;
}
-QObject *QQmlObjectModel::object(int index, bool)
+QObject *QQmlObjectModel::object(int index, QQmlIncubator::IncubationMode)
{
Q_D(QQmlObjectModel);
QQmlObjectModelPrivate::Item &item = d->children[index];
@@ -287,7 +287,7 @@ QQmlInstanceModel::ReleaseFlags QQmlObjectModel::release(QObject *item)
if (!d->children[idx].deref())
return QQmlInstanceModel::Referenced;
}
- return 0;
+ return nullptr;
}
QString QQmlObjectModel::stringValue(int index, const QString &name)
@@ -298,6 +298,11 @@ QString QQmlObjectModel::stringValue(int index, const QString &name)
return QQmlEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString();
}
+QQmlIncubator::Status QQmlObjectModel::incubationStatus(int)
+{
+ return QQmlIncubator::Ready;
+}
+
int QQmlObjectModel::indexOf(QObject *item, QObject *) const
{
Q_D(const QQmlObjectModel);
@@ -332,7 +337,7 @@ QObject *QQmlObjectModel::get(int index) const
{
Q_D(const QQmlObjectModel);
if (index < 0 || index >= d->children.count())
- return 0;
+ return nullptr;
return d->children.at(index).item;
}
diff --git a/src/qml/types/qqmlobjectmodel_p.h b/src/qml/types/qqmlobjectmodel_p.h
index fc4c03874f..267828dcdd 100644
--- a/src/qml/types/qqmlobjectmodel_p.h
+++ b/src/qml/types/qqmlobjectmodel_p.h
@@ -52,6 +52,7 @@
//
#include <private/qtqmlglobal_p.h>
+#include <private/qqmlincubator_p.h>
#include <QtQml/qqml.h>
#include <QtCore/qobject.h>
@@ -74,11 +75,12 @@ public:
virtual int count() const = 0;
virtual bool isValid() const = 0;
- virtual QObject *object(int index, bool asynchronous=false) = 0;
+ virtual QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) = 0;
virtual ReleaseFlags release(QObject *object) = 0;
virtual void cancel(int) {}
virtual QString stringValue(int, const QString &) = 0;
virtual void setWatchedRoles(const QList<QByteArray> &roles) = 0;
+ virtual QQmlIncubator::Status incubationStatus(int index) = 0;
virtual int indexOf(QObject *object, QObject *objectContext) const = 0;
@@ -90,7 +92,7 @@ Q_SIGNALS:
void destroyingItem(QObject *object);
protected:
- QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = 0)
+ QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = nullptr)
: QObject(dd, parent) {}
private:
@@ -108,15 +110,16 @@ class Q_QML_PRIVATE_EXPORT QQmlObjectModel : public QQmlInstanceModel
Q_CLASSINFO("DefaultProperty", "children")
public:
- QQmlObjectModel(QObject *parent=0);
+ QQmlObjectModel(QObject *parent=nullptr);
~QQmlObjectModel() {}
int count() const override;
bool isValid() const override;
- QObject *object(int index, bool asynchronous = false) override;
+ QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
ReleaseFlags release(QObject *object) override;
QString stringValue(int index, const QString &role) override;
void setWatchedRoles(const QList<QByteArray> &) override {}
+ QQmlIncubator::Status incubationStatus(int index) override;
int indexOf(QObject *object, QObject *objectContext) const override;
diff --git a/src/qml/types/qqmltimer.cpp b/src/qml/types/qqmltimer.cpp
index 2037c4f6cd..6554010f36 100644
--- a/src/qml/types/qqmltimer.cpp
+++ b/src/qml/types/qqmltimer.cpp
@@ -57,7 +57,7 @@ class QQmlTimerPrivate : public QObjectPrivate, public QAnimationJobChangeListen
Q_DECLARE_PUBLIC(QQmlTimer)
public:
QQmlTimerPrivate()
- : interval(1000), running(false), repeating(false), triggeredOnStart(false)
+ : running(false), repeating(false), triggeredOnStart(false)
, classBegun(false), componentComplete(false), firstTick(true), awaitingTick(false) {}
void animationFinished(QAbstractAnimationJob *) override;
@@ -71,7 +71,7 @@ public:
}
}
- int interval;
+ int interval = 1000;
QPauseAnimationJob pause;
bool running : 1;
bool repeating : 1;
diff --git a/src/qml/types/qqmltimer_p.h b/src/qml/types/qqmltimer_p.h
index 7739dad2a6..d597869994 100644
--- a/src/qml/types/qqmltimer_p.h
+++ b/src/qml/types/qqmltimer_p.h
@@ -72,7 +72,7 @@ class Q_QML_PRIVATE_EXPORT QQmlTimer : public QObject, public QQmlParserStatus
Q_PROPERTY(QObject *parent READ parent CONSTANT)
public:
- QQmlTimer(QObject *parent=0);
+ QQmlTimer(QObject *parent=nullptr);
void setInterval(int interval);
int interval() const;
diff --git a/src/qml/types/qquickpackage.cpp b/src/qml/types/qquickpackage.cpp
index e0d1888f33..e8e897bab9 100644
--- a/src/qml/types/qquickpackage.cpp
+++ b/src/qml/types/qquickpackage.cpp
@@ -183,7 +183,7 @@ QObject *QQuickPackage::part(const QString &name)
if (name == QLatin1String("default") && !d->dataList.isEmpty())
return d->dataList.at(0);
- return 0;
+ return nullptr;
}
QQuickPackageAttached *QQuickPackage::qmlAttachedProperties(QObject *o)
diff --git a/src/qml/types/qquickpackage_p.h b/src/qml/types/qquickpackage_p.h
index ca383bfdcb..122c7fcb30 100644
--- a/src/qml/types/qquickpackage_p.h
+++ b/src/qml/types/qquickpackage_p.h
@@ -66,7 +66,7 @@ class Q_AUTOTEST_EXPORT QQuickPackage : public QObject
Q_PROPERTY(QQmlListProperty<QObject> data READ data)
public:
- QQuickPackage(QObject *parent=0);
+ QQuickPackage(QObject *parent=nullptr);
virtual ~QQuickPackage();
QQmlListProperty<QObject> data();
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 346f2e6a61..80c2d3a4bc 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -186,7 +186,7 @@ public:
int m_nextId;
- static QV4::ReturnedValue method_sendMessage(const QV4::BuiltinFunction *, QV4::CallData *callData);
+ static QV4::ReturnedValue method_sendMessage(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
signals:
void stopThread();
@@ -201,9 +201,9 @@ private:
};
QQuickWorkerScriptEnginePrivate::WorkerEngine::WorkerEngine(QQuickWorkerScriptEnginePrivate *parent)
-: QV8Engine(0), p(parent)
+ : QV8Engine(nullptr, new QV4::ExecutionEngine), p(parent)
#if QT_CONFIG(qml_network)
-, accessManager(0)
+, accessManager(nullptr)
#endif
{
m_v4Engine->v8Engine = this;
@@ -214,6 +214,7 @@ QQuickWorkerScriptEnginePrivate::WorkerEngine::~WorkerEngine()
#if QT_CONFIG(qml_network)
delete accessManager;
#endif
+ delete m_v4Engine;
}
void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
@@ -246,11 +247,11 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
QV4::ScopedFunctionObject createsendconstructor(scope, createsendscript.run());
Q_ASSERT(!scope.engine->hasException);
QV4::ScopedString name(scope, m_v4Engine->newString(QStringLiteral("sendMessage")));
- QV4::ScopedValue function(scope, QV4::BuiltinFunction::create(globalContext, name,
- QQuickWorkerScriptEnginePrivate::method_sendMessage));
+ QV4::ScopedValue function(scope, QV4::FunctionObject::createBuiltinFunction(globalContext, name,
+ QQuickWorkerScriptEnginePrivate::method_sendMessage));
QV4::JSCallData jsCallData(scope, 1);
jsCallData->args[0] = function;
- *jsCallData->thisObject = global();
+ *jsCallData->thisObject = m_v4Engine->global();
createsend.set(scope.engine, createsendconstructor->call(jsCallData));
}
@@ -267,7 +268,7 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(i
QV4::ScopedValue v(scope);
QV4::JSCallData jsCallData(scope, 1);
jsCallData->args[0] = QV4::Primitive::fromInt32(id);
- *jsCallData->thisObject = global();
+ *jsCallData->thisObject = m_v4Engine->global();
v = f->call(jsCallData);
if (scope.hasException())
v = scope.engine->catchException();
@@ -289,19 +290,19 @@ QNetworkAccessManager *QQuickWorkerScriptEnginePrivate::WorkerEngine::networkAcc
#endif
QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *engine)
-: workerEngine(0), qmlengine(engine), m_nextId(0)
+: workerEngine(nullptr), qmlengine(engine), m_nextId(0)
{
}
-QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::BuiltinFunction *b,
- QV4::CallData *callData)
+QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::FunctionObject *b,
+ const QV4::Value *, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- WorkerEngine *engine = (WorkerEngine*)scope.engine->v8Engine;
+ WorkerEngine *engine = static_cast<WorkerEngine *>(scope.engine->v8Engine);
- int id = callData->argc() > 1 ? callData->args[1].toInt32() : 0;
+ int id = argc > 1 ? argv[1].toInt32() : 0;
- QV4::ScopedValue v(scope, callData->argument(2));
+ QV4::ScopedValue v(scope, argc > 2 ? argv[2] : QV4::Primitive::undefinedValue());
QByteArray data = QV4::Serialize::serialize(v, scope.engine);
QMutexLocker locker(&engine->p->m_lock);
@@ -367,7 +368,7 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d
Q_ASSERT(!!qmlContext);
QV4::JSCallData jsCallData(scope, 2);
- *jsCallData->thisObject = workerEngine->global();
+ *jsCallData->thisObject = v4->global();
jsCallData->args[0] = qmlContext->d()->qml(); // ###
jsCallData->args[1] = value;
f->call(jsCallData);
@@ -396,22 +397,10 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
QV4::Scoped<QV4::QmlContext> qmlContext(scope, getWorker(script));
Q_ASSERT(!!qmlContext);
- if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url)) {
- QV4::CompiledData::CompilationUnit *jsUnit = cachedUnit->createCompilationUnit();
- program.reset(new QV4::Script(v4, qmlContext, jsUnit));
- } else {
- QFile f(fileName);
- if (!f.open(QIODevice::ReadOnly)) {
- qWarning().nospace() << "WorkerScript: Cannot find source file " << url.toString();
- return;
- }
-
- QByteArray data = f.readAll();
- QString sourceCode = QString::fromUtf8(data);
- QmlIR::Document::removeScriptPragmas(sourceCode);
-
- program.reset(new QV4::Script(v4, qmlContext, sourceCode, url.toString()));
- program->parse();
+ program.reset(QV4::Script::createFromFileOrCache(v4, qmlContext, fileName, url));
+ if (program.isNull()) {
+ qWarning().nospace() << "WorkerScript: Cannot find source file " << url.toString();
+ return;
}
if (!v4->hasException)
@@ -518,7 +507,7 @@ QQuickWorkerScriptEngine::~QQuickWorkerScriptEngine()
}
QQuickWorkerScriptEnginePrivate::WorkerScript::WorkerScript()
-: id(-1), initialized(false), owner(0)
+: id(-1), initialized(false), owner(nullptr)
{
}
@@ -545,7 +534,7 @@ void QQuickWorkerScriptEngine::removeWorkerScript(int id)
{
QQuickWorkerScriptEnginePrivate::WorkerScript* script = d->workers.value(id);
if (script) {
- script->owner = 0;
+ script->owner = nullptr;
QCoreApplication::postEvent(d, new WorkerRemoveEvent(id));
}
}
@@ -576,7 +565,7 @@ void QQuickWorkerScriptEngine::run()
qDeleteAll(d->workers);
d->workers.clear();
- delete d->workerEngine; d->workerEngine = 0;
+ delete d->workerEngine; d->workerEngine = nullptr;
}
@@ -627,7 +616,7 @@ void QQuickWorkerScriptEngine::run()
{Threaded ListModel Example}
*/
QQuickWorkerScript::QQuickWorkerScript(QObject *parent)
-: QObject(parent), m_engine(0), m_scriptId(-1), m_componentComplete(true)
+: QObject(parent), m_engine(nullptr), m_scriptId(-1), m_componentComplete(true)
{
}
@@ -707,7 +696,7 @@ QQuickWorkerScriptEngine *QQuickWorkerScript::engine()
QQmlEngine *engine = qmlEngine(this);
if (!engine) {
qWarning("QQuickWorkerScript: engine() called without qmlEngine() set");
- return 0;
+ return nullptr;
}
m_engine = QQmlEnginePrivate::get(engine)->getWorkerScriptEngine();
@@ -718,7 +707,7 @@ QQuickWorkerScriptEngine *QQuickWorkerScript::engine()
return m_engine;
}
- return 0;
+ return nullptr;
}
void QQuickWorkerScript::componentComplete()
@@ -742,8 +731,7 @@ bool QQuickWorkerScript::event(QEvent *event)
QQmlEngine *engine = qmlEngine(this);
if (engine) {
WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
- QV8Engine *v8engine = QQmlEnginePrivate::get(engine)->v8engine();
- QV4::Scope scope(QV8Engine::getV4(v8engine));
+ QV4::Scope scope(engine->handle());
QV4::ScopedValue value(scope, QV4::Serialize::deserialize(workerEvent->data(), scope.engine));
emit message(QQmlV4Handle(value));
}
diff --git a/src/qml/types/qquickworkerscript_p.h b/src/qml/types/qquickworkerscript_p.h
index 8ea630c685..1a8d2ab076 100644
--- a/src/qml/types/qquickworkerscript_p.h
+++ b/src/qml/types/qquickworkerscript_p.h
@@ -67,7 +67,7 @@ class QQuickWorkerScriptEngine : public QThread
{
Q_OBJECT
public:
- QQuickWorkerScriptEngine(QQmlEngine *parent = 0);
+ QQuickWorkerScriptEngine(QQmlEngine *parent = nullptr);
~QQuickWorkerScriptEngine();
int registerWorkerScript(QQuickWorkerScript *);
@@ -91,7 +91,7 @@ class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserSt
Q_INTERFACES(QQmlParserStatus)
public:
- QQuickWorkerScript(QObject *parent = 0);
+ QQuickWorkerScript(QObject *parent = nullptr);
~QQuickWorkerScript();
QUrl source() const;
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index d5b38f6d3e..b4bebb9d5d 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -61,10 +61,10 @@ public:
V4_DEFINE_EXTENSION(QQmlAdaptorModelEngineData, engineData)
-static QV4::ReturnedValue get_index(const QV4::BuiltinFunction *f, QV4::CallData *callData)
+static QV4::ReturnedValue get_index(const QV4::FunctionObject *f, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(f);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")));
@@ -106,8 +106,8 @@ public:
void setValue(const QString &role, const QVariant &value) override;
bool resolveIndex(const QQmlAdaptorModel &model, int idx) override;
- static QV4::ReturnedValue get_property(const QV4::BuiltinFunction *, QV4::CallData *);
- static QV4::ReturnedValue set_property(const QV4::BuiltinFunction *, QV4::CallData *);
+ static QV4::ReturnedValue get_property(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue set_property(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
VDMModelDelegateDataType *type;
QVector<QVariant> cachedData;
@@ -121,8 +121,8 @@ class VDMModelDelegateDataType
public:
VDMModelDelegateDataType(QQmlAdaptorModel *model)
: model(model)
- , metaObject(0)
- , propertyCache(0)
+ , metaObject(nullptr)
+ , propertyCache(nullptr)
, propertyOffset(0)
, signalOffset(0)
, hasModelData(false)
@@ -176,7 +176,7 @@ public:
const int idx = item->modelIndex();
if (idx >= index && idx < index + count) {
for (int i = 0; i < signalIndexes.count(); ++i)
- QMetaObject::activate(item, signalIndexes.at(i), 0);
+ QMetaObject::activate(item, signalIndexes.at(i), nullptr);
}
}
return changed;
@@ -195,10 +195,10 @@ public:
dataType->watchedRoles += newRoles;
}
- static QV4::ReturnedValue get_hasModelChildren(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+ static QV4::ReturnedValue get_hasModelChildren(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")));
@@ -217,8 +217,8 @@ public:
QV4::ExecutionEngine *v4 = data->v4;
QV4::Scope scope(v4);
QV4::ScopedObject proto(scope, v4->newObject());
- proto->defineAccessorProperty(QStringLiteral("index"), get_index, 0);
- proto->defineAccessorProperty(QStringLiteral("hasModelChildren"), get_hasModelChildren, 0);
+ proto->defineAccessorProperty(QStringLiteral("index"), get_index, nullptr);
+ proto->defineAccessorProperty(QStringLiteral("hasModelChildren"), get_hasModelChildren, nullptr);
QV4::ScopedProperty p(scope);
typedef QHash<QByteArray, int>::const_iterator iterator;
@@ -298,11 +298,11 @@ int QQmlDMCachedModelData::metaCall(QMetaObject::Call call, int id, void **argum
const QMetaObject *meta = metaObject();
if (cachedData.count() > 1) {
cachedData[propertyIndex] = *static_cast<QVariant *>(arguments[0]);
- QMetaObject::activate(this, meta, propertyIndex, 0);
+ QMetaObject::activate(this, meta, propertyIndex, nullptr);
} else if (cachedData.count() == 1) {
cachedData[0] = *static_cast<QVariant *>(arguments[0]);
- QMetaObject::activate(this, meta, 0, 0);
- QMetaObject::activate(this, meta, 1, 0);
+ QMetaObject::activate(this, meta, 0, nullptr);
+ QMetaObject::activate(this, meta, 1, nullptr);
}
} else if (*type->model) {
setValue(type->propertyRoles.at(propertyIndex), *static_cast<QVariant *>(arguments[0]));
@@ -336,17 +336,17 @@ bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &, int idx)
const QMetaObject *meta = metaObject();
const int propertyCount = type->propertyRoles.count();
for (int i = 0; i < propertyCount; ++i)
- QMetaObject::activate(this, meta, i, 0);
+ QMetaObject::activate(this, meta, i, nullptr);
return true;
} else {
return false;
}
}
-QV4::ReturnedValue QQmlDMCachedModelData::get_property(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDMCachedModelData::get_property(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
@@ -365,13 +365,13 @@ QV4::ReturnedValue QQmlDMCachedModelData::get_property(const QV4::BuiltinFunctio
return QV4::Encode::undefined();
}
-QV4::ReturnedValue QQmlDMCachedModelData::set_property(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDMCachedModelData::set_property(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
QV4::Scope scope(b);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- if (!callData->argc())
+ if (!argc)
return scope.engine->throwTypeError();
uint propertyId = static_cast<const QV4::IndexedBuiltinFunction *>(b)->d()->index;
@@ -380,12 +380,12 @@ QV4::ReturnedValue QQmlDMCachedModelData::set_property(const QV4::BuiltinFunctio
QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
if (!modelData->cachedData.isEmpty()) {
if (modelData->cachedData.count() > 1) {
- modelData->cachedData[propertyId] = scope.engine->toVariant(callData->args[0], QVariant::Invalid);
- QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), propertyId, 0);
+ modelData->cachedData[propertyId] = scope.engine->toVariant(argv[0], QVariant::Invalid);
+ QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), propertyId, nullptr);
} else if (modelData->cachedData.count() == 1) {
- modelData->cachedData[0] = scope.engine->toVariant(callData->args[0], QVariant::Invalid);
- QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 0, 0);
- QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 1, 0);
+ modelData->cachedData[0] = scope.engine->toVariant(argv[0], QVariant::Invalid);
+ QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 0, nullptr);
+ QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 1, nullptr);
}
}
}
@@ -586,26 +586,26 @@ public:
}
}
- static QV4::ReturnedValue get_modelData(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+ static QV4::ReturnedValue get_modelData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::ExecutionEngine *v4 = b->engine();
- QQmlDelegateModelItemObject *o = callData->thisObject.as<QQmlDelegateModelItemObject>();
+ const QQmlDelegateModelItemObject *o = thisObject->as<QQmlDelegateModelItemObject>();
if (!o)
return v4->throwTypeError(QStringLiteral("Not a valid VisualData object"));
return v4->fromVariant(static_cast<QQmlDMListAccessorData *>(o->d()->item)->cachedData);
}
- static QV4::ReturnedValue set_modelData(const QV4::BuiltinFunction *b, QV4::CallData *callData)
+ static QV4::ReturnedValue set_modelData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
QV4::ExecutionEngine *v4 = b->engine();
- QQmlDelegateModelItemObject *o = callData->thisObject.as<QQmlDelegateModelItemObject>();
+ const QQmlDelegateModelItemObject *o = thisObject->as<QQmlDelegateModelItemObject>();
if (!o)
return v4->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- if (!callData->argc())
+ if (!argc)
return v4->throwTypeError();
- static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(v4->toVariant(callData->args[0], QVariant::Invalid));
+ static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(v4->toVariant(argv[0], QVariant::Invalid));
return QV4::Encode::undefined();
}
@@ -710,7 +710,7 @@ public:
QMetaObjectBuilder builder;
VDMObjectDelegateDataType()
- : metaObject(0)
+ : metaObject(nullptr)
, propertyOffset(0)
, signalOffset(0)
, shared(true)
@@ -720,7 +720,7 @@ public:
VDMObjectDelegateDataType(const VDMObjectDelegateDataType &type)
: QQmlRefCount()
, QQmlAdaptorModel::Accessors()
- , metaObject(0)
+ , metaObject(nullptr)
, propertyOffset(type.propertyOffset)
, signalOffset(type.signalOffset)
, shared(false)
@@ -759,7 +759,7 @@ public:
dataType->initializeMetaType(model);
return index >= 0 && index < model.list.count()
? new QQmlDMObjectData(metaType, dataType, index, qvariant_cast<QObject *>(model.list.at(index)))
- : 0;
+ : nullptr;
}
void initializeMetaType(QQmlAdaptorModel &)
@@ -807,7 +807,7 @@ public:
QMetaObject::metacall(m_data->object, call, id - m_type->propertyOffset + objectPropertyOffset, arguments);
return -1;
} else if (id >= m_type->signalOffset && call == QMetaObject::InvokeMetaMethod) {
- QMetaObject::activate(m_data, this, id - m_type->signalOffset, 0);
+ QMetaObject::activate(m_data, this, id - m_type->signalOffset, nullptr);
return -1;
} else {
return m_data->qt_metacall(call, id, arguments);
@@ -937,10 +937,10 @@ void QQmlAdaptorModel::setModel(const QVariant &variant, QQmlDelegateModel *vdm,
accessors = new VDMObjectDelegateDataType;
} else if (list.type() != QQmlListAccessor::Invalid
&& list.type() != QQmlListAccessor::Instance) { // Null QObject
- setObject(0);
+ setObject(nullptr);
accessors = &qt_vdm_list_accessors;
} else {
- setObject(0);
+ setObject(nullptr);
accessors = &qt_vdm_null_accessors;
}
}
@@ -960,7 +960,7 @@ bool QQmlAdaptorModel::isValid() const
void QQmlAdaptorModel::objectDestroyed(QObject *)
{
- setModel(QVariant(), 0, 0);
+ setModel(QVariant(), nullptr, nullptr);
}
QQmlAdaptorModelEngineData::QQmlAdaptorModelEngineData(QV4::ExecutionEngine *v4)
@@ -968,7 +968,7 @@ QQmlAdaptorModelEngineData::QQmlAdaptorModelEngineData(QV4::ExecutionEngine *v4)
{
QV4::Scope scope(v4);
QV4::ScopedObject proto(scope, v4->newObject());
- proto->defineAccessorProperty(QStringLiteral("index"), get_index, 0);
+ proto->defineAccessorProperty(QStringLiteral("index"), get_index, nullptr);
proto->defineAccessorProperty(QStringLiteral("modelData"),
QQmlDMListAccessorData::get_modelData, QQmlDMListAccessorData::set_modelData);
listItemProto.set(v4, proto);
diff --git a/src/qml/util/qqmladaptormodel_p.h b/src/qml/util/qqmladaptormodel_p.h
index 7bbddcff07..8f773efa20 100644
--- a/src/qml/util/qqmladaptormodel_p.h
+++ b/src/qml/util/qqmladaptormodel_p.h
@@ -74,7 +74,7 @@ public:
inline Accessors() {}
virtual ~Accessors();
virtual int count(const QQmlAdaptorModel &) const { return 0; }
- virtual void cleanup(QQmlAdaptorModel &, QQmlDelegateModel * = 0) const {}
+ virtual void cleanup(QQmlAdaptorModel &, QQmlDelegateModel * = nullptr) const {}
virtual QVariant value(const QQmlAdaptorModel &, int, const QString &) const {
return QVariant(); }
@@ -82,7 +82,7 @@ public:
virtual QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &,
QQmlDelegateModelItemMetaType *,
- int) const { return 0; }
+ int) const { return nullptr; }
virtual bool notify(
const QQmlAdaptorModel &,
diff --git a/src/qml/util/qqmlchangeset.cpp b/src/qml/util/qqmlchangeset.cpp
index ccfd34161f..561bde7d0c 100644
--- a/src/qml/util/qqmlchangeset.cpp
+++ b/src/qml/util/qqmlchangeset.cpp
@@ -122,7 +122,7 @@ void QQmlChangeSet::remove(int index, int count)
{
QVector<Change> removes;
removes.append(Change(index, count));
- remove(&removes, 0);
+ remove(&removes, nullptr);
}
/*!
diff --git a/src/qml/util/qqmlchangeset_p.h b/src/qml/util/qqmlchangeset_p.h
index 8e1fa3f9f2..8347a3ff19 100644
--- a/src/qml/util/qqmlchangeset_p.h
+++ b/src/qml/util/qqmlchangeset_p.h
@@ -62,10 +62,10 @@ class Q_QML_PRIVATE_EXPORT QQmlChangeSet
public:
struct MoveKey
{
- MoveKey() : moveId(-1), offset(0) {}
+ MoveKey() {}
MoveKey(int moveId, int offset) : moveId(moveId), offset(offset) {}
- int moveId;
- int offset;
+ int moveId = -1;
+ int offset = 0;
};
// The storrage for Change (below). This struct is trivial, which it has to be in order to store
@@ -119,7 +119,7 @@ public:
void change(int index, int count);
void insert(const QVector<Change> &inserts);
- void remove(const QVector<Change> &removes, QVector<Change> *inserts = 0);
+ void remove(const QVector<Change> &removes, QVector<Change> *inserts = nullptr);
void move(const QVector<Change> &removes, const QVector<Change> &inserts);
void change(const QVector<Change> &changes);
void apply(const QQmlChangeSet &changeSet);
diff --git a/src/qml/util/qqmllistaccessor.cpp b/src/qml/util/qqmllistaccessor.cpp
index 356584abdc..ad55519ad3 100644
--- a/src/qml/util/qqmllistaccessor.cpp
+++ b/src/qml/util/qqmllistaccessor.cpp
@@ -72,7 +72,7 @@ void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine)
if (d.userType() == qMetaTypeId<QJSValue>())
d = d.value<QJSValue>().toVariant();
- QQmlEnginePrivate *enginePrivate = engine?QQmlEnginePrivate::get(engine):0;
+ QQmlEnginePrivate *enginePrivate = engine?QQmlEnginePrivate::get(engine):nullptr;
if (!d.isValid()) {
m_type = Invalid;
diff --git a/src/qml/util/qqmllistaccessor_p.h b/src/qml/util/qqmllistaccessor_p.h
index bad5a5803c..bcd079adef 100644
--- a/src/qml/util/qqmllistaccessor_p.h
+++ b/src/qml/util/qqmllistaccessor_p.h
@@ -63,7 +63,7 @@ public:
~QQmlListAccessor();
QVariant list() const;
- void setList(const QVariant &, QQmlEngine * = 0);
+ void setList(const QVariant &, QQmlEngine * = nullptr);
bool isValid() const;
diff --git a/src/qml/util/qqmllistcompositor.cpp b/src/qml/util/qqmllistcompositor.cpp
index 05a4eaac39..8b0b8f48f0 100644
--- a/src/qml/util/qqmllistcompositor.cpp
+++ b/src/qml/util/qqmllistcompositor.cpp
@@ -1253,7 +1253,7 @@ void QQmlListCompositor::listItemsRemoved(
QVector<QQmlChangeSet::Change> removals;
removals.append(QQmlChangeSet::Change(index, count));
- listItemsRemoved(translatedRemovals, list, &removals, 0, 0);
+ listItemsRemoved(translatedRemovals, list, &removals, nullptr, nullptr);
}
/*!
diff --git a/src/qml/util/qqmllistcompositor_p.h b/src/qml/util/qqmllistcompositor_p.h
index 6ae9c47df3..172040559c 100644
--- a/src/qml/util/qqmllistcompositor_p.h
+++ b/src/qml/util/qqmllistcompositor_p.h
@@ -87,17 +87,17 @@ public:
class Range
{
public:
- Range() : next(this), previous(this), list(0), index(0), count(0), flags(0) {}
+ Range() : next(this), previous(this) {}
Range(Range *next, void *list, int index, int count, uint flags)
: next(next), previous(next->previous), list(list), index(index), count(count), flags(flags) {
next->previous = this; previous->next = this; }
Range *next;
Range *previous;
- void *list;
- int index;
- int count;
- uint flags;
+ void *list = nullptr;
+ int index = 0;
+ int count = 0;
+ uint flags = 0;
inline int start() const { return index; }
inline int end() const { return index + count; }
@@ -145,11 +145,11 @@ public:
void setGroup(Group g) { group = g; groupFlag = 1 << g; }
- Range *range;
- int offset;
- Group group;
+ Range *range = nullptr;
+ int offset = 0;
+ Group group = Default;
int groupFlag;
- int groupCount;
+ int groupCount = 0;
union {
struct {
int cacheIndex;
@@ -222,22 +222,22 @@ public:
const iterator &end() { return m_end; }
- void append(void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0);
- void insert(Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0);
- iterator insert(iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0);
+ void append(void *list, int index, int count, uint flags, QVector<Insert> *inserts = nullptr);
+ void insert(Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = nullptr);
+ iterator insert(iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = nullptr);
- void setFlags(Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts = 0);
- void setFlags(iterator from, int count, Group group, uint flags, QVector<Insert> *inserts = 0);
- void setFlags(Group fromGroup, int from, int count, uint flags, QVector<Insert> *inserts = 0) {
+ void setFlags(Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts = nullptr);
+ void setFlags(iterator from, int count, Group group, uint flags, QVector<Insert> *inserts = nullptr);
+ void setFlags(Group fromGroup, int from, int count, uint flags, QVector<Insert> *inserts = nullptr) {
setFlags(fromGroup, from, count, fromGroup, flags, inserts); }
- void setFlags(const iterator from, int count, uint flags, QVector<Insert> *inserts = 0) {
+ void setFlags(const iterator from, int count, uint flags, QVector<Insert> *inserts = nullptr) {
setFlags(from, count, from.group, flags, inserts); }
- void clearFlags(Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removals = 0);
- void clearFlags(iterator from, int count, Group group, uint flags, QVector<Remove> *removals = 0);
- void clearFlags(Group fromGroup, int from, int count, uint flags, QVector<Remove> *removals = 0) {
+ void clearFlags(Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removals = nullptr);
+ void clearFlags(iterator from, int count, Group group, uint flags, QVector<Remove> *removals = nullptr);
+ void clearFlags(Group fromGroup, int from, int count, uint flags, QVector<Remove> *removals = nullptr) {
clearFlags(fromGroup, from, count, fromGroup, flags, removals); }
- void clearFlags(const iterator &from, int count, uint flags, QVector<Remove> *removals = 0) {
+ void clearFlags(const iterator &from, int count, uint flags, QVector<Remove> *removals = nullptr) {
clearFlags(from, count, from.group, flags, removals); }
bool verifyMoveTo(Group fromGroup, int from, Group toGroup, int to, int count, Group group) const;
@@ -249,8 +249,8 @@ public:
int to,
int count,
Group group,
- QVector<Remove> *removals = 0,
- QVector<Insert> *inserts = 0);
+ QVector<Remove> *removals = nullptr,
+ QVector<Insert> *inserts = nullptr);
void clear();
void listItemsInserted(void *list, int index, int count, QVector<Insert> *inserts);
@@ -289,13 +289,13 @@ private:
QVector<Remove> *translatedRemovals,
void *list,
QVector<QQmlChangeSet::Change> *removals,
- QVector<QQmlChangeSet::Change> *insertions = 0,
- QVector<MovedFlags> *movedFlags = 0);
+ QVector<QQmlChangeSet::Change> *insertions = nullptr,
+ QVector<MovedFlags> *movedFlags = nullptr);
void listItemsInserted(
QVector<Insert> *translatedInsertions,
void *list,
const QVector<QQmlChangeSet::Change> &insertions,
- const QVector<MovedFlags> *movedFlags = 0);
+ const QVector<MovedFlags> *movedFlags = nullptr);
void listItemsChanged(
QVector<Change> *translatedChanges,
void *list,
@@ -308,8 +308,7 @@ Q_DECLARE_TYPEINFO(QQmlListCompositor::Change, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QQmlListCompositor::Remove, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QQmlListCompositor::Insert, Q_PRIMITIVE_TYPE);
-inline QQmlListCompositor::iterator::iterator()
- : range(0), offset(0), group(Default), groupCount(0) {}
+inline QQmlListCompositor::iterator::iterator() {}
inline QQmlListCompositor::iterator::iterator(const iterator &it)
: range(it.range)
, offset(it.offset)
diff --git a/src/qml/util/qqmlpropertymap.cpp b/src/qml/util/qqmlpropertymap.cpp
index b54e8d901a..578c05086f 100644
--- a/src/qml/util/qqmlpropertymap.cpp
+++ b/src/qml/util/qqmlpropertymap.cpp
@@ -355,7 +355,7 @@ QQmlPropertyMap::QQmlPropertyMap(const QMetaObject *staticMetaObject, QObject *p
*/
/*!
- \fn QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)
+ \fn template<class DerivedType> QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)
Constructs a bindable map with parent object \a parent. Use this constructor
in classes derived from QQmlPropertyMap.
diff --git a/src/qml/util/qqmlpropertymap.h b/src/qml/util/qqmlpropertymap.h
index 3930ac00a8..cb7ada3d79 100644
--- a/src/qml/util/qqmlpropertymap.h
+++ b/src/qml/util/qqmlpropertymap.h
@@ -56,7 +56,7 @@ class Q_QML_EXPORT QQmlPropertyMap : public QObject
Q_OBJECT
public:
explicit QQmlPropertyMap(QObject *parent = nullptr);
- virtual ~QQmlPropertyMap();
+ ~QQmlPropertyMap() override;
QVariant value(const QString &key) const;
void insert(const QString &key, const QVariant &value);