aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-08-31 08:55:16 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-08-31 08:55:16 +0200
commit71478352376022faa9be6d79f2a760c289945ff5 (patch)
tree0f8ff4a88c1b033367337a93d23a329d145ee903
parentc38efcb67cf93ba3e91e184c3b891efef4ef75a3 (diff)
parent05daa9bfe1a03ffe1cc580b6cfd88e093e2493c0 (diff)
Merge branch 'master' into refactor
Conflicts: src/3rdparty/v8 src/declarative/declarative.pro src/declarative/items/qsgcanvas.cpp src/declarative/items/qsgshadereffectsource_p.h src/declarative/items/qsgview.cpp src/declarative/particles/qsgcustomparticle.cpp src/imports/gestures/gestures.pro src/imports/particles/particles.pro src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro src/qtquick1/qtquick1.pro tests/auto/declarative/examples/examples.pro tests/auto/declarative/qsglistview/qsglistview.pro tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro Change-Id: I423344f83e1835116cad531b877fde6e68a8849a
-rw-r--r--.gitmodules3
-rw-r--r--examples/declarative/particles/allsmiles/smile.qml40
-rw-r--r--examples/declarative/particles/asteroid/blackhole.qml2
-rw-r--r--examples/declarative/particles/custom/blurparticles.qml29
-rw-r--r--examples/declarative/particles/custom/custom.qml12
-rw-r--r--examples/declarative/particles/custom/shader.qml11
-rw-r--r--examples/declarative/particles/spaceexplorer/spaceexplorer.qml6
m---------src/3rdparty/v80
-rw-r--r--src/declarative/debugger/qdeclarativedebughelper.cpp1
-rw-r--r--src/declarative/debugger/qdeclarativedebughelper_p.h4
-rw-r--r--src/declarative/declarative.pro3
-rw-r--r--src/declarative/items/items.pri1
-rw-r--r--src/declarative/items/qsganimatedimage.cpp3
-rw-r--r--src/declarative/items/qsgborderimage.cpp5
-rw-r--r--src/declarative/items/qsgcanvas.cpp94
-rw-r--r--src/declarative/items/qsgpositioners.cpp34
-rw-r--r--src/declarative/items/qsgpositioners_p.h2
-rw-r--r--src/declarative/items/qsgpositioners_p_p.h38
-rw-r--r--src/declarative/items/qsgshadereffect.cpp12
-rw-r--r--src/declarative/items/qsgshadereffectsource.cpp8
-rw-r--r--src/declarative/items/qsgshadereffectsource_p.h1
-rw-r--r--src/declarative/items/qsgview.cpp47
-rw-r--r--src/declarative/items/qsgview_p.h (renamed from tests/auto/declarative/qdeclarativedebughelper/private_headers/qdeclarativedebughelper_p.h)65
-rw-r--r--src/declarative/items/qsgvisualitemmodel.cpp2
-rw-r--r--src/declarative/particles/defaultshaders/imagevertex.shader3
-rw-r--r--src/declarative/particles/qsgcustomparticle.cpp69
-rw-r--r--src/declarative/particles/qsgimageparticle.cpp4
-rw-r--r--src/declarative/particles/qsgparticleaffector.cpp10
-rw-r--r--src/declarative/particles/qsgparticlesystem_p.h1
-rw-r--r--src/declarative/particles/qsgpointattractor.cpp28
-rw-r--r--src/declarative/particles/qsgpointattractor_p.h5
-rw-r--r--src/declarative/particles/qsgv8particledata.cpp4
-rw-r--r--src/declarative/qml/ftw/ftw.pri23
-rw-r--r--src/declarative/qml/ftw/qbitfield_p.h (renamed from src/declarative/qml/qbitfield_p.h)0
-rw-r--r--src/declarative/qml/ftw/qdeclarativepool.cpp92
-rw-r--r--src/declarative/qml/ftw/qdeclarativepool_p.h266
-rw-r--r--src/declarative/qml/ftw/qdeclarativerefcount.cpp (renamed from src/declarative/qml/qdeclarativerefcount.cpp)0
-rw-r--r--src/declarative/qml/ftw/qdeclarativerefcount_p.h (renamed from src/declarative/qml/qdeclarativerefcount_p.h)0
-rw-r--r--src/declarative/qml/ftw/qdeclarativeutils_p.h91
-rw-r--r--src/declarative/qml/ftw/qfastmetabuilder.cpp371
-rw-r--r--src/declarative/qml/ftw/qfastmetabuilder_p.h204
-rw-r--r--src/declarative/qml/ftw/qfieldlist_p.h210
-rw-r--r--src/declarative/qml/ftw/qhashedstring.cpp479
-rw-r--r--src/declarative/qml/ftw/qhashedstring_p.h1130
-rw-r--r--src/declarative/qml/ftw/qhashfield_p.h120
-rw-r--r--src/declarative/qml/ftw/qintrusivelist.cpp (renamed from src/declarative/qml/qintrusivelist.cpp)0
-rw-r--r--src/declarative/qml/ftw/qintrusivelist_p.h (renamed from src/declarative/qml/qintrusivelist_p.h)0
-rw-r--r--src/declarative/qml/ftw/qmetaobjectbuilder.cpp (renamed from src/declarative/qml/qmetaobjectbuilder.cpp)0
-rw-r--r--src/declarative/qml/ftw/qmetaobjectbuilder_p.h (renamed from src/declarative/qml/qmetaobjectbuilder_p.h)0
-rw-r--r--src/declarative/qml/ftw/qpodvector_p.h (renamed from src/declarative/qml/qpodvector_p.h)0
-rw-r--r--src/declarative/qml/parser/parser.pri4
-rw-r--r--src/declarative/qml/parser/qdeclarativejs.g563
-rw-r--r--src/declarative/qml/parser/qdeclarativejsast_p.h109
-rw-r--r--src/declarative/qml/parser/qdeclarativejsengine_p.cpp79
-rw-r--r--src/declarative/qml/parser/qdeclarativejsengine_p.h73
-rw-r--r--src/declarative/qml/parser/qdeclarativejsgrammar.cpp1060
-rw-r--r--src/declarative/qml/parser/qdeclarativejsgrammar_p.h23
-rw-r--r--src/declarative/qml/parser/qdeclarativejskeywords_p.h860
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer.cpp1917
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer_p.h247
-rw-r--r--src/declarative/qml/parser/qdeclarativejsmemorypool_p.h124
-rw-r--r--src/declarative/qml/parser/qdeclarativejsnodepool_p.h139
-rw-r--r--src/declarative/qml/parser/qdeclarativejsparser.cpp507
-rw-r--r--src/declarative/qml/parser/qdeclarativejsparser_p.h9
-rw-r--r--src/declarative/qml/qdeclarative.h18
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp2
-rw-r--r--src/declarative/qml/qdeclarativecompileddata.cpp8
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp1830
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h351
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp2
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h2
-rw-r--r--src/declarative/qml/qdeclarativecustomparser.cpp27
-rw-r--r--src/declarative/qml/qdeclarativecustomparser_p.h10
-rw-r--r--src/declarative/qml/qdeclarativecustomparser_p_p.h10
-rw-r--r--src/declarative/qml/qdeclarativedirparser.cpp53
-rw-r--r--src/declarative/qml/qdeclarativedirparser_p.h10
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp32
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h1
-rw-r--r--src/declarative/qml/qdeclarativeexpression.cpp4
-rw-r--r--src/declarative/qml/qdeclarativeimport.cpp414
-rw-r--r--src/declarative/qml/qdeclarativeimport_p.h22
-rw-r--r--src/declarative/qml/qdeclarativeintegercache.cpp5
-rw-r--r--src/declarative/qml/qdeclarativeintegercache_p.h1
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp377
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h68
-rw-r--r--src/declarative/qml/qdeclarativeparser.cpp437
-rw-r--r--src/declarative/qml/qdeclarativeparser_p.h375
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp96
-rw-r--r--src/declarative/qml/qdeclarativepropertycache.cpp95
-rw-r--r--src/declarative/qml/qdeclarativepropertycache_p.h4
-rw-r--r--src/declarative/qml/qdeclarativerewrite.cpp6
-rw-r--r--src/declarative/qml/qdeclarativerewrite_p.h6
-rw-r--r--src/declarative/qml/qdeclarativescript.cpp (renamed from src/declarative/qml/qdeclarativescriptparser.cpp)793
-rw-r--r--src/declarative/qml/qdeclarativescript_p.h526
-rw-r--r--src/declarative/qml/qdeclarativescriptparser_p.h150
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp252
-rw-r--r--src/declarative/qml/qdeclarativetypeloader_p.h29
-rw-r--r--src/declarative/qml/qdeclarativetypenamecache.cpp97
-rw-r--r--src/declarative/qml/qdeclarativetypenamecache_p.h93
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp15
-rw-r--r--src/declarative/qml/qdeclarativeworkerscript.cpp2
-rw-r--r--src/declarative/qml/qml.pri15
-rw-r--r--src/declarative/qml/v4/qdeclarativev4compiler.cpp110
-rw-r--r--src/declarative/qml/v4/qdeclarativev4compiler_p.h16
-rw-r--r--src/declarative/qml/v4/qdeclarativev4compiler_p_p.h67
-rw-r--r--src/declarative/qml/v4/qdeclarativev4instruction.cpp6
-rw-r--r--src/declarative/qml/v4/qdeclarativev4instruction_p.h13
-rw-r--r--src/declarative/qml/v4/qdeclarativev4ir.cpp163
-rw-r--r--src/declarative/qml/v4/qdeclarativev4ir_p.h167
-rw-r--r--src/declarative/qml/v4/qdeclarativev4irbuilder.cpp176
-rw-r--r--src/declarative/qml/v4/qdeclarativev4irbuilder_p.h7
-rw-r--r--src/declarative/qml/v8/qhashedstring.cpp103
-rw-r--r--src/declarative/qml/v8/qhashedstring_p.h664
-rw-r--r--src/declarative/qml/v8/qv8_p.h2
-rw-r--r--src/declarative/qml/v8/qv8contextwrapper.cpp18
-rw-r--r--src/declarative/qml/v8/qv8debug_p.h2
-rw-r--r--src/declarative/qml/v8/qv8engine.cpp4
-rw-r--r--src/declarative/qml/v8/qv8engine_p.h4
-rw-r--r--src/declarative/qml/v8/qv8include.cpp4
-rw-r--r--src/declarative/qml/v8/qv8qobjectwrapper.cpp26
-rw-r--r--src/declarative/qml/v8/qv8typewrapper.cpp85
-rw-r--r--src/declarative/qml/v8/qv8typewrapper_p.h3
-rw-r--r--src/declarative/qml/v8/v8.pri2
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp8
-rw-r--r--src/declarative/util/qdeclarativeconnections.cpp2
-rw-r--r--src/declarative/util/qdeclarativefontloader.cpp7
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp31
-rw-r--r--src/declarative/util/qdeclarativepackage_p.h2
-rw-r--r--src/declarative/util/qdeclarativepropertychanges.cpp14
-rw-r--r--src/declarative/util/qdeclarativestateoperations.cpp8
-rw-r--r--src/declarative/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch343
-rw-r--r--src/declarative/v8/0002-Add-a-bit-field-3-to-Map.patch118
-rw-r--r--src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch364
-rw-r--r--src/declarative/v8/0004-Generalize-external-object-resources.patch894
-rw-r--r--src/declarative/v8/0005-Introduce-a-QML-compilation-mode.patch1777
-rw-r--r--src/declarative/v8/0006-Allow-access-to-the-calling-script-data.patch48
-rw-r--r--src/declarative/v8/0007-Fix-warnings.patch46
-rw-r--r--src/declarative/v8/0008-Add-custom-object-compare-callback.patch489
-rw-r--r--src/declarative/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch286
-rw-r--r--src/declarative/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch397
-rw-r--r--src/declarative/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch63
-rw-r--r--src/declarative/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch116
-rw-r--r--src/declarative/v8/0013-Remove-execute-flag-from-v8-debug.h.patch15
-rw-r--r--src/declarative/v8/README1
-rw-r--r--src/declarative/v8/v8.pri253
-rw-r--r--src/declarative/v8/v8base.pri19
-rwxr-xr-xsrc/declarative/v8/wrapcc.pl48
-rw-r--r--src/imports/gestures/gestures.pro2
-rw-r--r--src/imports/gestures/qdeclarativegesturearea.cpp3
-rw-r--r--src/imports/particles/particles.pro2
-rw-r--r--src/imports/testlib/testlib.pro2
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro2
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp1
-rw-r--r--src/qmltest/qmltest.pro2
-rw-r--r--src/qmltest/quicktest.cpp9
-rw-r--r--src/qmltest/quicktestresult.cpp4
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativeitem.cpp4
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp2
-rw-r--r--src/qtquick1/qtquick1.pro3
-rw-r--r--src/qtquick1/util/qdeclarativeconnections.cpp2
-rw-r--r--src/qtquick1/util/qdeclarativelistmodel.cpp3
-rw-r--r--src/qtquick1/util/qdeclarativepropertychanges.cpp14
-rw-r--r--tests/auto/declarative/declarative.pro4
-rw-r--r--tests/auto/declarative/examples/examples.pro2
-rw-r--r--tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro2
-rw-r--r--tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro2
-rw-r--r--tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro2
-rw-r--r--tests/auto/declarative/qdeclarativedebug/qdeclarativedebug.pro4
-rw-r--r--tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp11
-rw-r--r--tests/auto/declarative/qdeclarativedebugclient/qdeclarativedebugclient.pro4
-rw-r--r--tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp5
-rw-r--r--tests/auto/declarative/qdeclarativedebughelper/qdeclarativedebughelper.pro6
-rw-r--r--tests/auto/declarative/qdeclarativedebughelper/tst_qdeclarativedebughelper.cpp112
-rw-r--r--tests/auto/declarative/qdeclarativedebugservice/qdeclarativedebugservice.pro2
-rw-r--r--tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp4
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMajorVersionFail.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMajorVersionFail.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMinorVersionFail.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMinorVersionFail.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApi.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/moduleApi.qml)2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiCaching.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/moduleApiCaching.qml)2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiEnums.qml8
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiWriting.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/moduleApiWriting.qml)3
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApi.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiCaching.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiWriting.qml32
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro2
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp16
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.h5
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp185
-rw-r--r--tests/auto/declarative/qdeclarativefontloader/data/daniel.ttfbin0 -> 51984 bytes
-rw-r--r--tests/auto/declarative/qdeclarativefontloader/data/dummy.ttf0
-rw-r--r--tests/auto/declarative/qdeclarativefontloader/data/tarzeau_ocr_a.ttfbin0 -> 24544 bytes
-rw-r--r--tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro18
-rw-r--r--tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp230
-rw-r--r--tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro2
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/empty.errors.txt4
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/signal.2.errors.txt2
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro2
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro2
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp10
-rw-r--r--tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro2
-rw-r--r--tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro2
-rw-r--r--tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro2
-rw-r--r--tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro2
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro2
-rw-r--r--tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro2
-rw-r--r--tests/auto/declarative/qdeclarativev4/qdeclarativev4.pro2
-rw-r--r--tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro2
-rw-r--r--tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro2
-rw-r--r--tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro2
-rw-r--r--tests/auto/declarative/qjsengine/tst_qjsengine.cpp19
-rw-r--r--tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro2
-rw-r--r--tests/auto/declarative/qsgflickable/qsgflickable.pro2
-rw-r--r--tests/auto/declarative/qsgflipable/qsgflipable.pro2
-rw-r--r--tests/auto/declarative/qsggridview/qsggridview.pro2
-rw-r--r--tests/auto/declarative/qsgitem/tst_qsgitem.cpp148
-rw-r--r--tests/auto/declarative/qsglistview/qsglistview.pro2
-rw-r--r--tests/auto/declarative/qsglistview/tst_qsglistview.cpp1
-rw-r--r--tests/auto/declarative/qsgpathview/qsgpathview.pro2
-rw-r--r--tests/auto/declarative/qsgpositioners/qsgpositioners.pro2
-rw-r--r--tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp52
-rw-r--r--tests/auto/declarative/qsgtext/qsgtext.pro2
-rw-r--r--tests/auto/declarative/qsgtextedit/qsgtextedit.pro2
-rw-r--r--tests/auto/declarative/qsgtextinput/qsgtextinput.pro2
-rw-r--r--tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp2
-rw-r--r--tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro2
-rw-r--r--tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp79
-rw-r--r--tests/auto/declarative/v8/Makefile.nonqt11
-rw-r--r--tests/auto/declarative/v8/README.txt13
-rw-r--r--tests/auto/declarative/v8/tst_v8.cpp79
-rw-r--r--tests/auto/declarative/v8/v8.pro10
-rw-r--r--tests/auto/declarative/v8/v8main.cpp17
-rw-r--r--tests/auto/declarative/v8/v8test.cpp254
-rw-r--r--tests/auto/declarative/v8/v8test.h51
-rw-r--r--tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp13
-rw-r--r--tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro2
-rw-r--r--tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro2
-rw-r--r--tests/benchmarks/declarative/compilation/tst_compilation.cpp6
-rw-r--r--tests/benchmarks/declarative/creation/creation.pro4
-rw-r--r--tests/benchmarks/declarative/creation/tst_creation.cpp8
-rw-r--r--tools/qmlplugindump/main.cpp13
-rw-r--r--tools/qmlplugindump/qmlplugindump.pro2
-rw-r--r--tools/qmlscene/main.cpp11
-rw-r--r--tools/qmlviewer/qml.pri2
262 files changed, 11288 insertions, 12825 deletions
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 183f5b46cc..0000000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "src/3rdparty/v8"]
- path = src/3rdparty/v8
- url = git://github.com/aaronkennedy/v8.git
diff --git a/examples/declarative/particles/allsmiles/smile.qml b/examples/declarative/particles/allsmiles/smile.qml
index 3eb57617ec..bfce60cc4a 100644
--- a/examples/declarative/particles/allsmiles/smile.qml
+++ b/examples/declarative/particles/allsmiles/smile.qml
@@ -70,47 +70,17 @@ Rectangle{
source: "content/particle.png"
}
vertexShader:"
- attribute highp vec2 vPos;
- attribute highp vec2 vTex;
- attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
- attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
- attribute highp float r;
-
uniform highp float maxWidth;
uniform highp float maxHeight;
-
- uniform highp mat4 qt_Matrix;
- uniform highp float timestamp;
- uniform lowp float qt_Opacity;
-
- varying highp vec2 fTex;
- varying highp vec2 fTex2;
+ varying highp vec2 fTex2;
varying lowp float fFade;
+ uniform lowp float qt_Opacity;
void main() {
- fTex = vTex;
fTex2 = vec2(vPos.x / maxWidth, vPos.y / maxHeight);
- highp float size = vData.z;
- highp float endSize = vData.w;
-
highp float t = (timestamp - vData.x) / vData.y;
-
- highp float currentSize = mix(size, endSize, t * t);
-
- if (t < 0. || t > 1.)
- currentSize = 0.;
-
- highp vec2 pos = vPos
- - currentSize / 2. + currentSize * vTex // adjust size
- + vVec.xy * t * vData.y // apply speed vector..
- + 0.5 * vVec.zw * pow(t * vData.y, 2.);
-
- gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
-
- highp float fadeIn = min(t * 10., 1.);
- highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
-
- fFade = fadeIn * fadeOut * qt_Opacity;
+ fFade = min(t*4., (1.-t*t)*.75) * qt_Opacity;
+ defaultMain();
}
"
property variant particleTexture: particleSource
@@ -120,7 +90,7 @@ Rectangle{
uniform sampler2D pictureTexture;
varying highp vec2 fTex;
varying highp vec2 fTex2;
- varying highp float fFade;
+ varying lowp float fFade;
void main() {
gl_FragColor = texture2D(pictureTexture, fTex2) * texture2D(particleTexture, fTex).w * fFade;
}"
diff --git a/examples/declarative/particles/asteroid/blackhole.qml b/examples/declarative/particles/asteroid/blackhole.qml
index 4a7ce02538..441f4c38d6 100644
--- a/examples/declarative/particles/asteroid/blackhole.qml
+++ b/examples/declarative/particles/asteroid/blackhole.qml
@@ -149,7 +149,7 @@ Rectangle{
id: gs; x: root.width/2; y: root.height/2; strength: 4000000;
system: particles
physics: PointAttractor.Acceleration
- proportionalToDistance: PointAttractor.Quadratic
+ proportionalToDistance: PointAttractor.InverseQuadratic
}
Kill{
system: particles
diff --git a/examples/declarative/particles/custom/blurparticles.qml b/examples/declarative/particles/custom/blurparticles.qml
index 7974c6ab7c..238608c002 100644
--- a/examples/declarative/particles/custom/blurparticles.qml
+++ b/examples/declarative/particles/custom/blurparticles.qml
@@ -68,41 +68,14 @@ Rectangle{
CustomParticle{
system: sys
- //TODO: Someway that you don't have to rewrite the basics for a simple addition
vertexShader:"
- attribute highp vec2 vPos;
- attribute highp vec2 vTex;
- attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
- attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
- attribute highp float r;
-
- uniform highp mat4 qt_Matrix;
- uniform highp float timestamp;
uniform lowp float qt_Opacity;
-
- varying highp vec2 fTex;
varying lowp float fFade;
varying lowp float fBlur;
void main() {
- fTex = vTex;
- highp float size = vData.z;
- highp float endSize = vData.w;
-
+ defaultMain();
highp float t = (timestamp - vData.x) / vData.y;
-
- highp float currentSize = mix(size, endSize, t * t);
-
- if (t < 0. || t > 1.)
- currentSize = 0.;
-
- highp vec2 pos = vPos
- - currentSize / 2. + currentSize * vTex // adjust size
- + vVec.xy * t * vData.y // apply speed vector..
- + 0.5 * vVec.zw * pow(t * vData.y, 2.);
-
- gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
-
highp float fadeIn = min(t * 10., 1.);
highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
diff --git a/examples/declarative/particles/custom/custom.qml b/examples/declarative/particles/custom/custom.qml
index 9a562af3b6..4b75cf6ebe 100644
--- a/examples/declarative/particles/custom/custom.qml
+++ b/examples/declarative/particles/custom/custom.qml
@@ -44,18 +44,8 @@ ParticleSystem{
}
}
CustomParticle{
- //TODO: Someway that you don't have to rewrite the basics for a simple addition
vertexShader:"
- attribute highp vec2 vPos;
- attribute highp vec2 vTex;
- attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
- attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
-
- uniform highp mat4 qt_ModelViewProjectionMatrix;
- uniform highp float timestamp;
uniform lowp float qt_Opacity;
-
- varying highp vec2 fTex;
varying lowp float fFade;
varying highp vec2 fPos;
@@ -76,7 +66,7 @@ ParticleSystem{
+ vVec.xy * t * vData.y // apply speed vector..
+ 0.5 * vVec.zw * pow(t * vData.y, 2.);
- gl_Position = qt_ModelViewProjectionMatrix * vec4(pos.x, pos.y, 0, 1);
+ gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
highp float fadeIn = min(t * 20., 1.);
highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
diff --git a/examples/declarative/particles/custom/shader.qml b/examples/declarative/particles/custom/shader.qml
index 329eaf226b..6253679cb7 100644
--- a/examples/declarative/particles/custom/shader.qml
+++ b/examples/declarative/particles/custom/shader.qml
@@ -27,19 +27,8 @@ ParticleSystem{
acceleration: PointDirection{x: -root.width/40; y: -root.height/40; xVariation: -root.width/20; yVariation: -root.width/20}
}
CustomParticle{
- //TODO: Someway that you don't have to rewrite the basics for a simple addition
vertexShader:"
- attribute highp vec2 vPos;
- attribute highp vec2 vTex;
- attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
- attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
- attribute highp float r;
-
- uniform highp mat4 qt_Matrix;
- uniform highp float timestamp;
uniform lowp float qt_Opacity;
-
- varying highp vec2 fTex;
varying lowp float fFade;
varying highp vec2 fPos;
diff --git a/examples/declarative/particles/spaceexplorer/spaceexplorer.qml b/examples/declarative/particles/spaceexplorer/spaceexplorer.qml
index 1bb3cdae02..727d711053 100644
--- a/examples/declarative/particles/spaceexplorer/spaceexplorer.qml
+++ b/examples/declarative/particles/spaceexplorer/spaceexplorer.qml
@@ -276,7 +276,7 @@ Rectangle{
}
PointAttractor{
id: gs1; x: vorteX; y: vorteY; strength: 800000;
- proportionalToDistance: PointAttractor.Quadratic;
+ proportionalToDistance: PointAttractor.InverseQuadratic;
system: foreground
}
Kill{
@@ -289,7 +289,7 @@ Rectangle{
PointAttractor{
id: gs2; x: vorteX2; y: vorteY2; strength: 800000;
- proportionalToDistance: PointAttractor.Quadratic;
+ proportionalToDistance: PointAttractor.InverseQuadratic;
system: foreground
}
Kill{
@@ -302,7 +302,7 @@ Rectangle{
PointAttractor{
id: gs3; x: vorteX3; y: vorteY3; strength: 800000;
- proportionalToDistance: PointAttractor.Quadratic;
+ proportionalToDistance: PointAttractor.InverseQuadratic;
system: foreground
}
Kill{
diff --git a/src/3rdparty/v8 b/src/3rdparty/v8
deleted file mode 160000
-Subproject 472c04c9e7a64e8734c76d2cf97a7cc5b773b78
diff --git a/src/declarative/debugger/qdeclarativedebughelper.cpp b/src/declarative/debugger/qdeclarativedebughelper.cpp
index 5f5d8754bb..cbe4a85c61 100644
--- a/src/declarative/debugger/qdeclarativedebughelper.cpp
+++ b/src/declarative/debugger/qdeclarativedebughelper.cpp
@@ -58,6 +58,7 @@ void QDeclarativeDebugHelper::setAnimationSlowDownFactor(qreal factor)
}
void QDeclarativeDebugHelper::enableDebugging() {
+ qWarning("QDeclarativeDebugHelper::enableDebugging() is deprecated! Add CONFIG += declarative_debug to your .pro file instead.");
#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
qWarning("Qml debugging is enabled. Only use this in a safe environment!");
diff --git a/src/declarative/debugger/qdeclarativedebughelper_p.h b/src/declarative/debugger/qdeclarativedebughelper_p.h
index 60187112bf..d9ed5796ee 100644
--- a/src/declarative/debugger/qdeclarativedebughelper_p.h
+++ b/src/declarative/debugger/qdeclarativedebughelper_p.h
@@ -52,6 +52,10 @@ QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
+#ifndef QT_BUILD_DECLARATIVE_LIB
+#warning Use of this header file is deprecated! Add CONFIG += declarative_debug to your .pro file instead.
+#endif
+
// Helper methods to access private API through a stable interface
// This is used in the qmljsdebugger library of QtCreator.
class Q_DECLARATIVE_EXPORT QDeclarativeDebugHelper
diff --git a/src/declarative/declarative.pro b/src/declarative/declarative.pro
index 89b94526af..5db77a79dd 100644
--- a/src/declarative/declarative.pro
+++ b/src/declarative/declarative.pro
@@ -6,7 +6,7 @@ QPRO_PWD = $$PWD
CONFIG += module
MODULE_PRI += ../../modules/qt_declarative.pri
-QT = core-private gui gui-private network widgets-private sql
+QT = core-private gui gui-private network widgets-private sql v8-private
contains(QT_CONFIG, svg): QT += svg
DEFINES += QT_BUILD_DECLARATIVE_LIB QT_NO_URL_CAST_FROM_STRING
@@ -34,7 +34,6 @@ include(debugger/debugger.pri)
include(scenegraph/scenegraph.pri)
include(items/items.pri)
include(particles/particles.pri)
-include(v8/v8.pri)
symbian: {
TARGET.UID3=0x2001E623
diff --git a/src/declarative/items/items.pri b/src/declarative/items/items.pri
index 848c782a6e..9880dd8dc6 100644
--- a/src/declarative/items/items.pri
+++ b/src/declarative/items/items.pri
@@ -53,6 +53,7 @@ HEADERS += \
$$PWD/qsgtranslate_p.h \
$$PWD/qsgclipnode_p.h \
$$PWD/qsgview.h \
+ $$PWD/qsgview_p.h \
$$PWD/qsganimation_p.h \
$$PWD/qsganimation_p_p.h \
$$PWD/qsgstateoperations_p.h \
diff --git a/src/declarative/items/qsganimatedimage.cpp b/src/declarative/items/qsganimatedimage.cpp
index ea36153ef0..e4bba512af 100644
--- a/src/declarative/items/qsganimatedimage.cpp
+++ b/src/declarative/items/qsganimatedimage.cpp
@@ -264,7 +264,6 @@ void QSGAnimatedImage::load()
if (d->progress != oldProgress)
emit progressChanged(d->progress);
} else {
-#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
if (!lf.isEmpty()) {
//### should be unified with movieRequestFinished
@@ -298,7 +297,7 @@ void QSGAnimatedImage::load()
emit progressChanged(d->progress);
return;
}
-#endif
+
d->status = Loading;
d->progress = 0;
emit statusChanged(d->status);
diff --git a/src/declarative/items/qsgborderimage.cpp b/src/declarative/items/qsgborderimage.cpp
index 8d54bce419..30b10321a0 100644
--- a/src/declarative/items/qsgborderimage.cpp
+++ b/src/declarative/items/qsgborderimage.cpp
@@ -306,15 +306,12 @@ void QSGBorderImage::load()
} else {
d->status = Loading;
if (d->url.path().endsWith(QLatin1String("sci"))) {
-#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
if (!lf.isEmpty()) {
QFile file(lf);
file.open(QIODevice::ReadOnly);
setGridScaledImage(QSGGridScaledImage(&file));
- } else
-#endif
- {
+ } else {
QNetworkRequest req(d->url);
d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp
index 8ff7d17837..95ee95d0f7 100644
--- a/src/declarative/items/qsgcanvas.cpp
+++ b/src/declarative/items/qsgcanvas.cpp
@@ -153,17 +153,17 @@ public:
Focus behavior
==============
-Prior to being added to a valid canvas items can set and clear focus with no
+Prior to being added to a valid canvas items can set and clear focus with no
effect. Only once items are added to a canvas (by way of having a parent set that
-already belongs to a canvas) do the focus rules apply. Focus goes back to
+already belongs to a canvas) do the focus rules apply. Focus goes back to
having no effect if an item is removed from a canvas.
When an item is moved into a new focus scope (either being added to a canvas
-for the first time, or having its parent changed), if the focus scope already has
+for the first time, or having its parent changed), if the focus scope already has
a scope focused item that takes precedence over the item being added. Otherwise,
-the focus of the added tree is used. In the case of of a tree of items being
+the focus of the added tree is used. In the case of of a tree of items being
added to a canvas for the first time, which may have a conflicted focus state (two
-or more items in one scope having focus set), the same rule is applied item by item -
+or more items in one scope having focus set), the same rule is applied item by item -
thus the first item that has focus will get it (assuming the scope doesn't already
have a scope focused item), and the other items will have their focus cleared.
*/
@@ -478,7 +478,7 @@ void QSGCanvasPrivate::sceneMouseEventForTransform(QGraphicsSceneMouseEvent &sce
sceneEvent.setLastPos(transform.map(sceneEvent.lastScenePos()));
for (int ii = 0; ii < 5; ++ii) {
if (sceneEvent.buttons() & (1 << ii)) {
- sceneEvent.setButtonDownPos((Qt::MouseButton)(1 << ii),
+ sceneEvent.setButtonDownPos((Qt::MouseButton)(1 << ii),
transform.map(sceneEvent.buttonDownScenePos((Qt::MouseButton)(1 << ii))));
}
}
@@ -692,7 +692,7 @@ void QSGCanvasPrivate::setFocusInScope(QSGItem *scope, QSGItem *item, FocusOptio
updateInputMethodData();
QFocusEvent event(QEvent::FocusIn, Qt::OtherFocusReason);
- q->sendEvent(newActiveFocusItem, &event);
+ q->sendEvent(newActiveFocusItem, &event);
} else {
updateInputMethodData();
}
@@ -778,12 +778,12 @@ void QSGCanvasPrivate::clearFocusInScope(QSGItem *scope, QSGItem *item, FocusOpt
updateInputMethodData();
QFocusEvent event(QEvent::FocusIn, Qt::OtherFocusReason);
- q->sendEvent(newActiveFocusItem, &event);
+ q->sendEvent(newActiveFocusItem, &event);
} else {
updateInputMethodData();
}
- if (!changed.isEmpty())
+ if (!changed.isEmpty())
notifyFocusChangesRecur(changed.data(), changed.count() - 1);
}
@@ -807,7 +807,7 @@ void QSGCanvasPrivate::notifyFocusChangesRecur(QSGItem **items, int remaining)
itemPrivate->itemChange(QSGItem::ItemActiveFocusHasChanged, itemPrivate->activeFocus);
emit item->activeFocusChanged(itemPrivate->activeFocus);
}
- }
+ }
}
void QSGCanvasPrivate::updateInputMethodData()
@@ -891,21 +891,21 @@ QSGCanvas::~QSGCanvas()
QSGItem *QSGCanvas::rootItem() const
{
Q_D(const QSGCanvas);
-
+
return d->rootItem;
}
QSGItem *QSGCanvas::activeFocusItem() const
{
Q_D(const QSGCanvas);
-
+
return d->activeFocusItem;
}
QSGItem *QSGCanvas::mouseGrabberItem() const
{
Q_D(const QSGCanvas);
-
+
return d->mouseGrabberItem;
}
@@ -1016,7 +1016,7 @@ bool QSGCanvasPrivate::deliverInitialMousePressEvent(QSGItem *item, QGraphicsSce
event->accept();
mouseGrabberItem = item;
q->sendEvent(item, event);
- if (event->isAccepted())
+ if (event->isAccepted())
return true;
mouseGrabberItem->ungrabMouse();
mouseGrabberItem = 0;
@@ -1030,10 +1030,10 @@ bool QSGCanvasPrivate::deliverMouseEvent(QGraphicsSceneMouseEvent *sceneEvent)
{
Q_Q(QSGCanvas);
- if (!mouseGrabberItem &&
+ if (!mouseGrabberItem &&
sceneEvent->type() == QEvent::GraphicsSceneMousePress &&
(sceneEvent->button() & sceneEvent->buttons()) == sceneEvent->buttons()) {
-
+
return deliverInitialMousePressEvent(rootItem, sceneEvent);
}
@@ -1053,7 +1053,7 @@ bool QSGCanvasPrivate::deliverMouseEvent(QGraphicsSceneMouseEvent *sceneEvent)
void QSGCanvas::mousePressEvent(QMouseEvent *event)
{
Q_D(QSGCanvas);
-
+
#ifdef MOUSE_DEBUG
qWarning() << "QSGCanvas::mousePressEvent()" << event->pos() << event->button() << event->buttons();
#endif
@@ -1068,7 +1068,7 @@ void QSGCanvas::mousePressEvent(QMouseEvent *event)
void QSGCanvas::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QSGCanvas);
-
+
#ifdef MOUSE_DEBUG
qWarning() << "QSGCanvas::mouseReleaseEvent()" << event->pos() << event->button() << event->buttons();
#endif
@@ -1090,7 +1090,7 @@ void QSGCanvas::mouseReleaseEvent(QMouseEvent *event)
void QSGCanvas::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_D(QSGCanvas);
-
+
#ifdef MOUSE_DEBUG
qWarning() << "QSGCanvas::mouseDoubleClickEvent()" << event->pos() << event->button() << event->buttons();
#endif
@@ -1104,7 +1104,7 @@ void QSGCanvas::mouseDoubleClickEvent(QMouseEvent *event)
else
event->ignore();
return;
- }
+ }
d->deliverMouseEvent(&sceneEvent);
event->setAccepted(sceneEvent.isAccepted());
@@ -1129,7 +1129,7 @@ bool QSGCanvasPrivate::sendHoverEvent(QEvent::Type type, QSGItem *item,
void QSGCanvas::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QSGCanvas);
-
+
#ifdef MOUSE_DEBUG
qWarning() << "QSGCanvas::mouseMoveEvent()" << event->pos() << event->button() << event->buttons();
#endif
@@ -1173,7 +1173,7 @@ bool QSGCanvasPrivate::deliverHoverEvent(QSGItem *item, const QPointF &scenePos,
QList<QSGItem *> children = itemPrivate->paintOrderChildItems();
for (int ii = children.count() - 1; ii >= 0; --ii) {
QSGItem *child = children.at(ii);
- if (!child->isEnabled())
+ if (!child->isVisible() || !child->isEnabled())
continue;
if (deliverHoverEvent(child, scenePos, lastScenePos, modifiers, accepted))
return true;
@@ -1186,38 +1186,36 @@ bool QSGCanvasPrivate::deliverHoverEvent(QSGItem *item, const QPointF &scenePos,
//move
accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted);
} else {
- QList<QSGItem*> parents;
+ QList<QSGItem *> itemsToHover;
QSGItem* parent = item;
- parents << item;
+ itemsToHover << item;
while ((parent = parent->parentItem()))
- parents << parent;
+ itemsToHover << parent;
- //exit from previous (excepting ancestors)
- while (!hoverItems.isEmpty() && !parents.contains(hoverItems[0])){
+ // Leaving from previous hovered items until we reach the item or one of its ancestors.
+ while (!hoverItems.isEmpty() && !itemsToHover.contains(hoverItems[0])) {
sendHoverEvent(QEvent::HoverLeave, hoverItems[0], scenePos, lastScenePos, modifiers, accepted);
hoverItems.removeFirst();
}
if (!hoverItems.isEmpty() && hoverItems[0] == item){//Not entering a new Item
+ // ### Shouldn't we send moves for the parent items as well?
accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted);
} else {
- //enter any ancestors that also wish to be hovered and aren't
+ // Enter items that are not entered yet.
int startIdx = -1;
if (!hoverItems.isEmpty())
- startIdx = parents.indexOf(hoverItems[0]);
+ startIdx = itemsToHover.indexOf(hoverItems[0]) - 1;
if (startIdx == -1)
- startIdx = parents.count() - 1;
+ startIdx = itemsToHover.count() - 1;
for (int i = startIdx; i >= 0; i--) {
- if (QSGItemPrivate::get(parents[i])->hoverEnabled) {
- hoverItems.prepend(parents[i]);
- sendHoverEvent(QEvent::HoverEnter, parents[i], scenePos, lastScenePos, modifiers, accepted);
+ QSGItem *itemToHover = itemsToHover[i];
+ if (QSGItemPrivate::get(itemToHover)->hoverEnabled) {
+ hoverItems.prepend(itemToHover);
+ sendHoverEvent(QEvent::HoverEnter, itemToHover, scenePos, lastScenePos, modifiers, accepted);
}
}
-
- //enter new item
- hoverItems.prepend(item);
- accepted = sendHoverEvent(QEvent::HoverEnter, item, scenePos, lastScenePos, modifiers, accepted);
}
}
return true;
@@ -1505,17 +1503,17 @@ bool QSGCanvasPrivate::sendFilteredMouseEvent(QSGItem *target, QSGItem *item, QG
return true;
QSGItemPrivate *targetPrivate = QSGItemPrivate::get(target);
- if (targetPrivate->filtersChildMouseEvents)
+ if (targetPrivate->filtersChildMouseEvents)
if (target->childMouseEventFilter(item, event))
return true;
return false;
}
-bool QSGCanvas::sendEvent(QSGItem *item, QEvent *e)
-{
+bool QSGCanvas::sendEvent(QSGItem *item, QEvent *e)
+{
Q_D(QSGCanvas);
-
+
if (!item) {
qWarning("QSGCanvas::sendEvent: Cannot send event to a null item");
return false;
@@ -1549,7 +1547,7 @@ bool QSGCanvas::sendEvent(QSGItem *item, QEvent *e)
case QEvent::GraphicsSceneMouseRelease:
case QEvent::GraphicsSceneMouseDoubleClick:
case QEvent::GraphicsSceneMouseMove:
- // XXX todo - should sendEvent be doing this? how does it relate to forwarded events?
+ // XXX todo - should sendEvent be doing this? how does it relate to forwarded events?
{
QGraphicsSceneMouseEvent *se = static_cast<QGraphicsSceneMouseEvent *>(e);
if (!d->sendFilteredMouseEvent(item->parentItem(), item, se)) {
@@ -1581,7 +1579,7 @@ bool QSGCanvas::sendEvent(QSGItem *item, QEvent *e)
break;
}
- return false;
+ return false;
}
void QSGCanvasPrivate::cleanupNodes()
@@ -1626,12 +1624,12 @@ void QSGCanvasPrivate::updateDirtyNode(QSGItem *item)
itemPriv->dirtyAttributes = 0;
if ((dirty & QSGItemPrivate::TransformUpdateMask) ||
- (dirty & QSGItemPrivate::Size && itemPriv->origin != QSGItem::TopLeft &&
+ (dirty & QSGItemPrivate::Size && itemPriv->origin != QSGItem::TopLeft &&
(itemPriv->scale != 1. || itemPriv->rotation != 0.))) {
QMatrix4x4 matrix;
- if (itemPriv->x != 0. || itemPriv->y != 0.)
+ if (itemPriv->x != 0. || itemPriv->y != 0.)
matrix.translate(itemPriv->x, itemPriv->y);
for (int ii = itemPriv->transforms.count() - 1; ii >= 0; --ii)
@@ -1779,10 +1777,10 @@ void QSGCanvasPrivate::updateDirtyNode(QSGItem *item)
if (dirty & QSGItemPrivate::ContentUpdateMask) {
if (itemPriv->flags & QSGItem::ItemHasContents) {
- updatePaintNodeData.transformNode = itemPriv->itemNode();
+ updatePaintNodeData.transformNode = itemPriv->itemNode();
itemPriv->paintNode = item->updatePaintNode(itemPriv->paintNode, &updatePaintNodeData);
- Q_ASSERT(itemPriv->paintNode == 0 ||
+ Q_ASSERT(itemPriv->paintNode == 0 ||
itemPriv->paintNode->parent() == 0 ||
itemPriv->paintNode->parent() == itemPriv->childContainerNode());
@@ -1957,7 +1955,7 @@ void QSGCanvasRenderThread::run()
} else {
makeCurrent();
}
-
+
while (!shouldExit) {
lock();
diff --git a/src/declarative/items/qsgpositioners.cpp b/src/declarative/items/qsgpositioners.cpp
index fca0aa1877..0401494d3b 100644
--- a/src/declarative/items/qsgpositioners.cpp
+++ b/src/declarative/items/qsgpositioners.cpp
@@ -93,6 +93,9 @@ QSGBasePositioner::QSGBasePositioner(PositionerType at, QSGItem *parent)
for the child items. Depending on the chosen type, only x or y changes will be applied.
Note that the subclass is responsible for adding the spacing in between items.
+
+ Positioning is usually delayed until before a frame is rendered, to batch multiple repositioning
+ changes into one calculation.
*/
QSGBasePositioner::QSGBasePositioner(QSGBasePositionerPrivate &dd, PositionerType at, QSGItem *parent)
@@ -110,6 +113,13 @@ QSGBasePositioner::~QSGBasePositioner()
positionedItems.clear();
}
+void QSGBasePositioner::updatePolish()
+{
+ Q_D(QSGBasePositioner);
+ if (d->positioningDirty)
+ prePositioning();
+}
+
int QSGBasePositioner::spacing() const
{
Q_D(const QSGBasePositioner);
@@ -122,7 +132,7 @@ void QSGBasePositioner::setSpacing(int s)
if (s==d->spacing)
return;
d->spacing = s;
- prePositioning();
+ d->setPositioningDirty();
emit spacingChanged();
}
@@ -169,7 +179,7 @@ void QSGBasePositioner::itemChange(ItemChange change, const ItemChangeData &valu
{
Q_D(QSGBasePositioner);
if (change == ItemChildAddedChange){
- prePositioning();
+ d->setPositioningDirty();
} else if (change == ItemChildRemovedChange) {
QSGItem *child = value.item;
QSGBasePositioner::PositionedItem posItem(child);
@@ -178,7 +188,7 @@ void QSGBasePositioner::itemChange(ItemChange change, const ItemChangeData &valu
d->unwatchChanges(child);
positionedItems.remove(idx);
}
- prePositioning();
+ d->setPositioningDirty();
}
QSGItem::itemChange(change, value);
@@ -193,7 +203,7 @@ void QSGBasePositioner::prePositioning()
if (d->doingPositioning)
return;
- d->queuedPositioning = false;
+ d->positioningDirty = false;
d->doingPositioning = true;
//Need to order children by creation order modified by stacking order
QList<QSGItem *> children = childItems();
@@ -463,6 +473,10 @@ void QSGPositionerAttached::setIsLastItem(bool isLastItem)
Items with a width or height of 0 will not be positioned.
+ Positioning is batched and syncronized with painting to reduce the number of
+ calculations needed. This means that positioners may not reposition items immediately
+ when changes occur, but it will have moved by the next frame.
+
\sa Row, Grid, Flow, Positioner, {declarative/positioners}{Positioners example}
*/
/*!
@@ -607,6 +621,10 @@ void QSGColumn::reportConflictingAnchors()
Items with a width or height of 0 will not be positioned.
+ Positioning is batched and syncronized with painting to reduce the number of
+ calculations needed. This means that positioners may not reposition items immediately
+ when changes occur, but it will have moved by the next frame.
+
\sa Column, Grid, Flow, Positioner, {declarative/positioners}{Positioners example}
*/
/*!
@@ -838,6 +856,10 @@ void QSGRow::reportConflictingAnchors()
Items with a width or height of 0 will not be positioned.
+ Positioning is batched and syncronized with painting to reduce the number of
+ calculations needed. This means that positioners may not reposition items immediately
+ when changes occur, but it will have moved by the next frame.
+
\sa Flow, Row, Column, Positioner, {declarative/positioners}{Positioners example}
*/
/*!
@@ -1265,6 +1287,10 @@ void QSGGrid::reportConflictingAnchors()
Items with a width or height of 0 will not be positioned.
+ Positioning is batched and syncronized with painting to reduce the number of
+ calculations needed. This means that positioners may not reposition items immediately
+ when changes occur, but it will have moved by the next frame.
+
\sa Column, Row, Grid, Positioner, {declarative/positioners}{Positioners example}
*/
/*!
diff --git a/src/declarative/items/qsgpositioners_p.h b/src/declarative/items/qsgpositioners_p.h
index 7200b6da8d..f8711251d3 100644
--- a/src/declarative/items/qsgpositioners_p.h
+++ b/src/declarative/items/qsgpositioners_p.h
@@ -121,6 +121,8 @@ protected:
virtual void itemChange(ItemChange, const ItemChangeData &);
void finishApplyTransitions();
+ virtual void updatePolish();
+
Q_SIGNALS:
void spacingChanged();
void moveChanged();
diff --git a/src/declarative/items/qsgpositioners_p_p.h b/src/declarative/items/qsgpositioners_p_p.h
index a29982b1b7..3c1185378b 100644
--- a/src/declarative/items/qsgpositioners_p_p.h
+++ b/src/declarative/items/qsgpositioners_p_p.h
@@ -74,7 +74,7 @@ class QSGBasePositionerPrivate : public QSGImplicitSizeItemPrivate, public QSGIt
public:
QSGBasePositionerPrivate()
: spacing(0), type(QSGBasePositioner::None)
- , moveTransition(0), addTransition(0), queuedPositioning(false)
+ , moveTransition(0), addTransition(0), positioningDirty(false)
, doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight)
{
}
@@ -97,25 +97,23 @@ public:
void watchChanges(QSGItem *other);
void unwatchChanges(QSGItem* other);
- bool queuedPositioning : 1;
+ void setPositioningDirty() {
+ Q_Q(QSGBasePositioner);
+ if (!positioningDirty) {
+ positioningDirty = true;
+ q->polish();
+ }
+ }
+
+ bool positioningDirty : 1;
bool doingPositioning : 1;
bool anchorConflict : 1;
Qt::LayoutDirection layoutDirection;
- void schedulePositioning()
- {
- Q_Q(QSGBasePositioner);
- if(!queuedPositioning){
- QTimer::singleShot(0,q,SLOT(prePositioning()));
- queuedPositioning = true;
- }
- }
-
void mirrorChange() {
- Q_Q(QSGBasePositioner);
if (type != QSGBasePositioner::Vertical)
- q->prePositioning();
+ setPositioningDirty();
}
bool isLeftToRight() const {
if (type == QSGBasePositioner::Vertical)
@@ -127,26 +125,18 @@ public:
virtual void itemSiblingOrderChanged(QSGItem* other)
{
Q_UNUSED(other);
- //Delay is due to many children often being reordered at once
- //And we only want to reposition them all once
- schedulePositioning();
+ setPositioningDirty();
}
void itemGeometryChanged(QSGItem *, const QRectF &newGeometry, const QRectF &oldGeometry)
{
- Q_Q(QSGBasePositioner);
if (newGeometry.size() != oldGeometry.size())
- q->prePositioning();
+ setPositioningDirty();
}
virtual void itemVisibilityChanged(QSGItem *)
{
- schedulePositioning();
- }
- virtual void itemOpacityChanged(QSGItem *)
- {
- Q_Q(QSGBasePositioner);
- q->prePositioning();
+ setPositioningDirty();
}
void itemDestroyed(QSGItem *item)
diff --git a/src/declarative/items/qsgshadereffect.cpp b/src/declarative/items/qsgshadereffect.cpp
index ff131509f3..b81e7f15af 100644
--- a/src/declarative/items/qsgshadereffect.cpp
+++ b/src/declarative/items/qsgshadereffect.cpp
@@ -98,7 +98,7 @@ QSGShaderEffectItem::QSGShaderEffectItem(QSGItem *parent)
/*!
\qmlclass ShaderEffect QSGShaderEffect
- \since 5.0
+ \inqmlmodule QtQuick 2
\ingroup qml-basic-visual-elements
\brief The ShaderEffect element applies custom shaders to a rectangle.
\inherits Item
@@ -214,7 +214,7 @@ void QSGShaderEffect::componentComplete()
}
/*!
- \qmlproperty string ShaderEffect::fragmentShader
+ \qmlproperty string QtQuick2::ShaderEffect::fragmentShader
This property holds the fragment shader's GLSL source code.
The default shader passes the texture coordinate along to the fragment
@@ -234,7 +234,7 @@ void QSGShaderEffect::setFragmentShader(const QByteArray &code)
}
/*!
- \qmlproperty string ShaderEffect::vertexShader
+ \qmlproperty string QtQuick2::ShaderEffect::vertexShader
This property holds the vertex shader's GLSL source code.
The default shader expects the texture coordinate to be passed from the
@@ -255,7 +255,7 @@ void QSGShaderEffect::setVertexShader(const QByteArray &code)
}
/*!
- \qmlproperty bool ShaderEffect::blending
+ \qmlproperty bool QtQuick2::ShaderEffect::blending
If this property is true, the output from the \l fragmentShader is blended
with the background using source-over blend mode. If false, the background
@@ -275,7 +275,7 @@ void QSGShaderEffect::setBlending(bool enable)
}
/*!
- \qmlproperty size ShaderEffect::mesh
+ \qmlproperty size QtQuick2::ShaderEffect::mesh
This property holds the mesh resolution. The default resolution is 1x1
which is the minimum and corresponds to a mesh with four vertices.
@@ -358,7 +358,7 @@ void QSGShaderEffect::setMesh(const QVariant &mesh)
}
/*!
- \qmlproperty enumeration ShaderEffect::cullMode
+ \qmlproperty enumeration QtQuick2::ShaderEffect::cullMode
This property defines which sides of the element should be visible.
diff --git a/src/declarative/items/qsgshadereffectsource.cpp b/src/declarative/items/qsgshadereffectsource.cpp
index 4035608a6e..bb55af524b 100644
--- a/src/declarative/items/qsgshadereffectsource.cpp
+++ b/src/declarative/items/qsgshadereffectsource.cpp
@@ -406,6 +406,14 @@ void QSGShaderEffectTexture::grab()
markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
}
+QImage QSGShaderEffectTexture::toImage() const
+{
+ if (m_fbo)
+ return m_fbo->toImage();
+
+ return QImage();
+}
+
/*!
\qmlclass ShaderEffectSource QSGShaderEffectSource
\since 5.0
diff --git a/src/declarative/items/qsgshadereffectsource_p.h b/src/declarative/items/qsgshadereffectsource_p.h
index 6cb76ddba4..77cb412884 100644
--- a/src/declarative/items/qsgshadereffectsource_p.h
+++ b/src/declarative/items/qsgshadereffectsource_p.h
@@ -117,6 +117,7 @@ public:
void scheduleUpdate();
void scheduleForCleanup();
+ QImage toImage() const;
Q_SIGNALS:
void textureChanged();
diff --git a/src/declarative/items/qsgview.cpp b/src/declarative/items/qsgview.cpp
index 48b3074363..236fd4ec1f 100644
--- a/src/declarative/items/qsgview.cpp
+++ b/src/declarative/items/qsgview.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qsgview.h"
+#include "qsgview_p.h"
#include "qsgcanvas_p.h"
#include "qsgitem_p.h"
@@ -52,45 +53,13 @@
#include <private/qdeclarativeengine_p.h>
#include <QtCore/qbasictimer.h>
-// XXX todo - This whole class should probably be merged with QDeclarativeView for
+
+// XXX todo - This whole class should probably be merged with QDeclarativeView for
// maximum seamlessness
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
-class QSGViewPrivate : public QSGCanvasPrivate,
- public QSGItemChangeListener
-{
- Q_DECLARE_PUBLIC(QSGView)
-public:
- QSGViewPrivate();
- ~QSGViewPrivate();
-
- void execute();
- void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
- void initResize();
- void updateSize();
- void setRootObject(QObject *);
-
- void init();
-
- QSize rootObjectSize() const;
-
- QPointer<QSGItem> root;
-
- QUrl source;
-
- QDeclarativeEngine engine;
- QDeclarativeComponent *component;
- QBasicTimer resizetimer;
-
- QSGView::ResizeMode resizeMode;
- QSize initialSize;
- QElapsedTimer frameTimer;
-
- bool resized;
-};
-
void QSGViewPrivate::init()
{
QDeclarativeEnginePrivate::get(&engine)->sgContext = QSGCanvasPrivate::context;
@@ -103,8 +72,8 @@ QSGViewPrivate::QSGViewPrivate()
{
}
-QSGViewPrivate::~QSGViewPrivate()
-{
+QSGViewPrivate::~QSGViewPrivate()
+{
QDeclarativeInspectorService::instance()->removeView(q_func());
delete root;
@@ -126,7 +95,7 @@ void QSGViewPrivate::execute()
if (!component->isLoading()) {
q->continueExecute();
} else {
- QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
+ QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
q, SLOT(continueExecute()));
}
}
@@ -397,9 +366,9 @@ QSGItem *QSGView::rootObject() const
void QSGView::resizeEvent(QResizeEvent *e)
{
Q_D(QSGView);
- if (d->resizeMode == SizeRootObjectToView)
+ if (d->resizeMode == SizeRootObjectToView)
d->updateSize();
-
+
QSGCanvas::resizeEvent(e);
}
diff --git a/tests/auto/declarative/qdeclarativedebughelper/private_headers/qdeclarativedebughelper_p.h b/src/declarative/items/qsgview_p.h
index c08f6fd639..3f8d69e8c0 100644
--- a/tests/auto/declarative/qdeclarativedebughelper/private_headers/qdeclarativedebughelper_p.h
+++ b/src/declarative/items/qsgview_p.h
@@ -39,33 +39,70 @@
**
****************************************************************************/
-#ifndef QDECLARATIVEDEBUGHELPER_P_H
-#define QDECLARATIVEDEBUGHELPER_P_H
+#ifndef QSGVIEW_P_H
+#define QSGVIEW_P_H
-#include <QtCore/qglobal.h>
+#include "qsgview.h"
+
+#include <QtCore/qurl.h>
+#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qpointer.h>
+#include <QtDeclarative/qsgview.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/private/qsgcanvas_p.h>
+
+#include "qsgitemchangelistener_p.h"
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-class QJSEngine;
-class QDeclarativeEngine;
+QT_MODULE(Declarative)
+
+class QDeclarativeContext;
+class QDeclarativeError;
+class QSGItem;
+class QDeclarativeComponent;
-// Helper methods to access private API through a stable interface
-// This is used in the qmljsdebugger library of QtCreator.
-class Q_DECLARATIVE_EXPORT QDeclarativeDebugHelper
+class QSGViewPrivate : public QSGCanvasPrivate,
+ public QSGItemChangeListener
{
+ Q_DECLARE_PUBLIC(QSGView)
public:
- static QJSEngine *getScriptEngine(QDeclarativeEngine *engine);
- static void setAnimationSlowDownFactor(qreal factor);
+ static QSGViewPrivate* get(QSGView *view) { return view->d_func(); }
+ static const QSGViewPrivate* get(const QSGView *view) { return view->d_func(); }
+
+ QSGViewPrivate();
+ ~QSGViewPrivate();
+
+ void execute();
+ void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
+ void initResize();
+ void updateSize();
+ void setRootObject(QObject *);
+
+ void init();
+
+ QSize rootObjectSize() const;
+
+ QPointer<QSGItem> root;
+
+ QUrl source;
+
+ QDeclarativeEngine engine;
+ QDeclarativeComponent *component;
+ QBasicTimer resizetimer;
+
+ QSGView::ResizeMode resizeMode;
+ QSize initialSize;
+ QElapsedTimer frameTimer;
- // Enables remote debugging functionality
- // Only use this for debugging in a safe environment!
- static void enableDebugging();
+ bool resized;
};
QT_END_NAMESPACE
QT_END_HEADER
-#endif // QDECLARATIVEDEBUGHELPER_P_H
+#endif // QSGVIEW_P_H
diff --git a/src/declarative/items/qsgvisualitemmodel.cpp b/src/declarative/items/qsgvisualitemmodel.cpp
index 5dfe01dd2b..4dd508d0aa 100644
--- a/src/declarative/items/qsgvisualitemmodel.cpp
+++ b/src/declarative/items/qsgvisualitemmodel.cpp
@@ -1511,7 +1511,7 @@ void QSGVisualDataModel::_q_rowsMoved(const QModelIndex &sourceParent, int sourc
Q_D(QSGVisualDataModel);
const int count = sourceEnd - sourceStart + 1;
if (destinationParent == d->m_root && sourceParent == d->m_root) {
- _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow-1, count);
+ _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow-count, count);
} else if (sourceParent == d->m_root) {
_q_itemsRemoved(sourceStart, count);
} else if (destinationParent == d->m_root) {
diff --git a/src/declarative/particles/defaultshaders/imagevertex.shader b/src/declarative/particles/defaultshaders/imagevertex.shader
index e1033c9165..9967ef85a2 100644
--- a/src/declarative/particles/defaultshaders/imagevertex.shader
+++ b/src/declarative/particles/defaultshaders/imagevertex.shader
@@ -75,8 +75,9 @@ void main() {
currentSize = currentSize * sizetable[int(floor(t*64.))];
fade = fade * opacitytable[int(floor(t*64.))];
#endif
+
if (entry == 1.)
- fade = fadeIn * fadeOut;
+ fade = fade * fadeIn * fadeOut;
else if(entry == 2.)
currentSize = currentSize * fadeIn * fadeOut;
diff --git a/src/declarative/particles/qsgcustomparticle.cpp b/src/declarative/particles/qsgcustomparticle.cpp
index db544d20e8..12d32a27b4 100644
--- a/src/declarative/particles/qsgcustomparticle.cpp
+++ b/src/declarative/particles/qsgcustomparticle.cpp
@@ -45,17 +45,17 @@
QT_BEGIN_NAMESPACE
-//TODO: Can we make the code such that you don't have to copy the whole vertex shader just to add one little calculation?
//Includes comments because the code isn't self explanatory
-static const char qt_particles_default_vertex_code[] =
+static const char qt_particles_template_vertex_code[] =
"attribute highp vec2 vPos; \n"
"attribute highp vec2 vTex; \n"
"attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize \n"
"attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration \n"
+ "attribute highp float r; \n"
"uniform highp mat4 qt_Matrix; \n"
"uniform highp float timestamp; \n"
"varying highp vec2 fTex; \n"
- "void main() { \n"
+ "void defaultMain() { \n"
" fTex = vTex; \n"
" highp float size = vData.z; \n"
" highp float endSize = vData.w; \n"
@@ -68,6 +68,10 @@ static const char qt_particles_default_vertex_code[] =
" + vVec.xy * t * vData.y // apply speed vector.. \n"
" + 0.5 * vVec.zw * pow(t * vData.y, 2.); \n"
" gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1); \n"
+ "}\n";
+static const char qt_particles_default_vertex_code[] =
+ "void main() { \n"
+ " defaultMain(); \n"
"}";
static const char qt_particles_default_fragment_code[] =//TODO: Default frag requires source?
@@ -78,9 +82,6 @@ static const char qt_particles_default_fragment_code[] =//TODO: Default frag req
" gl_FragColor = texture2D(source, fTex) * qt_Opacity; \n"
"}";
-static const char qt_position_attribute_name[] = "qt_Vertex";
-static const char qt_texcoord_attribute_name[] = "qt_MultiTexCoord0";
-
static QSGGeometry::Attribute PlainParticle_Attributes[] = {
{ 0, 2, GL_FLOAT }, // Position
{ 1, 2, GL_FLOAT }, // TexCoord
@@ -157,8 +158,9 @@ void QSGCustomParticle::componentComplete()
\qmlproperty string QtQuick.Particles2::CustomParticle::fragmentShader
This property holds the fragment shader's GLSL source code.
- The default shader passes the texture coordinate along to the fragment
- shader as "varying highp vec2 qt_TexCoord0".
+ The default shader expects the texture coordinate to be passed from the
+ vertex shader as "varying highp vec2 fTex", and it samples from a
+ sampler2D named "source".
*/
void QSGCustomParticle::setFragmentShader(const QByteArray &code)
@@ -176,9 +178,41 @@ void QSGCustomParticle::setFragmentShader(const QByteArray &code)
\qmlproperty string QtQuick.Particles2::CustomParticle::vertexShader
This property holds the vertex shader's GLSL source code.
- The default shader expects the texture coordinate to be passed from the
- vertex shader as "varying highp vec2 qt_TexCoord0", and it samples from a
- sampler2D named "source".
+
+ The default shader passes the texture coordinate along to the fragment
+ shader as "varying highp vec2 fTex".
+
+ To aid writing a particle vertex shader, the following GLSL code is prepended
+ to your vertex shader:
+ \code
+ attribute highp vec2 vPos;
+ attribute highp vec2 vTex;
+ attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
+ attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
+ attribute highp float r;
+ uniform highp mat4 qt_Matrix;
+ uniform highp float timestamp;
+ varying highp vec2 fTex;
+ void defaultMain() {
+ fTex = vTex;
+ highp float size = vData.z;
+ highp float endSize = vData.w;
+ highp float t = (timestamp - vData.x) / vData.y;
+ highp float currentSize = mix(size, endSize, t * t);
+ if (t < 0. || t > 1.)
+ currentSize = 0.;
+ highp vec2 pos = vPos
+ - currentSize / 2. + currentSize * vTex // adjust size
+ + vVec.xy * t * vData.y // apply speed vector..
+ + 0.5 * vVec.zw * pow(t * vData.y, 2.);
+ gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
+ }
+ \endcode
+
+ defaultMain() is the same code as in the default shader, you can call this for basic
+ particle functions and then add additional variables for custom effects. Note that
+ the vertex shader for particles is responsible for simulating the movement of particles
+ over time, the particle data itself only has the starting position and spawn time.
*/
void QSGCustomParticle::setVertexShader(const QByteArray &code)
@@ -311,6 +345,7 @@ void QSGCustomParticle::updateProperties()
vertexCode = qt_particles_default_vertex_code;
if (fragmentCode.isEmpty())
fragmentCode = qt_particles_default_fragment_code;
+ vertexCode = qt_particles_template_vertex_code + vertexCode;
m_source.attributeNames.clear();
m_source.attributeNames << "vPos" << "vTex" << "vData" << "vVec" << "r";
@@ -318,10 +353,6 @@ void QSGCustomParticle::updateProperties()
lookThroughShaderCode(vertexCode);
lookThroughShaderCode(fragmentCode);
- if (!m_source.attributeNames.contains(qt_position_attribute_name))
- qWarning("QSGCustomParticle: Missing reference to \'%s\'.", qt_position_attribute_name);
- if (!m_source.attributeNames.contains(qt_texcoord_attribute_name))
- qWarning("QSGCustomParticle: Missing reference to \'%s\'.", qt_texcoord_attribute_name);
if (!m_source.respectsMatrix)
qWarning("QSGCustomParticle: Missing reference to \'qt_Matrix\'.");
if (!m_source.respectsOpacity)
@@ -352,17 +383,13 @@ void QSGCustomParticle::lookThroughShaderCode(const QByteArray &code)
QByteArray name = re.cap(3).toLatin1(); // variable name
if (decl == "attribute") {
- if (!m_source.attributeNames.contains(name))//TODO: Can they add custom attributes?
+ if (!m_source.attributeNames.contains(name))
qWarning() << "Custom Particle: Unknown attribute " << name;
} else {
Q_ASSERT(decl == "uniform");//TODO: Shouldn't assert
if (name == "qt_Matrix") {
m_source.respectsMatrix = true;
- } else if (name == "qt_ModelViewProjectionMatrix") {
- // TODO: Remove after grace period.
- qWarning("ShaderEffect: qt_ModelViewProjectionMatrix is deprecated. Use qt_Matrix instead.");
- m_source.respectsMatrix = true;
} else if (name == "qt_Opacity") {
m_source.respectsOpacity = true;
} else if (name == "timestamp") {
@@ -443,7 +470,9 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNodes()
m_material = new QSGShaderEffectMaterialObject;
}
+ s.vertexCode = qt_particles_template_vertex_code + s.vertexCode;
m_material->setProgramSource(s);
+
foreach (const QString &str, m_particles){
int gIdx = m_system->m_groupIds[str];
int count = m_system->m_groupData[gIdx]->size();
diff --git a/src/declarative/particles/qsgimageparticle.cpp b/src/declarative/particles/qsgimageparticle.cpp
index 737b393de7..853a08a890 100644
--- a/src/declarative/particles/qsgimageparticle.cpp
+++ b/src/declarative/particles/qsgimageparticle.cpp
@@ -258,7 +258,7 @@ public:
m_animcount_id = program()->uniformLocation("animcount");
m_entry_id = program()->uniformLocation("entry");
m_sizetable_id = program()->uniformLocation("sizetable");
- m_opacitytable_id = program()->uniformLocation("sizetable");
+ m_opacitytable_id = program()->uniformLocation("opacitytable");
}
void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) {
@@ -432,7 +432,7 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size)
{
if (img.isNull()){
for (int i=0; i<size; i++)
- array[i] = 1;
+ array[i] = 1.0;
return;
}
QImage scaled = img.scaled(size,1);
diff --git a/src/declarative/particles/qsgparticleaffector.cpp b/src/declarative/particles/qsgparticleaffector.cpp
index 4cb3e49403..331310625f 100644
--- a/src/declarative/particles/qsgparticleaffector.cpp
+++ b/src/declarative/particles/qsgparticleaffector.cpp
@@ -42,6 +42,7 @@
#include "qsgparticleaffector_p.h"
#include <QDebug>
QT_BEGIN_NAMESPACE
+
/*!
\qmlclass Affector QSGParticleAffector
\inqmlmodule QtQuick.Particles 2
@@ -159,8 +160,10 @@ void QSGParticleAffector::affectSystem(qreal dt)
if ((m_onceOff && m_onceOffed.contains(qMakePair(d->group, d->index)))
|| !d->stillAlive())
continue;
- //Need to have previous location for affected. if signal || shape might be faster?
- QPointF curPos = QPointF(d->curX(), d->curY());
+ //Need to have previous location for affected anyways
+ QPointF curPos;
+ if (m_signal || (width() && height()))
+ curPos = QPointF(d->curX(), d->curY());
if (width() == 0 || height() == 0
|| m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()),curPos)){
if (m_collisionParticles.isEmpty() || isColliding(d)){
@@ -181,8 +184,9 @@ void QSGParticleAffector::affectSystem(qreal dt)
bool QSGParticleAffector::affectParticle(QSGParticleData *d, qreal dt)
{
if (isAffectConnected()){
+ d->update = 0.0;
emit affectParticle(d->v8Value(), dt);
- return true;
+ return d->update == 1.0;
}
return m_signal;//If signalling, then we always 'null affect' it.
}
diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h
index 9f4020d041..abb7f52c31 100644
--- a/src/declarative/particles/qsgparticlesystem_p.h
+++ b/src/declarative/particles/qsgparticlesystem_p.h
@@ -202,6 +202,7 @@ public:
float r;
QSGItem* delegate;
int modelIndex;
+ float update;//Used by custom affectors
void debugDump();
bool stillAlive();
diff --git a/src/declarative/particles/qsgpointattractor.cpp b/src/declarative/particles/qsgpointattractor.cpp
index 1a3c3c25c5..21eaeaac12 100644
--- a/src/declarative/particles/qsgpointattractor.cpp
+++ b/src/declarative/particles/qsgpointattractor.cpp
@@ -65,21 +65,31 @@ bool QSGPointAttractorAffector::affectParticle(QSGParticleData *d, qreal dt)
{
if (m_strength == 0.0)
return false;
- qreal dx = m_y - d->curX();
- qreal dy = m_x - d->curY();
+ qreal dx = m_x - d->curX();
+ qreal dy = m_y - d->curY();
qreal r = sqrt((dx*dx) + (dy*dy));
qreal theta = atan2(dy,dx);
qreal ds = 0;
switch (m_proportionalToDistance){
+ case InverseQuadratic:
+ ds = (m_strength / qMax<qreal>(1.,r*r));
+ break;
+ case InverseLinear:
+ ds = (m_strength / qMax<qreal>(1.,r));
+ break;
case Quadratic:
- ds = (m_strength / qMax<qreal>(1.,r*r)) * dt;
+ ds = (m_strength * qMax<qreal>(1.,r*r));
break;
- case Linear://also default
- default:
- ds = (m_strength / qMax<qreal>(1.,r)) * dt;
+ case Linear:
+ ds = (m_strength * qMax<qreal>(1.,r));
+ break;
+ default: //also Constant
+ ds = m_strength;
}
+ ds *= dt;
dx = ds * cos(theta);
dy = ds * sin(theta);
+ qreal vx,vy;
switch (m_physics){
case Position:
d->x = (d->x + dx);
@@ -91,8 +101,10 @@ bool QSGPointAttractorAffector::affectParticle(QSGParticleData *d, qreal dt)
break;
case Velocity: //also default
default:
- d->setInstantaneousVX(d->vx + dx);
- d->setInstantaneousVY(d->vy + dy);
+ vx = d->curVX();
+ vy = d->curVY();
+ d->setInstantaneousVX(vx + dx);
+ d->setInstantaneousVY(vy + dy);
}
return true;
diff --git a/src/declarative/particles/qsgpointattractor_p.h b/src/declarative/particles/qsgpointattractor_p.h
index 95716483ed..298965a5c9 100644
--- a/src/declarative/particles/qsgpointattractor_p.h
+++ b/src/declarative/particles/qsgpointattractor_p.h
@@ -64,8 +64,11 @@ class QSGPointAttractorAffector : public QSGParticleAffector
public:
enum Proportion{
+ Constant,
Linear,
- Quadratic
+ Quadratic,
+ InverseLinear,
+ InverseQuadratic
};
enum PhysicsAffects {
diff --git a/src/declarative/particles/qsgv8particledata.cpp b/src/declarative/particles/qsgv8particledata.cpp
index b3ff482d8b..72c0b7c2de 100644
--- a/src/declarative/particles/qsgv8particledata.cpp
+++ b/src/declarative/particles/qsgv8particledata.cpp
@@ -150,6 +150,7 @@ FLOAT_GETTER_AND_SETTER(frameDuration)
FLOAT_GETTER_AND_SETTER(frameCount)
FLOAT_GETTER_AND_SETTER(animT)
FLOAT_GETTER_AND_SETTER(r)
+FLOAT_GETTER_AND_SETTER(update)
FAKE_FLOAT_GETTER_AND_SETTER(curX, curX, setInstantaneousX)
FAKE_FLOAT_GETTER_AND_SETTER(curVX, curVX, setInstantaneousVX)
FAKE_FLOAT_GETTER_AND_SETTER(curAX, curAX, setInstantaneousAX)
@@ -157,7 +158,7 @@ FAKE_FLOAT_GETTER_AND_SETTER(curY, curY, setInstantaneousY)
FAKE_FLOAT_GETTER_AND_SETTER(curVY, curVY, setInstantaneousVY)
FAKE_FLOAT_GETTER_AND_SETTER(curAY, curAY, setInstantaneousAY)
-//TODO: Non-floats (color) and special floats (curX) once basic floats are working well
+//TODO: Non-floats (color, update?) once floats are working well
QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine)
{
@@ -189,6 +190,7 @@ QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine)
FLOAT_REGISTER_ACCESSOR(ft, engine, frameCount);
FLOAT_REGISTER_ACCESSOR(ft, engine, animT);
FLOAT_REGISTER_ACCESSOR(ft, engine, r);
+ FLOAT_REGISTER_ACCESSOR(ft, engine, update);
FLOAT_REGISTER_ACCESSOR(ft, engine, curX);
FLOAT_REGISTER_ACCESSOR(ft, engine, curVX);
FLOAT_REGISTER_ACCESSOR(ft, engine, curAX);
diff --git a/src/declarative/qml/ftw/ftw.pri b/src/declarative/qml/ftw/ftw.pri
new file mode 100644
index 0000000000..545c47e3c6
--- /dev/null
+++ b/src/declarative/qml/ftw/ftw.pri
@@ -0,0 +1,23 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/qbitfield_p.h \
+ $$PWD/qintrusivelist_p.h \
+ $$PWD/qmetaobjectbuilder_p.h \
+ $$PWD/qpodvector_p.h \
+ $$PWD/qhashedstring_p.h \
+ $$PWD/qdeclarativerefcount_p.h \
+ $$PWD/qdeclarativepool_p.h \
+ $$PWD/qfieldlist_p.h \
+ $$PWD/qdeclarativeutils_p.h \
+ $$PWD/qfastmetabuilder_p.h \
+ $$PWD/qhashfield_p.h \
+
+SOURCES += \
+ $$PWD/qintrusivelist.cpp \
+ $$PWD/qmetaobjectbuilder.cpp \
+ $$PWD/qhashedstring.cpp \
+ $$PWD/qdeclarativerefcount.cpp \
+ $$PWD/qdeclarativepool.cpp \
+ $$PWD/qfastmetabuilder.cpp \
+
diff --git a/src/declarative/qml/qbitfield_p.h b/src/declarative/qml/ftw/qbitfield_p.h
index 67f578beda..67f578beda 100644
--- a/src/declarative/qml/qbitfield_p.h
+++ b/src/declarative/qml/ftw/qbitfield_p.h
diff --git a/src/declarative/qml/ftw/qdeclarativepool.cpp b/src/declarative/qml/ftw/qdeclarativepool.cpp
new file mode 100644
index 0000000000..94bb89bd46
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativepool.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativepool_p.h"
+
+// #define POOL_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+void QDeclarativePool::newpage()
+{
+#ifdef POOL_DEBUG
+ qWarning("QDeclarativePool: Allocating page");
+#endif
+
+ Page *page = (Page *)malloc(sizeof(Page));
+ page->header.next = _page;
+ page->header.free = page->memory;
+ _page = page;
+}
+
+void QDeclarativePool::clear()
+{
+#ifdef POOL_DEBUG
+ int count = 0;
+#endif
+
+ Class *c = _classList;
+ while (c) {
+ Class *n = c->_next;
+ c->_destroy(c);
+#ifdef POOL_DEBUG
+ ++count;
+#endif
+ c = n;
+ }
+
+#ifdef POOL_DEBUG
+ qWarning("QDeclarativePool: Destroyed %d objects", count);
+#endif
+
+ Page *p = _page;
+ while (p) {
+ Page *n = p->header.next;
+ free(p);
+ p = n;
+ }
+
+ _classList = 0;
+ _page = 0;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/ftw/qdeclarativepool_p.h b/src/declarative/qml/ftw/qdeclarativepool_p.h
new file mode 100644
index 0000000000..8935046cc3
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativepool_p.h
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEPOOL_P_H
+#define QDECLARATIVEPOOL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativePool
+{
+public:
+ // The class has a destructor that needs to be called
+ class Class {
+ public:
+ inline QDeclarativePool *pool() const;
+
+ private:
+ void *operator new(size_t);
+ void *operator new(size_t, void *m) { return m; }
+ friend class QDeclarativePool;
+
+ QDeclarativePool *_pool;
+ Class *_next;
+ void (*_destroy)(Class *);
+ };
+
+ // The class is plain old data and no destructor needs to
+ // be called
+ class POD {
+ public:
+ inline QDeclarativePool *pool() const;
+
+ private:
+ void *operator new(size_t);
+ void *operator new(size_t, void *m) { return m; }
+ friend class QDeclarativePool;
+
+ QDeclarativePool *_pool;
+ };
+
+ inline QDeclarativePool();
+ inline ~QDeclarativePool();
+
+ void clear();
+
+ template<typename T>
+ inline T *New();
+ template<typename T>
+ inline T *NewRaw();
+ template<typename T>
+ inline T *NewRawArray(int length);
+
+ inline QString *NewString(const QString &);
+ inline QByteArray *NewByteArray(const QByteArray &);
+
+ template<typename T>
+ struct List {
+ List() : m_length(0), m_data(0) {}
+ List(const List &o) : m_length(o.m_length), m_data(o.m_data) {}
+ List &operator=(const List &o) {
+ m_length = o.m_length;
+ m_data = o.m_data;
+ return *this;
+ }
+
+ int count() const {
+ return m_length;
+ }
+ int length() const {
+ return m_length;
+ }
+ const T &at(int index) const {
+ Q_ASSERT(index < m_length);
+ return m_data[index];
+ };
+ T &operator[](int index) {
+ Q_ASSERT(index < m_length);
+ return m_data[index];
+ };
+ private:
+ friend class QDeclarativePool;
+ List(T *d, int l) : m_length(l), m_data(d) {}
+ int m_length;
+ T *m_data;
+ };
+
+ template<typename T>
+ inline List<T> NewRawList(int length);
+
+private:
+ struct StringClass : public QString, public Class {
+ };
+ struct ByteArrayClass : public QByteArray, public Class {
+ };
+
+ inline void *allocate(int size);
+ void newpage();
+
+ template<typename T>
+ inline void initialize(POD *);
+ template<typename T>
+ inline void initialize(Class *);
+ template<typename T>
+ static void destroy(Class *c);
+
+ struct Page {
+ struct Header {
+ Page *next;
+ char *free;
+ } header;
+
+ static const int pageSize = 4 * 4096 - sizeof(Header);
+
+ char memory[pageSize];
+ };
+
+ Page *_page;
+ Class *_classList;
+};
+
+QDeclarativePool::QDeclarativePool()
+: _page(0), _classList(0)
+{
+}
+
+QDeclarativePool::~QDeclarativePool()
+{
+ clear();
+}
+
+template<typename T>
+T *QDeclarativePool::New()
+{
+ T *rv = new (allocate(sizeof(T))) T;
+ initialize<T>(rv);
+ rv->_pool = this;
+ return rv;
+}
+
+template<typename T>
+T *QDeclarativePool::NewRaw()
+{
+ return (T*)allocate(sizeof(T));
+}
+
+template<typename T>
+T *QDeclarativePool::NewRawArray(int length)
+{
+ return (T*)allocate(length * sizeof(T));
+}
+
+template<typename T>
+QDeclarativePool::List<T> QDeclarativePool::NewRawList(int length)
+{
+ return List<T>(NewRawArray<T>(length), length);
+}
+
+QString *QDeclarativePool::NewString(const QString &s)
+{
+ QString *rv = New<StringClass>();
+ *rv = s;
+ return rv;
+}
+
+QByteArray *QDeclarativePool::NewByteArray(const QByteArray &s)
+{
+ QByteArray *rv = New<ByteArrayClass>();
+ *rv = s;
+ return rv;
+}
+
+void *QDeclarativePool::allocate(int size)
+{
+ if (!_page || (_page->header.free + size) > (_page->memory + Page::pageSize))
+ newpage();
+
+ void *rv = _page->header.free;
+ _page->header.free += size + ((8 - size) & 7); // ensure 8 byte alignment;
+ return rv;
+}
+
+template<typename T>
+void QDeclarativePool::initialize(QDeclarativePool::POD *)
+{
+}
+
+template<typename T>
+void QDeclarativePool::initialize(QDeclarativePool::Class *c)
+{
+ c->_next = _classList;
+ c->_destroy = &destroy<T>;
+ _classList = c;
+}
+
+template<typename T>
+void QDeclarativePool::destroy(Class *c)
+{
+ static_cast<T *>(c)->~T();
+}
+
+QDeclarativePool *QDeclarativePool::Class::pool() const
+{
+ return _pool;
+}
+
+QDeclarativePool *QDeclarativePool::POD::pool() const
+{
+ return _pool;
+}
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEPOOL_P_H
+
diff --git a/src/declarative/qml/qdeclarativerefcount.cpp b/src/declarative/qml/ftw/qdeclarativerefcount.cpp
index a17d5b7142..a17d5b7142 100644
--- a/src/declarative/qml/qdeclarativerefcount.cpp
+++ b/src/declarative/qml/ftw/qdeclarativerefcount.cpp
diff --git a/src/declarative/qml/qdeclarativerefcount_p.h b/src/declarative/qml/ftw/qdeclarativerefcount_p.h
index 381327098c..381327098c 100644
--- a/src/declarative/qml/qdeclarativerefcount_p.h
+++ b/src/declarative/qml/ftw/qdeclarativerefcount_p.h
diff --git a/src/declarative/qml/ftw/qdeclarativeutils_p.h b/src/declarative/qml/ftw/qdeclarativeutils_p.h
new file mode 100644
index 0000000000..63e90012c2
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativeutils_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEUTIL_P_H
+#define QDECLARATIVEUTIL_P_H
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+namespace QDeclarativeUtils {
+
+inline bool isUpper(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= 'A' && c <= 'Z') || (c > 127 && QChar::category(c) == QChar::Letter_Uppercase));
+}
+
+inline bool isLower(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= 'a' && c <= 'z') || (c > 127 && QChar::category(c) == QChar::Letter_Lowercase));
+}
+
+inline bool isLetter(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c > 127 && qc.isLetter()));
+}
+
+inline bool isDigit(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= '0' && c <= '9') || (c > 127 && qc.isDigit()));
+}
+
+inline bool isLetterOrNumber(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c > 127 && qc.isLetterOrNumber()));
+}
+
+inline bool isSpace(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return (c == 0x20 || (c >= 0x09 && c <= 0x0D) || c == 0x85 || (c > 127 && qc.isSpace()));
+}
+
+} // namespace QDeclarative
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEUTIL_P_H
diff --git a/src/declarative/qml/ftw/qfastmetabuilder.cpp b/src/declarative/qml/ftw/qfastmetabuilder.cpp
new file mode 100644
index 0000000000..20c5e08499
--- /dev/null
+++ b/src/declarative/qml/ftw/qfastmetabuilder.cpp
@@ -0,0 +1,371 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfastmetabuilder_p.h"
+
+QT_BEGIN_NAMESPACE
+
+struct QFastMetaBuilderHeader
+{
+ int fieldCount;
+};
+
+struct QMetaObjectPrivate
+{
+ int revision;
+ int className;
+ int classInfoCount, classInfoData;
+ int methodCount, methodData;
+ int propertyCount, propertyData;
+ int enumeratorCount, enumeratorData;
+ int constructorCount, constructorData; //since revision 2
+ int flags; //since revision 3
+ int signalCount; //since revision 4
+};
+
+enum MetaObjectFlag {
+ DynamicMetaObject = 0x01
+};
+
+enum PropertyFlags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ Resettable = 0x00000004,
+ EnumOrFlag = 0x00000008,
+ StdCppSet = 0x00000100,
+// Override = 0x00000200,
+ Constant = 0x00000400,
+ Final = 0x00000800,
+ Designable = 0x00001000,
+ ResolveDesignable = 0x00002000,
+ Scriptable = 0x00004000,
+ ResolveScriptable = 0x00008000,
+ Stored = 0x00010000,
+ ResolveStored = 0x00020000,
+ Editable = 0x00040000,
+ ResolveEditable = 0x00080000,
+ User = 0x00100000,
+ ResolveUser = 0x00200000,
+ Notify = 0x00400000,
+ Revisioned = 0x00800000
+};
+
+enum MethodFlags {
+ AccessPrivate = 0x00,
+ AccessProtected = 0x01,
+ AccessPublic = 0x02,
+ AccessMask = 0x03, //mask
+
+ MethodMethod = 0x00,
+ MethodSignal = 0x04,
+ MethodSlot = 0x08,
+ MethodConstructor = 0x0c,
+ MethodTypeMask = 0x0c,
+
+ MethodCompatibility = 0x10,
+ MethodCloned = 0x20,
+ MethodScriptable = 0x40,
+ MethodRevisioned = 0x80
+};
+
+#define FMBHEADER_FIELD_COUNT 1
+
+#define HEADER_FIELD_COUNT 14
+#define CLASSINFO_FIELD_COUNT 2
+#define METHOD_FIELD_COUNT 5
+#define PROPERTY_FIELD_COUNT 3
+#define PROPERTY_NOTIFY_FIELD_COUNT 1
+
+static inline uint *fieldPointer(QByteArray &data)
+{ return reinterpret_cast<uint *>(data.data()) + FMBHEADER_FIELD_COUNT; }
+
+static inline const uint *fieldPointer(const QByteArray &data)
+{ return reinterpret_cast<const uint *>(data.constData()) + FMBHEADER_FIELD_COUNT; }
+
+static inline QMetaObjectPrivate *priv(QByteArray &data)
+{ return reinterpret_cast<QMetaObjectPrivate*>(fieldPointer(data)); }
+
+static inline const QMetaObjectPrivate *priv(const QByteArray &data)
+{ return reinterpret_cast<const QMetaObjectPrivate*>(fieldPointer(data)); }
+
+static inline QFastMetaBuilderHeader *header(QByteArray &data)
+{ return reinterpret_cast<QFastMetaBuilderHeader*>(data.data()); }
+
+static inline const QFastMetaBuilderHeader *header(const QByteArray &data)
+{ return reinterpret_cast<const QFastMetaBuilderHeader*>(data.constData()); }
+
+QFastMetaBuilder::QFastMetaBuilder()
+: m_zeroPtr(0), m_stringData(0), m_stringDataLength(0), m_stringDataAllocated(0)
+{
+}
+
+QFastMetaBuilder::~QFastMetaBuilder()
+{
+}
+
+QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength,
+ int propertyCount, int methodCount,
+ int signalCount, int classInfoCount)
+{
+ Q_ASSERT(m_data.isEmpty());
+ Q_ASSERT(classNameLength > 0);
+ Q_ASSERT(propertyCount >= 0);
+ Q_ASSERT(methodCount >= 0);
+ Q_ASSERT(signalCount >= 0);
+ Q_ASSERT(classInfoCount >= 0);
+
+ int fieldCount = FMBHEADER_FIELD_COUNT +
+ HEADER_FIELD_COUNT +
+ propertyCount * (PROPERTY_FIELD_COUNT + PROPERTY_NOTIFY_FIELD_COUNT) +
+ methodCount * (METHOD_FIELD_COUNT) +
+ signalCount * (METHOD_FIELD_COUNT) +
+ classInfoCount * CLASSINFO_FIELD_COUNT;
+
+ m_data.resize(fieldCount * sizeof(uint) + classNameLength + 1);
+ m_stringData = m_data.data() + m_data.size() - classNameLength - 1;
+ m_stringDataLength = classNameLength + 1;
+ m_stringDataAllocated = classNameLength + 1;
+ m_stringData[classNameLength] = 0;
+ m_zeroPtr = classNameLength;
+
+ header(m_data)->fieldCount = fieldCount;
+
+ QMetaObjectPrivate *p = priv(m_data);
+
+ int dataIndex = HEADER_FIELD_COUNT;
+
+ p->revision = 4;
+ p->className = 0;
+
+ // Class infos
+ p->classInfoCount = classInfoCount;
+ if (p->classInfoCount) {
+ p->classInfoData = dataIndex;
+ dataIndex += p->classInfoCount * CLASSINFO_FIELD_COUNT;
+ } else {
+ p->classInfoData = 0;
+ }
+
+ // Methods
+ p->methodCount = methodCount + signalCount;
+ if (p->methodCount) {
+ p->methodData = dataIndex;
+ dataIndex += p->methodCount * METHOD_FIELD_COUNT;
+ } else {
+ p->methodData = 0;
+ }
+ p->signalCount = signalCount;
+
+ // Properties
+ p->propertyCount = propertyCount;
+ if (p->propertyCount) {
+ p->propertyData = dataIndex;
+ dataIndex += p->propertyCount * (PROPERTY_FIELD_COUNT + PROPERTY_NOTIFY_FIELD_COUNT);
+ } else {
+ p->propertyData = 0;
+ }
+
+ // Flags
+ p->flags = DynamicMetaObject; // Always dynamic
+
+ // Enums and constructors not supported
+ p->enumeratorCount = 0;
+ p->enumeratorData = 0;
+ p->constructorCount = 0;
+ p->constructorData = 0;
+
+ StringRef className;
+ className._b = this;
+ className._o = 0;
+ className._l = classNameLength;
+ return className;
+}
+
+// Allocate a string of \a length. \a length should *not* include the null terminator.
+QFastMetaBuilder::StringRef QFastMetaBuilder::newString(int length)
+{
+ Q_ASSERT(length > 0);
+
+ StringRef sr;
+ sr._b = this;
+ sr._o = m_stringDataLength;
+ sr._l = length;
+
+ m_stringDataLength += length + 1 /* for null terminator */;
+
+ return sr;
+}
+
+void QFastMetaBuilder::setClassInfo(int index, const StringRef &key, const StringRef &value)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!key.isEmpty() && !value.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ Q_ASSERT(index < p->classInfoCount);
+
+ uint *ptr = fieldPointer(m_data) + p->classInfoData + index * CLASSINFO_FIELD_COUNT;
+ // classinfo: key, value
+ ptr[0] = key.offset(); ptr[1] = value.offset();
+}
+
+void QFastMetaBuilder::setProperty(int index, const StringRef &name, const StringRef &type,
+ QMetaType::Type mtype, PropertyFlag flags, int notifySignal)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!name.isEmpty() && !type.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ Q_ASSERT(index < p->propertyCount);
+
+ uint qtType = mtype;
+ if ((int)qtType == qMetaTypeId<QVariant>())
+ qtType = 0xFF; // Special handling for QVariant
+
+ uint *ptr = fieldPointer(m_data) + p->propertyData + index * PROPERTY_FIELD_COUNT;
+ // properties: name, type, flags
+ ptr[0] = name.offset();
+ ptr[1] = type.offset();
+ if (notifySignal == -1) {
+ ptr[2] = qtType << 24;
+ ptr[2] |= flags | Scriptable | Readable;
+ *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = 0;
+ } else {
+ ptr[2] = qtType << 24;
+ ptr[2] |= flags | Scriptable | Readable | Notify;
+ *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = notifySignal;
+ }
+}
+
+void QFastMetaBuilder::setProperty(int index, const StringRef &name, const StringRef &type,
+ QFastMetaBuilder::PropertyFlag flags, int notifySignal)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!name.isEmpty() && !type.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ Q_ASSERT(index < p->propertyCount);
+
+ uint *ptr = fieldPointer(m_data) + p->propertyData + index * PROPERTY_FIELD_COUNT;
+ // properties: name, type, flags
+ ptr[0] = name.offset();
+ ptr[1] = type.offset();
+ if (notifySignal == -1) {
+ ptr[2] = flags | Scriptable | Readable;
+ *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = 0;
+ } else {
+ ptr[2] = flags | Scriptable | Readable | Notify;
+ *(fieldPointer(m_data) + p->propertyData + p->propertyCount * PROPERTY_FIELD_COUNT + index) = notifySignal;
+ }
+}
+
+void QFastMetaBuilder::setSignal(int index, const StringRef &signature,
+ const StringRef &parameterNames,
+ const StringRef &type)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!signature.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ int mindex = metaObjectIndexForSignal(index);
+
+ uint *ptr = fieldPointer(m_data) + p->methodData + mindex * METHOD_FIELD_COUNT;
+ // methods: signature, parameters, type, tag, flags
+ ptr[0] = signature.offset();
+ ptr[1] = parameterNames.isEmpty()?m_zeroPtr:parameterNames.offset();
+ ptr[2] = type.isEmpty()?m_zeroPtr:type.offset();
+ ptr[3] = m_zeroPtr;
+ ptr[4] = AccessProtected | MethodSignal;
+}
+
+void QFastMetaBuilder::setMethod(int index, const StringRef &signature,
+ const StringRef &parameterNames,
+ const StringRef &type)
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(!signature.isEmpty());
+
+ QMetaObjectPrivate *p = priv(m_data);
+ int mindex = metaObjectIndexForMethod(index);
+
+ uint *ptr = fieldPointer(m_data) + p->methodData + mindex * METHOD_FIELD_COUNT;
+ // methods: signature, parameters, type, tag, flags
+ ptr[0] = signature.offset();
+ ptr[1] = parameterNames.isEmpty()?m_zeroPtr:parameterNames.offset();
+ ptr[2] = type.isEmpty()?m_zeroPtr:type.offset();
+ ptr[3] = m_zeroPtr;
+ ptr[4] = AccessProtected | MethodSlot;
+}
+
+int QFastMetaBuilder::metaObjectIndexForSignal(int index) const
+{
+ Q_ASSERT(!m_data.isEmpty());
+ Q_ASSERT(index < priv(m_data)->signalCount);
+ return index;
+}
+
+int QFastMetaBuilder::metaObjectIndexForMethod(int index) const
+{
+ Q_ASSERT(!m_data.isEmpty());
+
+ const QMetaObjectPrivate *p = priv(m_data);
+ Q_ASSERT(index < (p->methodCount - p->signalCount));
+ return index + p->signalCount;
+}
+
+void QFastMetaBuilder::allocateStringData()
+{
+ if (m_stringDataAllocated < m_stringDataLength) {
+ m_data.resize(m_data.size() + m_stringDataLength - m_stringDataAllocated);
+ m_stringDataAllocated = m_stringDataLength;
+ m_stringData = m_data.data() + header(m_data)->fieldCount * sizeof(uint);
+ }
+}
+
+void QFastMetaBuilder::fromData(QMetaObject *output, const QMetaObject *parent, const QByteArray &data)
+{
+ output->d.superdata = parent;
+ output->d.stringdata = data.constData() + header(data)->fieldCount * sizeof(uint);
+ output->d.data = fieldPointer(data);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/ftw/qfastmetabuilder_p.h b/src/declarative/qml/ftw/qfastmetabuilder_p.h
new file mode 100644
index 0000000000..9a6971d652
--- /dev/null
+++ b/src/declarative/qml/ftw/qfastmetabuilder_p.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFASTMETABUILDER_P_H
+#define QFASTMETABUILDER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of moc. This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qmetatype.h>
+
+#include <private/qhashedstring_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QFastMetaBuilder
+{
+public:
+ QFastMetaBuilder();
+ ~QFastMetaBuilder();
+
+ struct StringRef {
+ public:
+ inline StringRef();
+ inline StringRef(const StringRef &);
+ inline StringRef &operator=(const StringRef &);
+
+ inline void load(const QHashedStringRef &);
+ inline void load(const QByteArray &);
+ inline void load(const char *);
+
+ inline bool isEmpty() const;
+ inline QFastMetaBuilder *builder() const;
+ inline int offset() const;
+ inline char *data();
+ inline int length() const;
+ private:
+ friend class QFastMetaBuilder;
+
+ QFastMetaBuilder *_b;
+ int _o;
+ int _l;
+ };
+ StringRef newString(int length);
+
+ // Returns class name
+ StringRef init(int classNameLength,
+ int propertyCount, int methodCount,
+ int signalCount, int classInfoCount);
+
+ void setClassInfo(int index, const StringRef &key, const StringRef &value);
+
+ enum PropertyFlag {
+ None = 0x00000000,
+ Writable = 0x00000002,
+ Resettable = 0x00000004,
+ Constant = 0x00000400,
+ Final = 0x00000800
+ };
+ // void setProperty(int index, const StringRef &name, QMetaType::Type type, int notifySignal = -1);
+ void setProperty(int index, const StringRef &name, const StringRef &type,
+ QMetaType::Type mtype, PropertyFlag flags, int notifySignal = -1);
+ void setProperty(int index, const StringRef &name, const StringRef &type,
+ PropertyFlag flags, int notifySignal = -1);
+ void setMethod(int index, const StringRef &signature,
+ const StringRef &parameterNames = StringRef(),
+ const StringRef &type = StringRef());
+ void setSignal(int index, const StringRef &signature,
+ const StringRef &parameterNames = StringRef(),
+ const StringRef &type = StringRef());
+
+ int metaObjectIndexForSignal(int) const;
+ int metaObjectIndexForMethod(int) const;
+
+ QByteArray toData() const { return m_data; }
+ static void fromData(QMetaObject *, const QMetaObject *parent, const QByteArray &);
+private:
+ friend class StringRef;
+
+ QByteArray m_data;
+ int m_zeroPtr;
+
+ void allocateStringData();
+ char *m_stringData;
+ int m_stringDataLength;
+ int m_stringDataAllocated;
+};
+
+QFastMetaBuilder::StringRef::StringRef()
+: _b(0), _o(0), _l(0)
+{
+}
+
+QFastMetaBuilder::StringRef::StringRef(const StringRef &o)
+: _b(o._b), _o(o._o), _l(o._l)
+{
+}
+
+QFastMetaBuilder::StringRef &QFastMetaBuilder::StringRef::operator=(const StringRef &o)
+{
+ _b = o._b;
+ _o = o._o;
+ _l = o._l;
+ return *this;
+}
+
+bool QFastMetaBuilder::StringRef::isEmpty() const
+{
+ return _l == 0;
+}
+
+QFastMetaBuilder *QFastMetaBuilder::StringRef::builder() const
+{
+ return _b;
+}
+
+int QFastMetaBuilder::StringRef::offset() const
+{
+ return _o;
+}
+
+char *QFastMetaBuilder::StringRef::data()
+{
+ Q_ASSERT(_b);
+ if (_b->m_stringDataLength != _b->m_stringDataAllocated)
+ _b->allocateStringData();
+ return _b->m_stringData + _o;
+}
+
+int QFastMetaBuilder::StringRef::length() const
+{
+ return _l;
+}
+
+void QFastMetaBuilder::StringRef::load(const QHashedStringRef &str)
+{
+ Q_ASSERT(str.utf8length() == _l);
+ str.writeUtf8(data());
+ *(data() + _l) = 0;
+}
+
+void QFastMetaBuilder::StringRef::load(const QByteArray &str)
+{
+ Q_ASSERT(str.length() == _l);
+ strcpy(data(), str.constData());
+}
+
+void QFastMetaBuilder::StringRef::load(const char *str)
+{
+ Q_ASSERT(strlen(str) == (uint)_l);
+ strcpy(data(), str);
+}
+
+QT_END_NAMESPACE
+
+#endif // QFASTMETABUILDER_P_H
+
diff --git a/src/declarative/qml/ftw/qfieldlist_p.h b/src/declarative/qml/ftw/qfieldlist_p.h
new file mode 100644
index 0000000000..65b1d4b4ee
--- /dev/null
+++ b/src/declarative/qml/ftw/qfieldlist_p.h
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFIELDLIST_P_H
+#define QFIELDLIST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+template<class N, N *N::*nextMember>
+class QFieldList
+{
+public:
+ inline QFieldList();
+ inline N *first() const;
+ inline void append(N *);
+ inline void prepend(N *);
+
+ inline bool isEmpty() const;
+ inline bool isOne() const;
+ inline bool isMany() const;
+ inline int count() const;
+
+ inline void append(QFieldList<N, nextMember> &);
+ inline void prepend(QFieldList<N, nextMember> &);
+ inline void insertAfter(N *, QFieldList<N, nextMember> &);
+
+ static inline N *next(N *v);
+
+private:
+ N *_first;
+ N *_last;
+ int _count;
+};
+
+template<class N, N *N::*nextMember>
+QFieldList<N, nextMember>::QFieldList()
+: _first(0), _last(0), _count(0)
+{
+}
+
+template<class N, N *N::*nextMember>
+N *QFieldList<N, nextMember>::first() const
+{
+ return _first;
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::append(N *v)
+{
+ Q_ASSERT(v->*nextMember == 0);
+ if (isEmpty()) {
+ _first = v;
+ _last = v;
+ } else {
+ _last->*nextMember = v;
+ _last = v;
+ }
+ ++_count;
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::prepend(N *v)
+{
+ Q_ASSERT(v->*nextMember == 0);
+ if (isEmpty()) {
+ _first = v;
+ _last = v;
+ } else {
+ v->*nextMember = _first;
+ _first = v;
+ }
+ ++_count;
+}
+
+template<class N, N *N::*nextMember>
+bool QFieldList<N, nextMember>::isEmpty() const
+{
+ return _count == 0;
+}
+
+template<class N, N *N::*nextMember>
+bool QFieldList<N, nextMember>::isOne() const
+{
+ return _count == 1;
+}
+
+template<class N, N *N::*nextMember>
+bool QFieldList<N, nextMember>::isMany() const
+{
+ return _count > 1;
+}
+
+template<class N, N *N::*nextMember>
+int QFieldList<N, nextMember>::count() const
+{
+ return _count;
+}
+
+template<class N, N *N::*nextMember>
+N *QFieldList<N, nextMember>::next(N *v)
+{
+ Q_ASSERT(v);
+ return v->*nextMember;
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::append(QFieldList<N, nextMember> &o)
+{
+ if (!o.isEmpty()) {
+ if (isEmpty()) {
+ _first = o._first;
+ _last = o._last;
+ _count = o._count;
+ } else {
+ _last->*nextMember = o._first;
+ _last = o._last;
+ _count += o._count;
+ }
+ o._first = o._last = 0; o._count = 0;
+ }
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::prepend(QFieldList<N, nextMember> &o)
+{
+ if (!o.isEmpty()) {
+ if (isEmpty()) {
+ _first = o._first;
+ _last = o._last;
+ _count = o._count;
+ } else {
+ o._last->*nextMember = _first;
+ _first = o._first;
+ _count += o._count;
+ }
+ o._first = o._last = 0; o._count = 0;
+ }
+}
+
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::insertAfter(N *after, QFieldList<N, nextMember> &o)
+{
+ if (after == 0) {
+ prepend(o);
+ } else if (after == _last) {
+ append(o);
+ } else if (!o.isEmpty()) {
+ if (isEmpty()) {
+ _first = o._first;
+ _last = o._last;
+ _count = o._count;
+ } else {
+ o._last->*nextMember = after->*nextMember;
+ after->*nextMember = o._first;
+ _count += o._count;
+ }
+ o._first = o._last = 0; o._count = 0;
+ }
+}
+
+#endif // QFIELDLIST_P_H
diff --git a/src/declarative/qml/ftw/qhashedstring.cpp b/src/declarative/qml/ftw/qhashedstring.cpp
new file mode 100644
index 0000000000..4a7b3376cc
--- /dev/null
+++ b/src/declarative/qml/ftw/qhashedstring.cpp
@@ -0,0 +1,479 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhashedstring_p.h"
+
+// This is a reimplementation of V8's string hash algorithm. It is significantly
+// faster to do it here than call into V8, but it adds the maintainence burden of
+// ensuring that the two hashes are identical. We Q_ASSERT() that the two return
+// the same value. If these asserts start to fail, the hash code needs to be
+// synced with V8.
+namespace String {
+ static const int kMaxArrayIndexSize = 10;
+ static const int kMaxHashCalcLength = 16383;
+ static const int kNofHashBitFields = 2;
+ static const int kHashShift = kNofHashBitFields;
+ static const int kIsNotArrayIndexMask = 1 << 1;
+ static const int kArrayIndexValueBits = 24;
+ static const int kArrayIndexHashLengthShift = kArrayIndexValueBits + kNofHashBitFields;
+ static const int kMaxCachedArrayIndexLength = 7;
+};
+
+template <typename schar>
+uint32_t calculateHash(const schar* chars, int length) {
+ if (length > String::kMaxHashCalcLength) {
+ // V8 trivial hash
+ return (length << String::kHashShift) | String::kIsNotArrayIndexMask;
+ }
+
+ uint32_t raw_running_hash = 0;
+ uint32_t array_index = 0;
+ bool is_array_index = (0 < length && length <= String::kMaxArrayIndexSize);
+ bool is_first_char = true;
+
+ int ii = 0;
+ for (;is_array_index && ii < length; ++ii) {
+ quint32 c = *chars++;
+
+ raw_running_hash += c;
+ raw_running_hash += (raw_running_hash << 10);
+ raw_running_hash ^= (raw_running_hash >> 6);
+
+ if (c < '0' || c > '9') {
+ is_array_index = false;
+ } else {
+ int d = c - '0';
+ if (is_first_char) {
+ is_first_char = false;
+ if (c == '0' && length > 1) {
+ is_array_index = false;
+ continue;
+ }
+ }
+ if (array_index > 429496729U - ((d + 2) >> 3)) {
+ is_array_index = false;
+ } else {
+ array_index = array_index * 10 + d;
+ }
+ }
+ }
+
+ for (;ii < length; ++ii) {
+ raw_running_hash += *chars++;
+ raw_running_hash += (raw_running_hash << 10);
+ raw_running_hash ^= (raw_running_hash >> 6);
+ }
+
+ if (is_array_index) {
+ array_index <<= String::kHashShift;
+ array_index |= length << String::kArrayIndexHashLengthShift;
+ return array_index;
+ } else {
+ raw_running_hash += (raw_running_hash << 3);
+ raw_running_hash ^= (raw_running_hash >> 11);
+ raw_running_hash += (raw_running_hash << 15);
+ if (raw_running_hash == 0) {
+ raw_running_hash = 27;
+ }
+
+ return (raw_running_hash << String::kHashShift) | String::kIsNotArrayIndexMask;
+ }
+}
+
+inline quint32 stringHash(const QChar* data, int length)
+{
+ quint32 rv = calculateHash<quint16>((quint16*)data, length) >> String::kHashShift;
+ Q_ASSERT(rv == v8::String::ComputeHash((uint16_t*)data, length));
+ return rv;
+}
+
+inline quint32 stringHash(const char *data, int length)
+{
+ quint32 rv = calculateHash<quint8>((quint8*)data, length) >> String::kHashShift;
+ Q_ASSERT(rv == v8::String::ComputeHash((char *)data, length));
+ return rv;
+}
+
+void QHashedString::computeHash() const
+{
+ m_hash = stringHash(constData(), length());
+}
+
+void QHashedStringRef::computeHash() const
+{
+ m_hash = stringHash(m_data, m_length);
+}
+
+void QHashedCStringRef::computeHash() const
+{
+ m_hash = stringHash(m_data, m_length);
+}
+
+/*
+ A QHash has initially around pow(2, MinNumBits) buckets. For
+ example, if MinNumBits is 4, it has 17 buckets.
+*/
+const int MinNumBits = 4;
+
+/*
+ The prime_deltas array is a table of selected prime values, even
+ though it doesn't look like one. The primes we are using are 1,
+ 2, 5, 11, 17, 37, 67, 131, 257, ..., i.e. primes in the immediate
+ surrounding of a power of two.
+
+ The primeForNumBits() function returns the prime associated to a
+ power of two. For example, primeForNumBits(8) returns 257.
+*/
+
+static const uchar prime_deltas[] = {
+ 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
+ 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
+};
+
+static inline int primeForNumBits(int numBits)
+{
+ return (1 << numBits) + prime_deltas[numBits];
+}
+
+void QStringHashData::rehashToSize(int size)
+{
+ short bits = qMax(MinNumBits, (int)numBits);
+ while (primeForNumBits(bits) < size) bits++;
+
+ if (bits > numBits)
+ rehashToBits(bits);
+}
+
+void QStringHashData::rehashToBits(short bits)
+{
+ numBits = qMax(MinNumBits, (int)bits);
+
+ int nb = primeForNumBits(numBits);
+ if (nb == numBuckets && buckets)
+ return;
+
+ numBuckets = nb;
+
+ delete [] buckets;
+ buckets = new QStringHashNode *[numBuckets];
+ ::memset(buckets, 0, sizeof(QStringHashNode *) * numBuckets);
+
+ QStringHashNode *nodeList = nodes;
+ while (nodeList) {
+ int bucket = nodeList->hash % numBuckets;
+ nodeList->next = buckets[bucket];
+ buckets[bucket] = nodeList;
+
+ nodeList = nodeList->nlist;
+ }
+}
+
+// Copy of QString's qMemCompare
+bool QHashedString::compare(const QChar *lhs, const QChar *rhs, int length)
+{
+ Q_ASSERT(lhs && rhs);
+ const quint16 *a = (const quint16 *)lhs;
+ const quint16 *b = (const quint16 *)rhs;
+
+ if (a == b || !length)
+ return true;
+
+ register union {
+ const quint16 *w;
+ const quint32 *d;
+ quintptr value;
+ } sa, sb;
+ sa.w = a;
+ sb.w = b;
+
+ // check alignment
+ if ((sa.value & 2) == (sb.value & 2)) {
+ // both addresses have the same alignment
+ if (sa.value & 2) {
+ // both addresses are not aligned to 4-bytes boundaries
+ // compare the first character
+ if (*sa.w != *sb.w)
+ return false;
+ --length;
+ ++sa.w;
+ ++sb.w;
+
+ // now both addresses are 4-bytes aligned
+ }
+
+ // both addresses are 4-bytes aligned
+ // do a fast 32-bit comparison
+ register const quint32 *e = sa.d + (length >> 1);
+ for ( ; sa.d != e; ++sa.d, ++sb.d) {
+ if (*sa.d != *sb.d)
+ return false;
+ }
+
+ // do we have a tail?
+ return (length & 1) ? *sa.w == *sb.w : true;
+ } else {
+ // one of the addresses isn't 4-byte aligned but the other is
+ register const quint16 *e = sa.w + length;
+ for ( ; sa.w != e; ++sa.w, ++sb.w) {
+ if (*sa.w != *sb.w)
+ return false;
+ }
+ }
+ return true;
+}
+
+// Unicode stuff
+static inline bool isUnicodeNonCharacter(uint ucs4)
+{
+ // Unicode has a couple of "non-characters" that one can use internally,
+ // but are not allowed to be used for text interchange.
+ //
+ // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF,
+ // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and
+ // U+FDEF (inclusive)
+
+ return (ucs4 & 0xfffe) == 0xfffe
+ || (ucs4 - 0xfdd0U) < 16;
+}
+
+static int utf8LengthFromUtf16(const QChar *uc, int len)
+{
+ int length = 0;
+
+ int surrogate_high = -1;
+
+ const QChar *ch = uc;
+ int invalid = 0;
+
+ const QChar *end = ch + len;
+ while (ch < end) {
+ uint u = ch->unicode();
+ if (surrogate_high >= 0) {
+ if (u >= 0xdc00 && u < 0xe000) {
+ u = (surrogate_high - 0xd800)*0x400 + (u - 0xdc00) + 0x10000;
+ surrogate_high = -1;
+ } else {
+ // high surrogate without low
+ ++ch;
+ ++invalid;
+ surrogate_high = -1;
+ continue;
+ }
+ } else if (u >= 0xdc00 && u < 0xe000) {
+ // low surrogate without high
+ ++ch;
+ ++invalid;
+ continue;
+ } else if (u >= 0xd800 && u < 0xdc00) {
+ surrogate_high = u;
+ ++ch;
+ continue;
+ }
+
+ if (u < 0x80) {
+ ++length;
+ } else {
+ if (u < 0x0800) {
+ ++length;
+ } else {
+ // is it one of the Unicode non-characters?
+ if (isUnicodeNonCharacter(u)) {
+ ++length;
+ ++ch;
+ ++invalid;
+ continue;
+ }
+
+ if (u > 0xffff) {
+ ++length;
+ ++length;
+ } else {
+ ++length;
+ }
+ ++length;
+ }
+ ++length;
+ }
+ ++ch;
+ }
+
+ return length;
+}
+
+// Writes the utf8 version of uc to output. uc is of length len.
+// There must be at least utf8LengthFromUtf16(uc, len) bytes in output.
+// A null terminator is not written.
+static void utf8FromUtf16(char *output, const QChar *uc, int len)
+{
+ uchar replacement = '?';
+ int surrogate_high = -1;
+
+ uchar* cursor = (uchar*)output;
+ const QChar *ch = uc;
+ int invalid = 0;
+
+ const QChar *end = ch + len;
+ while (ch < end) {
+ uint u = ch->unicode();
+ if (surrogate_high >= 0) {
+ if (u >= 0xdc00 && u < 0xe000) {
+ u = (surrogate_high - 0xd800)*0x400 + (u - 0xdc00) + 0x10000;
+ surrogate_high = -1;
+ } else {
+ // high surrogate without low
+ *cursor = replacement;
+ ++ch;
+ ++invalid;
+ surrogate_high = -1;
+ continue;
+ }
+ } else if (u >= 0xdc00 && u < 0xe000) {
+ // low surrogate without high
+ *cursor = replacement;
+ ++ch;
+ ++invalid;
+ continue;
+ } else if (u >= 0xd800 && u < 0xdc00) {
+ surrogate_high = u;
+ ++ch;
+ continue;
+ }
+
+ if (u < 0x80) {
+ *cursor++ = (uchar)u;
+ } else {
+ if (u < 0x0800) {
+ *cursor++ = 0xc0 | ((uchar) (u >> 6));
+ } else {
+ // is it one of the Unicode non-characters?
+ if (isUnicodeNonCharacter(u)) {
+ *cursor++ = replacement;
+ ++ch;
+ ++invalid;
+ continue;
+ }
+
+ if (u > 0xffff) {
+ *cursor++ = 0xf0 | ((uchar) (u >> 18));
+ *cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
+ } else {
+ *cursor++ = 0xe0 | (((uchar) (u >> 12)) & 0x3f);
+ }
+ *cursor++ = 0x80 | (((uchar) (u >> 6)) & 0x3f);
+ }
+ *cursor++ = 0x80 | ((uchar) (u&0x3f));
+ }
+ ++ch;
+ }
+}
+
+void QHashedStringRef::computeUtf8Length() const
+{
+ if (m_length)
+ m_utf8length = utf8LengthFromUtf16(m_data, m_length);
+ else
+ m_utf8length = 0;
+}
+
+QHashedStringRef QHashedStringRef::mid(int offset, int length) const
+{
+ Q_ASSERT(offset < m_length);
+ return QHashedStringRef(m_data + offset,
+ (length == -1 || (offset + length) > m_length)?(m_length - offset):length);
+}
+
+bool QHashedStringRef::endsWith(const QString &s) const
+{
+ return s.length() < m_length &&
+ QHashedString::compare(s.constData(), m_data + m_length - s.length(), s.length());
+}
+
+bool QHashedStringRef::startsWith(const QString &s) const
+{
+ return s.length() < m_length &&
+ QHashedString::compare(s.constData(), m_data, s.length());
+}
+
+QString QHashedStringRef::toString() const
+{
+ if (m_length == 0)
+ return QString();
+ return QString(m_data, m_length);
+}
+
+QByteArray QHashedStringRef::toUtf8() const
+{
+ if (m_length == 0)
+ return QByteArray();
+
+ QByteArray result;
+ result.resize(utf8length());
+ writeUtf8(result.data());
+ return result;
+}
+
+void QHashedStringRef::writeUtf8(char *output) const
+{
+ if (m_length) {
+ int ulen = utf8length();
+ if (ulen == m_length) {
+ // Must be a latin1 string
+ uchar *o = (uchar *)output;
+ const QChar *c = m_data;
+ while (ulen--)
+ *o++ = (uchar)((*c++).unicode());
+ } else {
+ utf8FromUtf16(output, m_data, m_length);
+ }
+ }
+}
+
+QString QHashedCStringRef::toUtf16() const
+{
+ if (m_length == 0)
+ return QString();
+
+ QString rv;
+ rv.resize(m_length);
+ writeUtf16((uint16_t*)rv.data());
+ return rv;
+}
+
diff --git a/src/declarative/qml/ftw/qhashedstring_p.h b/src/declarative/qml/ftw/qhashedstring_p.h
new file mode 100644
index 0000000000..f6c7f20d3a
--- /dev/null
+++ b/src/declarative/qml/ftw/qhashedstring_p.h
@@ -0,0 +1,1130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHASHEDSTRING_P_H
+#define QHASHEDSTRING_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qstring.h>
+#include <private/qv8_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QHashedStringRef;
+class Q_AUTOTEST_EXPORT QHashedString : public QString
+{
+public:
+ inline QHashedString();
+ inline QHashedString(const QString &string);
+ inline QHashedString(const QString &string, quint32);
+ inline QHashedString(const QHashedString &string);
+
+ inline QHashedString &operator=(const QHashedString &string);
+ inline bool operator==(const QHashedString &string) const;
+ inline bool operator==(const QHashedStringRef &string) const;
+
+ inline quint32 hash() const;
+ inline quint32 existingHash() const;
+
+ static inline bool isUpper(const QChar &);
+
+ static bool compare(const QChar *lhs, const QChar *rhs, int length);
+ static inline bool compare(const QChar *lhs, const char *rhs, int length);
+ static inline bool compare(const char *lhs, const char *rhs, int length);
+private:
+ friend class QHashedStringRef;
+ friend class QStringHashNode;
+
+ void computeHash() const;
+ mutable quint32 m_hash;
+};
+
+class Q_AUTOTEST_EXPORT QHashedV8String
+{
+public:
+ inline QHashedV8String();
+ explicit inline QHashedV8String(v8::Handle<v8::String>);
+ inline QHashedV8String(const QHashedV8String &string);
+ inline QHashedV8String &operator=(const QHashedV8String &other);
+
+ inline bool operator==(const QHashedV8String &string);
+
+ inline quint32 hash() const;
+ inline int length() const;
+ inline quint32 symbolId() const;
+
+ inline v8::Handle<v8::String> string() const;
+
+private:
+ v8::String::CompleteHashData m_hash;
+ v8::Handle<v8::String> m_string;
+};
+
+class QHashedCStringRef;
+class Q_AUTOTEST_EXPORT QHashedStringRef
+{
+public:
+ inline QHashedStringRef();
+ inline QHashedStringRef(const QString &);
+ inline QHashedStringRef(const QStringRef &);
+ inline QHashedStringRef(const QChar *, int);
+ inline QHashedStringRef(const QChar *, int, quint32);
+ inline QHashedStringRef(const QHashedString &);
+ inline QHashedStringRef(const QHashedStringRef &);
+ inline QHashedStringRef &operator=(const QHashedStringRef &);
+
+ inline bool operator==(const QString &string) const;
+ inline bool operator==(const QHashedString &string) const;
+ inline bool operator==(const QHashedStringRef &string) const;
+ inline bool operator==(const QHashedCStringRef &string) const;
+ inline bool operator!=(const QString &string) const;
+ inline bool operator!=(const QHashedString &string) const;
+ inline bool operator!=(const QHashedStringRef &string) const;
+ inline bool operator!=(const QHashedCStringRef &string) const;
+
+ inline quint32 hash() const;
+
+ inline const QChar &at(int) const;
+ inline const QChar *constData() const;
+ bool startsWith(const QString &) const;
+ bool endsWith(const QString &) const;
+ QHashedStringRef mid(int, int) const;
+
+ inline bool isEmpty() const;
+ inline int length() const;
+ inline bool startsWithUpper() const;
+
+ QString toString() const;
+
+ inline int utf8length() const;
+ QByteArray toUtf8() const;
+ void writeUtf8(char *) const;
+private:
+ friend class QHashedString;
+
+ void computeHash() const;
+ void computeUtf8Length() const;
+
+ const QChar *m_data;
+ int m_length;
+ mutable int m_utf8length;
+ mutable quint32 m_hash;
+};
+
+class Q_AUTOTEST_EXPORT QHashedCStringRef
+{
+public:
+ inline QHashedCStringRef();
+ inline QHashedCStringRef(const char *, int);
+ inline QHashedCStringRef(const char *, int, quint32);
+ inline QHashedCStringRef(const QHashedCStringRef &);
+
+ inline quint32 hash() const;
+
+ inline const char *constData() const;
+ inline int length() const;
+
+ QString toUtf16() const;
+ inline int utf16length() const;
+ inline void writeUtf16(QChar *) const;
+ inline void writeUtf16(uint16_t *) const;
+private:
+ friend class QHashedStringRef;
+
+ void computeHash() const;
+
+ const char *m_data;
+ int m_length;
+ mutable quint32 m_hash;
+};
+
+class QStringHashData;
+class Q_AUTOTEST_EXPORT QStringHashNode
+{
+public:
+ QStringHashNode()
+ : nlist(0), next(0), length(0), hash(0), pooled(0), ckey(0), ukey(0), symbolId()
+ {
+ }
+
+ QStringHashNode(const QHashedString &key)
+ : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(0), key(key),
+ ukey(key.constData()), symbolId(0) {
+ }
+
+ QStringHashNode(const QHashedCStringRef &key)
+ : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(key.constData()),
+ ukey(0), symbolId(0) {
+ }
+
+ QStringHashNode(const QStringHashNode &o)
+ : nlist(0), next(0), length(o.length), hash(o.hash), pooled(0), ckey(o.ckey), key(o.key),
+ ukey(o.ukey), symbolId(o.symbolId) {
+ }
+
+ QStringHashNode *nlist;
+ QStringHashNode *next;
+ qint32 length;
+ quint32 hash;
+
+ quint32 pooled:1;
+ const char *ckey;
+ QString key;
+ const QChar *ukey;
+
+ quint32 symbolId;
+
+ inline bool equals(v8::Handle<v8::String> string) {
+ return ckey?string->Equals((char*)ckey, length):
+ string->Equals((uint16_t*)ukey, length);
+ }
+
+ inline bool symbolEquals(const QHashedV8String &string) {
+ Q_ASSERT(string.symbolId() != 0);
+ return length == string.length() && hash == string.hash() &&
+ (string.symbolId() == symbolId || equals(string.string()));
+ }
+
+ inline bool equals(const QHashedV8String &string) {
+ return length == string.length() && hash == string.hash() &&
+ equals(string.string());
+ }
+
+ inline bool equals(const QHashedStringRef &string) {
+ return length == string.length() &&
+ hash == string.hash() &&
+ (ckey?(QHashedString::compare(string.constData(), ckey, length)):
+ (QHashedString::compare(string.constData(), ukey, length)));
+ }
+
+ inline bool equals(const QHashedCStringRef &string) {
+ return length == string.length() &&
+ hash == string.hash() &&
+ (ckey?(QHashedString::compare(string.constData(), ckey, length)):
+ (QHashedString::compare(ukey, string.constData(), length)));
+ }
+};
+
+struct Q_AUTOTEST_EXPORT QStringHashData
+{
+public:
+ QStringHashData()
+ : nodes(0), buckets(0), numBuckets(0), size(0), numBits(0) {}
+
+ QStringHashNode *nodes;
+ QStringHashNode **buckets;
+ int numBuckets;
+ int size;
+ short numBits;
+
+ void rehashToBits(short);
+ void rehashToSize(int);
+
+private:
+ QStringHashData(const QStringHashData &);
+ QStringHashData &operator=(const QStringHashData &);
+};
+
+template<class T, int SmallThreshold = 0>
+class Q_AUTOTEST_EXPORT QStringHash
+{
+public:
+ struct Node : public QStringHashNode {
+ Node(const QHashedString &key, const T &value) : QStringHashNode(key), value(value) {}
+ Node(const QHashedCStringRef &key, const T &value) : QStringHashNode(key), value(value) {}
+ Node(const Node &o) : QStringHashNode(o), value(o.value) {}
+ Node() {}
+ T value;
+ };
+ struct ReservedNodePool
+ {
+ ReservedNodePool() : count(0), used(0), nodes(0) {}
+ ~ReservedNodePool() { delete [] nodes; }
+ int count;
+ int used;
+ Node *nodes;
+ };
+
+ QStringHashData data;
+ ReservedNodePool *nodePool;
+
+ inline Node *findNode(const QString &) const;
+ inline Node *findNode(const QHashedString &) const;
+ inline Node *findNode(const QHashedStringRef &) const;
+ inline Node *findNode(const QHashedCStringRef &) const;
+ inline Node *findNode(const QHashedV8String &) const;
+ inline Node *findSymbolNode(const QHashedV8String &) const;
+ inline Node *createNode(const QHashedString &, const T &);
+ inline Node *createNode(const QHashedCStringRef &, const T &);
+
+ inline Node *takeNode(const QHashedString &key, const T &value);
+ inline Node *takeNode(const QHashedCStringRef &key, const T &value);
+ inline Node *takeNode(const Node &o);
+
+ inline void copy(const QStringHash<T,SmallThreshold> &);
+public:
+ inline QStringHash();
+ inline QStringHash(const QStringHash &);
+ inline ~QStringHash();
+
+ QStringHash &operator=(const QStringHash<T,SmallThreshold> &);
+
+ void copyAndReserve(const QStringHash<T,SmallThreshold> &other, int additionalReserve);
+
+ inline bool isEmpty() const;
+ inline void clear();
+ inline int count() const;
+
+ inline void insert(const QString &, const T &);
+ inline void insert(const QHashedString &, const T &);
+ inline void insert(const QHashedStringRef &, const T &);
+ inline void insert(const QHashedCStringRef &, const T &);
+
+ inline T *value(const QString &) const;
+ inline T *value(const QHashedString &) const;
+ inline T *value(const QHashedStringRef &) const;
+ inline T *value(const QHashedV8String &) const;
+ inline T *value(const QHashedCStringRef &) const;
+
+ inline bool contains(const QString &) const;
+ inline bool contains(const QHashedString &) const;
+ inline bool contains(const QHashedStringRef &) const;
+ inline bool contains(const QHashedCStringRef &) const;
+
+ T &operator[](const QString &);
+ T &operator[](const QHashedString &);
+ T &operator[](const QHashedStringRef &);
+ T &operator[](const QHashedCStringRef &);
+
+ class ConstIterator {
+ public:
+ ConstIterator() : n(0) {}
+ ConstIterator(Node *n) : n(n) {}
+
+ ConstIterator &operator++() { n = (Node *)n->nlist; return *this; }
+ bool operator==(const ConstIterator &o) const { return n == o.n; }
+ bool operator!=(const ConstIterator &o) const { return n != o.n; }
+
+ QHashedString key() const {
+ if (n->ckey) {
+ return QHashedString(QString::fromLatin1(n->ckey, n->length), n->hash);
+ } else {
+ return QHashedString(n->key, n->hash);
+ }
+ }
+ const T &value() const { return n->value; }
+ const T &operator*() const { return n->value; }
+ private:
+ Node *n;
+ };
+
+ ConstIterator begin() const { return ConstIterator((Node *)data.nodes); }
+ ConstIterator end() const { return ConstIterator(); }
+
+ inline void reserve(int);
+};
+
+template<class T, int SmallThreshold>
+QStringHash<T,SmallThreshold>::QStringHash()
+: nodePool(0)
+{
+}
+
+template<class T, int SmallThreshold>
+QStringHash<T,SmallThreshold>::QStringHash(const QStringHash<T,SmallThreshold> &other)
+: nodePool(0)
+{
+ data.numBits = other.data.numBits;
+ data.size = other.data.size;
+ reserve(other.count());
+ copy(other);
+}
+
+template<class T, int SmallThreshold>
+QStringHash<T,SmallThreshold> &QStringHash<T,SmallThreshold>::operator=(const QStringHash<T,SmallThreshold> &other)
+{
+ if (&other == this)
+ return *this;
+
+ clear();
+
+ data.numBits = other.data.numBits;
+ data.size = other.data.size;
+ reserve(other.count());
+ copy(other);
+
+ return *this;
+}
+
+template<class T, int SmallThreshold>
+void QStringHash<T,SmallThreshold>::copyAndReserve(const QStringHash<T,SmallThreshold> &other, int additionalReserve)
+{
+ clear();
+
+ data.numBits = other.data.numBits;
+ data.size = other.data.size;;
+ reserve(other.count() + additionalReserve);
+ copy(other);
+}
+
+template<class T, int SmallThreshold>
+QStringHash<T,SmallThreshold>::~QStringHash()
+{
+ clear();
+}
+
+template<class T, int SmallThreshold>
+void QStringHash<T,SmallThreshold>::clear()
+{
+ // If all the nodes were allocated from the node pool, we
+ // don't need to clean them individually
+ if (!nodePool || data.size != nodePool->used) {
+ QStringHashNode *n = data.nodes;
+ while (n) {
+ Node *o = (Node *)n;
+ n = n->nlist;
+ if (!o->pooled) delete o;
+ }
+ }
+ if (nodePool) delete nodePool;
+ delete [] data.buckets;
+
+ data.nodes = 0;
+ data.buckets = 0;
+ data.numBuckets = 0;
+ data.numBits = 0;
+ data.size = 0;
+
+ nodePool = 0;
+}
+
+template<class T, int SmallThreshold>
+bool QStringHash<T,SmallThreshold>::isEmpty() const
+{
+ return data.nodes == 0;
+}
+
+template<class T, int SmallThreshold>
+int QStringHash<T,SmallThreshold>::count() const
+{
+ return data.size;
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::takeNode(const QHashedString &key, const T &value)
+{
+ if (nodePool && nodePool->used != nodePool->count) {
+ Node *rv = nodePool->nodes + nodePool->used++;
+ rv->length = key.length();
+ rv->hash = key.hash();
+ rv->key = key;
+ rv->ukey = rv->key.constData();
+ rv->pooled = 1;
+ rv->value = value;
+ return rv;
+ } else {
+ return new Node(key, value);
+ }
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::takeNode(const QHashedCStringRef &key, const T &value)
+{
+ if (nodePool && nodePool->used != nodePool->count) {
+ Node *rv = nodePool->nodes + nodePool->used++;
+ rv->length = key.length();
+ rv->hash = key.hash();
+ rv->ckey = key.constData();
+ rv->pooled = 1;
+ rv->value = value;
+ return rv;
+ } else {
+ return new Node(key, value);
+ }
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::takeNode(const Node &o)
+{
+ if (nodePool && nodePool->used != nodePool->count) {
+ Node *rv = nodePool->nodes + nodePool->used++;
+ rv->length = o.length;
+ rv->hash = o.hash;
+ rv->ckey = o.ckey;
+ rv->key = o.key;
+ rv->ukey = o.ukey;
+ rv->pooled = 1;
+ rv->symbolId = o.symbolId;
+ rv->value = o.value;
+ return rv;
+ } else {
+ return new Node(o);
+ }
+}
+
+template<class T, int SmallThreshold>
+void QStringHash<T,SmallThreshold>::copy(const QStringHash<T,SmallThreshold> &other)
+{
+ Q_ASSERT(data.nodes == 0);
+
+ if (other.data.size <= SmallThreshold) {
+ QStringHashNode *n = other.data.nodes;
+ while (n) {
+ Node *o = (Node *)n;
+ Node *mynode = takeNode(*o);
+ mynode->nlist = data.nodes;
+ mynode->next = data.nodes;
+ data.nodes = mynode;
+
+ n = o->nlist;
+ }
+ } else {
+ // Ensure buckets array is created
+ data.rehashToBits(data.numBits);
+
+ QStringHashNode *n = other.data.nodes;
+ while (n) {
+ Node *o = (Node *)n;
+ Node *mynode = takeNode(*o);
+ mynode->nlist = data.nodes;
+ data.nodes = mynode;
+
+ int bucket = mynode->hash % data.numBuckets;
+ mynode->next = data.buckets[bucket];
+ data.buckets[bucket] = mynode;
+
+ n = o->nlist;
+ }
+ }
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::createNode(const QHashedString &key, const T &value)
+{
+ Node *n = takeNode(key, value);
+
+ if (data.size < SmallThreshold) {
+
+ n->nlist = data.nodes;
+ n->next = data.nodes;
+ data.nodes = n;
+
+ } else {
+ if (data.size >= data.numBuckets)
+ data.rehashToBits(data.numBits + 1);
+
+ n->nlist = data.nodes;
+ data.nodes = n;
+
+ int bucket = key.hash() % data.numBuckets;
+ n->next = data.buckets[bucket];
+ data.buckets[bucket] = n;
+ }
+
+ data.size++;
+
+ return n;
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::createNode(const QHashedCStringRef &key, const T &value)
+{
+ Node *n = takeNode(key, value);
+
+ if (data.size < SmallThreshold) {
+
+ n->nlist = data.nodes;
+ n->next = data.nodes;
+ data.nodes = n;
+
+ } else {
+ if (data.size >= data.numBuckets)
+ data.rehashToBits(data.numBits + 1);
+
+ n->nlist = data.nodes;
+ data.nodes = n;
+
+ int bucket = key.hash() % data.numBuckets;
+ n->next = data.buckets[bucket];
+ data.buckets[bucket] = n;
+ }
+
+ data.size++;
+
+ return n;
+}
+
+template<class T, int SmallThreshold>
+void QStringHash<T,SmallThreshold>::insert(const QString &key, const T &value)
+{
+ QHashedStringRef ch(key);
+ Node *n = findNode(key);
+ if (n) n->value = value;
+ else createNode(QHashedString(key, ch.hash()), value);
+}
+
+template<class T, int SmallThreshold>
+void QStringHash<T,SmallThreshold>::insert(const QHashedString &key, const T &value)
+{
+ Node *n = findNode(key);
+ if (n) n->value = value;
+ else createNode(key, value);
+}
+
+template<class T, int SmallThreshold>
+void QStringHash<T,SmallThreshold>::insert(const QHashedStringRef &key, const T &value)
+{
+ Node *n = findNode(key);
+ if (n) n->value = value;
+ else createNode(key, value);
+}
+
+template<class T, int SmallThreshold>
+void QStringHash<T,SmallThreshold>::insert(const QHashedCStringRef &key, const T &value)
+{
+ Node *n = findNode(key);
+ if (n) n->value = value;
+ else createNode(key, value);
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QString &string) const
+{
+ return findNode(QHashedStringRef(string));
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedString &string) const
+{
+ return findNode(QHashedStringRef(string.constData(), string.length(), string.hash()));
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedStringRef &string) const
+{
+ QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
+ while (node && !node->equals(string))
+ node = node->next;
+
+ return (Node *)node;
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedCStringRef &string) const
+{
+ QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
+ while (node && !node->equals(string))
+ node = node->next;
+
+ return (Node *)node;
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findNode(const QHashedV8String &string) const
+{
+ QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
+ while (node && !node->equals(string))
+ node = node->next;
+
+ return (Node *)node;
+}
+
+template<class T, int SmallThreshold>
+typename QStringHash<T,SmallThreshold>::Node *QStringHash<T,SmallThreshold>::findSymbolNode(const QHashedV8String &string) const
+{
+ Q_ASSERT(string.symbolId() != 0);
+
+ QStringHashNode *node = (data.size <= SmallThreshold)?data.nodes:data.buckets[string.hash() % data.numBuckets];
+ while (node && !node->symbolEquals(string))
+ node = node->next;
+
+ if (node)
+ node->symbolId = string.symbolId();
+
+ return (Node *)node;
+}
+
+template<class T, int SmallThreshold>
+T *QStringHash<T,SmallThreshold>::value(const QString &key) const
+{
+ Node *n = findNode(key);
+ return n?&n->value:0;
+}
+
+template<class T, int SmallThreshold>
+T *QStringHash<T,SmallThreshold>::value(const QHashedString &key) const
+{
+ Node *n = findNode(key);
+ return n?&n->value:0;
+}
+
+template<class T, int SmallThreshold>
+T *QStringHash<T,SmallThreshold>::value(const QHashedStringRef &key) const
+{
+ Node *n = findNode(key);
+ return n?&n->value:0;
+}
+
+template<class T, int SmallThreshold>
+T *QStringHash<T,SmallThreshold>::value(const QHashedCStringRef &key) const
+{
+ Node *n = findNode(key);
+ return n?&n->value:0;
+}
+
+template<class T, int SmallThreshold>
+T *QStringHash<T,SmallThreshold>::value(const QHashedV8String &string) const
+{
+ Node *n = string.symbolId()?findSymbolNode(string):findNode(string);
+ return n?&n->value:0;
+}
+
+template<class T, int SmallThreshold>
+bool QStringHash<T,SmallThreshold>::contains(const QString &s) const
+{
+ return 0 != value(s);
+}
+
+template<class T, int SmallThreshold>
+bool QStringHash<T,SmallThreshold>::contains(const QHashedString &s) const
+{
+ return 0 != value(s);
+}
+
+template<class T, int SmallThreshold>
+bool QStringHash<T,SmallThreshold>::contains(const QHashedStringRef &s) const
+{
+ return 0 != value(s);
+}
+
+template<class T, int SmallThreshold>
+bool QStringHash<T,SmallThreshold>::contains(const QHashedCStringRef &s) const
+{
+ return 0 != value(s);
+}
+
+template<class T, int SmallThreshold>
+T &QStringHash<T,SmallThreshold>::operator[](const QString &key)
+{
+ QHashedStringRef cs(key);
+ Node *n = findNode(cs);
+ if (n) return n->value;
+ else return createNode(QHashedString(key, cs.hash()), T())->value;
+}
+
+template<class T, int SmallThreshold>
+T &QStringHash<T,SmallThreshold>::operator[](const QHashedString &key)
+{
+ Node *n = findNode(key);
+ if (n) return n->value;
+ else return createNode(key, T())->value;
+}
+
+template<class T, int SmallThreshold>
+T &QStringHash<T,SmallThreshold>::operator[](const QHashedStringRef &key)
+{
+ Node *n = findNode(key);
+ if (n) return n->value;
+ else return createNode(key, T())->value;
+}
+
+template<class T, int SmallThreshold>
+T &QStringHash<T,SmallThreshold>::operator[](const QHashedCStringRef &key)
+{
+ Node *n = findNode(key);
+ if (n) return n->value;
+ else return createNode(key, T())->value;
+}
+
+template<class T, int SmallThreshold>
+void QStringHash<T,SmallThreshold>::reserve(int n)
+{
+ if (nodePool || 0 == n)
+ return;
+ nodePool = new ReservedNodePool;
+ nodePool->count = n;
+ nodePool->used = 0;
+ nodePool->nodes = new Node[n];
+
+ if (n > SmallThreshold)
+ data.rehashToSize(n);
+}
+
+inline uint qHash(const QHashedString &string)
+{
+ return uint(string.hash());
+}
+
+inline uint qHash(const QHashedStringRef &string)
+{
+ return uint(string.hash());
+}
+
+QHashedString::QHashedString()
+: QString(), m_hash(0)
+{
+}
+
+QHashedString::QHashedString(const QString &string)
+: QString(string), m_hash(0)
+{
+}
+
+QHashedString::QHashedString(const QString &string, quint32 hash)
+: QString(string), m_hash(hash)
+{
+}
+
+QHashedString::QHashedString(const QHashedString &string)
+: QString(string), m_hash(string.m_hash)
+{
+}
+
+QHashedString &QHashedString::operator=(const QHashedString &string)
+{
+ static_cast<QString &>(*this) = string;
+ m_hash = string.m_hash;
+ return *this;
+}
+
+bool QHashedString::operator==(const QHashedString &string) const
+{
+ return (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
+ static_cast<const QString &>(*this) == static_cast<const QString &>(string);
+}
+
+bool QHashedString::operator==(const QHashedStringRef &string) const
+{
+ return length() == string.m_length &&
+ (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
+ QHashedString::compare(constData(), string.m_data, string.m_length);
+}
+
+quint32 QHashedString::hash() const
+{
+ if (!m_hash) computeHash();
+ return m_hash;
+}
+
+quint32 QHashedString::existingHash() const
+{
+ return m_hash;
+}
+
+bool QHashedString::isUpper(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ // Optimize for _, a-z and A-Z.
+ return ((c != '_' ) && (!(c >= 'a' && c <= 'z')) &&
+ ((c >= 'A' && c <= 'Z') || QChar::category(c) == QChar::Letter_Uppercase));
+}
+
+QHashedV8String::QHashedV8String()
+{
+}
+
+QHashedV8String::QHashedV8String(v8::Handle<v8::String> string)
+: m_hash(string->CompleteHash()), m_string(string)
+{
+ Q_ASSERT(!m_string.IsEmpty());
+}
+
+QHashedV8String::QHashedV8String(const QHashedV8String &string)
+: m_hash(string.m_hash), m_string(string.m_string)
+{
+}
+
+QHashedV8String &QHashedV8String::operator=(const QHashedV8String &other)
+{
+ m_hash = other.m_hash;
+ m_string = other.m_string;
+ return *this;
+}
+
+bool QHashedV8String::operator==(const QHashedV8String &string)
+{
+ return m_hash.hash == string.m_hash.hash && m_hash.length == string.m_hash.length &&
+ m_string.IsEmpty() == m_string.IsEmpty() &&
+ (m_string.IsEmpty() || m_string->StrictEquals(string.m_string));
+}
+
+quint32 QHashedV8String::hash() const
+{
+ return m_hash.hash;
+}
+
+int QHashedV8String::length() const
+{
+ return m_hash.length;
+}
+
+quint32 QHashedV8String::symbolId() const
+{
+ return m_hash.symbol_id;
+}
+
+v8::Handle<v8::String> QHashedV8String::string() const
+{
+ return m_string;
+}
+
+QHashedStringRef::QHashedStringRef()
+: m_data(0), m_length(0), m_utf8length(-1), m_hash(0)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QString &str)
+: m_data(str.constData()), m_length(str.length()), m_utf8length(0), m_hash(0)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QStringRef &str)
+: m_data(str.constData()), m_length(str.length()), m_utf8length(0), m_hash(0)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QChar *data, int length)
+: m_data(data), m_length(length), m_utf8length(0), m_hash(0)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QChar *data, int length, quint32 hash)
+: m_data(data), m_length(length), m_utf8length(0), m_hash(hash)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QHashedString &string)
+: m_data(string.constData()), m_length(string.length()), m_utf8length(0), m_hash(string.m_hash)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QHashedStringRef &string)
+: m_data(string.m_data), m_length(string.m_length), m_utf8length(string.m_utf8length),
+ m_hash(string.m_hash)
+{
+}
+
+QHashedStringRef &QHashedStringRef::operator=(const QHashedStringRef &o)
+{
+ m_data = o.m_data;
+ m_length = o.m_length;
+ m_utf8length = o.m_utf8length;
+ m_hash = o.m_hash;
+ return *this;
+}
+
+bool QHashedStringRef::operator==(const QString &string) const
+{
+ return m_length == string.length() &&
+ QHashedString::compare(string.constData(), m_data, m_length);
+}
+
+bool QHashedStringRef::operator==(const QHashedString &string) const
+{
+ return m_length == string.length() &&
+ (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
+ QHashedString::compare(string.constData(), m_data, m_length);
+}
+
+bool QHashedStringRef::operator==(const QHashedStringRef &string) const
+{
+ return m_length == string.m_length &&
+ (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
+ QHashedString::compare(string.m_data, m_data, m_length);
+}
+
+bool QHashedStringRef::operator==(const QHashedCStringRef &string) const
+{
+ return m_length == string.m_length &&
+ (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
+ QHashedString::compare(m_data, string.m_data, m_length);
+}
+
+bool QHashedStringRef::operator!=(const QString &string) const
+{
+ return m_length != string.length() ||
+ !QHashedString::compare(string.constData(), m_data, m_length);
+}
+
+bool QHashedStringRef::operator!=(const QHashedString &string) const
+{
+ return m_length != string.length() ||
+ (m_hash != string.m_hash && m_hash && string.m_hash) ||
+ !QHashedString::compare(string.constData(), m_data, m_length);
+}
+
+bool QHashedStringRef::operator!=(const QHashedStringRef &string) const
+{
+ return m_length != string.m_length ||
+ (m_hash != string.m_hash && m_hash && string.m_hash) ||
+ QHashedString::compare(string.m_data, m_data, m_length);
+}
+
+bool QHashedStringRef::operator!=(const QHashedCStringRef &string) const
+{
+ return m_length != string.m_length ||
+ (m_hash != string.m_hash && m_hash && string.m_hash) ||
+ QHashedString::compare(m_data, string.m_data, m_length);
+}
+
+const QChar &QHashedStringRef::at(int index) const
+{
+ Q_ASSERT(index < m_length);
+ return m_data[index];
+}
+
+const QChar *QHashedStringRef::constData() const
+{
+ return m_data;
+}
+
+bool QHashedStringRef::isEmpty() const
+{
+ return m_length == 0;
+}
+
+int QHashedStringRef::length() const
+{
+ return m_length;
+}
+
+int QHashedStringRef::utf8length() const
+{
+ if (m_utf8length < m_length)
+ computeUtf8Length();
+ return m_utf8length;
+}
+
+bool QHashedStringRef::startsWithUpper() const
+{
+ if (m_length < 1) return false;
+ return QHashedString::isUpper(m_data[0]);
+}
+
+quint32 QHashedStringRef::hash() const
+{
+ if (!m_hash) computeHash();
+ return m_hash;
+}
+
+QHashedCStringRef::QHashedCStringRef()
+: m_data(0), m_length(0), m_hash(0)
+{
+}
+
+QHashedCStringRef::QHashedCStringRef(const char *data, int length)
+: m_data(data), m_length(length), m_hash(0)
+{
+}
+
+QHashedCStringRef::QHashedCStringRef(const char *data, int length, quint32 hash)
+: m_data(data), m_length(length), m_hash(hash)
+{
+}
+
+QHashedCStringRef::QHashedCStringRef(const QHashedCStringRef &o)
+: m_data(o.m_data), m_length(o.m_length), m_hash(o.m_hash)
+{
+}
+
+quint32 QHashedCStringRef::hash() const
+{
+ if (!m_hash) computeHash();
+ return m_hash;
+}
+
+const char *QHashedCStringRef::constData() const
+{
+ return m_data;
+}
+
+int QHashedCStringRef::length() const
+{
+ return m_length;
+}
+
+int QHashedCStringRef::utf16length() const
+{
+ return m_length;
+}
+
+void QHashedCStringRef::writeUtf16(QChar *output) const
+{
+ writeUtf16((uint16_t *)output);
+}
+
+void QHashedCStringRef::writeUtf16(uint16_t *output) const
+{
+ int l = m_length;
+ const char *d = m_data;
+ while (l--)
+ *output++ = *d++;
+}
+
+bool QHashedString::compare(const QChar *lhs, const char *rhs, int length)
+{
+ Q_ASSERT(lhs && rhs);
+ const quint16 *l = (const quint16*)lhs;
+ while (length--)
+ if (*l++ != *rhs++) return false;
+ return true;
+}
+
+bool QHashedString::compare(const char *lhs, const char *rhs, int length)
+{
+ Q_ASSERT(lhs && rhs);
+ return 0 == ::memcmp(lhs, rhs, length);
+}
+
+QT_END_NAMESPACE
+
+#endif // QHASHEDSTRING_P_H
diff --git a/src/declarative/qml/ftw/qhashfield_p.h b/src/declarative/qml/ftw/qhashfield_p.h
new file mode 100644
index 0000000000..874626496a
--- /dev/null
+++ b/src/declarative/qml/ftw/qhashfield_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHASHFIELD_P_H
+#define QHASHFIELD_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+// QHashField can be used for doing coarse grained set testing, in
+// cases where you do not expect the set to contain the item. For
+// example where you would write:
+// QSet<QString> strings;
+// for (int ii = 0; ii < mystrings.count(); ++ii) {
+// if (strings.contains(mystrings.at(ii)))
+// qFatal("Duplication!");
+// strings.insert(mystrings);
+// }
+// You may write:
+// QHashField strings;
+// for (int ii = 0; ii < mystrings.count(); ++ii) {
+// if (strings.testAndSet(qHash(mystrings.at(ii)))) {
+// // The string *might* be duplicated
+// for (int jj = 0; jj < ii; ++jj) {
+// if (mystrings.at(ii) == mystrings.at(jj))
+// qFatal("Duplication!");
+// }
+// }
+// }
+// For small lists of things, where the hash is cheap to calculate
+// and you don't expect duplication this will be much faster.
+class QHashField {
+public:
+ inline QHashField();
+
+ inline void clear();
+
+ inline bool test(quint32 hash);
+ inline bool testAndSet(quint32 hash);
+private:
+ quint32 m_field;
+};
+
+QHashField::QHashField()
+: m_field(0)
+{
+}
+
+void QHashField::clear()
+{
+ m_field = 0;
+}
+
+bool QHashField::test(quint32 hash)
+{
+ return m_field & (1 << (hash % 31));
+}
+
+bool QHashField::testAndSet(quint32 hash)
+{
+ quint32 mask = 1 << (hash % 31);
+ bool rv = m_field & mask;
+ m_field |= mask;
+ return rv;
+}
+
+QT_END_NAMESPACE
+
+#endif // QHASHFIELD_P_H
diff --git a/src/declarative/qml/qintrusivelist.cpp b/src/declarative/qml/ftw/qintrusivelist.cpp
index dabb893e91..dabb893e91 100644
--- a/src/declarative/qml/qintrusivelist.cpp
+++ b/src/declarative/qml/ftw/qintrusivelist.cpp
diff --git a/src/declarative/qml/qintrusivelist_p.h b/src/declarative/qml/ftw/qintrusivelist_p.h
index 717b11c344..717b11c344 100644
--- a/src/declarative/qml/qintrusivelist_p.h
+++ b/src/declarative/qml/ftw/qintrusivelist_p.h
diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/ftw/qmetaobjectbuilder.cpp
index f5e8369ebc..f5e8369ebc 100644
--- a/src/declarative/qml/qmetaobjectbuilder.cpp
+++ b/src/declarative/qml/ftw/qmetaobjectbuilder.cpp
diff --git a/src/declarative/qml/qmetaobjectbuilder_p.h b/src/declarative/qml/ftw/qmetaobjectbuilder_p.h
index a80ba904b6..a80ba904b6 100644
--- a/src/declarative/qml/qmetaobjectbuilder_p.h
+++ b/src/declarative/qml/ftw/qmetaobjectbuilder_p.h
diff --git a/src/declarative/qml/qpodvector_p.h b/src/declarative/qml/ftw/qpodvector_p.h
index 7b50463145..7b50463145 100644
--- a/src/declarative/qml/qpodvector_p.h
+++ b/src/declarative/qml/ftw/qpodvector_p.h
diff --git a/src/declarative/qml/parser/parser.pri b/src/declarative/qml/parser/parser.pri
index fd4361c2df..4f1ff2fd21 100644
--- a/src/declarative/qml/parser/parser.pri
+++ b/src/declarative/qml/parser/parser.pri
@@ -8,9 +8,9 @@ HEADERS += \
$$PWD/qdeclarativejsgrammar_p.h \
$$PWD/qdeclarativejslexer_p.h \
$$PWD/qdeclarativejsmemorypool_p.h \
- $$PWD/qdeclarativejsnodepool_p.h \
$$PWD/qdeclarativejsparser_p.h \
- $$PWD/qdeclarativejsglobal_p.h
+ $$PWD/qdeclarativejsglobal_p.h \
+ $$PWD/qdeclarativejskeywords_p.h
SOURCES += \
$$PWD/qdeclarativejsast.cpp \
diff --git a/src/declarative/qml/parser/qdeclarativejs.g b/src/declarative/qml/parser/qdeclarativejs.g
index a57ecba3f9..6487379f06 100644
--- a/src/declarative/qml/parser/qdeclarativejs.g
+++ b/src/declarative/qml/parser/qdeclarativejs.g
@@ -29,7 +29,7 @@
%token T_AND "&" T_AND_AND "&&" T_AND_EQ "&="
%token T_BREAK "break" T_CASE "case" T_CATCH "catch"
-%token T_COLON ":" T_COMMA ";" T_CONTINUE "continue"
+%token T_COLON ":" T_COMMA "," T_CONTINUE "continue"
%token T_DEFAULT "default" T_DELETE "delete" T_DIVIDE_ "/"
%token T_DIVIDE_EQ "/=" T_DO "do" T_DOT "."
%token T_ELSE "else" T_EQ "=" T_EQ_EQ "=="
@@ -67,6 +67,8 @@
%token T_AS "as"
%token T_ON "on"
+%token T_ERROR
+
--- feed tokens
%token T_FEED_UI_PROGRAM
%token T_FEED_UI_OBJECT_MEMBER
@@ -130,7 +132,7 @@
#include "qdeclarativejsengine_p.h"
#include "qdeclarativejslexer_p.h"
#include "qdeclarativejsast_p.h"
-#include "qdeclarativejsnodepool_p.h"
+#include "qdeclarativejsmemorypool_p.h"
./
@@ -208,7 +210,6 @@ QT_QML_BEGIN_NAMESPACE
namespace QDeclarativeJS {
class Engine;
-class NameId;
class QML_PARSER_EXPORT Parser: protected $table
{
@@ -216,7 +217,6 @@ public:
union Value {
int ival;
double dval;
- NameId *sval;
AST::ArgumentList *ArgumentList;
AST::CaseBlock *CaseBlock;
AST::CaseClause *CaseClause;
@@ -332,6 +332,9 @@ protected:
inline Value &sym(int index)
{ return sym_stack [tos + index - 1]; }
+ inline QStringRef &stringRef(int index)
+ { return string_stack [tos + index - 1]; }
+
inline AST::SourceLocation &loc(int index)
{ return location_stack [tos + index - 1]; }
@@ -339,11 +342,13 @@ protected:
protected:
Engine *driver;
+ MemoryPool *pool;
int tos;
int stack_size;
Value *sym_stack;
int *state_stack;
AST::SourceLocation *location_stack;
+ QStringRef *string_stack;
AST::Node *program;
@@ -354,9 +359,11 @@ protected:
int token;
double dval;
AST::SourceLocation loc;
+ QStringRef spell;
};
double yylval;
+ QStringRef yytokenspell;
AST::SourceLocation yylloc;
AST::SourceLocation yyprevlloc;
@@ -397,6 +404,7 @@ void Parser::reallocateStack()
sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value)));
state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));
location_stack = reinterpret_cast<AST::SourceLocation*> (qRealloc(location_stack, stack_size * sizeof(AST::SourceLocation)));
+ string_stack = reinterpret_cast<QStringRef*> (qRealloc(string_stack, stack_size * sizeof(QStringRef)));
}
inline static bool automatic(Engine *driver, int token)
@@ -409,11 +417,13 @@ inline static bool automatic(Engine *driver, int token)
Parser::Parser(Engine *engine):
driver(engine),
+ pool(engine->pool()),
tos(0),
stack_size(0),
sym_stack(0),
state_stack(0),
location_stack(0),
+ string_stack(0),
first_token(0),
last_token(0)
{
@@ -425,6 +435,7 @@ Parser::~Parser()
qFree(sym_stack);
qFree(state_stack);
qFree(location_stack);
+ qFree(string_stack);
}
}
@@ -433,14 +444,14 @@ static inline AST::SourceLocation location(Lexer *lexer)
AST::SourceLocation loc;
loc.offset = lexer->tokenOffset();
loc.length = lexer->tokenLength();
- loc.startLine = lexer->startLineNo();
- loc.startColumn = lexer->startColumnNo();
+ loc.startLine = lexer->tokenStartLine();
+ loc.startColumn = lexer->tokenStartColumn();
return loc;
}
AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
{
- QVarLengthArray<NameId *, 4> nameIds;
+ QVarLengthArray<QStringRef, 4> nameIds;
QVarLengthArray<AST::SourceLocation, 4> locations;
AST::ExpressionNode *it = expr;
@@ -451,12 +462,12 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
}
if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(it)) {
- AST::UiQualifiedId *q = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), idExpr->name);
+ AST::UiQualifiedId *q = new (pool) AST::UiQualifiedId(idExpr->name);
q->identifierToken = idExpr->identifierToken;
AST::UiQualifiedId *currentId = q;
for (int i = nameIds.size() - 1; i != -1; --i) {
- currentId = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), currentId, nameIds[i]);
+ currentId = new (pool) AST::UiQualifiedId(currentId, nameIds[i]);
currentId->identifierToken = locations[i];
}
@@ -492,11 +503,13 @@ bool Parser::parse(int startToken)
if (first_token == last_token) {
yytoken = lexer->lex();
- yylval = lexer->dval();
+ yylval = lexer->tokenValue();
+ yytokenspell = lexer->tokenSpell();
yylloc = location(lexer);
} else {
yytoken = first_token->token;
yylval = first_token->dval;
+ yytokenspell = first_token->spell;
yylloc = first_token->loc;
++first_token;
}
@@ -507,6 +520,7 @@ bool Parser::parse(int startToken)
if (action != ACCEPT_STATE) {
yytoken = -1;
sym(1).dval = yylval;
+ stringRef(1) = yytokenspell;
loc(1) = yylloc;
} else {
--tos;
@@ -574,7 +588,7 @@ case $rule_number: {
UiProgram: UiImportListOpt UiRootMember ;
/.
case $rule_number: {
- sym(1).UiProgram = makeAstNode<AST::UiProgram> (driver->nodePool(), sym(1).UiImportList,
+ sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiImportList,
sym(2).UiObjectMemberList->finish());
} break;
./
@@ -590,15 +604,14 @@ case $rule_number: {
UiImportList: UiImport ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::UiImportList> (driver->nodePool(), sym(1).UiImport);
+ sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImport);
} break;
./
UiImportList: UiImportList UiImport ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::UiImportList> (driver->nodePool(),
- sym(1).UiImportList, sym(2).UiImport);
+ sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImportList, sym(2).UiImport);
} break;
./
@@ -628,7 +641,7 @@ case $rule_number: {
sym(1).UiImport->versionToken = loc(2);
sym(1).UiImport->asToken = loc(3);
sym(1).UiImport->importIdToken = loc(4);
- sym(1).UiImport->importId = sym(4).sval;
+ sym(1).UiImport->importId = stringRef(4);
sym(1).UiImport->semicolonToken = loc(5);
} break;
./
@@ -639,7 +652,7 @@ UiImport: UiImportHead T_AS JsIdentifier T_SEMICOLON ;
case $rule_number: {
sym(1).UiImport->asToken = loc(2);
sym(1).UiImport->importIdToken = loc(3);
- sym(1).UiImport->importId = sym(3).sval;
+ sym(1).UiImport->importId = stringRef(3);
sym(1).UiImport->semicolonToken = loc(4);
} break;
./
@@ -651,10 +664,10 @@ case $rule_number: {
AST::UiImport *node = 0;
if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) {
- node = makeAstNode<AST::UiImport>(driver->nodePool(), importIdLiteral->value);
+ node = new (pool) AST::UiImport(importIdLiteral->value);
node->fileNameToken = loc(2);
} else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) {
- node = makeAstNode<AST::UiImport>(driver->nodePool(), qualifiedId);
+ node = new (pool) AST::UiImport(qualifiedId);
node->fileNameToken = loc(2);
}
@@ -681,21 +694,21 @@ case $rule_number: {
UiRootMember: UiObjectDefinition ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+ sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
} break;
./
UiObjectMemberList: UiObjectMember ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+ sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
} break;
./
UiObjectMemberList: UiObjectMemberList UiObjectMember ;
/.
case $rule_number: {
- AST::UiObjectMemberList *node = makeAstNode<AST:: UiObjectMemberList> (driver->nodePool(),
+ AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(
sym(1).UiObjectMemberList, sym(2).UiObjectMember);
sym(1).Node = node;
} break;
@@ -704,14 +717,14 @@ case $rule_number: {
UiArrayMemberList: UiObjectDefinition ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+ sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember);
} break;
./
UiArrayMemberList: UiArrayMemberList T_COMMA UiObjectDefinition ;
/.
case $rule_number: {
- AST::UiArrayMemberList *node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(),
+ AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(
sym(1).UiArrayMemberList, sym(3).UiObjectMember);
node->commaToken = loc(2);
sym(1).Node = node;
@@ -721,7 +734,7 @@ case $rule_number: {
UiObjectInitializer: T_LBRACE T_RBRACE ;
/.
case $rule_number: {
- AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), (AST::UiObjectMemberList*)0);
+ AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0);
node->lbraceToken = loc(1);
node->rbraceToken = loc(2);
sym(1).Node = node;
@@ -731,7 +744,7 @@ case $rule_number: {
UiObjectInitializer: T_LBRACE UiObjectMemberList T_RBRACE ;
/.
case $rule_number: {
- AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), sym(2).UiObjectMemberList->finish());
+ AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish());
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
@@ -741,7 +754,7 @@ case $rule_number: {
UiObjectDefinition: UiQualifiedId UiObjectInitializer ;
/.
case $rule_number: {
- AST::UiObjectDefinition *node = makeAstNode<AST::UiObjectDefinition> (driver->nodePool(), sym(1).UiQualifiedId,
+ AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId,
sym(2).UiObjectInitializer);
sym(1).Node = node;
} break;
@@ -752,7 +765,7 @@ UiObjectMember: UiObjectDefinition ;
UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ;
/.
case $rule_number: {
- AST::UiArrayBinding *node = makeAstNode<AST::UiArrayBinding> (driver->nodePool(),
+ AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding(
sym(1).UiQualifiedId, sym(4).UiArrayMemberList->finish());
node->colonToken = loc(2);
node->lbracketToken = loc(3);
@@ -764,7 +777,7 @@ case $rule_number: {
UiObjectMember: UiQualifiedId T_COLON UiQualifiedId UiObjectInitializer ;
/.
case $rule_number: {
- AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+ AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
sym(1).UiQualifiedId, sym(3).UiQualifiedId, sym(4).UiObjectInitializer);
node->colonToken = loc(2);
sym(1).Node = node;
@@ -774,7 +787,7 @@ case $rule_number: {
UiObjectMember: UiQualifiedId T_ON UiQualifiedId UiObjectInitializer ;
/.
case $rule_number: {
- AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+ AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer);
node->colonToken = loc(2);
node->hasOnToken = true;
@@ -791,7 +804,7 @@ UiObjectMember: UiQualifiedId T_COLON UiScriptStatement ;
/.
case $rule_number:
{
- AST::UiScriptBinding *node = makeAstNode<AST::UiScriptBinding> (driver->nodePool(),
+ AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(
sym(1).UiQualifiedId, sym(3).Statement);
node->colonToken = loc(2);
sym(1).Node = node;
@@ -799,17 +812,7 @@ case $rule_number:
./
UiPropertyType: T_VAR ;
-/.
-case $rule_number:
-./
UiPropertyType: T_RESERVED_WORD ;
-/.
-case $rule_number: {
- sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
- break;
-}
-./
-
UiPropertyType: T_IDENTIFIER ;
UiParameterListOpt: ;
@@ -829,7 +832,7 @@ case $rule_number: {
UiParameterList: UiPropertyType JsIdentifier ;
/.
case $rule_number: {
- AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).sval, sym(2).sval);
+ AST::UiParameterList *node = new (pool) AST::UiParameterList(stringRef(1), stringRef(2));
node->identifierToken = loc(2);
sym(1).Node = node;
} break;
@@ -838,7 +841,7 @@ case $rule_number: {
UiParameterList: UiParameterList T_COMMA UiPropertyType JsIdentifier ;
/.
case $rule_number: {
- AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).UiParameterList, sym(3).sval, sym(4).sval);
+ AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, stringRef(3), stringRef(4));
node->commaToken = loc(2);
node->identifierToken = loc(4);
sym(1).Node = node;
@@ -849,7 +852,7 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_AUT
UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_SEMICOLON ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(QStringRef(), stringRef(2));
node->type = AST::UiPublicMember::Signal;
node->propertyToken = loc(1);
node->typeToken = loc(2);
@@ -864,7 +867,7 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER T_AUTOMATIC_SEMICOLON ;
UiObjectMember: T_SIGNAL T_IDENTIFIER T_SEMICOLON ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(QStringRef(), stringRef(2));
node->type = AST::UiPublicMember::Signal;
node->propertyToken = loc(1);
node->typeToken = loc(2);
@@ -878,8 +881,8 @@ UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_
UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_SEMICOLON ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
- node->typeModifier = sym(2).sval;
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(4), stringRef(6));
+ node->typeModifier = stringRef(2);
node->propertyToken = loc(1);
node->typeModifierToken = loc(2);
node->typeToken = loc(4);
@@ -893,7 +896,7 @@ UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_AUTOMATIC_SEMICOLON ;
UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_SEMICOLON ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3));
node->propertyToken = loc(1);
node->typeToken = loc(2);
node->identifierToken = loc(3);
@@ -906,7 +909,7 @@ UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_AUTOMATIC_SEM
UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_SEMICOLON ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4));
node->isDefaultMember = true;
node->defaultToken = loc(1);
node->propertyToken = loc(2);
@@ -920,7 +923,7 @@ case $rule_number: {
UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval,
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3),
sym(5).Statement);
node->propertyToken = loc(1);
node->typeToken = loc(2);
@@ -933,7 +936,7 @@ case $rule_number: {
UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4),
sym(6).Statement);
node->isReadonlyMember = true;
node->readonlyToken = loc(1);
@@ -948,7 +951,7 @@ case $rule_number: {
UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4),
sym(6).Statement);
node->isDefaultMember = true;
node->defaultToken = loc(1);
@@ -963,19 +966,19 @@ case $rule_number: {
UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
- node->typeModifier = sym(2).sval;
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(4), stringRef(6));
+ node->typeModifier = stringRef(2);
node->propertyToken = loc(1);
node->typeModifierToken = loc(2);
node->typeToken = loc(4);
node->identifierToken = loc(6);
node->semicolonToken = loc(7); // insert a fake ';' before ':'
- AST::UiQualifiedId *propertyName = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), sym(6).sval);
+ AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6));
propertyName->identifierToken = loc(6);
propertyName->next = 0;
- AST::UiArrayBinding *binding = makeAstNode<AST::UiArrayBinding> (driver->nodePool(),
+ AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(
propertyName, sym(9).UiArrayMemberList->finish());
binding->colonToken = loc(7);
binding->lbracketToken = loc(8);
@@ -990,17 +993,17 @@ case $rule_number: {
UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiQualifiedId UiObjectInitializer ;
/.
case $rule_number: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3));
node->propertyToken = loc(1);
node->typeToken = loc(2);
node->identifierToken = loc(3);
node->semicolonToken = loc(4); // insert a fake ';' before ':'
- AST::UiQualifiedId *propertyName = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), sym(3).sval);
+ AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3));
propertyName->identifierToken = loc(3);
propertyName->next = 0;
- AST::UiObjectBinding *binding = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+ AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer);
binding->colonToken = loc(4);
@@ -1013,54 +1016,23 @@ case $rule_number: {
UiObjectMember: FunctionDeclaration ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
+ sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
} break;
./
UiObjectMember: VariableStatement ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
+ sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
} break;
./
JsIdentifier: T_IDENTIFIER;
JsIdentifier: T_PROPERTY ;
-/.
-case $rule_number: {
- QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_PROPERTY]);
- sym(1).sval = driver->intern(s.constData(), s.length());
- break;
-}
-./
-
JsIdentifier: T_SIGNAL ;
-/.
-case $rule_number: {
- QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_SIGNAL]);
- sym(1).sval = driver->intern(s.constData(), s.length());
- break;
-}
-./
-
JsIdentifier: T_READONLY ;
-/.
-case $rule_number: {
- QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_READONLY]);
- sym(1).sval = driver->intern(s.constData(), s.length());
- break;
-}
-./
-
JsIdentifier: T_ON ;
-/.
-case $rule_number: {
- QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_ON]);
- sym(1).sval = driver->intern(s.constData(), s.length());
- break;
-}
-./
--------------------------------------------------------------------------------------------------------
-- Expressions
@@ -1069,7 +1041,7 @@ case $rule_number: {
PrimaryExpression: T_THIS ;
/.
case $rule_number: {
- AST::ThisExpression *node = makeAstNode<AST::ThisExpression> (driver->nodePool());
+ AST::ThisExpression *node = new (pool) AST::ThisExpression();
node->thisToken = loc(1);
sym(1).Node = node;
} break;
@@ -1078,7 +1050,7 @@ case $rule_number: {
PrimaryExpression: JsIdentifier ;
/.
case $rule_number: {
- AST::IdentifierExpression *node = makeAstNode<AST::IdentifierExpression> (driver->nodePool(), sym(1).sval);
+ AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
@@ -1087,7 +1059,7 @@ case $rule_number: {
PrimaryExpression: T_NULL ;
/.
case $rule_number: {
- AST::NullExpression *node = makeAstNode<AST::NullExpression> (driver->nodePool());
+ AST::NullExpression *node = new (pool) AST::NullExpression();
node->nullToken = loc(1);
sym(1).Node = node;
} break;
@@ -1096,7 +1068,7 @@ case $rule_number: {
PrimaryExpression: T_TRUE ;
/.
case $rule_number: {
- AST::TrueLiteral *node = makeAstNode<AST::TrueLiteral> (driver->nodePool());
+ AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
node->trueToken = loc(1);
sym(1).Node = node;
} break;
@@ -1105,7 +1077,7 @@ case $rule_number: {
PrimaryExpression: T_FALSE ;
/.
case $rule_number: {
- AST::FalseLiteral *node = makeAstNode<AST::FalseLiteral> (driver->nodePool());
+ AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
node->falseToken = loc(1);
sym(1).Node = node;
} break;
@@ -1114,7 +1086,7 @@ case $rule_number: {
PrimaryExpression: T_NUMERIC_LITERAL ;
/.
case $rule_number: {
- AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval);
+ AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
node->literalToken = loc(1);
sym(1).Node = node;
} break;
@@ -1126,7 +1098,7 @@ PrimaryExpression: T_MULTILINE_STRING_LITERAL ;
PrimaryExpression: T_STRING_LITERAL ;
/.
case $rule_number: {
- AST::StringLiteral *node = makeAstNode<AST::StringLiteral> (driver->nodePool(), sym(1).sval);
+ AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
node->literalToken = loc(1);
sym(1).Node = node;
} break;
@@ -1146,7 +1118,8 @@ case $rule_number: {
loc(1).length = lexer->tokenLength();
- AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
+ AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
+ driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
node->literalToken = loc(1);
sym(1).Node = node;
} break;
@@ -1166,7 +1139,8 @@ case $rule_number: {
loc(1).length = lexer->tokenLength();
- AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
+ AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
+ driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
node->literalToken = loc(1);
sym(1).Node = node;
} break;
@@ -1175,7 +1149,7 @@ case $rule_number: {
PrimaryExpression: T_LBRACKET T_RBRACKET ;
/.
case $rule_number: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), (AST::Elision *) 0);
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
node->lbracketToken = loc(1);
node->rbracketToken = loc(2);
sym(1).Node = node;
@@ -1185,7 +1159,7 @@ case $rule_number: {
PrimaryExpression: T_LBRACKET Elision T_RBRACKET ;
/.
case $rule_number: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).Elision->finish());
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
@@ -1195,7 +1169,7 @@ case $rule_number: {
PrimaryExpression: T_LBRACKET ElementList T_RBRACKET ;
/.
case $rule_number: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish ());
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
@@ -1205,7 +1179,7 @@ case $rule_number: {
PrimaryExpression: T_LBRACKET ElementList T_COMMA T_RBRACKET ;
/.
case $rule_number: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
(AST::Elision *) 0);
node->lbracketToken = loc(1);
node->commaToken = loc(3);
@@ -1217,7 +1191,7 @@ case $rule_number: {
PrimaryExpression: T_LBRACKET ElementList T_COMMA Elision T_RBRACKET ;
/.
case $rule_number: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
sym(4).Elision->finish());
node->lbracketToken = loc(1);
node->commaToken = loc(3);
@@ -1229,7 +1203,7 @@ case $rule_number: {
-- PrimaryExpression: T_LBRACE T_RBRACE ;
-- /.
-- case $rule_number: {
--- sym(1).Node = makeAstNode<AST::ObjectLiteral> (driver->nodePool());
+-- sym(1).Node = new (pool) AST::ObjectLiteral();
-- } break;
-- ./
@@ -1238,10 +1212,10 @@ PrimaryExpression: T_LBRACE PropertyNameAndValueListOpt T_RBRACE ;
case $rule_number: {
AST::ObjectLiteral *node = 0;
if (sym(2).Node)
- node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
+ node = new (pool) AST::ObjectLiteral(
sym(2).PropertyNameAndValueList->finish ());
else
- node = makeAstNode<AST::ObjectLiteral> (driver->nodePool());
+ node = new (pool) AST::ObjectLiteral();
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
@@ -1251,7 +1225,7 @@ case $rule_number: {
PrimaryExpression: T_LBRACE PropertyNameAndValueList T_COMMA T_RBRACE ;
/.
case $rule_number: {
- AST::ObjectLiteral *node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
+ AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
sym(2).PropertyNameAndValueList->finish ());
node->lbraceToken = loc(1);
node->rbraceToken = loc(4);
@@ -1262,7 +1236,7 @@ case $rule_number: {
PrimaryExpression: T_LPAREN Expression T_RPAREN ;
/.
case $rule_number: {
- AST::NestedExpression *node = makeAstNode<AST::NestedExpression>(driver->nodePool(), sym(2).Expression);
+ AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
node->lparenToken = loc(1);
node->rparenToken = loc(3);
sym(1).Node = node;
@@ -1295,21 +1269,21 @@ case $rule_number: {
ElementList: AssignmentExpression ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), (AST::Elision *) 0, sym(1).Expression);
+ sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
} break;
./
ElementList: Elision AssignmentExpression ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).Elision->finish(), sym(2).Expression);
+ sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
} break;
./
ElementList: ElementList T_COMMA AssignmentExpression ;
/.
case $rule_number: {
- AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList,
+ AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
(AST::Elision *) 0, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
@@ -1319,7 +1293,7 @@ case $rule_number: {
ElementList: ElementList T_COMMA Elision AssignmentExpression ;
/.
case $rule_number: {
- AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList, sym(3).Elision->finish(),
+ AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(),
sym(4).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
@@ -1329,7 +1303,7 @@ case $rule_number: {
Elision: T_COMMA ;
/.
case $rule_number: {
- AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool());
+ AST::Elision *node = new (pool) AST::Elision();
node->commaToken = loc(1);
sym(1).Node = node;
} break;
@@ -1338,7 +1312,7 @@ case $rule_number: {
Elision: Elision T_COMMA ;
/.
case $rule_number: {
- AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool(), sym(1).Elision);
+ AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
@@ -1347,7 +1321,7 @@ case $rule_number: {
PropertyNameAndValueList: PropertyName T_COLON AssignmentExpression ;
/.
case $rule_number: {
- AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
+ AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
sym(1).PropertyName, sym(3).Expression);
node->colonToken = loc(2);
sym(1).Node = node;
@@ -1357,7 +1331,7 @@ case $rule_number: {
PropertyNameAndValueList: PropertyNameAndValueList T_COMMA PropertyName T_COLON AssignmentExpression ;
/.
case $rule_number: {
- AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
+ AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression);
node->commaToken = loc(2);
node->colonToken = loc(4);
@@ -1368,7 +1342,7 @@ case $rule_number: {
PropertyName: T_IDENTIFIER %prec SHIFT_THERE ;
/.
case $rule_number: {
- AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
+ AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
@@ -1380,7 +1354,7 @@ PropertyName: T_SIGNAL ;
PropertyName: T_PROPERTY ;
/.
case $rule_number: {
- AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()));
+ AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
@@ -1389,7 +1363,7 @@ case $rule_number: {
PropertyName: T_STRING_LITERAL ;
/.
case $rule_number: {
- AST::StringLiteralPropertyName *node = makeAstNode<AST::StringLiteralPropertyName> (driver->nodePool(), sym(1).sval);
+ AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
@@ -1398,7 +1372,7 @@ case $rule_number: {
PropertyName: T_NUMERIC_LITERAL ;
/.
case $rule_number: {
- AST::NumericLiteralPropertyName *node = makeAstNode<AST::NumericLiteralPropertyName> (driver->nodePool(), sym(1).dval);
+ AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
@@ -1407,139 +1381,43 @@ case $rule_number: {
PropertyName: ReservedIdentifier ;
/.
case $rule_number: {
- AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
+ AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
./
ReservedIdentifier: T_BREAK ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_CASE ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_CATCH ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_CONTINUE ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_DEFAULT ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_DELETE ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_DO ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_ELSE ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_FALSE ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_FINALLY ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_FOR ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_FUNCTION ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_IF ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_IN ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_INSTANCEOF ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_NEW ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_NULL ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_RETURN ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_SWITCH ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_THIS ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_THROW ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_TRUE ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_TRY ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_TYPEOF ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_VAR ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_VOID ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_WHILE ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_CONST ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_DEBUGGER ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_RESERVED_WORD ;
-/.
-case $rule_number:
-./
ReservedIdentifier: T_WITH ;
-/.
-case $rule_number:
-{
- sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
-} break;
-./
PropertyIdentifier: JsIdentifier ;
PropertyIdentifier: ReservedIdentifier ;
@@ -1550,7 +1428,7 @@ MemberExpression: FunctionExpression ;
MemberExpression: MemberExpression T_LBRACKET Expression T_RBRACKET ;
/.
case $rule_number: {
- AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+ AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
@@ -1560,7 +1438,7 @@ case $rule_number: {
MemberExpression: MemberExpression T_DOT PropertyIdentifier ;
/.
case $rule_number: {
- AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
+ AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
@@ -1570,7 +1448,7 @@ case $rule_number: {
MemberExpression: T_NEW MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ;
/.
case $rule_number: {
- AST::NewMemberExpression *node = makeAstNode<AST::NewMemberExpression> (driver->nodePool(), sym(2).Expression, sym(4).ArgumentList);
+ AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
node->newToken = loc(1);
node->lparenToken = loc(3);
node->rparenToken = loc(5);
@@ -1583,7 +1461,7 @@ NewExpression: MemberExpression ;
NewExpression: T_NEW NewExpression ;
/.
case $rule_number: {
- AST::NewExpression *node = makeAstNode<AST::NewExpression> (driver->nodePool(), sym(2).Expression);
+ AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
node->newToken = loc(1);
sym(1).Node = node;
} break;
@@ -1592,7 +1470,7 @@ case $rule_number: {
CallExpression: MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ;
/.
case $rule_number: {
- AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
+ AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
@@ -1602,7 +1480,7 @@ case $rule_number: {
CallExpression: CallExpression T_LPAREN ArgumentListOpt T_RPAREN ;
/.
case $rule_number: {
- AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
+ AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
@@ -1612,7 +1490,7 @@ case $rule_number: {
CallExpression: CallExpression T_LBRACKET Expression T_RBRACKET ;
/.
case $rule_number: {
- AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+ AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
@@ -1622,7 +1500,7 @@ case $rule_number: {
CallExpression: CallExpression T_DOT PropertyIdentifier ;
/.
case $rule_number: {
- AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
+ AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
@@ -1646,14 +1524,14 @@ case $rule_number: {
ArgumentList: AssignmentExpression ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).Expression);
+ sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
} break;
./
ArgumentList: ArgumentList T_COMMA AssignmentExpression ;
/.
case $rule_number: {
- AST::ArgumentList *node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).ArgumentList, sym(3).Expression);
+ AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
@@ -1666,7 +1544,7 @@ PostfixExpression: LeftHandSideExpression ;
PostfixExpression: LeftHandSideExpression T_PLUS_PLUS ;
/.
case $rule_number: {
- AST::PostIncrementExpression *node = makeAstNode<AST::PostIncrementExpression> (driver->nodePool(), sym(1).Expression);
+ AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
node->incrementToken = loc(2);
sym(1).Node = node;
} break;
@@ -1675,7 +1553,7 @@ case $rule_number: {
PostfixExpression: LeftHandSideExpression T_MINUS_MINUS ;
/.
case $rule_number: {
- AST::PostDecrementExpression *node = makeAstNode<AST::PostDecrementExpression> (driver->nodePool(), sym(1).Expression);
+ AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
node->decrementToken = loc(2);
sym(1).Node = node;
} break;
@@ -1686,7 +1564,7 @@ UnaryExpression: PostfixExpression ;
UnaryExpression: T_DELETE UnaryExpression ;
/.
case $rule_number: {
- AST::DeleteExpression *node = makeAstNode<AST::DeleteExpression> (driver->nodePool(), sym(2).Expression);
+ AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
node->deleteToken = loc(1);
sym(1).Node = node;
} break;
@@ -1695,7 +1573,7 @@ case $rule_number: {
UnaryExpression: T_VOID UnaryExpression ;
/.
case $rule_number: {
- AST::VoidExpression *node = makeAstNode<AST::VoidExpression> (driver->nodePool(), sym(2).Expression);
+ AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
node->voidToken = loc(1);
sym(1).Node = node;
} break;
@@ -1704,7 +1582,7 @@ case $rule_number: {
UnaryExpression: T_TYPEOF UnaryExpression ;
/.
case $rule_number: {
- AST::TypeOfExpression *node = makeAstNode<AST::TypeOfExpression> (driver->nodePool(), sym(2).Expression);
+ AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
node->typeofToken = loc(1);
sym(1).Node = node;
} break;
@@ -1713,7 +1591,7 @@ case $rule_number: {
UnaryExpression: T_PLUS_PLUS UnaryExpression ;
/.
case $rule_number: {
- AST::PreIncrementExpression *node = makeAstNode<AST::PreIncrementExpression> (driver->nodePool(), sym(2).Expression);
+ AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
node->incrementToken = loc(1);
sym(1).Node = node;
} break;
@@ -1722,7 +1600,7 @@ case $rule_number: {
UnaryExpression: T_MINUS_MINUS UnaryExpression ;
/.
case $rule_number: {
- AST::PreDecrementExpression *node = makeAstNode<AST::PreDecrementExpression> (driver->nodePool(), sym(2).Expression);
+ AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
node->decrementToken = loc(1);
sym(1).Node = node;
} break;
@@ -1731,7 +1609,7 @@ case $rule_number: {
UnaryExpression: T_PLUS UnaryExpression ;
/.
case $rule_number: {
- AST::UnaryPlusExpression *node = makeAstNode<AST::UnaryPlusExpression> (driver->nodePool(), sym(2).Expression);
+ AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
node->plusToken = loc(1);
sym(1).Node = node;
} break;
@@ -1740,7 +1618,7 @@ case $rule_number: {
UnaryExpression: T_MINUS UnaryExpression ;
/.
case $rule_number: {
- AST::UnaryMinusExpression *node = makeAstNode<AST::UnaryMinusExpression> (driver->nodePool(), sym(2).Expression);
+ AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
node->minusToken = loc(1);
sym(1).Node = node;
} break;
@@ -1749,7 +1627,7 @@ case $rule_number: {
UnaryExpression: T_TILDE UnaryExpression ;
/.
case $rule_number: {
- AST::TildeExpression *node = makeAstNode<AST::TildeExpression> (driver->nodePool(), sym(2).Expression);
+ AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
node->tildeToken = loc(1);
sym(1).Node = node;
} break;
@@ -1758,7 +1636,7 @@ case $rule_number: {
UnaryExpression: T_NOT UnaryExpression ;
/.
case $rule_number: {
- AST::NotExpression *node = makeAstNode<AST::NotExpression> (driver->nodePool(), sym(2).Expression);
+ AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
node->notToken = loc(1);
sym(1).Node = node;
} break;
@@ -1769,7 +1647,7 @@ MultiplicativeExpression: UnaryExpression ;
MultiplicativeExpression: MultiplicativeExpression T_STAR UnaryExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mul, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1779,7 +1657,7 @@ case $rule_number: {
MultiplicativeExpression: MultiplicativeExpression T_DIVIDE_ UnaryExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Div, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1789,7 +1667,7 @@ case $rule_number: {
MultiplicativeExpression: MultiplicativeExpression T_REMAINDER UnaryExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mod, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1801,7 +1679,7 @@ AdditiveExpression: MultiplicativeExpression ;
AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Add, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1811,7 +1689,7 @@ case $rule_number: {
AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Sub, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1823,7 +1701,7 @@ ShiftExpression: AdditiveExpression ;
ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::LShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1833,7 +1711,7 @@ case $rule_number: {
ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::RShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1843,7 +1721,7 @@ case $rule_number: {
ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::URShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1855,7 +1733,7 @@ RelationalExpression: ShiftExpression ;
RelationalExpression: RelationalExpression T_LT ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1865,7 +1743,7 @@ case $rule_number: {
RelationalExpression: RelationalExpression T_GT ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1875,7 +1753,7 @@ case $rule_number: {
RelationalExpression: RelationalExpression T_LE ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1885,7 +1763,7 @@ case $rule_number: {
RelationalExpression: RelationalExpression T_GE ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1895,7 +1773,7 @@ case $rule_number: {
RelationalExpression: RelationalExpression T_INSTANCEOF ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1905,7 +1783,7 @@ case $rule_number: {
RelationalExpression: RelationalExpression T_IN ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::In, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1917,7 +1795,7 @@ RelationalExpressionNotIn: ShiftExpression ;
RelationalExpressionNotIn: RelationalExpressionNotIn T_LT ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1927,7 +1805,7 @@ case $rule_number: {
RelationalExpressionNotIn: RelationalExpressionNotIn T_GT ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1937,7 +1815,7 @@ case $rule_number: {
RelationalExpressionNotIn: RelationalExpressionNotIn T_LE ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1947,7 +1825,7 @@ case $rule_number: {
RelationalExpressionNotIn: RelationalExpressionNotIn T_GE ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1957,7 +1835,7 @@ case $rule_number: {
RelationalExpressionNotIn: RelationalExpressionNotIn T_INSTANCEOF ShiftExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1969,7 +1847,7 @@ EqualityExpression: RelationalExpression ;
EqualityExpression: EqualityExpression T_EQ_EQ RelationalExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1979,7 +1857,7 @@ case $rule_number: {
EqualityExpression: EqualityExpression T_NOT_EQ RelationalExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1989,7 +1867,7 @@ case $rule_number: {
EqualityExpression: EqualityExpression T_EQ_EQ_EQ RelationalExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1999,7 +1877,7 @@ case $rule_number: {
EqualityExpression: EqualityExpression T_NOT_EQ_EQ RelationalExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2011,7 +1889,7 @@ EqualityExpressionNotIn: RelationalExpressionNotIn ;
EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ RelationalExpressionNotIn ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2021,7 +1899,7 @@ case $rule_number: {
EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ RelationalExpressionNotIn;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2031,7 +1909,7 @@ case $rule_number: {
EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ_EQ RelationalExpressionNotIn ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2041,7 +1919,7 @@ case $rule_number: {
EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ_EQ RelationalExpressionNotIn ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2053,7 +1931,7 @@ BitwiseANDExpression: EqualityExpression ;
BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2065,7 +1943,7 @@ BitwiseANDExpressionNotIn: EqualityExpressionNotIn ;
BitwiseANDExpressionNotIn: BitwiseANDExpressionNotIn T_AND EqualityExpressionNotIn ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2077,7 +1955,7 @@ BitwiseXORExpression: BitwiseANDExpression ;
BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2089,7 +1967,7 @@ BitwiseXORExpressionNotIn: BitwiseANDExpressionNotIn ;
BitwiseXORExpressionNotIn: BitwiseXORExpressionNotIn T_XOR BitwiseANDExpressionNotIn ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2101,7 +1979,7 @@ BitwiseORExpression: BitwiseXORExpression ;
BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2113,7 +1991,7 @@ BitwiseORExpressionNotIn: BitwiseXORExpressionNotIn ;
BitwiseORExpressionNotIn: BitwiseORExpressionNotIn T_OR BitwiseXORExpressionNotIn ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2125,7 +2003,7 @@ LogicalANDExpression: BitwiseORExpression ;
LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2137,7 +2015,7 @@ LogicalANDExpressionNotIn: BitwiseORExpressionNotIn ;
LogicalANDExpressionNotIn: LogicalANDExpressionNotIn T_AND_AND BitwiseORExpressionNotIn ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2149,7 +2027,7 @@ LogicalORExpression: LogicalANDExpression ;
LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2161,7 +2039,7 @@ LogicalORExpressionNotIn: LogicalANDExpressionNotIn ;
LogicalORExpressionNotIn: LogicalORExpressionNotIn T_OR_OR LogicalANDExpressionNotIn ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2173,7 +2051,7 @@ ConditionalExpression: LogicalORExpression ;
ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression ;
/.
case $rule_number: {
- AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
+ AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
node->colonToken = loc(4);
@@ -2186,7 +2064,7 @@ ConditionalExpressionNotIn: LogicalORExpressionNotIn ;
ConditionalExpressionNotIn: LogicalORExpressionNotIn T_QUESTION AssignmentExpressionNotIn T_COLON AssignmentExpressionNotIn ;
/.
case $rule_number: {
- AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
+ AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
node->colonToken = loc(4);
@@ -2199,7 +2077,7 @@ AssignmentExpression: ConditionalExpression ;
AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2211,7 +2089,7 @@ AssignmentExpressionNotIn: ConditionalExpressionNotIn ;
AssignmentExpressionNotIn: LeftHandSideExpression AssignmentOperator AssignmentExpressionNotIn ;
/.
case $rule_number: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -2307,7 +2185,7 @@ Expression: AssignmentExpression ;
Expression: Expression T_COMMA AssignmentExpression ;
/.
case $rule_number: {
- AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+ AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
@@ -2327,7 +2205,7 @@ ExpressionNotIn: AssignmentExpressionNotIn ;
ExpressionNotIn: ExpressionNotIn T_COMMA AssignmentExpressionNotIn ;
/.
case $rule_number: {
- AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+ AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
@@ -2362,7 +2240,7 @@ Statement: DebuggerStatement ;
Block: T_LBRACE StatementListOpt T_RBRACE ;
/.
case $rule_number: {
- AST::Block *node = makeAstNode<AST::Block> (driver->nodePool(), sym(2).StatementList);
+ AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
@@ -2372,14 +2250,14 @@ case $rule_number: {
StatementList: Statement ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).Statement);
+ sym(1).Node = new (pool) AST::StatementList(sym(1).Statement);
} break;
./
StatementList: StatementList Statement ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).StatementList, sym(2).Statement);
+ sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement);
} break;
./
@@ -2401,7 +2279,7 @@ VariableStatement: VariableDeclarationKind VariableDeclarationList T_AUTOMATIC_S
VariableStatement: VariableDeclarationKind VariableDeclarationList T_SEMICOLON ;
/.
case $rule_number: {
- AST::VariableStatement *node = makeAstNode<AST::VariableStatement> (driver->nodePool(),
+ AST::VariableStatement *node = new (pool) AST::VariableStatement(
sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
node->declarationKindToken = loc(1);
node->semicolonToken = loc(3);
@@ -2426,14 +2304,14 @@ case $rule_number: {
VariableDeclarationList: VariableDeclaration ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
+ sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
./
VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration ;
/.
case $rule_number: {
- AST::VariableDeclarationList *node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(),
+ AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(
sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
node->commaToken = loc(2);
sym(1).Node = node;
@@ -2443,21 +2321,21 @@ case $rule_number: {
VariableDeclarationListNotIn: VariableDeclarationNotIn ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
+ sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
./
VariableDeclarationListNotIn: VariableDeclarationListNotIn T_COMMA VariableDeclarationNotIn ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
+ sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
} break;
./
VariableDeclaration: JsIdentifier InitialiserOpt ;
/.
case $rule_number: {
- AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
+ AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
@@ -2466,7 +2344,7 @@ case $rule_number: {
VariableDeclarationNotIn: JsIdentifier InitialiserNotInOpt ;
/.
case $rule_number: {
- AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
+ AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
@@ -2509,7 +2387,7 @@ InitialiserNotInOpt: InitialiserNotIn ;
EmptyStatement: T_SEMICOLON ;
/.
case $rule_number: {
- AST::EmptyStatement *node = makeAstNode<AST::EmptyStatement> (driver->nodePool());
+ AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
node->semicolonToken = loc(1);
sym(1).Node = node;
} break;
@@ -2519,7 +2397,7 @@ ExpressionStatement: Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
ExpressionStatement: Expression T_SEMICOLON ;
/.
case $rule_number: {
- AST::ExpressionStatement *node = makeAstNode<AST::ExpressionStatement> (driver->nodePool(), sym(1).Expression);
+ AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
@@ -2528,11 +2406,11 @@ case $rule_number: {
IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement T_ELSE Statement ;
/.
case $rule_number: {
- AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement, sym(7).Statement);
+ AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
- node->elseToken = loc(5);
+ node->elseToken = loc(6);
sym(1).Node = node;
} break;
./
@@ -2540,7 +2418,7 @@ case $rule_number: {
IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement ;
/.
case $rule_number: {
- AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+ AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
@@ -2553,7 +2431,7 @@ IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_AUTOMA
IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_SEMICOLON ;
/.
case $rule_number: {
- AST::DoWhileStatement *node = makeAstNode<AST::DoWhileStatement> (driver->nodePool(), sym(2).Statement, sym(5).Expression);
+ AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
node->doToken = loc(1);
node->whileToken = loc(3);
node->lparenToken = loc(4);
@@ -2566,7 +2444,7 @@ case $rule_number: {
IterationStatement: T_WHILE T_LPAREN Expression T_RPAREN Statement ;
/.
case $rule_number: {
- AST::WhileStatement *node = makeAstNode<AST::WhileStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+ AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
node->whileToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
@@ -2577,7 +2455,7 @@ case $rule_number: {
IterationStatement: T_FOR T_LPAREN ExpressionNotInOpt T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
/.
case $rule_number: {
- AST::ForStatement *node = makeAstNode<AST::ForStatement> (driver->nodePool(), sym(3).Expression,
+ AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression,
sym(5).Expression, sym(7).Expression, sym(9).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
@@ -2591,7 +2469,7 @@ case $rule_number: {
IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationListNotIn T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
/.
case $rule_number: {
- AST::LocalForStatement *node = makeAstNode<AST::LocalForStatement> (driver->nodePool(),
+ AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression,
sym(8).Expression, sym(10).Statement);
node->forToken = loc(1);
@@ -2607,7 +2485,7 @@ case $rule_number: {
IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression T_RPAREN Statement ;
/.
case $rule_number: {
- AST:: ForEachStatement *node = makeAstNode<AST::ForEachStatement> (driver->nodePool(), sym(3).Expression,
+ AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression,
sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
@@ -2620,7 +2498,7 @@ case $rule_number: {
IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationNotIn T_IN Expression T_RPAREN Statement ;
/.
case $rule_number: {
- AST::LocalForEachStatement *node = makeAstNode<AST::LocalForEachStatement> (driver->nodePool(),
+ AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(
sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
@@ -2635,7 +2513,7 @@ ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
ContinueStatement: T_CONTINUE T_SEMICOLON ;
/.
case $rule_number: {
- AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool());
+ AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
node->continueToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
@@ -2646,7 +2524,7 @@ ContinueStatement: T_CONTINUE JsIdentifier T_AUTOMATIC_SEMICOLON ; -- automatic
ContinueStatement: T_CONTINUE JsIdentifier T_SEMICOLON ;
/.
case $rule_number: {
- AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool(), sym(2).sval);
+ AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
node->continueToken = loc(1);
node->identifierToken = loc(2);
node->semicolonToken = loc(3);
@@ -2658,7 +2536,7 @@ BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
BreakStatement: T_BREAK T_SEMICOLON ;
/.
case $rule_number: {
- AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool());
+ AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
node->breakToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
@@ -2669,7 +2547,7 @@ BreakStatement: T_BREAK JsIdentifier T_AUTOMATIC_SEMICOLON ; -- automatic semic
BreakStatement: T_BREAK JsIdentifier T_SEMICOLON ;
/.
case $rule_number: {
- AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool(), sym(2).sval);
+ AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
node->breakToken = loc(1);
node->identifierToken = loc(2);
node->semicolonToken = loc(3);
@@ -2681,7 +2559,7 @@ ReturnStatement: T_RETURN ExpressionOpt T_AUTOMATIC_SEMICOLON ; -- automatic se
ReturnStatement: T_RETURN ExpressionOpt T_SEMICOLON ;
/.
case $rule_number: {
- AST::ReturnStatement *node = makeAstNode<AST::ReturnStatement> (driver->nodePool(), sym(2).Expression);
+ AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
node->returnToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
@@ -2691,7 +2569,7 @@ case $rule_number: {
WithStatement: T_WITH T_LPAREN Expression T_RPAREN Statement ;
/.
case $rule_number: {
- AST::WithStatement *node = makeAstNode<AST::WithStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+ AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
node->withToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
@@ -2702,7 +2580,7 @@ case $rule_number: {
SwitchStatement: T_SWITCH T_LPAREN Expression T_RPAREN CaseBlock ;
/.
case $rule_number: {
- AST::SwitchStatement *node = makeAstNode<AST::SwitchStatement> (driver->nodePool(), sym(3).Expression, sym(5).CaseBlock);
+ AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
node->switchToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
@@ -2713,7 +2591,7 @@ case $rule_number: {
CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE ;
/.
case $rule_number: {
- AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses);
+ AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
@@ -2723,7 +2601,7 @@ case $rule_number: {
CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE ;
/.
case $rule_number: {
- AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
+ AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(5);
sym(1).Node = node;
@@ -2733,14 +2611,14 @@ case $rule_number: {
CaseClauses: CaseClause ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClause);
+ sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
} break;
./
CaseClauses: CaseClauses CaseClause ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClauses, sym(2).CaseClause);
+ sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
} break;
./
@@ -2761,7 +2639,7 @@ case $rule_number: {
CaseClause: T_CASE Expression T_COLON StatementListOpt ;
/.
case $rule_number: {
- AST::CaseClause *node = makeAstNode<AST::CaseClause> (driver->nodePool(), sym(2).Expression, sym(4).StatementList);
+ AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
node->caseToken = loc(1);
node->colonToken = loc(3);
sym(1).Node = node;
@@ -2771,7 +2649,7 @@ case $rule_number: {
DefaultClause: T_DEFAULT T_COLON StatementListOpt ;
/.
case $rule_number: {
- AST::DefaultClause *node = makeAstNode<AST::DefaultClause> (driver->nodePool(), sym(3).StatementList);
+ AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
node->defaultToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
@@ -2784,7 +2662,7 @@ LabelledStatement: T_SIGNAL T_COLON Statement ;
LabelledStatement: T_PROPERTY T_COLON Statement ;
/.
case $rule_number: {
- AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()), sym(3).Statement);
+ AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
node->identifierToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
@@ -2794,7 +2672,7 @@ case $rule_number: {
LabelledStatement: T_IDENTIFIER T_COLON Statement ;
/.
case $rule_number: {
- AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), sym(1).sval, sym(3).Statement);
+ AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
node->identifierToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
@@ -2805,7 +2683,7 @@ ThrowStatement: T_THROW Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicol
ThrowStatement: T_THROW Expression T_SEMICOLON ;
/.
case $rule_number: {
- AST::ThrowStatement *node = makeAstNode<AST::ThrowStatement> (driver->nodePool(), sym(2).Expression);
+ AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
node->throwToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
@@ -2815,7 +2693,7 @@ case $rule_number: {
TryStatement: T_TRY Block Catch ;
/.
case $rule_number: {
- AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch);
+ AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
@@ -2824,7 +2702,7 @@ case $rule_number: {
TryStatement: T_TRY Block Finally ;
/.
case $rule_number: {
- AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Finally);
+ AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
@@ -2833,7 +2711,7 @@ case $rule_number: {
TryStatement: T_TRY Block Catch Finally ;
/.
case $rule_number: {
- AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch, sym(4).Finally);
+ AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
@@ -2842,7 +2720,7 @@ case $rule_number: {
Catch: T_CATCH T_LPAREN JsIdentifier T_RPAREN Block ;
/.
case $rule_number: {
- AST::Catch *node = makeAstNode<AST::Catch> (driver->nodePool(), sym(3).sval, sym(5).Block);
+ AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
node->catchToken = loc(1);
node->lparenToken = loc(2);
node->identifierToken = loc(3);
@@ -2854,7 +2732,7 @@ case $rule_number: {
Finally: T_FINALLY Block ;
/.
case $rule_number: {
- AST::Finally *node = makeAstNode<AST::Finally> (driver->nodePool(), sym(2).Block);
+ AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
node->finallyToken = loc(1);
sym(1).Node = node;
} break;
@@ -2864,7 +2742,7 @@ DebuggerStatement: T_DEBUGGER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
DebuggerStatement: T_DEBUGGER T_SEMICOLON ;
/.
case $rule_number: {
- AST::DebuggerStatement *node = makeAstNode<AST::DebuggerStatement> (driver->nodePool());
+ AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
node->debuggerToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
@@ -2874,7 +2752,7 @@ case $rule_number: {
FunctionDeclaration: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
/.
case $rule_number: {
- AST::FunctionDeclaration *node = makeAstNode<AST::FunctionDeclaration> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
+ AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
node->identifierToken = loc(2);
node->lparenToken = loc(3);
@@ -2888,9 +2766,9 @@ case $rule_number: {
FunctionExpression: T_FUNCTION IdentifierOpt T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
/.
case $rule_number: {
- AST::FunctionExpression *node = makeAstNode<AST::FunctionExpression> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
+ AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
- if (sym(2).sval)
+ if (! stringRef(2).isNull())
node->identifierToken = loc(2);
node->lparenToken = loc(3);
node->rparenToken = loc(5);
@@ -2903,7 +2781,7 @@ case $rule_number: {
FormalParameterList: JsIdentifier ;
/.
case $rule_number: {
- AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).sval);
+ AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
@@ -2912,7 +2790,7 @@ case $rule_number: {
FormalParameterList: FormalParameterList T_COMMA JsIdentifier ;
/.
case $rule_number: {
- AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).FormalParameterList, sym(3).sval);
+ AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3));
node->commaToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
@@ -2945,49 +2823,49 @@ FunctionBodyOpt: FunctionBody ;
FunctionBody: SourceElements ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::FunctionBody> (driver->nodePool(), sym(1).SourceElements->finish ());
+ sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ());
} break;
./
Program: SourceElements ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::Program> (driver->nodePool(), sym(1).SourceElements->finish ());
+ sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ());
} break;
./
SourceElements: SourceElement ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElement);
+ sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement);
} break;
./
SourceElements: SourceElements SourceElement ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElements, sym(2).SourceElement);
+ sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement);
} break;
./
SourceElement: Statement ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::StatementSourceElement> (driver->nodePool(), sym(1).Statement);
+ sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement);
} break;
./
SourceElement: FunctionDeclaration ;
/.
case $rule_number: {
- sym(1).Node = makeAstNode<AST::FunctionSourceElement> (driver->nodePool(), sym(1).FunctionDeclaration);
+ sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration);
} break;
./
IdentifierOpt: ;
/.
case $rule_number: {
- sym(1).sval = 0;
+ stringRef(1) = QStringRef();
} break;
./
@@ -3016,6 +2894,7 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ;
SavedToken &tk = token_buffer[0];
tk.token = yytoken;
tk.dval = yylval;
+ tk.spell = yytokenspell;
tk.loc = yylloc;
yylloc = yyprevlloc;
@@ -3041,11 +2920,13 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ;
token_buffer[0].token = yytoken;
token_buffer[0].dval = yylval;
+ token_buffer[0].spell = yytokenspell;
token_buffer[0].loc = yylloc;
- token_buffer[1].token = yytoken = lexer->lex();
- token_buffer[1].dval = yylval = lexer->dval();
- token_buffer[1].loc = yylloc = location(lexer);
+ token_buffer[1].token = yytoken = lexer->lex();
+ token_buffer[1].dval = yylval = lexer->tokenValue();
+ token_buffer[1].spell = yytokenspell = lexer->tokenSpell();
+ token_buffer[1].loc = yylloc = location(lexer);
if (t_action(errorState, yytoken)) {
QString msg;
diff --git a/src/declarative/qml/parser/qdeclarativejsast_p.h b/src/declarative/qml/parser/qdeclarativejsast_p.h
index 0fc989c333..b2c441d37b 100644
--- a/src/declarative/qml/parser/qdeclarativejsast_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsast_p.h
@@ -55,6 +55,7 @@
#include "qdeclarativejsastvisitor_p.h"
#include "qdeclarativejsglobal_p.h"
+#include "qdeclarativejsmemorypool_p.h"
#include <QtCore/QString>
@@ -107,7 +108,7 @@ enum Op {
} // namespace QSOperator
namespace QDeclarativeJS {
-class NameId;
+
namespace AST {
template <typename _T1, typename _T2>
@@ -119,7 +120,7 @@ _T1 cast(_T2 *ast)
return 0;
}
-class QML_PARSER_EXPORT Node
+class QML_PARSER_EXPORT Node: public Managed
{
public:
enum Kind {
@@ -273,7 +274,7 @@ class QML_PARSER_EXPORT UiFormal: public Node
public:
QDECLARATIVEJS_DECLARE_AST_NODE(UiFormal)
- UiFormal(NameId *name, NameId *alias = 0)
+ UiFormal(const QStringRef &name, const QStringRef &alias)
: name(name), alias(alias)
{ }
@@ -286,8 +287,8 @@ public:
virtual void accept0(Visitor *visitor);
// attributes
- NameId *name;
- NameId *alias;
+ QStringRef name;
+ QStringRef alias;
SourceLocation identifierToken;
SourceLocation asToken;
SourceLocation aliasToken;
@@ -398,7 +399,7 @@ class QML_PARSER_EXPORT IdentifierExpression: public ExpressionNode
public:
QDECLARATIVEJS_DECLARE_AST_NODE(IdentifierExpression)
- IdentifierExpression(NameId *n):
+ IdentifierExpression(const QStringRef &n):
name (n) { kind = K; }
virtual void accept0(Visitor *visitor);
@@ -410,7 +411,7 @@ public:
{ return identifierToken; }
// attributes
- NameId *name;
+ QStringRef name;
SourceLocation identifierToken;
};
@@ -497,7 +498,7 @@ class QML_PARSER_EXPORT StringLiteral: public ExpressionNode
public:
QDECLARATIVEJS_DECLARE_AST_NODE(StringLiteral)
- StringLiteral(NameId *v):
+ StringLiteral(const QStringRef &v):
value (v) { kind = K; }
virtual void accept0(Visitor *visitor);
@@ -509,7 +510,7 @@ public:
{ return literalToken; }
// attributes:
- NameId *value;
+ QStringRef value;
SourceLocation literalToken;
};
@@ -518,7 +519,7 @@ class QML_PARSER_EXPORT RegExpLiteral: public ExpressionNode
public:
QDECLARATIVEJS_DECLARE_AST_NODE(RegExpLiteral)
- RegExpLiteral(NameId *p, int f):
+ RegExpLiteral(const QStringRef &p, int f):
pattern (p), flags (f) { kind = K; }
virtual void accept0(Visitor *visitor);
@@ -530,7 +531,7 @@ public:
{ return literalToken; }
// attributes:
- NameId *pattern;
+ QStringRef pattern;
int flags;
SourceLocation literalToken;
};
@@ -705,13 +706,13 @@ class QML_PARSER_EXPORT IdentifierPropertyName: public PropertyName
public:
QDECLARATIVEJS_DECLARE_AST_NODE(IdentifierPropertyName)
- IdentifierPropertyName(NameId *n):
+ IdentifierPropertyName(const QStringRef &n):
id (n) { kind = K; }
virtual void accept0(Visitor *visitor);
// attributes
- NameId *id;
+ QStringRef id;
};
class QML_PARSER_EXPORT StringLiteralPropertyName: public PropertyName
@@ -719,13 +720,13 @@ class QML_PARSER_EXPORT StringLiteralPropertyName: public PropertyName
public:
QDECLARATIVEJS_DECLARE_AST_NODE(StringLiteralPropertyName)
- StringLiteralPropertyName(NameId *n):
+ StringLiteralPropertyName(const QStringRef &n):
id (n) { kind = K; }
virtual void accept0(Visitor *visitor);
// attributes
- NameId *id;
+ QStringRef id;
};
class QML_PARSER_EXPORT NumericLiteralPropertyName: public PropertyName
@@ -771,7 +772,7 @@ class QML_PARSER_EXPORT FieldMemberExpression: public ExpressionNode
public:
QDECLARATIVEJS_DECLARE_AST_NODE(FieldMemberExpression)
- FieldMemberExpression(ExpressionNode *b, NameId *n):
+ FieldMemberExpression(ExpressionNode *b, const QStringRef &n):
base (b), name (n)
{ kind = K; }
@@ -785,7 +786,7 @@ public:
// attributes
ExpressionNode *base;
- NameId *name;
+ QStringRef name;
SourceLocation dotToken;
SourceLocation identifierToken;
};
@@ -1277,14 +1278,14 @@ class QML_PARSER_EXPORT VariableDeclaration: public Node
public:
QDECLARATIVEJS_DECLARE_AST_NODE(VariableDeclaration)
- VariableDeclaration(NameId *n, ExpressionNode *e):
+ VariableDeclaration(const QStringRef &n, ExpressionNode *e):
name (n), expression (e), readOnly(false)
{ kind = K; }
virtual void accept0(Visitor *visitor);
// attributes
- NameId *name;
+ QStringRef name;
ExpressionNode *expression;
bool readOnly;
SourceLocation identifierToken;
@@ -1570,7 +1571,7 @@ class QML_PARSER_EXPORT ContinueStatement: public Statement
public:
QDECLARATIVEJS_DECLARE_AST_NODE(ContinueStatement)
- ContinueStatement(NameId *l = 0):
+ ContinueStatement(const QStringRef &l = QStringRef()):
label (l) { kind = K; }
virtual void accept0(Visitor *visitor);
@@ -1582,7 +1583,7 @@ public:
{ return semicolonToken; }
// attributes
- NameId *label;
+ QStringRef label;
SourceLocation continueToken;
SourceLocation identifierToken;
SourceLocation semicolonToken;
@@ -1593,7 +1594,7 @@ class QML_PARSER_EXPORT BreakStatement: public Statement
public:
QDECLARATIVEJS_DECLARE_AST_NODE(BreakStatement)
- BreakStatement(NameId *l = 0):
+ BreakStatement(const QStringRef &l):
label (l) { kind = K; }
virtual void accept0(Visitor *visitor);
@@ -1605,7 +1606,7 @@ public:
{ return semicolonToken; }
// attributes
- NameId *label;
+ QStringRef label;
SourceLocation breakToken;
SourceLocation identifierToken;
SourceLocation semicolonToken;
@@ -1773,7 +1774,7 @@ class QML_PARSER_EXPORT LabelledStatement: public Statement
public:
QDECLARATIVEJS_DECLARE_AST_NODE(LabelledStatement)
- LabelledStatement(NameId *l, Statement *stmt):
+ LabelledStatement(const QStringRef &l, Statement *stmt):
label (l), statement (stmt)
{ kind = K; }
@@ -1786,7 +1787,7 @@ public:
{ return statement->lastSourceLocation(); }
// attributes
- NameId *label;
+ QStringRef label;
Statement *statement;
SourceLocation identifierToken;
SourceLocation colonToken;
@@ -1819,14 +1820,14 @@ class QML_PARSER_EXPORT Catch: public Node
public:
QDECLARATIVEJS_DECLARE_AST_NODE(Catch)
- Catch(NameId *n, Block *stmt):
+ Catch(const QStringRef &n, Block *stmt):
name (n), statement (stmt)
{ kind = K; }
virtual void accept0(Visitor *visitor);
// attributes
- NameId *name;
+ QStringRef name;
Block *statement;
SourceLocation catchToken;
SourceLocation lparenToken;
@@ -1894,7 +1895,7 @@ class QML_PARSER_EXPORT FunctionExpression: public ExpressionNode
public:
QDECLARATIVEJS_DECLARE_AST_NODE(FunctionExpression)
- FunctionExpression(NameId *n, FormalParameterList *f, FunctionBody *b):
+ FunctionExpression(const QStringRef &n, FormalParameterList *f, FunctionBody *b):
name (n), formals (f), body (b)
{ kind = K; }
@@ -1907,7 +1908,7 @@ public:
{ return rbraceToken; }
// attributes
- NameId *name;
+ QStringRef name;
FormalParameterList *formals;
FunctionBody *body;
SourceLocation functionToken;
@@ -1923,7 +1924,7 @@ class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression
public:
QDECLARATIVEJS_DECLARE_AST_NODE(FunctionDeclaration)
- FunctionDeclaration(NameId *n, FormalParameterList *f, FunctionBody *b):
+ FunctionDeclaration(const QStringRef &n, FormalParameterList *f, FunctionBody *b):
FunctionExpression(n, f, b)
{ kind = K; }
@@ -1935,11 +1936,11 @@ class QML_PARSER_EXPORT FormalParameterList: public Node
public:
QDECLARATIVEJS_DECLARE_AST_NODE(FormalParameterList)
- FormalParameterList(NameId *n):
+ FormalParameterList(const QStringRef &n):
name (n), next (this)
{ kind = K; }
- FormalParameterList(FormalParameterList *previous, NameId *n):
+ FormalParameterList(FormalParameterList *previous, const QStringRef &n):
name (n)
{
kind = K;
@@ -1957,7 +1958,7 @@ public:
}
// attributes
- NameId *name;
+ QStringRef name;
FormalParameterList *next;
SourceLocation commaToken;
SourceLocation identifierToken;
@@ -2105,11 +2106,11 @@ class QML_PARSER_EXPORT UiQualifiedId: public Node
public:
QDECLARATIVEJS_DECLARE_AST_NODE(UiQualifiedId)
- UiQualifiedId(NameId *name)
+ UiQualifiedId(const QStringRef &name)
: next(this), name(name)
{ kind = K; }
- UiQualifiedId(UiQualifiedId *previous, NameId *name)
+ UiQualifiedId(UiQualifiedId *previous, const QStringRef &name)
: name(name)
{
kind = K;
@@ -2128,7 +2129,7 @@ public:
// attributes
UiQualifiedId *next;
- NameId *name;
+ QStringRef name;
SourceLocation identifierToken;
};
@@ -2137,12 +2138,12 @@ class QML_PARSER_EXPORT UiImport: public Node
public:
QDECLARATIVEJS_DECLARE_AST_NODE(UiImport)
- UiImport(NameId *fileName)
- : fileName(fileName), importUri(0), importId(0)
+ UiImport(const QStringRef &fileName)
+ : fileName(fileName), importUri(0)
{ kind = K; }
UiImport(UiQualifiedId *uri)
- : fileName(0), importUri(uri), importId(0)
+ : importUri(uri)
{ kind = K; }
virtual SourceLocation firstSourceLocation() const
@@ -2154,9 +2155,9 @@ public:
virtual void accept0(Visitor *visitor);
// attributes
- NameId *fileName;
+ QStringRef fileName;
UiQualifiedId *importUri;
- NameId *importId;
+ QStringRef importId;
SourceLocation importToken;
SourceLocation fileNameToken;
SourceLocation versionToken;
@@ -2306,11 +2307,11 @@ class QML_PARSER_EXPORT UiParameterList: public Node
public:
QDECLARATIVEJS_DECLARE_AST_NODE(UiParameterList)
- UiParameterList(NameId *t, NameId *n):
+ UiParameterList(const QStringRef &t, const QStringRef &n):
type (t), name (n), next (this)
{ kind = K; }
- UiParameterList(UiParameterList *previous, NameId *t, NameId *n):
+ UiParameterList(UiParameterList *previous, const QStringRef &t, const QStringRef &n):
type (t), name (n)
{
kind = K;
@@ -2328,8 +2329,8 @@ public:
}
// attributes
- NameId *type;
- NameId *name;
+ QStringRef type;
+ QStringRef name;
UiParameterList *next;
SourceLocation commaToken;
SourceLocation identifierToken;
@@ -2340,15 +2341,15 @@ class QML_PARSER_EXPORT UiPublicMember: public UiObjectMember
public:
QDECLARATIVEJS_DECLARE_AST_NODE(UiPublicMember)
- UiPublicMember(NameId *memberType,
- NameId *name)
- : type(Property), typeModifier(0), memberType(memberType), name(name), statement(0), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
+ UiPublicMember(const QStringRef &memberType,
+ const QStringRef &name)
+ : type(Property), memberType(memberType), name(name), statement(0), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
{ kind = K; }
- UiPublicMember(NameId *memberType,
- NameId *name,
+ UiPublicMember(const QStringRef &memberType,
+ const QStringRef &name,
Statement *statement)
- : type(Property), typeModifier(0), memberType(memberType), name(name), statement(statement), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
+ : type(Property), memberType(memberType), name(name), statement(statement), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
{ kind = K; }
virtual SourceLocation firstSourceLocation() const
@@ -2375,9 +2376,9 @@ public:
// attributes
enum { Signal, Property } type;
- NameId *typeModifier;
- NameId *memberType;
- NameId *name;
+ QStringRef typeModifier;
+ QStringRef memberType;
+ QStringRef name;
Statement *statement; // initialized with a JS expression
UiObjectMember *binding; // initialized with a QML object or array.
bool isDefaultMember;
diff --git a/src/declarative/qml/parser/qdeclarativejsengine_p.cpp b/src/declarative/qml/parser/qdeclarativejsengine_p.cpp
index a449f779b7..233ff7f20e 100644
--- a/src/declarative/qml/parser/qdeclarativejsengine_p.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsengine_p.cpp
@@ -40,66 +40,16 @@
****************************************************************************/
#include "qdeclarativejsengine_p.h"
-
#include "qdeclarativejsglobal_p.h"
-#include "qdeclarativejsnodepool_p.h"
#include <qnumeric.h>
#include <QHash>
+#include <QDebug>
QT_QML_BEGIN_NAMESPACE
namespace QDeclarativeJS {
-uint qHash(const QDeclarativeJS::NameId &id)
-{ return qHash(id.asString()); }
-
-QString numberToString(double value)
-{ return QString::number(value); }
-
-int Ecma::RegExp::flagFromChar(const QChar &ch)
-{
- static QHash<QChar, int> flagsHash;
- if (flagsHash.isEmpty()) {
- flagsHash[QLatin1Char('g')] = Global;
- flagsHash[QLatin1Char('i')] = IgnoreCase;
- flagsHash[QLatin1Char('m')] = Multiline;
- }
- QHash<QChar, int>::const_iterator it;
- it = flagsHash.constFind(ch);
- if (it == flagsHash.constEnd())
- return 0;
- return it.value();
-}
-
-QString Ecma::RegExp::flagsToString(int flags)
-{
- QString result;
- if (flags & Global)
- result += QLatin1Char('g');
- if (flags & IgnoreCase)
- result += QLatin1Char('i');
- if (flags & Multiline)
- result += QLatin1Char('m');
- return result;
-}
-
-NodePool::NodePool(const QString &fileName, Engine *engine)
- : m_fileName(fileName), m_engine(engine)
-{
- m_engine->setNodePool(this);
-}
-
-NodePool::~NodePool()
-{
-}
-
-Code *NodePool::createCompiledCode(AST::Node *, CompilationUnit &)
-{
- Q_ASSERT(0);
- return 0;
-}
-
static int toDigit(char c)
{
if ((c >= '0') && (c <= '9'))
@@ -172,14 +122,14 @@ double integerFromString(const QString &str, int radix)
Engine::Engine()
- : _lexer(0), _nodePool(0)
+ : _lexer(0)
{ }
Engine::~Engine()
{ }
-QSet<NameId> Engine::literals() const
-{ return _literals; }
+void Engine::setCode(const QString &code)
+{ _code = code; }
void Engine::addComment(int pos, int len, int line, int col)
{ if (len > 0) _comments.append(QDeclarativeJS::AST::SourceLocation(pos, len, line, col)); }
@@ -187,25 +137,24 @@ void Engine::addComment(int pos, int len, int line, int col)
QList<QDeclarativeJS::AST::SourceLocation> Engine::comments() const
{ return _comments; }
-NameId *Engine::intern(const QChar *u, int s)
-{ return const_cast<NameId *>(&*_literals.insert(NameId(u, s))); }
-
-QString Engine::toString(NameId *id)
-{ return id->asString(); }
-
Lexer *Engine::lexer() const
{ return _lexer; }
void Engine::setLexer(Lexer *lexer)
{ _lexer = lexer; }
-NodePool *Engine::nodePool() const
-{ return _nodePool; }
-
-void Engine::setNodePool(NodePool *nodePool)
-{ _nodePool = nodePool; }
+MemoryPool *Engine::pool()
+{ return &_pool; }
+QStringRef Engine::newStringRef(const QString &text)
+{
+ const int pos = _extraCode.length();
+ _extraCode += text;
+ return _extraCode.midRef(pos, text.length());
+}
+QStringRef Engine::newStringRef(const QChar *chars, int size)
+{ return newStringRef(QString(chars, size)); }
} // end of namespace QDeclarativeJS
diff --git a/src/declarative/qml/parser/qdeclarativejsengine_p.h b/src/declarative/qml/parser/qdeclarativejsengine_p.h
index e366e8b9b3..13389434f4 100644
--- a/src/declarative/qml/parser/qdeclarativejsengine_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsengine_p.h
@@ -55,6 +55,7 @@
#include "qdeclarativejsglobal_p.h"
#include "qdeclarativejsastfwd_p.h"
+#include "qdeclarativejsmemorypool_p.h"
#include <QString>
#include <QSet>
@@ -62,54 +63,9 @@
QT_QML_BEGIN_NAMESPACE
namespace QDeclarativeJS {
-class QML_PARSER_EXPORT NameId
-{
- QString _text;
-
-public:
- NameId(const QChar *u, int s)
- : _text(u, s)
- { }
-
- const QString asString() const
- { return _text; }
-
- bool operator == (const NameId &other) const
- { return _text == other._text; }
-
- bool operator != (const NameId &other) const
- { return _text != other._text; }
-
- bool operator < (const NameId &other) const
- { return _text < other._text; }
-};
-
-uint qHash(const QDeclarativeJS::NameId &id);
-
-} // end of namespace QDeclarativeJS
-
-namespace QDeclarativeJS {
class Lexer;
-class NodePool;
-
-namespace Ecma {
-
-class QML_PARSER_EXPORT RegExp
-{
-public:
- enum RegExpFlag {
- Global = 0x01,
- IgnoreCase = 0x02,
- Multiline = 0x04
- };
-
-public:
- static int flagFromChar(const QChar &);
- static QString flagsToString(int flags);
-};
-
-} // end of namespace Ecma
+class MemoryPool;
class QML_PARSER_EXPORT DiagnosticMessage
{
@@ -136,30 +92,33 @@ public:
class QML_PARSER_EXPORT Engine
{
Lexer *_lexer;
- NodePool *_nodePool;
- QSet<NameId> _literals;
- QList<QDeclarativeJS::AST::SourceLocation> _comments;
+ MemoryPool _pool;
+ QList<AST::SourceLocation> _comments;
+ QString _extraCode;
+ QString _code;
public:
Engine();
~Engine();
- QSet<NameId> literals() const;
+ void setCode(const QString &code);
void addComment(int pos, int len, int line, int col);
- QList<QDeclarativeJS::AST::SourceLocation> comments() const;
-
- NameId *intern(const QChar *u, int s);
-
- static QString toString(NameId *id);
+ QList<AST::SourceLocation> comments() const;
Lexer *lexer() const;
void setLexer(Lexer *lexer);
- NodePool *nodePool() const;
- void setNodePool(NodePool *nodePool);
+ MemoryPool *pool();
+
+ inline QStringRef midRef(int position, int size) { return _code.midRef(position, size); }
+
+ QStringRef newStringRef(const QString &s);
+ QStringRef newStringRef(const QChar *chars, int size);
};
+double integerFromString(const char *buf, int size, int radix);
+
} // end of namespace QDeclarativeJS
QT_QML_END_NAMESPACE
diff --git a/src/declarative/qml/parser/qdeclarativejsgrammar.cpp b/src/declarative/qml/parser/qdeclarativejsgrammar.cpp
index 38bd46bfcf..89c00c2839 100644
--- a/src/declarative/qml/parser/qdeclarativejsgrammar.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsgrammar.cpp
@@ -45,7 +45,7 @@
QT_BEGIN_NAMESPACE
const char *const QDeclarativeJSGrammar::spell [] = {
- "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ";", "continue",
+ "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ",", "continue",
"default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===",
"finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier",
"if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=",
@@ -55,44 +55,44 @@ const char *const QDeclarativeJSGrammar::spell [] = {
"this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^",
"^=", "null", "true", "false", "const", "debugger", "reserved word", "multiline string literal", "comment", "public",
"import", "as", "on", 0, 0, 0, 0, 0, 0, 0,
- 0};
+ 0, 0};
const short QDeclarativeJSGrammar::lhs [] = {
- 101, 101, 101, 101, 101, 101, 102, 108, 108, 111,
- 111, 113, 112, 112, 112, 112, 112, 112, 112, 112,
- 115, 110, 109, 118, 118, 119, 119, 120, 120, 117,
- 106, 106, 106, 106, 122, 122, 122, 122, 106, 127,
- 127, 127, 128, 128, 129, 129, 106, 106, 106, 106,
- 106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
- 106, 106, 106, 116, 116, 116, 116, 116, 132, 132,
- 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
- 132, 132, 132, 132, 132, 132, 121, 134, 134, 134,
- 134, 133, 133, 136, 136, 138, 138, 138, 138, 138,
- 138, 139, 139, 139, 139, 139, 139, 139, 139, 139,
- 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
- 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
- 139, 139, 140, 140, 114, 114, 114, 114, 114, 143,
- 143, 144, 144, 144, 144, 142, 142, 145, 145, 146,
- 146, 147, 147, 147, 148, 148, 148, 148, 148, 148,
- 148, 148, 148, 148, 149, 149, 149, 149, 150, 150,
- 150, 151, 151, 151, 151, 152, 152, 152, 152, 152,
- 152, 152, 153, 153, 153, 153, 153, 153, 154, 154,
- 154, 154, 154, 155, 155, 155, 155, 155, 156, 156,
- 157, 157, 158, 158, 159, 159, 160, 160, 161, 161,
- 162, 162, 163, 163, 164, 164, 165, 165, 166, 166,
- 167, 167, 137, 137, 168, 168, 169, 169, 169, 169,
- 169, 169, 169, 169, 169, 169, 169, 169, 104, 104,
- 170, 170, 171, 171, 172, 172, 103, 103, 103, 103,
- 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
- 103, 123, 184, 184, 183, 183, 131, 131, 185, 185,
- 186, 186, 188, 188, 187, 189, 192, 190, 190, 193,
- 191, 191, 124, 125, 125, 126, 126, 173, 173, 173,
- 173, 173, 173, 173, 174, 174, 174, 174, 175, 175,
- 175, 175, 176, 176, 177, 179, 194, 194, 197, 197,
- 195, 195, 198, 196, 178, 178, 178, 180, 180, 181,
- 181, 181, 199, 200, 182, 182, 130, 141, 204, 204,
- 201, 201, 202, 202, 205, 107, 206, 206, 105, 105,
- 203, 203, 135, 135, 207};
+ 102, 102, 102, 102, 102, 102, 103, 109, 109, 112,
+ 112, 114, 113, 113, 113, 113, 113, 113, 113, 113,
+ 116, 111, 110, 119, 119, 120, 120, 121, 121, 118,
+ 107, 107, 107, 107, 123, 123, 123, 123, 107, 128,
+ 128, 128, 129, 129, 130, 130, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 117, 117, 117, 117, 117, 133, 133,
+ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
+ 133, 133, 133, 133, 133, 133, 122, 135, 135, 135,
+ 135, 134, 134, 137, 137, 139, 139, 139, 139, 139,
+ 139, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 141, 141, 115, 115, 115, 115, 115, 144,
+ 144, 145, 145, 145, 145, 143, 143, 146, 146, 147,
+ 147, 148, 148, 148, 149, 149, 149, 149, 149, 149,
+ 149, 149, 149, 149, 150, 150, 150, 150, 151, 151,
+ 151, 152, 152, 152, 152, 153, 153, 153, 153, 153,
+ 153, 153, 154, 154, 154, 154, 154, 154, 155, 155,
+ 155, 155, 155, 156, 156, 156, 156, 156, 157, 157,
+ 158, 158, 159, 159, 160, 160, 161, 161, 162, 162,
+ 163, 163, 164, 164, 165, 165, 166, 166, 167, 167,
+ 168, 168, 138, 138, 169, 169, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 105, 105,
+ 171, 171, 172, 172, 173, 173, 104, 104, 104, 104,
+ 104, 104, 104, 104, 104, 104, 104, 104, 104, 104,
+ 104, 124, 185, 185, 184, 184, 132, 132, 186, 186,
+ 187, 187, 189, 189, 188, 190, 193, 191, 191, 194,
+ 192, 192, 125, 126, 126, 127, 127, 174, 174, 174,
+ 174, 174, 174, 174, 175, 175, 175, 175, 176, 176,
+ 176, 176, 177, 177, 178, 180, 195, 195, 198, 198,
+ 196, 196, 199, 197, 179, 179, 179, 181, 181, 182,
+ 182, 182, 200, 201, 183, 183, 131, 142, 205, 205,
+ 202, 202, 203, 203, 206, 108, 207, 207, 106, 106,
+ 204, 204, 136, 136, 208};
const short QDeclarativeJSGrammar::rhs [] = {
2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
@@ -212,71 +212,71 @@ const short QDeclarativeJSGrammar::goto_default [] = {
185, 199, 181, 184, 198, 206, 0};
const short QDeclarativeJSGrammar::action_index [] = {
- 350, 1271, 2492, 2492, 2395, 999, 52, 93, 137, -101,
- 104, 72, 66, 177, -101, 285, 80, -101, -101, 641,
- 71, 130, 167, 178, -101, -101, -101, 431, 321, 1271,
- -101, -101, -101, 393, -101, 2201, 2007, 1271, 1271, 1271,
- -101, 811, 1271, -101, -101, -101, 1271, 1271, -101, -101,
- -101, -101, -101, 1271, -101, 1271, 1271, -101, 1271, 1271,
- 87, 188, -101, -101, 1271, 1271, 1271, -101, -101, -101,
- 179, 1271, 263, 1271, 1271, 1271, 1271, 456, 1271, 1271,
- 1271, 1271, 1271, 1271, 321, 1271, 1271, 1271, 128, 114,
- 120, 193, 181, 172, 321, 321, 446, 395, 405, 1271,
- -8, 1271, 76, 2104, 1271, 1271, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- 110, 1271, -101, -101, 68, 38, -101, 1271, -101, -101,
- 1271, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, 1271, 32, 1271, 1271, 85, 83,
- 1271, -101, 2104, 1271, 1271, -101, 108, -101, 53, -101,
- -101, 64, -101, 393, 89, 62, -101, 297, -101, 63,
- 2492, -101, -101, -101, -101, -101, 154, -101, -101, 47,
- -101, -101, -101, -101, -101, -101, 2492, -101, -101, 461,
- -101, 470, 74, 2395, 59, 393, 92, 67, 2686, 152,
- 1271, -101, 65, 43, 1271, 41, -101, 39, 34, -101,
- -101, 393, -101, -101, -101, -101, -101, -101, 86, -101,
- -101, -101, -101, 90, -101, -101, -101, -101, -101, -101,
- -11, 50, 1271, 103, 82, -101, -101, 1455, -101, 84,
- 44, 5, -101, 267, 70, 33, 575, 79, 69, 471,
- 235, 393, 1271, 275, 1271, 1271, 1271, 1271, 305, 1271,
- 1271, 1271, 1271, 1271, 229, 201, 225, 202, 321, 355,
- 374, 380, 1271, 35, 1271, 81, 1271, -101, 641, 1271,
- -101, 1271, 61, 1, 1271, 29, 2395, -101, 1271, 133,
- 2395, -101, 1271, 73, 1271, 1271, 99, 97, 1271, -101,
- 51, 153, 60, -101, -101, 1271, -101, 393, 1271, -101,
- 56, 1271, -25, 2395, -101, 1271, 129, 2395, -101, -35,
- 309, -56, -31, 2492, -39, -101, 2395, -101, 1271, 245,
- 2395, -5, 2395, -101, 6, 0, -33, -101, -101, 2395,
- -43, 543, 7, 488, 112, 1271, 2395, -1, -27, 453,
- 8, -18, 630, 14, 16, -101, 1365, -101, 12, -19,
- 3, 1271, 58, -30, 1271, -2, 1271, -29, -36, 1271,
- -101, 2298, 18, -101, -101, -101, -101, -101, -101, 1271,
- -101, -101, -101, -101, 223, -101, 1271, -10, -101, 2395,
- -101, 95, -101, -101, 2395, -101, 1271, 107, 20, -101,
- 40, -101, 46, 100, 1271, -101, 55, 57, -101, 28,
- -101, 2395, -101, 118, 2395, -101, 161, -101, -101, 126,
- 2395, 37, -101, -12, -4, -101, 393, -34, -6, -101,
- -101, -101, -101, 1271, 98, 2395, -101, 1271, 116, 2395,
- -101, 19, -101, 186, -101, -101, 1271, -101, -101, 303,
- -101, -101, -101, 119, 1638, -101, -101, 1821, -101, -101,
- 1914, -101, -101, -101, -101, -101, -101, 123, -101, -101,
- -101, -101, -101, -101, -101, -101, 2492, -101, -101, -101,
- 94, -26, 819, 158, -28, 4, -101, -101, 210, -101,
- 203, -101, -101, -101, 393, 230, -101, 1545, -101, -101,
- -101, -101, -101, -101, 234, 2, 393, 232, 17, 393,
- 163, -101, 10, -101, 908, 125, -101, 13, 908, -101,
- -101, 1090, -101, -101, -101, 1181, -101, -101, 214, -101,
- 1545, -101, 262, 9, -101, -101, 180, 318, 30, 1545,
- -101, 238, -101, 236, -101, 26, -32, 315, 183, 288,
- -101, 77, -101, -101, -101, 1728, 908, 291, 2589, 2007,
- -3, -101, 443, 25, 497, 88, 1271, 2395, 24, 11,
- 384, 36, 27, 702, 48, 49, -101, 1365, -101, 54,
- 31, 45, 1271, 58, 15, 1271, 42, 1271, 23, 22,
- 122, -101, -101, 21, -101, -101, 730, -101, 254, -70,
- 908, -101, -101, 138, 393, -101, 143, -101, 134, -101,
- -101, 268, -101, -101, 124, -101, -101, -101, -101, -101,
- -101,
+ 360, 1286, 2520, 2520, 2422, 1011, 52, 96, 132, -102,
+ 104, 69, 66, 177, -102, 283, 80, -102, -102, 649,
+ 71, 120, 160, 169, -102, -102, -102, 444, 325, 1286,
+ -102, -102, -102, 324, -102, 2226, 2030, 1286, 1286, 1286,
+ -102, 801, 1286, -102, -102, -102, 1286, 1286, -102, -102,
+ -102, -102, -102, 1286, -102, 1286, 1286, -102, 1286, 1286,
+ 87, 190, -102, -102, 1286, 1286, 1286, -102, -102, -102,
+ 187, 1286, 251, 1286, 1286, 1286, 1286, 471, 1286, 1286,
+ 1286, 1286, 1286, 1286, 325, 1286, 1286, 1286, 128, 113,
+ 127, 182, 168, 159, 325, 325, 454, 406, 416, 1286,
+ -7, 1286, 76, 2128, 1286, 1286, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ 107, 1286, -102, -102, 68, 44, -102, 1286, -102, -102,
+ 1286, -102, -102, -102, -102, -102, -102, -102, -102, -102,
+ -102, -102, -102, -102, 1286, 32, 1286, 1286, 88, 86,
+ 1286, -102, 2128, 1286, 1286, -102, 103, -102, 56, -102,
+ -102, 65, -102, 398, 89, 63, -102, 274, -102, 62,
+ 2520, -102, -102, -102, -102, -102, 248, -102, -102, 47,
+ -102, -102, -102, -102, -102, -102, 2520, -102, -102, 467,
+ -102, 470, 73, 2422, 53, 398, 91, 67, 2716, 154,
+ 1286, -102, 64, 43, 1286, 41, -102, 39, 34, -102,
+ -102, 398, -102, -102, -102, -102, -102, -102, 82, -102,
+ -102, -102, -102, 90, -102, -102, -102, -102, -102, -102,
+ -8, 51, 1286, 100, 77, -102, -102, 1472, -102, 84,
+ 38, 5, -102, 266, 70, 33, 555, 79, 74, 477,
+ 234, 320, 1286, 281, 1286, 1286, 1286, 1286, 311, 1286,
+ 1286, 1286, 1286, 1286, 230, 189, 213, 208, 325, 371,
+ 386, 396, 1286, 35, 1286, 81, 1286, -102, 649, 1286,
+ -102, 1286, 60, 1, 1286, 31, 2422, -102, 1286, 140,
+ 2422, -102, 1286, 72, 1286, 1286, 97, 93, 1286, -102,
+ 50, 149, 61, -102, -102, 1286, -102, 310, 1286, -102,
+ 58, 1286, -25, 2422, -102, 1286, 125, 2422, -102, -35,
+ 292, -56, -31, 2520, -39, -102, 2422, -102, 1286, 141,
+ 2422, -5, 2422, -102, 6, 0, -33, -102, -102, 2422,
+ -43, 550, 7, 478, 115, 1286, 2422, -1, -27, 451,
+ 8, -18, 627, 14, 16, -102, 1381, -102, 12, -19,
+ 3, 1286, 59, -30, 1286, -2, 1286, -29, -36, 1286,
+ -102, 2324, 18, -102, -102, -102, -102, -102, -102, 1286,
+ -102, -102, -102, -102, 203, -102, 1286, -10, -102, 2422,
+ -102, 94, -102, -102, 2422, -102, 1286, 102, 20, -102,
+ 40, -102, 46, 99, 1286, -102, 55, 57, -102, 28,
+ -102, 2422, -102, 114, 2422, -102, 161, -102, -102, 121,
+ 2422, 37, -102, -12, -4, -102, 398, -34, -6, -102,
+ -102, -102, -102, 1286, 98, 2422, -102, 1286, 105, 2422,
+ -102, 19, -102, 181, -102, -102, 1286, -102, -102, 288,
+ -102, -102, -102, 110, 1657, -102, -102, 1842, -102, -102,
+ 1936, -102, -102, -102, -102, -102, -102, 122, -102, -102,
+ -102, -102, -102, -102, -102, -102, 2520, -102, -102, -102,
+ 92, -26, 829, 142, -28, 4, -102, -102, 191, -102,
+ 202, -102, -102, -102, 398, 218, -102, 1563, -102, -102,
+ -102, -102, -102, -102, 237, 2, 368, 207, 17, 398,
+ 205, -102, 10, -102, 919, 124, -102, 13, 919, -102,
+ -102, 1103, -102, -102, -102, 1195, -102, -102, 214, -102,
+ 1563, -102, 271, 9, -102, -102, 174, 307, 30, 1563,
+ -102, 228, -102, 212, -102, 26, -32, 301, 179, 265,
+ -102, 75, -102, -102, -102, 1748, 919, 280, 2618, 2030,
+ -3, -102, 459, 25, 486, 85, 1286, 2422, 24, 11,
+ 378, 36, 27, 711, 48, 49, -102, 1381, -102, 54,
+ 29, 45, 1286, 59, 15, 1286, 42, 1286, 23, 22,
+ 117, -102, -102, 21, -102, -102, 739, -102, 201, -70,
+ 919, -102, -102, 116, 398, -102, 143, -102, 129, -102,
+ -102, 252, -102, -102, 126, -102, -102, -102, -102, -102,
+ -102,
-107, 25, -75, 27, 30, 272, -107, -107, -107, -107,
-107, -107, -107, -107, -107, -107, -107, -107, -107, -42,
@@ -351,252 +351,245 @@ const short QDeclarativeJSGrammar::action_info [] = {
541, -110, -129, 561, 568, 333, 466, 559, 556, 527,
510, 529, 541, 346, 534, 424, 541, 257, 440, -126,
408, 424, -121, 420, 541, -118, -100, 444, 457, 453,
- 424, -99, 304, 348, 431, -123, 251, 416, 325, 141,
- 457, 101, 414, 164, 440, 453, 147, 71, 296, 416,
- 99, 312, 272, 430, 294, 272, 252, 164, 141, 306,
- 170, 335, 292, 640, 301, 257, 190, 187, 149, 346,
- 183, 312, 236, 348, 318, 71, 141, 0, 0, 172,
- 427, 141, 0, 179, 294, 141, 141, 331, 141, 314,
- 99, 292, 189, 315, 141, 434, 141, 477, 173, 62,
- 538, 141, 443, 538, 0, 249, 248, 141, 573, 572,
- 63, 141, 616, 256, 255, 101, 444, 242, 241, 249,
- 248, 247, 246, 172, 58, 428, 413, 412, 455, 409,
- 58, 327, 141, 254, 177, 59, 142, 418, 58, 141,
- 532, 59, 173, 249, 248, 478, 459, 58, 611, 59,
- 166, 539, 172, 488, 167, 636, 635, 525, 59, 337,
- 64, 64, 103, 310, 469, 630, 629, 85, 0, 86,
- 64, 173, 0, 174, 633, 632, 85, 0, 86, 511,
- 87, 104, 511, 105, 328, 235, 234, 575, 85, 87,
- 86, 550, 438, 437, 533, 531, 85, 85, 86, 86,
- 0, 87, 511, 513, 631, 65, 65, 517, 172, 87,
- 87, 66, 66, 541, 512, 65, 0, 470, 468, 172,
- 85, 66, 86, 141, 85, 513, 86, 173, 513, 406,
- 85, 511, 86, 87, 0, 511, 512, 87, 173, 512,
- 406, 0, 0, 87, 563, 551, 549, 172, 513, 0,
- 0, 73, 74, 0, 0, 274, 275, 0, 0, 512,
- 0, 518, 516, 274, 275, -87, 173, 34, 174, 564,
- 562, 626, 576, 73, 74, 350, 172, 513, 75, 76,
- 0, 513, 276, 277, 0, 627, 625, 34, 512, 0,
- 276, 277, 512, 0, -87, 173, 34, 174, 279, 280,
- 75, 76, 34, 0, 48, 50, 49, 281, 34, 0,
- 282, 0, 283, 0, 34, 624, 85, 34, 86, 0,
- 0, 0, 0, 0, 48, 50, 49, 0, 0, 87,
- 45, 0, 0, 48, 50, 49, 0, 0, 0, 48,
- 50, 49, 0, 0, 0, 48, 50, 49, 279, 280,
- 45, 48, 50, 49, 48, 50, 49, 281, 0, 45,
- 282, 0, 283, 0, 0, 45, 0, 279, 280, 0,
- 0, 45, 0, 279, 280, 0, 281, 45, 0, 282,
- 45, 283, 281, 34, 0, 282, 0, 283, 78, 79,
- -341, 0, 34, 0, 0, 0, 80, 81, 78, 79,
- 82, 0, 83, 0, 0, 0, 80, 81, 0, 0,
- 82, 0, 83, 6, 5, 4, 1, 3, 2, 0,
- 48, 50, 49, 0, 78, 79, 0, 0, 0, 48,
- 50, 49, 80, 81, 0, 0, 82, 0, 83, 78,
- 79, 0, 34, 0, 0, 0, 45, 80, 81, 78,
- 79, 82, 34, 83, 0, 45, 0, 80, 81, -341,
- 34, 82, 0, 83, 279, 280, 0, 0, 0, 34,
- 0, 0, 0, 281, 240, 239, 282, 0, 283, 48,
- 50, 49, 0, 0, 0, 0, 0, 34, 0, 48,
- 50, 49, 240, 239, 0, 0, 34, 48, 50, 49,
- 0, 245, 244, 0, 0, 45, 48, 50, 49, 0,
- 0, 0, 0, 0, 0, 45, 0, 0, 0, 245,
- 244, 0, 0, 45, 48, 50, 49, 0, 245, 244,
- 0, 0, 45, 48, 50, 49, 0, 0, 0, 0,
- 0, 0, 34, 0, 0, 0, 0, 0, 151, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 152, 45,
- 0, 0, 153, 0, 0, 0, 0, 0, 0, 0,
- 0, 154, 0, 155, 240, 239, 308, 0, 0, 48,
- 50, 49, 0, 0, 156, 0, 157, 62, 0, 0,
+ 424, -99, 304, 348, 431, 416, -123, 325, 141, 251,
+ 457, 414, 101, 164, 440, 453, 147, 71, 296, 416,
+ 99, 312, 272, 430, 294, 272, 292, 252, 141, 257,
+ 164, 306, 335, 170, 301, 190, 640, 187, 346, 312,
+ 318, 183, 236, 348, 149, 71, 141, 172, 141, 427,
+ 141, 141, 0, 141, 294, 141, 179, 99, 477, 331,
+ 292, 434, 141, 189, 314, 538, 173, 443, 315, 62,
+ 141, 172, 538, 141, 249, 248, 573, 572, 256, 255,
+ 63, 444, 616, 242, 241, 101, 249, 248, 141, 141,
+ 173, 247, 246, 58, 428, 413, 412, 327, 455, 177,
+ 254, 409, 418, 142, 59, 459, 478, 58, 58, 141,
+ 166, 525, 58, 611, 167, 172, 249, 248, 59, 59,
+ 539, 64, 488, 59, 85, 337, 86, 636, 635, 469,
+ 630, 629, 103, 85, 173, 86, 174, 87, 575, 64,
+ 310, 350, 64, 511, 633, 632, 87, 85, 511, 86,
+ 328, 104, 532, 105, 85, 0, 86, 513, 172, 0,
+ 87, 550, 438, 437, 541, 517, 65, 87, 512, 0,
+ 0, 511, 66, 85, 631, 86, 511, 173, 85, 406,
+ 86, 511, 470, 468, 65, 0, 87, 65, 626, 513,
+ 66, 87, 172, 66, 513, 85, 141, 86, 0, 85,
+ 512, 86, 627, 625, 563, 512, 533, 531, 87, 73,
+ 74, 173, 87, 406, 0, 551, 549, 513, 0, 518,
+ 516, 34, 513, 576, 274, 275, 172, 513, 512, 564,
+ 562, 0, 624, 512, 34, 172, 75, 76, 512, 274,
+ 275, 73, 74, 34, -87, 173, 0, 174, 0, 235,
+ 234, 276, 277, -87, 173, 0, 174, 34, 48, 50,
+ 49, 34, 0, 0, 0, 0, 276, 277, 75, 76,
+ 34, 48, 50, 49, 279, 280, 34, 0, 0, 34,
+ 48, 50, 49, 281, 45, 0, 282, 0, 283, 34,
+ 85, 0, 86, 34, 48, 50, 49, 45, 48, 50,
+ 49, 0, 0, 87, 0, 0, 45, 48, 50, 49,
+ 0, 0, 0, 48, 50, 49, 48, 50, 49, 0,
+ 45, 0, 0, 0, 45, 0, 48, 50, 49, 0,
+ 48, 50, 49, 45, 279, 280, 0, 34, 0, 45,
+ 0, 0, 45, 281, 0, 0, 282, 34, 283, 279,
+ 280, 0, 45, 0, -341, 0, 45, 0, 281, 279,
+ 280, 282, 0, 283, 0, 0, 0, 34, 281, 78,
+ 79, 282, 0, 283, 48, 50, 49, 80, 81, 78,
+ 79, 82, 0, 83, 48, 50, 49, 80, 81, 0,
+ 0, 82, 0, 83, 6, 5, 4, 1, 3, 2,
+ 45, 0, 0, 0, 48, 50, 49, 78, 79, 0,
+ 45, 0, 0, 0, 0, 80, 81, 78, 79, 82,
+ 34, 83, 0, 0, 0, 80, 81, -341, 34, 82,
+ 45, 83, 0, 0, 78, 79, 34, 0, 0, 34,
+ 279, 280, 80, 81, 0, 0, 82, 34, 83, 281,
+ 0, 0, 282, 0, 283, 34, 0, 48, 50, 49,
+ 240, 239, 0, 0, 0, 48, 50, 49, 240, 239,
+ 0, 245, 244, 48, 50, 49, 48, 50, 49, 245,
+ 244, 0, 0, 45, 48, 50, 49, 245, 244, 0,
+ 0, 45, 48, 50, 49, 0, 0, 0, 151, 45,
+ 0, 0, 45, 0, 0, 0, 0, 0, 152, 0,
+ 45, 0, 153, 0, 0, 0, 0, 0, 45, 34,
+ 0, 154, 0, 155, 0, 0, 308, 0, 0, 0,
+ 0, 0, 0, 0, 156, 0, 157, 62, 0, 0,
0, 0, 0, 0, 158, 0, 0, 159, 63, 0,
- 0, 0, 0, 160, 0, 45, 0, 0, 0, 161,
- 0, 0, 30, 31, 151, 0, 0, 0, 0, 0,
- 0, 0, 33, 0, 152, 162, 0, 0, 153, 34,
- 0, 0, 0, 35, 36, 0, 37, 154, 0, 155,
- 0, 0, 0, 41, 0, 0, 0, 44, 0, 0,
- 156, 0, 157, 62, 0, 0, 0, 0, 0, 0,
- 158, 0, 0, 159, 63, 51, 48, 50, 49, 160,
- 52, 0, 0, 0, 0, 161, 0, 0, 0, 0,
- 0, 43, 54, 32, 30, 31, 0, 40, 0, 0,
- 0, 162, 45, 0, 33, 0, 0, 0, 0, 0,
- 0, 34, 0, 0, 0, 35, 36, 0, 37, 0,
- 0, 0, 30, 31, 0, 41, 0, 0, 0, 44,
- 0, 0, 33, 0, 0, 0, 0, 0, 0, 34,
- 0, 0, 0, 35, 36, 0, 37, 51, 48, 50,
- 49, 0, 52, 502, 0, 0, 0, 44, 0, 0,
- 0, 0, 0, 43, 54, 32, 0, 0, 0, 40,
- 0, 0, 0, 0, 45, 51, 48, 50, 49, 0,
- 52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 43, 54, 32, 0, 0, 0, 40, 0, 0,
- 0, 0, 45, 30, 31, 0, 0, 0, 0, 0,
- 0, 30, 31, 33, 0, 0, 0, 0, 0, 0,
- 34, 33, 0, 0, 35, 36, 0, 37, 34, 0,
- 0, 0, 35, 36, 41, 37, 0, 0, 44, 0,
- 0, 0, 502, 0, 0, 0, 44, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 51, 48, 50, 49,
- 0, 52, 0, 0, 51, 48, 50, 49, 0, 52,
+ 0, 240, 239, 160, 0, 0, 48, 50, 49, 161,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 162, 0, 0, 0, 30,
+ 31, 0, 45, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 151, 0, 0, 0, 34, 0, 0, 0,
+ 35, 36, 152, 37, 0, 0, 153, 0, 0, 0,
+ 41, 0, 0, 0, 44, 154, 0, 155, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 156, 0,
+ 157, 62, 51, 48, 50, 49, 0, 52, 158, 0,
+ 0, 159, 63, 0, 0, 0, 0, 160, 43, 54,
+ 32, 0, 0, 161, 40, 0, 0, 0, 0, 45,
+ 0, 0, 0, 30, 31, 0, 0, 0, 0, 162,
+ 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
+ 34, 0, 0, 0, 35, 36, 0, 37, 0, 0,
+ 0, 30, 31, 0, 41, 0, 0, 0, 44, 0,
+ 0, 33, 0, 0, 0, 0, 0, 0, 34, 0,
+ 0, 0, 35, 36, 0, 37, 51, 48, 50, 49,
+ 0, 52, 502, 0, 0, 0, 44, 0, 0, 0,
0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
- 43, 54, 32, 45, 0, 0, 40, 0, 0, 0,
- 0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
- 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 33, 0, 0, 0, 0, 0, 0, 34, 0, 0,
- 0, 35, 36, 0, 37, 0, 0, 0, 0, 0,
- 0, 502, 0, 0, 0, 44, 0, 0, 0, 0,
+ 0, 0, 0, 45, 51, 48, 50, 49, 0, 52,
+ 0, 0, 0, 30, 31, 0, 0, 0, 0, 0,
+ 43, 54, 32, 33, 0, 0, 40, 0, 0, 0,
+ 34, 45, 0, 0, 35, 36, 0, 37, 0, 0,
+ 0, 30, 31, 0, 41, 0, 0, 0, 44, 0,
+ 0, 33, 0, 0, 0, 0, 0, 0, 34, 0,
+ 0, 0, 35, 36, 0, 37, 51, 48, 50, 49,
+ 0, 52, 502, 0, 0, 0, 44, 0, 0, 0,
+ 0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
+ 0, 0, 0, 45, 51, 48, 50, 49, 0, 52,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 51, 48, 50, 49, 0, 52, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 43,
- 54, 32, 0, 0, 0, 40, 0, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 0, 501,
+ 43, 54, 32, 0, 0, 0, 40, 0, 0, 0,
+ 0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
0, 30, 31, 0, 0, 0, 0, 0, 0, 0,
- 0, 215, 0, 0, 0, 0, 0, 0, 34, 0,
+ 0, 33, 0, 0, 0, 0, 0, 0, 34, 0,
0, 0, 35, 36, 0, 37, 0, 0, 0, 0,
0, 0, 502, 0, 0, 0, 44, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 51, 503, 505, 504, 0, 52,
- 0, 0, 0, 0, 226, 0, 0, 0, 0, 0,
- 43, 54, 32, 210, 0, 0, 40, 0, 0, 0,
+ 0, 0, 0, 0, 51, 48, 50, 49, 0, 52,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 43, 54, 32, 0, 0, 0, 40, 0, 0, 0,
0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
- 501, 0, 30, 31, 0, 0, 0, 0, 0, 0,
- 0, 0, 215, 0, 0, 0, 0, 0, 0, 34,
- 0, 0, 0, 35, 36, 0, 37, 0, 0, 0,
- 0, 0, 0, 502, 0, 0, 0, 44, 0, 0,
- 0, 0, 0, 0, 0, 543, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 51, 503, 505, 504, 0,
- 52, 0, 0, 0, 0, 226, 0, 0, 0, 0,
- 0, 43, 54, 32, 210, 0, 0, 40, 0, 0,
- 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
0, 501, 0, 30, 31, 0, 0, 0, 0, 0,
0, 0, 0, 215, 0, 0, 0, 0, 0, 0,
34, 0, 0, 0, 35, 36, 0, 37, 0, 0,
0, 0, 0, 0, 502, 0, 0, 0, 44, 0,
- 0, 0, 0, 0, 0, 0, 546, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 51, 503, 505, 504,
0, 52, 0, 0, 0, 0, 226, 0, 0, 0,
0, 0, 43, 54, 32, 210, 0, 0, 40, 0,
0, 0, 0, 45, 0, 0, 0, 0, 0, 0,
- 0, 0, 29, 30, 31, 0, 0, 0, 0, 0,
- 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
- 34, 0, 0, 0, 35, 36, 0, 37, 0, 0,
- 0, 38, 0, 39, 41, 42, 0, 0, 44, 0,
- 0, 0, 46, 0, 47, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 51, 48, 50, 49,
- 0, 52, 0, 53, 0, 55, 0, 56, 0, 0,
- 0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
- 0, 0, 0, 45, 0, 0, 0, 0, 0, 0,
- 0, 0, -119, 0, 0, 0, 29, 30, 31, 0,
- 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
+ 0, 0, 0, 501, 0, 30, 31, 0, 0, 0,
+ 0, 0, 0, 0, 0, 215, 0, 0, 0, 0,
+ 0, 0, 34, 0, 0, 0, 35, 36, 0, 37,
+ 0, 0, 0, 0, 0, 0, 502, 0, 0, 0,
+ 44, 0, 0, 0, 0, 0, 0, 0, 543, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 51, 503,
+ 505, 504, 0, 52, 0, 0, 0, 0, 226, 0,
+ 0, 0, 0, 0, 43, 54, 32, 210, 0, 0,
+ 40, 0, 0, 0, 0, 45, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 501, 0, 30, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 215, 0, 0,
0, 0, 0, 0, 34, 0, 0, 0, 35, 36,
- 0, 37, 0, 0, 0, 38, 0, 39, 41, 42,
- 0, 0, 44, 0, 0, 0, 46, 0, 47, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 51, 48, 50, 49, 0, 52, 0, 53, 0, 55,
- 0, 56, 0, 0, 0, 0, 43, 54, 32, 0,
+ 0, 37, 0, 0, 0, 0, 0, 0, 502, 0,
+ 0, 0, 44, 0, 0, 0, 0, 0, 0, 0,
+ 546, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 51, 503, 505, 504, 0, 52, 0, 0, 0, 0,
+ 226, 0, 0, 0, 0, 0, 43, 54, 32, 210,
0, 0, 40, 0, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 29, 30, 31, 0,
- 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
- 0, 0, 0, 0, 34, 0, 0, 0, 35, 36,
- 0, 37, 0, 0, 0, 38, 0, 39, 41, 42,
- 0, 0, 44, 0, 0, 0, 46, 0, 47, 0,
+ 0, 0, 0, 0, 0, 0, 0, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 34, 0, 0, 0, 35,
+ 36, 0, 37, 0, 0, 0, 38, 0, 39, 41,
+ 42, 0, 0, 44, 0, 0, 0, 46, 0, 47,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 51, 48, 50, 49, 0, 52, 0, 53, 0, 55,
- 271, 56, 0, 0, 0, 0, 43, 54, 32, 0,
- 0, 0, 40, 0, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 29, 30, 31, 0,
- 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
- 0, 0, 0, 0, 34, 217, 0, 0, 218, 36,
- 0, 37, 0, 0, 0, 38, 0, 39, 41, 42,
- 0, 0, 44, 0, 0, 0, 46, 0, 47, 0,
- 0, 0, 0, 0, 0, 0, 221, 0, 0, 0,
- 51, 48, 50, 49, 0, 52, 0, 53, 0, 55,
- 0, 56, 0, 0, 0, 0, 43, 54, 32, 0,
- 0, 0, 40, 0, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 483, 0, 0, 29,
- 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 33, 0, 0, 0, 0, 0, 0, 34, 0, 0,
- 0, 35, 36, 0, 37, 0, 0, 0, 38, 0,
- 39, 41, 42, 0, 0, 44, 0, 0, 0, 46,
- 0, 47, 0, 0, 486, 0, 0, 0, 0, 0,
- 0, 0, 0, 51, 48, 50, 49, 0, 52, 0,
- 53, 0, 55, 0, 56, 0, 0, 0, 0, 43,
- 54, 32, 0, 0, 0, 40, 0, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 0, 29,
- 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 33, 0, 0, 0, 0, 0, 0, 34, 217, 0,
- 0, 578, 579, 0, 37, 0, 0, 0, 38, 0,
- 39, 41, 42, 0, 0, 44, 0, 0, 0, 46,
- 0, 47, 0, 0, 0, 0, 0, 0, 0, 221,
- 0, 0, 0, 51, 48, 50, 49, 0, 52, 0,
- 53, 0, 55, 0, 56, 0, 0, 0, 0, 43,
- 54, 32, 0, 0, 0, 40, 0, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 0, 475,
+ 0, 51, 48, 50, 49, 0, 52, 0, 53, 0,
+ 55, 0, 56, 0, 0, 0, 0, 43, 54, 32,
+ 0, 0, 0, 40, 0, 0, 0, 0, 45, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, -119, 0,
0, 0, 29, 30, 31, 0, 0, 0, 0, 0,
0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
34, 0, 0, 0, 35, 36, 0, 37, 0, 0,
0, 38, 0, 39, 41, 42, 0, 0, 44, 0,
- 0, 0, 46, 0, 47, 0, 0, 481, 0, 0,
+ 0, 0, 46, 0, 47, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 51, 48, 50, 49,
0, 52, 0, 53, 0, 55, 0, 56, 0, 0,
0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
0, 0, 0, 45, 0, 0, 0, 0, 0, 0,
- 0, 0, 483, 0, 0, 29, 30, 31, 0, 0,
- 0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
- 0, 0, 0, 34, 0, 0, 0, 35, 36, 0,
- 37, 0, 0, 0, 38, 0, 39, 41, 42, 0,
- 0, 44, 0, 0, 0, 46, 0, 47, 0, 0,
- 484, 0, 0, 0, 0, 0, 0, 0, 0, 51,
- 48, 50, 49, 0, 52, 0, 53, 0, 55, 0,
- 56, 0, 0, 0, 0, 43, 54, 32, 0, 0,
- 0, 40, 0, 0, 0, 0, 45, 0, 0, 0,
- 0, 0, 0, 0, 0, 475, 0, 0, 29, 30,
+ 0, 0, 0, 29, 30, 31, 0, 0, 0, 0,
+ 0, 0, 0, 0, 33, 0, 0, 0, 0, 0,
+ 0, 34, 0, 0, 0, 35, 36, 0, 37, 0,
+ 0, 0, 38, 0, 39, 41, 42, 0, 0, 44,
+ 0, 0, 0, 46, 0, 47, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 51, 48, 50,
+ 49, 0, 52, 0, 53, 0, 55, 271, 56, 0,
+ 0, 0, 0, 43, 54, 32, 0, 0, 0, 40,
+ 0, 0, 0, 0, 45, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 29, 30, 31, 0, 0, 0,
+ 0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
+ 0, 0, 34, 217, 0, 0, 218, 36, 0, 37,
+ 0, 0, 0, 38, 0, 39, 41, 42, 0, 0,
+ 44, 0, 0, 0, 46, 0, 47, 0, 0, 0,
+ 0, 0, 0, 0, 221, 0, 0, 0, 51, 48,
+ 50, 49, 0, 52, 0, 53, 0, 55, 0, 56,
+ 0, 0, 0, 0, 43, 54, 32, 0, 0, 0,
+ 40, 0, 0, 0, 0, 45, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 483, 0, 0, 29, 30,
31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
0, 0, 0, 0, 0, 0, 34, 0, 0, 0,
35, 36, 0, 37, 0, 0, 0, 38, 0, 39,
41, 42, 0, 0, 44, 0, 0, 0, 46, 0,
- 47, 0, 0, 476, 0, 0, 0, 0, 0, 0,
+ 47, 0, 0, 486, 0, 0, 0, 0, 0, 0,
0, 0, 51, 48, 50, 49, 0, 52, 0, 53,
0, 55, 0, 56, 0, 0, 0, 0, 43, 54,
32, 0, 0, 0, 40, 0, 0, 0, 0, 45,
- 0, 0, 0, 0, 0, 0, 0, 0, 109, 110,
- 111, 0, 0, 113, 115, 116, 0, 0, 117, 0,
- 118, 0, 0, 0, 120, 121, 122, 0, 0, 0,
- 0, 0, 0, 34, 123, 124, 125, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 126, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 129, 0, 0, 0, 0, 0, 0,
- 48, 50, 49, 130, 131, 132, 0, 134, 135, 136,
- 137, 138, 139, 0, 0, 127, 133, 119, 112, 114,
- 128, 0, 0, 0, 0, 0, 45, 0, 0, 0,
- 0, 0, 0, 0, 0, 109, 110, 111, 0, 0,
- 113, 115, 116, 0, 0, 117, 0, 118, 0, 0,
- 0, 120, 121, 122, 0, 0, 0, 0, 0, 0,
- 393, 123, 124, 125, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 126, 0, 0, 0, 394, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 129, 0, 0, 0, 0, 0, 398, 395, 397, 0,
- 130, 131, 132, 0, 134, 135, 136, 137, 138, 139,
- 0, 0, 127, 133, 119, 112, 114, 128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 29,
+ 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 33, 0, 0, 0, 0, 0, 0, 34, 217, 0,
+ 0, 578, 579, 0, 37, 0, 0, 0, 38, 0,
+ 39, 41, 42, 0, 0, 44, 0, 0, 0, 46,
+ 0, 47, 0, 0, 0, 0, 0, 0, 0, 221,
+ 0, 0, 0, 51, 48, 50, 49, 0, 52, 0,
+ 53, 0, 55, 0, 56, 0, 0, 0, 0, 43,
+ 54, 32, 0, 0, 0, 40, 0, 0, 0, 0,
+ 45, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 475, 0, 0, 29, 30, 31, 0, 0, 0, 0,
+ 0, 0, 0, 0, 33, 0, 0, 0, 0, 0,
+ 0, 34, 0, 0, 0, 35, 36, 0, 37, 0,
+ 0, 0, 38, 0, 39, 41, 42, 0, 0, 44,
+ 0, 0, 0, 46, 0, 47, 0, 0, 481, 0,
+ 0, 0, 0, 0, 0, 0, 0, 51, 48, 50,
+ 49, 0, 52, 0, 53, 0, 55, 0, 56, 0,
+ 0, 0, 0, 43, 54, 32, 0, 0, 0, 40,
+ 0, 0, 0, 0, 45, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 483, 0, 0, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 34, 0, 0, 0, 35,
+ 36, 0, 37, 0, 0, 0, 38, 0, 39, 41,
+ 42, 0, 0, 44, 0, 0, 0, 46, 0, 47,
+ 0, 0, 484, 0, 0, 0, 0, 0, 0, 0,
+ 0, 51, 48, 50, 49, 0, 52, 0, 53, 0,
+ 55, 0, 56, 0, 0, 0, 0, 43, 54, 32,
+ 0, 0, 0, 40, 0, 0, 0, 0, 45, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 475, 0,
+ 0, 29, 30, 31, 0, 0, 0, 0, 0, 0,
+ 0, 0, 33, 0, 0, 0, 0, 0, 0, 34,
+ 0, 0, 0, 35, 36, 0, 37, 0, 0, 0,
+ 38, 0, 39, 41, 42, 0, 0, 44, 0, 0,
+ 0, 46, 0, 47, 0, 0, 476, 0, 0, 0,
+ 0, 0, 0, 0, 0, 51, 48, 50, 49, 0,
+ 52, 0, 53, 0, 55, 0, 56, 0, 0, 0,
+ 0, 43, 54, 32, 0, 0, 0, 40, 0, 0,
+ 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
0, 0, 109, 110, 111, 0, 0, 113, 115, 116,
0, 0, 117, 0, 118, 0, 0, 0, 120, 121,
- 122, 0, 0, 0, 0, 0, 0, 393, 123, 124,
+ 122, 0, 0, 0, 0, 0, 0, 34, 123, 124,
125, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 126, 0, 0, 0, 394, 0, 0, 0, 0,
- 0, 0, 0, 396, 0, 0, 0, 129, 0, 0,
- 0, 0, 0, 398, 395, 397, 0, 130, 131, 132,
+ 0, 126, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 129, 0, 0,
+ 0, 0, 0, 0, 48, 50, 49, 130, 131, 132,
0, 134, 135, 136, 137, 138, 139, 0, 0, 127,
133, 119, 112, 114, 128, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 209,
- 0, 0, 0, 0, 211, 0, 29, 30, 31, 213,
- 0, 0, 0, 0, 0, 0, 214, 33, 0, 0,
- 0, 0, 0, 0, 216, 217, 0, 0, 218, 36,
- 0, 37, 0, 0, 0, 38, 0, 39, 41, 42,
- 0, 0, 44, 0, 0, 0, 46, 0, 47, 0,
- 0, 0, 0, 0, 220, 0, 221, 0, 0, 0,
- 51, 219, 222, 49, 223, 52, 224, 53, 225, 55,
- 226, 56, 227, 228, 0, 0, 43, 54, 32, 210,
- 212, 0, 40, 0, 0, 0, 0, 45, 0, 0,
+ 45, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 109, 110, 111, 0, 0, 113, 115, 116, 0, 0,
+ 117, 0, 118, 0, 0, 0, 120, 121, 122, 0,
+ 0, 0, 0, 0, 0, 393, 123, 124, 125, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 126,
+ 0, 0, 0, 394, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 129, 0, 0, 0, 0,
+ 0, 398, 395, 397, 0, 130, 131, 132, 0, 134,
+ 135, 136, 137, 138, 139, 0, 0, 127, 133, 119,
+ 112, 114, 128, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 109, 110,
+ 111, 0, 0, 113, 115, 116, 0, 0, 117, 0,
+ 118, 0, 0, 0, 120, 121, 122, 0, 0, 0,
+ 0, 0, 0, 393, 123, 124, 125, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 126, 0, 0,
+ 0, 394, 0, 0, 0, 0, 0, 0, 0, 396,
+ 0, 0, 0, 129, 0, 0, 0, 0, 0, 398,
+ 395, 397, 0, 130, 131, 132, 0, 134, 135, 136,
+ 137, 138, 139, 0, 0, 127, 133, 119, 112, 114,
+ 128, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 209, 0, 0, 0,
0, 211, 0, 29, 30, 31, 213, 0, 0, 0,
- 0, 0, 0, 214, 215, 0, 0, 0, 0, 0,
+ 0, 0, 0, 214, 33, 0, 0, 0, 0, 0,
0, 216, 217, 0, 0, 218, 36, 0, 37, 0,
0, 0, 38, 0, 39, 41, 42, 0, 0, 44,
0, 0, 0, 46, 0, 47, 0, 0, 0, 0,
@@ -604,16 +597,26 @@ const short QDeclarativeJSGrammar::action_info [] = {
49, 223, 52, 224, 53, 225, 55, 226, 56, 227,
228, 0, 0, 43, 54, 32, 210, 212, 0, 40,
0, 0, 0, 0, 45, 0, 0, 0, 0, 0,
- 0, 0, 0, 582, 110, 111, 0, 0, 584, 115,
- 586, 30, 31, 587, 0, 118, 0, 0, 0, 120,
- 589, 590, 0, 0, 0, 0, 0, 0, 591, 592,
- 124, 125, 218, 36, 0, 37, 0, 0, 0, 38,
- 0, 39, 593, 42, 0, 0, 595, 0, 0, 0,
- 46, 0, 47, 0, 0, 0, 0, 0, 597, 0,
- 221, 0, 0, 0, 599, 596, 598, 49, 600, 601,
- 602, 53, 604, 605, 606, 607, 608, 609, 0, 0,
- 594, 603, 588, 583, 585, 128, 40, 0, 0, 0,
- 0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 209, 0, 0, 0, 0, 211,
+ 0, 29, 30, 31, 213, 0, 0, 0, 0, 0,
+ 0, 214, 215, 0, 0, 0, 0, 0, 0, 216,
+ 217, 0, 0, 218, 36, 0, 37, 0, 0, 0,
+ 38, 0, 39, 41, 42, 0, 0, 44, 0, 0,
+ 0, 46, 0, 47, 0, 0, 0, 0, 0, 220,
+ 0, 221, 0, 0, 0, 51, 219, 222, 49, 223,
+ 52, 224, 53, 225, 55, 226, 56, 227, 228, 0,
+ 0, 43, 54, 32, 210, 212, 0, 40, 0, 0,
+ 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 582, 110, 111, 0, 0, 584, 115, 586,
+ 30, 31, 587, 0, 118, 0, 0, 0, 120, 589,
+ 590, 0, 0, 0, 0, 0, 0, 591, 592, 124,
+ 125, 218, 36, 0, 37, 0, 0, 0, 38, 0,
+ 39, 593, 42, 0, 0, 595, 0, 0, 0, 46,
+ 0, 47, 0, 0, 0, 0, 0, 597, 0, 221,
+ 0, 0, 0, 599, 596, 598, 49, 600, 601, 602,
+ 53, 604, 605, 606, 607, 608, 609, 0, 0, 594,
+ 603, 588, 583, 585, 128, 40, 0, 0, 0, 0,
+ 45, 0, 0, 0, 0, 0, 0, 0, 0, 0,
361, 110, 111, 0, 0, 363, 115, 365, 30, 31,
366, 0, 118, 0, 0, 0, 120, 368, 369, 0,
0, 0, 0, 0, 0, 370, 371, 124, 125, 218,
@@ -623,7 +626,7 @@ const short QDeclarativeJSGrammar::action_info [] = {
0, 378, 375, 377, 49, 379, 380, 381, 53, 383,
384, 385, 386, 387, 388, 0, 0, 373, 382, 367,
362, 364, 128, 40, 0, 0, 0, 0, 45, 0,
- 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
567, 169, 558, 570, 574, 515, 569, 557, 309, 548,
461, 528, 311, 530, 417, 555, 307, 188, 415, 358,
@@ -681,201 +684,166 @@ const short QDeclarativeJSGrammar::action_check [] = {
33, 7, 7, 29, 8, 60, 17, 7, 66, 37,
66, 24, 33, 7, 34, 5, 33, 36, 33, 7,
60, 5, 7, 33, 33, 7, 7, 20, 36, 36,
- 5, 7, 61, 36, 7, 7, 77, 36, 17, 8,
- 36, 79, 7, 2, 33, 36, 8, 1, 8, 36,
- 48, 2, 1, 55, 79, 1, 36, 2, 8, 60,
- 7, 31, 48, 0, 61, 36, 33, 8, 60, 7,
- 36, 2, 55, 36, 7, 1, 8, -1, -1, 15,
- 10, 8, -1, 60, 79, 8, 8, 61, 8, 50,
- 48, 48, 60, 54, 8, 7, 8, 8, 34, 42,
- 8, 8, 6, 8, -1, 61, 62, 8, 61, 62,
- 53, 8, 90, 61, 62, 79, 20, 61, 62, 61,
- 62, 61, 62, 15, 40, 55, 61, 62, 60, 7,
- 40, 8, 8, 60, 56, 51, 56, 60, 40, 8,
- 7, 51, 34, 61, 62, 56, 60, 40, 56, 51,
- 50, 56, 15, 60, 54, 61, 62, 29, 51, 60,
- 12, 12, 15, 60, 8, 61, 62, 25, -1, 27,
- 12, 34, -1, 36, 61, 62, 25, -1, 27, 29,
- 38, 34, 29, 36, 61, 61, 62, 7, 25, 38,
- 27, 7, 61, 62, 61, 62, 25, 25, 27, 27,
- -1, 38, 29, 75, 91, 57, 57, 7, 15, 38,
- 38, 63, 63, 33, 86, 57, -1, 61, 62, 15,
- 25, 63, 27, 8, 25, 75, 27, 34, 75, 36,
- 25, 29, 27, 38, -1, 29, 86, 38, 34, 86,
- 36, -1, -1, 38, 36, 61, 62, 15, 75, -1,
- -1, 18, 19, -1, -1, 18, 19, -1, -1, 86,
- -1, 61, 62, 18, 19, 33, 34, 29, 36, 61,
- 62, 47, 92, 18, 19, 60, 15, 75, 45, 46,
- -1, 75, 45, 46, -1, 61, 62, 29, 86, -1,
- 45, 46, 86, -1, 33, 34, 29, 36, 23, 24,
- 45, 46, 29, -1, 66, 67, 68, 32, 29, -1,
- 35, -1, 37, -1, 29, 91, 25, 29, 27, -1,
- -1, -1, -1, -1, 66, 67, 68, -1, -1, 38,
- 92, -1, -1, 66, 67, 68, -1, -1, -1, 66,
- 67, 68, -1, -1, -1, 66, 67, 68, 23, 24,
- 92, 66, 67, 68, 66, 67, 68, 32, -1, 92,
- 35, -1, 37, -1, -1, 92, -1, 23, 24, -1,
- -1, 92, -1, 23, 24, -1, 32, 92, -1, 35,
- 92, 37, 32, 29, -1, 35, -1, 37, 23, 24,
- 36, -1, 29, -1, -1, -1, 31, 32, 23, 24,
- 35, -1, 37, -1, -1, -1, 31, 32, -1, -1,
- 35, -1, 37, 93, 94, 95, 96, 97, 98, -1,
- 66, 67, 68, -1, 23, 24, -1, -1, -1, 66,
- 67, 68, 31, 32, -1, -1, 35, -1, 37, 23,
- 24, -1, 29, -1, -1, -1, 92, 31, 32, 23,
- 24, 35, 29, 37, -1, 92, -1, 31, 32, 36,
- 29, 35, -1, 37, 23, 24, -1, -1, -1, 29,
- -1, -1, -1, 32, 61, 62, 35, -1, 37, 66,
- 67, 68, -1, -1, -1, -1, -1, 29, -1, 66,
- 67, 68, 61, 62, -1, -1, 29, 66, 67, 68,
- -1, 61, 62, -1, -1, 92, 66, 67, 68, -1,
- -1, -1, -1, -1, -1, 92, -1, -1, -1, 61,
- 62, -1, -1, 92, 66, 67, 68, -1, 61, 62,
- -1, -1, 92, 66, 67, 68, -1, -1, -1, -1,
- -1, -1, 29, -1, -1, -1, -1, -1, 3, -1,
- 92, -1, -1, -1, -1, -1, -1, -1, 13, 92,
- -1, -1, 17, -1, -1, -1, -1, -1, -1, -1,
- -1, 26, -1, 28, 61, 62, 31, -1, -1, 66,
- 67, 68, -1, -1, 39, -1, 41, 42, -1, -1,
+ 5, 7, 61, 36, 7, 36, 7, 17, 8, 77,
+ 36, 7, 79, 2, 33, 36, 8, 1, 8, 36,
+ 48, 2, 1, 55, 79, 1, 48, 36, 8, 36,
+ 2, 60, 31, 7, 61, 33, 0, 8, 7, 2,
+ 7, 36, 55, 36, 60, 1, 8, 15, 8, 10,
+ 8, 8, -1, 8, 79, 8, 60, 48, 8, 61,
+ 48, 7, 8, 60, 50, 8, 34, 6, 54, 42,
+ 8, 15, 8, 8, 61, 62, 61, 62, 61, 62,
+ 53, 20, 90, 61, 62, 79, 61, 62, 8, 8,
+ 34, 61, 62, 40, 55, 61, 62, 8, 60, 56,
+ 60, 7, 60, 56, 51, 60, 56, 40, 40, 8,
+ 50, 29, 40, 56, 54, 15, 61, 62, 51, 51,
+ 56, 12, 60, 51, 25, 60, 27, 61, 62, 8,
+ 61, 62, 15, 25, 34, 27, 36, 38, 7, 12,
+ 60, 60, 12, 29, 61, 62, 38, 25, 29, 27,
+ 61, 34, 7, 36, 25, -1, 27, 75, 15, -1,
+ 38, 7, 61, 62, 33, 7, 57, 38, 86, -1,
+ -1, 29, 63, 25, 91, 27, 29, 34, 25, 36,
+ 27, 29, 61, 62, 57, -1, 38, 57, 47, 75,
+ 63, 38, 15, 63, 75, 25, 8, 27, -1, 25,
+ 86, 27, 61, 62, 36, 86, 61, 62, 38, 18,
+ 19, 34, 38, 36, -1, 61, 62, 75, -1, 61,
+ 62, 29, 75, 92, 18, 19, 15, 75, 86, 61,
+ 62, -1, 91, 86, 29, 15, 45, 46, 86, 18,
+ 19, 18, 19, 29, 33, 34, -1, 36, -1, 61,
+ 62, 45, 46, 33, 34, -1, 36, 29, 66, 67,
+ 68, 29, -1, -1, -1, -1, 45, 46, 45, 46,
+ 29, 66, 67, 68, 23, 24, 29, -1, -1, 29,
+ 66, 67, 68, 32, 92, -1, 35, -1, 37, 29,
+ 25, -1, 27, 29, 66, 67, 68, 92, 66, 67,
+ 68, -1, -1, 38, -1, -1, 92, 66, 67, 68,
+ -1, -1, -1, 66, 67, 68, 66, 67, 68, -1,
+ 92, -1, -1, -1, 92, -1, 66, 67, 68, -1,
+ 66, 67, 68, 92, 23, 24, -1, 29, -1, 92,
+ -1, -1, 92, 32, -1, -1, 35, 29, 37, 23,
+ 24, -1, 92, -1, 36, -1, 92, -1, 32, 23,
+ 24, 35, -1, 37, -1, -1, -1, 29, 32, 23,
+ 24, 35, -1, 37, 66, 67, 68, 31, 32, 23,
+ 24, 35, -1, 37, 66, 67, 68, 31, 32, -1,
+ -1, 35, -1, 37, 94, 95, 96, 97, 98, 99,
+ 92, -1, -1, -1, 66, 67, 68, 23, 24, -1,
+ 92, -1, -1, -1, -1, 31, 32, 23, 24, 35,
+ 29, 37, -1, -1, -1, 31, 32, 36, 29, 35,
+ 92, 37, -1, -1, 23, 24, 29, -1, -1, 29,
+ 23, 24, 31, 32, -1, -1, 35, 29, 37, 32,
+ -1, -1, 35, -1, 37, 29, -1, 66, 67, 68,
+ 61, 62, -1, -1, -1, 66, 67, 68, 61, 62,
+ -1, 61, 62, 66, 67, 68, 66, 67, 68, 61,
+ 62, -1, -1, 92, 66, 67, 68, 61, 62, -1,
+ -1, 92, 66, 67, 68, -1, -1, -1, 3, 92,
+ -1, -1, 92, -1, -1, -1, -1, -1, 13, -1,
+ 92, -1, 17, -1, -1, -1, -1, -1, 92, 29,
+ -1, 26, -1, 28, -1, -1, 31, -1, -1, -1,
+ -1, -1, -1, -1, 39, -1, 41, 42, -1, -1,
-1, -1, -1, -1, 49, -1, -1, 52, 53, -1,
- -1, -1, -1, 58, -1, 92, -1, -1, -1, 64,
- -1, -1, 12, 13, 3, -1, -1, -1, -1, -1,
- -1, -1, 22, -1, 13, 80, -1, -1, 17, 29,
- -1, -1, -1, 33, 34, -1, 36, 26, -1, 28,
- -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
- 39, -1, 41, 42, -1, -1, -1, -1, -1, -1,
- 49, -1, -1, 52, 53, 65, 66, 67, 68, 58,
- 70, -1, -1, -1, -1, 64, -1, -1, -1, -1,
- -1, 81, 82, 83, 12, 13, -1, 87, -1, -1,
- -1, 80, 92, -1, 22, -1, -1, -1, -1, -1,
- -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
- -1, -1, 12, 13, -1, 43, -1, -1, -1, 47,
- -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
- -1, -1, -1, 33, 34, -1, 36, 65, 66, 67,
- 68, -1, 70, 43, -1, -1, -1, 47, -1, -1,
- -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
- -1, -1, -1, -1, 92, 65, 66, 67, 68, -1,
- 70, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 81, 82, 83, -1, -1, -1, 87, -1, -1,
- -1, -1, 92, 12, 13, -1, -1, -1, -1, -1,
- -1, 12, 13, 22, -1, -1, -1, -1, -1, -1,
- 29, 22, -1, -1, 33, 34, -1, 36, 29, -1,
- -1, -1, 33, 34, 43, 36, -1, -1, 47, -1,
- -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
- -1, 70, -1, -1, 65, 66, 67, 68, -1, 70,
+ -1, 61, 62, 58, -1, -1, 66, 67, 68, 64,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 80, -1, -1, -1, 12,
+ 13, -1, 92, -1, -1, -1, -1, -1, -1, 22,
+ -1, -1, 3, -1, -1, -1, 29, -1, -1, -1,
+ 33, 34, 13, 36, -1, -1, 17, -1, -1, -1,
+ 43, -1, -1, -1, 47, 26, -1, 28, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 39, -1,
+ 41, 42, 65, 66, 67, 68, -1, 70, 49, -1,
+ -1, 52, 53, -1, -1, -1, -1, 58, 81, 82,
+ 83, -1, -1, 64, 87, -1, -1, -1, -1, 92,
+ -1, -1, -1, 12, 13, -1, -1, -1, -1, 80,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, 12, 13, -1, 43, -1, -1, -1, 47, -1,
+ -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
+ -1, -1, 33, 34, -1, 36, 65, 66, 67, 68,
+ -1, 70, 43, -1, -1, -1, 47, -1, -1, -1,
-1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
- 81, 82, 83, 92, -1, -1, 87, -1, -1, -1,
- -1, 92, -1, -1, -1, -1, -1, -1, -1, -1,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
- 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, -1, -1,
- -1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
+ -1, -1, -1, 92, 65, 66, 67, 68, -1, 70,
+ -1, -1, -1, 12, 13, -1, -1, -1, -1, -1,
+ 81, 82, 83, 22, -1, -1, 87, -1, -1, -1,
+ 29, 92, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, 12, 13, -1, 43, -1, -1, -1, 47, -1,
+ -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
+ -1, -1, 33, 34, -1, 36, 65, 66, 67, 68,
+ -1, 70, 43, -1, -1, -1, 47, -1, -1, -1,
+ -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
+ -1, -1, -1, 92, 65, 66, 67, 68, -1, 70,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 81,
- 82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
- 92, -1, -1, -1, -1, -1, -1, -1, -1, 10,
+ 81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
+ -1, 92, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 12, 13, -1, -1, -1, -1, -1, -1, -1,
-1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
-1, -1, 33, 34, -1, 36, -1, -1, -1, -1,
-1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
- -1, -1, -1, -1, 75, -1, -1, -1, -1, -1,
- 81, 82, 83, 84, -1, -1, 87, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
-1, 92, -1, -1, -1, -1, -1, -1, -1, -1,
- 10, -1, 12, 13, -1, -1, -1, -1, -1, -1,
- -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
- -1, -1, -1, 33, 34, -1, 36, -1, -1, -1,
- -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
- -1, -1, -1, -1, -1, 55, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
- 70, -1, -1, -1, -1, 75, -1, -1, -1, -1,
- -1, 81, 82, 83, 84, -1, -1, 87, -1, -1,
- -1, -1, 92, -1, -1, -1, -1, -1, -1, -1,
-1, 10, -1, 12, 13, -1, -1, -1, -1, -1,
-1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
-1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
- -1, -1, -1, -1, -1, -1, 55, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
-1, 70, -1, -1, -1, -1, 75, -1, -1, -1,
-1, -1, 81, 82, 83, 84, -1, -1, 87, -1,
-1, -1, -1, 92, -1, -1, -1, -1, -1, -1,
- -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
- -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
- 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
- -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
- -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
- -1, 70, -1, 72, -1, 74, -1, 76, -1, -1,
- -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
- -1, -1, -1, 92, -1, -1, -1, -1, -1, -1,
- -1, -1, 7, -1, -1, -1, 11, 12, 13, -1,
+ -1, -1, -1, 10, -1, 12, 13, -1, -1, -1,
+ -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
+ -1, -1, 29, -1, -1, -1, 33, 34, -1, 36,
+ -1, -1, -1, -1, -1, -1, 43, -1, -1, -1,
+ 47, -1, -1, -1, -1, -1, -1, -1, 55, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 65, 66,
+ 67, 68, -1, 70, -1, -1, -1, -1, 75, -1,
+ -1, -1, -1, -1, 81, 82, 83, 84, -1, -1,
+ 87, -1, -1, -1, -1, 92, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 10, -1, 12, 13, -1,
-1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
-1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
- -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
- -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
- -1, 76, -1, -1, -1, -1, 81, 82, 83, -1,
+ -1, 36, -1, -1, -1, -1, -1, -1, 43, -1,
+ -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
+ 55, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, -1, -1, -1, -1,
+ 75, -1, -1, -1, -1, -1, 81, 82, 83, 84,
-1, -1, 87, -1, -1, -1, -1, 92, -1, -1,
- -1, -1, -1, -1, -1, -1, 11, 12, 13, -1,
- -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
- -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
- -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
- -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
+ -1, -1, -1, -1, -1, -1, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
+ -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
+ 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
+ 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
- 75, 76, -1, -1, -1, -1, 81, 82, 83, -1,
- -1, -1, 87, -1, -1, -1, -1, 92, -1, -1,
- -1, -1, -1, -1, -1, -1, 11, 12, 13, -1,
- -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
- -1, -1, -1, -1, 29, 30, -1, -1, 33, 34,
- -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
- -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
- -1, -1, -1, -1, -1, -1, 61, -1, -1, -1,
- 65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
- -1, 76, -1, -1, -1, -1, 81, 82, 83, -1,
- -1, -1, 87, -1, -1, -1, -1, 92, -1, -1,
- -1, -1, -1, -1, -1, -1, 8, -1, -1, 11,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
- 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
- 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
- -1, 53, -1, -1, 56, -1, -1, -1, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- 72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
- 82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
- 92, -1, -1, -1, -1, -1, -1, -1, -1, 11,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
- 22, -1, -1, -1, -1, -1, -1, 29, 30, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
- 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
- -1, 53, -1, -1, -1, -1, -1, -1, -1, 61,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- 72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
- 82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
- 92, -1, -1, -1, -1, -1, -1, -1, -1, 8,
+ -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
+ 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
+ -1, -1, -1, 87, -1, -1, -1, -1, 92, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 7, -1,
-1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
-1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
-1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
- -1, -1, 51, -1, 53, -1, -1, 56, -1, -1,
+ -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
-1, 70, -1, 72, -1, 74, -1, 76, -1, -1,
-1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
-1, -1, -1, 92, -1, -1, -1, -1, -1, -1,
- -1, -1, 8, -1, -1, 11, 12, 13, -1, -1,
- -1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
- -1, -1, -1, 29, -1, -1, -1, 33, 34, -1,
- 36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
- -1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
- 56, -1, -1, -1, -1, -1, -1, -1, -1, 65,
- 66, 67, 68, -1, 70, -1, 72, -1, 74, -1,
- 76, -1, -1, -1, -1, 81, 82, 83, -1, -1,
- -1, 87, -1, -1, -1, -1, 92, -1, -1, -1,
+ -1, -1, -1, 11, 12, 13, -1, -1, -1, -1,
+ -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,
+ -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
+ -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
+ -1, -1, -1, 51, -1, 53, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
+ 68, -1, 70, -1, 72, -1, 74, 75, 76, -1,
+ -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
+ -1, -1, -1, -1, 92, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 11, 12, 13, -1, -1, -1,
+ -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
+ -1, -1, 29, 30, -1, -1, 33, 34, -1, 36,
+ -1, -1, -1, 40, -1, 42, 43, 44, -1, -1,
+ 47, -1, -1, -1, 51, -1, 53, -1, -1, -1,
+ -1, -1, -1, -1, 61, -1, -1, -1, 65, 66,
+ 67, 68, -1, 70, -1, 72, -1, 74, -1, 76,
+ -1, -1, -1, -1, 81, 82, 83, -1, -1, -1,
+ 87, -1, -1, -1, -1, 92, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 8, -1, -1, 11, 12,
13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
-1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
@@ -885,45 +853,73 @@ const short QDeclarativeJSGrammar::action_check [] = {
-1, -1, 65, 66, 67, 68, -1, 70, -1, 72,
-1, 74, -1, 76, -1, -1, -1, -1, 81, 82,
83, -1, -1, -1, 87, -1, -1, -1, -1, 92,
- -1, -1, -1, -1, -1, -1, -1, -1, 4, 5,
- 6, -1, -1, 9, 10, 11, -1, -1, 14, -1,
- 16, -1, -1, -1, 20, 21, 22, -1, -1, -1,
- -1, -1, -1, 29, 30, 31, 32, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 43, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 59, -1, -1, -1, -1, -1, -1,
- 66, 67, 68, 69, 70, 71, -1, 73, 74, 75,
- 76, 77, 78, -1, -1, 81, 82, 83, 84, 85,
- 86, -1, -1, -1, -1, -1, 92, -1, -1, -1,
- -1, -1, -1, -1, -1, 4, 5, 6, -1, -1,
- 9, 10, 11, -1, -1, 14, -1, 16, -1, -1,
- -1, 20, 21, 22, -1, -1, -1, -1, -1, -1,
- 29, 30, 31, 32, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 59, -1, -1, -1, -1, -1, 65, 66, 67, -1,
- 69, 70, 71, -1, 73, 74, 75, 76, 77, 78,
- -1, -1, 81, 82, 83, 84, 85, 86, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 11,
+ 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
+ 22, -1, -1, -1, -1, -1, -1, 29, 30, -1,
+ -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
+ 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
+ -1, 53, -1, -1, -1, -1, -1, -1, -1, 61,
+ -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
+ 72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
+ 82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
+ 92, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 8, -1, -1, 11, 12, 13, -1, -1, -1, -1,
+ -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,
+ -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
+ -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
+ -1, -1, -1, 51, -1, 53, -1, -1, 56, -1,
+ -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
+ 68, -1, 70, -1, 72, -1, 74, -1, 76, -1,
+ -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
+ -1, -1, -1, -1, 92, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
+ -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
+ 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
+ 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
+ -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
+ -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
+ 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
+ -1, -1, -1, 87, -1, -1, -1, -1, 92, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 8, -1,
+ -1, 11, 12, 13, -1, -1, -1, -1, -1, -1,
+ -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
+ -1, -1, -1, 33, 34, -1, 36, -1, -1, -1,
+ 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
+ -1, 51, -1, 53, -1, -1, 56, -1, -1, -1,
+ -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
+ 70, -1, 72, -1, 74, -1, 76, -1, -1, -1,
+ -1, 81, 82, 83, -1, -1, -1, 87, -1, -1,
+ -1, -1, 92, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 4, 5, 6, -1, -1, 9, 10, 11,
-1, -1, 14, -1, 16, -1, -1, -1, 20, 21,
22, -1, -1, -1, -1, -1, -1, 29, 30, 31,
32, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
- -1, -1, -1, 55, -1, -1, -1, 59, -1, -1,
- -1, -1, -1, 65, 66, 67, -1, 69, 70, 71,
+ -1, 43, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 59, -1, -1,
+ -1, -1, -1, -1, 66, 67, 68, 69, 70, 71,
-1, 73, 74, 75, 76, 77, 78, -1, -1, 81,
82, 83, 84, 85, 86, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 4,
- -1, -1, -1, -1, 9, -1, 11, 12, 13, 14,
- -1, -1, -1, -1, -1, -1, 21, 22, -1, -1,
- -1, -1, -1, -1, 29, 30, -1, -1, 33, 34,
- -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
- -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
- -1, -1, -1, -1, 59, -1, 61, -1, -1, -1,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, -1, -1, 81, 82, 83, 84,
- 85, -1, 87, -1, -1, -1, -1, 92, -1, -1,
+ 92, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 4, 5, 6, -1, -1, 9, 10, 11, -1, -1,
+ 14, -1, 16, -1, -1, -1, 20, 21, 22, -1,
+ -1, -1, -1, -1, -1, 29, 30, 31, 32, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 43,
+ -1, -1, -1, 47, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 59, -1, -1, -1, -1,
+ -1, 65, 66, 67, -1, 69, 70, 71, -1, 73,
+ 74, 75, 76, 77, 78, -1, -1, 81, 82, 83,
+ 84, 85, 86, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 4, 5,
+ 6, -1, -1, 9, 10, 11, -1, -1, 14, -1,
+ 16, -1, -1, -1, 20, 21, 22, -1, -1, -1,
+ -1, -1, -1, 29, 30, 31, 32, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 43, -1, -1,
+ -1, 47, -1, -1, -1, -1, -1, -1, -1, 55,
+ -1, -1, -1, 59, -1, -1, -1, -1, -1, 65,
+ 66, 67, -1, 69, 70, 71, -1, 73, 74, 75,
+ 76, 77, 78, -1, -1, 81, 82, 83, 84, 85,
+ 86, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 4, -1, -1, -1,
-1, 9, -1, 11, 12, 13, 14, -1, -1, -1,
-1, -1, -1, 21, 22, -1, -1, -1, -1, -1,
@@ -934,16 +930,26 @@ const short QDeclarativeJSGrammar::action_check [] = {
68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
78, -1, -1, 81, 82, 83, 84, 85, -1, 87,
-1, -1, -1, -1, 92, -1, -1, -1, -1, -1,
- -1, -1, -1, 4, 5, 6, -1, -1, 9, 10,
- 11, 12, 13, 14, -1, 16, -1, -1, -1, 20,
- 21, 22, -1, -1, -1, -1, -1, -1, 29, 30,
- 31, 32, 33, 34, -1, 36, -1, -1, -1, 40,
- -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
- 51, -1, 53, -1, -1, -1, -1, -1, 59, -1,
- 61, -1, -1, -1, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 78, -1, -1,
- 81, 82, 83, 84, 85, 86, 87, -1, -1, -1,
- -1, 92, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 4, -1, -1, -1, -1, 9,
+ -1, 11, 12, 13, 14, -1, -1, -1, -1, -1,
+ -1, 21, 22, -1, -1, -1, -1, -1, -1, 29,
+ 30, -1, -1, 33, 34, -1, 36, -1, -1, -1,
+ 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
+ -1, 51, -1, 53, -1, -1, -1, -1, -1, 59,
+ -1, 61, -1, -1, -1, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, -1,
+ -1, 81, 82, 83, 84, 85, -1, 87, -1, -1,
+ -1, -1, 92, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 4, 5, 6, -1, -1, 9, 10, 11,
+ 12, 13, 14, -1, 16, -1, -1, -1, 20, 21,
+ 22, -1, -1, -1, -1, -1, -1, 29, 30, 31,
+ 32, 33, 34, -1, 36, -1, -1, -1, 40, -1,
+ 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
+ -1, 53, -1, -1, -1, -1, -1, 59, -1, 61,
+ -1, -1, -1, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, -1, -1, 81,
+ 82, 83, 84, 85, 86, 87, -1, -1, -1, -1,
+ 92, -1, -1, -1, -1, -1, -1, -1, -1, -1,
4, 5, 6, -1, -1, 9, 10, 11, 12, 13,
14, -1, 16, -1, -1, -1, 20, 21, 22, -1,
-1, -1, -1, -1, -1, 29, 30, 31, 32, 33,
@@ -953,7 +959,7 @@ const short QDeclarativeJSGrammar::action_check [] = {
-1, 65, 66, 67, 68, 69, 70, 71, 72, 73,
74, 75, 76, 77, 78, -1, -1, 81, 82, 83,
84, 85, 86, 87, -1, -1, -1, -1, 92, -1,
- -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
26, 36, 15, 15, 15, 15, 26, 26, 3, 15,
15, 26, 2, 15, 3, 19, 2, 15, 2, 2,
diff --git a/src/declarative/qml/parser/qdeclarativejsgrammar_p.h b/src/declarative/qml/parser/qdeclarativejsgrammar_p.h
index a093bc25d9..0dae476372 100644
--- a/src/declarative/qml/parser/qdeclarativejsgrammar_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsgrammar_p.h
@@ -63,8 +63,8 @@ class QDeclarativeJSGrammar
public:
enum VariousConstants {
EOF_SYMBOL = 0,
- REDUCE_HERE = 100,
- SHIFT_THERE = 99,
+ REDUCE_HERE = 101,
+ SHIFT_THERE = 100,
T_AND = 1,
T_AND_AND = 2,
T_AND_EQ = 3,
@@ -89,13 +89,14 @@ public:
T_EQ = 17,
T_EQ_EQ = 18,
T_EQ_EQ_EQ = 19,
+ T_ERROR = 93,
T_FALSE = 83,
- T_FEED_JS_EXPRESSION = 96,
- T_FEED_JS_PROGRAM = 98,
- T_FEED_JS_SOURCE_ELEMENT = 97,
- T_FEED_JS_STATEMENT = 95,
- T_FEED_UI_OBJECT_MEMBER = 94,
- T_FEED_UI_PROGRAM = 93,
+ T_FEED_JS_EXPRESSION = 97,
+ T_FEED_JS_PROGRAM = 99,
+ T_FEED_JS_SOURCE_ELEMENT = 98,
+ T_FEED_JS_STATEMENT = 96,
+ T_FEED_UI_OBJECT_MEMBER = 95,
+ T_FEED_UI_PROGRAM = 94,
T_FINALLY = 20,
T_FOR = 21,
T_FUNCTION = 22,
@@ -167,12 +168,12 @@ public:
ACCEPT_STATE = 640,
RULE_COUNT = 345,
STATE_COUNT = 641,
- TERMINAL_COUNT = 101,
+ TERMINAL_COUNT = 102,
NON_TERMINAL_COUNT = 107,
GOTO_INDEX_OFFSET = 641,
- GOTO_INFO_OFFSET = 2787,
- GOTO_CHECK_OFFSET = 2787
+ GOTO_INFO_OFFSET = 2818,
+ GOTO_CHECK_OFFSET = 2818
};
static const char *const spell [];
diff --git a/src/declarative/qml/parser/qdeclarativejskeywords_p.h b/src/declarative/qml/parser/qdeclarativejskeywords_p.h
new file mode 100644
index 0000000000..26e0def859
--- /dev/null
+++ b/src/declarative/qml/parser/qdeclarativejskeywords_p.h
@@ -0,0 +1,860 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEJSKEYWORDS_P_H
+#define QDECLARATIVEJSKEYWORDS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+static inline int classify2(const QChar *s) {
+ if (s[0].unicode() == 'a') {
+ if (s[1].unicode() == 's') {
+ return Lexer::T_AS;
+ }
+ }
+ else if (s[0].unicode() == 'd') {
+ if (s[1].unicode() == 'o') {
+ return Lexer::T_DO;
+ }
+ }
+ else if (s[0].unicode() == 'i') {
+ if (s[1].unicode() == 'f') {
+ return Lexer::T_IF;
+ }
+ else if (s[1].unicode() == 'n') {
+ return Lexer::T_IN;
+ }
+ }
+ else if (s[0].unicode() == 'o') {
+ if (s[1].unicode() == 'n') {
+ return Lexer::T_ON;
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify3(const QChar *s) {
+ if (s[0].unicode() == 'f') {
+ if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 'r') {
+ return Lexer::T_FOR;
+ }
+ }
+ }
+ else if (s[0].unicode() == 'i') {
+ if (s[1].unicode() == 'n') {
+ if (s[2].unicode() == 't') {
+ return Lexer::T_INT;
+ }
+ }
+ }
+ else if (s[0].unicode() == 'n') {
+ if (s[1].unicode() == 'e') {
+ if (s[2].unicode() == 'w') {
+ return Lexer::T_NEW;
+ }
+ }
+ }
+ else if (s[0].unicode() == 't') {
+ if (s[1].unicode() == 'r') {
+ if (s[2].unicode() == 'y') {
+ return Lexer::T_TRY;
+ }
+ }
+ }
+ else if (s[0].unicode() == 'v') {
+ if (s[1].unicode() == 'a') {
+ if (s[2].unicode() == 'r') {
+ return Lexer::T_VAR;
+ }
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify4(const QChar *s) {
+ if (s[0].unicode() == 'b') {
+ if (s[1].unicode() == 'y') {
+ if (s[2].unicode() == 't') {
+ if (s[3].unicode() == 'e') {
+ return Lexer::T_BYTE;
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'c') {
+ if (s[1].unicode() == 'a') {
+ if (s[2].unicode() == 's') {
+ if (s[3].unicode() == 'e') {
+ return Lexer::T_CASE;
+ }
+ }
+ }
+ else if (s[1].unicode() == 'h') {
+ if (s[2].unicode() == 'a') {
+ if (s[3].unicode() == 'r') {
+ return Lexer::T_CHAR;
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'e') {
+ if (s[1].unicode() == 'l') {
+ if (s[2].unicode() == 's') {
+ if (s[3].unicode() == 'e') {
+ return Lexer::T_ELSE;
+ }
+ }
+ }
+ else if (s[1].unicode() == 'n') {
+ if (s[2].unicode() == 'u') {
+ if (s[3].unicode() == 'm') {
+ return Lexer::T_ENUM;
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'g') {
+ if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 't') {
+ if (s[3].unicode() == 'o') {
+ return Lexer::T_GOTO;
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'l') {
+ if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 'n') {
+ if (s[3].unicode() == 'g') {
+ return Lexer::T_LONG;
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'n') {
+ if (s[1].unicode() == 'u') {
+ if (s[2].unicode() == 'l') {
+ if (s[3].unicode() == 'l') {
+ return Lexer::T_NULL;
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 't') {
+ if (s[1].unicode() == 'h') {
+ if (s[2].unicode() == 'i') {
+ if (s[3].unicode() == 's') {
+ return Lexer::T_THIS;
+ }
+ }
+ }
+ else if (s[1].unicode() == 'r') {
+ if (s[2].unicode() == 'u') {
+ if (s[3].unicode() == 'e') {
+ return Lexer::T_TRUE;
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'v') {
+ if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 'i') {
+ if (s[3].unicode() == 'd') {
+ return Lexer::T_VOID;
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'w') {
+ if (s[1].unicode() == 'i') {
+ if (s[2].unicode() == 't') {
+ if (s[3].unicode() == 'h') {
+ return Lexer::T_WITH;
+ }
+ }
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify5(const QChar *s) {
+ if (s[0].unicode() == 'b') {
+ if (s[1].unicode() == 'r') {
+ if (s[2].unicode() == 'e') {
+ if (s[3].unicode() == 'a') {
+ if (s[4].unicode() == 'k') {
+ return Lexer::T_BREAK;
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'c') {
+ if (s[1].unicode() == 'a') {
+ if (s[2].unicode() == 't') {
+ if (s[3].unicode() == 'c') {
+ if (s[4].unicode() == 'h') {
+ return Lexer::T_CATCH;
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'l') {
+ if (s[2].unicode() == 'a') {
+ if (s[3].unicode() == 's') {
+ if (s[4].unicode() == 's') {
+ return Lexer::T_CLASS;
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 'n') {
+ if (s[3].unicode() == 's') {
+ if (s[4].unicode() == 't') {
+ return Lexer::T_CONST;
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'f') {
+ if (s[1].unicode() == 'a') {
+ if (s[2].unicode() == 'l') {
+ if (s[3].unicode() == 's') {
+ if (s[4].unicode() == 'e') {
+ return Lexer::T_FALSE;
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'i') {
+ if (s[2].unicode() == 'n') {
+ if (s[3].unicode() == 'a') {
+ if (s[4].unicode() == 'l') {
+ return Lexer::T_FINAL;
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'l') {
+ if (s[2].unicode() == 'o') {
+ if (s[3].unicode() == 'a') {
+ if (s[4].unicode() == 't') {
+ return Lexer::T_FLOAT;
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 's') {
+ if (s[1].unicode() == 'h') {
+ if (s[2].unicode() == 'o') {
+ if (s[3].unicode() == 'r') {
+ if (s[4].unicode() == 't') {
+ return Lexer::T_SHORT;
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'u') {
+ if (s[2].unicode() == 'p') {
+ if (s[3].unicode() == 'e') {
+ if (s[4].unicode() == 'r') {
+ return Lexer::T_SUPER;
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 't') {
+ if (s[1].unicode() == 'h') {
+ if (s[2].unicode() == 'r') {
+ if (s[3].unicode() == 'o') {
+ if (s[4].unicode() == 'w') {
+ return Lexer::T_THROW;
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'w') {
+ if (s[1].unicode() == 'h') {
+ if (s[2].unicode() == 'i') {
+ if (s[3].unicode() == 'l') {
+ if (s[4].unicode() == 'e') {
+ return Lexer::T_WHILE;
+ }
+ }
+ }
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify6(const QChar *s) {
+ if (s[0].unicode() == 'd') {
+ if (s[1].unicode() == 'e') {
+ if (s[2].unicode() == 'l') {
+ if (s[3].unicode() == 'e') {
+ if (s[4].unicode() == 't') {
+ if (s[5].unicode() == 'e') {
+ return Lexer::T_DELETE;
+ }
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 'u') {
+ if (s[3].unicode() == 'b') {
+ if (s[4].unicode() == 'l') {
+ if (s[5].unicode() == 'e') {
+ return Lexer::T_DOUBLE;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'e') {
+ if (s[1].unicode() == 'x') {
+ if (s[2].unicode() == 'p') {
+ if (s[3].unicode() == 'o') {
+ if (s[4].unicode() == 'r') {
+ if (s[5].unicode() == 't') {
+ return Lexer::T_EXPORT;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'i') {
+ if (s[1].unicode() == 'm') {
+ if (s[2].unicode() == 'p') {
+ if (s[3].unicode() == 'o') {
+ if (s[4].unicode() == 'r') {
+ if (s[5].unicode() == 't') {
+ return Lexer::T_IMPORT;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'n') {
+ if (s[1].unicode() == 'a') {
+ if (s[2].unicode() == 't') {
+ if (s[3].unicode() == 'i') {
+ if (s[4].unicode() == 'v') {
+ if (s[5].unicode() == 'e') {
+ return Lexer::T_NATIVE;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'p') {
+ if (s[1].unicode() == 'u') {
+ if (s[2].unicode() == 'b') {
+ if (s[3].unicode() == 'l') {
+ if (s[4].unicode() == 'i') {
+ if (s[5].unicode() == 'c') {
+ return Lexer::T_PUBLIC;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'r') {
+ if (s[1].unicode() == 'e') {
+ if (s[2].unicode() == 't') {
+ if (s[3].unicode() == 'u') {
+ if (s[4].unicode() == 'r') {
+ if (s[5].unicode() == 'n') {
+ return Lexer::T_RETURN;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 's') {
+ if (s[1].unicode() == 'i') {
+ if (s[2].unicode() == 'g') {
+ if (s[3].unicode() == 'n') {
+ if (s[4].unicode() == 'a') {
+ if (s[5].unicode() == 'l') {
+ return Lexer::T_SIGNAL;
+ }
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 't') {
+ if (s[2].unicode() == 'a') {
+ if (s[3].unicode() == 't') {
+ if (s[4].unicode() == 'i') {
+ if (s[5].unicode() == 'c') {
+ return Lexer::T_STATIC;
+ }
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'w') {
+ if (s[2].unicode() == 'i') {
+ if (s[3].unicode() == 't') {
+ if (s[4].unicode() == 'c') {
+ if (s[5].unicode() == 'h') {
+ return Lexer::T_SWITCH;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 't') {
+ if (s[1].unicode() == 'h') {
+ if (s[2].unicode() == 'r') {
+ if (s[3].unicode() == 'o') {
+ if (s[4].unicode() == 'w') {
+ if (s[5].unicode() == 's') {
+ return Lexer::T_THROWS;
+ }
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'y') {
+ if (s[2].unicode() == 'p') {
+ if (s[3].unicode() == 'e') {
+ if (s[4].unicode() == 'o') {
+ if (s[5].unicode() == 'f') {
+ return Lexer::T_TYPEOF;
+ }
+ }
+ }
+ }
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify7(const QChar *s) {
+ if (s[0].unicode() == 'b') {
+ if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 'o') {
+ if (s[3].unicode() == 'l') {
+ if (s[4].unicode() == 'e') {
+ if (s[5].unicode() == 'a') {
+ if (s[6].unicode() == 'n') {
+ return Lexer::T_BOOLEAN;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'd') {
+ if (s[1].unicode() == 'e') {
+ if (s[2].unicode() == 'f') {
+ if (s[3].unicode() == 'a') {
+ if (s[4].unicode() == 'u') {
+ if (s[5].unicode() == 'l') {
+ if (s[6].unicode() == 't') {
+ return Lexer::T_DEFAULT;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'e') {
+ if (s[1].unicode() == 'x') {
+ if (s[2].unicode() == 't') {
+ if (s[3].unicode() == 'e') {
+ if (s[4].unicode() == 'n') {
+ if (s[5].unicode() == 'd') {
+ if (s[6].unicode() == 's') {
+ return Lexer::T_EXTENDS;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'f') {
+ if (s[1].unicode() == 'i') {
+ if (s[2].unicode() == 'n') {
+ if (s[3].unicode() == 'a') {
+ if (s[4].unicode() == 'l') {
+ if (s[5].unicode() == 'l') {
+ if (s[6].unicode() == 'y') {
+ return Lexer::T_FINALLY;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'p') {
+ if (s[1].unicode() == 'a') {
+ if (s[2].unicode() == 'c') {
+ if (s[3].unicode() == 'k') {
+ if (s[4].unicode() == 'a') {
+ if (s[5].unicode() == 'g') {
+ if (s[6].unicode() == 'e') {
+ return Lexer::T_PACKAGE;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'r') {
+ if (s[2].unicode() == 'i') {
+ if (s[3].unicode() == 'v') {
+ if (s[4].unicode() == 'a') {
+ if (s[5].unicode() == 't') {
+ if (s[6].unicode() == 'e') {
+ return Lexer::T_PRIVATE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify8(const QChar *s) {
+ if (s[0].unicode() == 'a') {
+ if (s[1].unicode() == 'b') {
+ if (s[2].unicode() == 's') {
+ if (s[3].unicode() == 't') {
+ if (s[4].unicode() == 'r') {
+ if (s[5].unicode() == 'a') {
+ if (s[6].unicode() == 'c') {
+ if (s[7].unicode() == 't') {
+ return Lexer::T_ABSTRACT;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'c') {
+ if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 'n') {
+ if (s[3].unicode() == 't') {
+ if (s[4].unicode() == 'i') {
+ if (s[5].unicode() == 'n') {
+ if (s[6].unicode() == 'u') {
+ if (s[7].unicode() == 'e') {
+ return Lexer::T_CONTINUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'd') {
+ if (s[1].unicode() == 'e') {
+ if (s[2].unicode() == 'b') {
+ if (s[3].unicode() == 'u') {
+ if (s[4].unicode() == 'g') {
+ if (s[5].unicode() == 'g') {
+ if (s[6].unicode() == 'e') {
+ if (s[7].unicode() == 'r') {
+ return Lexer::T_DEBUGGER;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'f') {
+ if (s[1].unicode() == 'u') {
+ if (s[2].unicode() == 'n') {
+ if (s[3].unicode() == 'c') {
+ if (s[4].unicode() == 't') {
+ if (s[5].unicode() == 'i') {
+ if (s[6].unicode() == 'o') {
+ if (s[7].unicode() == 'n') {
+ return Lexer::T_FUNCTION;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'p') {
+ if (s[1].unicode() == 'r') {
+ if (s[2].unicode() == 'o') {
+ if (s[3].unicode() == 'p') {
+ if (s[4].unicode() == 'e') {
+ if (s[5].unicode() == 'r') {
+ if (s[6].unicode() == 't') {
+ if (s[7].unicode() == 'y') {
+ return Lexer::T_PROPERTY;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'r') {
+ if (s[1].unicode() == 'e') {
+ if (s[2].unicode() == 'a') {
+ if (s[3].unicode() == 'd') {
+ if (s[4].unicode() == 'o') {
+ if (s[5].unicode() == 'n') {
+ if (s[6].unicode() == 'l') {
+ if (s[7].unicode() == 'y') {
+ return Lexer::T_READONLY;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'v') {
+ if (s[1].unicode() == 'o') {
+ if (s[2].unicode() == 'l') {
+ if (s[3].unicode() == 'a') {
+ if (s[4].unicode() == 't') {
+ if (s[5].unicode() == 'i') {
+ if (s[6].unicode() == 'l') {
+ if (s[7].unicode() == 'e') {
+ return Lexer::T_VOLATILE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify9(const QChar *s) {
+ if (s[0].unicode() == 'i') {
+ if (s[1].unicode() == 'n') {
+ if (s[2].unicode() == 't') {
+ if (s[3].unicode() == 'e') {
+ if (s[4].unicode() == 'r') {
+ if (s[5].unicode() == 'f') {
+ if (s[6].unicode() == 'a') {
+ if (s[7].unicode() == 'c') {
+ if (s[8].unicode() == 'e') {
+ return Lexer::T_INTERFACE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'p') {
+ if (s[1].unicode() == 'r') {
+ if (s[2].unicode() == 'o') {
+ if (s[3].unicode() == 't') {
+ if (s[4].unicode() == 'e') {
+ if (s[5].unicode() == 'c') {
+ if (s[6].unicode() == 't') {
+ if (s[7].unicode() == 'e') {
+ if (s[8].unicode() == 'd') {
+ return Lexer::T_PROTECTED;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 't') {
+ if (s[1].unicode() == 'r') {
+ if (s[2].unicode() == 'a') {
+ if (s[3].unicode() == 'n') {
+ if (s[4].unicode() == 's') {
+ if (s[5].unicode() == 'i') {
+ if (s[6].unicode() == 'e') {
+ if (s[7].unicode() == 'n') {
+ if (s[8].unicode() == 't') {
+ return Lexer::T_TRANSIENT;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify10(const QChar *s) {
+ if (s[0].unicode() == 'i') {
+ if (s[1].unicode() == 'm') {
+ if (s[2].unicode() == 'p') {
+ if (s[3].unicode() == 'l') {
+ if (s[4].unicode() == 'e') {
+ if (s[5].unicode() == 'm') {
+ if (s[6].unicode() == 'e') {
+ if (s[7].unicode() == 'n') {
+ if (s[8].unicode() == 't') {
+ if (s[9].unicode() == 's') {
+ return Lexer::T_IMPLEMENTS;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (s[1].unicode() == 'n') {
+ if (s[2].unicode() == 's') {
+ if (s[3].unicode() == 't') {
+ if (s[4].unicode() == 'a') {
+ if (s[5].unicode() == 'n') {
+ if (s[6].unicode() == 'c') {
+ if (s[7].unicode() == 'e') {
+ if (s[8].unicode() == 'o') {
+ if (s[9].unicode() == 'f') {
+ return Lexer::T_INSTANCEOF;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify12(const QChar *s) {
+ if (s[0].unicode() == 's') {
+ if (s[1].unicode() == 'y') {
+ if (s[2].unicode() == 'n') {
+ if (s[3].unicode() == 'c') {
+ if (s[4].unicode() == 'h') {
+ if (s[5].unicode() == 'r') {
+ if (s[6].unicode() == 'o') {
+ if (s[7].unicode() == 'n') {
+ if (s[8].unicode() == 'i') {
+ if (s[9].unicode() == 'z') {
+ if (s[10].unicode() == 'e') {
+ if (s[11].unicode() == 'd') {
+ return Lexer::T_SYNCHRONIZED;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return Lexer::T_IDENTIFIER;
+}
+
+int Lexer::classify(const QChar *s, int n) {
+ switch (n) {
+ case 2: return classify2(s);
+ case 3: return classify3(s);
+ case 4: return classify4(s);
+ case 5: return classify5(s);
+ case 6: return classify6(s);
+ case 7: return classify7(s);
+ case 8: return classify8(s);
+ case 9: return classify9(s);
+ case 10: return classify10(s);
+ case 12: return classify12(s);
+ default: return Lexer::T_IDENTIFIER;
+ } // switch
+}
+
+#endif // QDECLARATIVEJSKEYWORDS_P_H
diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp
index 4d68f289bc..d466140949 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer.cpp
+++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp
@@ -39,1220 +39,1005 @@
**
****************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "qdeclarativejslexer_p.h"
-
-#include "qdeclarativejsglobal_p.h"
#include "qdeclarativejsengine_p.h"
-#include "qdeclarativejsgrammar_p.h"
-
-#include <QtCore/qcoreapplication.h>
+#include "qdeclarativejsmemorypool_p.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#include <private/qdeclarativeutils_p.h>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QVarLengthArray>
+#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
QT_END_NAMESPACE
-QT_QML_BEGIN_NAMESPACE
+using namespace QDeclarativeJS;
-#define shiftWindowsLineBreak() \
- do { \
- if (((current == '\r') && (next1 == '\n')) \
- || ((current == '\n') && (next1 == '\r'))) { \
- shift(1); \
- } \
- } \
- while (0)
+enum RegExpFlag {
+ Global = 0x01,
+ IgnoreCase = 0x02,
+ Multiline = 0x04
+};
-namespace QDeclarativeJS {
-extern double integerFromString(const char *buf, int size, int radix);
+static int flagFromChar(const QChar &ch)
+{
+ switch (ch.unicode()) {
+ case 'g': return Global;
+ case 'i': return IgnoreCase;
+ case 'm': return Multiline;
+ }
+ return 0;
}
-using namespace QDeclarativeJS;
+static unsigned char convertHex(ushort c)
+{
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ else if (c >= 'a' && c <= 'f')
+ return (c - 'a' + 10);
+ else
+ return (c - 'A' + 10);
+}
-Lexer::Lexer(Engine *eng, bool tokenizeComments)
- : driver(eng),
- yylineno(0),
- done(false),
- size8(128), size16(128),
- pos8(0), pos16(0),
- terminator(false),
- restrKeyword(false),
- delimited(false),
- stackToken(-1),
- state(Start),
- pos(0),
- code(0), length(0),
- yycolumn(0),
- startpos(0),
- startlineno(0), startcolumn(0),
- bol(true),
- current(0), next1(0), next2(0), next3(0),
- err(NoError),
- wantRx(false),
- check_reserved(true),
- parenthesesState(IgnoreParentheses),
- parenthesesCount(0),
- prohibitAutomaticSemicolon(false),
- tokenizeComments(tokenizeComments)
+static QChar convertHex(QChar c1, QChar c2)
{
- if (driver) driver->setLexer(this);
- // allocate space for read buffers
- buffer8 = new char[size8];
- buffer16 = new QChar[size16];
- pattern = 0;
- flags = 0;
+ return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
+}
+static QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
+{
+ return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()),
+ (convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
}
-Lexer::~Lexer()
+Lexer::Lexer(Engine *engine)
+ : _engine(engine)
+ , _codePtr(0)
+ , _lastLinePtr(0)
+ , _tokenLinePtr(0)
+ , _tokenStartPtr(0)
+ , _char(QLatin1Char('\n'))
+ , _errorCode(NoError)
+ , _currentLineNumber(0)
+ , _tokenValue(0)
+ , _parenthesesState(IgnoreParentheses)
+ , _parenthesesCount(0)
+ , _stackToken(-1)
+ , _patternFlags(0)
+ , _tokenLength(0)
+ , _tokenLine(0)
+ , _validTokenText(false)
+ , _prohibitAutomaticSemicolon(false)
+ , _restrictedKeyword(false)
+ , _terminator(false)
+ , _delimited(false)
{
- delete [] buffer8;
- delete [] buffer16;
+ if (engine)
+ engine->setLexer(this);
}
-void Lexer::setCode(const QString &c, int lineno)
+QString Lexer::code() const
{
- errmsg.clear();
- yylineno = lineno;
- yycolumn = 1;
- restrKeyword = false;
- delimited = false;
- stackToken = -1;
- pos = 0;
- code = c.unicode();
- length = c.length();
- bol = true;
-
- // read first characters
- current = (length > 0) ? code[0].unicode() : 0;
- next1 = (length > 1) ? code[1].unicode() : 0;
- next2 = (length > 2) ? code[2].unicode() : 0;
- next3 = (length > 3) ? code[3].unicode() : 0;
+ return _code;
}
-void Lexer::shift(uint p)
+void Lexer::setCode(const QString &code, int lineno)
{
- while (p--) {
- ++pos;
- ++yycolumn;
- current = next1;
- next1 = next2;
- next2 = next3;
- next3 = (pos + 3 < length) ? code[pos+3].unicode() : 0;
- }
+ if (_engine)
+ _engine->setCode(code);
+
+ _code = code;
+ _tokenText.clear();
+ _tokenText.reserve(1024);
+ _errorMessage.clear();
+ _tokenSpell = QStringRef();
+
+ _codePtr = code.unicode();
+ _lastLinePtr = _codePtr;
+ _tokenLinePtr = _codePtr;
+ _tokenStartPtr = _codePtr;
+
+ _char = QLatin1Char('\n');
+ _errorCode = NoError;
+
+ _currentLineNumber = lineno;
+ _tokenValue = 0;
+
+ // parentheses state
+ _parenthesesState = IgnoreParentheses;
+ _parenthesesCount = 0;
+
+ _stackToken = -1;
+
+ _patternFlags = 0;
+ _tokenLength = 0;
+ _tokenLine = lineno;
+
+ _validTokenText = false;
+ _prohibitAutomaticSemicolon = false;
+ _restrictedKeyword = false;
+ _terminator = false;
+ _delimited = false;
}
-void Lexer::setDone(State s)
+void Lexer::scanChar()
{
- state = s;
- done = true;
+ _char = *_codePtr++;
+
+ if (_char == QLatin1Char('\n')) {
+ _lastLinePtr = _codePtr; // points to the first character after the newline
+ ++_currentLineNumber;
+ }
}
-int Lexer::findReservedWord(const QChar *c, int size) const
+int Lexer::lex()
{
- switch (size) {
- case 2: {
- if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o'))
- return QDeclarativeJSGrammar::T_DO;
- else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('f'))
- return QDeclarativeJSGrammar::T_IF;
- else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n'))
- return QDeclarativeJSGrammar::T_IN;
- else if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('s'))
- return QDeclarativeJSGrammar::T_AS;
- else if (c[0] == QLatin1Char('o') && c[1] == QLatin1Char('n'))
- return QDeclarativeJSGrammar::T_ON;
- } break;
-
- case 3: {
- if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('o') && c[2] == QLatin1Char('r'))
- return QDeclarativeJSGrammar::T_FOR;
- else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('e') && c[2] == QLatin1Char('w'))
- return QDeclarativeJSGrammar::T_NEW;
- else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r') && c[2] == QLatin1Char('y'))
- return QDeclarativeJSGrammar::T_TRY;
- else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('a') && c[2] == QLatin1Char('r'))
- return QDeclarativeJSGrammar::T_VAR;
- else if (check_reserved) {
- if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n') && c[2] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- }
- } break;
-
- case 4: {
- if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
- && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_CASE;
- else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('l')
- && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_ELSE;
- else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
- && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('s'))
- return QDeclarativeJSGrammar::T_THIS;
- else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
- && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('d'))
- return QDeclarativeJSGrammar::T_VOID;
- else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('i')
- && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('h'))
- return QDeclarativeJSGrammar::T_WITH;
- else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
- && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_TRUE;
- else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('u')
- && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('l'))
- return QDeclarativeJSGrammar::T_NULL;
- else if (check_reserved) {
- if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('n')
- && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('m'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('y')
- && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('l') && c[1] == QLatin1Char('o')
- && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('g'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('h')
- && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('r'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('g') && c[1] == QLatin1Char('o')
- && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('o'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- }
- } break;
-
- case 5: {
- if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('r')
- && c[2] == QLatin1Char('e') && c[3] == QLatin1Char('a')
- && c[4] == QLatin1Char('k'))
- return QDeclarativeJSGrammar::T_BREAK;
- else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
- && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('c')
- && c[4] == QLatin1Char('h'))
- return QDeclarativeJSGrammar::T_CATCH;
- else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
- && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
- && c[4] == QLatin1Char('w'))
- return QDeclarativeJSGrammar::T_THROW;
- else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('h')
- && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('l')
- && c[4] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_WHILE;
- else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
- && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('s')
- && c[4] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_CONST;
- else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('a')
- && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('s')
- && c[4] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_FALSE;
- else if (check_reserved) {
- if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('h')
- && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('r')
- && c[4] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('u')
- && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
- && c[4] == QLatin1Char('r'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
- && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
- && c[4] == QLatin1Char('l'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('l')
- && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('s')
- && c[4] == QLatin1Char('s'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('l')
- && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('a')
- && c[4] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- }
- } break;
-
- case 6: {
- if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
- && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('e')
- && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_DELETE;
- else if (c[0] == QLatin1Char('r') && c[1] == QLatin1Char('e')
- && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('u')
- && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('n'))
- return QDeclarativeJSGrammar::T_RETURN;
- else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('w')
- && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('t')
- && c[4] == QLatin1Char('c') && c[5] == QLatin1Char('h'))
- return QDeclarativeJSGrammar::T_SWITCH;
- else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('y')
- && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
- && c[4] == QLatin1Char('o') && c[5] == QLatin1Char('f'))
- return QDeclarativeJSGrammar::T_TYPEOF;
- else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
- && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
- && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_IMPORT;
- else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('i')
- && c[2] == QLatin1Char('g') && c[3] == QLatin1Char('n')
- && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('l'))
- return QDeclarativeJSGrammar::T_SIGNAL;
- else if (check_reserved) {
- if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
- && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
- && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('t')
- && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('t')
- && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o')
- && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('b')
- && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
- && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
- && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('u')
- && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('l')
- && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
- return QDeclarativeJSGrammar::T_PUBLIC;
- else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('a')
- && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('i')
- && c[4] == QLatin1Char('v') && c[5] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
- && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
- && c[4] == QLatin1Char('w') && c[5] == QLatin1Char('s'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- }
- } break;
-
- case 7: {
- if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
- && c[2] == QLatin1Char('f') && c[3] == QLatin1Char('a')
- && c[4] == QLatin1Char('u') && c[5] == QLatin1Char('l')
- && c[6] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_DEFAULT;
- else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
- && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
- && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('l')
- && c[6] == QLatin1Char('y'))
- return QDeclarativeJSGrammar::T_FINALLY;
- else if (check_reserved) {
- if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('o')
- && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('l')
- && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('a')
- && c[6] == QLatin1Char('n'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
- && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
- && c[4] == QLatin1Char('n') && c[5] == QLatin1Char('d')
- && c[6] == QLatin1Char('s'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('a')
- && c[2] == QLatin1Char('c') && c[3] == QLatin1Char('k')
- && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('g')
- && c[6] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
- && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('v')
- && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('t')
- && c[6] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- }
- } break;
-
- case 8: {
- if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
- && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('t')
- && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('n')
- && c[6] == QLatin1Char('u') && c[7] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_CONTINUE;
- else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('u')
- && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
- && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
- && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n'))
- return QDeclarativeJSGrammar::T_FUNCTION;
- else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
- && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('u')
- && c[4] == QLatin1Char('g') && c[5] == QLatin1Char('g')
- && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('r'))
- return QDeclarativeJSGrammar::T_DEBUGGER;
- else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
- && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('p')
- && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('r')
- && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('y'))
- return QDeclarativeJSGrammar::T_PROPERTY;
- else if (c[0] == QLatin1Char('r') && c[1] == QLatin1Char('e')
- && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('d')
- && c[4] == QLatin1Char('o') && c[5] == QLatin1Char('n')
- && c[6] == QLatin1Char('l') && c[7] == QLatin1Char('y'))
- return QDeclarativeJSGrammar::T_READONLY;
- else if (check_reserved) {
- if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('b')
- && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
- && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('a')
- && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
- && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('a')
- && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
- && c[6] == QLatin1Char('l') && c[7] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- }
- } break;
-
- case 9: {
- if (check_reserved) {
- if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
- && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
- && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('f')
- && c[6] == QLatin1Char('a') && c[7] == QLatin1Char('c')
- && c[8] == QLatin1Char('e'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
- && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('n')
- && c[4] == QLatin1Char('s') && c[5] == QLatin1Char('i')
- && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
- && c[8] == QLatin1Char('t'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
- && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('t')
- && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('c')
- && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('e')
- && c[8] == QLatin1Char('d'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- }
- } break;
-
- case 10: {
- if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
- && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
- && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('n')
- && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('e')
- && c[8] == QLatin1Char('o') && c[9] == QLatin1Char('f'))
- return QDeclarativeJSGrammar::T_INSTANCEOF;
- else if (check_reserved) {
- if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
- && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('l')
- && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('m')
- && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
- && c[8] == QLatin1Char('t') && c[9] == QLatin1Char('s'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
- }
- } break;
-
- case 12: {
- if (check_reserved) {
- if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('y')
- && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
- && c[4] == QLatin1Char('h') && c[5] == QLatin1Char('r')
- && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n')
- && c[8] == QLatin1Char('i') && c[9] == QLatin1Char('z')
- && c[10] == QLatin1Char('e') && c[11] == QLatin1Char('d'))
- return QDeclarativeJSGrammar::T_RESERVED_WORD;
+ _tokenSpell = QStringRef();
+ int token = scanToken();
+ _tokenLength = _codePtr - _tokenStartPtr - 1;
+
+ _delimited = false;
+ _restrictedKeyword = false;
+
+ // update the flags
+ switch (token) {
+ case T_LBRACE:
+ case T_SEMICOLON:
+ _delimited = true;
+ break;
+
+ case T_IF:
+ case T_FOR:
+ case T_WHILE:
+ case T_WITH:
+ _parenthesesState = CountParentheses;
+ _parenthesesCount = 0;
+ break;
+
+ case T_DO:
+ _parenthesesState = BalancedParentheses;
+ break;
+
+ case T_CONTINUE:
+ case T_BREAK:
+ case T_RETURN:
+ case T_THROW:
+ _restrictedKeyword = true;
+ break;
+ } // switch
+
+ // update the parentheses state
+ switch (_parenthesesState) {
+ case IgnoreParentheses:
+ break;
+
+ case CountParentheses:
+ if (token == T_RPAREN) {
+ --_parenthesesCount;
+ if (_parenthesesCount == 0)
+ _parenthesesState = BalancedParentheses;
+ } else if (token == T_LPAREN) {
+ ++_parenthesesCount;
}
- } break;
+ break;
+ case BalancedParentheses:
+ _parenthesesState = IgnoreParentheses;
+ break;
} // switch
- return -1;
+ return token;
}
-int Lexer::lex()
+bool Lexer::isUnicodeEscapeSequence(const QChar *chars)
+{
+ if (isHexDigit(chars[0]) && isHexDigit(chars[1]) && isHexDigit(chars[2]) && isHexDigit(chars[3]))
+ return true;
+
+ return false;
+}
+
+QChar Lexer::decodeUnicodeEscapeCharacter(bool *ok)
+{
+ if (_char == QLatin1Char('u') && isUnicodeEscapeSequence(&_codePtr[0])) {
+ scanChar(); // skip u
+
+ const QChar c1 = _char;
+ scanChar();
+
+ const QChar c2 = _char;
+ scanChar();
+
+ const QChar c3 = _char;
+ scanChar();
+
+ const QChar c4 = _char;
+ scanChar();
+
+ if (ok)
+ *ok = true;
+
+ return convertUnicode(c1, c2, c3, c4);
+ }
+
+ *ok = false;
+ return QChar();
+}
+
+int Lexer::scanToken()
{
- int token = 0;
- state = Start;
- ushort stringType = 0; // either single or double quotes
- bool multiLineString = false;
- pos8 = pos16 = 0;
- done = false;
- terminator = false;
-
- // did we push a token on the stack previously ?
- // (after an automatic semicolon insertion)
- if (stackToken >= 0) {
- setDone(Other);
- token = stackToken;
- stackToken = -1;
+ if (_stackToken != -1) {
+ int tk = _stackToken;
+ _stackToken = -1;
+ return tk;
}
- bool identifierWithEscapedUnicode = false;
-
- while (!done) {
- switch (state) {
- case Start:
- if (isWhiteSpace()) {
- // do nothing
- } else if (current == '/' && next1 == '/') {
- recordStartPos();
- shift(1);
- state = InSingleLineComment;
- } else if (current == '/' && next1 == '*') {
- recordStartPos();
- shift(1);
- state = InMultiLineComment;
- } else if (current == 0) {
- syncProhibitAutomaticSemicolon();
- if (!terminator && !delimited && !prohibitAutomaticSemicolon) {
- // automatic semicolon insertion if program incomplete
- token = QDeclarativeJSGrammar::T_SEMICOLON;
- stackToken = 0;
- setDone(Other);
- } else {
- setDone(Eof);
- }
- } else if (isLineTerminator()) {
- if (restrKeyword) {
- // automatic semicolon insertion
- recordStartPos();
- token = QDeclarativeJSGrammar::T_SEMICOLON;
- setDone(Other);
- } else {
- shiftWindowsLineBreak();
- yylineno++;
- yycolumn = 0;
- bol = true;
- terminator = true;
- syncProhibitAutomaticSemicolon();
- }
- } else if (current == '"' || current == '\'') {
- recordStartPos();
- state = InString;
- multiLineString = false;
- stringType = current;
- } else if (current == '\\' && next1 == 'u') {
- identifierWithEscapedUnicode = true;
- recordStartPos();
-
- shift(2); // skip the unicode escape prefix `\u'
-
- if (isHexDigit(current) && isHexDigit(next1) &&
- isHexDigit(next2) && isHexDigit(next3)) {
- record16(convertUnicode(current, next1, next2, next3));
- shift(3);
- state = InIdentifier;
- } else {
- setDone(Bad);
- err = IllegalUnicodeEscapeSequence;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal unicode escape sequence");
- break;
- }
+ _terminator = false;
+
+again:
+ _validTokenText = false;
+ _tokenLinePtr = _lastLinePtr;
- } else if (isIdentLetter(current)) {
- identifierWithEscapedUnicode = false;
- recordStartPos();
- record16(current);
- state = InIdentifier;
- } else if (current == '0') {
- recordStartPos();
- record8(current);
- state = InNum0;
- } else if (isDecimalDigit(current)) {
- recordStartPos();
- record8(current);
- state = InNum;
- } else if (current == '.' && isDecimalDigit(next1)) {
- recordStartPos();
- record8(current);
- state = InDecimal;
+ while (QDeclarativeUtils::isSpace(_char)) {
+ if (_char == QLatin1Char('\n')) {
+ _tokenLinePtr = _codePtr;
+
+ if (_restrictedKeyword) {
+ // automatic semicolon insertion
+ _tokenLine = _currentLineNumber;
+ _tokenStartPtr = _codePtr - 1; // ### TODO: insert it before the optional \r sequence.
+ return T_SEMICOLON;
} else {
- recordStartPos();
- token = matchPunctuator(current, next1, next2, next3);
- if (token != -1) {
- if (terminator && !delimited && !prohibitAutomaticSemicolon
- && (token == QDeclarativeJSGrammar::T_PLUS_PLUS
- || token == QDeclarativeJSGrammar::T_MINUS_MINUS)) {
- // automatic semicolon insertion
- stackToken = token;
- token = QDeclarativeJSGrammar::T_SEMICOLON;
- }
- setDone(Other);
- }
- else {
- setDone(Bad);
- err = IllegalCharacter;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal character");
+ _terminator = true;
+ syncProhibitAutomaticSemicolon();
+ }
+ }
+
+ scanChar();
+ }
+
+ _tokenStartPtr = _codePtr - 1;
+ _tokenLine = _currentLineNumber;
+
+ if (_char.isNull())
+ return EOF_SYMBOL;
+
+ const QChar ch = _char;
+ scanChar();
+
+ switch (ch.unicode()) {
+ case '~': return T_TILDE;
+ case '}': return T_RBRACE;
+
+ case '|':
+ if (_char == QLatin1Char('|')) {
+ scanChar();
+ return T_OR_OR;
+ } else if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_OR_EQ;
+ }
+ return T_OR;
+
+ case '{': return T_LBRACE;
+
+ case '^':
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_XOR_EQ;
+ }
+ return T_XOR;
+
+ case ']': return T_RBRACKET;
+ case '[': return T_LBRACKET;
+ case '?': return T_QUESTION;
+
+ case '>':
+ if (_char == QLatin1Char('>')) {
+ scanChar();
+ if (_char == QLatin1Char('>')) {
+ scanChar();
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_GT_GT_GT_EQ;
}
+ return T_GT_GT_GT;
+ } else if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_GT_GT_EQ;
}
- break;
- case InString:
- if (current == stringType) {
- shift(1);
- setDone(String);
- } else if (isLineTerminator()) {
- multiLineString = true;
- record16(current);
- } else if (current == 0 || isLineTerminator()) {
- setDone(Bad);
- err = UnclosedStringLiteral;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Unclosed string at end of line");
- } else if (current == '\\') {
- state = InEscapeSequence;
- } else {
- record16(current);
+ return T_GT_GT;
+ } else if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_GE;
+ }
+ return T_GT;
+
+ case '=':
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_EQ_EQ_EQ;
}
- break;
- // Escape Sequences inside of strings
- case InEscapeSequence:
- if (isOctalDigit(current)) {
- if (current >= '0' && current <= '3' &&
- isOctalDigit(next1) && isOctalDigit(next2)) {
- record16(convertOctal(current, next1, next2));
- shift(2);
- state = InString;
- } else if (isOctalDigit(current) &&
- isOctalDigit(next1)) {
- record16(convertOctal('0', current, next1));
- shift(1);
- state = InString;
- } else if (isOctalDigit(current)) {
- record16(convertOctal('0', '0', current));
- state = InString;
- } else {
- setDone(Bad);
- err = IllegalEscapeSequence;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal escape sequence");
- }
- } else if (current == 'x')
- state = InHexEscape;
- else if (current == 'u')
- state = InUnicodeEscape;
- else {
- if (isLineTerminator()) {
- shiftWindowsLineBreak();
- yylineno++;
- yycolumn = 0;
- bol = true;
+ return T_EQ_EQ;
+ }
+ return T_EQ;
+
+ case '<':
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_LE;
+ } else if (_char == QLatin1Char('<')) {
+ scanChar();
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_LT_LT_EQ;
+ }
+ return T_LT_LT;
+ }
+ return T_LT;
+
+ case ';': return T_SEMICOLON;
+ case ':': return T_COLON;
+
+ case '/':
+ if (_char == QLatin1Char('*')) {
+ scanChar();
+ while (!_char.isNull()) {
+ if (_char == QLatin1Char('*')) {
+ scanChar();
+ if (_char == QLatin1Char('/')) {
+ scanChar();
+
+ if (_engine) {
+ _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 4,
+ tokenStartLine(), tokenStartColumn() + 2);
+ }
+
+ goto again;
+ }
} else {
- record16(singleEscape(current));
+ scanChar();
}
- state = InString;
- }
- break;
- case InHexEscape:
- if (isHexDigit(current) && isHexDigit(next1)) {
- state = InString;
- record16(QLatin1Char(convertHex(current, next1)));
- shift(1);
- } else if (current == stringType) {
- record16(QLatin1Char('x'));
- shift(1);
- setDone(String);
- } else {
- record16(QLatin1Char('x'));
- record16(current);
- state = InString;
}
- break;
- case InUnicodeEscape:
- if (isHexDigit(current) && isHexDigit(next1) &&
- isHexDigit(next2) && isHexDigit(next3)) {
- record16(convertUnicode(current, next1, next2, next3));
- shift(3);
- state = InString;
- } else if (current == stringType) {
- record16(QLatin1Char('u'));
- shift(1);
- setDone(String);
- } else {
- setDone(Bad);
- err = IllegalUnicodeEscapeSequence;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal unicode escape sequence");
+ } else if (_char == QLatin1Char('/')) {
+ while (!_char.isNull() && _char != QLatin1Char('\n')) {
+ scanChar();
}
- break;
- case InSingleLineComment:
- if (isLineTerminator()) {
- shiftWindowsLineBreak();
- yylineno++;
- yycolumn = 0;
- terminator = true;
- bol = true;
- if (restrKeyword) {
- token = QDeclarativeJSGrammar::T_SEMICOLON;
- setDone(Other);
- } else
- state = Start;
- if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
- } else if (current == 0) {
- if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
- setDone(Eof);
+ if (_engine) {
+ _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 2,
+ tokenStartLine(), tokenStartColumn() + 2);
}
+ goto again;
+ } if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_DIVIDE_EQ;
+ }
+ return T_DIVIDE_;
- break;
- case InMultiLineComment:
- if (current == 0) {
- setDone(Bad);
- err = UnclosedComment;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Unclosed comment at end of file");
- if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
- } else if (isLineTerminator()) {
- shiftWindowsLineBreak();
- yylineno++;
- } else if (current == '*' && next1 == '/') {
- state = Start;
- shift(1);
- if (driver) driver->addComment(startpos+2, tokenLength()-3, startlineno, startcolumn+2);
+ case '.':
+ if (QDeclarativeUtils::isDigit(_char)) {
+ QVarLengthArray<char,32> chars;
+
+ chars.append(ch.unicode()); // append the `.'
+
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
+ scanChar();
}
- break;
- case InIdentifier:
- if (isIdentLetter(current) || isDecimalDigit(current)) {
- record16(current);
- break;
- } else if (current == '\\' && next1 == 'u') {
- identifierWithEscapedUnicode = true;
- shift(2); // skip the unicode escape prefix `\u'
-
- if (isHexDigit(current) && isHexDigit(next1) &&
- isHexDigit(next2) && isHexDigit(next3)) {
- record16(convertUnicode(current, next1, next2, next3));
- shift(3);
- break;
- } else {
- setDone(Bad);
- err = IllegalUnicodeEscapeSequence;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal unicode escape sequence");
- break;
+ if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+ if (QDeclarativeUtils::isDigit(_codePtr[0]) || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+ QDeclarativeUtils::isDigit(_codePtr[1]))) {
+
+ chars.append(_char.unicode());
+ scanChar(); // consume `e'
+
+ if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
+ chars.append(_char.unicode());
+ scanChar(); // consume the sign
+ }
+
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
+ scanChar();
+ }
}
}
- setDone(Identifier);
- break;
- case InNum0:
- if (current == 'x' || current == 'X') {
- record8(current);
- state = InHex;
- } else if (current == '.') {
- record8(current);
- state = InDecimal;
- } else if (current == 'e' || current == 'E') {
- record8(current);
- state = InExponentIndicator;
- } else if (isOctalDigit(current)) {
- record8(current);
- state = InOctal;
- } else if (isDecimalDigit(current)) {
- record8(current);
- state = InDecimal;
- } else {
- setDone(Number);
- }
- break;
- case InHex:
- if (isHexDigit(current))
- record8(current);
- else
- setDone(Hex);
- break;
- case InOctal:
- if (isOctalDigit(current)) {
- record8(current);
- } else if (isDecimalDigit(current)) {
- record8(current);
- state = InDecimal;
- } else {
- setDone(Octal);
+
+ chars.append('\0');
+
+ const char *begin = chars.constData();
+ const char *end = 0;
+ bool ok = false;
+
+ _tokenValue = qstrtod(begin, &end, &ok);
+
+ if (end - begin != chars.size() - 1) {
+ _errorCode = IllegalExponentIndicator;
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Illegal syntax for exponential number");
+ return T_ERROR;
}
- break;
- case InNum:
- if (isDecimalDigit(current)) {
- record8(current);
- } else if (current == '.') {
- record8(current);
- state = InDecimal;
- } else if (current == 'e' || current == 'E') {
- record8(current);
- state = InExponentIndicator;
- } else {
- setDone(Number);
+
+ return T_NUMERIC_LITERAL;
+ }
+ return T_DOT;
+
+ case '-':
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_MINUS_EQ;
+ } else if (_char == QLatin1Char('-')) {
+ scanChar();
+
+ if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) {
+ _stackToken = T_PLUS_PLUS;
+ return T_SEMICOLON;
}
- break;
- case InDecimal:
- if (isDecimalDigit(current)) {
- record8(current);
- } else if (current == 'e' || current == 'E') {
- record8(current);
- state = InExponentIndicator;
- } else {
- setDone(Number);
+
+ return T_MINUS_MINUS;
+ }
+ return T_MINUS;
+
+ case ',': return T_COMMA;
+
+ case '+':
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_PLUS_EQ;
+ } else if (_char == QLatin1Char('+')) {
+ scanChar();
+
+ if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) {
+ _stackToken = T_PLUS_PLUS;
+ return T_SEMICOLON;
}
- break;
- case InExponentIndicator:
- if (current == '+' || current == '-') {
- record8(current);
- } else if (isDecimalDigit(current)) {
- record8(current);
- state = InExponent;
- } else {
- setDone(Bad);
- err = IllegalExponentIndicator;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal syntax for exponential number");
+
+ return T_PLUS_PLUS;
+ }
+ return T_PLUS;
+
+ case '*':
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_STAR_EQ;
+ }
+ return T_STAR;
+
+ case ')': return T_RPAREN;
+ case '(': return T_LPAREN;
+
+ case '&':
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_AND_EQ;
+ } else if (_char == QLatin1Char('&')) {
+ scanChar();
+ return T_AND_AND;
+ }
+ return T_AND;
+
+ case '%':
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_REMAINDER_EQ;
+ }
+ return T_REMAINDER;
+
+ case '!':
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ if (_char == QLatin1Char('=')) {
+ scanChar();
+ return T_NOT_EQ_EQ;
}
- break;
- case InExponent:
- if (isDecimalDigit(current)) {
- record8(current);
- } else {
- setDone(Number);
+ return T_NOT_EQ;
+ }
+ return T_NOT;
+
+ case '\'':
+ case '"': {
+ const QChar quote = ch;
+ _validTokenText = true;
+
+ bool multilineStringLiteral = false;
+
+ const QChar *startCode = _codePtr;
+
+ if (_engine) {
+ while (!_char.isNull()) {
+ if (_char == QLatin1Char('\n') || _char == QLatin1Char('\\')) {
+ break;
+ } else if (_char == quote) {
+ _tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
+ scanChar();
+
+ return T_STRING_LITERAL;
+ }
+ scanChar();
}
- break;
- default:
- Q_ASSERT_X(0, "Lexer::lex", "Unhandled state in switch statement");
}
- // move on to the next character
- if (!done)
- shift(1);
- if (state != Start && state != InSingleLineComment)
- bol = false;
- }
+ _tokenText.resize(0);
+ startCode--;
+ while (startCode != _codePtr - 1)
+ _tokenText += *startCode++;
+
+ while (! _char.isNull()) {
+ if (_char == QLatin1Char('\n')) {
+ multilineStringLiteral = true;
+ _tokenText += _char;
+ scanChar();
+ } else if (_char == quote) {
+ scanChar();
+
+ if (_engine)
+ _tokenSpell = _engine->newStringRef(_tokenText);
+
+ return multilineStringLiteral ? T_MULTILINE_STRING_LITERAL : T_STRING_LITERAL;
+ } else if (_char == QLatin1Char('\\')) {
+ scanChar();
+
+ QChar u;
+ bool ok = false;
+
+ switch (_char.unicode()) {
+ // unicode escape sequence
+ case 'u':
+ u = decodeUnicodeEscapeCharacter(&ok);
+ if (! ok)
+ u = _char;
+ break;
- // no identifiers allowed directly after numeric literal, e.g. "3in" is bad
- if ((state == Number || state == Octal || state == Hex)
- && isIdentLetter(current)) {
- state = Bad;
- err = IllegalIdentifier;
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Identifier cannot start with numeric literal");
- }
+ // hex escape sequence
+ case 'x':
+ case 'X':
+ if (isHexDigit(_codePtr[0]) && isHexDigit(_codePtr[1])) {
+ scanChar();
- // terminate string
- buffer8[pos8] = '\0';
-
- double dval = 0;
- if (state == Number) {
- dval = qstrtod(buffer8, 0, 0);
- } else if (state == Hex) { // scan hex numbers
- dval = integerFromString(buffer8, pos8, 16);
- state = Number;
- } else if (state == Octal) { // scan octal number
- dval = integerFromString(buffer8, pos8, 8);
- state = Number;
- }
+ const QChar c1 = _char;
+ scanChar();
- restrKeyword = false;
- delimited = false;
+ const QChar c2 = _char;
+ scanChar();
- switch (parenthesesState) {
- case IgnoreParentheses:
- break;
- case CountParentheses:
- if (token == QDeclarativeJSGrammar::T_RPAREN) {
- --parenthesesCount;
- if (parenthesesCount == 0)
- parenthesesState = BalancedParentheses;
- } else if (token == QDeclarativeJSGrammar::T_LPAREN) {
- ++parenthesesCount;
+ u = convertHex(c1, c2);
+ } else {
+ u = _char;
+ }
+ break;
+
+ // single character escape sequence
+ case '\\': u = QLatin1Char('\''); scanChar(); break;
+ case '\'': u = QLatin1Char('\''); scanChar(); break;
+ case '\"': u = QLatin1Char('\"'); scanChar(); break;
+ case 'b': u = QLatin1Char('\b'); scanChar(); break;
+ case 'f': u = QLatin1Char('\f'); scanChar(); break;
+ case 'n': u = QLatin1Char('\n'); scanChar(); break;
+ case 'r': u = QLatin1Char('\r'); scanChar(); break;
+ case 't': u = QLatin1Char('\t'); scanChar(); break;
+ case 'v': u = QLatin1Char('\v'); scanChar(); break;
+
+ case '0':
+ if (! _codePtr[1].isDigit()) {
+ scanChar();
+ u = QLatin1Char('\0');
+ } else {
+ // ### parse deprecated octal escape sequence ?
+ u = _char;
+ }
+ break;
+
+ case '\r':
+ while (_char == QLatin1Char('\r'))
+ scanChar();
+
+ if (_char == QLatin1Char('\n')) {
+ u = _char;
+ scanChar();
+ } else {
+ u = QLatin1Char('\n');
+ }
+
+ break;
+
+ case '\n':
+ u = _char;
+ scanChar();
+ break;
+
+ default:
+ // non escape character
+ u = _char;
+ scanChar();
+ }
+
+ _tokenText += u;
+ } else {
+ _tokenText += _char;
+ scanChar();
+ }
}
- break;
- case BalancedParentheses:
- parenthesesState = IgnoreParentheses;
- break;
+
+ _errorCode = UnclosedStringLiteral;
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Unclosed string at end of line");
+ return T_ERROR;
}
- switch (state) {
- case Eof:
- return 0;
- case Other:
- if (token == QDeclarativeJSGrammar::T_RBRACE || token == QDeclarativeJSGrammar::T_SEMICOLON)
- delimited = true;
- return token;
- case Identifier:
- token = -1;
- if (! identifierWithEscapedUnicode)
- token = findReservedWord(buffer16, pos16);
-
- if (token < 0) {
- /* TODO: close leak on parse error. same holds true for String */
- if (driver)
- qsyylval.ustr = driver->intern(buffer16, pos16);
- else
- qsyylval.ustr = 0;
- return QDeclarativeJSGrammar::T_IDENTIFIER;
- }
- if (token == QDeclarativeJSGrammar::T_CONTINUE || token == QDeclarativeJSGrammar::T_BREAK
- || token == QDeclarativeJSGrammar::T_RETURN || token == QDeclarativeJSGrammar::T_THROW) {
- restrKeyword = true;
- } else if (token == QDeclarativeJSGrammar::T_IF || token == QDeclarativeJSGrammar::T_FOR
- || token == QDeclarativeJSGrammar::T_WHILE || token == QDeclarativeJSGrammar::T_WITH) {
- parenthesesState = CountParentheses;
- parenthesesCount = 0;
- } else if (token == QDeclarativeJSGrammar::T_DO) {
- parenthesesState = BalancedParentheses;
- }
- return token;
- case String:
- if (driver)
- qsyylval.ustr = driver->intern(buffer16, pos16);
- else
- qsyylval.ustr = 0;
- return multiLineString?QDeclarativeJSGrammar::T_MULTILINE_STRING_LITERAL:QDeclarativeJSGrammar::T_STRING_LITERAL;
- case Number:
- qsyylval.dval = dval;
- return QDeclarativeJSGrammar::T_NUMERIC_LITERAL;
- case Bad:
- return -1;
default:
- Q_ASSERT(!"unhandled numeration value in switch");
- return -1;
- }
-}
+ if (QDeclarativeUtils::isLetter(ch) || ch == QLatin1Char('$') || ch == QLatin1Char('_') || (ch == QLatin1Char('\\') && _char == QLatin1Char('u'))) {
+ bool identifierWithEscapeChars = false;
+ if (ch == QLatin1Char('\\')) {
+ identifierWithEscapeChars = true;
+ _tokenText.resize(0);
+ bool ok = false;
+ _tokenText += decodeUnicodeEscapeCharacter(&ok);
+ _validTokenText = true;
+ if (! ok) {
+ _errorCode = IllegalUnicodeEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Illegal unicode escape sequence");
+ return T_ERROR;
+ }
+ }
+ while (true) {
+ if (QDeclarativeUtils::isLetterOrNumber(_char) || _char == QLatin1Char('$') || _char == QLatin1Char('_')) {
+ if (identifierWithEscapeChars)
+ _tokenText += _char;
+
+ scanChar();
+ } else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
+ if (! identifierWithEscapeChars) {
+ identifierWithEscapeChars = true;
+ _tokenText.resize(0);
+ _tokenText.insert(0, _tokenStartPtr, _codePtr - _tokenStartPtr - 1);
+ _validTokenText = true;
+ }
-bool Lexer::isWhiteSpace() const
-{
- return (current == ' ' || current == '\t' ||
- current == 0x0b || current == 0x0c);
-}
+ scanChar(); // skip '\\'
+ bool ok = false;
+ _tokenText += decodeUnicodeEscapeCharacter(&ok);
+ if (! ok) {
+ _errorCode = IllegalUnicodeEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Illegal unicode escape sequence");
+ return T_ERROR;
+ }
+ } else {
+ _tokenLength = _codePtr - _tokenStartPtr - 1;
-bool Lexer::isLineTerminator() const
-{
- return (current == '\n' || current == '\r');
-}
+ int kind = T_IDENTIFIER;
-bool Lexer::isIdentLetter(ushort c)
-{
- // ASCII-biased, since all reserved words are ASCII, aand hence the
- // bulk of content to be parsed.
- if ((c >= 'a' && c <= 'z')
- || (c >= 'A' && c <= 'Z')
- || c == '$'
- || c == '_')
- return true;
- if (c < 128)
- return false;
- return QChar(c).isLetterOrNumber();
-}
+ if (! identifierWithEscapeChars)
+ kind = classify(_tokenStartPtr, _tokenLength);
-bool Lexer::isDecimalDigit(ushort c)
-{
- return (c >= '0' && c <= '9');
-}
+ if (_engine) {
+ if (kind == T_IDENTIFIER && identifierWithEscapeChars)
+ _tokenSpell = _engine->newStringRef(_tokenText);
+ else
+ _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
+ }
-bool Lexer::isHexDigit(ushort c) const
-{
- return ((c >= '0' && c <= '9')
- || (c >= 'a' && c <= 'f')
- || (c >= 'A' && c <= 'F'));
-}
+ return kind;
+ }
+ }
+ } else if (QDeclarativeUtils::isDigit(ch)) {
+ if (ch != QLatin1Char('0')) {
+ double integer = ch.unicode() - '0';
+
+ QChar n = _char;
+ const QChar *code = _codePtr;
+ while (QDeclarativeUtils::isDigit(n)) {
+ integer = integer * 10 + (n.unicode() - '0');
+ n = *code++;
+ }
-bool Lexer::isOctalDigit(ushort c) const
-{
- return (c >= '0' && c <= '7');
-}
+ if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) {
+ if (code != _codePtr) {
+ _codePtr = code - 1;
+ scanChar();
+ }
+ _tokenValue = integer;
+ return T_NUMERIC_LITERAL;
+ }
+ }
-int Lexer::matchPunctuator(ushort c1, ushort c2,
- ushort c3, ushort c4)
-{
- if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
- shift(4);
- return QDeclarativeJSGrammar::T_GT_GT_GT_EQ;
- } else if (c1 == '=' && c2 == '=' && c3 == '=') {
- shift(3);
- return QDeclarativeJSGrammar::T_EQ_EQ_EQ;
- } else if (c1 == '!' && c2 == '=' && c3 == '=') {
- shift(3);
- return QDeclarativeJSGrammar::T_NOT_EQ_EQ;
- } else if (c1 == '>' && c2 == '>' && c3 == '>') {
- shift(3);
- return QDeclarativeJSGrammar::T_GT_GT_GT;
- } else if (c1 == '<' && c2 == '<' && c3 == '=') {
- shift(3);
- return QDeclarativeJSGrammar::T_LT_LT_EQ;
- } else if (c1 == '>' && c2 == '>' && c3 == '=') {
- shift(3);
- return QDeclarativeJSGrammar::T_GT_GT_EQ;
- } else if (c1 == '<' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_LE;
- } else if (c1 == '>' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_GE;
- } else if (c1 == '!' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_NOT_EQ;
- } else if (c1 == '+' && c2 == '+') {
- shift(2);
- return QDeclarativeJSGrammar::T_PLUS_PLUS;
- } else if (c1 == '-' && c2 == '-') {
- shift(2);
- return QDeclarativeJSGrammar::T_MINUS_MINUS;
- } else if (c1 == '=' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_EQ_EQ;
- } else if (c1 == '+' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_PLUS_EQ;
- } else if (c1 == '-' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_MINUS_EQ;
- } else if (c1 == '*' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_STAR_EQ;
- } else if (c1 == '/' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_DIVIDE_EQ;
- } else if (c1 == '&' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_AND_EQ;
- } else if (c1 == '^' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_XOR_EQ;
- } else if (c1 == '%' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_REMAINDER_EQ;
- } else if (c1 == '|' && c2 == '=') {
- shift(2);
- return QDeclarativeJSGrammar::T_OR_EQ;
- } else if (c1 == '<' && c2 == '<') {
- shift(2);
- return QDeclarativeJSGrammar::T_LT_LT;
- } else if (c1 == '>' && c2 == '>') {
- shift(2);
- return QDeclarativeJSGrammar::T_GT_GT;
- } else if (c1 == '&' && c2 == '&') {
- shift(2);
- return QDeclarativeJSGrammar::T_AND_AND;
- } else if (c1 == '|' && c2 == '|') {
- shift(2);
- return QDeclarativeJSGrammar::T_OR_OR;
- }
+ QVarLengthArray<char,32> chars;
+ chars.append(ch.unicode());
- switch(c1) {
- case '=': shift(1); return QDeclarativeJSGrammar::T_EQ;
- case '>': shift(1); return QDeclarativeJSGrammar::T_GT;
- case '<': shift(1); return QDeclarativeJSGrammar::T_LT;
- case ',': shift(1); return QDeclarativeJSGrammar::T_COMMA;
- case '!': shift(1); return QDeclarativeJSGrammar::T_NOT;
- case '~': shift(1); return QDeclarativeJSGrammar::T_TILDE;
- case '?': shift(1); return QDeclarativeJSGrammar::T_QUESTION;
- case ':': shift(1); return QDeclarativeJSGrammar::T_COLON;
- case '.': shift(1); return QDeclarativeJSGrammar::T_DOT;
- case '+': shift(1); return QDeclarativeJSGrammar::T_PLUS;
- case '-': shift(1); return QDeclarativeJSGrammar::T_MINUS;
- case '*': shift(1); return QDeclarativeJSGrammar::T_STAR;
- case '/': shift(1); return QDeclarativeJSGrammar::T_DIVIDE_;
- case '&': shift(1); return QDeclarativeJSGrammar::T_AND;
- case '|': shift(1); return QDeclarativeJSGrammar::T_OR;
- case '^': shift(1); return QDeclarativeJSGrammar::T_XOR;
- case '%': shift(1); return QDeclarativeJSGrammar::T_REMAINDER;
- case '(': shift(1); return QDeclarativeJSGrammar::T_LPAREN;
- case ')': shift(1); return QDeclarativeJSGrammar::T_RPAREN;
- case '{': shift(1); return QDeclarativeJSGrammar::T_LBRACE;
- case '}': shift(1); return QDeclarativeJSGrammar::T_RBRACE;
- case '[': shift(1); return QDeclarativeJSGrammar::T_LBRACKET;
- case ']': shift(1); return QDeclarativeJSGrammar::T_RBRACKET;
- case ';': shift(1); return QDeclarativeJSGrammar::T_SEMICOLON;
-
- default: return -1;
- }
-}
+ if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) {
+ // parse hex integer literal
-ushort Lexer::singleEscape(ushort c) const
-{
- switch(c) {
- case 'b':
- return 0x08;
- case 't':
- return 0x09;
- case 'n':
- return 0x0A;
- case 'v':
- return 0x0B;
- case 'f':
- return 0x0C;
- case 'r':
- return 0x0D;
- case '"':
- return 0x22;
- case '\'':
- return 0x27;
- case '\\':
- return 0x5C;
- default:
- return c;
- }
-}
+ chars.append(_char.unicode());
+ scanChar(); // consume `x'
-ushort Lexer::convertOctal(ushort c1, ushort c2,
- ushort c3) const
-{
- return ((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0');
-}
+ while (isHexDigit(_char)) {
+ chars.append(_char.unicode());
+ scanChar();
+ }
-unsigned char Lexer::convertHex(ushort c)
-{
- if (c >= '0' && c <= '9')
- return (c - '0');
- else if (c >= 'a' && c <= 'f')
- return (c - 'a' + 10);
- else
- return (c - 'A' + 10);
-}
+ _tokenValue = integerFromString(chars.constData(), chars.size(), 16);
+ return T_NUMERIC_LITERAL;
+ }
-unsigned char Lexer::convertHex(ushort c1, ushort c2)
-{
- return ((convertHex(c1) << 4) + convertHex(c2));
-}
+ // decimal integer literal
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
+ scanChar(); // consume the digit
+ }
-QChar Lexer::convertUnicode(ushort c1, ushort c2,
- ushort c3, ushort c4)
-{
- return QChar((convertHex(c3) << 4) + convertHex(c4),
- (convertHex(c1) << 4) + convertHex(c2));
-}
+ if (_char == QLatin1Char('.')) {
+ chars.append(_char.unicode());
+ scanChar(); // consume `.'
-void Lexer::record8(ushort c)
-{
- Q_ASSERT(c <= 0xff);
-
- // enlarge buffer if full
- if (pos8 >= size8 - 1) {
- char *tmp = new char[2 * size8];
- memcpy(tmp, buffer8, size8 * sizeof(char));
- delete [] buffer8;
- buffer8 = tmp;
- size8 *= 2;
- }
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
+ scanChar();
+ }
- buffer8[pos8++] = (char) c;
-}
+ if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+ if (QDeclarativeUtils::isDigit(_codePtr[0]) || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+ QDeclarativeUtils::isDigit(_codePtr[1]))) {
-void Lexer::record16(QChar c)
-{
- // enlarge buffer if full
- if (pos16 >= size16 - 1) {
- QChar *tmp = new QChar[2 * size16];
- memcpy(tmp, buffer16, size16 * sizeof(QChar));
- delete [] buffer16;
- buffer16 = tmp;
- size16 *= 2;
- }
+ chars.append(_char.unicode());
+ scanChar(); // consume `e'
- buffer16[pos16++] = c;
-}
+ if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
+ chars.append(_char.unicode());
+ scanChar(); // consume the sign
+ }
-void Lexer::recordStartPos()
-{
- startpos = pos;
- startlineno = yylineno;
- startcolumn = yycolumn;
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
+ scanChar();
+ }
+ }
+ }
+ } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+ if (QDeclarativeUtils::isDigit(_codePtr[0]) || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+ QDeclarativeUtils::isDigit(_codePtr[1]))) {
+
+ chars.append(_char.unicode());
+ scanChar(); // consume `e'
+
+ if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
+ chars.append(_char.unicode());
+ scanChar(); // consume the sign
+ }
+
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
+ scanChar();
+ }
+ }
+ }
+
+ chars.append('\0');
+
+ const char *begin = chars.constData();
+ const char *end = 0;
+ bool ok = false;
+
+ _tokenValue = qstrtod(begin, &end, &ok);
+
+ if (end - begin != chars.size() - 1) {
+ _errorCode = IllegalExponentIndicator;
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Illegal syntax for exponential number");
+ return T_ERROR;
+ }
+
+ return T_NUMERIC_LITERAL;
+ }
+
+ break;
+ }
+
+ return T_ERROR;
}
bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
{
- pos16 = 0;
- pattern = 0;
+ _tokenText.resize(0);
+ _validTokenText = true;
+ _patternFlags = 0;
if (prefix == EqualPrefix)
- record16(QLatin1Char('='));
+ _tokenText += QLatin1Char('=');
while (true) {
- switch (current) {
-
+ switch (_char.unicode()) {
case 0: // eof
case '\n': case '\r': // line terminator
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression literal");
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression literal");
return false;
case '/':
- shift(1);
-
- if (driver) // create the pattern
- pattern = driver->intern(buffer16, pos16);
+ scanChar();
// scan the flags
- pos16 = 0;
- flags = 0;
- while (isIdentLetter(current)) {
- int flag = Ecma::RegExp::flagFromChar(current);
+ _patternFlags = 0;
+ while (isIdentLetter(_char)) {
+ int flag = flagFromChar(_char);
if (flag == 0) {
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Invalid regular expression flag '%0'")
- .arg(QChar(current));
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Invalid regular expression flag '%0'")
+ .arg(QChar(_char));
return false;
}
- flags |= flag;
- record16(current);
- shift(1);
+ _patternFlags |= flag;
+ scanChar();
}
+
+ _tokenLength = _codePtr - _tokenStartPtr - 1;
return true;
case '\\':
// regular expression backslash sequence
- record16(current);
- shift(1);
+ _tokenText += _char;
+ scanChar();
- if (! current || isLineTerminator()) {
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
+ if (_char.isNull() || isLineTerminator()) {
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
return false;
}
- record16(current);
- shift(1);
+ _tokenText += _char;
+ scanChar();
break;
case '[':
// regular expression class
- record16(current);
- shift(1);
+ _tokenText += _char;
+ scanChar();
- while (current && ! isLineTerminator()) {
- if (current == ']')
+ while (! _char.isNull() && ! isLineTerminator()) {
+ if (_char == QLatin1Char(']'))
break;
- else if (current == '\\') {
+ else if (_char == QLatin1Char('\\')) {
// regular expression backslash sequence
- record16(current);
- shift(1);
+ _tokenText += _char;
+ scanChar();
- if (! current || isLineTerminator()) {
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
+ if (_char.isNull() || isLineTerminator()) {
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
return false;
}
- record16(current);
- shift(1);
+ _tokenText += _char;
+ scanChar();
} else {
- record16(current);
- shift(1);
+ _tokenText += _char;
+ scanChar();
}
}
- if (current != ']') {
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression class");
+ if (_char != QLatin1Char(']')) {
+ _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression class");
return false;
}
- record16(current);
- shift(1); // skip ]
+ _tokenText += _char;
+ scanChar(); // skip ]
break;
default:
- record16(current);
- shift(1);
+ _tokenText += _char;
+ scanChar();
} // switch
} // while
return false;
}
+bool Lexer::isLineTerminator() const
+{
+ return (_char == QLatin1Char('\n') || _char == QLatin1Char('\r'));
+}
+
+bool Lexer::isIdentLetter(QChar ch)
+{
+ // ASCII-biased, since all reserved words are ASCII, aand hence the
+ // bulk of content to be parsed.
+ if ((ch >= QLatin1Char('a') && ch <= QLatin1Char('z'))
+ || (ch >= QLatin1Char('A') && ch <= QLatin1Char('Z'))
+ || ch == QLatin1Char('$')
+ || ch == QLatin1Char('_'))
+ return true;
+ if (ch.unicode() < 128)
+ return false;
+ return ch.isLetterOrNumber();
+}
+
+bool Lexer::isDecimalDigit(ushort c)
+{
+ return (c >= '0' && c <= '9');
+}
+
+bool Lexer::isHexDigit(QChar c)
+{
+ return ((c >= QLatin1Char('0') && c <= QLatin1Char('9'))
+ || (c >= QLatin1Char('a') && c <= QLatin1Char('f'))
+ || (c >= QLatin1Char('A') && c <= QLatin1Char('F')));
+}
+
+bool Lexer::isOctalDigit(ushort c)
+{
+ return (c >= '0' && c <= '7');
+}
+
+int Lexer::tokenOffset() const
+{
+ return _tokenStartPtr - _code.unicode();
+}
+
+int Lexer::tokenLength() const
+{
+ return _tokenLength;
+}
+
+int Lexer::tokenStartLine() const
+{
+ return _tokenLine;
+}
+
+int Lexer::tokenStartColumn() const
+{
+ return _tokenStartPtr - _tokenLinePtr + 1;
+}
+
+int Lexer::tokenEndLine() const
+{
+ return _currentLineNumber;
+}
+
+int Lexer::tokenEndColumn() const
+{
+ return _codePtr - _lastLinePtr;
+}
+
+QStringRef Lexer::tokenSpell() const
+{
+ return _tokenSpell;
+}
+
+double Lexer::tokenValue() const
+{
+ return _tokenValue;
+}
+
+QString Lexer::tokenText() const
+{
+ if (_validTokenText)
+ return _tokenText;
+
+ return QString(_tokenStartPtr, _tokenLength);
+}
+
+Lexer::Error Lexer::errorCode() const
+{
+ return _errorCode;
+}
+
+QString Lexer::errorMessage() const
+{
+ return _errorMessage;
+}
+
void Lexer::syncProhibitAutomaticSemicolon()
{
- if (parenthesesState == BalancedParentheses) {
+ if (_parenthesesState == BalancedParentheses) {
// we have seen something like "if (foo)", which means we should
// never insert an automatic semicolon at this point, since it would
// then be expanded into an empty statement (ECMA-262 7.9.1)
- prohibitAutomaticSemicolon = true;
- parenthesesState = IgnoreParentheses;
+ _prohibitAutomaticSemicolon = true;
+ _parenthesesState = IgnoreParentheses;
} else {
- prohibitAutomaticSemicolon = false;
+ _prohibitAutomaticSemicolon = false;
}
}
-QT_QML_END_NAMESPACE
-
+bool Lexer::prevTerminator() const
+{
+ return _terminator;
+}
+#include "qdeclarativejskeywords_p.h"
diff --git a/src/declarative/qml/parser/qdeclarativejslexer_p.h b/src/declarative/qml/parser/qdeclarativejslexer_p.h
index 5147df17e4..1852894b58 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer_p.h
+++ b/src/declarative/qml/parser/qdeclarativejslexer_p.h
@@ -54,7 +54,7 @@
//
#include "qdeclarativejsglobal_p.h"
-
+#include "qdeclarativejsgrammar_p.h"
#include <QtCore/QString>
QT_QML_BEGIN_NAMESPACE
@@ -62,55 +62,41 @@ QT_QML_BEGIN_NAMESPACE
namespace QDeclarativeJS {
class Engine;
-class NameId;
-class QML_PARSER_EXPORT Lexer
+class QML_PARSER_EXPORT Lexer: public QDeclarativeJSGrammar
{
public:
- Lexer(Engine *eng, bool tokenizeComments = false);
- ~Lexer();
-
- void setCode(const QString &c, int lineno);
- int lex();
-
- int currentLineNo() const { return yylineno; }
- int currentColumnNo() const { return yycolumn; }
-
- int tokenOffset() const { return startpos; }
- int tokenLength() const { return pos - startpos; }
-
- int startLineNo() const { return startlineno; }
- int startColumnNo() const { return startcolumn; }
-
- int endLineNo() const { return currentLineNo(); }
- int endColumnNo() const
- { int col = currentColumnNo(); return (col > 0) ? col - 1 : col; }
-
- bool prevTerminator() const { return terminator; }
-
- enum State { Start,
- Identifier,
- InIdentifier,
- InSingleLineComment,
- InMultiLineComment,
- InNum,
- InNum0,
- InHex,
- InOctal,
- InDecimal,
- InExponentIndicator,
- InExponent,
- Hex,
- Octal,
- Number,
- String,
- Eof,
- InString,
- InEscapeSequence,
- InHexEscape,
- InUnicodeEscape,
- Other,
- Bad };
+ enum {
+ T_ABSTRACT = T_RESERVED_WORD,
+ T_BOOLEAN = T_RESERVED_WORD,
+ T_BYTE = T_RESERVED_WORD,
+ T_CHAR = T_RESERVED_WORD,
+ T_CLASS = T_RESERVED_WORD,
+ T_DOUBLE = T_RESERVED_WORD,
+ T_ENUM = T_RESERVED_WORD,
+ T_EXPORT = T_RESERVED_WORD,
+ T_EXTENDS = T_RESERVED_WORD,
+ T_FINAL = T_RESERVED_WORD,
+ T_FLOAT = T_RESERVED_WORD,
+ T_GOTO = T_RESERVED_WORD,
+ T_IMPLEMENTS = T_RESERVED_WORD,
+ T_INT = T_RESERVED_WORD,
+ T_INTERFACE = T_RESERVED_WORD,
+ T_LET = T_RESERVED_WORD,
+ T_LONG = T_RESERVED_WORD,
+ T_NATIVE = T_RESERVED_WORD,
+ T_PACKAGE = T_RESERVED_WORD,
+ T_PRIVATE = T_RESERVED_WORD,
+ T_PROTECTED = T_RESERVED_WORD,
+ T_SHORT = T_RESERVED_WORD,
+ T_STATIC = T_RESERVED_WORD,
+ T_SUPER = T_RESERVED_WORD,
+ T_SYNCHRONIZED = T_RESERVED_WORD,
+ T_THROWS = T_RESERVED_WORD,
+ T_TRANSIENT = T_RESERVED_WORD,
+ T_VOLATILE = T_RESERVED_WORD,
+ T_YIELD = T_RESERVED_WORD
+ };
enum Error {
NoError,
@@ -123,127 +109,102 @@ public:
IllegalIdentifier
};
- enum ParenthesesState {
- IgnoreParentheses,
- CountParentheses,
- BalancedParentheses
- };
-
enum RegExpBodyPrefix {
NoPrefix,
EqualPrefix
};
+public:
+ Lexer(Engine *engine);
+
+ QString code() const;
+ void setCode(const QString &code, int lineno);
+
+ int lex();
+
bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix);
- NameId *pattern;
- int flags;
+ int regExpFlags() const { return _patternFlags; }
+ QString regExpPattern() const { return _tokenText; }
+
+ int tokenOffset() const;
+ int tokenLength() const;
- State lexerState() const
- { return state; }
+ int tokenStartLine() const;
+ int tokenStartColumn() const;
- QString errorMessage() const
- { return errmsg; }
- void setErrorMessage(const QString &err)
- { errmsg = err; }
- void setErrorMessage(const char *err)
- { setErrorMessage(QString::fromLatin1(err)); }
+ int tokenEndLine() const;
+ int tokenEndColumn() const;
- Error error() const
- { return err; }
- void clearError()
- { err = NoError; }
+ QStringRef tokenSpell() const;
+ double tokenValue() const;
+ QString tokenText() const;
+
+ Error errorCode() const;
+ QString errorMessage() const;
+
+ bool prevTerminator() const;
+
+ enum ParenthesesState {
+ IgnoreParentheses,
+ CountParentheses,
+ BalancedParentheses
+ };
private:
- Engine *driver;
- int yylineno;
- bool done;
- char *buffer8;
- QChar *buffer16;
- uint size8, size16;
- uint pos8, pos16;
- bool terminator;
- bool restrKeyword;
- // encountered delimiter like "'" and "}" on last run
- bool delimited;
- int stackToken;
-
- State state;
- void setDone(State s);
- uint pos;
- void shift(uint p);
- int lookupKeyword(const char *);
-
- bool isWhiteSpace() const;
+ inline void scanChar();
+ int scanToken();
+
+ int classify(const QChar *s, int n);
+
bool isLineTerminator() const;
- bool isHexDigit(ushort c) const;
- bool isOctalDigit(ushort c) const;
-
- int matchPunctuator(ushort c1, ushort c2,
- ushort c3, ushort c4);
- ushort singleEscape(ushort c) const;
- ushort convertOctal(ushort c1, ushort c2,
- ushort c3) const;
-public:
- static unsigned char convertHex(ushort c1);
- static unsigned char convertHex(ushort c1, ushort c2);
- static QChar convertUnicode(ushort c1, ushort c2,
- ushort c3, ushort c4);
- static bool isIdentLetter(ushort c);
+ static bool isIdentLetter(QChar c);
static bool isDecimalDigit(ushort c);
+ static bool isHexDigit(QChar c);
+ static bool isOctalDigit(ushort c);
+ static bool isUnicodeEscapeSequence(const QChar *chars);
- inline int ival() const { return qsyylval.ival; }
- inline double dval() const { return qsyylval.dval; }
- inline NameId *ustr() const { return qsyylval.ustr; }
-
- const QChar *characterBuffer() const { return buffer16; }
- int characterCount() const { return pos16; }
+ void syncProhibitAutomaticSemicolon();
+ QChar decodeUnicodeEscapeCharacter(bool *ok);
private:
- void record8(ushort c);
- void record16(QChar c);
- void recordStartPos();
+ Engine *_engine;
- int findReservedWord(const QChar *buffer, int size) const;
+ QString _code;
+ QString _tokenText;
+ QString _errorMessage;
+ QStringRef _tokenSpell;
- void syncProhibitAutomaticSemicolon();
+ const QChar *_codePtr;
+ const QChar *_lastLinePtr;
+ const QChar *_tokenLinePtr;
+ const QChar *_tokenStartPtr;
- const QChar *code;
- uint length;
- int yycolumn;
- int startpos;
- int startlineno;
- int startcolumn;
- int bol; // begin of line
-
- union {
- int ival;
- double dval;
- NameId *ustr;
- } qsyylval;
-
- // current and following unicode characters
- ushort current, next1, next2, next3;
-
- struct keyword {
- const char *name;
- int token;
- };
+ QChar _char;
+ Error _errorCode;
+
+ int _currentLineNumber;
+ double _tokenValue;
+
+ // parentheses state
+ ParenthesesState _parenthesesState;
+ int _parenthesesCount;
- QString errmsg;
- Error err;
+ int _stackToken;
- bool wantRx;
- bool check_reserved;
+ int _patternFlags;
+ int _tokenLength;
+ int _tokenLine;
- ParenthesesState parenthesesState;
- int parenthesesCount;
- bool prohibitAutomaticSemicolon;
- bool tokenizeComments;
+ bool _validTokenText;
+ bool _prohibitAutomaticSemicolon;
+ bool _restrictedKeyword;
+ bool _terminator;
+ bool _delimited;
};
-} // namespace QDeclarativeJS
+} // end of namespace QDeclarativeJS
QT_QML_END_NAMESPACE
-#endif
+#endif // LEXER_H
diff --git a/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h b/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h
index 8d61dbe714..043331d9e8 100644
--- a/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h
@@ -57,8 +57,9 @@
#include <QtCore/qglobal.h>
#include <QtCore/qshareddata.h>
+#include <QtCore/qdebug.h>
-#include <string.h>
+#include <cstring>
QT_QML_BEGIN_NAMESPACE
@@ -66,64 +67,103 @@ namespace QDeclarativeJS {
class QML_PARSER_EXPORT MemoryPool : public QSharedData
{
+ MemoryPool(const MemoryPool &other);
+ void operator =(const MemoryPool &other);
+
public:
- enum { maxBlockCount = -1 };
- enum { defaultBlockSize = 1 << 12 };
-
- MemoryPool() {
- m_blockIndex = maxBlockCount;
- m_currentIndex = 0;
- m_storage = 0;
- m_currentBlock = 0;
- m_currentBlockSize = 0;
+ MemoryPool()
+ : _blocks(0),
+ _allocatedBlocks(0),
+ _blockCount(-1),
+ _ptr(0),
+ _end(0)
+ { }
+
+ ~MemoryPool()
+ {
+ if (_blocks) {
+ for (int i = 0; i < _allocatedBlocks; ++i) {
+ if (char *b = _blocks[i])
+ qFree(b);
+ }
+
+ qFree(_blocks);
+ }
}
- virtual ~MemoryPool() {
- for (int index = 0; index < m_blockIndex + 1; ++index)
- qFree(m_storage[index]);
+ inline void *allocate(size_t size)
+ {
+ size = (size + 7) & ~7;
+ if (_ptr && (_ptr + size < _end)) {
+ void *addr = _ptr;
+ _ptr += size;
+ return addr;
+ }
+ return allocate_helper(size);
+ }
- qFree(m_storage);
+ void reset()
+ {
+ _blockCount = -1;
+ _ptr = _end = 0;
}
- char *allocate(int bytes) {
- bytes += (8 - bytes) & 7; // ensure multiple of 8 bytes (maintain alignment)
- if (m_currentBlock == 0 || m_currentBlockSize < m_currentIndex + bytes) {
- ++m_blockIndex;
- m_currentBlockSize = defaultBlockSize << m_blockIndex;
+private:
+ void *allocate_helper(size_t size)
+ {
+ Q_ASSERT(size < BLOCK_SIZE);
+
+ if (++_blockCount == _allocatedBlocks) {
+ if (! _allocatedBlocks)
+ _allocatedBlocks = DEFAULT_BLOCK_COUNT;
+ else
+ _allocatedBlocks *= 2;
- m_storage = reinterpret_cast<char**>(qRealloc(m_storage, sizeof(char*) * (1 + m_blockIndex)));
- m_currentBlock = m_storage[m_blockIndex] = reinterpret_cast<char*>(qMalloc(m_currentBlockSize));
- ::memset(m_currentBlock, 0, m_currentBlockSize);
+ _blocks = (char **) qRealloc(_blocks, sizeof(char *) * _allocatedBlocks);
- m_currentIndex = (8 - quintptr(m_currentBlock)) & 7; // ensure first chunk is 64-bit aligned
- Q_ASSERT(m_currentIndex + bytes <= m_currentBlockSize);
+ for (int index = _blockCount; index < _allocatedBlocks; ++index)
+ _blocks[index] = 0;
}
- char *p = reinterpret_cast<char *>
- (m_currentBlock + m_currentIndex);
+ char *&block = _blocks[_blockCount];
- m_currentIndex += bytes;
+ if (! block)
+ block = (char *) qMalloc(BLOCK_SIZE);
- return p;
- }
+ _ptr = block;
+ _end = _ptr + BLOCK_SIZE;
- int bytesAllocated() const {
- int bytes = 0;
- for (int index = 0; index < m_blockIndex; ++index)
- bytes += (defaultBlockSize << index);
- bytes += m_currentIndex;
- return bytes;
+ void *addr = _ptr;
+ _ptr += size;
+ return addr;
}
private:
- int m_blockIndex;
- int m_currentIndex;
- char *m_currentBlock;
- int m_currentBlockSize;
- char **m_storage;
+ char **_blocks;
+ int _allocatedBlocks;
+ int _blockCount;
+ char *_ptr;
+ char *_end;
+
+ enum
+ {
+ BLOCK_SIZE = 8 * 1024,
+ DEFAULT_BLOCK_COUNT = 8
+ };
+};
-private:
- Q_DISABLE_COPY(MemoryPool)
+class QML_PARSER_EXPORT Managed
+{
+ Managed(const Managed &other);
+ void operator = (const Managed &other);
+
+public:
+ Managed() {}
+ ~Managed() {}
+
+ void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); }
+ void operator delete(void *) {}
+ void operator delete(void *, MemoryPool *) {}
};
} // namespace QDeclarativeJS
diff --git a/src/declarative/qml/parser/qdeclarativejsnodepool_p.h b/src/declarative/qml/parser/qdeclarativejsnodepool_p.h
deleted file mode 100644
index 401500c57c..0000000000
--- a/src/declarative/qml/parser/qdeclarativejsnodepool_p.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVEJSNODEPOOL_P_H
-#define QDECLARATIVEJSNODEPOOL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qdeclarativejsglobal_p.h"
-#include "qdeclarativejsmemorypool_p.h"
-
-#include <QtCore/QHash>
-#include <QtCore/QString>
-
-QT_QML_BEGIN_NAMESPACE
-
-namespace QDeclarativeJS {
-
-namespace AST {
-class Node;
-} // namespace AST
-
-class Code;
-class CompilationUnit;
-class Engine;
-
-template <typename NodeType>
-inline NodeType *makeAstNode(MemoryPool *storage)
-{
- NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType();
- return node;
-}
-
-template <typename NodeType, typename Arg1>
-inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1)
-{
- NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1);
- return node;
-}
-
-template <typename NodeType, typename Arg1, typename Arg2>
-inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2)
-{
- NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2);
- return node;
-}
-
-template <typename NodeType, typename Arg1, typename Arg2, typename Arg3>
-inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2, Arg3 arg3)
-{
- NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2, arg3);
- return node;
-}
-
-template <typename NodeType, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
-{
- NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2, arg3, arg4);
- return node;
-}
-
-class QML_PARSER_EXPORT NodePool : public MemoryPool
-{
-public:
- NodePool(const QString &fileName, Engine *engine);
- virtual ~NodePool();
-
- Code *createCompiledCode(AST::Node *node, CompilationUnit &compilation);
-
- inline QString fileName() const { return m_fileName; }
- inline Engine *engine() const { return m_engine; }
-#ifndef J_SCRIPT_NO_EVENT_NOTIFY
- inline qint64 id() const { return m_id; }
-#endif
-
-private:
- QHash<AST::Node*, Code*> m_codeCache;
- QString m_fileName;
- Engine *m_engine;
-#ifndef J_SCRIPT_NO_EVENT_NOTIFY
- qint64 m_id;
-#endif
-
-private:
- Q_DISABLE_COPY(NodePool)
-};
-
-} // namespace QDeclarativeJS
-
-QT_QML_END_NAMESPACE
-
-#endif
diff --git a/src/declarative/qml/parser/qdeclarativejsparser.cpp b/src/declarative/qml/parser/qdeclarativejsparser.cpp
index 01132e5362..546cfdd100 100644
--- a/src/declarative/qml/parser/qdeclarativejsparser.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsparser.cpp
@@ -47,7 +47,7 @@
#include "qdeclarativejsengine_p.h"
#include "qdeclarativejslexer_p.h"
#include "qdeclarativejsast_p.h"
-#include "qdeclarativejsnodepool_p.h"
+#include "qdeclarativejsmemorypool_p.h"
@@ -73,6 +73,7 @@ void Parser::reallocateStack()
sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value)));
state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));
location_stack = reinterpret_cast<AST::SourceLocation*> (qRealloc(location_stack, stack_size * sizeof(AST::SourceLocation)));
+ string_stack = reinterpret_cast<QStringRef*> (qRealloc(string_stack, stack_size * sizeof(QStringRef)));
}
inline static bool automatic(Engine *driver, int token)
@@ -85,11 +86,13 @@ inline static bool automatic(Engine *driver, int token)
Parser::Parser(Engine *engine):
driver(engine),
+ pool(engine->pool()),
tos(0),
stack_size(0),
sym_stack(0),
state_stack(0),
location_stack(0),
+ string_stack(0),
first_token(0),
last_token(0)
{
@@ -101,6 +104,7 @@ Parser::~Parser()
qFree(sym_stack);
qFree(state_stack);
qFree(location_stack);
+ qFree(string_stack);
}
}
@@ -109,14 +113,14 @@ static inline AST::SourceLocation location(Lexer *lexer)
AST::SourceLocation loc;
loc.offset = lexer->tokenOffset();
loc.length = lexer->tokenLength();
- loc.startLine = lexer->startLineNo();
- loc.startColumn = lexer->startColumnNo();
+ loc.startLine = lexer->tokenStartLine();
+ loc.startColumn = lexer->tokenStartColumn();
return loc;
}
AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
{
- QVarLengthArray<NameId *, 4> nameIds;
+ QVarLengthArray<QStringRef, 4> nameIds;
QVarLengthArray<AST::SourceLocation, 4> locations;
AST::ExpressionNode *it = expr;
@@ -127,12 +131,12 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
}
if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(it)) {
- AST::UiQualifiedId *q = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), idExpr->name);
+ AST::UiQualifiedId *q = new (pool) AST::UiQualifiedId(idExpr->name);
q->identifierToken = idExpr->identifierToken;
AST::UiQualifiedId *currentId = q;
for (int i = nameIds.size() - 1; i != -1; --i) {
- currentId = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), currentId, nameIds[i]);
+ currentId = new (pool) AST::UiQualifiedId(currentId, nameIds[i]);
currentId->identifierToken = locations[i];
}
@@ -168,11 +172,13 @@ bool Parser::parse(int startToken)
if (first_token == last_token) {
yytoken = lexer->lex();
- yylval = lexer->dval();
+ yylval = lexer->tokenValue();
+ yytokenspell = lexer->tokenSpell();
yylloc = location(lexer);
} else {
yytoken = first_token->token;
yylval = first_token->dval;
+ yytokenspell = first_token->spell;
yylloc = first_token->loc;
++first_token;
}
@@ -183,6 +189,7 @@ bool Parser::parse(int startToken)
if (action != ACCEPT_STATE) {
yytoken = -1;
sym(1).dval = yylval;
+ stringRef(1) = yytokenspell;
loc(1) = yylloc;
} else {
--tos;
@@ -225,7 +232,7 @@ case 5: {
} break;
case 6: {
- sym(1).UiProgram = makeAstNode<AST::UiProgram> (driver->nodePool(), sym(1).UiImportList,
+ sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiImportList,
sym(2).UiObjectMemberList->finish());
} break;
@@ -234,12 +241,11 @@ case 8: {
} break;
case 9: {
- sym(1).Node = makeAstNode<AST::UiImportList> (driver->nodePool(), sym(1).UiImport);
+ sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImport);
} break;
case 10: {
- sym(1).Node = makeAstNode<AST::UiImportList> (driver->nodePool(),
- sym(1).UiImportList, sym(2).UiImport);
+ sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImportList, sym(2).UiImport);
} break;
case 13: {
@@ -255,14 +261,14 @@ case 17: {
sym(1).UiImport->versionToken = loc(2);
sym(1).UiImport->asToken = loc(3);
sym(1).UiImport->importIdToken = loc(4);
- sym(1).UiImport->importId = sym(4).sval;
+ sym(1).UiImport->importId = stringRef(4);
sym(1).UiImport->semicolonToken = loc(5);
} break;
case 19: {
sym(1).UiImport->asToken = loc(2);
sym(1).UiImport->importIdToken = loc(3);
- sym(1).UiImport->importId = sym(3).sval;
+ sym(1).UiImport->importId = stringRef(3);
sym(1).UiImport->semicolonToken = loc(4);
} break;
@@ -270,10 +276,10 @@ case 20: {
AST::UiImport *node = 0;
if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) {
- node = makeAstNode<AST::UiImport>(driver->nodePool(), importIdLiteral->value);
+ node = new (pool) AST::UiImport(importIdLiteral->value);
node->fileNameToken = loc(2);
} else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) {
- node = makeAstNode<AST::UiImport>(driver->nodePool(), qualifiedId);
+ node = new (pool) AST::UiImport(qualifiedId);
node->fileNameToken = loc(2);
}
@@ -294,52 +300,52 @@ case 21: {
} break;
case 22: {
- sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+ sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
} break;
case 23: {
- sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+ sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
} break;
case 24: {
- AST::UiObjectMemberList *node = makeAstNode<AST:: UiObjectMemberList> (driver->nodePool(),
+ AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(
sym(1).UiObjectMemberList, sym(2).UiObjectMember);
sym(1).Node = node;
} break;
case 25: {
- sym(1).Node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+ sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember);
} break;
case 26: {
- AST::UiArrayMemberList *node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(),
+ AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(
sym(1).UiArrayMemberList, sym(3).UiObjectMember);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
case 27: {
- AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), (AST::UiObjectMemberList*)0);
+ AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0);
node->lbraceToken = loc(1);
node->rbraceToken = loc(2);
sym(1).Node = node;
} break;
case 28: {
- AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), sym(2).UiObjectMemberList->finish());
+ AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish());
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
case 29: {
- AST::UiObjectDefinition *node = makeAstNode<AST::UiObjectDefinition> (driver->nodePool(), sym(1).UiQualifiedId,
+ AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId,
sym(2).UiObjectInitializer);
sym(1).Node = node;
} break;
case 31: {
- AST::UiArrayBinding *node = makeAstNode<AST::UiArrayBinding> (driver->nodePool(),
+ AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding(
sym(1).UiQualifiedId, sym(4).UiArrayMemberList->finish());
node->colonToken = loc(2);
node->lbracketToken = loc(3);
@@ -348,14 +354,14 @@ case 31: {
} break;
case 32: {
- AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+ AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
sym(1).UiQualifiedId, sym(3).UiQualifiedId, sym(4).UiObjectInitializer);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
case 33: {
- AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+ AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer);
node->colonToken = loc(2);
node->hasOnToken = true;
@@ -364,19 +370,12 @@ case 33: {
case 38:
{
- AST::UiScriptBinding *node = makeAstNode<AST::UiScriptBinding> (driver->nodePool(),
+ AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(
sym(1).UiQualifiedId, sym(3).Statement);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 39:
-
-case 40: {
- sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
- break;
-}
-
case 42: {
sym(1).Node = 0;
} break;
@@ -386,20 +385,20 @@ case 43: {
} break;
case 44: {
- AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).sval, sym(2).sval);
+ AST::UiParameterList *node = new (pool) AST::UiParameterList(stringRef(1), stringRef(2));
node->identifierToken = loc(2);
sym(1).Node = node;
} break;
case 45: {
- AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).UiParameterList, sym(3).sval, sym(4).sval);
+ AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, stringRef(3), stringRef(4));
node->commaToken = loc(2);
node->identifierToken = loc(4);
sym(1).Node = node;
} break;
case 47: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(QStringRef(), stringRef(2));
node->type = AST::UiPublicMember::Signal;
node->propertyToken = loc(1);
node->typeToken = loc(2);
@@ -410,7 +409,7 @@ case 47: {
} break;
case 49: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(QStringRef(), stringRef(2));
node->type = AST::UiPublicMember::Signal;
node->propertyToken = loc(1);
node->typeToken = loc(2);
@@ -420,8 +419,8 @@ case 49: {
} break;
case 51: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
- node->typeModifier = sym(2).sval;
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(4), stringRef(6));
+ node->typeModifier = stringRef(2);
node->propertyToken = loc(1);
node->typeModifierToken = loc(2);
node->typeToken = loc(4);
@@ -431,7 +430,7 @@ case 51: {
} break;
case 53: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3));
node->propertyToken = loc(1);
node->typeToken = loc(2);
node->identifierToken = loc(3);
@@ -440,7 +439,7 @@ case 53: {
} break;
case 55: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4));
node->isDefaultMember = true;
node->defaultToken = loc(1);
node->propertyToken = loc(2);
@@ -451,7 +450,7 @@ case 55: {
} break;
case 56: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval,
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3),
sym(5).Statement);
node->propertyToken = loc(1);
node->typeToken = loc(2);
@@ -461,7 +460,7 @@ case 56: {
} break;
case 57: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4),
sym(6).Statement);
node->isReadonlyMember = true;
node->readonlyToken = loc(1);
@@ -473,7 +472,7 @@ case 57: {
} break;
case 58: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4),
sym(6).Statement);
node->isDefaultMember = true;
node->defaultToken = loc(1);
@@ -485,19 +484,19 @@ case 58: {
} break;
case 59: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
- node->typeModifier = sym(2).sval;
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(4), stringRef(6));
+ node->typeModifier = stringRef(2);
node->propertyToken = loc(1);
node->typeModifierToken = loc(2);
node->typeToken = loc(4);
node->identifierToken = loc(6);
node->semicolonToken = loc(7); // insert a fake ';' before ':'
- AST::UiQualifiedId *propertyName = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), sym(6).sval);
+ AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6));
propertyName->identifierToken = loc(6);
propertyName->next = 0;
- AST::UiArrayBinding *binding = makeAstNode<AST::UiArrayBinding> (driver->nodePool(),
+ AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(
propertyName, sym(9).UiArrayMemberList->finish());
binding->colonToken = loc(7);
binding->lbracketToken = loc(8);
@@ -509,17 +508,17 @@ case 59: {
} break;
case 60: {
- AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3));
node->propertyToken = loc(1);
node->typeToken = loc(2);
node->identifierToken = loc(3);
node->semicolonToken = loc(4); // insert a fake ';' before ':'
- AST::UiQualifiedId *propertyName = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), sym(3).sval);
+ AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3));
propertyName->identifierToken = loc(3);
propertyName->next = 0;
- AST::UiObjectBinding *binding = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+ AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer);
binding->colonToken = loc(4);
@@ -529,75 +528,51 @@ case 60: {
} break;
case 61: {
- sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
+ sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
} break;
case 62: {
- sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
+ sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
} break;
-case 64: {
- QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_PROPERTY]);
- sym(1).sval = driver->intern(s.constData(), s.length());
- break;
-}
-
-case 65: {
- QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_SIGNAL]);
- sym(1).sval = driver->intern(s.constData(), s.length());
- break;
-}
-
-case 66: {
- QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_READONLY]);
- sym(1).sval = driver->intern(s.constData(), s.length());
- break;
-}
-
-case 67: {
- QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_ON]);
- sym(1).sval = driver->intern(s.constData(), s.length());
- break;
-}
-
case 68: {
- AST::ThisExpression *node = makeAstNode<AST::ThisExpression> (driver->nodePool());
+ AST::ThisExpression *node = new (pool) AST::ThisExpression();
node->thisToken = loc(1);
sym(1).Node = node;
} break;
case 69: {
- AST::IdentifierExpression *node = makeAstNode<AST::IdentifierExpression> (driver->nodePool(), sym(1).sval);
+ AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
case 70: {
- AST::NullExpression *node = makeAstNode<AST::NullExpression> (driver->nodePool());
+ AST::NullExpression *node = new (pool) AST::NullExpression();
node->nullToken = loc(1);
sym(1).Node = node;
} break;
case 71: {
- AST::TrueLiteral *node = makeAstNode<AST::TrueLiteral> (driver->nodePool());
+ AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
node->trueToken = loc(1);
sym(1).Node = node;
} break;
case 72: {
- AST::FalseLiteral *node = makeAstNode<AST::FalseLiteral> (driver->nodePool());
+ AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
node->falseToken = loc(1);
sym(1).Node = node;
} break;
case 73: {
- AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval);
+ AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
node->literalToken = loc(1);
sym(1).Node = node;
} break;
case 74:
case 75: {
- AST::StringLiteral *node = makeAstNode<AST::StringLiteral> (driver->nodePool(), sym(1).sval);
+ AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
node->literalToken = loc(1);
sym(1).Node = node;
} break;
@@ -611,7 +586,8 @@ case 76: {
loc(1).length = lexer->tokenLength();
- AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
+ AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
+ driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
node->literalToken = loc(1);
sym(1).Node = node;
} break;
@@ -625,34 +601,35 @@ case 77: {
loc(1).length = lexer->tokenLength();
- AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
+ AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
+ driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
node->literalToken = loc(1);
sym(1).Node = node;
} break;
case 78: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), (AST::Elision *) 0);
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
node->lbracketToken = loc(1);
node->rbracketToken = loc(2);
sym(1).Node = node;
} break;
case 79: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).Elision->finish());
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
case 80: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish ());
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
case 81: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
(AST::Elision *) 0);
node->lbracketToken = loc(1);
node->commaToken = loc(3);
@@ -661,7 +638,7 @@ case 81: {
} break;
case 82: {
- AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
sym(4).Elision->finish());
node->lbracketToken = loc(1);
node->commaToken = loc(3);
@@ -672,17 +649,17 @@ case 82: {
case 83: {
AST::ObjectLiteral *node = 0;
if (sym(2).Node)
- node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
+ node = new (pool) AST::ObjectLiteral(
sym(2).PropertyNameAndValueList->finish ());
else
- node = makeAstNode<AST::ObjectLiteral> (driver->nodePool());
+ node = new (pool) AST::ObjectLiteral();
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
case 84: {
- AST::ObjectLiteral *node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
+ AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
sym(2).PropertyNameAndValueList->finish ());
node->lbraceToken = loc(1);
node->rbraceToken = loc(4);
@@ -690,7 +667,7 @@ case 84: {
} break;
case 85: {
- AST::NestedExpression *node = makeAstNode<AST::NestedExpression>(driver->nodePool(), sym(2).Expression);
+ AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
node->lparenToken = loc(1);
node->rparenToken = loc(3);
sym(1).Node = node;
@@ -717,48 +694,48 @@ case 86: {
} break;
case 87: {
- sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), (AST::Elision *) 0, sym(1).Expression);
+ sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
} break;
case 88: {
- sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).Elision->finish(), sym(2).Expression);
+ sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
} break;
case 89: {
- AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList,
+ AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
(AST::Elision *) 0, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
case 90: {
- AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList, sym(3).Elision->finish(),
+ AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(),
sym(4).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
case 91: {
- AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool());
+ AST::Elision *node = new (pool) AST::Elision();
node->commaToken = loc(1);
sym(1).Node = node;
} break;
case 92: {
- AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool(), sym(1).Elision);
+ AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
case 93: {
- AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
+ AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
sym(1).PropertyName, sym(3).Expression);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
case 94: {
- AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
+ AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression);
node->commaToken = loc(2);
node->colonToken = loc(4);
@@ -766,116 +743,51 @@ case 94: {
} break;
case 95: {
- AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
+ AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
case 96:
case 97: {
- AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()));
+ AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
case 98: {
- AST::StringLiteralPropertyName *node = makeAstNode<AST::StringLiteralPropertyName> (driver->nodePool(), sym(1).sval);
+ AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
case 99: {
- AST::NumericLiteralPropertyName *node = makeAstNode<AST::NumericLiteralPropertyName> (driver->nodePool(), sym(1).dval);
+ AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
case 100: {
- AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
+ AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 101:
-
-case 102:
-
-case 103:
-
-case 104:
-
-case 105:
-
-case 106:
-
-case 107:
-
-case 108:
-
-case 109:
-
-case 110:
-
-case 111:
-
-case 112:
-
-case 113:
-
-case 114:
-
-case 115:
-
-case 116:
-
-case 117:
-
-case 118:
-
-case 119:
-
-case 120:
-
-case 121:
-
-case 122:
-
-case 123:
-
-case 124:
-
-case 125:
-
-case 126:
-
-case 127:
-
-case 128:
-
-case 129:
-
-case 130:
-
-case 131:
-{
- sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
-} break;
-
case 136: {
- AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+ AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
case 137: {
- AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
+ AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
case 138: {
- AST::NewMemberExpression *node = makeAstNode<AST::NewMemberExpression> (driver->nodePool(), sym(2).Expression, sym(4).ArgumentList);
+ AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
node->newToken = loc(1);
node->lparenToken = loc(3);
node->rparenToken = loc(5);
@@ -883,34 +795,34 @@ case 138: {
} break;
case 140: {
- AST::NewExpression *node = makeAstNode<AST::NewExpression> (driver->nodePool(), sym(2).Expression);
+ AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
node->newToken = loc(1);
sym(1).Node = node;
} break;
case 141: {
- AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
+ AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
case 142: {
- AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
+ AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
case 143: {
- AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+ AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
case 144: {
- AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
+ AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
@@ -925,342 +837,342 @@ case 146: {
} break;
case 147: {
- sym(1).Node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).Expression);
+ sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
} break;
case 148: {
- AST::ArgumentList *node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).ArgumentList, sym(3).Expression);
+ AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
case 152: {
- AST::PostIncrementExpression *node = makeAstNode<AST::PostIncrementExpression> (driver->nodePool(), sym(1).Expression);
+ AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
node->incrementToken = loc(2);
sym(1).Node = node;
} break;
case 153: {
- AST::PostDecrementExpression *node = makeAstNode<AST::PostDecrementExpression> (driver->nodePool(), sym(1).Expression);
+ AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
node->decrementToken = loc(2);
sym(1).Node = node;
} break;
case 155: {
- AST::DeleteExpression *node = makeAstNode<AST::DeleteExpression> (driver->nodePool(), sym(2).Expression);
+ AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
node->deleteToken = loc(1);
sym(1).Node = node;
} break;
case 156: {
- AST::VoidExpression *node = makeAstNode<AST::VoidExpression> (driver->nodePool(), sym(2).Expression);
+ AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
node->voidToken = loc(1);
sym(1).Node = node;
} break;
case 157: {
- AST::TypeOfExpression *node = makeAstNode<AST::TypeOfExpression> (driver->nodePool(), sym(2).Expression);
+ AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
node->typeofToken = loc(1);
sym(1).Node = node;
} break;
case 158: {
- AST::PreIncrementExpression *node = makeAstNode<AST::PreIncrementExpression> (driver->nodePool(), sym(2).Expression);
+ AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
node->incrementToken = loc(1);
sym(1).Node = node;
} break;
case 159: {
- AST::PreDecrementExpression *node = makeAstNode<AST::PreDecrementExpression> (driver->nodePool(), sym(2).Expression);
+ AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
node->decrementToken = loc(1);
sym(1).Node = node;
} break;
case 160: {
- AST::UnaryPlusExpression *node = makeAstNode<AST::UnaryPlusExpression> (driver->nodePool(), sym(2).Expression);
+ AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
node->plusToken = loc(1);
sym(1).Node = node;
} break;
case 161: {
- AST::UnaryMinusExpression *node = makeAstNode<AST::UnaryMinusExpression> (driver->nodePool(), sym(2).Expression);
+ AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
node->minusToken = loc(1);
sym(1).Node = node;
} break;
case 162: {
- AST::TildeExpression *node = makeAstNode<AST::TildeExpression> (driver->nodePool(), sym(2).Expression);
+ AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
node->tildeToken = loc(1);
sym(1).Node = node;
} break;
case 163: {
- AST::NotExpression *node = makeAstNode<AST::NotExpression> (driver->nodePool(), sym(2).Expression);
+ AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
node->notToken = loc(1);
sym(1).Node = node;
} break;
case 165: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mul, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 166: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Div, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 167: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mod, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 169: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Add, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 170: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Sub, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 172: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::LShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 173: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::RShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 174: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::URShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 176: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 177: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 178: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 179: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 180: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 181: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::In, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 183: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 184: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 185: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 186: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 187: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 189: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 190: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 191: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 192: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 194: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 195: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 196: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 197: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 199: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 201: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 203: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 205: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 207: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 209: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 211: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 213: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 215: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 217: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 219: {
- AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
+ AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
node->colonToken = loc(4);
@@ -1268,7 +1180,7 @@ case 219: {
} break;
case 221: {
- AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
+ AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
node->colonToken = loc(4);
@@ -1276,14 +1188,14 @@ case 221: {
} break;
case 223: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
case 225: {
- AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
@@ -1338,7 +1250,7 @@ case 237: {
} break;
case 239: {
- AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+ AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
@@ -1348,7 +1260,7 @@ case 240: {
} break;
case 243: {
- AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+ AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
@@ -1358,18 +1270,18 @@ case 244: {
} break;
case 261: {
- AST::Block *node = makeAstNode<AST::Block> (driver->nodePool(), sym(2).StatementList);
+ AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
case 262: {
- sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).Statement);
+ sym(1).Node = new (pool) AST::StatementList(sym(1).Statement);
} break;
case 263: {
- sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).StatementList, sym(2).Statement);
+ sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement);
} break;
case 264: {
@@ -1381,7 +1293,7 @@ case 265: {
} break;
case 267: {
- AST::VariableStatement *node = makeAstNode<AST::VariableStatement> (driver->nodePool(),
+ AST::VariableStatement *node = new (pool) AST::VariableStatement(
sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
node->declarationKindToken = loc(1);
node->semicolonToken = loc(3);
@@ -1397,32 +1309,32 @@ case 269: {
} break;
case 270: {
- sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
+ sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
case 271: {
- AST::VariableDeclarationList *node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(),
+ AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(
sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
case 272: {
- sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
+ sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
case 273: {
- sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
+ sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
} break;
case 274: {
- AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
+ AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
case 275: {
- AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
+ AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
@@ -1446,28 +1358,28 @@ case 280: {
} break;
case 282: {
- AST::EmptyStatement *node = makeAstNode<AST::EmptyStatement> (driver->nodePool());
+ AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
node->semicolonToken = loc(1);
sym(1).Node = node;
} break;
case 284: {
- AST::ExpressionStatement *node = makeAstNode<AST::ExpressionStatement> (driver->nodePool(), sym(1).Expression);
+ AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
case 285: {
- AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement, sym(7).Statement);
+ AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
- node->elseToken = loc(5);
+ node->elseToken = loc(6);
sym(1).Node = node;
} break;
case 286: {
- AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+ AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
@@ -1475,7 +1387,7 @@ case 286: {
} break;
case 288: {
- AST::DoWhileStatement *node = makeAstNode<AST::DoWhileStatement> (driver->nodePool(), sym(2).Statement, sym(5).Expression);
+ AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
node->doToken = loc(1);
node->whileToken = loc(3);
node->lparenToken = loc(4);
@@ -1485,7 +1397,7 @@ case 288: {
} break;
case 289: {
- AST::WhileStatement *node = makeAstNode<AST::WhileStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+ AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
node->whileToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
@@ -1493,7 +1405,7 @@ case 289: {
} break;
case 290: {
- AST::ForStatement *node = makeAstNode<AST::ForStatement> (driver->nodePool(), sym(3).Expression,
+ AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression,
sym(5).Expression, sym(7).Expression, sym(9).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
@@ -1504,7 +1416,7 @@ case 290: {
} break;
case 291: {
- AST::LocalForStatement *node = makeAstNode<AST::LocalForStatement> (driver->nodePool(),
+ AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression,
sym(8).Expression, sym(10).Statement);
node->forToken = loc(1);
@@ -1517,7 +1429,7 @@ case 291: {
} break;
case 292: {
- AST:: ForEachStatement *node = makeAstNode<AST::ForEachStatement> (driver->nodePool(), sym(3).Expression,
+ AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression,
sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
@@ -1527,7 +1439,7 @@ case 292: {
} break;
case 293: {
- AST::LocalForEachStatement *node = makeAstNode<AST::LocalForEachStatement> (driver->nodePool(),
+ AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(
sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
@@ -1538,14 +1450,14 @@ case 293: {
} break;
case 295: {
- AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool());
+ AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
node->continueToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
case 297: {
- AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool(), sym(2).sval);
+ AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
node->continueToken = loc(1);
node->identifierToken = loc(2);
node->semicolonToken = loc(3);
@@ -1553,14 +1465,14 @@ case 297: {
} break;
case 299: {
- AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool());
+ AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
node->breakToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
case 301: {
- AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool(), sym(2).sval);
+ AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
node->breakToken = loc(1);
node->identifierToken = loc(2);
node->semicolonToken = loc(3);
@@ -1568,14 +1480,14 @@ case 301: {
} break;
case 303: {
- AST::ReturnStatement *node = makeAstNode<AST::ReturnStatement> (driver->nodePool(), sym(2).Expression);
+ AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
node->returnToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
case 304: {
- AST::WithStatement *node = makeAstNode<AST::WithStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+ AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
node->withToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
@@ -1583,7 +1495,7 @@ case 304: {
} break;
case 305: {
- AST::SwitchStatement *node = makeAstNode<AST::SwitchStatement> (driver->nodePool(), sym(3).Expression, sym(5).CaseBlock);
+ AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
node->switchToken = loc(1);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
@@ -1591,25 +1503,25 @@ case 305: {
} break;
case 306: {
- AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses);
+ AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
case 307: {
- AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
+ AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(5);
sym(1).Node = node;
} break;
case 308: {
- sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClause);
+ sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
} break;
case 309: {
- sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClauses, sym(2).CaseClause);
+ sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
} break;
case 310: {
@@ -1621,60 +1533,60 @@ case 311: {
} break;
case 312: {
- AST::CaseClause *node = makeAstNode<AST::CaseClause> (driver->nodePool(), sym(2).Expression, sym(4).StatementList);
+ AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
node->caseToken = loc(1);
node->colonToken = loc(3);
sym(1).Node = node;
} break;
case 313: {
- AST::DefaultClause *node = makeAstNode<AST::DefaultClause> (driver->nodePool(), sym(3).StatementList);
+ AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
node->defaultToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
case 314:
case 315: {
- AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()), sym(3).Statement);
+ AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
node->identifierToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
case 316: {
- AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), sym(1).sval, sym(3).Statement);
+ AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
node->identifierToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
case 318: {
- AST::ThrowStatement *node = makeAstNode<AST::ThrowStatement> (driver->nodePool(), sym(2).Expression);
+ AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
node->throwToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
case 319: {
- AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch);
+ AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
case 320: {
- AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Finally);
+ AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
case 321: {
- AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch, sym(4).Finally);
+ AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
case 322: {
- AST::Catch *node = makeAstNode<AST::Catch> (driver->nodePool(), sym(3).sval, sym(5).Block);
+ AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
node->catchToken = loc(1);
node->lparenToken = loc(2);
node->identifierToken = loc(3);
@@ -1683,20 +1595,20 @@ case 322: {
} break;
case 323: {
- AST::Finally *node = makeAstNode<AST::Finally> (driver->nodePool(), sym(2).Block);
+ AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
node->finallyToken = loc(1);
sym(1).Node = node;
} break;
case 325: {
- AST::DebuggerStatement *node = makeAstNode<AST::DebuggerStatement> (driver->nodePool());
+ AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
node->debuggerToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
case 326: {
- AST::FunctionDeclaration *node = makeAstNode<AST::FunctionDeclaration> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
+ AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
node->identifierToken = loc(2);
node->lparenToken = loc(3);
@@ -1707,9 +1619,9 @@ case 326: {
} break;
case 327: {
- AST::FunctionExpression *node = makeAstNode<AST::FunctionExpression> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
+ AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
- if (sym(2).sval)
+ if (! stringRef(2).isNull())
node->identifierToken = loc(2);
node->lparenToken = loc(3);
node->rparenToken = loc(5);
@@ -1719,13 +1631,13 @@ case 327: {
} break;
case 328: {
- AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).sval);
+ AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
case 329: {
- AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).FormalParameterList, sym(3).sval);
+ AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3));
node->commaToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
@@ -1744,31 +1656,31 @@ case 332: {
} break;
case 334: {
- sym(1).Node = makeAstNode<AST::FunctionBody> (driver->nodePool(), sym(1).SourceElements->finish ());
+ sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ());
} break;
case 335: {
- sym(1).Node = makeAstNode<AST::Program> (driver->nodePool(), sym(1).SourceElements->finish ());
+ sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ());
} break;
case 336: {
- sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElement);
+ sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement);
} break;
case 337: {
- sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElements, sym(2).SourceElement);
+ sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement);
} break;
case 338: {
- sym(1).Node = makeAstNode<AST::StatementSourceElement> (driver->nodePool(), sym(1).Statement);
+ sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement);
} break;
case 339: {
- sym(1).Node = makeAstNode<AST::FunctionSourceElement> (driver->nodePool(), sym(1).FunctionDeclaration);
+ sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration);
} break;
case 340: {
- sym(1).sval = 0;
+ stringRef(1) = QStringRef();
} break;
case 342: {
@@ -1788,6 +1700,7 @@ case 342: {
SavedToken &tk = token_buffer[0];
tk.token = yytoken;
tk.dval = yylval;
+ tk.spell = yytokenspell;
tk.loc = yylloc;
yylloc = yyprevlloc;
@@ -1813,11 +1726,13 @@ case 342: {
token_buffer[0].token = yytoken;
token_buffer[0].dval = yylval;
+ token_buffer[0].spell = yytokenspell;
token_buffer[0].loc = yylloc;
- token_buffer[1].token = yytoken = lexer->lex();
- token_buffer[1].dval = yylval = lexer->dval();
- token_buffer[1].loc = yylloc = location(lexer);
+ token_buffer[1].token = yytoken = lexer->lex();
+ token_buffer[1].dval = yylval = lexer->tokenValue();
+ token_buffer[1].spell = yytokenspell = lexer->tokenSpell();
+ token_buffer[1].loc = yylloc = location(lexer);
if (t_action(errorState, yytoken)) {
QString msg;
diff --git a/src/declarative/qml/parser/qdeclarativejsparser_p.h b/src/declarative/qml/parser/qdeclarativejsparser_p.h
index 0cbd76adfc..d94b3df2ec 100644
--- a/src/declarative/qml/parser/qdeclarativejsparser_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsparser_p.h
@@ -72,7 +72,6 @@ QT_QML_BEGIN_NAMESPACE
namespace QDeclarativeJS {
class Engine;
-class NameId;
class QML_PARSER_EXPORT Parser: protected QDeclarativeJSGrammar
{
@@ -80,7 +79,6 @@ public:
union Value {
int ival;
double dval;
- NameId *sval;
AST::ArgumentList *ArgumentList;
AST::CaseBlock *CaseBlock;
AST::CaseClause *CaseClause;
@@ -196,6 +194,9 @@ protected:
inline Value &sym(int index)
{ return sym_stack [tos + index - 1]; }
+ inline QStringRef &stringRef(int index)
+ { return string_stack [tos + index - 1]; }
+
inline AST::SourceLocation &loc(int index)
{ return location_stack [tos + index - 1]; }
@@ -203,11 +204,13 @@ protected:
protected:
Engine *driver;
+ MemoryPool *pool;
int tos;
int stack_size;
Value *sym_stack;
int *state_stack;
AST::SourceLocation *location_stack;
+ QStringRef *string_stack;
AST::Node *program;
@@ -218,9 +221,11 @@ protected:
int token;
double dval;
AST::SourceLocation loc;
+ QStringRef spell;
};
double yylval;
+ QStringRef yytokenspell;
AST::SourceLocation yylloc;
AST::SourceLocation yyprevlloc;
diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h
index 311ecd31ca..a0eb98d366 100644
--- a/src/declarative/qml/qdeclarative.h
+++ b/src/declarative/qml/qdeclarative.h
@@ -420,33 +420,35 @@ Q_DECLARATIVE_EXPORT void qmlRegisterBaseTypes(const char *uri, int versionMajor
Installing a module API into a uri allows developers to provide arbitrary functionality
(methods and properties) in a namespace that doesn't necessarily contain elements.
- A module API may be either a QObject or a QScriptValue. Only one module API provider
+ A module API may be either a QObject or a QJSValue. Only one module API provider
may be registered into any given namespace (combination of \a uri, \a majorVersion and \a minorVersion).
- This function should be used to register a module API provider function which returns a QScriptValue as a module API.
+ This function should be used to register a module API provider function which returns a QJSValue as a module API.
+
+ \e NOTE: QJSValue module API properties will \e not trigger binding re-evaluation if changed.
Usage:
\code
// first, define the module API provider function (callback).
- static QScriptValue *example_qscriptvalue_module_api_provider(QDeclarativeEngine *engine, QScriptEngine *scriptEngine)
+ static QJSValue *example_qjsvalue_module_api_provider(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
static int seedValue = 5;
- QScriptValue example = scriptEngine->newObject();
+ QJSValue example = scriptEngine->newObject();
example.setProperty("someProperty", seedValue++);
return example;
}
// second, register the module API provider with QML by calling this function in an initialization function.
...
- qmlRegisterModuleApi("Qt.example.qscriptvalueApi", 1, 0, example_qscriptvalue_module_api_provider);
+ qmlRegisterModuleApi("Qt.example.qjsvalueApi", 1, 0, example_qjsvalue_module_api_provider);
...
\endcode
In order to use the registered module API in QML, you must import the module API.
\qml
import QtQuick 2.0
- import Qt.example.qscriptvalueApi 1.0 as ExampleApi
+ import Qt.example.qjsvalueApi 1.0 as ExampleApi
Item {
id: root
property int someValue: ExampleApi.someProperty
@@ -474,7 +476,7 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi
Installing a module API into a uri allows developers to provide arbitrary functionality
(methods and properties) in a namespace that doesn't necessarily contain elements.
- A module API may be either a QObject or a QScriptValue. Only one module API provider
+ A module API may be either a QObject or a QJSValue. Only one module API provider
may be registered into any given namespace (combination of \a uri, \a majorVersion and \a minorVersion).
This function should be used to register a module API provider function which returns a QObject as a module API.
@@ -507,7 +509,7 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi
};
// second, define the module API provider function (callback).
- static QObject *example_qobject_module_api_provider(QDeclarativeEngine *engine, QScriptEngine *scriptEngine)
+ static QObject *example_qobject_module_api_provider(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 069744153a..d817990d7b 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -235,7 +235,7 @@ QDeclarativeBinding::createBinding(Identifier id, QObject *obj, QDeclarativeCont
QDeclarativeContextData *ctxtdata = QDeclarativeContextData::get(ctxt);
- QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(qmlEngine(obj));
+ QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(ctxt->engine());
QDeclarativeCompiledData *cdata = 0;
QDeclarativeTypeData *typeData = 0;
if (engine && ctxtdata && !ctxtdata->url.isEmpty()) {
diff --git a/src/declarative/qml/qdeclarativecompileddata.cpp b/src/declarative/qml/qdeclarativecompileddata.cpp
index da7c3fea7b..c59dd78d53 100644
--- a/src/declarative/qml/qdeclarativecompileddata.cpp
+++ b/src/declarative/qml/qdeclarativecompileddata.cpp
@@ -100,6 +100,7 @@ int QDeclarativeCompiledData::indexForUrl(const QUrl &data)
QDeclarativeCompiledData::QDeclarativeCompiledData(QDeclarativeEngine *engine)
: QDeclarativeCleanup(engine), importCache(0), root(0), rootPropertyCache(0)
{
+ bytecode.reserve(1024);
}
QDeclarativeCompiledData::~QDeclarativeCompiledData()
@@ -202,10 +203,9 @@ int QDeclarativeCompiledData::addInstruction(const QDeclarativeInstruction &inst
{
int ptrOffset = bytecode.size();
int size = instr.size();
- bytecode.resize(bytecode.size() + size);
- char *data = bytecode.data() + ptrOffset;
- qMemCopy(data, &instr, size);
-
+ if (bytecode.capacity() <= bytecode.size() + size)
+ bytecode.reserve(bytecode.size() + size + 512);
+ bytecode.append(reinterpret_cast<const char *>(&instr), size);
return ptrOffset;
}
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index 7cc8422ddd..79094b7e0e 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -41,11 +41,10 @@
#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativeparser_p.h"
-#include "private/qdeclarativescriptparser_p.h"
#include "qdeclarativepropertyvaluesource.h"
#include "qdeclarativecomponent.h"
#include "private/qmetaobjectbuilder_p.h"
+#include "private/qfastmetabuilder_p.h"
#include "private/qdeclarativestringconverters_p.h"
#include "private/qdeclarativeengine_p.h"
#include "qdeclarativeengine.h"
@@ -61,9 +60,9 @@
#include "private/qdeclarativerewrite_p.h"
#include "qdeclarativescriptstring.h"
#include "private/qdeclarativeglobal_p.h"
-#include "private/qdeclarativescriptparser_p.h"
#include "private/qdeclarativebinding_p.h"
#include "private/qdeclarativev4compiler_p.h"
+#include "private/qdeclarativeutils_p.h"
#include <QColor>
#include <QDebug>
@@ -79,14 +78,22 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATS);
-using namespace QDeclarativeParser;
+using namespace QDeclarativeScript;
+using namespace QDeclarativeCompilerTypes;
+
+static QString id_string(QLatin1String("id"));
+static QString on_string(QLatin1String("on"));
+static QString Changed_string(QLatin1String("Changed"));
+static QString Component_string(QLatin1String("Component"));
/*!
Instantiate a new QDeclarativeCompiler.
*/
-QDeclarativeCompiler::QDeclarativeCompiler()
-: output(0), engine(0), unitRoot(0), unit(0)
+QDeclarativeCompiler::QDeclarativeCompiler(QDeclarativePool *pool)
+: pool(pool), output(0), engine(0), unitRoot(0), unit(0), componentStats(0)
{
+ if (compilerStatDump())
+ componentStats = pool->New<ComponentStats>();
}
/*!
@@ -113,9 +120,14 @@ QList<QDeclarativeError> QDeclarativeCompiler::errors() const
Attached property names are those that start with a capital letter.
*/
-bool QDeclarativeCompiler::isAttachedPropertyName(const QByteArray &name)
+bool QDeclarativeCompiler::isAttachedPropertyName(const QString &name)
+{
+ return isAttachedPropertyName(QHashedStringRef(&name));
+}
+
+bool QDeclarativeCompiler::isAttachedPropertyName(const QHashedStringRef &name)
{
- return !name.isEmpty() && name.at(0) >= 'A' && name.at(0) <= 'Z';
+ return !name.isEmpty() && QDeclarativeUtils::isUpper(name.at(0));
}
/*!
@@ -129,15 +141,20 @@ bool QDeclarativeCompiler::isAttachedPropertyName(const QByteArray &name)
character codes in property names, for simplicity and performance reasons
QML only supports letters, numbers and underscores.
*/
-bool QDeclarativeCompiler::isSignalPropertyName(const QByteArray &name)
+bool QDeclarativeCompiler::isSignalPropertyName(const QString &name)
+{
+ return isSignalPropertyName(QStringRef(&name));
+}
+
+bool QDeclarativeCompiler::isSignalPropertyName(const QHashedStringRef &name)
{
if (name.length() < 3) return false;
- if (!name.startsWith("on")) return false;
- int ns = name.size();
+ if (!name.startsWith(on_string)) return false;
+ int ns = name.length();
for (int i = 2; i < ns; ++i) {
- char curr = name.at(i);
- if (curr == '_') continue;
- if (curr >= 'A' && curr <= 'Z') return true;
+ const QChar curr = name.at(i);
+ if (curr.unicode() == '_') continue;
+ if (QDeclarativeUtils::isUpper(curr)) return true;
return false;
}
return false; // consists solely of underscores - invalid.
@@ -155,7 +172,7 @@ bool QDeclarativeCompiler::isSignalPropertyName(const QByteArray &name)
For example:
\code
- COMPILE_EXCEPTION(property, tr("Error for property \"%1\"").arg(QString::fromUtf8(property->name)));
+ COMPILE_EXCEPTION(property, tr("Error for property \"%1\"").arg(property->name));
\endcode
*/
#define COMPILE_EXCEPTION(token, desc) \
@@ -187,27 +204,33 @@ bool QDeclarativeCompiler::isSignalPropertyName(const QByteArray &name)
This test corresponds to action taken by genLiteralAssignment(). Any change
made here, must have a corresponding action in genLiteralAssigment().
*/
-bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
- QDeclarativeParser::Value *v)
+bool QDeclarativeCompiler::testLiteralAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Value *v)
{
- QString string = v->value.asString();
+ const QDeclarativeScript::Variant &value = v->value;
- if (!prop.isWritable())
- COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
+ if (!prop->core.isWritable())
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
- if (prop.isEnumType()) {
- int value;
- if (prop.isFlagType()) {
- value = prop.enumerator().keysToValue(string.toUtf8().constData());
+ if (prop->core.isEnum()) {
+ QMetaProperty p = prop->parent->metaObject()->property(prop->index);
+ int enumValue;
+ if (p.isFlagType()) {
+ enumValue = p.enumerator().keysToValue(value.asString().toUtf8().constData());
} else
- value = prop.enumerator().keyToValue(string.toUtf8().constData());
- if (value == -1)
+ enumValue = p.enumerator().keyToValue(value.asString().toUtf8().constData());
+
+ if (enumValue == -1)
COMPILE_EXCEPTION(v, tr("Invalid property assignment: unknown enumeration"));
+
+ v->value = QDeclarativeScript::Variant((double)enumValue);
return true;
}
- int type = prop.userType();
+
+ int type = prop->type;
+
switch(type) {
- case -1:
+ case QMetaType::QVariant:
break;
case QVariant::String:
if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string expected"));
@@ -249,7 +272,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::Color:
{
bool ok;
- QDeclarativeStringConverters::colorFromString(string, &ok);
+ QDeclarativeStringConverters::colorFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected"));
}
break;
@@ -257,21 +280,21 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::Date:
{
bool ok;
- QDeclarativeStringConverters::dateFromString(string, &ok);
+ QDeclarativeStringConverters::dateFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: date expected"));
}
break;
case QVariant::Time:
{
bool ok;
- QDeclarativeStringConverters::timeFromString(string, &ok);
+ QDeclarativeStringConverters::timeFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: time expected"));
}
break;
case QVariant::DateTime:
{
bool ok;
- QDeclarativeStringConverters::dateTimeFromString(string, &ok);
+ QDeclarativeStringConverters::dateTimeFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected"));
}
break;
@@ -280,7 +303,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::PointF:
{
bool ok;
- QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
+ QPointF point = QDeclarativeStringConverters::pointFFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: point expected"));
}
break;
@@ -288,7 +311,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::SizeF:
{
bool ok;
- QSizeF size = QDeclarativeStringConverters::sizeFFromString(string, &ok);
+ QSizeF size = QDeclarativeStringConverters::sizeFFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: size expected"));
}
break;
@@ -296,7 +319,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::RectF:
{
bool ok;
- QRectF rect = QDeclarativeStringConverters::rectFFromString(string, &ok);
+ QRectF rect = QDeclarativeStringConverters::rectFFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: rect expected"));
}
break;
@@ -308,24 +331,22 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::Vector3D:
{
bool ok;
- QDeclarativeStringConverters::vector3DFromString(string, &ok);
+ QDeclarativeStringConverters::vector3DFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: 3D vector expected"));
}
break;
case QVariant::Vector4D:
{
bool ok;
- QDeclarativeStringConverters::vector4DFromString(string, &ok);
+ QDeclarativeStringConverters::vector4DFromString(value.asString(), &ok);
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: 4D vector expected"));
}
break;
default:
{
- int t = prop.userType();
- QDeclarativeMetaType::StringConverter converter =
- QDeclarativeMetaType::customStringConverter(t);
+ QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type);
if (!converter)
- COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName(prop.type()))));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName((QVariant::Type)type))));
}
break;
}
@@ -338,140 +359,132 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
Any literal assignment that is approved in testLiteralAssignment() must have
a corresponding action in this method.
*/
-void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
- QDeclarativeParser::Value *v)
+void QDeclarativeCompiler::genLiteralAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Value *v)
{
QDeclarativeInstruction instr;
- if (prop.isEnumType()) {
- int value;
- if (v->value.isNumber()) {
- // Preresolved enum
- value = (int)v->value.asNumber();
- } else {
- // Must be a string
- if (prop.isFlagType()) {
- value = prop.enumerator().keysToValue(v->value.asString().toUtf8().constData());
- } else
- value = prop.enumerator().keyToValue(v->value.asString().toUtf8().constData());
- }
+
+ if (prop->core.isEnum()) {
+ Q_ASSERT(v->value.isNumber());
+ // Preresolved value
+ int value = (int)v->value.asNumber();
instr.setType(QDeclarativeInstruction::StoreInteger);
- instr.storeInteger.propertyIndex = prop.propertyIndex();
+ instr.storeInteger.propertyIndex = prop->index;
instr.storeInteger.value = value;
output->addInstruction(instr);
return;
}
- QString string = v->value.asString();
-
- int type = prop.userType();
+ int type = prop->type;
switch(type) {
- case -1:
+ case QMetaType::QVariant:
{
if (v->value.isNumber()) {
double n = v->value.asNumber();
if (double(int(n)) == n) {
instr.setType(QDeclarativeInstruction::StoreVariantInteger);
- instr.storeInteger.propertyIndex = prop.propertyIndex();
+ instr.storeInteger.propertyIndex = prop->index;
instr.storeInteger.value = int(n);
} else {
instr.setType(QDeclarativeInstruction::StoreVariantDouble);
- instr.storeDouble.propertyIndex = prop.propertyIndex();
+ instr.storeDouble.propertyIndex = prop->index;
instr.storeDouble.value = n;
}
} else if(v->value.isBoolean()) {
instr.setType(QDeclarativeInstruction::StoreVariantBool);
- instr.storeBool.propertyIndex = prop.propertyIndex();
+ instr.storeBool.propertyIndex = prop->index;
instr.storeBool.value = v->value.asBoolean();
} else {
instr.setType(QDeclarativeInstruction::StoreVariant);
- instr.storeString.propertyIndex = prop.propertyIndex();
- instr.storeString.value = output->indexForString(string);
+ instr.storeString.propertyIndex = prop->index;
+ instr.storeString.value = output->indexForString(v->value.asString());
}
}
break;
case QVariant::String:
{
instr.setType(QDeclarativeInstruction::StoreString);
- instr.storeString.propertyIndex = prop.propertyIndex();
- instr.storeString.value = output->indexForString(string);
+ instr.storeString.propertyIndex = prop->index;
+ instr.storeString.value = output->indexForString(v->value.asString());
}
break;
case QVariant::ByteArray:
{
instr.setType(QDeclarativeInstruction::StoreByteArray);
- instr.storeByteArray.propertyIndex = prop.propertyIndex();
- instr.storeByteArray.value = output->indexForByteArray(string.toLatin1());
+ instr.storeByteArray.propertyIndex = prop->index;
+ instr.storeByteArray.value = output->indexForByteArray(v->value.asString().toLatin1());
}
break;
case QVariant::Url:
{
instr.setType(QDeclarativeInstruction::StoreUrl);
+ QString string = v->value.asString();
QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string));
- instr.storeUrl.propertyIndex = prop.propertyIndex();
+ instr.storeUrl.propertyIndex = prop->index;
instr.storeUrl.value = output->indexForUrl(u);
}
break;
case QVariant::UInt:
{
instr.setType(QDeclarativeInstruction::StoreInteger);
- instr.storeInteger.propertyIndex = prop.propertyIndex();
+ instr.storeInteger.propertyIndex = prop->index;
instr.storeInteger.value = uint(v->value.asNumber());
}
break;
case QVariant::Int:
{
instr.setType(QDeclarativeInstruction::StoreInteger);
- instr.storeInteger.propertyIndex = prop.propertyIndex();
+ instr.storeInteger.propertyIndex = prop->index;
instr.storeInteger.value = int(v->value.asNumber());
}
break;
case QMetaType::Float:
{
instr.setType(QDeclarativeInstruction::StoreFloat);
- instr.storeFloat.propertyIndex = prop.propertyIndex();
+ instr.storeFloat.propertyIndex = prop->index;
instr.storeFloat.value = float(v->value.asNumber());
}
break;
case QVariant::Double:
{
instr.setType(QDeclarativeInstruction::StoreDouble);
- instr.storeDouble.propertyIndex = prop.propertyIndex();
+ instr.storeDouble.propertyIndex = prop->index;
instr.storeDouble.value = v->value.asNumber();
}
break;
case QVariant::Color:
{
- QColor c = QDeclarativeStringConverters::colorFromString(string);
+ QColor c = QDeclarativeStringConverters::colorFromString(v->value.asString());
instr.setType(QDeclarativeInstruction::StoreColor);
- instr.storeColor.propertyIndex = prop.propertyIndex();
+ instr.storeColor.propertyIndex = prop->index;
instr.storeColor.value = c.rgba();
}
break;
#ifndef QT_NO_DATESTRING
case QVariant::Date:
{
- QDate d = QDeclarativeStringConverters::dateFromString(string);
+ QDate d = QDeclarativeStringConverters::dateFromString(v->value.asString());
instr.setType(QDeclarativeInstruction::StoreDate);
- instr.storeDate.propertyIndex = prop.propertyIndex();
+ instr.storeDate.propertyIndex = prop->index;
instr.storeDate.value = d.toJulianDay();
}
break;
case QVariant::Time:
{
- QTime time = QDeclarativeStringConverters::timeFromString(string);
+ QTime time = QDeclarativeStringConverters::timeFromString(v->value.asString());
instr.setType(QDeclarativeInstruction::StoreTime);
- instr.storeTime.propertyIndex = prop.propertyIndex();
+ instr.storeTime.propertyIndex = prop->index;
Q_ASSERT(sizeof(instr.storeTime.time) == sizeof(QTime));
::memcpy(&instr.storeTime.time, &time, sizeof(QTime));
}
break;
case QVariant::DateTime:
{
- QDateTime dateTime = QDeclarativeStringConverters::dateTimeFromString(string);
+ QDateTime dateTime = QDeclarativeStringConverters::dateTimeFromString(v->value.asString());
QTime time = dateTime.time();
instr.setType(QDeclarativeInstruction::StoreDateTime);
- instr.storeDateTime.propertyIndex = prop.propertyIndex();
+ instr.storeDateTime.propertyIndex = prop->index;
instr.storeDateTime.date = dateTime.date().toJulianDay();
Q_ASSERT(sizeof(instr.storeDateTime.time) == sizeof(QTime));
::memcpy(&instr.storeDateTime.time, &time, sizeof(QTime));
@@ -481,9 +494,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Point:
{
bool ok;
- QPoint point = QDeclarativeStringConverters::pointFFromString(string, &ok).toPoint();
+ QPoint point = QDeclarativeStringConverters::pointFFromString(v->value.asString(), &ok).toPoint();
instr.setType(QDeclarativeInstruction::StorePoint);
- instr.storePoint.propertyIndex = prop.propertyIndex();
+ instr.storePoint.propertyIndex = prop->index;
instr.storePoint.point.xp = point.x();
instr.storePoint.point.yp = point.y();
}
@@ -491,9 +504,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::PointF:
{
bool ok;
- QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
+ QPointF point = QDeclarativeStringConverters::pointFFromString(v->value.asString(), &ok);
instr.setType(QDeclarativeInstruction::StorePointF);
- instr.storePointF.propertyIndex = prop.propertyIndex();
+ instr.storePointF.propertyIndex = prop->index;
instr.storePointF.point.xp = point.x();
instr.storePointF.point.yp = point.y();
}
@@ -501,9 +514,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Size:
{
bool ok;
- QSize size = QDeclarativeStringConverters::sizeFFromString(string, &ok).toSize();
+ QSize size = QDeclarativeStringConverters::sizeFFromString(v->value.asString(), &ok).toSize();
instr.setType(QDeclarativeInstruction::StoreSize);
- instr.storeSize.propertyIndex = prop.propertyIndex();
+ instr.storeSize.propertyIndex = prop->index;
instr.storeSize.size.wd = size.width();
instr.storeSize.size.ht = size.height();
}
@@ -511,9 +524,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::SizeF:
{
bool ok;
- QSizeF size = QDeclarativeStringConverters::sizeFFromString(string, &ok);
+ QSizeF size = QDeclarativeStringConverters::sizeFFromString(v->value.asString(), &ok);
instr.setType(QDeclarativeInstruction::StoreSizeF);
- instr.storeSizeF.propertyIndex = prop.propertyIndex();
+ instr.storeSizeF.propertyIndex = prop->index;
instr.storeSizeF.size.wd = size.width();
instr.storeSizeF.size.ht = size.height();
}
@@ -521,9 +534,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Rect:
{
bool ok;
- QRect rect = QDeclarativeStringConverters::rectFFromString(string, &ok).toRect();
+ QRect rect = QDeclarativeStringConverters::rectFFromString(v->value.asString(), &ok).toRect();
instr.setType(QDeclarativeInstruction::StoreRect);
- instr.storeRect.propertyIndex = prop.propertyIndex();
+ instr.storeRect.propertyIndex = prop->index;
instr.storeRect.rect.x1 = rect.left();
instr.storeRect.rect.y1 = rect.top();
instr.storeRect.rect.x2 = rect.right();
@@ -533,9 +546,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::RectF:
{
bool ok;
- QRectF rect = QDeclarativeStringConverters::rectFFromString(string, &ok);
+ QRectF rect = QDeclarativeStringConverters::rectFFromString(v->value.asString(), &ok);
instr.setType(QDeclarativeInstruction::StoreRectF);
- instr.storeRectF.propertyIndex = prop.propertyIndex();
+ instr.storeRectF.propertyIndex = prop->index;
instr.storeRectF.rect.xp = rect.left();
instr.storeRectF.rect.yp = rect.top();
instr.storeRectF.rect.w = rect.width();
@@ -546,16 +559,16 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
{
bool b = v->value.asBoolean();
instr.setType(QDeclarativeInstruction::StoreBool);
- instr.storeBool.propertyIndex = prop.propertyIndex();
+ instr.storeBool.propertyIndex = prop->index;
instr.storeBool.value = b;
}
break;
case QVariant::Vector3D:
{
bool ok;
- QVector3D vector = QDeclarativeStringConverters::vector3DFromString(string, &ok);
+ QVector3D vector = QDeclarativeStringConverters::vector3DFromString(v->value.asString(), &ok);
instr.setType(QDeclarativeInstruction::StoreVector3D);
- instr.storeVector3D.propertyIndex = prop.propertyIndex();
+ instr.storeVector3D.propertyIndex = prop->index;
instr.storeVector3D.vector.xp = vector.x();
instr.storeVector3D.vector.yp = vector.y();
instr.storeVector3D.vector.zp = vector.z();
@@ -564,9 +577,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Vector4D:
{
bool ok;
- QVector4D vector = QDeclarativeStringConverters::vector4DFromString(string, &ok);
+ QVector4D vector = QDeclarativeStringConverters::vector4DFromString(v->value.asString(), &ok);
instr.setType(QDeclarativeInstruction::StoreVector4D);
- instr.storeVector4D.propertyIndex = prop.propertyIndex();
+ instr.storeVector4D.propertyIndex = prop->index;
instr.storeVector4D.vector.xp = vector.x();
instr.storeVector4D.vector.yp = vector.y();
instr.storeVector4D.vector.zp = vector.z();
@@ -575,11 +588,10 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
break;
default:
{
- int t = prop.userType();
instr.setType(QDeclarativeInstruction::AssignCustomType);
- instr.assignCustomType.propertyIndex = prop.propertyIndex();
- instr.assignCustomType.primitive = output->indexForString(string);
- instr.assignCustomType.type = t;
+ instr.assignCustomType.propertyIndex = prop->index;
+ instr.assignCustomType.primitive = output->indexForString(v->value.asString());
+ instr.assignCustomType.type = type;
}
break;
}
@@ -594,7 +606,7 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data)
data->types.clear();
data->primitives.clear();
data->datas.clear();
- data->bytecode.clear();
+ data->bytecode.resize(0);
}
/*!
@@ -621,13 +633,13 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
// Compile types
const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
- QList<QDeclarativeScriptParser::TypeReference *> referencedTypes = unit->parser().referencedTypes();
+ QList<QDeclarativeScript::TypeReference *> referencedTypes = unit->parser().referencedTypes();
for (int ii = 0; ii < resolvedTypes.count(); ++ii) {
QDeclarativeCompiledData::TypeReference ref;
const QDeclarativeTypeData::TypeReference &tref = resolvedTypes.at(ii);
- QDeclarativeScriptParser::TypeReference *parserRef = referencedTypes.at(ii);
+ QDeclarativeScript::TypeReference *parserRef = referencedTypes.at(ii);
if (tref.type) {
ref.type = tref.type;
@@ -652,11 +664,11 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
} else if (tref.typeData) {
ref.component = tref.typeData->compiledData();
}
- ref.className = parserRef->name.toUtf8();
+ ref.className = parserRef->name;
out->types << ref;
}
- QDeclarativeParser::Object *root = unit->parser().tree();
+ QDeclarativeScript::Object *root = unit->parser().tree();
Q_ASSERT(root);
this->engine = engine;
@@ -668,15 +680,14 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
if (!isError()) {
if (compilerDump())
out->dumpInstructions();
- if (compilerStatDump())
+ if (componentStats)
dumpStats();
Q_ASSERT(out->rootPropertyCache);
} else {
reset(out);
}
- compileState = ComponentCompileState();
- savedCompileStates.clear();
+ compileState = 0;
output = 0;
this->engine = 0;
this->enginePrivate = 0;
@@ -686,10 +697,13 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
return !isError();
}
-void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
+void QDeclarativeCompiler::compileTree(QDeclarativeScript::Object *tree)
{
- compileState.root = tree;
- componentStat.lineNumber = tree->location.start.line;
+ compileState = pool->New<ComponentCompileState>();
+
+ compileState->root = tree;
+ if (componentStats)
+ componentStats->componentStat.lineNumber = tree->location.start.line;
// Build global import scripts
QStringList importedScriptIndexes;
@@ -720,21 +734,21 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
QDeclarativeInstruction init;
init.setType(QDeclarativeInstruction::Init);
- init.init.bindingsSize = compileState.bindings.count();
- init.init.parserStatusSize = compileState.parserStatusCount;
+ init.init.bindingsSize = compileState->bindings.count();
+ init.init.parserStatusSize = compileState->parserStatusCount;
init.init.contextCache = genContextCache();
- if (compileState.compiledBindingData.isEmpty())
+ if (compileState->compiledBindingData.isEmpty())
init.init.compiledBinding = -1;
else
- init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
+ init.init.compiledBinding = output->indexForByteArray(compileState->compiledBindingData);
output->addInstruction(init);
- if (!compileState.v8BindingProgram.isEmpty()) {
+ if (!compileState->v8BindingProgram.isEmpty()) {
QDeclarativeInstruction bindings;
bindings.setType(QDeclarativeInstruction::InitV8Bindings);
- bindings.initV8Bindings.program = output->indexForString(compileState.v8BindingProgram);
- bindings.initV8Bindings.programIndex = compileState.v8BindingProgramIndex;
- bindings.initV8Bindings.line = compileState.v8BindingProgramLine;
+ bindings.initV8Bindings.program = output->indexForString(compileState->v8BindingProgram);
+ bindings.initV8Bindings.programIndex = compileState->v8BindingProgramIndex;
+ bindings.initV8Bindings.line = compileState->v8BindingProgramLine;
output->addInstruction(bindings);
}
@@ -760,25 +774,27 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
enginePrivate->registerCompositeType(output);
}
-static bool ValuePtrLessThan(const QDeclarativeParser::Value *t1, const QDeclarativeParser::Value *t2)
+static bool QStringList_contains(const QStringList &list, const QHashedStringRef &string)
{
- return t1->location.start.line < t2->location.start.line ||
- (t1->location.start.line == t2->location.start.line &&
- t1->location.start.column < t2->location.start.column);
+ for (int ii = 0; ii < list.count(); ++ii)
+ if (string == list.at(ii))
+ return true;
+
+ return false;
}
-bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildObject(QDeclarativeScript::Object *obj, const BindingContext &ctxt)
{
- componentStat.objects++;
+ if (componentStats)
+ componentStats->componentStat.objects++;
Q_ASSERT (obj->type != -1);
const QDeclarativeCompiledData::TypeReference &tr =
output->types.at(obj->type);
obj->metatype = tr.metaObject();
- if (tr.type)
+ if (tr.type)
obj->typeName = tr.type->qmlTypeName();
- obj->className = tr.className;
// This object is a "Component" element
if (tr.type && obj->metatype == &QDeclarativeComponent::staticMetaObject) {
@@ -799,7 +815,7 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
Q_ASSERT(type);
obj->parserStatusCast = type->parserStatusCast();
if (obj->parserStatusCast != -1)
- compileState.parserStatusCount++;
+ compileState->parserStatusCount++;
// Check if this is a custom parser type. Custom parser types allow
// assignments to non-existent properties. These assignments are then
@@ -814,8 +830,8 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
// Must do id property first. This is to ensure that the id given to any
// id reference created matches the order in which the objects are
// instantiated
- foreach(Property *prop, obj->properties) {
- if (prop->name == "id") {
+ for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
+ if (prop->name() == id_string) {
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
break;
}
@@ -825,34 +841,75 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
Property *defaultProperty = 0;
Property *skipProperty = 0;
if (obj->defaultProperty) {
- const QMetaObject *metaObject = obj->metaObject();
- Q_ASSERT(metaObject);
- QMetaProperty p = QDeclarativeMetaType::defaultProperty(metaObject);
- if (p.name()) {
- Property *explicitProperty = obj->getProperty(p.name(), false);
- if (explicitProperty && !explicitProperty->value) {
- skipProperty = explicitProperty;
-
- defaultProperty = new Property;
- defaultProperty->parent = obj;
- defaultProperty->isDefault = true;
- defaultProperty->location = obj->defaultProperty->location;
- defaultProperty->listValueRange = obj->defaultProperty->listValueRange;
-
- defaultProperty->values = obj->defaultProperty->values;
- defaultProperty->values += explicitProperty->values;
- foreach(QDeclarativeParser::Value *value, defaultProperty->values)
- value->addref();
- qSort(defaultProperty->values.begin(), defaultProperty->values.end(), ValuePtrLessThan);
+ defaultProperty = obj->defaultProperty;
+
+ Property *explicitProperty = 0;
+
+ const QMetaObject *mo = obj->metatype;
+ int idx = mo->indexOfClassInfo("DefaultProperty");
+ if (idx != -1) {
+ QMetaClassInfo info = mo->classInfo(idx);
+ const char *p = info.value();
+ if (p) {
+ int plen = 0;
+ char ord = 0;
+ while (char c = p[plen++]) { ord |= c; };
+ --plen;
+
+ if (ord & 0x80) {
+ // Utf8 - unoptimal, but seldom hit
+ QString *s = pool->NewString(QString::fromUtf8(p, plen));
+ QHashedStringRef r(*s);
+
+ if (obj->propertiesHashField.test(r.hash())) {
+ for (Property *ep = obj->properties.first(); ep; ep = obj->properties.next(ep)) {
+ if (ep->name() == r) {
+ explicitProperty = ep;
+ break;
+ }
+ }
+ }
+
+ if (!explicitProperty)
+ defaultProperty->setName(r);
- } else {
- defaultProperty = obj->defaultProperty;
- defaultProperty->addref();
+ } else {
+ QHashedCStringRef r(p, plen);
+
+ if (obj->propertiesHashField.test(r.hash())) {
+ for (Property *ep = obj->properties.first(); ep; ep = obj->properties.next(ep)) {
+ if (ep->name() == r) {
+ explicitProperty = ep;
+ break;
+ }
+ }
+ }
+
+ if (!explicitProperty) {
+ // Set the default property name
+ QChar *buffer = pool->NewRawArray<QChar>(r.length());
+ r.writeUtf16(buffer);
+ defaultProperty->setName(QHashedStringRef(buffer, r.length(), r.hash()));
+ }
+ }
}
- } else {
- defaultProperty = obj->defaultProperty;
- defaultProperty->addref();
}
+
+ if (explicitProperty && !explicitProperty->value && !explicitProperty->values.isEmpty()) {
+
+ skipProperty = explicitProperty; // We merge the values into defaultProperty
+
+ // Find the correct insertion point
+ Value *insertPos = 0;
+
+ for (Value *v = defaultProperty->values.first(); v; v = Property::ValueList::next(v)) {
+ if (!(v->location.start < explicitProperty->values.first()->location.start))
+ break;
+ insertPos = v;
+ }
+
+ defaultProperty->values.insertAfter(insertPos, explicitProperty->values);
+ }
}
QDeclarativeCustomParser *cp = 0;
@@ -860,39 +917,38 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
cp = output->types.at(obj->type).type->customParser();
// Build all explicit properties specified
- foreach(Property *prop, obj->properties) {
+ for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
if (prop == skipProperty)
continue;
- if (prop->name == "id")
+ if (prop->name() == id_string)
continue;
bool canDefer = false;
if (isCustomParser) {
- if (doesPropertyExist(prop, obj) &&
+ if (doesPropertyExist(prop, obj) &&
(!(cp->flags() & QDeclarativeCustomParser::AcceptsAttachedProperties) ||
- !isAttachedPropertyName(prop->name))) {
- int ids = compileState.ids.count();
+ !isAttachedPropertyName(prop->name()))) {
+ int ids = compileState->ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
- canDefer = ids == compileState.ids.count();
- } else if (isSignalPropertyName(prop->name) &&
+ canDefer = ids == compileState->ids.count();
+ } else if (isSignalPropertyName(prop->name()) &&
(cp->flags() & QDeclarativeCustomParser::AcceptsSignalHandlers)) {
COMPILE_CHECK(buildSignal(prop,obj,objCtxt));
} else {
customProps << QDeclarativeCustomParserNodePrivate::fromProperty(prop);
}
} else {
- if (isSignalPropertyName(prop->name)) {
+ if (isSignalPropertyName(prop->name())) {
COMPILE_CHECK(buildSignal(prop,obj,objCtxt));
} else {
- int ids = compileState.ids.count();
+ int ids = compileState->ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
- canDefer = ids == compileState.ids.count();
+ canDefer = ids == compileState->ids.count();
}
}
- if (canDefer && !deferredList.isEmpty() &&
- deferredList.contains(QString::fromUtf8(prop->name)))
+ if (canDefer && !deferredList.isEmpty() && QStringList_contains(deferredList, prop->name()))
prop->isDeferred = true;
}
@@ -904,26 +960,22 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
bool canDefer = false;
if (isCustomParser) {
if (doesPropertyExist(prop, obj)) {
- int ids = compileState.ids.count();
+ int ids = compileState->ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
- canDefer = ids == compileState.ids.count();
+ canDefer = ids == compileState->ids.count();
} else {
customProps << QDeclarativeCustomParserNodePrivate::fromProperty(prop);
}
} else {
- int ids = compileState.ids.count();
+ int ids = compileState->ids.count();
COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
- canDefer = ids == compileState.ids.count();
+ canDefer = ids == compileState->ids.count();
}
- if (canDefer && !deferredList.isEmpty() &&
- deferredList.contains(QString::fromUtf8(prop->name)))
+ if (canDefer && !deferredList.isEmpty() && QStringList_contains(deferredList, prop->name()))
prop->isDeferred = true;
}
- if (defaultProperty)
- defaultProperty->release();
-
// Compile custom parser parts
if (isCustomParser && !customProps.isEmpty()) {
cp->clearErrors();
@@ -941,7 +993,7 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi
return true;
}
-void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genObject(QDeclarativeScript::Object *obj)
{
QDeclarativeCompiledData::TypeReference &tr = output->types[obj->type];
if (tr.type && obj->metatype == &QDeclarativeComponent::staticMetaObject) {
@@ -951,7 +1003,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
// Create the object
if (obj->custom.isEmpty() && output->types.at(obj->type).type &&
- !output->types.at(obj->type).type->isExtendedType() && obj != compileState.root) {
+ !output->types.at(obj->type).type->isExtendedType() && obj != compileState->root) {
QDeclarativeInstruction create;
create.setType(QDeclarativeInstruction::CreateSimpleObject);
@@ -1039,23 +1091,24 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
genObjectBody(obj);
}
-void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genObjectBody(QDeclarativeScript::Object *obj)
{
- typedef QPair<Property *, int> PropPair;
- foreach(const PropPair &prop, obj->scriptStringProperties) {
- const QString &script = prop.first->values.at(0)->value.asScript();
+ for (Property *prop = obj->scriptStringProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
+ Q_ASSERT(prop->scriptStringScope != -1);
+ const QString &script = prop->values.first()->value.asScript();
QDeclarativeInstruction ss;
ss.setType(QDeclarativeInstruction::StoreScriptString);
- ss.storeScriptString.propertyIndex = prop.first->index;
+ ss.storeScriptString.propertyIndex = prop->index;
ss.storeScriptString.value = output->indexForString(script);
- ss.storeScriptString.scope = prop.second;
- ss.storeScriptString.bindingId = rewriteBinding(script, prop.first->name);
- ss.storeScriptString.line = prop.first->location.start.line;
+ ss.storeScriptString.scope = prop->scriptStringScope;
+// ss.storeScriptString.bindingId = rewriteBinding(script, prop->name());
+ ss.storeScriptString.bindingId = rewriteBinding(script, QString()); // XXX
+ ss.storeScriptString.line = prop->location.start.line;
output->addInstruction(ss);
}
bool seenDefer = false;
- foreach(Property *prop, obj->valueProperties) {
+ for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (prop->isDeferred) {
seenDefer = true;
continue;
@@ -1072,13 +1125,13 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
QDeclarativeInstruction init;
init.setType(QDeclarativeInstruction::Init);
- init.init.bindingsSize = compileState.bindings.count(); // XXX - bigger than necessary
- init.init.parserStatusSize = compileState.parserStatusCount; // XXX - bigger than necessary
+ init.init.bindingsSize = compileState->bindings.count(); // XXX - bigger than necessary
+ init.init.parserStatusSize = compileState->parserStatusCount; // XXX - bigger than necessary
init.init.contextCache = -1;
init.init.compiledBinding = -1;
output->addInstruction(init);
- foreach(Property *prop, obj->valueProperties) {
+ for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (!prop->isDeferred)
continue;
genValueProperty(prop, obj);
@@ -1091,9 +1144,9 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
output->instruction(deferIdx)->defer.deferCount = output->nextInstructionIndex() - nextInstructionIndex;
}
- foreach(Property *prop, obj->signalProperties) {
+ for (Property *prop = obj->signalProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
- QDeclarativeParser::Value *v = prop->values.at(0);
+ QDeclarativeScript::Value *v = prop->values.first();
if (v->type == Value::SignalObject) {
@@ -1102,21 +1155,18 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
QDeclarativeInstruction assign;
assign.setType(QDeclarativeInstruction::AssignSignalObject);
assign.assignSignalObject.line = v->location.start.line;
- assign.assignSignalObject.signal =
- output->indexForByteArray(prop->name);
+ assign.assignSignalObject.signal = output->indexForString(prop->name().toString());
output->addInstruction(assign);
} else if (v->type == Value::SignalExpression) {
- BindingContext ctxt = compileState.signalExpressions.value(v);
-
QDeclarativeInstruction store;
store.setType(QDeclarativeInstruction::StoreSignal);
store.storeSignal.signalIndex = prop->index;
store.storeSignal.value =
output->indexForString(v->value.asScript().trimmed());
- store.storeSignal.context = ctxt.stack;
- store.storeSignal.name = output->indexForByteArray(prop->name);
+ store.storeSignal.context = v->signalExpressionContextStack;
+ store.storeSignal.name = output->indexForByteArray(prop->name().toUtf8());
store.storeSignal.line = v->location.start.line;
output->addInstruction(store);
@@ -1124,7 +1174,7 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
}
- foreach(Property *prop, obj->attachedProperties) {
+ for (Property *prop = obj->attachedProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
QDeclarativeInstruction fetch;
fetch.setType(QDeclarativeInstruction::FetchAttached);
fetch.fetchAttached.id = prop->index;
@@ -1138,7 +1188,7 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
output->addInstruction(pop);
}
- foreach(Property *prop, obj->groupedProperties) {
+ for (Property *prop = obj->groupedProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
QDeclarativeInstruction fetch;
fetch.setType(QDeclarativeInstruction::FetchObject);
fetch.fetch.property = prop->index;
@@ -1161,25 +1211,25 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
output->addInstruction(pop);
}
- foreach(Property *prop, obj->valueTypeProperties) {
+ for (Property *prop = obj->valueTypeProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (!prop->isAlias)
genValueTypeProperty(obj, prop);
}
- foreach(Property *prop, obj->valueProperties) {
+ for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (prop->isDeferred)
continue;
if (prop->isAlias)
genValueProperty(prop, obj);
}
- foreach(Property *prop, obj->valueTypeProperties) {
+ for (Property *prop = obj->valueTypeProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (prop->isAlias)
genValueTypeProperty(obj, prop);
}
}
-void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *prop)
+void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeScript::Object *obj,QDeclarativeScript::Property *prop)
{
QDeclarativeInstruction fetch;
fetch.setType(QDeclarativeInstruction::FetchValueType);
@@ -1190,7 +1240,7 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,
if (obj->type == -1 || output->types.at(obj->type).component) {
// We only have to do this if this is a composite type. If it is a builtin
// type it can't possibly already have bindings that need to be cleared.
- foreach(Property *vprop, prop->value->valueProperties) {
+ for (Property *vprop = prop->value->valueProperties.first(); vprop; vprop = Object::PropertyList::next(vprop)) {
if (!vprop->values.isEmpty()) {
Q_ASSERT(vprop->index >= 0 && vprop->index < 32);
fetch.fetchValue.bindingSkipList |= (1 << vprop->index);
@@ -1200,7 +1250,7 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,
output->addInstruction(fetch);
- foreach(Property *vprop, prop->value->valueProperties) {
+ for (Property *vprop = prop->value->valueProperties.first(); vprop; vprop = Object::PropertyList::next(vprop)) {
genPropertyAssignment(vprop, prop->value, prop);
}
@@ -1212,9 +1262,9 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,
output->addInstruction(pop);
}
-void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genComponent(QDeclarativeScript::Object *obj)
{
- QDeclarativeParser::Object *root = obj->defaultProperty->values.at(0)->object;
+ QDeclarativeScript::Object *root = obj->defaultProperty->values.first()->object;
Q_ASSERT(root);
QDeclarativeInstruction create;
@@ -1225,26 +1275,26 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
int createInstruction = output->addInstruction(create);
int nextInstructionIndex = output->nextInstructionIndex();
- ComponentCompileState oldCompileState = compileState;
+ ComponentCompileState *oldCompileState = compileState;
compileState = componentState(root);
QDeclarativeInstruction init;
init.setType(QDeclarativeInstruction::Init);
- init.init.bindingsSize = compileState.bindings.count();
- init.init.parserStatusSize = compileState.parserStatusCount;
+ init.init.bindingsSize = compileState->bindings.count();
+ init.init.parserStatusSize = compileState->parserStatusCount;
init.init.contextCache = genContextCache();
- if (compileState.compiledBindingData.isEmpty())
+ if (compileState->compiledBindingData.isEmpty())
init.init.compiledBinding = -1;
else
- init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
+ init.init.compiledBinding = output->indexForByteArray(compileState->compiledBindingData);
output->addInstruction(init);
- if (!compileState.v8BindingProgram.isEmpty()) {
+ if (!compileState->v8BindingProgram.isEmpty()) {
QDeclarativeInstruction bindings;
bindings.setType(QDeclarativeInstruction::InitV8Bindings);
- bindings.initV8Bindings.program = output->indexForString(compileState.v8BindingProgram);
- bindings.initV8Bindings.programIndex = compileState.v8BindingProgramIndex;
- bindings.initV8Bindings.line = compileState.v8BindingProgramLine;
+ bindings.initV8Bindings.program = output->indexForString(compileState->v8BindingProgram);
+ bindings.initV8Bindings.programIndex = compileState->v8BindingProgramIndex;
+ bindings.initV8Bindings.line = compileState->v8BindingProgramLine;
output->addInstruction(bindings);
}
@@ -1277,7 +1327,7 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
}
}
-bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildComponent(QDeclarativeScript::Object *obj,
const BindingContext &ctxt)
{
// The special "Component" element can only have the id property and a
@@ -1285,21 +1335,21 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
// Find, check and set the "id" property (if any)
Property *idProp = 0;
- if (obj->properties.count() > 1 ||
- (obj->properties.count() == 1 && obj->properties.begin().key() != "id"))
- COMPILE_EXCEPTION(*obj->properties.begin(), tr("Component elements may not contain properties other than id"));
+ if (obj->properties.isMany() ||
+ (obj->properties.isOne() && obj->properties.first()->name() != id_string))
+ COMPILE_EXCEPTION(obj->properties.first(), tr("Component elements may not contain properties other than id"));
- if (obj->properties.count())
- idProp = *obj->properties.begin();
+ if (!obj->properties.isEmpty())
+ idProp = obj->properties.first();
if (idProp) {
- if (idProp->value || idProp->values.count() > 1 || idProp->values.at(0)->object)
+ if (idProp->value || idProp->values.isMany() || idProp->values.first()->object)
COMPILE_EXCEPTION(idProp, tr("Invalid component id specification"));
COMPILE_CHECK(checkValidId(idProp->values.first(), idProp->values.first()->primitive()))
QString idVal = idProp->values.first()->primitive();
- if (compileState.ids.contains(idVal))
+ if (compileState->ids.value(idVal))
COMPILE_EXCEPTION(idProp, tr("id is not unique"));
obj->id = idVal;
@@ -1308,8 +1358,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
// Check the Component tree is well formed
if (obj->defaultProperty &&
- (obj->defaultProperty->value || obj->defaultProperty->values.count() > 1 ||
- (obj->defaultProperty->values.count() == 1 && !obj->defaultProperty->values.first()->object)))
+ (obj->defaultProperty->value || obj->defaultProperty->values.isMany() ||
+ (obj->defaultProperty->values.isOne() && !obj->defaultProperty->values.first()->object)))
COMPILE_EXCEPTION(obj, tr("Invalid component body specification"));
if (!obj->dynamicProperties.isEmpty())
@@ -1319,8 +1369,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
if (!obj->dynamicSlots.isEmpty())
COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new functions."));
- QDeclarativeParser::Object *root = 0;
- if (obj->defaultProperty && obj->defaultProperty->values.count())
+ QDeclarativeScript::Object *root = 0;
+ if (obj->defaultProperty && !obj->defaultProperty->values.isEmpty())
root = obj->defaultProperty->values.first()->object;
if (!root)
@@ -1332,26 +1382,34 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj,
return true;
}
-bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeScript::Object *obj,
const BindingContext &ctxt)
{
- ComponentCompileState oldComponentCompileState = compileState;
- ComponentStat oldComponentStat = componentStat;
+ ComponentCompileState *oldComponentCompileState = compileState;
+ compileState = pool->New<ComponentCompileState>();
+ compileState->root = obj;
+ compileState->nested = true;
+
+ if (componentStats) {
+ ComponentStat oldComponentStat = componentStats->componentStat;
- compileState = ComponentCompileState();
- compileState.root = obj;
- compileState.nested = true;
+ componentStats->componentStat = ComponentStat();
+ componentStats->componentStat.lineNumber = obj->location.start.line;
- componentStat = ComponentStat();
- componentStat.lineNumber = obj->location.start.line;
+ if (obj)
+ COMPILE_CHECK(buildObject(obj, ctxt));
- if (obj)
- COMPILE_CHECK(buildObject(obj, ctxt));
+ COMPILE_CHECK(completeComponentBuild());
- COMPILE_CHECK(completeComponentBuild());
+ componentStats->componentStat = oldComponentStat;
+ } else {
+ if (obj)
+ COMPILE_CHECK(buildObject(obj, ctxt));
+
+ COMPILE_CHECK(completeComponentBuild());
+ }
compileState = oldComponentCompileState;
- componentStat = oldComponentStat;
return true;
}
@@ -1360,15 +1418,15 @@ bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeParser::Object *ob
// Build a sub-object. A sub-object is one that was not created directly by
// QML - such as a grouped property object, or an attached object. Sub-object's
// can't have an id, involve a custom parser, have attached properties etc.
-bool QDeclarativeCompiler::buildSubObject(QDeclarativeParser::Object *obj, const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildSubObject(QDeclarativeScript::Object *obj, const BindingContext &ctxt)
{
Q_ASSERT(obj->metatype);
Q_ASSERT(!obj->defaultProperty);
Q_ASSERT(ctxt.isSubContext()); // sub-objects must always be in a binding
// sub-context
- foreach(Property *prop, obj->properties) {
- if (isSignalPropertyName(prop->name)) {
+ for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
+ if (isSignalPropertyName(prop->name())) {
COMPILE_CHECK(buildSignal(prop, obj, ctxt));
} else {
COMPILE_CHECK(buildProperty(prop, obj, ctxt));
@@ -1380,49 +1438,51 @@ bool QDeclarativeCompiler::buildSubObject(QDeclarativeParser::Object *obj, const
int QDeclarativeCompiler::componentTypeRef()
{
- QDeclarativeType *t = QDeclarativeMetaType::qmlType("QtQuick/Component",2,0);
+ QDeclarativeType *t = QDeclarativeMetaType::qmlType(QLatin1String("QtQuick/Component"),2,0);
for (int ii = output->types.count() - 1; ii >= 0; --ii) {
if (output->types.at(ii).type == t)
return ii;
}
QDeclarativeCompiledData::TypeReference ref;
- ref.className = "Component";
+ ref.className = Component_string;
ref.type = t;
output->types << ref;
return output->types.count() - 1;
}
-bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildSignal(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj,
const BindingContext &ctxt)
{
Q_ASSERT(obj->metaObject());
- QByteArray name = prop->name;
- Q_ASSERT(name.startsWith("on"));
- name = name.mid(2);
+ const QHashedStringRef &propName = prop->name();
+
+ Q_ASSERT(propName.startsWith(on_string));
+ QString name = propName.mid(2, -1).toString();
// Note that the property name could start with any alpha or '_' or '$' character,
// so we need to do the lower-casing of the first alpha character.
for (int firstAlphaIndex = 0; firstAlphaIndex < name.size(); ++firstAlphaIndex) {
- if (name[firstAlphaIndex] >= 'A' && name[firstAlphaIndex] <= 'Z') {
- name[firstAlphaIndex] = name[firstAlphaIndex] - 'A' + 'a';
+ if (QDeclarativeUtils::isUpper(name.at(firstAlphaIndex))) {
+ name[firstAlphaIndex] = name.at(firstAlphaIndex).toLower();
break;
}
}
bool notInRevision = false;
- int sigIdx = indexOfSignal(obj, name, &notInRevision);
- if (sigIdx == -1) {
+ QDeclarativePropertyCache::Data *sig = signal(obj, QStringRef(&name), &notInRevision);
+
+ if (sig == 0) {
- if (notInRevision && -1 == indexOfProperty(obj, prop->name, 0)) {
+ if (notInRevision && 0 == property(obj, propName, 0)) {
Q_ASSERT(obj->type != -1);
const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type);
if (type.type) {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name().toString()).arg(type.type->module()).arg(type.majorVersion).arg(type.minorVersion));
} else {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name().toString()));
}
}
@@ -1432,26 +1492,28 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
} else {
- if (prop->value || prop->values.count() != 1)
+ if (prop->value || !prop->values.isOne())
COMPILE_EXCEPTION(prop, tr("Incorrectly specified signal assignment"));
- prop->index = sigIdx;
+ prop->index = sig->coreIndex;
+ prop->core = *sig;
+
obj->addSignalProperty(prop);
- if (prop->values.at(0)->object) {
- COMPILE_CHECK(buildObject(prop->values.at(0)->object, ctxt));
- prop->values.at(0)->type = Value::SignalObject;
+ if (prop->values.first()->object) {
+ COMPILE_CHECK(buildObject(prop->values.first()->object, ctxt));
+ prop->values.first()->type = Value::SignalObject;
} else {
- prop->values.at(0)->type = Value::SignalExpression;
+ prop->values.first()->type = Value::SignalExpression;
- if (!prop->values.at(0)->value.isScript())
+ if (!prop->values.first()->value.isScript())
COMPILE_EXCEPTION(prop, tr("Cannot assign a value to a signal (expecting a script to be run)"));
- QString script = prop->values.at(0)->value.asScript().trimmed();
+ QString script = prop->values.first()->value.asScript().trimmed();
if (script.isEmpty())
COMPILE_EXCEPTION(prop, tr("Empty signal assignment"));
- compileState.signalExpressions.insert(prop->values.at(0), ctxt);
+ prop->values.first()->signalExpressionContextStack = ctxt.stack;
}
}
@@ -1462,37 +1524,28 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
/*!
Returns true if (value) property \a prop exists on obj, false otherwise.
*/
-bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj)
+bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj)
{
- if(isAttachedPropertyName(prop->name) || prop->name == "id")
+ if (prop->name().isEmpty())
+ return false;
+ if(isAttachedPropertyName(prop->name()) || prop->name() == id_string)
return true;
- const QMetaObject *mo = obj->metaObject();
- if (mo) {
- if (prop->isDefault) {
- QMetaProperty p = QDeclarativeMetaType::defaultProperty(mo);
- return p.name() != 0;
- } else {
- int idx = indexOfProperty(obj, prop->name);
- return idx != -1 && mo->property(idx).isScriptable();
- }
- }
-
- return false;
+ return property(obj, prop->name()) != 0;
}
-bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ const BindingContext &ctxt)
{
- if (prop->isEmpty())
+ if (prop->isEmpty())
COMPILE_EXCEPTION(prop, tr("Empty property assignment"));
const QMetaObject *metaObject = obj->metaObject();
Q_ASSERT(metaObject);
- if (isAttachedPropertyName(prop->name)) {
+ if (isAttachedPropertyName(prop->name())) {
// Setup attached property data
if (ctxt.isSubContext()) {
@@ -1504,7 +1557,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
QDeclarativeType *type = 0;
QDeclarativeImportedNamespace *typeNamespace = 0;
- unit->imports().resolveType(prop->name, &type, 0, 0, 0, &typeNamespace);
+ unit->imports().resolveType(prop->name().toString(), &type, 0, 0, 0, &typeNamespace);
if (typeNamespace) {
COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj,
@@ -1522,44 +1575,35 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
prop->value->metatype = type->attachedPropertiesType();
} else {
// Setup regular property data
- QMetaProperty p;
-
- if (prop->isDefault) {
- p = QDeclarativeMetaType::defaultProperty(metaObject);
+ bool notInRevision = false;
+ QDeclarativePropertyCache::Data *d =
+ prop->name().isEmpty()?0:property(obj, prop->name(), &notInRevision);
- if (p.name()) {
- prop->index = p.propertyIndex();
- prop->name = p.name();
- }
-
- } else {
- bool notInRevision = false;
- prop->index = indexOfProperty(obj, prop->name, &notInRevision);
- if (prop->index == -1 && notInRevision) {
- const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
- const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type);
- if (type.type) {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
- } else {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)));
- }
- }
-
- if (prop->index != -1) {
- p = metaObject->property(prop->index);
- Q_ASSERT(p.name());
-
- if (!p.isScriptable()) {
- prop->index = -1;
- p = QMetaProperty();
- }
+ if (d == 0 && notInRevision) {
+ const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
+ const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type);
+ if (type.type) {
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name().toString()).arg(type.type->module()).arg(type.majorVersion).arg(type.minorVersion));
+ } else {
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name().toString()));
}
+ } else if (d) {
+ prop->index = d->coreIndex;
+ prop->core = *d;
+ } else if (prop->isDefault) {
+ QMetaProperty p = QDeclarativeMetaType::defaultProperty(metaObject);
+ QDeclarativePropertyCache::Data defaultPropertyData;
+ defaultPropertyData.load(p, engine);
+ if (p.name())
+ prop->setName(p.name());
+ prop->core = defaultPropertyData;
+ prop->index = prop->core.coreIndex;
}
// We can't error here as the "id" property does not require a
// successful index resolution
- if (p.name())
- prop->type = p.userType();
+ if (prop->index != -1)
+ prop->type = prop->core.propType;
// Check if this is an alias
if (prop->index != -1 &&
@@ -1576,17 +1620,17 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
prop->parent->setBindingBit(prop->index);
}
- if (!prop->isDefault && prop->name == "id" && !ctxt.isSubContext()) {
+ if (!prop->isDefault && prop->name() == id_string && !ctxt.isSubContext()) {
// The magic "id" behavior doesn't apply when "id" is resolved as a
// default property or to sub-objects (which are always in binding
// sub-contexts)
COMPILE_CHECK(buildIdProperty(prop, obj));
if (prop->type == QVariant::String &&
- prop->values.at(0)->value.isString())
+ prop->values.first()->value.isString())
COMPILE_CHECK(buildPropertyAssignment(prop, obj, ctxt));
- } else if (isAttachedPropertyName(prop->name)) {
+ } else if (isAttachedPropertyName(prop->name())) {
COMPILE_CHECK(buildAttachedProperty(prop, obj, ctxt));
@@ -1595,14 +1639,14 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
if (prop->isDefault) {
COMPILE_EXCEPTION(prop->values.first(), tr("Cannot assign to non-existent default property"));
} else {
- COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name().toString()));
}
} else if (prop->value) {
COMPILE_CHECK(buildGroupedProperty(prop, obj, ctxt));
- } else if (enginePrivate->isList(prop->type)) {
+ } else if (prop->core.isQList()) {
COMPILE_CHECK(buildListProperty(prop, obj, ctxt));
@@ -1620,22 +1664,22 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
}
bool QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeImportedNamespace *ns,
- QDeclarativeParser::Property *nsProp,
- QDeclarativeParser::Object *obj,
+ QDeclarativeScript::Property *nsProp,
+ QDeclarativeScript::Object *obj,
const BindingContext &ctxt)
{
if (!nsProp->value)
COMPILE_EXCEPTION(nsProp, tr("Invalid use of namespace"));
- foreach (Property *prop, nsProp->value->properties) {
+ for (Property *prop = nsProp->value->properties.first(); prop; prop = nsProp->value->properties.next(prop)) {
- if (!isAttachedPropertyName(prop->name))
+ if (!isAttachedPropertyName(prop->name()))
COMPILE_EXCEPTION(prop, tr("Not an attached property name"));
// Setup attached property data
QDeclarativeType *type = 0;
- unit->imports().resolveType(ns, prop->name, &type, 0, 0, 0);
+ unit->imports().resolveType(ns, prop->name().toString(), &type, 0, 0, 0);
if (!type || !type->attachedPropertiesType())
COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
@@ -1653,18 +1697,18 @@ bool QDeclarativeCompiler::buildPropertyInNamespace(QDeclarativeImportedNamespac
return true;
}
-void QDeclarativeCompiler::genValueProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genValueProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj)
{
- if (enginePrivate->isList(prop->type)) {
+ if (prop->core.isQList()) {
genListProperty(prop, obj);
} else {
genPropertyAssignment(prop, obj);
}
}
-void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::genListProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj)
{
int listType = enginePrivate->listType(prop->type);
@@ -1675,8 +1719,7 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop,
fetch.fetchQmlList.type = listType;
output->addInstruction(fetch);
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->values.at(ii);
+ for (Value *v = prop->values.first(); v; v = Property::ValueList::next(v)) {
if (v->type == Value::CreatedObject) {
@@ -1705,12 +1748,11 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop,
output->addInstruction(pop);
}
-void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Property *valueTypeProperty)
+void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Property *valueTypeProperty)
{
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->values.at(ii);
+ for (Value *v = prop->values.first(); v; v = Property::ValueList::next(v)) {
Q_ASSERT(v->type == Value::CreatedObject ||
v->type == Value::PropertyBinding ||
@@ -1728,7 +1770,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
store.storeObject.propertyIndex = prop->index;
output->addInstruction(store);
- } else if (prop->type == -1) {
+ } else if (prop->type == QMetaType::QVariant) {
QDeclarativeInstruction store;
store.setType(QDeclarativeInstruction::StoreVariantObject);
@@ -1751,16 +1793,13 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
} else if (v->type == Value::Literal) {
- QMetaProperty mp = obj->metaObject()->property(prop->index);
- genLiteralAssignment(mp, v);
+ genLiteralAssignment(prop, v);
}
}
- for (int ii = 0; ii < prop->onValues.count(); ++ii) {
-
- QDeclarativeParser::Value *v = prop->onValues.at(ii);
+ for (Value *v = prop->onValues.first(); v; v = Property::ValueList::next(v)) {
Q_ASSERT(v->type == Value::ValueSource ||
v->type == Value::ValueInterceptor);
@@ -1801,23 +1840,23 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
}
}
-bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj)
+bool QDeclarativeCompiler::buildIdProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj)
{
if (prop->value ||
- prop->values.count() > 1 ||
- prop->values.at(0)->object)
+ prop->values.isMany() ||
+ prop->values.first()->object)
COMPILE_EXCEPTION(prop, tr("Invalid use of id property"));
- QDeclarativeParser::Value *idValue = prop->values.at(0);
+ QDeclarativeScript::Value *idValue = prop->values.first();
QString val = idValue->primitive();
COMPILE_CHECK(checkValidId(idValue, val));
- if (compileState.ids.contains(val))
+ if (compileState->ids.value(val))
COMPILE_EXCEPTION(prop, tr("id is not unique"));
- prop->values.at(0)->type = Value::Id;
+ prop->values.first()->type = Value::Id;
obj->id = val;
addId(val, obj);
@@ -1825,35 +1864,37 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop,
return true;
}
-void QDeclarativeCompiler::addId(const QString &id, QDeclarativeParser::Object *obj)
+void QDeclarativeCompiler::addId(const QString &id, QDeclarativeScript::Object *obj)
{
- Q_ASSERT(!compileState.ids.contains(id));
+ Q_ASSERT(!compileState->ids.value(id));
Q_ASSERT(obj->id == id);
- obj->idIndex = compileState.ids.count();
- compileState.ids.insert(id, obj);
- compileState.idIndexes.insert(obj->idIndex, obj);
+ obj->idIndex = compileState->ids.count();
+ compileState->ids.append(obj);
}
-void QDeclarativeCompiler::addBindingReference(const BindingReference &ref)
+void QDeclarativeCompiler::addBindingReference(BindingReference *ref)
{
- Q_ASSERT(ref.value && !compileState.bindings.contains(ref.value));
- compileState.bindings.insert(ref.value, ref);
+ Q_ASSERT(ref->value && !ref->value->bindingReference);
+ ref->value->bindingReference = ref;
+ compileState->bindings.prepend(ref);
}
void QDeclarativeCompiler::saveComponentState()
{
- Q_ASSERT(compileState.root);
- Q_ASSERT(!savedCompileStates.contains(compileState.root));
+ Q_ASSERT(compileState->root);
+ Q_ASSERT(compileState->root->componentCompileState == 0);
+
+ compileState->root->componentCompileState = compileState;
- savedCompileStates.insert(compileState.root, compileState);
- savedComponentStats.append(componentStat);
+ if (componentStats)
+ componentStats->savedComponentStats.append(componentStats->componentStat);
}
-QDeclarativeCompiler::ComponentCompileState
-QDeclarativeCompiler::componentState(QDeclarativeParser::Object *obj)
+QDeclarativeCompilerTypes::ComponentCompileState *
+QDeclarativeCompiler::componentState(QDeclarativeScript::Object *obj)
{
- Q_ASSERT(savedCompileStates.contains(obj));
- return savedCompileStates.value(obj);
+ Q_ASSERT(obj->componentCompileState);
+ return obj->componentCompileState;
}
// Build attached property object. In this example,
@@ -1861,8 +1902,8 @@ QDeclarativeCompiler::componentState(QDeclarativeParser::Object *obj)
// GridView.row: 10
// }
// GridView is an attached property object.
-bool QDeclarativeCompiler::buildAttachedProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildAttachedProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
const BindingContext &ctxt)
{
Q_ASSERT(prop->value);
@@ -1882,32 +1923,33 @@ bool QDeclarativeCompiler::buildAttachedProperty(QDeclarativeParser::Property *p
// font.family: "Helvetica"
// }
// font is a nested property. pointSize and family are not.
-bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
const BindingContext &ctxt)
{
Q_ASSERT(prop->type != 0);
Q_ASSERT(prop->index != -1);
if (QDeclarativeValueTypeFactory::isValueType(prop->type)) {
- if (prop->type >= 0 /* QVariant == -1 */ && enginePrivate->valueTypes[prop->type]) {
+ if (prop->type >= 0 && enginePrivate->valueTypes[prop->type]) {
- if (prop->values.count()) {
- if (prop->values.at(0)->location < prop->value->location) {
+ if (!prop->values.isEmpty()) {
+ if (prop->values.first()->location < prop->value->location) {
COMPILE_EXCEPTION(prop->value, tr( "Property has already been assigned a value"));
} else {
- COMPILE_EXCEPTION(prop->values.at(0), tr( "Property has already been assigned a value"));
+ COMPILE_EXCEPTION(prop->values.first(), tr( "Property has already been assigned a value"));
}
}
if (!obj->metaObject()->property(prop->index).isWritable()) {
- COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
}
if (prop->isAlias) {
- foreach (Property *vtProp, prop->value->properties)
+ for (Property *vtProp = prop->value->properties.first(); vtProp; vtProp = prop->value->properties.next(vtProp)) {
vtProp->isAlias = true;
+ }
}
COMPILE_CHECK(buildValueTypeProperty(enginePrivate->valueTypes[prop->type],
@@ -1923,8 +1965,8 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr
if (!prop->value->metatype)
COMPILE_EXCEPTION(prop, tr("Invalid grouped property access"));
- if (prop->values.count())
- COMPILE_EXCEPTION(prop->values.at(0), tr( "Cannot assign a value directly to a grouped property"));
+ if (!prop->values.isEmpty())
+ COMPILE_EXCEPTION(prop->values.first(), tr( "Cannot assign a value directly to a grouped property"));
obj->addGroupedProperty(prop);
@@ -1935,32 +1977,32 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr
}
bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Object *baseObj,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Object *baseObj,
const BindingContext &ctxt)
{
if (obj->defaultProperty)
COMPILE_EXCEPTION(obj, tr("Invalid property use"));
obj->metatype = type->metaObject();
- foreach (Property *prop, obj->properties) {
- int idx = type->metaObject()->indexOfProperty(prop->name.constData());
- if (idx == -1)
- COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
- QMetaProperty p = type->metaObject()->property(idx);
- if (!p.isScriptable())
- COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
- prop->index = idx;
- prop->type = p.userType();
+ for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) {
+
+ QDeclarativePropertyCache::Data *d = property(obj, prop->name());
+ if (d == 0)
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name().toString()));
+
+ prop->index = d->coreIndex;
+ prop->type = d->propType;
+ prop->core = *d;
prop->isValueTypeSubProperty = true;
if (prop->value)
COMPILE_EXCEPTION(prop, tr("Property assignment expected"));
- if (prop->values.count() > 1) {
+ if (prop->values.isMany()) {
COMPILE_EXCEPTION(prop, tr("Single property assignment expected"));
- } else if (prop->values.count()) {
- QDeclarativeParser::Value *value = prop->values.at(0);
+ } else if (!prop->values.isEmpty()) {
+ QDeclarativeScript::Value *value = prop->values.first();
if (value->object) {
COMPILE_EXCEPTION(prop, tr("Unexpected object assignment"));
@@ -1969,27 +2011,30 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
//optimization for <Type>.<EnumValue> enum assignments
bool isEnumAssignment = false;
- COMPILE_CHECK(testQualifiedEnumAssignment(p, obj, value, &isEnumAssignment));
+
+ if (prop->core.isEnum())
+ COMPILE_CHECK(testQualifiedEnumAssignment(obj->metatype->property(prop->index), obj,
+ value, &isEnumAssignment));
+
if (isEnumAssignment) {
value->type = Value::Literal;
} else {
- BindingReference reference;
- reference.expression = value->value;
- reference.property = prop;
- reference.value = value;
- reference.bindingContext = ctxt;
- reference.bindingContext.owner++;
+ BindingReference *reference = pool->New<BindingReference>();
+ reference->expression = value->value;
+ reference->property = prop;
+ reference->value = value;
+ reference->bindingContext = ctxt;
+ reference->bindingContext.owner++;
addBindingReference(reference);
value->type = Value::PropertyBinding;
}
} else {
- COMPILE_CHECK(testLiteralAssignment(p, value));
+ COMPILE_CHECK(testLiteralAssignment(prop, value));
value->type = Value::Literal;
}
}
- for (int ii = 0; ii < prop->onValues.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->onValues.at(ii);
+ for (Value *v = prop->onValues.first(); v; v = Property::ValueList::next(v)) {
Q_ASSERT(v->object);
COMPILE_CHECK(buildPropertyOnAssignment(prop, obj, baseObj, v, ctxt));
@@ -2004,11 +2049,11 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
// Build assignments to QML lists. QML lists are properties of type
// QDeclarativeListProperty<T>. List properties can accept a list of
// objects, or a single binding.
-bool QDeclarativeCompiler::buildListProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildListProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
const BindingContext &ctxt)
{
- Q_ASSERT(enginePrivate->isList(prop->type));
+ Q_ASSERT(prop->core.isQList());
int t = prop->type;
@@ -2018,8 +2063,7 @@ bool QDeclarativeCompiler::buildListProperty(QDeclarativeParser::Property *prop,
bool listTypeIsInterface = QDeclarativeMetaType::isInterface(listType);
bool assignedBinding = false;
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->values.at(ii);
+ for (Value *v = prop->values.first(); v; v = Property::ValueList::next(v)) {
if (v->object) {
v->type = Value::CreatedObject;
COMPILE_CHECK(buildObject(v->object, ctxt));
@@ -2048,33 +2092,33 @@ bool QDeclarativeCompiler::buildListProperty(QDeclarativeParser::Property *prop,
}
// Compiles an assignment to a QDeclarativeScriptString property
-bool QDeclarativeCompiler::buildScriptStringProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildScriptStringProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
const BindingContext &ctxt)
{
- if (prop->values.count() > 1)
- COMPILE_EXCEPTION(prop->values.at(1), tr( "Cannot assign multiple values to a script property"));
+ if (prop->values.isMany())
+ COMPILE_EXCEPTION(prop->values.first()->nextValue, tr( "Cannot assign multiple values to a script property"));
- if (prop->values.at(0)->object)
- COMPILE_EXCEPTION(prop->values.at(0), tr( "Invalid property assignment: script expected"));
+ if (prop->values.first()->object)
+ COMPILE_EXCEPTION(prop->values.first(), tr( "Invalid property assignment: script expected"));
- obj->addScriptStringProperty(prop, ctxt.stack);
+ prop->scriptStringScope = ctxt.stack;
+ obj->addScriptStringProperty(prop);
return true;
}
// Compile regular property assignments of the form "property: <value>"
-bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
+bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
const BindingContext &ctxt)
{
obj->addValueProperty(prop);
- if (prop->values.count() > 1)
- COMPILE_EXCEPTION(prop->values.at(0), tr( "Cannot assign multiple values to a singular property") );
+ if (prop->values.isMany())
+ COMPILE_EXCEPTION(prop->values.first(), tr( "Cannot assign multiple values to a singular property") );
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->values.at(ii);
+ for (Value *v = prop->values.first(); v; v = Property::ValueList::next(v)) {
if (v->object) {
COMPILE_CHECK(buildPropertyObjectAssignment(prop, obj, v, ctxt));
@@ -2086,9 +2130,7 @@ bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeParser::Property
}
}
- for (int ii = 0; ii < prop->onValues.count(); ++ii) {
- QDeclarativeParser::Value *v = prop->onValues.at(ii);
-
+ for (Value *v = prop->onValues.first(); v; v = Property::ValueList::next(v)) {
Q_ASSERT(v->object);
COMPILE_CHECK(buildPropertyOnAssignment(prop, obj, obj, v, ctxt));
}
@@ -2097,16 +2139,16 @@ bool QDeclarativeCompiler::buildPropertyAssignment(QDeclarativeParser::Property
}
// Compile assigning a single object instance to a regular property
-bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Value *v,
+bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Value *v,
const BindingContext &ctxt)
{
Q_ASSERT(prop->index != -1);
Q_ASSERT(v->object->type != -1);
if (!obj->metaObject()->property(prop->index).isWritable())
- COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
if (QDeclarativeMetaType::isInterface(prop->type)) {
@@ -2115,7 +2157,7 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
v->type = Value::CreatedObject;
- } else if (prop->type == -1) {
+ } else if (prop->type == QMetaType::QVariant) {
// Assigning an object to a QVariant
COMPILE_CHECK(buildObject(v->object, ctxt));
@@ -2152,13 +2194,13 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
v->type = Value::CreatedObject;
} else if (propertyMetaObject == &QDeclarativeComponent::staticMetaObject) {
// Automatic "Component" insertion
- QDeclarativeParser::Object *root = v->object;
- QDeclarativeParser::Object *component = new QDeclarativeParser::Object;
+ QDeclarativeScript::Object *root = v->object;
+ QDeclarativeScript::Object *component = pool->New<Object>();
component->type = componentTypeRef();
component->typeName = "Qt/Component";
component->metatype = &QDeclarativeComponent::staticMetaObject;
component->location = root->location;
- QDeclarativeParser::Value *componentValue = new QDeclarativeParser::Value;
+ QDeclarativeScript::Value *componentValue = pool->New<Value>();
componentValue->object = root;
component->getDefaultProperty()->addValue(componentValue);
v->object = component;
@@ -2177,17 +2219,17 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro
// Item {
// NumberAnimation on x { }
// }
-bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Object *baseObj,
- QDeclarativeParser::Value *v,
+bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Object *baseObj,
+ QDeclarativeScript::Value *v,
const BindingContext &ctxt)
{
Q_ASSERT(prop->index != -1);
Q_ASSERT(v->object->type != -1);
if (!obj->metaObject()->property(prop->index).isWritable())
- COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
+ COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
// Normally buildObject() will set this up, but we need the static
@@ -2214,28 +2256,31 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert
buildDynamicMeta(baseObj, ForceCreation);
v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor;
} else {
- COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(QString::fromUtf8(prop->name.constData())));
+ COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(prop->name().toString()));
}
return true;
}
// Compile assigning a literal or binding to a regular property
-bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Value *v,
- const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Value *v,
+ const BindingContext &ctxt)
{
Q_ASSERT(prop->index != -1);
if (v->value.isScript()) {
//optimization for <Type>.<EnumValue> enum assignments
- bool isEnumAssignment = false;
- COMPILE_CHECK(testQualifiedEnumAssignment(obj->metaObject()->property(prop->index), obj, v, &isEnumAssignment));
- if (isEnumAssignment) {
- v->type = Value::Literal;
- return true;
+ if (prop->core.isEnum()) {
+ bool isEnumAssignment = false;
+ COMPILE_CHECK(testQualifiedEnumAssignment(obj->metaObject()->property(prop->index), obj,
+ v, &isEnumAssignment));
+ if (isEnumAssignment) {
+ v->type = Value::Literal;
+ return true;
+ }
}
COMPILE_CHECK(buildBinding(v, prop, ctxt));
@@ -2244,7 +2289,7 @@ bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeParser::Pr
} else {
- COMPILE_CHECK(testLiteralAssignment(obj->metaObject()->property(prop->index), v));
+ COMPILE_CHECK(testLiteralAssignment(prop, v));
v->type = Value::Literal;
}
@@ -2253,9 +2298,9 @@ bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeParser::Pr
}
bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Value *v,
- bool *isAssignment)
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Value *v,
+ bool *isAssignment)
{
*isAssignment = false;
if (!prop.isEnumType())
@@ -2265,7 +2310,7 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
QString string = v->value.asString();
- if (!string.at(0).isUpper())
+ if (!QDeclarativeUtils::isUpper(string.at(0)))
return true;
QStringList parts = string.split(QLatin1Char('.'));
@@ -2274,7 +2319,7 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
QString typeName = parts.at(0);
QDeclarativeType *type = 0;
- unit->imports().resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
+ unit->imports().resolveType(typeName, &type, 0, 0, 0, 0);
//handle enums on value types (where obj->typeName is empty)
QByteArray objTypeName = obj->typeName;
@@ -2312,7 +2357,7 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
return true;
v->type = Value::Literal;
- v->value = QDeclarativeParser::Variant((double)value);
+ v->value = QDeclarativeScript::Variant((double)value);
*isAssignment = true;
return true;
@@ -2331,7 +2376,7 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
if (dot > 0) {
const QByteArray &scope = script.left(dot);
QDeclarativeType *type = 0;
- unit->imports().resolveType(scope, &type, 0, 0, 0, 0);
+ unit->imports().resolveType(QString::fromUtf8(script.left(dot)), &type, 0, 0, 0, 0);
if (!type && scope != "Qt")
return -1;
const QMetaObject *mo = type ? type->metaObject() : StaticQtMetaObject::get();
@@ -2349,7 +2394,7 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const
{
QDeclarativeType *qmltype = 0;
- if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0))
+ if (!unit->imports().resolveType(QString::fromUtf8(name), &qmltype, 0, 0, 0, 0))
return 0;
if (!qmltype)
return 0;
@@ -2358,10 +2403,10 @@ const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) con
// similar to logic of completeComponentBuild, but also sticks data
// into primitives at the end
-int QDeclarativeCompiler::rewriteBinding(const QString& expression, const QByteArray& name)
+int QDeclarativeCompiler::rewriteBinding(const QString& expression, const QString& name)
{
QDeclarativeRewrite::RewriteBinding rewriteBinding;
- rewriteBinding.setName('$' + name.mid(name.lastIndexOf('.') + 1));
+ rewriteBinding.setName(QLatin1Char('$') + name.mid(name.lastIndexOf('.') + 1));
QString rewrite = rewriteBinding(expression, 0, 0);
@@ -2369,16 +2414,20 @@ int QDeclarativeCompiler::rewriteBinding(const QString& expression, const QByteA
}
// Ensures that the dynamic meta specification on obj is valid
-bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
+bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeScript::Object *obj)
{
- QSet<QByteArray> propNames;
- QSet<QByteArray> methodNames;
bool seenDefaultProperty = false;
+ // We use a coarse grain, 31 bit hash to check if there are duplicates.
+ // Calculating the hash for the names is not a waste as we have to test
+ // them against the illegalNames set anyway.
+ QHashField propNames;
+ QHashField methodNames;
+
// Check properties
- for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
- const QDeclarativeParser::Object::DynamicProperty &prop =
- obj->dynamicProperties.at(ii);
+ int dpCount = obj->dynamicProperties.count();
+ for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+ const QDeclarativeScript::Object::DynamicProperty &prop = *p;
if (prop.isDefaultProperty) {
if (seenDefaultProperty)
@@ -2386,60 +2435,75 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
seenDefaultProperty = true;
}
- if (propNames.contains(prop.name))
- COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
+ if (propNames.testAndSet(prop.name.hash())) {
+ for (Object::DynamicProperty *p2 = obj->dynamicProperties.first(); p2 != p;
+ p2 = obj->dynamicProperties.next(p2)) {
+ if (p2->name == prop.name)
+ COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
+ }
+ }
- QString propName = QString::fromUtf8(prop.name);
- if (propName.at(0).isUpper())
+ if (QDeclarativeUtils::isUpper(prop.name.at(0)))
COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
- if (enginePrivate->v8engine()->illegalNames().contains(propName))
+ if (enginePrivate->v8engine()->illegalNames().contains(prop.name))
COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
-
- propNames.insert(prop.name);
}
- for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
- const QDeclarativeParser::Object::DynamicSignal &currSig = obj->dynamicSignals.at(ii);
- QByteArray name = currSig.name;
- if (methodNames.contains(name))
- COMPILE_EXCEPTION(&currSig, tr("Duplicate signal name"));
- QString nameStr = QString::fromUtf8(name);
- if (nameStr.at(0).isUpper())
+ for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
+ const QDeclarativeScript::Object::DynamicSignal &currSig = *s;
+
+ if (methodNames.testAndSet(currSig.name.hash())) {
+ for (Object::DynamicSignal *s2 = obj->dynamicSignals.first(); s2 != s;
+ s2 = obj->dynamicSignals.next(s2)) {
+ if (s2->name == currSig.name)
+ COMPILE_EXCEPTION(&currSig, tr("Duplicate signal name"));
+ }
+ }
+
+ if (currSig.name.at(0).isUpper())
COMPILE_EXCEPTION(&currSig, tr("Signal names cannot begin with an upper case letter"));
- if (enginePrivate->v8engine()->illegalNames().contains(nameStr))
+ if (enginePrivate->v8engine()->illegalNames().contains(currSig.name))
COMPILE_EXCEPTION(&currSig, tr("Illegal signal name"));
- methodNames.insert(name);
- }
- for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
- const QDeclarativeParser::Object::DynamicSlot &currSlot = obj->dynamicSlots.at(ii);
- QByteArray name = currSlot.name;
- if (methodNames.contains(name))
- COMPILE_EXCEPTION(&currSlot, tr("Duplicate method name"));
- QString nameStr = QString::fromUtf8(name);
- if (nameStr.at(0).isUpper())
+ }
+
+ for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) {
+ const QDeclarativeScript::Object::DynamicSlot &currSlot = *s;
+
+ if (methodNames.testAndSet(currSlot.name.hash())) {
+ for (Object::DynamicSignal *s2 = obj->dynamicSignals.first(); s2;
+ s2 = obj->dynamicSignals.next(s2)) {
+ if (s2->name == currSlot.name)
+ COMPILE_EXCEPTION(&currSlot, tr("Duplicate method name"));
+ }
+ for (Object::DynamicSlot *s2 = obj->dynamicSlots.first(); s2 != s;
+ s2 = obj->dynamicSlots.next(s2)) {
+ if (s2->name == currSlot.name)
+ COMPILE_EXCEPTION(&currSlot, tr("Duplicate method name"));
+ }
+ }
+
+ if (currSlot.name.at(0).isUpper())
COMPILE_EXCEPTION(&currSlot, tr("Method names cannot begin with an upper case letter"));
- if (enginePrivate->v8engine()->illegalNames().contains(nameStr))
+ if (enginePrivate->v8engine()->illegalNames().contains(currSlot.name))
COMPILE_EXCEPTION(&currSlot, tr("Illegal method name"));
- methodNames.insert(name);
}
return true;
}
-bool QDeclarativeCompiler::mergeDynamicMetaProperties(QDeclarativeParser::Object *obj)
+bool QDeclarativeCompiler::mergeDynamicMetaProperties(QDeclarativeScript::Object *obj)
{
- for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
- const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+ for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
- if (!p.defaultValue || p.type == Object::DynamicProperty::Alias)
+ if (!p->defaultValue || p->type == Object::DynamicProperty::Alias)
continue;
Property *property = 0;
- if (p.isDefaultProperty) {
+ if (p->isDefaultProperty) {
property = obj->getDefaultProperty();
} else {
- property = obj->getProperty(p.name);
+ property = obj->getProperty(p->name);
if (!property->values.isEmpty())
COMPILE_EXCEPTION(property, tr("Property value set multiple times"));
}
@@ -2447,18 +2511,14 @@ bool QDeclarativeCompiler::mergeDynamicMetaProperties(QDeclarativeParser::Object
if (property->value)
COMPILE_EXCEPTION(property, tr("Invalid property nesting"));
- for (int ii = 0; ii < p.defaultValue->values.count(); ++ii) {
- QDeclarativeParser::Value *v = p.defaultValue->values.at(ii);
- v->addref();
- property->values.append(v);
- }
+ property->values.append(p->defaultValue->values);
}
return true;
}
Q_GLOBAL_STATIC(QAtomicInt, classIndexCounter)
-bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, DynamicMetaMode mode)
+bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeScript::Object *obj, DynamicMetaMode mode)
{
Q_ASSERT(obj);
Q_ASSERT(obj->metatype);
@@ -2469,61 +2529,121 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
obj->dynamicSlots.isEmpty())
return true;
- QByteArray dynamicData(sizeof(QDeclarativeVMEMetaData), (char)0);
+ bool resolveAlias = (mode == ResolveAliases);
+
+ const Object::DynamicProperty *defaultProperty = 0;
+ int aliasCount = 0;
+
+ for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+
+ if (p->type == Object::DynamicProperty::Alias)
+ aliasCount++;
+
+ if (p->isDefaultProperty &&
+ (resolveAlias || p->type != Object::DynamicProperty::Alias))
+ defaultProperty = p;
+
+ if (!resolveAlias) {
+ // No point doing this for both the alias and non alias cases
+ QDeclarativePropertyCache::Data *d = property(obj, p->name);
+ if (d && d->isFinal())
+ COMPILE_EXCEPTION(p, tr("Cannot override FINAL property"));
+ }
+ }
+
+ bool buildData = resolveAlias || aliasCount == 0;
+
+ QByteArray dynamicData;
+ if (buildData) {
+ typedef QDeclarativeVMEMetaData VMD;
+
+ dynamicData = QByteArray(sizeof(QDeclarativeVMEMetaData) +
+ (obj->dynamicProperties.count() - aliasCount) * sizeof(VMD::PropertyData) +
+ obj->dynamicSlots.count() * sizeof(VMD::MethodData) +
+ aliasCount * sizeof(VMD::AliasData), 0);
+ }
+
+ int uniqueClassId = classIndexCounter()->fetchAndAddRelaxed(1);
QByteArray newClassName = obj->metatype->className();
newClassName.append("_QML_");
- int idx = classIndexCounter()->fetchAndAddRelaxed(1);
- newClassName.append(QByteArray::number(idx));
- if (compileState.root == obj && !compileState.nested) {
+ newClassName.append(QByteArray::number(uniqueClassId));
+
+ if (compileState->root == obj && !compileState->nested) {
QString path = output->url.path();
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
if (lastSlash > -1) {
QString nameBase = path.mid(lastSlash + 1, path.length()-lastSlash-5);
- if (!nameBase.isEmpty() && nameBase.at(0).isUpper())
- newClassName = nameBase.toUtf8() + "_QMLTYPE_" + QByteArray::number(idx);
+ if (!nameBase.isEmpty() && QDeclarativeUtils::isUpper(nameBase.at(0)))
+ newClassName = nameBase.toUtf8() + "_QMLTYPE_" + QByteArray::number(uniqueClassId);
}
}
- QMetaObjectBuilder builder;
- builder.setClassName(newClassName);
- builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+ QFastMetaBuilder builder;
+ QFastMetaBuilder::StringRef classNameRef = builder.init(newClassName.length(),
+ obj->dynamicProperties.count() - (resolveAlias?0:aliasCount),
+ obj->dynamicSlots.count(),
+ obj->dynamicSignals.count() + obj->dynamicProperties.count(),
+ defaultProperty?1:0);
+
+ struct TypeData {
+ Object::DynamicProperty::Type dtype;
+ int metaType;
+ const char *cppType;
+ } builtinTypes[] = {
+ { Object::DynamicProperty::Variant, 0, "QVariant" },
+ { Object::DynamicProperty::Int, QMetaType::Int, "int" },
+ { Object::DynamicProperty::Bool, QMetaType::Bool, "bool" },
+ { Object::DynamicProperty::Real, QMetaType::Double, "double" },
+ { Object::DynamicProperty::String, QMetaType::QString, "QString" },
+ { Object::DynamicProperty::Url, QMetaType::QUrl, "QUrl" },
+ { Object::DynamicProperty::Color, QMetaType::QColor, "QColor" },
+ { Object::DynamicProperty::Time, QMetaType::QTime, "QTime" },
+ { Object::DynamicProperty::Date, QMetaType::QDate, "QDate" },
+ { Object::DynamicProperty::DateTime, QMetaType::QDateTime, "QDateTime" },
+ };
+ static const int builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData);
+ QFastMetaBuilder::StringRef typeRefs[builtinTypeCount];
+
+ // Reserve dynamic properties
+ if (obj->dynamicProperties.count()) {
+ typedef QDeclarativeVMEMetaData VMD;
+
+ int effectivePropertyIndex = 0;
+ for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+
+ // Reserve space for name
+ p->nameRef = builder.newString(p->name.utf8length());
+
+ int propertyType = 0;
+ bool readonly = false;
+ QFastMetaBuilder::StringRef typeRef;
+
+ if (p->type == Object::DynamicProperty::Alias) {
+ continue;
+ } else if (p->type < builtinTypeCount) {
+ Q_ASSERT(builtinTypes[p->type].dtype == p->type);
+ propertyType = builtinTypes[p->type].metaType;
+ if (typeRefs[p->type].isEmpty())
+ typeRefs[p->type] = builder.newString(strlen(builtinTypes[p->type].cppType));
+ typeRef = typeRefs[p->type];
+ if (p->type == Object::DynamicProperty::Variant)
+ propertyType = -1;
- bool hasAlias = false;
- for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
- const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+ } else {
+ Q_ASSERT(p->type == Object::DynamicProperty::CustomList ||
+ p->type == Object::DynamicProperty::Custom);
- int propIdx = obj->metaObject()->indexOfProperty(p.name.constData());
- if (-1 != propIdx) {
- QMetaProperty prop = obj->metaObject()->property(propIdx);
- if (prop.isFinal())
- COMPILE_EXCEPTION(&p, tr("Cannot override FINAL property"));
- }
+ // XXX don't double resolve this in the case of an alias run
- if (p.isDefaultProperty &&
- (p.type != Object::DynamicProperty::Alias ||
- mode == ResolveAliases))
- builder.addClassInfo("DefaultProperty", p.name);
-
- QByteArray type;
- int propertyType = 0;
- bool readonly = false;
- switch(p.type) {
- case Object::DynamicProperty::Alias:
- hasAlias = true;
- continue;
- break;
- case Object::DynamicProperty::CustomList:
- case Object::DynamicProperty::Custom:
- {
QByteArray customTypeName;
QDeclarativeType *qmltype = 0;
- QUrl url;
- if (!unit->imports().resolveType(p.customType, &qmltype, &url, 0, 0, 0))
- COMPILE_EXCEPTION(&p, tr("Invalid property type"));
+ QString url;
+ if (!unit->imports().resolveType(p->customType.toString(), &qmltype, &url, 0, 0, 0))
+ COMPILE_EXCEPTION(p, tr("Invalid property type"));
if (!qmltype) {
- QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(url);
+ QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(QUrl(url));
Q_ASSERT(tdata);
Q_ASSERT(tdata->isComplete());
@@ -2535,146 +2655,217 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
customTypeName = qmltype->typeName();
}
- if (p.type == Object::DynamicProperty::Custom) {
- type = customTypeName + '*';
+ if (p->type == Object::DynamicProperty::Custom) {
+ customTypeName += '*';
propertyType = QMetaType::QObjectStar;
} else {
readonly = true;
- type = "QDeclarativeListProperty<";
- type.append(customTypeName);
- type.append(">");
+ customTypeName = QByteArray("QDeclarativeListProperty<") + customTypeName + QByteArray(">");
propertyType = qMetaTypeId<QDeclarativeListProperty<QObject> >();
}
+
+ p->resolvedCustomTypeName = pool->NewByteArray(customTypeName);
+ p->typeRef = builder.newString(customTypeName.length());
+ typeRef = p->typeRef;
}
- break;
- case Object::DynamicProperty::Variant:
- propertyType = -1;
- type = "QVariant";
- break;
- case Object::DynamicProperty::Int:
- propertyType = QVariant::Int;
- type = "int";
- break;
- case Object::DynamicProperty::Bool:
- propertyType = QVariant::Bool;
- type = "bool";
- break;
- case Object::DynamicProperty::Real:
- propertyType = QVariant::Double;
- type = "double";
- break;
- case Object::DynamicProperty::String:
- propertyType = QVariant::String;
- type = "QString";
- break;
- case Object::DynamicProperty::Url:
- propertyType = QVariant::Url;
- type = "QUrl";
- break;
- case Object::DynamicProperty::Color:
- propertyType = QVariant::Color;
- type = "QColor";
- break;
- case Object::DynamicProperty::Time:
- propertyType = QVariant::Time;
- type = "QTime";
- break;
- case Object::DynamicProperty::Date:
- propertyType = QVariant::Date;
- type = "QDate";
- break;
- case Object::DynamicProperty::DateTime:
- propertyType = QVariant::DateTime;
- type = "QDateTime";
- break;
- }
- ((QDeclarativeVMEMetaData *)dynamicData.data())->propertyCount++;
- QDeclarativeVMEMetaData::PropertyData propertyData = { propertyType };
- dynamicData.append((char *)&propertyData, sizeof(propertyData));
+ if (buildData) {
+ VMD *vmd = (QDeclarativeVMEMetaData *)dynamicData.data();
+ vmd->propertyCount++;
+ (vmd->propertyData() + effectivePropertyIndex)->propertyType = propertyType;
+ }
- builder.addSignal(p.name + "Changed()");
- QMetaPropertyBuilder propBuilder =
- builder.addProperty(p.name, type, builder.methodCount() - 1);
- propBuilder.setWritable(!readonly);
- }
+ if (p->type < builtinTypeCount)
+ builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, (QMetaType::Type)propertyType,
+ readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable,
+ effectivePropertyIndex);
+ else
+ builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef,
+ readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable,
+ effectivePropertyIndex);
- for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
- const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+ p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()"));
+ builder.setSignal(effectivePropertyIndex, p->changedSignatureRef);
- if (p.type == Object::DynamicProperty::Alias) {
- if (mode == ResolveAliases) {
- ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
- COMPILE_CHECK(compileAlias(builder, dynamicData, obj, p));
- } else {
- // Need a fake signal so that the metaobject remains consistent across
- // the resolve and non-resolve alias runs
- builder.addSignal(p.name + "Changed()");
+ effectivePropertyIndex++;
+ }
+
+ if (aliasCount) {
+ int aliasIndex = 0;
+ for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+ if (p->type == Object::DynamicProperty::Alias) {
+ if (resolveAlias) {
+ Q_ASSERT(buildData);
+ ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
+ COMPILE_CHECK(compileAlias(builder, dynamicData, obj, effectivePropertyIndex,
+ aliasIndex, *p));
+ }
+ // Even if we aren't resolving the alias, we need a fake signal so that the
+ // metaobject remains consistent across the resolve and non-resolve alias runs
+ p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()"));
+ builder.setSignal(effectivePropertyIndex, p->changedSignatureRef);
+ effectivePropertyIndex++;
+ aliasIndex++;
+ }
}
}
}
- for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
- const Object::DynamicSignal &s = obj->dynamicSignals.at(ii);
- QByteArray sig(s.name + '(');
- for (int jj = 0; jj < s.parameterTypes.count(); ++jj) {
- if (jj) sig.append(',');
- sig.append(s.parameterTypes.at(jj));
- }
- sig.append(')');
- QMetaMethodBuilder b = builder.addSignal(sig);
- b.setParameterNames(s.parameterNames);
- ((QDeclarativeVMEMetaData *)dynamicData.data())->signalCount++;
+ // Reserve default property
+ QFastMetaBuilder::StringRef defPropRef;
+ if (defaultProperty) {
+ defPropRef = builder.newString(strlen("DefaultProperty"));
+ builder.setClassInfo(0, defPropRef, defaultProperty->nameRef);
+ }
+
+ // Reserve dynamic signals
+ int signalIndex = 0;
+ for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
+
+ int paramCount = s->parameterNames.count();
+
+ int signatureSize = s->name.utf8length() + 2 /* paren */;
+ int namesSize = 0;
+ if (paramCount) signatureSize += s->parameterTypesLength() + (paramCount - 1) /* commas */;
+ if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1) /* commas */;
+
+ s->signatureRef = builder.newString(signatureSize);
+ if (namesSize) s->parameterNamesRef = builder.newString(namesSize);
+
+ if (buildData)
+ ((QDeclarativeVMEMetaData *)dynamicData.data())->signalCount++;
+
+ builder.setSignal(signalIndex + obj->dynamicProperties.count(), s->signatureRef, s->parameterNamesRef);
+ ++signalIndex;
}
- QStringList funcScripts;
+ // Reserve dynamic slots
+ if (obj->dynamicSlots.count()) {
+
+ // Allocate QVariant string
+ if (typeRefs[0].isEmpty())
+ typeRefs[0] = builder.newString(strlen(builtinTypes[0].cppType));
+
+ typedef QDeclarativeVMEMetaData VMD;
+
+ int methodIndex = 0;
+ for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) {
+ int paramCount = s->parameterNames.count();
- for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
- Object::DynamicSlot &s = obj->dynamicSlots[ii];
- QByteArray sig(s.name + '(');
- QString funcScript(QLatin1String("(function ") + s.name + QLatin1Char('('));
+ int signatureSize = s->name.utf8length() + 2 /* paren */;
+ int namesSize = 0;
+ if (paramCount) signatureSize += (paramCount * strlen("QVariant") + (paramCount - 1));
+ if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1 /* commas */);
- for (int jj = 0; jj < s.parameterNames.count(); ++jj) {
- if (jj) {
- sig.append(',');
- funcScript.append(QLatin1Char(','));
+ s->signatureRef = builder.newString(signatureSize);
+ if (namesSize) s->parameterNamesRef = builder.newString(namesSize);
+
+ builder.setMethod(methodIndex, s->signatureRef, s->parameterNamesRef, typeRefs[0]);
+
+ if (buildData) {
+ QString funcScript;
+ funcScript.reserve(strlen("(function ") + s->name.length() + 1 /* lparen */ +
+ namesSize + 1 /* rparen */ + s->body.length() + 1 /* rparen */);
+ funcScript = QLatin1String("(function ") + s->name.toString() + QLatin1Char('(');
+ for (int jj = 0; jj < paramCount; ++jj) {
+ if (jj) funcScript.append(QLatin1Char(','));
+ funcScript.append(QLatin1String(s->parameterNames.at(jj)));
+ }
+ funcScript += QLatin1Char(')') + s->body + QLatin1Char(')');
+
+ VMD::MethodData methodData = { s->parameterNames.count(), 0,
+ funcScript.length(),
+ s->location.start.line };
+
+ VMD *vmd = (QDeclarativeVMEMetaData *)dynamicData.data();
+ vmd->methodCount++;
+
+ VMD::MethodData &md = *(vmd->methodData() + methodIndex);
+ md = methodData;
+ md.bodyOffset = dynamicData.size();
+
+ dynamicData.append((const char *)funcScript.constData(),
+ (funcScript.length() * sizeof(QChar)));
}
- funcScript.append(QLatin1String(s.parameterNames.at(jj)));
- sig.append("QVariant");
+
+ methodIndex++;
}
- sig.append(')');
- funcScript.append(QLatin1Char(')'));
- funcScript.append(s.body);
- funcScript.append(QLatin1Char(')'));
- funcScripts << funcScript;
+ }
- QMetaMethodBuilder b = builder.addSlot(sig);
- b.setReturnType("QVariant");
- b.setParameterNames(s.parameterNames);
+ // Now allocate used builtin types
+ for (int ii = 0; ii < builtinTypeCount; ++ii) {
+ if (!typeRefs[ii].isEmpty())
+ typeRefs[ii].load(builtinTypes[ii].cppType);
+ }
- ((QDeclarativeVMEMetaData *)dynamicData.data())->methodCount++;
- QDeclarativeVMEMetaData::MethodData methodData =
- { s.parameterNames.count(), 0, funcScript.length(), s.location.start.line };
+ // Now allocate properties
+ for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
- dynamicData.append((char *)&methodData, sizeof(methodData));
- }
+ char *d = p->changedSignatureRef.data();
+ p->name.writeUtf8(d);
+ strcpy(d + p->name.utf8length(), "Changed()");
- for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
- const QString &funcScript = funcScripts.at(ii);
- QDeclarativeVMEMetaData::MethodData *data =
- ((QDeclarativeVMEMetaData *)dynamicData.data())->methodData() + ii;
+ if (p->type == Object::DynamicProperty::Alias && !resolveAlias)
+ continue;
+
+ p->nameRef.load(p->name);
- data->bodyOffset = dynamicData.size();
+ if (p->type >= builtinTypeCount) {
+ Q_ASSERT(p->resolvedCustomTypeName);
+ p->typeRef.load(*p->resolvedCustomTypeName);
+ }
+ }
- dynamicData.append((const char *)funcScript.constData(),
- (funcScript.length() * sizeof(QChar)));
+ // Allocate default property if necessary
+ if (defaultProperty)
+ strcpy(defPropRef.data(), "DefaultProperty");
+
+ // Now allocate signals
+ for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
+
+ char *d = s->signatureRef.data();
+ char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data();
+ s->name.writeUtf8(d); d += s->name.utf8length();
+ *d++ = '(';
+
+ for (int jj = 0; jj < s->parameterNames.count(); ++jj) {
+ if (jj != 0) { *d++ = ','; *d2++ = ','; }
+ strcpy(d, s->parameterTypes.at(jj).constData());
+ d += s->parameterTypes.at(jj).length();
+ s->parameterNames.at(jj).writeUtf8(d2);
+ d2 += s->parameterNames.at(jj).utf8length();
+ }
+ *d++ = ')';
+ *d = 0;
+ if (d2) *d2 = 0;
+ }
+
+ // Now allocate methods
+ for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) {
+ char *d = s->signatureRef.data();
+ char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data();
+ s->name.writeUtf8(d); d += s->name.utf8length();
+ *d++ = '(';
+ for (int jj = 0; jj < s->parameterNames.count(); ++jj) {
+ if (jj != 0) { *d++ = ','; *d2++ = ','; }
+ strcpy(d, "QVariant");
+ d += strlen("QVariant");
+ strcpy(d2, s->parameterNames.at(jj).constData());
+ d2 += s->parameterNames.at(jj).length();
+ }
+ *d++ = ')';
+ *d = 0;
+ if (d2) *d2 = 0;
}
- obj->metadata = builder.toRelocatableData();
- builder.fromRelocatableData(&obj->extObject, obj->metatype, obj->metadata);
+ // Now allocate class name
+ classNameRef.load(newClassName);
- if (mode == IgnoreAliases && hasAlias)
- compileState.aliasingObjects << obj;
+ obj->metadata = builder.toData();
+ builder.fromData(&obj->extObject, obj->metatype, obj->metadata);
+
+ if (mode == IgnoreAliases && aliasCount)
+ compileState->aliasingObjects.append(obj);
obj->synthdata = dynamicData;
@@ -2694,23 +2885,23 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
return true;
}
-bool QDeclarativeCompiler::checkValidId(QDeclarativeParser::Value *v, const QString &val)
+bool QDeclarativeCompiler::checkValidId(QDeclarativeScript::Value *v, const QString &val)
{
if (val.isEmpty())
COMPILE_EXCEPTION(v, tr( "Invalid empty ID"));
- if (val.at(0).isLetter() && !val.at(0).isLower())
+ QChar ch = val.at(0);
+ if (QDeclarativeUtils::isLetter(ch) && !QDeclarativeUtils::isLower(ch))
COMPILE_EXCEPTION(v, tr( "IDs cannot start with an uppercase letter"));
QChar u(QLatin1Char('_'));
- for (int ii = 0; ii < val.count(); ++ii) {
+ if (!QDeclarativeUtils::isLetter(ch) && ch != u)
+ COMPILE_EXCEPTION(v, tr( "IDs must start with a letter or underscore"));
- if (ii == 0 && !val.at(ii).isLetter() && val.at(ii) != u) {
- COMPILE_EXCEPTION(v, tr( "IDs must start with a letter or underscore"));
- } else if (ii != 0 && !val.at(ii).isLetterOrNumber() && val.at(ii) != u) {
+ for (int ii = 1; ii < val.count(); ++ii) {
+ ch = val.at(ii);
+ if (!QDeclarativeUtils::isLetterOrNumber(ch) && ch != u)
COMPILE_EXCEPTION(v, tr( "IDs must contain only letters, numbers, and underscores"));
- }
-
}
if (enginePrivate->v8engine()->illegalNames().contains(val))
@@ -2725,7 +2916,7 @@ static QStringList astNodeToStringList(QDeclarativeJS::AST::Node *node)
{
if (node->kind == QDeclarativeJS::AST::Node::Kind_IdentifierExpression) {
QString name =
- static_cast<QDeclarativeJS::AST::IdentifierExpression *>(node)->name->asString();
+ static_cast<QDeclarativeJS::AST::IdentifierExpression *>(node)->name.toString();
return QStringList() << name;
} else if (node->kind == QDeclarativeJS::AST::Node::Kind_FieldMemberExpression) {
QDeclarativeJS::AST::FieldMemberExpression *expr = static_cast<QDeclarativeJS::AST::FieldMemberExpression *>(node);
@@ -2733,26 +2924,27 @@ static QStringList astNodeToStringList(QDeclarativeJS::AST::Node *node)
QStringList rv = astNodeToStringList(expr->base);
if (rv.isEmpty())
return rv;
- rv.append(expr->name->asString());
+ rv.append(expr->name.toString());
return rv;
}
return QStringList();
}
-bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
+bool QDeclarativeCompiler::compileAlias(QFastMetaBuilder &builder,
QByteArray &data,
- QDeclarativeParser::Object *obj,
- const Object::DynamicProperty &prop)
+ QDeclarativeScript::Object *obj,
+ int propIndex, int aliasIndex,
+ Object::DynamicProperty &prop)
{
if (!prop.defaultValue)
COMPILE_EXCEPTION(obj, tr("No property alias location"));
- if (prop.defaultValue->values.count() != 1 ||
- prop.defaultValue->values.at(0)->object ||
- !prop.defaultValue->values.at(0)->value.isScript())
+ if (!prop.defaultValue->values.isOne() ||
+ prop.defaultValue->values.first()->object ||
+ !prop.defaultValue->values.first()->value.isScript())
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
- QDeclarativeJS::AST::Node *node = prop.defaultValue->values.at(0)->value.asAST();
+ QDeclarativeJS::AST::Node *node = prop.defaultValue->values.first()->value.asAST();
if (!node)
COMPILE_EXCEPTION(obj, tr("No property alias location")); // ### Can this happen?
@@ -2761,19 +2953,19 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
if (alias.count() < 1 || alias.count() > 3)
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>"));
- if (!compileState.ids.contains(alias.at(0)))
+ QDeclarativeScript::Object *idObject = compileState->ids.value(alias.at(0));
+ if (!idObject)
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0)));
- QDeclarativeParser::Object *idObject = compileState.ids[alias.at(0)];
-
QByteArray typeName;
int propIdx = -1;
int flags = 0;
+ int type = 0;
bool writable = false;
bool resettable = false;
if (alias.count() == 2 || alias.count() == 3) {
- propIdx = indexOfProperty(idObject, alias.at(1).toUtf8());
+ propIdx = indexOfProperty(idObject, alias.at(1));
if (-1 == propIdx) {
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
@@ -2788,6 +2980,9 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
writable = aliasProperty.isWritable();
resettable = aliasProperty.isResettable();
+ if (aliasProperty.type() < QVariant::UserType)
+ type = aliasProperty.type();
+
if (alias.count() == 3) {
QDeclarativeValueType *valueType = enginePrivate->valueTypes[aliasProperty.type()];
if (!valueType)
@@ -2802,6 +2997,11 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
aliasProperty = valueType->metaObject()->property(valueTypeIndex);
propIdx |= (valueTypeIndex << 16);
+
+ // update the property type
+ type = aliasProperty.type();
+ if (type >= QVariant::UserType)
+ type = 0;
}
if (aliasProperty.isEnumType())
@@ -2823,49 +3023,59 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder,
if (typeName.endsWith('*'))
flags |= QML_ALIAS_FLAG_PTR;
- data.append((const char *)&idObject->idIndex, sizeof(idObject->idIndex));
- data.append((const char *)&propIdx, sizeof(propIdx));
- data.append((const char *)&flags, sizeof(flags));
+ QDeclarativeVMEMetaData::AliasData aliasData = { idObject->idIndex, propIdx, flags };
+
+ typedef QDeclarativeVMEMetaData VMD;
+ VMD *vmd = (QDeclarativeVMEMetaData *)data.data();
+ *(vmd->aliasData() + aliasIndex) = aliasData;
+
+ prop.nameRef = builder.newString(prop.name.utf8length());
+ prop.resolvedCustomTypeName = pool->NewByteArray(typeName);
+ prop.typeRef = builder.newString(typeName.length());
+
+ int propertyFlags = 0;
+ if (writable)
+ propertyFlags |= QFastMetaBuilder::Writable;
+ if (resettable)
+ propertyFlags |= QFastMetaBuilder::Resettable;
+
+ builder.setProperty(propIndex, prop.nameRef, prop.typeRef, (QMetaType::Type)type,
+ (QFastMetaBuilder::PropertyFlag)propertyFlags,
+ propIndex);
- builder.addSignal(prop.name + "Changed()");
- QMetaPropertyBuilder propBuilder =
- builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
- propBuilder.setWritable(writable);
- propBuilder.setResettable(resettable);
return true;
}
-bool QDeclarativeCompiler::buildBinding(QDeclarativeParser::Value *value,
- QDeclarativeParser::Property *prop,
- const BindingContext &ctxt)
+bool QDeclarativeCompiler::buildBinding(QDeclarativeScript::Value *value,
+ QDeclarativeScript::Property *prop,
+ const BindingContext &ctxt)
{
Q_ASSERT(prop->index != -1);
Q_ASSERT(prop->parent);
Q_ASSERT(prop->parent->metaObject());
- QMetaProperty mp = prop->parent->metaObject()->property(prop->index);
- if (!mp.isWritable() && !QDeclarativeMetaType::isList(prop->type))
- COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
+ if (!prop->core.isWritable() && !prop->core.isQList())
+ COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
- BindingReference reference;
- reference.expression = value->value;
- reference.property = prop;
- reference.value = value;
- reference.bindingContext = ctxt;
+ BindingReference *reference = pool->New<BindingReference>();
+ reference->expression = value->value;
+ reference->property = prop;
+ reference->value = value;
+ reference->bindingContext = ctxt;
addBindingReference(reference);
return true;
}
-void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *binding,
- QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Property *valueTypeProperty)
+void QDeclarativeCompiler::genBindingAssignment(QDeclarativeScript::Value *binding,
+ QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Property *valueTypeProperty)
{
Q_UNUSED(obj);
- Q_ASSERT(compileState.bindings.contains(binding));
+ Q_ASSERT(binding->bindingReference);
- const BindingReference &ref = compileState.bindings.value(binding);
+ const BindingReference &ref = *binding->bindingReference;
if (ref.dataType == BindingReference::V4) {
QDeclarativeInstruction store;
store.setType(QDeclarativeInstruction::StoreV4Binding);
@@ -2921,22 +3131,20 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi
int QDeclarativeCompiler::genContextCache()
{
- if (compileState.ids.count() == 0)
+ if (compileState->ids.count() == 0)
return -1;
QDeclarativeIntegerCache *cache = new QDeclarativeIntegerCache();
-
- for (QHash<QString, QDeclarativeParser::Object *>::ConstIterator iter = compileState.ids.begin();
- iter != compileState.ids.end();
- ++iter)
- cache->add(iter.key(), (*iter)->idIndex);
+ cache->reserve(compileState->ids.count());
+ for (Object *o = compileState->ids.first(); o; o = compileState->ids.next(o))
+ cache->add(o->id, o->idIndex);
output->contextCaches.append(cache);
return output->contextCaches.count() - 1;
}
-int QDeclarativeCompiler::genValueTypeData(QDeclarativeParser::Property *valueTypeProp,
- QDeclarativeParser::Property *prop)
+int QDeclarativeCompiler::genValueTypeData(QDeclarativeScript::Property *valueTypeProp,
+ QDeclarativeScript::Property *prop)
{
typedef QDeclarativePropertyPrivate QDPP;
QByteArray data = QDPP::saveValueType(prop->parent->metaObject(), prop->index,
@@ -2946,7 +3154,7 @@ int QDeclarativeCompiler::genValueTypeData(QDeclarativeParser::Property *valueTy
return output->indexForByteArray(data);
}
-int QDeclarativeCompiler::genPropertyData(QDeclarativeParser::Property *prop)
+int QDeclarativeCompiler::genPropertyData(QDeclarativeScript::Property *prop)
{
typedef QDeclarativePropertyPrivate QDPP;
QByteArray data = QDPP::saveProperty(prop->parent->metaObject(), prop->index, engine);
@@ -2956,27 +3164,25 @@ int QDeclarativeCompiler::genPropertyData(QDeclarativeParser::Property *prop)
bool QDeclarativeCompiler::completeComponentBuild()
{
- componentStat.ids = compileState.ids.count();
+ if (componentStats)
+ componentStats->componentStat.ids = compileState->ids.count();
- for (int ii = 0; ii < compileState.aliasingObjects.count(); ++ii) {
- QDeclarativeParser::Object *aliasObject = compileState.aliasingObjects.at(ii);
+ for (Object *aliasObject = compileState->aliasingObjects.first(); aliasObject;
+ aliasObject = compileState->aliasingObjects.next(aliasObject))
COMPILE_CHECK(buildDynamicMeta(aliasObject, ResolveAliases));
- }
- QDeclarativeV4Compiler::Expression expr;
- expr.component = compileState.root;
- expr.ids = compileState.ids;
+ QDeclarativeV4Compiler::Expression expr(unit->imports());
+ expr.component = compileState->root;
+ expr.ids = &compileState->ids;
expr.importCache = output->importCache;
- expr.imports = unit->imports();
QDeclarativeV4Compiler bindingCompiler;
QList<BindingReference*> sharedBindings;
- for (QHash<QDeclarativeParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin();
- iter != compileState.bindings.end(); ++iter) {
+ for (BindingReference *b = compileState->bindings.first(); b; b = b->nextReference) {
- BindingReference &binding = *iter;
+ BindingReference &binding = *b;
// ### We don't currently optimize for bindings on alias's - because
// of the solution to QTBUG-13719
@@ -2989,7 +3195,8 @@ bool QDeclarativeCompiler::completeComponentBuild()
if (index != -1) {
binding.dataType = BindingReference::V4;
binding.compiledIndex = index;
- componentStat.optimizedBindings.append(iter.key()->location);
+ if (componentStats)
+ componentStats->componentStat.optimizedBindings.append(b->value->location);
continue;
}
}
@@ -2998,19 +3205,20 @@ bool QDeclarativeCompiler::completeComponentBuild()
QString expression = binding.expression.asScript();
QDeclarativeRewrite::RewriteBinding rewriteBinding;
- rewriteBinding.setName('$'+binding.property->name);
+ rewriteBinding.setName(QLatin1Char('$')+binding.property->name().toString());
bool isSharable = false;
binding.rewrittenExpression = rewriteBinding(binding.expression.asAST(), expression, &isSharable);
if (isSharable && !binding.property->isAlias /* See above re alias */ &&
binding.property->type != qMetaTypeId<QDeclarativeBinding*>()) {
binding.dataType = BindingReference::V8;
- sharedBindings.append(&iter.value());
+ sharedBindings.append(b);
} else {
binding.dataType = BindingReference::QtScript;
}
- componentStat.scriptBindings.append(iter.key()->location);
+ if (componentStats)
+ componentStats->componentStat.scriptBindings.append(b->value->location);
}
if (!sharedBindings.isEmpty()) {
@@ -3029,7 +3237,7 @@ bool QDeclarativeCompiler::completeComponentBuild()
QString functionArray(QLatin1String("["));
for (int ii = 0; ii < sharedBindings.count(); ++ii) {
BindingReference *reference = sharedBindings.at(ii);
- QDeclarativeParser::Value *value = reference->value;
+ QDeclarativeScript::Value *value = reference->value;
const QString &expression = reference->rewrittenExpression;
if (ii != 0) functionArray += QLatin1String(",");
@@ -3044,14 +3252,14 @@ bool QDeclarativeCompiler::completeComponentBuild()
}
functionArray += QLatin1String("]");
- compileState.v8BindingProgram = functionArray;
- compileState.v8BindingProgramLine = startLineNumber;
- compileState.v8BindingProgramIndex = output->v8bindings.count();
+ compileState->v8BindingProgram = functionArray;
+ compileState->v8BindingProgramLine = startLineNumber;
+ compileState->v8BindingProgramIndex = output->v8bindings.count();
output->v8bindings.append(v8::Persistent<v8::Array>());
}
if (bindingCompiler.isValid())
- compileState.compiledBindingData = bindingCompiler.program();
+ compileState->compiledBindingData = bindingCompiler.program();
saveComponentState();
@@ -3060,9 +3268,10 @@ bool QDeclarativeCompiler::completeComponentBuild()
void QDeclarativeCompiler::dumpStats()
{
+ Q_ASSERT(componentStats);
qWarning().nospace() << "QML Document: " << output->url.toString();
- for (int ii = 0; ii < savedComponentStats.count(); ++ii) {
- const ComponentStat &stat = savedComponentStats.at(ii);
+ for (int ii = 0; ii < componentStats->savedComponentStats.count(); ++ii) {
+ const ComponentStat &stat = componentStats->savedComponentStats.at(ii);
qWarning().nospace() << " Component Line " << stat.lineNumber;
qWarning().nospace() << " Total Objects: " << stat.objects;
qWarning().nospace() << " IDs Used: " << stat.ids;
@@ -3111,7 +3320,7 @@ void QDeclarativeCompiler::dumpStats()
Returns true if from can be assigned to a (QObject) property of type
to.
*/
-bool QDeclarativeCompiler::canCoerce(int to, QDeclarativeParser::Object *from)
+bool QDeclarativeCompiler::canCoerce(int to, QDeclarativeScript::Object *from)
{
const QMetaObject *toMo =
enginePrivate->rawMetaObjectForType(to);
@@ -3125,7 +3334,20 @@ bool QDeclarativeCompiler::canCoerce(int to, QDeclarativeParser::Object *from)
return false;
}
-QDeclarativeType *QDeclarativeCompiler::toQmlType(QDeclarativeParser::Object *from)
+/*!
+ Returns the element name, as written in the QML file, for o.
+*/
+QString QDeclarativeCompiler::elementName(QDeclarativeScript::Object *o)
+{
+ Q_ASSERT(o);
+ if (o->type != -1) {
+ return output->types.at(o->type).className;
+ } else {
+ return QString();
+ }
+}
+
+QDeclarativeType *QDeclarativeCompiler::toQmlType(QDeclarativeScript::Object *from)
{
// ### Optimize
const QMetaObject *mo = from->metatype;
@@ -3137,7 +3359,7 @@ QDeclarativeType *QDeclarativeCompiler::toQmlType(QDeclarativeParser::Object *fr
return type;
}
-QStringList QDeclarativeCompiler::deferredProperties(QDeclarativeParser::Object *obj)
+QStringList QDeclarativeCompiler::deferredProperties(QDeclarativeScript::Object *obj)
{
const QMetaObject *mo = obj->metatype;
@@ -3150,74 +3372,108 @@ QStringList QDeclarativeCompiler::deferredProperties(QDeclarativeParser::Object
return rv;
}
-// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName
-int QDeclarativeCompiler::indexOfSignal(QDeclarativeParser::Object *object, const QByteArray &name,
- bool *notInRevision)
+QDeclarativePropertyCache::Data *
+QDeclarativeCompiler::property(QDeclarativeScript::Object *object, int index)
{
- if (notInRevision) *notInRevision = false;
+ QDeclarativePropertyCache *cache = 0;
+
+ if (object->synthCache)
+ cache = object->synthCache;
+ else if (object->type != -1)
+ cache = output->types[object->type].createPropertyCache(engine);
+ else
+ cache = QDeclarativeEnginePrivate::get(engine)->cache(object->metaObject());
- if (object->synthCache || (object->type != -1 && output->types.at(object->type).propertyCache())) {
- // XXX fromUtf8
- QString strName(QString::fromUtf8(name));
- QDeclarativePropertyCache *cache =
- object->synthCache?object->synthCache:output->types.at(object->type).propertyCache();
+ return cache->property(index);
+}
- QDeclarativePropertyCache::Data *d = cache->property(strName);
- if (notInRevision) *notInRevision = false;
+QDeclarativePropertyCache::Data *
+QDeclarativeCompiler::property(QDeclarativeScript::Object *object, const QHashedStringRef &name, bool *notInRevision)
+{
+ if (notInRevision) *notInRevision = false;
- while (d && !(d->isFunction()))
- d = cache->overrideData(d);
+ QDeclarativePropertyCache *cache = 0;
- if (d && !cache->isAllowedInRevision(d)) {
- if (notInRevision) *notInRevision = true;
- return -1;
- } else if (d) {
- return d->coreIndex;
- }
+ if (object->synthCache)
+ cache = object->synthCache;
+ else if (object->type != -1)
+ cache = output->types[object->type].createPropertyCache(engine);
+ else
+ cache = QDeclarativeEnginePrivate::get(engine)->cache(object->metaObject());
- if (name.endsWith("Changed")) {
- QByteArray propName = name.mid(0, name.length() - 7);
+ QDeclarativePropertyCache::Data *d = cache->property(name);
- int propIndex = indexOfProperty(object, propName, notInRevision);
- if (propIndex != -1) {
- d = cache->property(propIndex);
- return d->notifyIndex;
- }
- }
+ // Find the first property
+ while (d && d->isFunction())
+ d = cache->overrideData(d);
- return -1;
+ if (d && !cache->isAllowedInRevision(d)) {
+ if (notInRevision) *notInRevision = true;
+ return 0;
} else {
- return QDeclarativePropertyPrivate::findSignalByName(object->metaObject(), name).methodIndex();
+ return d;
}
-
}
-int QDeclarativeCompiler::indexOfProperty(QDeclarativeParser::Object *object, const QByteArray &name,
- bool *notInRevision)
+// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName
+QDeclarativePropertyCache::Data *
+QDeclarativeCompiler::signal(QDeclarativeScript::Object *object, const QHashedStringRef &name, bool *notInRevision)
{
if (notInRevision) *notInRevision = false;
- if (object->synthCache || (object->type != -1 && output->types.at(object->type).propertyCache())) {
- // XXX fromUtf8
- QString strName(QString::fromUtf8(name));
- QDeclarativePropertyCache *cache =
- object->synthCache?object->synthCache:output->types.at(object->type).propertyCache();
+ QDeclarativePropertyCache *cache = 0;
- QDeclarativePropertyCache::Data *d = cache->property(strName);
- // Find the first property
- while (d && d->isFunction())
- d = cache->overrideData(d);
+ if (object->synthCache)
+ cache = object->synthCache;
+ else if (object->type != -1)
+ cache = output->types[object->type].createPropertyCache(engine);
+ else
+ cache = QDeclarativeEnginePrivate::get(engine)->cache(object->metaObject());
- if (d && !cache->isAllowedInRevision(d)) {
- if (notInRevision) *notInRevision = true;
- return -1;
- } else {
- return d?d->coreIndex:-1;
- }
- } else {
- const QMetaObject *mo = object->metaObject();
- return mo->indexOfProperty(name.constData());
+
+ QDeclarativePropertyCache::Data *d = cache->property(name);
+ if (notInRevision) *notInRevision = false;
+
+ while (d && !(d->isFunction()))
+ d = cache->overrideData(d);
+
+ if (d && !cache->isAllowedInRevision(d)) {
+ if (notInRevision) *notInRevision = true;
+ return 0;
+ } else if (d) {
+ return d;
+ }
+
+ if (name.endsWith(Changed_string)) {
+ QHashedStringRef propName = name.mid(0, name.length() - Changed_string.length());
+
+ d = property(object, propName, notInRevision);
+ if (d)
+ return cache->method(d->notifyIndex);
}
+
+ return 0;
+}
+
+// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName
+int QDeclarativeCompiler::indexOfSignal(QDeclarativeScript::Object *object, const QString &name,
+ bool *notInRevision)
+{
+ QDeclarativePropertyCache::Data *d = signal(object, QStringRef(&name), notInRevision);
+ return d?d->coreIndex:-1;
+}
+
+int QDeclarativeCompiler::indexOfProperty(QDeclarativeScript::Object *object, const QString &name,
+ bool *notInRevision)
+{
+ return indexOfProperty(object, QStringRef(&name), notInRevision);
+}
+
+int QDeclarativeCompiler::indexOfProperty(QDeclarativeScript::Object *object, const QHashedStringRef &name,
+ bool *notInRevision)
+{
+ QDeclarativePropertyCache::Data *d = property(object, name, notInRevision);
+ return d?d->coreIndex:-1;
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index a2b959a568..0e159a2cdf 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -57,7 +57,7 @@
#include "qdeclarativeerror.h"
#include "private/qv8_p.h"
#include "private/qdeclarativeinstruction_p.h"
-#include "private/qdeclarativeparser_p.h"
+#include "private/qdeclarativescript_p.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qbitfield_p.h"
#include "private/qdeclarativepropertycache_p.h"
@@ -91,7 +91,7 @@ public:
TypeReference()
: type(0), typePropertyCache(0), component(0) {}
- QByteArray className;
+ QString className;
QDeclarativeType *type;
QDeclarativePropertyCache *typePropertyCache;
QDeclarativeCompiledData *component;
@@ -139,183 +139,237 @@ private:
int indexForUrl(const QUrl &);
};
+namespace QDeclarativeCompilerTypes {
+ struct BindingContext
+ {
+ BindingContext()
+ : stack(0), owner(0), object(0) {}
+ BindingContext(QDeclarativeScript::Object *o)
+ : stack(0), owner(0), object(o) {}
+ BindingContext incr() const {
+ BindingContext rv(object);
+ rv.stack = stack + 1;
+ return rv;
+ }
+ bool isSubContext() const { return stack != 0; }
+ int stack;
+ int owner;
+ QDeclarativeScript::Object *object;
+ };
+
+ struct BindingReference : public QDeclarativePool::Class
+ {
+ BindingReference() : nextReference(0) {}
+
+ QDeclarativeScript::Variant expression;
+ QDeclarativeScript::Property *property;
+ QDeclarativeScript::Value *value;
+
+ enum DataType { QtScript, V4, V8 };
+ DataType dataType;
+
+ int compiledIndex;
+
+ QString rewrittenExpression;
+ BindingContext bindingContext;
+
+ BindingReference *nextReference;
+ };
+
+ struct IdList : public QFieldList<QDeclarativeScript::Object,
+ &QDeclarativeScript::Object::nextIdObject>
+ {
+ QDeclarativeScript::Object *value(const QString &id) const {
+ for (QDeclarativeScript::Object *o = first(); o; o = next(o)) {
+ if (o->id == id)
+ return o;
+ }
+ return 0;
+ }
+ };
+
+ // Contains all the incremental compiler state about a component. As
+ // a single QML file can have multiple components defined, there may be
+ // more than one of these for each compile
+ struct ComponentCompileState : public QDeclarativePool::Class
+ {
+ ComponentCompileState()
+ : parserStatusCount(0), pushedProperties(0), nested(false), v8BindingProgramLine(-1), root(0) {}
+
+ IdList ids;
+ int parserStatusCount;
+ int pushedProperties;
+ bool nested;
+
+ QByteArray compiledBindingData;
+ QString v8BindingProgram;
+ int v8BindingProgramLine;
+ int v8BindingProgramIndex;
+
+ typedef QDeclarativeCompilerTypes::BindingReference B;
+ typedef QFieldList<B, &B::nextReference> BindingReferenceList;
+ BindingReferenceList bindings;
+ typedef QDeclarativeScript::Object O;
+ typedef QFieldList<O, &O::nextAliasingObject> AliasingObjectsList;
+ AliasingObjectsList aliasingObjects;
+ QDeclarativeScript::Object *root;
+ };
+};
+
class QMetaObjectBuilder;
class Q_AUTOTEST_EXPORT QDeclarativeCompiler
{
Q_DECLARE_TR_FUNCTIONS(QDeclarativeCompiler)
public:
- QDeclarativeCompiler();
+ QDeclarativeCompiler(QDeclarativePool *);
bool compile(QDeclarativeEngine *, QDeclarativeTypeData *, QDeclarativeCompiledData *);
bool isError() const;
QList<QDeclarativeError> errors() const;
- static bool isAttachedPropertyName(const QByteArray &);
- static bool isSignalPropertyName(const QByteArray &);
+ static bool isAttachedPropertyName(const QString &);
+ static bool isSignalPropertyName(const QString &);
+ static bool isAttachedPropertyName(const QHashedStringRef &);
+ static bool isSignalPropertyName(const QHashedStringRef &);
int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum
const QMetaObject *resolveType(const QByteArray& name) const; // for QDeclarativeCustomParser::resolveType
- int rewriteBinding(const QString& expression, const QByteArray& name); // for QDeclarativeCustomParser::rewriteBinding
+ int rewriteBinding(const QString& expression, const QString& name); // for QDeclarativeCustomParser::rewriteBinding
private:
static void reset(QDeclarativeCompiledData *);
- struct BindingContext {
- BindingContext()
- : stack(0), owner(0), object(0) {}
- BindingContext(QDeclarativeParser::Object *o)
- : stack(0), owner(0), object(o) {}
- BindingContext incr() const {
- BindingContext rv(object);
- rv.stack = stack + 1;
- return rv;
- }
- bool isSubContext() const { return stack != 0; }
- int stack;
- int owner;
- QDeclarativeParser::Object *object;
- };
-
- void compileTree(QDeclarativeParser::Object *tree);
+ void compileTree(QDeclarativeScript::Object *tree);
- bool buildObject(QDeclarativeParser::Object *obj, const BindingContext &);
- bool buildComponent(QDeclarativeParser::Object *obj, const BindingContext &);
- bool buildSubObject(QDeclarativeParser::Object *obj, const BindingContext &);
- bool buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj,
- const BindingContext &);
- bool buildProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj,
- const BindingContext &);
+ bool buildObject(QDeclarativeScript::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
+ bool buildComponent(QDeclarativeScript::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
+ bool buildSubObject(QDeclarativeScript::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
+ bool buildSignal(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj,
+ const QDeclarativeCompilerTypes::BindingContext &);
+ bool buildProperty(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj,
+ const QDeclarativeCompilerTypes::BindingContext &);
bool buildPropertyInNamespace(QDeclarativeImportedNamespace *ns,
- QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- const BindingContext &);
- bool buildIdProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
- bool buildAttachedProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
- bool buildGroupedProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
+ QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ const QDeclarativeCompilerTypes::BindingContext &);
+ bool buildIdProperty(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj);
+ bool buildAttachedProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool buildGroupedProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
bool buildValueTypeProperty(QObject *type,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Object *baseObj,
- const BindingContext &ctxt);
- bool buildListProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
- bool buildScriptStringProperty(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
- bool buildPropertyAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- const BindingContext &ctxt);
- bool buildPropertyObjectAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Value *value,
- const BindingContext &ctxt);
- bool buildPropertyOnAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Object *baseObj,
- QDeclarativeParser::Value *value,
- const BindingContext &ctxt);
- bool buildPropertyLiteralAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Value *value,
- const BindingContext &ctxt);
- bool doesPropertyExist(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
- bool testLiteralAssignment(const QMetaProperty &prop,
- QDeclarativeParser::Value *value);
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Object *baseObj,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool buildListProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool buildScriptStringProperty(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool buildPropertyAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool buildPropertyObjectAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Value *value,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool buildPropertyOnAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Object *baseObj,
+ QDeclarativeScript::Value *value,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool buildPropertyLiteralAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Value *value,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool doesPropertyExist(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj);
+ bool testLiteralAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Value *value);
bool testQualifiedEnumAssignment(const QMetaProperty &prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Value *value,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Value *value,
bool *isAssignment);
enum DynamicMetaMode { IgnoreAliases, ResolveAliases, ForceCreation };
- bool mergeDynamicMetaProperties(QDeclarativeParser::Object *obj);
- bool buildDynamicMeta(QDeclarativeParser::Object *obj, DynamicMetaMode mode);
- bool checkDynamicMeta(QDeclarativeParser::Object *obj);
- bool buildBinding(QDeclarativeParser::Value *, QDeclarativeParser::Property *prop,
- const BindingContext &ctxt);
- bool buildComponentFromRoot(QDeclarativeParser::Object *obj, const BindingContext &);
- bool compileAlias(QMetaObjectBuilder &,
+ bool mergeDynamicMetaProperties(QDeclarativeScript::Object *obj);
+ bool buildDynamicMeta(QDeclarativeScript::Object *obj, DynamicMetaMode mode);
+ bool checkDynamicMeta(QDeclarativeScript::Object *obj);
+ bool buildBinding(QDeclarativeScript::Value *, QDeclarativeScript::Property *prop,
+ const QDeclarativeCompilerTypes::BindingContext &ctxt);
+ bool buildComponentFromRoot(QDeclarativeScript::Object *obj, const QDeclarativeCompilerTypes::BindingContext &);
+ bool compileAlias(QFastMetaBuilder &,
QByteArray &data,
- QDeclarativeParser::Object *obj,
- const QDeclarativeParser::Object::DynamicProperty &);
+ QDeclarativeScript::Object *obj,
+ int propIndex, int aliasIndex,
+ QDeclarativeScript::Object::DynamicProperty &);
bool completeComponentBuild();
- bool checkValidId(QDeclarativeParser::Value *, const QString &);
-
-
- void genObject(QDeclarativeParser::Object *obj);
- void genObjectBody(QDeclarativeParser::Object *obj);
- void genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *);
- void genComponent(QDeclarativeParser::Object *obj);
- void genValueProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
- void genListProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj);
- void genPropertyAssignment(QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Property *valueTypeProperty = 0);
- void genLiteralAssignment(const QMetaProperty &prop,
- QDeclarativeParser::Value *value);
- void genBindingAssignment(QDeclarativeParser::Value *binding,
- QDeclarativeParser::Property *prop,
- QDeclarativeParser::Object *obj,
- QDeclarativeParser::Property *valueTypeProperty = 0);
+ bool checkValidId(QDeclarativeScript::Value *, const QString &);
+
+
+ void genObject(QDeclarativeScript::Object *obj);
+ void genObjectBody(QDeclarativeScript::Object *obj);
+ void genValueTypeProperty(QDeclarativeScript::Object *obj,QDeclarativeScript::Property *);
+ void genComponent(QDeclarativeScript::Object *obj);
+ void genValueProperty(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj);
+ void genListProperty(QDeclarativeScript::Property *prop, QDeclarativeScript::Object *obj);
+ void genPropertyAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Property *valueTypeProperty = 0);
+ void genLiteralAssignment(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Value *value);
+ void genBindingAssignment(QDeclarativeScript::Value *binding,
+ QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Object *obj,
+ QDeclarativeScript::Property *valueTypeProperty = 0);
int genContextCache();
- int genValueTypeData(QDeclarativeParser::Property *prop, QDeclarativeParser::Property *valueTypeProp);
- int genPropertyData(QDeclarativeParser::Property *prop);
+ int genValueTypeData(QDeclarativeScript::Property *prop, QDeclarativeScript::Property *valueTypeProp);
+ int genPropertyData(QDeclarativeScript::Property *prop);
int componentTypeRef();
- static QDeclarativeType *toQmlType(QDeclarativeParser::Object *from);
- bool canCoerce(int to, QDeclarativeParser::Object *from);
+ static QDeclarativeType *toQmlType(QDeclarativeScript::Object *from);
+ bool canCoerce(int to, QDeclarativeScript::Object *from);
- QStringList deferredProperties(QDeclarativeParser::Object *);
- int indexOfProperty(QDeclarativeParser::Object *, const QByteArray &, bool *notInRevision = 0);
- int indexOfSignal(QDeclarativeParser::Object *, const QByteArray &, bool *notInRevision = 0);
+ QString elementName(QDeclarativeScript::Object *);
- void addId(const QString &, QDeclarativeParser::Object *);
+ QStringList deferredProperties(QDeclarativeScript::Object *);
- void dumpStats();
+ QDeclarativePropertyCache::Data *property(QDeclarativeScript::Object *, int);
+ QDeclarativePropertyCache::Data *property(QDeclarativeScript::Object *, const QHashedStringRef &,
+ bool *notInRevision = 0);
+ QDeclarativePropertyCache::Data *signal(QDeclarativeScript::Object *, const QHashedStringRef &,
+ bool *notInRevision = 0);
+ int indexOfProperty(QDeclarativeScript::Object *, const QHashedStringRef &, bool *notInRevision = 0);
+ int indexOfProperty(QDeclarativeScript::Object *, const QString &, bool *notInRevision = 0);
+ int indexOfSignal(QDeclarativeScript::Object *, const QString &, bool *notInRevision = 0);
- struct BindingReference {
- QDeclarativeParser::Variant expression;
- QDeclarativeParser::Property *property;
- QDeclarativeParser::Value *value;
+ void addId(const QString &, QDeclarativeScript::Object *);
- enum DataType { QtScript, V4, V8 };
- DataType dataType;
+ void dumpStats();
- int compiledIndex;
+ void addBindingReference(QDeclarativeCompilerTypes::BindingReference *);
- QString rewrittenExpression;
- BindingContext bindingContext;
- };
- void addBindingReference(const BindingReference &);
+ QDeclarativeCompilerTypes::ComponentCompileState *compileState;
- struct ComponentCompileState
- {
- ComponentCompileState()
- : parserStatusCount(0), pushedProperties(0), nested(false), v8BindingProgramLine(-1), root(0) {}
- QHash<QString, QDeclarativeParser::Object *> ids;
- QHash<int, QDeclarativeParser::Object *> idIndexes;
- int parserStatusCount;
- int pushedProperties;
- bool nested;
+ QDeclarativePool *pool;
- QByteArray compiledBindingData;
- QString v8BindingProgram;
- int v8BindingProgramLine;
- int v8BindingProgramIndex;
+ QDeclarativeCompilerTypes::ComponentCompileState *componentState(QDeclarativeScript::Object *);
+ void saveComponentState();
+
+ QList<QDeclarativeError> exceptions;
+ QDeclarativeCompiledData *output;
+ QDeclarativeEngine *engine;
+ QDeclarativeEnginePrivate *enginePrivate;
+ QDeclarativeScript::Object *unitRoot;
+ QDeclarativeTypeData *unit;
- QHash<QDeclarativeParser::Value *, BindingReference> bindings;
- QHash<QDeclarativeParser::Value *, BindingContext> signalExpressions;
- QList<QDeclarativeParser::Object *> aliasingObjects;
- QDeclarativeParser::Object *root;
- };
- ComponentCompileState compileState;
+ // Compiler component statistics. Only collected if QML_COMPILER_STATS=1
struct ComponentStat
{
ComponentStat() : ids(0), objects(0) {}
@@ -323,25 +377,18 @@ private:
int lineNumber;
int ids;
- QList<QDeclarativeParser::LocationSpan> scriptBindings;
- QList<QDeclarativeParser::LocationSpan> optimizedBindings;
+ QList<QDeclarativeScript::LocationSpan> scriptBindings;
+ QList<QDeclarativeScript::LocationSpan> optimizedBindings;
int objects;
};
- ComponentStat componentStat;
-
- void saveComponentState();
-
- ComponentCompileState componentState(QDeclarativeParser::Object *);
- QHash<QDeclarativeParser::Object *, ComponentCompileState> savedCompileStates;
- QList<ComponentStat> savedComponentStats;
-
- QList<QDeclarativeError> exceptions;
- QDeclarativeCompiledData *output;
- QDeclarativeEngine *engine;
- QDeclarativeEnginePrivate *enginePrivate;
- QDeclarativeParser::Object *unitRoot;
- QDeclarativeTypeData *unit;
+ struct ComponentStats : public QDeclarativePool::Class
+ {
+ ComponentStat componentStat;
+ QList<ComponentStat> savedComponentStats;
+ };
+ ComponentStats *componentStats;
};
+
QT_END_NAMESPACE
#endif // QDECLARATIVECOMPILER_P_H
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index ca7f3e0f74..eea94cef3e 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -51,7 +51,7 @@
#include "private/qdeclarativebinding_p.h"
#include "private/qdeclarativebinding_p_p.h"
#include "private/qdeclarativeglobal_p.h"
-#include "private/qdeclarativescriptparser_p.h"
+#include "private/qdeclarativescript_p.h"
#include "private/qdeclarativedebugtrace_p.h"
#include "private/qdeclarativeenginedebug_p.h"
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 5f4072130a..9a068bbf8d 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -60,7 +60,7 @@
#include "private/qdeclarativetypenamecache_p.h"
#include "private/qdeclarativenotifier_p.h"
#include "qdeclarativelist.h"
-#include "private/qdeclarativeparser_p.h"
+#include "private/qdeclarativescript_p.h"
#include <QtCore/qhash.h>
#include <QtDeclarative/qjsvalue.h>
diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp
index e80d911bb5..e806707a06 100644
--- a/src/declarative/qml/qdeclarativecustomparser.cpp
+++ b/src/declarative/qml/qdeclarativecustomparser.cpp
@@ -42,14 +42,13 @@
#include "private/qdeclarativecustomparser_p.h"
#include "private/qdeclarativecustomparser_p_p.h"
-#include "private/qdeclarativeparser_p.h"
#include "private/qdeclarativecompiler_p.h"
#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
-using namespace QDeclarativeParser;
+using namespace QDeclarativeScript;
/*!
\class QDeclarativeCustomParser
@@ -95,18 +94,13 @@ using namespace QDeclarativeParser;
*/
QDeclarativeCustomParserNode
-QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeParser::Object *root)
+QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeScript::Object *root)
{
QDeclarativeCustomParserNode rootNode;
rootNode.d->name = root->typeName;
rootNode.d->location = root->location.start;
- for(QHash<QByteArray, Property *>::Iterator iter = root->properties.begin();
- iter != root->properties.end();
- ++iter) {
-
- Property *p = *iter;
-
+ for (Property *p = root->properties.first(); p; p = root->properties.next(p)) {
rootNode.d->properties << fromProperty(p);
}
@@ -117,11 +111,11 @@ QDeclarativeCustomParserNodePrivate::fromObject(QDeclarativeParser::Object *root
}
QDeclarativeCustomParserProperty
-QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeParser::Property *p)
+QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeScript::Property *p)
{
QDeclarativeCustomParserProperty prop;
- prop.d->name = p->name;
- prop.d->isList = (p->values.count() > 1);
+ prop.d->name = p->name().toUtf8();
+ prop.d->isList = p->values.isMany();
prop.d->location = p->location.start;
if (p->value) {
@@ -130,9 +124,8 @@ QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeParser::Property *
for (int ii = 0; ii < props.count(); ++ii)
prop.d->values << QVariant::fromValue(props.at(ii));
} else {
- for(int ii = 0; ii < p->values.count(); ++ii) {
- QDeclarativeParser::Value *v = p->values.at(ii);
- v->type = QDeclarativeParser::Value::Literal;
+ for (QDeclarativeScript::Value *v = p->values.first(); v; v = p->values.next(v)) {
+ v->type = QDeclarativeScript::Value::Literal;
if(v->object) {
QDeclarativeCustomParserNode node = fromObject(v->object);
@@ -181,7 +174,7 @@ QList<QDeclarativeCustomParserProperty> QDeclarativeCustomParserNode::properties
return d->properties;
}
-QDeclarativeParser::Location QDeclarativeCustomParserNode::location() const
+QDeclarativeScript::Location QDeclarativeCustomParserNode::location() const
{
return d->location;
}
@@ -221,7 +214,7 @@ bool QDeclarativeCustomParserProperty::isList() const
return d->isList;
}
-QDeclarativeParser::Location QDeclarativeCustomParserProperty::location() const
+QDeclarativeScript::Location QDeclarativeCustomParserProperty::location() const
{
return d->location;
}
diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h
index 31452836bd..47b3ee8f8e 100644
--- a/src/declarative/qml/qdeclarativecustomparser_p.h
+++ b/src/declarative/qml/qdeclarativecustomparser_p.h
@@ -55,7 +55,7 @@
#include "private/qdeclarativemetatype_p.h"
#include "qdeclarativeerror.h"
-#include "private/qdeclarativeparser_p.h"
+#include "private/qdeclarativescript_p.h"
#include "private/qdeclarativebinding_p.h"
#include <QtCore/qbytearray.h>
@@ -79,10 +79,10 @@ public:
~QDeclarativeCustomParserProperty();
QByteArray name() const;
- QDeclarativeParser::Location location() const;
+ QDeclarativeScript::Location location() const;
bool isList() const;
- // Will be one of QDeclarativeParser::Variant, QDeclarativeCustomParserProperty or
+ // Will be one of QDeclarativeScript::Variant, QDeclarativeCustomParserProperty or
// QDeclarativeCustomParserNode
QList<QVariant> assignedValues() const;
@@ -102,7 +102,7 @@ public:
~QDeclarativeCustomParserNode();
QByteArray name() const;
- QDeclarativeParser::Location location() const;
+ QDeclarativeScript::Location location() const;
QList<QDeclarativeCustomParserProperty> properties() const;
@@ -147,7 +147,7 @@ protected:
private:
QList<QDeclarativeError> exceptions;
QDeclarativeCompiler *compiler;
- QDeclarativeParser::Object *object;
+ QDeclarativeScript::Object *object;
Flags m_flags;
friend class QDeclarativeCompiler;
};
diff --git a/src/declarative/qml/qdeclarativecustomparser_p_p.h b/src/declarative/qml/qdeclarativecustomparser_p_p.h
index 386dd96bb4..b11cb3432d 100644
--- a/src/declarative/qml/qdeclarativecustomparser_p_p.h
+++ b/src/declarative/qml/qdeclarativecustomparser_p_p.h
@@ -55,7 +55,7 @@
#include "private/qdeclarativecustomparser_p.h"
-#include "private/qdeclarativeparser_p.h"
+#include "private/qdeclarativescript_p.h"
#include <QtCore/qglobal.h>
@@ -66,10 +66,10 @@ class QDeclarativeCustomParserNodePrivate
public:
QByteArray name;
QList<QDeclarativeCustomParserProperty> properties;
- QDeclarativeParser::Location location;
+ QDeclarativeScript::Location location;
- static QDeclarativeCustomParserNode fromObject(QDeclarativeParser::Object *);
- static QDeclarativeCustomParserProperty fromProperty(QDeclarativeParser::Property *);
+ static QDeclarativeCustomParserNode fromObject(QDeclarativeScript::Object *);
+ static QDeclarativeCustomParserProperty fromProperty(QDeclarativeScript::Property *);
};
class QDeclarativeCustomParserPropertyPrivate
@@ -80,7 +80,7 @@ public:
QByteArray name;
bool isList;
- QDeclarativeParser::Location location;
+ QDeclarativeScript::Location location;
QList<QVariant> values;
};
diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp
index ba7aca038d..49cb40f654 100644
--- a/src/declarative/qml/qdeclarativedirparser.cpp
+++ b/src/declarative/qml/qdeclarativedirparser.cpp
@@ -41,8 +41,11 @@
#include "private/qdeclarativedirparser_p.h"
#include "qdeclarativeerror.h"
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativeutils_p.h>
#include <QtCore/QTextStream>
+#include <QtCore/QFile>
#include <QtCore/QtDebug>
QT_BEGIN_NAMESPACE
@@ -66,6 +69,16 @@ void QDeclarativeDirParser::setUrl(const QUrl &url)
_url = url;
}
+QString QDeclarativeDirParser::fileSource() const
+{
+ return _filePathSouce;
+}
+
+void QDeclarativeDirParser::setFileSource(const QString &filePath)
+{
+ _filePathSouce = filePath;
+}
+
QString QDeclarativeDirParser::source() const
{
return _source;
@@ -92,6 +105,23 @@ bool QDeclarativeDirParser::parse()
_plugins.clear();
_components.clear();
+ if (_source.isEmpty() && !_filePathSouce.isEmpty()) {
+ QFile file(_filePathSouce);
+ if (!QDeclarative_isFileCaseCorrect(_filePathSouce)) {
+ QDeclarativeError error;
+ error.setDescription(QString::fromUtf8("cannot load module \"$$URI$$\": File name case mismatch for \"%1\"").arg(_filePathSouce));
+ _errors.prepend(error);
+ return false;
+ } else if (file.open(QFile::ReadOnly)) {
+ _source = QString::fromUtf8(file.readAll());
+ } else {
+ QDeclarativeError error;
+ error.setDescription(QString::fromUtf8("module \"$$URI$$\" definition \"%1\" not readable").arg(_filePathSouce));
+ _errors.prepend(error);
+ return false;
+ }
+ }
+
QTextStream stream(&_source);
int lineNumber = 0;
@@ -111,9 +141,9 @@ bool QDeclarativeDirParser::parse()
while (index != length) {
const QChar ch = line.at(index);
- if (ch.isSpace()) {
+ if (QDeclarativeUtils::isSpace(ch)) {
do { ++index; }
- while (index != length && line.at(index).isSpace());
+ while (index != length && QDeclarativeUtils::isSpace(line.at(index)));
} else if (ch == QLatin1Char('#')) {
// recognized a comment
@@ -123,7 +153,7 @@ bool QDeclarativeDirParser::parse()
const int start = index;
do { ++index; }
- while (index != length && !line.at(index).isSpace());
+ while (index != length && !QDeclarativeUtils::isSpace(line.at(index)));
const QString lexeme = line.mid(start, index - start);
@@ -157,7 +187,7 @@ bool QDeclarativeDirParser::parse()
QString::fromUtf8("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1));
continue;
}
- Component entry(sections[1], sections[2], -1, -1);
+ Component entry(sections[1].toUtf8(), sections[2], -1, -1);
entry.internal = true;
_components.append(entry);
} else if (sections[0] == QLatin1String("typeinfo")) {
@@ -173,7 +203,7 @@ bool QDeclarativeDirParser::parse()
} else if (sectionCount == 2) {
// No version specified (should only be used for relative qmldir files)
- const Component entry(sections[0], sections[1], -1, -1);
+ const Component entry(sections[0].toUtf8(), sections[1], -1, -1);
_components.append(entry);
} else if (sectionCount == 3) {
const QString &version = sections[1];
@@ -191,7 +221,7 @@ bool QDeclarativeDirParser::parse()
const int minorVersion = version.mid(dotIndex + 1).toInt(&validVersionNumber);
if (validVersionNumber) {
- const Component entry(sections[0], sections[2], majorVersion, minorVersion);
+ const Component entry(sections[0].toUtf8(), sections[2], majorVersion, minorVersion);
_components.append(entry);
}
@@ -224,9 +254,16 @@ bool QDeclarativeDirParser::hasError() const
return false;
}
-QList<QDeclarativeError> QDeclarativeDirParser::errors() const
+QList<QDeclarativeError> QDeclarativeDirParser::errors(const QString &uri) const
{
- return _errors;
+ QList<QDeclarativeError> errors = _errors;
+ for (int i = 0; i < errors.size(); ++i) {
+ QDeclarativeError &e = errors[i];
+ QString description = e.description();
+ description.replace(QLatin1String("$$URI$$"), uri);
+ e.setDescription(description);
+ }
+ return errors;
}
QList<QDeclarativeDirParser::Plugin> QDeclarativeDirParser::plugins() const
diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h
index d40833ac45..8540747055 100644
--- a/src/declarative/qml/qdeclarativedirparser_p.h
+++ b/src/declarative/qml/qdeclarativedirparser_p.h
@@ -70,6 +70,9 @@ public:
QUrl url() const;
void setUrl(const QUrl &url);
+ QString fileSource() const;
+ void setFileSource(const QString &filePath);
+
QString source() const;
void setSource(const QString &source);
@@ -77,7 +80,7 @@ public:
bool parse();
bool hasError() const;
- QList<QDeclarativeError> errors() const;
+ QList<QDeclarativeError> errors(const QString &uri) const;
struct Plugin
{
@@ -95,11 +98,11 @@ public:
Component()
: majorVersion(0), minorVersion(0), internal(false) {}
- Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
+ Component(const QByteArray &typeName, const QString &fileName, int majorVersion, int minorVersion)
: typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
internal(false) {}
- QString typeName;
+ QByteArray typeName;
QString fileName;
int majorVersion;
int minorVersion;
@@ -129,6 +132,7 @@ private:
QList<QDeclarativeError> _errors;
QUrl _url;
QString _source;
+ QString _filePathSouce;
QList<Component> _components;
QList<Plugin> _plugins;
#ifdef QT_CREATOR
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 1906612e8a..051739be59 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -1126,6 +1126,34 @@ QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
return url.toLocalFile();
}
+
+static QString toLocalFile(const QString &url)
+{
+ if (!url.startsWith(QLatin1String("file://"), Qt::CaseInsensitive))
+ return QString();
+
+ QString file = url.mid(7);
+
+ //XXX TODO: handle windows hostnames: "//servername/path/to/file.txt"
+
+ // magic for drives on windows
+ if (file.length() > 2 && file.at(0) == QLatin1Char('/') && file.at(2) == QLatin1Char(':'))
+ file.remove(0, 1);
+
+ return file;
+}
+
+QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QString& url)
+{
+ if (url.startsWith(QLatin1String("qrc:"), Qt::CaseInsensitive)) {
+ if (url.length() > 4)
+ return QLatin1Char(':') + url.mid(4);
+ return QString();
+ }
+
+ return toLocalFile(url);
+}
+
void QDeclarativeEnginePrivate::sendQuit()
{
Q_Q(QDeclarativeEngine);
@@ -1424,7 +1452,9 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObj
return rv;
} else {
QDeclarativePropertyCache *super = cache(mo->superClass());
- QDeclarativePropertyCache *rv = super->copy();
+ QDeclarativePropertyCache *rv = super->copy(mo->propertyCount() + mo->methodCount() -
+ mo->superClass()->propertyCount() -
+ mo->superClass()->methodCount());
rv->append(q, mo);
propertyCache.insert(mo, rv);
return rv;
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index 6ff12189da..be4f714545 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -262,6 +262,7 @@ public:
static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); }
static QString urlToLocalFileOrQrc(const QUrl& url);
+ static QString urlToLocalFileOrQrc(const QString& url);
static void registerBaseTypes(const char *uri, int versionMajor, int versionMinor);
static void defineModule();
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp
index 8806996bd4..a24d46914c 100644
--- a/src/declarative/qml/qdeclarativeexpression.cpp
+++ b/src/declarative/qml/qdeclarativeexpression.cpp
@@ -242,7 +242,7 @@ QDeclarativeExpression::QDeclarativeExpression(const QDeclarativeScriptString &s
} else {
QDeclarativeContextData *ctxtdata = QDeclarativeContextData::get(script.context());
- QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(qmlEngine(script.scopeObject()));
+ QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(script.context()->engine());
QDeclarativeCompiledData *cdata = 0;
QDeclarativeTypeData *typeData = 0;
if (engine && ctxtdata && !ctxtdata->url.isEmpty()) {
@@ -251,7 +251,7 @@ QDeclarativeExpression::QDeclarativeExpression(const QDeclarativeScriptString &s
}
if (cdata)
- d->init(ctxtdata, cdata->primitives.at(id), cdata, script.scopeObject(),
+ d->init(ctxtdata, cdata->primitives.at(id), true, script.scopeObject(),
cdata->name, script.d.data()->lineNumber);
else
defaultConstruction = true;
diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp
index b2fa071f91..0c0719a710 100644
--- a/src/declarative/qml/qdeclarativeimport.cpp
+++ b/src/declarative/qml/qdeclarativeimport.cpp
@@ -65,30 +65,53 @@ static bool greaterThan(const QString &s1, const QString &s2)
return s1 > s2;
}
+QString resolveLocalUrl(const QString &url, const QString &relative)
+{
+ if (relative.contains(QLatin1Char(':'))) {
+ // contains a host name
+ return QUrl(url).resolved(QUrl(relative)).toString();
+ } else if (relative.isEmpty()) {
+ return url;
+ } else if (relative.at(0) == QLatin1Char('/') || !url.contains(QLatin1Char('/'))) {
+ return relative;
+ } else {
+ if (relative == QLatin1String("."))
+ return url.left(url.lastIndexOf(QLatin1Char('/')) + 1);
+ else if (relative.startsWith(QLatin1String("./")))
+ return url.left(url.lastIndexOf(QLatin1Char('/')) + 1) + relative.mid(2);
+ return url.left(url.lastIndexOf(QLatin1Char('/')) + 1) + relative;
+ }
+}
+
+
+
typedef QMap<QString, QString> StringStringMap;
Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri
class QDeclarativeImportedNamespace
{
public:
- QStringList uris;
- QStringList urls;
- QList<int> majversions;
- QList<int> minversions;
- QList<bool> isLibrary;
- QList<QDeclarativeDirComponents> qmlDirComponents;
-
-
- bool find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
- QDeclarativeType** type_return, QUrl* url_return,
- QUrl *base = 0, bool *typeRecursionDetected = 0);
- bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
- QUrl* url_return, QUrl *base = 0, QList<QDeclarativeError> *errors = 0);
+ struct Data {
+ QString uri;
+ QString url;
+ int majversion;
+ int minversion;
+ bool isLibrary;
+ QDeclarativeDirComponents qmlDirComponents;
+ };
+ QList<Data> imports;
+
+
+ bool find_helper(QDeclarativeTypeLoader *typeLoader, const Data &data, const QString& type, int *vmajor, int *vminor,
+ QDeclarativeType** type_return, QString* url_return,
+ QString *base = 0, bool *typeRecursionDetected = 0);
+ bool find(QDeclarativeTypeLoader *typeLoader, const QString& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
+ QString* url_return, QString *base = 0, QList<QDeclarativeError> *errors = 0);
};
class QDeclarativeImportsPrivate {
public:
- QDeclarativeImportsPrivate();
+ QDeclarativeImportsPrivate(QDeclarativeTypeLoader *loader);
~QDeclarativeImportsPrivate();
bool importExtension(const QString &absoluteFilePath, const QString &uri,
@@ -98,19 +121,21 @@ public:
QString resolvedUri(const QString &dir_arg, QDeclarativeImportDatabase *database);
bool add(const QDeclarativeDirComponents &qmldircomponentsnetwork,
const QString& uri_arg, const QString& prefix,
- int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType,
+ int vmaj, int vmin, QDeclarativeScript::Import::Type importType,
QDeclarativeImportDatabase *database, QList<QDeclarativeError> *errors);
- bool find(const QByteArray& type, int *vmajor, int *vminor,
- QDeclarativeType** type_return, QUrl* url_return, QList<QDeclarativeError> *errors);
+ bool find(const QString& type, int *vmajor, int *vminor,
+ QDeclarativeType** type_return, QString* url_return, QList<QDeclarativeError> *errors);
QDeclarativeImportedNamespace *findNamespace(const QString& type);
- QUrl base;
+ QUrl baseUrl;
+ QString base;
int ref;
QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
QDeclarativeImportedNamespace unqualifiedset;
QHash<QString,QDeclarativeImportedNamespace* > set;
+ QDeclarativeTypeLoader *typeLoader;
};
/*!
@@ -134,8 +159,8 @@ QDeclarativeImports::operator =(const QDeclarativeImports &copy)
return *this;
}
-QDeclarativeImports::QDeclarativeImports()
-: d(new QDeclarativeImportsPrivate)
+QDeclarativeImports::QDeclarativeImports(QDeclarativeTypeLoader *typeLoader)
+ : d(new QDeclarativeImportsPrivate(typeLoader))
{
}
@@ -150,7 +175,8 @@ QDeclarativeImports::~QDeclarativeImports()
*/
void QDeclarativeImports::setBaseUrl(const QUrl& url)
{
- d->base = url;
+ d->baseUrl = url;
+ d->base = url.toString();
}
/*!
@@ -158,25 +184,33 @@ void QDeclarativeImports::setBaseUrl(const QUrl& url)
*/
QUrl QDeclarativeImports::baseUrl() const
{
- return d->base;
+ return d->baseUrl;
}
-static QDeclarativeTypeNameCache *
-cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeImportedNamespace &set,
- QDeclarativeTypeNameCache *cache, bool importWasQualified)
+void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const
{
- if (!cache)
- cache = new QDeclarativeTypeNameCache(engine);
-
- QList<QDeclarativeType *> types = QDeclarativeMetaType::qmlTypes();
+ const QDeclarativeImportedNamespace &set = d->unqualifiedset;
- for (int ii = 0; ii < set.uris.count(); ++ii) {
- QByteArray uri = set.uris.at(ii).toUtf8();
- int major = set.majversions.at(ii);
- int minor = set.minversions.at(ii);
+ for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ const QDeclarativeImportedNamespace::Data &data = set.imports.at(ii);
+ QDeclarativeTypeModule *module = QDeclarativeMetaType::typeModule(data.uri, data.majversion);
+ if (module)
+ cache->m_anonymousImports.append(QDeclarativeTypeModuleVersion(module, data.minversion));
+ }
- if (importWasQualified) {
- QDeclarativeMetaType::ModuleApi moduleApi = QDeclarativeMetaType::moduleApi(uri, major, minor);
+ for (QHash<QString,QDeclarativeImportedNamespace* >::ConstIterator iter = d->set.begin();
+ iter != d->set.end();
+ ++iter) {
+
+ const QDeclarativeImportedNamespace &set = *iter.value();
+ QDeclarativeTypeNameCache::Import &import = cache->m_namedImports[iter.key()];
+ for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
+ const QDeclarativeImportedNamespace::Data &data = set.imports.at(ii);
+ QDeclarativeTypeModule *module = QDeclarativeMetaType::typeModule(data.uri, data.majversion);
+ if (module)
+ import.modules.append(QDeclarativeTypeModuleVersion(module, data.minversion));
+
+ QDeclarativeMetaType::ModuleApi moduleApi = QDeclarativeMetaType::moduleApi(data.uri.toUtf8(), data.majversion, data.minversion);
if (moduleApi.script || moduleApi.qobject) {
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
QDeclarativeMetaType::ModuleApiInstance *a = ep->moduleApiInstances.value(moduleApi);
@@ -186,46 +220,12 @@ cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeImportedNamespac
a->qobjectCallback = moduleApi.qobject;
ep->moduleApiInstances.insert(moduleApi, a);
}
- cache->setModuleApi(a);
- }
- }
-
- QByteArray base = uri + '/';
-
- foreach (QDeclarativeType *type, types) {
- if (type->qmlTypeName().startsWith(base) &&
- type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) &&
- (major < 0 || type->availableInVersion(major,minor)))
- {
- QString name = QString::fromUtf8(type->qmlTypeName().mid(base.length()));
-
- cache->add(name, type);
+ import.moduleApi = a;
}
}
}
- return cache;
-}
-
-void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const
-{
- const QDeclarativeImportedNamespace &set = d->unqualifiedset;
-
- for (QHash<QString,QDeclarativeImportedNamespace* >::ConstIterator iter = d->set.begin();
- iter != d->set.end(); ++iter) {
- QDeclarativeTypeNameCache::Data *d = cache->data(iter.key());
- if (d) {
- if (!d->typeNamespace)
- cacheForNamespace(engine, *(*iter), d->typeNamespace, true);
- } else {
- QDeclarativeTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0, true);
- cache->add(iter.key(), nc);
- nc->release();
- }
- }
-
- cacheForNamespace(engine, set, cache, false);
}
/*!
@@ -242,11 +242,11 @@ void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDecla
\sa addImport()
*/
-bool QDeclarativeImports::resolveType(const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin,
+bool QDeclarativeImports::resolveType(const QString& type,
+ QDeclarativeType** type_return, QString* url_return, int *vmaj, int *vmin,
QDeclarativeImportedNamespace** ns_return, QList<QDeclarativeError> *errors) const
{
- QDeclarativeImportedNamespace* ns = d->findNamespace(QString::fromUtf8(type));
+ QDeclarativeImportedNamespace* ns = d->findNamespace(type);
if (ns) {
if (ns_return)
*ns_return = ns;
@@ -281,25 +281,22 @@ bool QDeclarativeImports::resolveType(const QByteArray& type,
If either return pointer is 0, the corresponding search is not done.
*/
-bool QDeclarativeImports::resolveType(QDeclarativeImportedNamespace* ns, const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return,
+bool QDeclarativeImports::resolveType(QDeclarativeImportedNamespace* ns, const QString& type,
+ QDeclarativeType** type_return, QString* url_return,
int *vmaj, int *vmin) const
{
- return ns->find(type,vmaj,vmin,type_return,url_return);
+ return ns->find(d->typeLoader,type,vmaj,vmin,type_return,url_return);
}
-bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
- QDeclarativeType** type_return, QUrl* url_return,
- QUrl *base, bool *typeRecursionDetected)
+bool QDeclarativeImportedNamespace::find_helper(QDeclarativeTypeLoader *typeLoader, const Data &data, const QString& type, int *vmajor, int *vminor,
+ QDeclarativeType** type_return, QString* url_return,
+ QString *base, bool *typeRecursionDetected)
{
- int vmaj = majversions.at(i);
- int vmin = minversions.at(i);
+ int vmaj = data.majversion;
+ int vmin = data.minversion;
if (vmaj >= 0 && vmin >= 0) {
- QByteArray qt = uris.at(i).toUtf8();
- qt += '/';
- qt += type;
-
+ QString qt = data.uri + QLatin1Char('/') + type;
QDeclarativeType *t = QDeclarativeMetaType::qmlType(qt,vmaj,vmin);
if (t) {
if (vmajor) *vmajor = vmaj;
@@ -310,21 +307,18 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i
}
}
- QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml"));
- QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i);
-
+ const QDeclarativeDirComponents &qmldircomponents = data.qmlDirComponents;
bool typeWasDeclaredInQmldir = false;
if (!qmldircomponents.isEmpty()) {
- const QString typeName = QString::fromUtf8(type);
foreach (const QDeclarativeDirParser::Component &c, qmldircomponents) {
- if (c.typeName == typeName) {
+ if (c.typeName == type) {
typeWasDeclaredInQmldir = true;
-
// importing version -1 means import ALL versions
if ((vmaj == -1) || (c.majorVersion == vmaj && vmin >= c.minorVersion)) {
- QUrl candidate = url.resolved(QUrl(c.fileName));
+ QString url(data.url + type + QLatin1String(".qml"));
+ QString candidate = resolveLocalUrl(url, c.fileName);
if (c.internal && base) {
- if (base->resolved(QUrl(c.fileName)) != candidate)
+ if (resolveLocalUrl(*base, c.fileName) != candidate)
continue; // failed attempt to access an internal type
}
if (base && *base == candidate) {
@@ -340,10 +334,11 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i
}
}
- if (!typeWasDeclaredInQmldir && !isLibrary.at(i)) {
+ if (!typeWasDeclaredInQmldir && !data.isLibrary) {
// XXX search non-files too! (eg. zip files, see QT-524)
- QFileInfo f(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url));
- if (f.exists()) {
+ QString url(data.url + type + QLatin1String(".qml"));
+ QString file = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
+ if (!typeLoader->absoluteFilePath(file).isEmpty()) {
if (base && *base == url) { // no recursion
if (typeRecursionDetected)
*typeRecursionDetected = true;
@@ -357,8 +352,8 @@ bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, i
return false;
}
-QDeclarativeImportsPrivate::QDeclarativeImportsPrivate()
-: ref(1)
+QDeclarativeImportsPrivate::QDeclarativeImportsPrivate(QDeclarativeTypeLoader *loader)
+ : ref(1), typeLoader(loader)
{
}
@@ -372,52 +367,30 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath
QDeclarativeImportDatabase *database,
QDeclarativeDirComponents* components, QList<QDeclarativeError> *errors)
{
- QFile file(absoluteFilePath);
- QString filecontent;
- if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
+ const QDeclarativeDirParser *qmldirParser = typeLoader->qmlDirParser(absoluteFilePath);
+ if (qmldirParser->hasError()) {
if (errors) {
- QDeclarativeError error;
- error.setDescription(QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath));
- errors->prepend(error);
- }
- return false;
- } else if (file.open(QFile::ReadOnly)) {
- filecontent = QString::fromUtf8(file.readAll());
- if (qmlImportTrace())
- qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: "
- << "loaded " << absoluteFilePath;
- } else {
- if (errors) {
- QDeclarativeError error;
- error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath));
- errors->prepend(error);
+ const QList<QDeclarativeError> qmldirErrors = qmldirParser->errors(uri);
+ for (int i = 0; i < qmldirErrors.size(); ++i)
+ errors->prepend(qmldirErrors.at(i));
}
return false;
}
- QDir dir = QFileInfo(file).dir();
- QUrl url = QUrl::fromLocalFile(absoluteFilePath);
-
- QDeclarativeDirParser qmldirParser;
- qmldirParser.setSource(filecontent);
- qmldirParser.setUrl(url);
- // propagate any errors reported by the parser back up to the typeloader.
- if (qmldirParser.parse()) {
- if (errors) {
- for (int i = 0; i < qmldirParser.errors().size(); ++i) {
- errors->prepend(qmldirParser.errors().at(i));
- }
- }
- return false;
- }
+ if (qmlImportTrace())
+ qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base) << "::importExtension: "
+ << "loaded " << absoluteFilePath;
if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) {
qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath);
+ QString qmldirPath = absoluteFilePath;
+ int slash = absoluteFilePath.lastIndexOf(QLatin1Char('/'));
+ if (slash > 0)
+ qmldirPath.truncate(slash);
+ foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser->plugins()) {
- foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) {
-
- QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name);
+ QString resolvedFilePath = database->resolvePlugin(typeLoader, qmldirPath, plugin.path, plugin.name);
#if defined(QT_LIBINFIX) && defined(Q_OS_SYMBIAN)
if (resolvedFilePath.isEmpty()) {
// In case of libinfixed build, attempt to load libinfixed version, too.
@@ -434,7 +407,7 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath
QDeclarativeError poppedError = errors->takeFirst();
QDeclarativeError error;
error.setDescription(QDeclarativeImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(poppedError.description()));
- error.setUrl(url);
+ error.setUrl(QUrl::fromLocalFile(absoluteFilePath));
errors->prepend(error);
}
return false;
@@ -443,7 +416,7 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath
if (errors) {
QDeclarativeError error;
error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name));
- error.setUrl(url);
+ error.setUrl(QUrl::fromLocalFile(absoluteFilePath));
errors->prepend(error);
}
return false;
@@ -452,7 +425,7 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath
}
if (components)
- *components = qmldirParser.components();
+ *components = qmldirParser->components();
return true;
}
@@ -490,9 +463,12 @@ QString QDeclarativeImportsPrivate::resolvedUri(const QString &dir_arg, QDeclara
bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomponentsnetwork,
const QString& uri_arg, const QString& prefix, int vmaj, int vmin,
- QDeclarativeScriptParser::Import::Type importType,
+ QDeclarativeScript::Import::Type importType,
QDeclarativeImportDatabase *database, QList<QDeclarativeError> *errors)
{
+ static QLatin1String Slash_qmldir("/qmldir");
+ static QLatin1Char Slash('/');
+
QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork;
QString uri = uri_arg;
QDeclarativeImportedNamespace *s;
@@ -505,18 +481,18 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
}
QString url = uri;
bool versionFound = false;
- if (importType == QDeclarativeScriptParser::Import::Library) {
+ if (importType == QDeclarativeScript::Import::Library) {
Q_ASSERT(vmaj >= 0 && vmin >= 0); // Versions are always specified for libraries
- url.replace(QLatin1Char('.'), QLatin1Char('/'));
+ url.replace(QLatin1Char('.'), Slash);
bool found = false;
QString dir;
-
+ QString qmldir;
// step 1: search for extension with fully encoded version number
foreach (const QString &p, database->fileImportPath) {
- dir = p+QLatin1Char('/')+url;
+ dir = p+Slash+url;
QFileInfo fi(dir+QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin)+QLatin1String("/qmldir"));
const QString absoluteFilePath = fi.absoluteFilePath();
@@ -534,7 +510,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
// step 2: search for extension with encoded version major
foreach (const QString &p, database->fileImportPath) {
- dir = p+QLatin1Char('/')+url;
+ dir = p+Slash+url;
QFileInfo fi(dir+QString(QLatin1String(".%1")).arg(vmaj)+QLatin1String("/qmldir"));
const QString absoluteFilePath = fi.absoluteFilePath();
@@ -554,15 +530,14 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
// step 3: search for extension without version number
foreach (const QString &p, database->fileImportPath) {
- dir = p+QLatin1Char('/')+url;
+ dir = p+Slash+url;
+ qmldir = dir+Slash_qmldir;
- QFileInfo fi(dir+QLatin1String("/qmldir"));
- const QString absoluteFilePath = fi.absoluteFilePath();
-
- if (fi.isFile()) {
+ QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir);
+ if (!absoluteFilePath.isEmpty()) {
found = true;
-
- url = QUrl::fromLocalFile(fi.absolutePath()).toString();
+ QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(Slash)+1);
+ url = QLatin1String("file://") + absolutePath;
uri = resolvedUri(dir, database);
if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errors))
return false;
@@ -571,15 +546,13 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
}
}
- if (QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin)) {
+ if (QDeclarativeMetaType::isModule(uri, vmaj, vmin))
versionFound = true;
- }
if (!versionFound && qmldircomponents.isEmpty()) {
if (errors) {
- bool anyversion = QDeclarativeMetaType::isAnyModule(uri.toUtf8());
QDeclarativeError error; // we don't set the url or line or column as these will be set by the loader.
- if (anyversion)
+ if (QDeclarativeMetaType::isAnyModule(uri))
error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin));
else
error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg));
@@ -588,42 +561,39 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
return false;
}
} else {
-
- if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) {
- QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir")));
+ if (importType == QDeclarativeScript::Import::File && qmldircomponents.isEmpty()) {
+ QString importUrl = resolveLocalUrl(base, uri + Slash_qmldir);
QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl);
if (!localFileOrQrc.isEmpty()) {
- QString dir = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
- QFileInfo dirinfo(dir);
- if (dir.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
+ QString dir = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(resolveLocalUrl(base, uri));
+ if (!typeLoader->directoryExists(dir)) {
if (errors) {
QDeclarativeError error; // we don't set the line or column as these will be set by the loader.
error.setDescription(QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri_arg));
- error.setUrl(importUrl);
+ error.setUrl(QUrl(importUrl));
errors->prepend(error);
}
return false; // local import dirs must exist
}
- uri = resolvedUri(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri))), database);
- if (uri.endsWith(QLatin1Char('/')))
+ uri = resolvedUri(dir, database);
+ if (uri.endsWith(Slash))
uri.chop(1);
- if (QFile::exists(localFileOrQrc)) {
+ if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) {
if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errors))
return false;
}
} else {
if (prefix.isEmpty()) {
// directory must at least exist for valid import
- QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
- QFileInfo dirinfo(localFileOrQrc);
- if (localFileOrQrc.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
+ QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(resolveLocalUrl(base, uri));
+ if (!typeLoader->directoryExists(localFileOrQrc)) {
if (errors) {
QDeclarativeError error; // we don't set the line or column as these will be set by the loader.
if (localFileOrQrc.isEmpty())
error.setDescription(QDeclarativeImportDatabase::tr("import \"%1\" has no qmldir and no namespace").arg(uri));
else
error.setDescription(QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri));
- error.setUrl(importUrl);
+ error.setUrl(QUrl(importUrl));
errors->prepend(error);
}
return false;
@@ -632,9 +602,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
}
}
- url = base.resolved(QUrl(url)).toString();
- if (url.endsWith(QLatin1Char('/')))
- url.chop(1);
+ url = resolveLocalUrl(base, url);
}
if (!versionFound && vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) {
@@ -657,22 +625,28 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
}
}
- s->uris.prepend(uri);
- s->urls.prepend(url);
- s->majversions.prepend(vmaj);
- s->minversions.prepend(vmin);
- s->isLibrary.prepend(importType == QDeclarativeScriptParser::Import::Library);
- s->qmlDirComponents.prepend(qmldircomponents);
+ if (!url.endsWith(Slash))
+ url += Slash;
+
+ QDeclarativeImportedNamespace::Data data;
+ data.uri = uri;
+ data.url = url;
+ data.majversion = vmaj;
+ data.minversion = vmin;
+ data.isLibrary = importType == QDeclarativeScript::Import::Library;
+ data.qmlDirComponents = qmldircomponents;
+ s->imports.prepend(data);
+
return true;
}
-bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
- QUrl* url_return, QList<QDeclarativeError> *errors)
+bool QDeclarativeImportsPrivate::find(const QString& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
+ QString* url_return, QList<QDeclarativeError> *errors)
{
QDeclarativeImportedNamespace *s = 0;
- int slash = type.indexOf('/');
+ int slash = type.indexOf(QLatin1Char('/'));
if (slash >= 0) {
- QString namespaceName = QString::fromUtf8(type.left(slash));
+ QString namespaceName = type.left(slash);
s = set.value(namespaceName);
if (!s) {
if (errors) {
@@ -682,7 +656,7 @@ bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *
}
return false;
}
- int nslash = type.indexOf('/',slash+1);
+ int nslash = type.indexOf(QLatin1Char('/'),slash+1);
if (nslash > 0) {
if (errors) {
QDeclarativeError error;
@@ -694,13 +668,13 @@ bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *
} else {
s = &unqualifiedset;
}
- QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
+ QString unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
if (s) {
- if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errors))
+ if (s->find(typeLoader,unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errors))
return true;
- if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) {
+ if (s->imports.count() == 1 && !s->imports.at(0).isLibrary && url_return && s != &unqualifiedset) {
// qualified, and only 1 url
- *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml")));
+ *url_return = resolveLocalUrl(s->imports.at(0).url, unqualifiedtype + QLatin1String(".qml"));
return true;
}
}
@@ -713,21 +687,21 @@ QDeclarativeImportedNamespace *QDeclarativeImportsPrivate::findNamespace(const Q
return set.value(type);
}
-bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
- QUrl* url_return, QUrl *base, QList<QDeclarativeError> *errors)
+bool QDeclarativeImportedNamespace::find(QDeclarativeTypeLoader *typeLoader, const QString& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
+ QString* url_return, QString *base, QList<QDeclarativeError> *errors)
{
bool typeRecursionDetected = false;
- for (int i=0; i<urls.count(); ++i) {
- if (find_helper(i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) {
+ for (int i=0; i<imports.count(); ++i) {
+ if (find_helper(typeLoader, imports.at(i), type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) {
if (qmlCheckTypes()) {
// check for type clashes
- for (int j = i+1; j<urls.count(); ++j) {
- if (find_helper(j, type, vmajor, vminor, 0, 0, base)) {
+ for (int j = i+1; j<imports.count(); ++j) {
+ if (find_helper(typeLoader, imports.at(j), type, vmajor, vminor, 0, 0, base)) {
if (errors) {
- QString u1 = urls.at(i);
- QString u2 = urls.at(j);
+ QString u1 = imports.at(i).url;
+ QString u2 = imports.at(j).url;
if (base) {
- QString b = base->toString();
+ QString b = *base;
int slash = b.lastIndexOf(QLatin1Char('/'));
if (slash >= 0) {
b = b.left(slash+1);
@@ -749,8 +723,8 @@ bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, in
} else {
error.setDescription(QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5")
.arg(u1)
- .arg(majversions.at(i)).arg(minversions.at(i))
- .arg(majversions.at(j)).arg(minversions.at(j)));
+ .arg(imports.at(i).majversion).arg(imports.at(i).minversion)
+ .arg(imports.at(j).majversion).arg(imports.at(j).minversion));
}
errors->prepend(error);
}
@@ -850,14 +824,14 @@ QDeclarativeImportDatabase::~QDeclarativeImportDatabase()
*/
bool QDeclarativeImports::addImport(QDeclarativeImportDatabase *importDb,
const QString& uri, const QString& prefix, int vmaj, int vmin,
- QDeclarativeScriptParser::Import::Type importType,
+ QDeclarativeScript::Import::Type importType,
const QDeclarativeDirComponents &qmldircomponentsnetwork,
QList<QDeclarativeError> *errors)
{
if (qmlImportTrace())
qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::addImport: "
<< uri << " " << vmaj << '.' << vmin << " "
- << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File")
+ << (importType==QDeclarativeScript::Import::Library? "Library" : "File")
<< " as " << prefix;
return d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, importDb, errors);
@@ -871,7 +845,8 @@ bool QDeclarativeImports::addImport(QDeclarativeImportDatabase *importDb,
\a qmldirPath is the location of the qmldir file.
*/
-QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
+QString QDeclarativeImportDatabase::resolvePlugin(QDeclarativeTypeLoader *typeLoader,
+ const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName, const QStringList &suffixes,
const QString &prefix)
{
@@ -883,37 +858,40 @@ QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const
foreach (const QString &pluginPath, searchPaths) {
QString resolvedPath;
-
if (pluginPath == QLatin1String(".")) {
- if (qmldirPluginPathIsRelative)
- resolvedPath = qmldirPath.absoluteFilePath(qmldirPluginPath);
+ if (qmldirPluginPathIsRelative && !qmldirPluginPath.isEmpty() && qmldirPluginPath != QLatin1String("."))
+ resolvedPath = QDir::cleanPath(qmldirPath + QLatin1Char('/') + qmldirPluginPath);
else
- resolvedPath = qmldirPath.absolutePath();
+ resolvedPath = qmldirPath;
} else {
- resolvedPath = pluginPath;
+ if (QDir::isRelativePath(pluginPath))
+ resolvedPath = QDir::cleanPath(qmldirPath + QLatin1Char('/') + pluginPath);
+ else
+ resolvedPath = pluginPath;
}
// hack for resources, should probably go away
if (resolvedPath.startsWith(QLatin1Char(':')))
resolvedPath = QCoreApplication::applicationDirPath();
- QDir dir(resolvedPath);
+ if (!resolvedPath.endsWith(QLatin1Char('/')))
+ resolvedPath += QLatin1Char('/');
+
foreach (const QString &suffix, suffixes) {
QString pluginFileName = prefix;
pluginFileName += baseName;
pluginFileName += suffix;
- QFileInfo fileInfo(dir, pluginFileName);
-
- if (fileInfo.exists())
- return fileInfo.absoluteFilePath();
+ QString absolutePath = typeLoader->absoluteFilePath(resolvedPath + pluginFileName);
+ if (!absolutePath.isEmpty())
+ return absolutePath;
}
}
if (qmlImportTrace())
qDebug() << "QDeclarativeImportDatabase::resolvePlugin: Could not resolve plugin" << baseName
- << "in" << qmldirPath.absolutePath();
+ << "in" << qmldirPath;
return QString();
}
@@ -935,18 +913,19 @@ QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const
Version number on unix are ignored.
*/
-QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
+QString QDeclarativeImportDatabase::resolvePlugin(QDeclarativeTypeLoader *typeLoader,
+ const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName)
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
- return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
+ return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
QStringList()
# ifdef QT_DEBUG
<< QLatin1String("d.dll") // try a qmake-style debug build first
# endif
<< QLatin1String(".dll"));
#elif defined(Q_OS_SYMBIAN)
- return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
+ return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
QStringList()
<< QLatin1String(".dll")
<< QLatin1String(".qtplugin"));
@@ -954,7 +933,7 @@ QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const
# if defined(Q_OS_DARWIN)
- return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
+ return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
QStringList()
# ifdef QT_DEBUG
<< QLatin1String("_debug.dylib") // try a qmake-style debug build first
@@ -988,7 +967,7 @@ QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const
// Examples of valid library names:
// libfoo.so
- return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
+ return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
# endif
#endif
@@ -1097,7 +1076,7 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt
if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
if (errors) {
QDeclarativeError error;
- error.setDescription(tr("File name case mismatch for \"%2\"").arg(absoluteFilePath));
+ error.setDescription(tr("File name case mismatch for \"%1\"").arg(absoluteFilePath));
errors->prepend(error);
}
return false;
@@ -1146,5 +1125,4 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt
#endif
}
-
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeimport_p.h b/src/declarative/qml/qdeclarativeimport_p.h
index fe9404d9b2..c695a6b423 100644
--- a/src/declarative/qml/qdeclarativeimport_p.h
+++ b/src/declarative/qml/qdeclarativeimport_p.h
@@ -45,8 +45,9 @@
#include <QtCore/qurl.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qset.h>
+#include <QtCore/qstringlist.h>
#include <private/qdeclarativedirparser_p.h>
-#include <private/qdeclarativescriptparser_p.h>
+#include <private/qdeclarativescript_p.h>
#include <private/qdeclarativemetatype_p.h>
//
@@ -68,11 +69,12 @@ class QDir;
class QDeclarativeImportedNamespace;
class QDeclarativeImportsPrivate;
class QDeclarativeImportDatabase;
+class QDeclarativeTypeLoader;
class QDeclarativeImports
{
public:
- QDeclarativeImports();
+ QDeclarativeImports(QDeclarativeTypeLoader *);
QDeclarativeImports(const QDeclarativeImports &);
~QDeclarativeImports();
QDeclarativeImports &operator=(const QDeclarativeImports &);
@@ -80,19 +82,19 @@ public:
void setBaseUrl(const QUrl &url);
QUrl baseUrl() const;
- bool resolveType(const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return,
+ bool resolveType(const QString& type,
+ QDeclarativeType** type_return, QString* url_return,
int *version_major, int *version_minor,
QDeclarativeImportedNamespace** ns_return,
QList<QDeclarativeError> *errors = 0) const;
bool resolveType(QDeclarativeImportedNamespace*,
- const QByteArray& type,
- QDeclarativeType** type_return, QUrl* url_return,
+ const QString& type,
+ QDeclarativeType** type_return, QString* url_return,
int *version_major, int *version_minor) const;
bool addImport(QDeclarativeImportDatabase *,
const QString& uri, const QString& prefix, int vmaj, int vmin,
- QDeclarativeScriptParser::Import::Type importType,
+ QDeclarativeScript::Import::Type importType,
const QDeclarativeDirComponents &qmldircomponentsnetwork,
QList<QDeclarativeError> *errors);
@@ -122,10 +124,12 @@ public:
private:
friend class QDeclarativeImportsPrivate;
- QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
+ QString resolvePlugin(QDeclarativeTypeLoader *typeLoader,
+ const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName, const QStringList &suffixes,
const QString &prefix = QString());
- QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
+ QString resolvePlugin(QDeclarativeTypeLoader *typeLoader,
+ const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName);
diff --git a/src/declarative/qml/qdeclarativeintegercache.cpp b/src/declarative/qml/qdeclarativeintegercache.cpp
index ef99c63086..16bf8d1dab 100644
--- a/src/declarative/qml/qdeclarativeintegercache.cpp
+++ b/src/declarative/qml/qdeclarativeintegercache.cpp
@@ -61,6 +61,11 @@ QString QDeclarativeIntegerCache::findId(int value) const
return QString();
}
+void QDeclarativeIntegerCache::reserve(int size)
+{
+ stringCache.reserve(size);
+}
+
void QDeclarativeIntegerCache::add(const QString &id, int value)
{
Q_ASSERT(!stringCache.contains(id));
diff --git a/src/declarative/qml/qdeclarativeintegercache_p.h b/src/declarative/qml/qdeclarativeintegercache_p.h
index a66457cede..1ac03ada66 100644
--- a/src/declarative/qml/qdeclarativeintegercache_p.h
+++ b/src/declarative/qml/qdeclarativeintegercache_p.h
@@ -68,6 +68,7 @@ public:
inline int count() const;
void add(const QString &, int);
+ void reserve(int);
int value(const QString &);
inline int value(const QHashedV8String &);
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index a989ae847b..091a561993 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -42,15 +42,18 @@
#include <QtDeclarative/qdeclarativeprivate.h>
#include "private/qdeclarativemetatype_p.h"
-#include "private/qdeclarativeproxymetaobject_p.h"
-#include "private/qdeclarativecustomparser_p.h"
-#include "private/qdeclarativeguard_p.h"
+#include <private/qdeclarativeproxymetaobject_p.h>
+#include <private/qdeclarativecustomparser_p.h>
+#include <private/qdeclarativeguard_p.h>
+#include <private/qhashedstring_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qbitarray.h>
#include <QtCore/qreadwritelock.h>
+#include <QtCore/private/qmetaobject_p.h>
+
#include <qmetatype.h>
#include <qobjectdefs.h>
#include <qdatetime.h>
@@ -93,41 +96,68 @@ struct QDeclarativeMetaTypeData
QList<QDeclarativeType *> types;
typedef QHash<int, QDeclarativeType *> Ids;
Ids idToType;
- typedef QHash<QByteArray, QDeclarativeType *> Names;
+ typedef QHash<QString, QDeclarativeType *> Names;
Names nameToType;
typedef QHash<const QMetaObject *, QDeclarativeType *> MetaObjects;
MetaObjects metaObjectToType;
typedef QHash<int, QDeclarativeMetaType::StringConverter> StringConverters;
StringConverters stringConverters;
+
+ struct VersionedUri {
+ VersionedUri()
+ : majorVersion(0) {}
+ VersionedUri(const QString &uri, int majorVersion)
+ : uri(uri), majorVersion(majorVersion) {}
+ bool operator==(const VersionedUri &other) const {
+ return other.majorVersion == majorVersion && other.uri == uri;
+ }
+ QString uri;
+ int majorVersion;
+ };
+ typedef QHash<VersionedUri, QDeclarativeTypeModule *> TypeModules;
+ TypeModules uriToModule;
+
struct ModuleApiList {
ModuleApiList() : sorted(true) {}
QList<QDeclarativeMetaType::ModuleApi> moduleApis;
bool sorted;
};
- typedef QHash<QByteArray, ModuleApiList> ModuleApis;
+ typedef QHash<QString, ModuleApiList> ModuleApis;
ModuleApis moduleApis;
int moduleApiCount;
- struct ModuleInfo {
- ModuleInfo(int major, int minor)
- : vmajor(major), vminor_min(minor), vminor_max(minor) {}
- ModuleInfo(int major, int minor_min, int minor_max)
- : vmajor(major), vminor_min(minor_min), vminor_max(minor_max) {}
- int vmajor;
- int vminor_min, vminor_max;
- };
- typedef QHash<QPair<QByteArray,int>, ModuleInfo> ModuleInfoHash;
- ModuleInfoHash modules;
-
QBitArray objects;
QBitArray interfaces;
QBitArray lists;
QList<QDeclarativePrivate::AutoParentFunction> parentFunctions;
};
+
+class QDeclarativeTypeModulePrivate
+{
+public:
+ QDeclarativeTypeModulePrivate()
+ : minMinorVersion(INT_MAX), maxMinorVersion(0) {}
+
+ QDeclarativeMetaTypeData::VersionedUri uri;
+
+ int minMinorVersion;
+ int maxMinorVersion;
+
+ void add(QDeclarativeType *);
+
+ QStringHash<QList<QDeclarativeType *> > typeHash;
+ QList<QDeclarativeType *> types;
+};
+
Q_GLOBAL_STATIC(QDeclarativeMetaTypeData, metaTypeData)
Q_GLOBAL_STATIC(QReadWriteLock, metaTypeDataLock)
+static uint qHash(const QDeclarativeMetaTypeData::VersionedUri &v)
+{
+ return qHash(v.uri) ^ qHash(v.majorVersion);
+}
+
QDeclarativeMetaTypeData::QDeclarativeMetaTypeData()
: moduleApiCount(0)
{
@@ -145,11 +175,13 @@ public:
QDeclarativeTypePrivate();
void init() const;
+ void initEnums() const;
bool m_isInterface : 1;
const char *m_iid;
- QByteArray m_module;
+ QString m_module;
QByteArray m_name;
+ QString m_elementName;
int m_version_maj;
int m_version_min;
int m_typeId; int m_listId;
@@ -173,8 +205,10 @@ public:
int m_index;
QDeclarativeCustomParser *m_customParser;
mutable volatile bool m_isSetup:1;
- mutable bool m_haveSuperType : 1;
+ mutable volatile bool m_isEnumSetup:1;
+ mutable bool m_haveSuperType:1;
mutable QList<QDeclarativeProxyMetaObject::ProxyData> m_metaObjects;
+ mutable QStringHash<int> m_enums;
static QHash<const QMetaObject *, int> m_attachedPropertyIds;
};
@@ -186,7 +220,7 @@ QDeclarativeTypePrivate::QDeclarativeTypePrivate()
m_superType(0), m_allocationSize(0), m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0),
m_attachedPropertiesType(0), m_parserStatusCast(-1), m_propertyValueSourceCast(-1),
m_propertyValueInterceptorCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0),
- m_isSetup(false), m_haveSuperType(false)
+ m_isSetup(false), m_isEnumSetup(false), m_haveSuperType(false)
{
}
@@ -212,7 +246,7 @@ QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::Registe
if (type.uri) name += '/';
name += type.elementName;
- d->m_module = type.uri;
+ d->m_module = QString::fromUtf8(type.uri);
d->m_name = name;
d->m_version_maj = type.versionMajor;
d->m_version_min = type.versionMinor;
@@ -251,7 +285,7 @@ QDeclarativeType::~QDeclarativeType()
delete d;
}
-QByteArray QDeclarativeType::module() const
+QString QDeclarativeType::module() const
{
return d->m_module;
}
@@ -268,11 +302,13 @@ int QDeclarativeType::minorVersion() const
bool QDeclarativeType::availableInVersion(int vmajor, int vminor) const
{
+ Q_ASSERT(vmajor >= 0 && vminor >= 0);
return vmajor == d->m_version_maj && vminor >= d->m_version_min;
}
-bool QDeclarativeType::availableInVersion(const QByteArray &module, int vmajor, int vminor) const
+bool QDeclarativeType::availableInVersion(const QString &module, int vmajor, int vminor) const
{
+ Q_ASSERT(vmajor >= 0 && vminor >= 0);
return module == d->m_module && vmajor == d->m_version_maj && vminor >= d->m_version_min;
}
@@ -364,6 +400,24 @@ static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
}
}
+static bool isPropertyRevisioned(const QMetaObject *mo, int index)
+{
+ int i = index;
+ i -= mo->propertyOffset();
+ if (i < 0 && mo->d.superdata)
+ return isPropertyRevisioned(mo->d.superdata, index);
+
+ const QMetaObjectPrivate *mop = reinterpret_cast<const QMetaObjectPrivate*>(mo->d.data);
+ if (i >= 0 && i < mop->propertyCount) {
+ int handle = mop->propertyData + 3*i;
+ int flags = mo->d.data[handle + 2];
+
+ return (flags & Revisioned);
+ }
+
+ return false;
+}
+
void QDeclarativeTypePrivate::init() const
{
if (m_isSetup) return;
@@ -417,7 +471,7 @@ void QDeclarativeTypePrivate::init() const
mo = m_metaObjects.first().metaObject;
for (int ii = 0; !m_containsRevisionedAttributes && ii < mo->propertyCount(); ++ii) {
- if (mo->property(ii).revision() != 0)
+ if (isPropertyRevisioned(mo, ii))
m_containsRevisionedAttributes = true;
}
@@ -431,6 +485,27 @@ void QDeclarativeTypePrivate::init() const
lock.unlock();
}
+void QDeclarativeTypePrivate::initEnums() const
+{
+ if (m_isEnumSetup) return;
+
+ init();
+
+ QWriteLocker lock(metaTypeDataLock());
+ if (m_isEnumSetup) return;
+
+ const QMetaObject *metaObject = m_baseMetaObject;
+ for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
+
+ QMetaEnum e = metaObject->enumerator(ii);
+
+ for (int jj = 0; jj < e.keyCount(); ++jj)
+ m_enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj));
+ }
+
+ m_isEnumSetup = true;
+}
+
QByteArray QDeclarativeType::typeName() const
{
if (d->m_baseMetaObject)
@@ -439,7 +514,17 @@ QByteArray QDeclarativeType::typeName() const
return QByteArray();
}
-QByteArray QDeclarativeType::qmlTypeName() const
+const QString &QDeclarativeType::elementName() const
+{
+ if (d->m_elementName.isEmpty()) {
+ QByteArray n = qmlTypeName();
+ int idx = n.lastIndexOf('/');
+ d->m_elementName = QString::fromUtf8(n.mid(idx + 1));
+ }
+ return d->m_elementName;
+}
+
+const QByteArray &QDeclarativeType::qmlTypeName() const
{
return d->m_name;
}
@@ -591,6 +676,164 @@ int QDeclarativeType::index() const
return d->m_index;
}
+int QDeclarativeType::enumValue(const QHashedStringRef &name) const
+{
+ d->initEnums();
+
+ int *rv = d->m_enums.value(name);
+ return rv?*rv:-1;
+}
+
+int QDeclarativeType::enumValue(const QHashedV8String &name) const
+{
+ d->initEnums();
+
+ int *rv = d->m_enums.value(name);
+ return rv?*rv:-1;
+}
+
+QDeclarativeTypeModule::QDeclarativeTypeModule()
+: d(new QDeclarativeTypeModulePrivate)
+{
+}
+
+QDeclarativeTypeModule::~QDeclarativeTypeModule()
+{
+ delete d; d = 0;
+}
+
+QString QDeclarativeTypeModule::module() const
+{
+ return d->uri.uri;
+}
+
+int QDeclarativeTypeModule::majorVersion() const
+{
+ return d->uri.majorVersion;
+}
+
+int QDeclarativeTypeModule::minimumMinorVersion() const
+{
+ return d->minMinorVersion;
+}
+
+int QDeclarativeTypeModule::maximumMinorVersion() const
+{
+ return d->maxMinorVersion;
+}
+
+void QDeclarativeTypeModulePrivate::add(QDeclarativeType *type)
+{
+ types << type;
+
+ minMinorVersion = qMin(minMinorVersion, type->minorVersion());
+ maxMinorVersion = qMax(maxMinorVersion, type->minorVersion());
+
+ QList<QDeclarativeType *> &list = typeHash[type->elementName()];
+ for (int ii = 0; ii < list.count(); ++ii) {
+ if (list.at(ii)->minorVersion() < type->minorVersion()) {
+ list.insert(ii, type);
+ return;
+ }
+ }
+ list.append(type);
+}
+
+QList<QDeclarativeType *> QDeclarativeTypeModule::types()
+{
+ QList<QDeclarativeType *> rv;
+ QReadLocker lock(metaTypeDataLock());
+ rv = d->types;
+ return rv;
+}
+
+QList<QDeclarativeType *> QDeclarativeTypeModule::type(const QString &name)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QList<QDeclarativeType *> rv;
+ for (int ii = 0; ii < d->types.count(); ++ii) {
+ if (d->types.at(ii)->elementName() == name)
+ rv << d->types.at(ii);
+ }
+ return rv;
+}
+
+QDeclarativeType *QDeclarativeTypeModule::type(const QHashedStringRef &name, int minor)
+{
+ QReadLocker lock(metaTypeDataLock());
+
+ QList<QDeclarativeType *> *types = d->typeHash.value(name);
+ if (!types) return 0;
+
+ for (int ii = 0; ii < types->count(); ++ii)
+ if (types->at(ii)->minorVersion() <= minor)
+ return types->at(ii);
+
+ return 0;
+}
+
+QDeclarativeType *QDeclarativeTypeModule::type(const QHashedV8String &name, int minor)
+{
+ QReadLocker lock(metaTypeDataLock());
+
+ QList<QDeclarativeType *> *types = d->typeHash.value(name);
+ if (!types) return 0;
+
+ for (int ii = 0; ii < types->count(); ++ii)
+ if (types->at(ii)->minorVersion() <= minor)
+ return types->at(ii);
+
+ return 0;
+}
+
+
+QDeclarativeTypeModuleVersion::QDeclarativeTypeModuleVersion()
+: m_module(0), m_minor(0)
+{
+}
+
+QDeclarativeTypeModuleVersion::QDeclarativeTypeModuleVersion(QDeclarativeTypeModule *module, int minor)
+: m_module(module), m_minor(minor)
+{
+ Q_ASSERT(m_module);
+ Q_ASSERT(m_minor >= 0);
+}
+
+QDeclarativeTypeModuleVersion::QDeclarativeTypeModuleVersion(const QDeclarativeTypeModuleVersion &o)
+: m_module(o.m_module), m_minor(o.m_minor)
+{
+}
+
+QDeclarativeTypeModuleVersion &QDeclarativeTypeModuleVersion::operator=(const QDeclarativeTypeModuleVersion &o)
+{
+ m_module = o.m_module;
+ m_minor = o.m_minor;
+ return *this;
+}
+
+QDeclarativeTypeModule *QDeclarativeTypeModuleVersion::module() const
+{
+ return m_module;
+}
+
+int QDeclarativeTypeModuleVersion::minorVersion() const
+{
+ return m_minor;
+}
+
+QDeclarativeType *QDeclarativeTypeModuleVersion::type(const QHashedStringRef &name) const
+{
+ if (m_module) return m_module->type(name, m_minor);
+ else return 0;
+}
+
+QDeclarativeType *QDeclarativeTypeModuleVersion::type(const QHashedV8String &name) const
+{
+ if (m_module) return m_module->type(name, m_minor);
+ else return 0;
+}
+
+
int registerAutoParentFunction(QDeclarativePrivate::RegisterAutoParent &autoparent)
{
QWriteLocker lock(metaTypeDataLock());
@@ -618,7 +861,7 @@ int registerInterface(const QDeclarativePrivate::RegisterInterface &interface)
data->idToType.insert(type->qListTypeId(), type);
// XXX No insertMulti, so no multi-version interfaces?
if (!type->qmlTypeName().isEmpty())
- data->nameToType.insert(type->qmlTypeName(), type);
+ data->nameToType.insert(QString::fromUtf8(type->qmlTypeName()), type);
if (data->interfaces.size() <= interface.typeId)
data->interfaces.resize(interface.typeId + 16);
@@ -652,7 +895,7 @@ int registerType(const QDeclarativePrivate::RegisterType &type)
if (dtype->qListTypeId()) data->idToType.insert(dtype->qListTypeId(), dtype);
if (!dtype->qmlTypeName().isEmpty())
- data->nameToType.insertMulti(dtype->qmlTypeName(), dtype);
+ data->nameToType.insertMulti(QString::fromUtf8(dtype->qmlTypeName()), dtype);
data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
@@ -664,21 +907,16 @@ int registerType(const QDeclarativePrivate::RegisterType &type)
if (type.listId) data->lists.setBit(type.listId, true);
if (type.uri) {
- QByteArray mod(type.uri);
- QPair<QByteArray,int> key(mod,type.versionMajor);
- QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(key);
- if (it == data->modules.end()) {
- // New module
- data->modules.insert(key, QDeclarativeMetaTypeData::ModuleInfo(type.versionMajor,type.versionMinor));
- } else {
- if ((*it).vminor_max < type.versionMinor) {
- // Newer module
- data->modules.insert(key, QDeclarativeMetaTypeData::ModuleInfo((*it).vmajor, (*it).vminor_min, type.versionMinor));
- } else if ((*it).vminor_min > type.versionMinor) {
- // Older module
- data->modules.insert(key, QDeclarativeMetaTypeData::ModuleInfo((*it).vmajor, type.versionMinor, (*it).vminor_min));
- }
+ QString mod = QString::fromUtf8(type.uri);
+
+ QDeclarativeMetaTypeData::VersionedUri versionedUri(mod, type.versionMajor);
+ QDeclarativeTypeModule *module = data->uriToModule.value(versionedUri);
+ if (!module) {
+ module = new QDeclarativeTypeModule;
+ module->d->uri = versionedUri;
+ data->uriToModule.insert(versionedUri, module);
}
+ module->d->add(dtype);
}
return index;
@@ -689,7 +927,7 @@ int registerModuleApi(const QDeclarativePrivate::RegisterModuleApi &api)
QWriteLocker lock(metaTypeDataLock());
QDeclarativeMetaTypeData *data = metaTypeData();
- QByteArray uri(api.uri);
+ QString uri = QString::fromUtf8(api.uri);
QDeclarativeMetaType::ModuleApi import;
import.major = api.versionMajor;
import.minor = api.versionMinor;
@@ -730,15 +968,18 @@ int QDeclarativePrivate::qmlregister(RegistrationType type, void *data)
return -1;
}
-bool QDeclarativeMetaType::isAnyModule(const QByteArray &module)
+/*
+ Returns true if a module \a uri of any version is installed.
+*/
+bool QDeclarativeMetaType::isAnyModule(const QString &uri)
{
+ QReadLocker lock(metaTypeDataLock());
QDeclarativeMetaTypeData *data = metaTypeData();
- QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.begin();
- while (it != data->modules.end()) {
- if (it.key().first == module)
+ for (QDeclarativeMetaTypeData::TypeModules::ConstIterator iter = data->uriToModule.begin();
+ iter != data->uriToModule.end(); ++iter) {
+ if ((*iter)->module() == uri)
return true;
- ++it;
}
return false;
@@ -751,27 +992,35 @@ bool QDeclarativeMetaType::isAnyModule(const QByteArray &module)
So if only 4.7 and 4.9 have been registered, 4.7,4.8, and 4.9 are valid, but not 4.6 nor 4.10.
*/
-bool QDeclarativeMetaType::isModule(const QByteArray &module, int versionMajor, int versionMinor)
+bool QDeclarativeMetaType::isModule(const QString &module, int versionMajor, int versionMinor)
{
+ Q_ASSERT(versionMajor >= 0 && versionMinor >= 0);
+ QReadLocker lock(metaTypeDataLock());
+
QDeclarativeMetaTypeData *data = metaTypeData();
// first, check Types
- QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(QPair<QByteArray,int>(module,versionMajor));
- if (it != data->modules.end()) {
- if (((*it).vminor_max >= versionMinor && (*it).vminor_min <= versionMinor))
- return true;
- }
+ QDeclarativeTypeModule *tm =
+ data->uriToModule.value(QDeclarativeMetaTypeData::VersionedUri(module, versionMajor));
+ if (tm && tm->minimumMinorVersion() <= versionMinor && tm->maximumMinorVersion() >= versionMinor)
+ return true;
// then, check ModuleApis
foreach (const QDeclarativeMetaType::ModuleApi &mApi, data->moduleApis.value(module).moduleApis) {
- if (mApi.major == versionMajor && mApi.minor == versionMinor) {
+ if (mApi.major == versionMajor && mApi.minor == versionMinor) // XXX is this correct?
return true;
- }
}
return false;
}
+QDeclarativeTypeModule *QDeclarativeMetaType::typeModule(const QString &uri, int majorVersion)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QDeclarativeMetaTypeData *data = metaTypeData();
+ return data->uriToModule.value(QDeclarativeMetaTypeData::VersionedUri(uri, majorVersion));
+}
+
QList<QDeclarativePrivate::AutoParentFunction> QDeclarativeMetaType::parentFunctions()
{
QReadLocker lock(metaTypeDataLock());
@@ -785,7 +1034,7 @@ static bool operator<(const QDeclarativeMetaType::ModuleApi &lhs, const QDeclara
}
QDeclarativeMetaType::ModuleApi
-QDeclarativeMetaType::moduleApi(const QByteArray &uri, int versionMajor, int versionMinor)
+QDeclarativeMetaType::moduleApi(const QString &uri, int versionMajor, int versionMinor)
{
QReadLocker lock(metaTypeDataLock());
QDeclarativeMetaTypeData *data = metaTypeData();
@@ -1001,17 +1250,20 @@ QDeclarativeMetaType::StringConverter QDeclarativeMetaType::customStringConverte
Returns the type (if any) of URI-qualified named \a name in version specified
by \a version_major and \a version_minor.
*/
-QDeclarativeType *QDeclarativeMetaType::qmlType(const QByteArray &name, int version_major, int version_minor)
+QDeclarativeType *QDeclarativeMetaType::qmlType(const QString &name, int version_major, int version_minor)
{
+ Q_ASSERT(version_major >= 0 && version_minor >= 0);
QReadLocker lock(metaTypeDataLock());
QDeclarativeMetaTypeData *data = metaTypeData();
- QList<QDeclarativeType*> types = data->nameToType.values(name);
- foreach (QDeclarativeType *t, types) {
+ QDeclarativeMetaTypeData::Names::ConstIterator it = data->nameToType.find(name);
+ while (it != data->nameToType.end()) {
// XXX version_major<0 just a kludge for QDeclarativePropertyPrivate::initProperty
- if (version_major<0 || t->availableInVersion(version_major,version_minor))
- return t;
+ if (it.key() == name && (version_major<0 || (*it)->availableInVersion(version_major,version_minor)))
+ return (*it);
+ ++it;
}
+
return 0;
}
@@ -1032,8 +1284,9 @@ QDeclarativeType *QDeclarativeMetaType::qmlType(const QMetaObject *metaObject)
by \a version_major and \a version_minor in module specified by \a uri. Returns null if no
type is registered.
*/
-QDeclarativeType *QDeclarativeMetaType::qmlType(const QMetaObject *metaObject, const QByteArray &module, int version_major, int version_minor)
+QDeclarativeType *QDeclarativeMetaType::qmlType(const QMetaObject *metaObject, const QString &module, int version_major, int version_minor)
{
+ Q_ASSERT(version_major >= 0 && version_minor >= 0);
QReadLocker lock(metaTypeDataLock());
QDeclarativeMetaTypeData *data = metaTypeData();
@@ -1067,7 +1320,7 @@ QDeclarativeType *QDeclarativeMetaType::qmlType(int userType)
/*!
Returns the list of registered QML type names.
*/
-QList<QByteArray> QDeclarativeMetaType::qmlTypeNames()
+QList<QString> QDeclarativeMetaType::qmlTypeNames()
{
QReadLocker lock(metaTypeDataLock());
QDeclarativeMetaTypeData *data = metaTypeData();
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index 429aa7a98f..2a6ce20bbb 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -66,6 +66,7 @@ QT_BEGIN_NAMESPACE
class QDeclarativeType;
class QDeclarativeCustomParser;
class QDeclarativeTypePrivate;
+class QDeclarativeTypeModule;
class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeMetaType
{
@@ -73,12 +74,12 @@ public:
static bool canCopy(int type);
static bool copy(int type, void *data, const void *copy = 0);
- static QList<QByteArray> qmlTypeNames();
+ static QList<QString> qmlTypeNames();
static QList<QDeclarativeType*> qmlTypes();
- static QDeclarativeType *qmlType(const QByteArray &, int, int);
+ static QDeclarativeType *qmlType(const QString &, int, int);
static QDeclarativeType *qmlType(const QMetaObject *);
- static QDeclarativeType *qmlType(const QMetaObject *metaObject, const QByteArray &module, int version_major, int version_minor);
+ static QDeclarativeType *qmlType(const QMetaObject *metaObject, const QString &module, int version_major, int version_minor);
static QDeclarativeType *qmlType(int);
static QMetaProperty defaultProperty(const QMetaObject *);
@@ -104,8 +105,9 @@ public:
static void registerCustomStringConverter(int, StringConverter);
static StringConverter customStringConverter(int);
- static bool isAnyModule(const QByteArray &module);
- static bool isModule(const QByteArray &module, int versionMajor, int versionMinor);
+ static bool isAnyModule(const QString &uri);
+ static bool isModule(const QString &module, int versionMajor, int versionMinor);
+ static QDeclarativeTypeModule *typeModule(const QString &uri, int majorVersion);
static QList<QDeclarativePrivate::AutoParentFunction> parentFunctions();
@@ -126,21 +128,24 @@ public:
QJSValue (*script)(QDeclarativeEngine *, QJSEngine *);
QObject *(*qobject)(QDeclarativeEngine *, QJSEngine *);
};
- static ModuleApi moduleApi(const QByteArray &, int, int);
+ static ModuleApi moduleApi(const QString &, int, int);
};
+class QHashedStringRef;
+class QHashedV8String;
class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeType
{
public:
QByteArray typeName() const;
- QByteArray qmlTypeName() const;
+ const QByteArray &qmlTypeName() const;
+ const QString &elementName() const;
- QByteArray module() const;
+ QString module() const;
int majorVersion() const;
int minorVersion() const;
bool availableInVersion(int vmajor, int vminor) const;
- bool availableInVersion(const QByteArray &module, int vmajor, int vminor) const;
+ bool availableInVersion(const QString &module, int vmajor, int vminor) const;
QObject *create() const;
void create(QObject **, void **, size_t) const;
@@ -176,6 +181,8 @@ public:
int index() const;
+ int enumValue(const QHashedStringRef &) const;
+ int enumValue(const QHashedV8String &) const;
private:
QDeclarativeType *superType() const;
friend class QDeclarativeTypePrivate;
@@ -189,8 +196,49 @@ private:
QDeclarativeTypePrivate *d;
};
+class QDeclarativeTypeModulePrivate;
+class QDeclarativeTypeModule
+{
+public:
+ QString module() const;
+ int majorVersion() const;
+
+ int minimumMinorVersion() const;
+ int maximumMinorVersion() const;
+
+ QList<QDeclarativeType *> types();
+ QList<QDeclarativeType *> type(const QString &);
+
+ QDeclarativeType *type(const QHashedStringRef &, int);
+ QDeclarativeType *type(const QHashedV8String &, int);
+
+private:
+ friend int registerType(const QDeclarativePrivate::RegisterType &);
+ QDeclarativeTypeModule();
+ ~QDeclarativeTypeModule();
+ QDeclarativeTypeModulePrivate *d;
+};
+
+class QDeclarativeTypeModuleVersion
+{
+public:
+ QDeclarativeTypeModuleVersion();
+ QDeclarativeTypeModuleVersion(QDeclarativeTypeModule *, int);
+ QDeclarativeTypeModuleVersion(const QDeclarativeTypeModuleVersion &);
+ QDeclarativeTypeModuleVersion &operator=(const QDeclarativeTypeModuleVersion &);
+
+ QDeclarativeTypeModule *module() const;
+ int minorVersion() const;
+
+ QDeclarativeType *type(const QHashedStringRef &) const;
+ QDeclarativeType *type(const QHashedV8String &) const;
+
+private:
+ QDeclarativeTypeModule *m_module;
+ int m_minor;
+};
+
QDeclarativeMetaType::ModuleApi::ModuleApi()
-// : major(0), minor(0), script(0), qobject(0)
{
major = 0;
minor = 0;
diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp
deleted file mode 100644
index a405022a71..0000000000
--- a/src/declarative/qml/qdeclarativeparser.cpp
+++ /dev/null
@@ -1,437 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qdeclarativeparser_p.h"
-
-#include "qdeclarativepropertyvaluesource.h"
-#include "private/qdeclarativevme_p.h"
-#include "qdeclarative.h"
-#include "private/qdeclarativecomponent_p.h"
-#include "qdeclarativecomponent.h"
-#include "private/qmetaobjectbuilder_p.h"
-#include "private/qdeclarativevmemetaobject_p.h"
-#include "private/qdeclarativecompiler_p.h"
-#include "parser/qdeclarativejsast_p.h"
-#include "parser/qdeclarativejsengine_p.h"
-
-#include <QStack>
-#include <QColor>
-#include <QPointF>
-#include <QSizeF>
-#include <QRectF>
-#include <QStringBuilder>
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-using namespace QDeclarativeJS;
-using namespace QDeclarativeParser;
-
-QDeclarativeParser::Object::Object()
-: type(-1), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1)
-{
-}
-
-QDeclarativeParser::Object::~Object()
-{
- if (defaultProperty) defaultProperty->release();
- if (synthCache) synthCache->release();
- foreach(Property *prop, properties)
- prop->release();
- foreach(Property *prop, valueProperties)
- prop->release();
- foreach(Property *prop, signalProperties)
- prop->release();
- foreach(Property *prop, attachedProperties)
- prop->release();
- foreach(Property *prop, groupedProperties)
- prop->release();
- foreach(Property *prop, valueTypeProperties)
- prop->release();
- typedef QPair<Property *, int> PropPair;
- foreach(const PropPair &prop, scriptStringProperties)
- prop.first->release();
- foreach(const DynamicProperty &prop, dynamicProperties)
- if (prop.defaultValue) prop.defaultValue->release();
-}
-
-void Object::setBindingBit(int b)
-{
- while (bindingBitmask.size() < 4 * (1 + b / 32))
- bindingBitmask.append(char(0));
-
- quint32 *bits = (quint32 *)bindingBitmask.data();
- bits[b / 32] |= (1 << (b % 32));
-}
-
-const QMetaObject *Object::metaObject() const
-{
- if (!metadata.isEmpty() && metatype)
- return &extObject;
- else
- return metatype;
-}
-
-QDeclarativeParser::Property *Object::getDefaultProperty()
-{
- if (!defaultProperty) {
- defaultProperty = new Property;
- defaultProperty->parent = this;
- }
- return defaultProperty;
-}
-
-void QDeclarativeParser::Object::addValueProperty(Property *p)
-{
- p->addref();
- valueProperties << p;
-}
-
-void QDeclarativeParser::Object::addSignalProperty(Property *p)
-{
- p->addref();
- signalProperties << p;
-}
-
-void QDeclarativeParser::Object::addAttachedProperty(Property *p)
-{
- p->addref();
- attachedProperties << p;
-}
-
-void QDeclarativeParser::Object::addGroupedProperty(Property *p)
-{
- p->addref();
- groupedProperties << p;
-}
-
-void QDeclarativeParser::Object::addValueTypeProperty(Property *p)
-{
- p->addref();
- valueTypeProperties << p;
-}
-
-void QDeclarativeParser::Object::addScriptStringProperty(Property *p, int stack)
-{
- p->addref();
- scriptStringProperties << qMakePair(p, stack);
-}
-
-
-Property *QDeclarativeParser::Object::getProperty(const QByteArray &name, bool create)
-{
- if (!properties.contains(name)) {
- if (create) {
- Property *property = new Property(name);
- property->parent = this;
- properties.insert(name, property);
- } else {
- return 0;
- }
- }
- return properties[name];
-}
-
-QDeclarativeParser::Object::DynamicProperty::DynamicProperty()
-: isDefaultProperty(false), type(Variant), defaultValue(0)
-{
-}
-
-QDeclarativeParser::Object::DynamicProperty::DynamicProperty(const DynamicProperty &o)
-: isDefaultProperty(o.isDefaultProperty),
- type(o.type),
- customType(o.customType),
- name(o.name),
- defaultValue(o.defaultValue),
- location(o.location)
-{
-}
-
-QDeclarativeParser::Object::DynamicSignal::DynamicSignal()
-{
-}
-
-QDeclarativeParser::Object::DynamicSignal::DynamicSignal(const DynamicSignal &o)
-: name(o.name), parameterTypes(o.parameterTypes),
- parameterNames(o.parameterNames), location(o.location)
-{
-}
-
-QDeclarativeParser::Object::DynamicSlot::DynamicSlot()
-{
-}
-
-QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
-: name(o.name), body(o.body), parameterNames(o.parameterNames), location(o.location)
-{
-}
-
-QDeclarativeParser::Property::Property()
-: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false),
- isValueTypeSubProperty(false), isAlias(false)
-{
-}
-
-QDeclarativeParser::Property::Property(const QByteArray &n)
-: parent(0), type(0), index(-1), value(0), name(n), isDefault(false),
- isDeferred(false), isValueTypeSubProperty(false), isAlias(false)
-{
-}
-
-QDeclarativeParser::Property::~Property()
-{
- foreach(Value *value, values)
- value->release();
- foreach(Value *value, onValues)
- value->release();
- if (value) value->release();
-}
-
-QDeclarativeParser::Object *QDeclarativeParser::Property::getValue(const LocationSpan &l)
-{
- if (!value) { value = new QDeclarativeParser::Object; value->location = l; }
- return value;
-}
-
-void QDeclarativeParser::Property::addValue(Value *v)
-{
- values << v;
-}
-
-void QDeclarativeParser::Property::addOnValue(Value *v)
-{
- onValues << v;
-}
-
-bool QDeclarativeParser::Property::isEmpty() const
-{
- return !value && values.isEmpty() && onValues.isEmpty();
-}
-
-QDeclarativeParser::Value::Value()
-: type(Unknown), object(0)
-{
-}
-
-QDeclarativeParser::Value::~Value()
-{
- if (object) object->release();
-}
-
-QDeclarativeParser::Variant::Variant()
-: t(Invalid) {}
-
-QDeclarativeParser::Variant::Variant(const Variant &o)
-: t(o.t), d(o.d), s(o.s)
-{
-}
-
-QDeclarativeParser::Variant::Variant(bool v)
-: t(Boolean), b(v)
-{
-}
-
-QDeclarativeParser::Variant::Variant(double v, const QString &asWritten)
-: t(Number), d(v), s(asWritten)
-{
-}
-
-QDeclarativeParser::Variant::Variant(const QString &v)
-: t(String), s(v)
-{
-}
-
-QDeclarativeParser::Variant::Variant(const QString &v, QDeclarativeJS::AST::Node *n)
-: t(Script), n(n), s(v)
-{
-}
-
-QDeclarativeParser::Variant &QDeclarativeParser::Variant::operator=(const Variant &o)
-{
- t = o.t;
- d = o.d;
- s = o.s;
- return *this;
-}
-
-QDeclarativeParser::Variant::Type QDeclarativeParser::Variant::type() const
-{
- return t;
-}
-
-bool QDeclarativeParser::Variant::asBoolean() const
-{
- return b;
-}
-
-QString QDeclarativeParser::Variant::asString() const
-{
- return s;
-}
-
-double QDeclarativeParser::Variant::asNumber() const
-{
- return d;
-}
-
-//reverse of Lexer::singleEscape()
-QString escapedString(const QString &string)
-{
- QString tmp = QLatin1String("\"");
- for (int i = 0; i < string.length(); ++i) {
- const QChar &c = string.at(i);
- switch(c.unicode()) {
- case 0x08:
- tmp += QLatin1String("\\b");
- break;
- case 0x09:
- tmp += QLatin1String("\\t");
- break;
- case 0x0A:
- tmp += QLatin1String("\\n");
- break;
- case 0x0B:
- tmp += QLatin1String("\\v");
- break;
- case 0x0C:
- tmp += QLatin1String("\\f");
- break;
- case 0x0D:
- tmp += QLatin1String("\\r");
- break;
- case 0x22:
- tmp += QLatin1String("\\\"");
- break;
- case 0x27:
- tmp += QLatin1String("\\\'");
- break;
- case 0x5C:
- tmp += QLatin1String("\\\\");
- break;
- default:
- tmp += c;
- break;
- }
- }
- tmp += QLatin1Char('\"');
- return tmp;
-}
-
-QString QDeclarativeParser::Variant::asScript() const
-{
- switch(type()) {
- default:
- case Invalid:
- return QString();
- case Boolean:
- return b?QLatin1String("true"):QLatin1String("false");
- case Number:
- if (s.isEmpty())
- return QString::number(d);
- else
- return s;
- case String:
- return escapedString(s);
- case Script:
- return s;
- }
-}
-
-QDeclarativeJS::AST::Node *QDeclarativeParser::Variant::asAST() const
-{
- if (type() == Script)
- return n;
- else
- return 0;
-}
-
-bool QDeclarativeParser::Variant::isStringList() const
-{
- if (isString())
- return true;
-
- if (type() != Script || !n)
- return false;
-
- AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
- if (!array)
- return false;
-
- AST::ElementList *elements = array->elements;
-
- while (elements) {
-
- if (!AST::cast<AST::StringLiteral *>(elements->expression))
- return false;
-
- elements = elements->next;
- }
-
- return true;
-}
-
-QStringList QDeclarativeParser::Variant::asStringList() const
-{
- QStringList rv;
- if (isString()) {
- rv << asString();
- return rv;
- }
-
- AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
- if (!array)
- return rv;
-
- AST::ElementList *elements = array->elements;
- while (elements) {
-
- AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(elements->expression);
- if (!string)
- return QStringList();
- rv.append(string->value->asString());
-
- elements = elements->next;
- }
-
- return rv;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h
deleted file mode 100644
index 7080a8daee..0000000000
--- a/src/declarative/qml/qdeclarativeparser_p.h
+++ /dev/null
@@ -1,375 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVEPARSER_P_H
-#define QDECLARATIVEPARSER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qdeclarative.h"
-
-#include <QtCore/qbytearray.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qurl.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-
-#include <private/qobject_p.h>
-#include <private/qdeclarativerefcount_p.h>
-#include <private/qdeclarativeglobal_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QDeclarativePropertyCache;
-namespace QDeclarativeJS { namespace AST { class Node; } }
-
-/*
- XXX
-
- These types are created (and owned) by the QDeclarativeScriptParser and consumed by the
- QDeclarativeCompiler. During the compilation phase the compiler will update some of
- the fields for its own use.
-
- The types are part of the generic sounding "QDeclarativeParser" namespace for legacy
- reasons (there used to be more in this namespace) and will be cleaned up and
- migrated into a more appropriate location eventually.
-*/
-namespace QDeclarativeParser
-{
- struct Location
- {
- Location() : line(-1), column(-1) {}
- int line;
- int column;
- };
-
- struct LocationRange
- {
- LocationRange() : offset(0), length(0) {}
- quint32 offset;
- quint32 length;
- };
-
- struct LocationSpan
- {
- Location start;
- Location end;
- LocationRange range;
-
- bool operator<(LocationSpan &o) const {
- return (start.line < o.start.line) ||
- (start.line == o.start.line && start.column < o.start.column);
- }
- };
-
- class Property;
- class Object : public QDeclarativeRefCount
- {
- public:
- Object();
- virtual ~Object();
-
- // Type of the object. The integer is an index into the
- // QDeclarativeCompiledData::types array, or -1 if the object is a property
- // group.
- int type;
-
- // The fully-qualified name of this type
- QByteArray typeName;
- // The class name
- QByteArray className;
- // The id assigned to the object (if any). Set by the QDeclarativeCompiler
- QString id;
- // The id index assigned to the object (if any). Set by the QDeclarativeCompiler
- int idIndex;
- // Custom parsed data
- QByteArray custom;
- // Bit mask of the properties assigned bindings
- QByteArray bindingBitmask;
- void setBindingBit(int);
- // Returns the metaobject for this type, or 0 if not available.
- // Internally selectd between the metatype and extObject variables
- const QMetaObject *metaObject() const;
-
- // The compile time metaobject for this type
- const QMetaObject *metatype;
- // The synthesized metaobject, if QML added signals or properties to
- // this type. Otherwise null
- QAbstractDynamicMetaObject extObject;
- QByteArray metadata; // Generated by compiler
- QByteArray synthdata; // Generated by compiler
- QDeclarativePropertyCache *synthCache; // Generated by compiler
-
- Property *getDefaultProperty();
- Property *getProperty(const QByteArray &name, bool create=true);
-
- Property *defaultProperty;
- QHash<QByteArray, Property *> properties;
-
- // Output of the compilation phase (these properties continue to exist
- // in either the defaultProperty or properties members too)
- void addValueProperty(Property *);
- void addSignalProperty(Property *);
- void addAttachedProperty(Property *);
- void addGroupedProperty(Property *);
- void addValueTypeProperty(Property *);
- void addScriptStringProperty(Property *, int = 0);
- QList<Property *> valueProperties;
- QList<Property *> signalProperties;
- QList<Property *> attachedProperties;
- QList<Property *> groupedProperties;
- QList<Property *> valueTypeProperties;
- QList<QPair<Property *, int> > scriptStringProperties;
-
- // Script blocks that were nested under this object
- struct ScriptBlock {
- enum Pragma {
- None = 0x00000000,
- Shared = 0x00000001
- };
- Q_DECLARE_FLAGS(Pragmas, Pragma)
-
- QString code;
- QString file;
- Pragmas pragmas;
- };
-
- // The bytes to cast instances by to get to the QDeclarativeParserStatus
- // interface. -1 indicates the type doesn't support this interface.
- // Set by the QDeclarativeCompiler.
- int parserStatusCast;
-
- LocationSpan location;
-
- struct DynamicProperty {
- DynamicProperty();
- DynamicProperty(const DynamicProperty &);
-
- enum Type { Variant, Int, Bool, Real, String, Url, Color, Time, Date, DateTime, Alias, Custom, CustomList };
-
- bool isDefaultProperty;
- Type type;
- QByteArray customType;
- QByteArray name;
- QDeclarativeParser::Property *defaultValue;
- LocationSpan location;
- };
- struct DynamicSignal {
- DynamicSignal();
- DynamicSignal(const DynamicSignal &);
-
- QByteArray name;
- QList<QByteArray> parameterTypes;
- QList<QByteArray> parameterNames;
- LocationSpan location;
- };
- struct DynamicSlot {
- DynamicSlot();
- DynamicSlot(const DynamicSlot &);
-
- QByteArray name;
- QString body;
- QList<QByteArray> parameterNames;
- LocationSpan location;
- };
-
- // The list of dynamic properties
- QList<DynamicProperty> dynamicProperties;
- // The list of dynamic signals
- QList<DynamicSignal> dynamicSignals;
- // The list of dynamic slots
- QList<DynamicSlot> dynamicSlots;
- };
-
- class Q_DECLARATIVE_EXPORT Variant
- {
- public:
- enum Type {
- Invalid,
- Boolean,
- Number,
- String,
- Script
- };
-
- Variant();
- Variant(const Variant &);
- Variant(bool);
- Variant(double, const QString &asWritten=QString());
- Variant(const QString &);
- Variant(const QString &, QDeclarativeJS::AST::Node *);
- Variant &operator=(const Variant &);
-
- Type type() const;
-
- bool isBoolean() const { return type() == Boolean; }
- bool isNumber() const { return type() == Number; }
- bool isString() const { return type() == String; }
- bool isScript() const { return type() == Script; }
- bool isStringList() const;
-
- bool asBoolean() const;
- QString asString() const;
- double asNumber() const;
- QString asScript() const;
- QDeclarativeJS::AST::Node *asAST() const;
- QStringList asStringList() const;
-
- private:
- Type t;
- union {
- bool b;
- double d;
- QDeclarativeJS::AST::Node *n;
- };
- QString s;
- };
-
- class Value : public QDeclarativeRefCount
- {
- public:
- Value();
- virtual ~Value();
-
- enum Type {
- // The type of this value assignment is not yet known
- Unknown,
- // This is used as a literal property assignment
- Literal,
- // This is used as a property binding assignment
- PropertyBinding,
- // This is used as a QDeclarativePropertyValueSource assignment
- ValueSource,
- // This is used as a QDeclarativePropertyValueInterceptor assignment
- ValueInterceptor,
- // This is used as a property QObject assignment
- CreatedObject,
- // This is used as a signal object assignment
- SignalObject,
- // This is used as a signal expression assignment
- SignalExpression,
- // This is used as an id assignment only
- Id
- };
- Type type;
-
- // ### Temporary (for id only)
- QString primitive() const { return value.isString() ? value.asString() : value.asScript(); }
-
- // Primitive value
- Variant value;
- // Object value
- Object *object;
-
- LocationSpan location;
- };
-
- class Property : public QDeclarativeRefCount
- {
- public:
- Property();
- Property(const QByteArray &n);
- virtual ~Property();
-
- // The Object to which this property is attached
- Object *parent;
-
- Object *getValue(const LocationSpan &);
- void addValue(Value *v);
- void addOnValue(Value *v);
-
- // The QVariant::Type of the property, or 0 (QVariant::Invalid) if
- // unknown.
- int type;
- // The metaobject index of this property, or -1 if unknown.
- int index;
-
- // Returns true if this is an empty property - both value and values
- // are unset.
- bool isEmpty() const;
- // The list of values assigned to this property. Content in values
- // and value are mutually exclusive
- QList<Value *> values;
- // The list of values assigned to this property using the "on" syntax
- QList<Value *> onValues;
- // The accessed property. This is used to represent dot properties.
- // Content in value and values are mutually exclusive.
- Object *value;
- // The property name
- QByteArray name;
- // True if this property was accessed as the default property.
- bool isDefault;
- // True if the setting of this property will be deferred. Set by the
- // QDeclarativeCompiler
- bool isDeferred;
- // True if this property is a value-type pseudo-property
- bool isValueTypeSubProperty;
- // True if this property is a property alias. Set by the
- // QDeclarativeCompiler
- bool isAlias;
-
- LocationSpan location;
- LocationRange listValueRange;
- };
-}
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeParser::Object::ScriptBlock::Pragmas);
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QDeclarativeParser::Variant)
-
-QT_END_HEADER
-
-#endif // QDECLARATIVEPARSER_P_H
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 3406109a28..60e785510a 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -235,63 +235,71 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name
for (int ii = 0; ii < path.count() - 1; ++ii) {
const QString &pathName = path.at(ii);
- if (QDeclarativeTypeNameCache::Data *data = typeNameCache?typeNameCache->data(pathName):0) {
- if (data->type) {
- QDeclarativeAttachedPropertiesFunc func = data->type->attachedPropertiesFunction();
- if (!func) return; // Not an attachable type
-
- currentObject = qmlAttachedPropertiesObjectById(data->type->attachedPropertiesId(), currentObject);
- if (!currentObject) return; // Something is broken with the attachable type
- } else {
- Q_ASSERT(data->typeNamespace);
- if ((ii + 1) == path.count()) return; // No type following the namespace
+ if (typeNameCache) {
+ QDeclarativeTypeNameCache::Result r = typeNameCache->query(pathName);
+ if (r.isValid()) {
+ if (r.type) {
+ QDeclarativeAttachedPropertiesFunc func = r.type->attachedPropertiesFunction();
+ if (!func) return; // Not an attachable type
+
+ currentObject = qmlAttachedPropertiesObjectById(r.type->attachedPropertiesId(), 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) return; // Invalid type in namespace
- ++ii; data = data->typeNamespace->data(path.at(ii));
- if (!data || !data->type) return; // Invalid type in namespace
+ QDeclarativeAttachedPropertiesFunc func = r.type->attachedPropertiesFunction();
+ if (!func) return; // Not an attachable type
- QDeclarativeAttachedPropertiesFunc func = data->type->attachedPropertiesFunction();
- if (!func) return; // Not an attachable type
+ currentObject = qmlAttachedPropertiesObjectById(r.type->attachedPropertiesId(), currentObject);
+ if (!currentObject) return; // Something is broken with the attachable type
- currentObject = qmlAttachedPropertiesObjectById(data->type->attachedPropertiesId(), 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;
}
- } else {
- QDeclarativePropertyCache::Data local;
- QDeclarativePropertyCache::Data *property =
- QDeclarativePropertyCache::property(engine, obj, pathName, local);
+ }
- if (!property) return; // Not a property
- if (property->isFunction())
- return; // Not an object property
+ QDeclarativePropertyCache::Data local;
+ QDeclarativePropertyCache::Data *property =
+ QDeclarativePropertyCache::property(engine, obj, pathName, local);
- if (ii == (path.count() - 2) && QDeclarativeValueTypeFactory::isValueType(property->propType)) {
- // We're now at a value type property. We can use a global valuetypes array as we
- // never actually use the objects, just look up their properties.
- QObject *typeObject = (*qmlValueTypes())[property->propType];
- if (!typeObject) return; // Not a value type
+ if (!property) return; // Not a property
+ if (property->isFunction())
+ return; // Not an object property
- int idx = typeObject->metaObject()->indexOfProperty(path.last().toUtf8().constData());
- if (idx == -1) return; // Value type property does not exist
+ if (ii == (path.count() - 2) && QDeclarativeValueTypeFactory::isValueType(property->propType)) {
+ // We're now at a value type property. We can use a global valuetypes array as we
+ // never actually use the objects, just look up their properties.
+ QObject *typeObject = (*qmlValueTypes())[property->propType];
+ if (!typeObject) return; // Not a value type
- QMetaProperty vtProp = typeObject->metaObject()->property(idx);
+ int idx = typeObject->metaObject()->indexOfProperty(path.last().toUtf8().constData());
+ if (idx == -1) return; // Value type property does not exist
- object = currentObject;
- core = *property;
- valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(vtProp);
- valueType.valueTypeCoreIdx = idx;
- valueType.valueTypePropType = vtProp.userType();
+ QMetaProperty vtProp = typeObject->metaObject()->property(idx);
- return;
- } else {
- if (!property->isQObject())
- return; // Not an object property
+ object = currentObject;
+ core = *property;
+ valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(vtProp);
+ valueType.valueTypeCoreIdx = idx;
+ valueType.valueTypePropType = vtProp.userType();
- void *args[] = { &currentObject, 0 };
- QMetaObject::metacall(currentObject, QMetaObject::ReadProperty, property->coreIndex, args);
- if (!currentObject) return; // No value
+ return;
+ } else {
+ if (!property->isQObject())
+ return; // Not an object property
+
+ void *args[] = { &currentObject, 0 };
+ QMetaObject::metacall(currentObject, QMetaObject::ReadProperty, property->coreIndex, args);
+ if (!currentObject) return; // No value
- }
}
}
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp
index d2148ad874..406e43fc21 100644
--- a/src/declarative/qml/qdeclarativepropertycache.cpp
+++ b/src/declarative/qml/qdeclarativepropertycache.cpp
@@ -241,12 +241,13 @@ QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObj
QDeclarativePropertyCache::Data rv;
{
const QMetaObject *cmo = metaObject;
+ const QByteArray propertyName = property.toUtf8();
while (cmo) {
- int idx = metaObject->indexOfProperty(property.toUtf8());
+ int idx = cmo->indexOfProperty(propertyName);
if (idx != -1) {
- QMetaProperty p = metaObject->property(idx);
+ QMetaProperty p = cmo->property(idx);
if (p.isScriptable()) {
- rv.load(metaObject->property(idx));
+ rv.load(p);
return rv;
} else {
while (cmo && cmo->propertyOffset() >= idx)
@@ -278,14 +279,14 @@ QDeclarativePropertyCache::Data QDeclarativePropertyCache::create(const QMetaObj
return rv;
}
-QDeclarativePropertyCache *QDeclarativePropertyCache::copy()
+QDeclarativePropertyCache *QDeclarativePropertyCache::copy(int reserve)
{
QDeclarativePropertyCache *cache = new QDeclarativePropertyCache(engine);
cache->parent = this;
cache->parent->addref();
cache->propertyIndexCacheStart = propertyIndexCache.count() + propertyIndexCacheStart;
cache->methodIndexCacheStart = methodIndexCache.count() + methodIndexCacheStart;
- cache->stringCache = stringCache;
+ cache->stringCache.copyAndReserve(stringCache, reserve);
cache->allowedRevisionCache = allowedRevisionCache;
// We specifically do *NOT* copy the constructor
@@ -324,14 +325,13 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
// Extract method name
const char *signature = m.signature();
const char *cptr = signature;
- while (*cptr != '(') { Q_ASSERT(*cptr != 0); ++cptr; }
- QString str = dynamicMetaObject?QString::fromUtf8(signature, cptr - signature):
- QString::fromLatin1(signature, cptr - signature);
- QHashedString methodName(str);
+ bool utf8 = false;
+ while (*cptr != '(') { Q_ASSERT(*cptr != 0); utf8 |= *cptr & 0x80; ++cptr; }
Data *data = &methodIndexCache[ii - methodIndexCacheStart];
data->lazyLoad(m);
+
if (data->isSignal())
data->flags |= signalFlags;
else
@@ -342,15 +342,27 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
data->metaObjectOffset = allowedRevisionCache.count() - 1;
- if (Data **old = stringCache.value(methodName)) {
- // We only overload methods in the same class, exactly like C++
- if ((*old)->flags & Data::IsFunction && (*old)->coreIndex >= methodOffset)
- data->relatedIndex = (*old)->coreIndex;
- data->overrideIndexIsProperty = !bool((*old)->flags & Data::IsFunction);
- data->overrideIndex = (*old)->coreIndex;
+ Data *old = 0;
+
+ if (utf8) {
+ QHashedString methodName(QString::fromUtf8(signature, cptr - signature));
+ if (Data **it = stringCache.value(methodName))
+ old = *it;
+ stringCache.insert(methodName, data);
+ } else {
+ QHashedCStringRef methodName(signature, cptr - signature);
+ if (Data **it = stringCache.value(methodName))
+ old = *it;
+ stringCache.insert(methodName, data);
}
- stringCache.insert(methodName, data);
+ if (old) {
+ // We only overload methods in the same class, exactly like C++
+ if (old->flags & Data::IsFunction && old->coreIndex >= methodOffset)
+ data->relatedIndex = old->coreIndex;
+ data->overrideIndexIsProperty = !bool(old->flags & Data::IsFunction);
+ data->overrideIndex = old->coreIndex;
+ }
}
int propCount = metaObject->propertyCount();
@@ -362,9 +374,10 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
if (!p.isScriptable())
continue;
- QString str = dynamicMetaObject?QString::fromUtf8(p.name()):
- QString::fromLatin1(p.name());
- QHashedString propName(str);
+ const char *str = p.name();
+ bool utf8 = false;
+ const char *cptr = str;
+ while (*cptr != 0) { utf8 |= *cptr & 0x80; ++cptr; }
Data *data = &propertyIndexCache[ii - propertyIndexCacheStart];
@@ -376,12 +389,24 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
data->metaObjectOffset = allowedRevisionCache.count() - 1;
- if (Data **old = stringCache.value(propName)) {
- data->overrideIndexIsProperty = !bool((*old)->flags & Data::IsFunction);
- data->overrideIndex = (*old)->coreIndex;
+ Data *old = 0;
+
+ if (utf8) {
+ QHashedString propName(QString::fromUtf8(str, cptr - str));
+ if (Data **it = stringCache.value(propName))
+ old = *it;
+ stringCache.insert(propName, data);
+ } else {
+ QHashedCStringRef propName(str, cptr - str);
+ if (Data **it = stringCache.value(propName))
+ old = *it;
+ stringCache.insert(propName, data);
}
- stringCache.insert(propName, data);
+ if (old) {
+ data->overrideIndexIsProperty = !bool(old->flags & Data::IsFunction);
+ data->overrideIndex = old->coreIndex;
+ }
}
}
@@ -417,8 +442,12 @@ void QDeclarativePropertyCache::update(QDeclarativeEngine *engine, const QMetaOb
Q_ASSERT(stringCache.isEmpty());
// Optimization to prevent unnecessary reallocation of lists
- propertyIndexCache.reserve(metaObject->propertyCount());
- methodIndexCache.reserve(metaObject->methodCount());
+ int pc = metaObject->propertyCount();
+ int mc = metaObject->methodCount();
+ propertyIndexCache.reserve(pc);
+ methodIndexCache.reserve(mc);
+
+ stringCache.reserve(pc + mc);
updateRecur(engine,metaObject);
}
@@ -452,6 +481,22 @@ QDeclarativePropertyCache::method(int index) const
}
QDeclarativePropertyCache::Data *
+QDeclarativePropertyCache::property(const QHashedStringRef &str) const
+{
+ QDeclarativePropertyCache::Data **rv = stringCache.value(str);
+ if (rv && (*rv)->notFullyResolved()) resolve(*rv);
+ return rv?*rv:0;
+}
+
+QDeclarativePropertyCache::Data *
+QDeclarativePropertyCache::property(const QHashedCStringRef &str) const
+{
+ QDeclarativePropertyCache::Data **rv = stringCache.value(str);
+ if (rv && (*rv)->notFullyResolved()) resolve(*rv);
+ return rv?*rv:0;
+}
+
+QDeclarativePropertyCache::Data *
QDeclarativePropertyCache::property(const QString &str) const
{
QDeclarativePropertyCache::Data **rv = stringCache.value(str);
diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h
index cdbd49388f..8a1da1929c 100644
--- a/src/declarative/qml/qdeclarativepropertycache_p.h
+++ b/src/declarative/qml/qdeclarativepropertycache_p.h
@@ -172,7 +172,7 @@ public:
void update(QDeclarativeEngine *, const QMetaObject *);
- QDeclarativePropertyCache *copy();
+ QDeclarativePropertyCache *copy(int reserve = 0);
void append(QDeclarativeEngine *, const QMetaObject *, Data::Flag propertyFlags = Data::NoFlags,
Data::Flag methodFlags = Data::NoFlags, Data::Flag signalFlags = Data::NoFlags);
void append(QDeclarativeEngine *, const QMetaObject *, int revision, Data::Flag propertyFlags = Data::NoFlags,
@@ -181,6 +181,8 @@ public:
static Data create(const QMetaObject *, const QString &);
inline Data *property(const QHashedV8String &) const;
+ Data *property(const QHashedStringRef &) const;
+ Data *property(const QHashedCStringRef &) const;
Data *property(const QString &) const;
Data *property(int) const;
Data *method(int) const;
diff --git a/src/declarative/qml/qdeclarativerewrite.cpp b/src/declarative/qml/qdeclarativerewrite.cpp
index bff296b00b..be399dd074 100644
--- a/src/declarative/qml/qdeclarativerewrite.cpp
+++ b/src/declarative/qml/qdeclarativerewrite.cpp
@@ -54,7 +54,6 @@ namespace QDeclarativeRewrite {
bool SharedBindingTester::isSharable(const QString &code)
{
Engine engine;
- NodePool pool(QString(), &engine);
Lexer lexer(&engine);
Parser parser(&engine);
lexer.setCode(code, 0);
@@ -75,7 +74,6 @@ bool SharedBindingTester::isSharable(AST::Node *node)
QString RewriteBinding::operator()(const QString &code, bool *ok, bool *sharable)
{
Engine engine;
- NodePool pool(QString(), &engine);
Lexer lexer(&engine);
Parser parser(&engine);
lexer.setCode(code, 0);
@@ -118,7 +116,7 @@ QString RewriteBinding::operator()(QDeclarativeJS::AST::Node *node, const QStrin
unsigned startOfStatement = 0;
unsigned endOfStatement = (expression ? expression->lastSourceLocation().end() : statement->lastSourceLocation().end()) - _position;
- QString startString = QLatin1String("(function ") + QString::fromUtf8(_name) + QLatin1String("() { ");
+ QString startString = QLatin1String("(function ") + _name + QLatin1String("() { ");
if (expression)
startString += QLatin1String("return ");
_writer->replace(startOfStatement, 0, startString);
@@ -160,7 +158,7 @@ QString RewriteBinding::rewrite(QString code, unsigned position,
unsigned startOfStatement = node->firstSourceLocation().begin() - _position;
unsigned endOfStatement = node->lastSourceLocation().end() - _position;
- _writer->replace(startOfStatement, 0, QLatin1String("(function ") + QString::fromUtf8(_name) + QLatin1String("() { "));
+ _writer->replace(startOfStatement, 0, QLatin1String("(function ") + _name + QLatin1String("() { "));
_writer->replace(endOfStatement, 0, QLatin1String(" })"));
if (rewriteDump()) {
diff --git a/src/declarative/qml/qdeclarativerewrite_p.h b/src/declarative/qml/qdeclarativerewrite_p.h
index 9f4030667c..c57e9956b0 100644
--- a/src/declarative/qml/qdeclarativerewrite_p.h
+++ b/src/declarative/qml/qdeclarativerewrite_p.h
@@ -56,7 +56,7 @@
#include "rewriter/textwriter_p.h"
#include "parser/qdeclarativejslexer_p.h"
#include "parser/qdeclarativejsparser_p.h"
-#include "parser/qdeclarativejsnodepool_p.h"
+#include "parser/qdeclarativejsmemorypool_p.h"
QT_BEGIN_NAMESPACE
@@ -79,14 +79,14 @@ class RewriteBinding: protected AST::Visitor
{
unsigned _position;
TextWriter *_writer;
- QByteArray _name;
+ QString _name;
public:
QString operator()(const QString &code, bool *ok = 0, bool *sharable = 0);
QString operator()(QDeclarativeJS::AST::Node *node, const QString &code, bool *sharable = 0);
//name of the function: used for the debugger
- void setName(const QByteArray &name) { _name = name; }
+ void setName(const QString &name) { _name = name; }
protected:
using AST::Visitor::visit;
diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescript.cpp
index dcd12e287a..55a6b2b2cf 100644
--- a/src/declarative/qml/qdeclarativescriptparser.cpp
+++ b/src/declarative/qml/qdeclarativescript.cpp
@@ -39,13 +39,12 @@
**
****************************************************************************/
-#include "private/qdeclarativescriptparser_p.h"
+#include "private/qdeclarativescript_p.h"
-#include "private/qdeclarativeparser_p.h"
#include "parser/qdeclarativejsengine_p.h"
#include "parser/qdeclarativejsparser_p.h"
#include "parser/qdeclarativejslexer_p.h"
-#include "parser/qdeclarativejsnodepool_p.h"
+#include "parser/qdeclarativejsmemorypool_p.h"
#include "parser/qdeclarativejsastvisitor_p.h"
#include "parser/qdeclarativejsast_p.h"
#include "private/qdeclarativerewrite_p.h"
@@ -57,9 +56,399 @@
QT_BEGIN_NAMESPACE
using namespace QDeclarativeJS;
-using namespace QDeclarativeParser;
+using namespace QDeclarativeScript;
+
+//
+// Parser IR classes
+//
+QDeclarativeScript::Object::Object()
+: type(-1), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1),
+ componentCompileState(0), nextAliasingObject(0), nextIdObject(0)
+{
+}
+
+QDeclarativeScript::Object::~Object()
+{
+ if (synthCache) synthCache->release();
+}
+
+void Object::setBindingBit(int b)
+{
+ while (bindingBitmask.size() < 4 * (1 + b / 32))
+ bindingBitmask.append(char(0));
+
+ quint32 *bits = (quint32 *)bindingBitmask.data();
+ bits[b / 32] |= (1 << (b % 32));
+}
+
+const QMetaObject *Object::metaObject() const
+{
+ if (!metadata.isEmpty() && metatype)
+ return &extObject;
+ else
+ return metatype;
+}
+
+QDeclarativeScript::Property *Object::getDefaultProperty()
+{
+ if (!defaultProperty) {
+ defaultProperty = pool()->New<Property>();
+ defaultProperty->parent = this;
+ }
+ return defaultProperty;
+}
+
+void QDeclarativeScript::Object::addValueProperty(Property *p)
+{
+ valueProperties.append(p);
+}
+
+void QDeclarativeScript::Object::addSignalProperty(Property *p)
+{
+ signalProperties.append(p);
+}
+
+void QDeclarativeScript::Object::addAttachedProperty(Property *p)
+{
+ attachedProperties.append(p);
+}
+
+void QDeclarativeScript::Object::addGroupedProperty(Property *p)
+{
+ groupedProperties.append(p);
+}
+
+void QDeclarativeScript::Object::addValueTypeProperty(Property *p)
+{
+ valueTypeProperties.append(p);
+}
+
+void QDeclarativeScript::Object::addScriptStringProperty(Property *p)
+{
+ scriptStringProperties.append(p);
+}
+
+// This lookup is optimized for missing, and having to create a new property.
+Property *QDeclarativeScript::Object::getProperty(const QHashedStringRef &name, bool create)
+{
+ if (create) {
+ quint32 h = name.hash();
+ if (propertiesHashField.testAndSet(h)) {
+ for (Property *p = properties.first(); p; p = properties.next(p)) {
+ if (p->name() == name)
+ return p;
+ }
+ }
+
+ Property *property = pool()->New<Property>();
+ property->parent = this;
+ property->_name = name;
+ property->isDefault = false;
+ properties.prepend(property);
+ return property;
+ } else {
+ for (Property *p = properties.first(); p; p = properties.next(p)) {
+ if (p->name() == name)
+ return p;
+ }
+ }
+
+ return 0;
+}
+
+Property *QDeclarativeScript::Object::getProperty(const QStringRef &name, bool create)
+{
+ return getProperty(QHashedStringRef(name), create);
+}
+
+Property *QDeclarativeScript::Object::getProperty(const QString &name, bool create)
+{
+ for (Property *p = properties.first(); p; p = properties.next(p)) {
+ if (p->name() == name)
+ return p;
+ }
+
+ if (create) {
+ Property *property = pool()->New<Property>();
+ property->parent = this;
+ property->_name = QStringRef(pool()->NewString(name));
+ propertiesHashField.testAndSet(property->_name.hash());
+ property->isDefault = false;
+ properties.prepend(property);
+ return property;
+ } else {
+ return 0;
+ }
+}
+
+QDeclarativeScript::Object::DynamicProperty::DynamicProperty()
+: isDefaultProperty(false), type(Variant), defaultValue(0), nextProperty(0),
+ resolvedCustomTypeName(0)
+{
+}
+
+QDeclarativeScript::Object::DynamicSignal::DynamicSignal()
+: nextSignal(0)
+{
+}
+
+// Returns length in utf8 bytes
+int QDeclarativeScript::Object::DynamicSignal::parameterTypesLength() const
+{
+ int rv = 0;
+ for (int ii = 0; ii < parameterTypes.count(); ++ii)
+ rv += parameterTypes.at(ii).length();
+ return rv;
+}
+
+// Returns length in utf8 bytes
+int QDeclarativeScript::Object::DynamicSignal::parameterNamesLength() const
+{
+ int rv = 0;
+ for (int ii = 0; ii < parameterNames.count(); ++ii)
+ rv += parameterNames.at(ii).utf8length();
+ return rv;
+}
+
+QDeclarativeScript::Object::DynamicSlot::DynamicSlot()
+: nextSlot(0)
+{
+}
+
+int QDeclarativeScript::Object::DynamicSlot::parameterNamesLength() const
+{
+ int rv = 0;
+ for (int ii = 0; ii < parameterNames.count(); ++ii)
+ rv += parameterNames.at(ii).length();
+ return rv;
+}
+
+QDeclarativeScript::Property::Property()
+: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false),
+ isValueTypeSubProperty(false), isAlias(false), scriptStringScope(-1),
+ nextMainProperty(0), nextProperty(0)
+{
+}
+
+QDeclarativeScript::Object *QDeclarativeScript::Property::getValue(const LocationSpan &l)
+{
+ if (!value) { value = pool()->New<Object>(); value->location = l; }
+ return value;
+}
+
+void QDeclarativeScript::Property::addValue(Value *v)
+{
+ values.append(v);
+}
+
+void QDeclarativeScript::Property::addOnValue(Value *v)
+{
+ onValues.append(v);
+}
+
+bool QDeclarativeScript::Property::isEmpty() const
+{
+ return !value && values.isEmpty() && onValues.isEmpty();
+}
+
+QDeclarativeScript::Value::Value()
+: type(Unknown), object(0), bindingReference(0), signalExpressionContextStack(0), nextValue(0)
+{
+}
+
+QDeclarativeScript::Variant::Variant()
+: t(Invalid)
+{
+}
+
+QDeclarativeScript::Variant::Variant(const Variant &o)
+: t(o.t), d(o.d), asWritten(o.asWritten)
+{
+}
+
+QDeclarativeScript::Variant::Variant(bool v)
+: t(Boolean), b(v)
+{
+}
+
+QDeclarativeScript::Variant::Variant(double v, const QStringRef &asWritten)
+: t(Number), d(v), asWritten(asWritten)
+{
+}
+
+QDeclarativeScript::Variant::Variant(QDeclarativeJS::AST::StringLiteral *v)
+: t(String), l(v)
+{
+}
+
+QDeclarativeScript::Variant::Variant(const QStringRef &asWritten, QDeclarativeJS::AST::Node *n)
+: t(Script), n(n), asWritten(asWritten)
+{
+}
+
+QDeclarativeScript::Variant &QDeclarativeScript::Variant::operator=(const Variant &o)
+{
+ t = o.t;
+ d = o.d;
+ asWritten = o.asWritten;
+ return *this;
+}
+
+QDeclarativeScript::Variant::Type QDeclarativeScript::Variant::type() const
+{
+ return t;
+}
+
+bool QDeclarativeScript::Variant::asBoolean() const
+{
+ return b;
+}
+
+QString QDeclarativeScript::Variant::asString() const
+{
+ if (t == String) {
+ // XXX aakenned
+ return l->value.toString();
+ } else {
+ return asWritten.toString();
+ }
+}
+
+double QDeclarativeScript::Variant::asNumber() const
+{
+ return d;
+}
+
+//reverse of Lexer::singleEscape()
+QString escapedString(const QString &string)
+{
+ QString tmp = QLatin1String("\"");
+ for (int i = 0; i < string.length(); ++i) {
+ const QChar &c = string.at(i);
+ switch(c.unicode()) {
+ case 0x08:
+ tmp += QLatin1String("\\b");
+ break;
+ case 0x09:
+ tmp += QLatin1String("\\t");
+ break;
+ case 0x0A:
+ tmp += QLatin1String("\\n");
+ break;
+ case 0x0B:
+ tmp += QLatin1String("\\v");
+ break;
+ case 0x0C:
+ tmp += QLatin1String("\\f");
+ break;
+ case 0x0D:
+ tmp += QLatin1String("\\r");
+ break;
+ case 0x22:
+ tmp += QLatin1String("\\\"");
+ break;
+ case 0x27:
+ tmp += QLatin1String("\\\'");
+ break;
+ case 0x5C:
+ tmp += QLatin1String("\\\\");
+ break;
+ default:
+ tmp += c;
+ break;
+ }
+ }
+ tmp += QLatin1Char('\"');
+ return tmp;
+}
+
+QString QDeclarativeScript::Variant::asScript() const
+{
+ switch(type()) {
+ default:
+ case Invalid:
+ return QString();
+ case Boolean:
+ return b?QLatin1String("true"):QLatin1String("false");
+ case Number:
+ if (asWritten.isEmpty())
+ return QString::number(d);
+ else
+ return asWritten.toString();
+ case String:
+ return escapedString(asString());
+ case Script:
+ if (AST::IdentifierExpression *i = AST::cast<AST::IdentifierExpression *>(n)) {
+ // XXX aakenned
+ return i->name.toString();
+ } else
+ return asWritten.toString();
+ }
+}
+
+QDeclarativeJS::AST::Node *QDeclarativeScript::Variant::asAST() const
+{
+ if (type() == Script)
+ return n;
+ else
+ return 0;
+}
+
+bool QDeclarativeScript::Variant::isStringList() const
+{
+ if (isString())
+ return true;
+
+ if (type() != Script || !n)
+ return false;
+
+ AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
+ if (!array)
+ return false;
+
+ AST::ElementList *elements = array->elements;
+
+ while (elements) {
-void QDeclarativeScriptParser::Import::extractVersion(int *maj, int *min) const
+ if (!AST::cast<AST::StringLiteral *>(elements->expression))
+ return false;
+
+ elements = elements->next;
+ }
+
+ return true;
+}
+
+QStringList QDeclarativeScript::Variant::asStringList() const
+{
+ QStringList rv;
+ if (isString()) {
+ rv << asString();
+ return rv;
+ }
+
+ AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
+ if (!array)
+ return rv;
+
+ AST::ElementList *elements = array->elements;
+ while (elements) {
+
+ AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(elements->expression);
+ if (!string)
+ return QStringList();
+ rv.append(string->value.toString());
+
+ elements = elements->next;
+ }
+
+ return rv;
+}
+
+//
+// Actual parser classes
+//
+void QDeclarativeScript::Import::extractVersion(int *maj, int *min) const
{
*maj = -1; *min = -1;
@@ -81,16 +470,16 @@ class ProcessAST: protected AST::Visitor
{
struct State {
State() : object(0), property(0) {}
- State(QDeclarativeParser::Object *o) : object(o), property(0) {}
- State(QDeclarativeParser::Object *o, Property *p) : object(o), property(p) {}
+ State(QDeclarativeScript::Object *o) : object(o), property(0) {}
+ State(QDeclarativeScript::Object *o, Property *p) : object(o), property(p) {}
- QDeclarativeParser::Object *object;
+ QDeclarativeScript::Object *object;
Property *property;
};
struct StateStack : public QStack<State>
{
- void pushObject(QDeclarativeParser::Object *obj)
+ void pushObject(QDeclarativeScript::Object *obj)
{
push(State(obj));
}
@@ -100,12 +489,27 @@ class ProcessAST: protected AST::Visitor
const State &state = top();
if (state.property) {
State s(state.property->getValue(location),
- state.property->getValue(location)->getProperty(name.toUtf8()));
+ state.property->getValue(location)->getProperty(name));
s.property->location = location;
push(s);
} else {
- State s(state.object,
- state.object->getProperty(name.toUtf8()));
+ State s(state.object, state.object->getProperty(name));
+
+ s.property->location = location;
+ push(s);
+ }
+ }
+
+ void pushProperty(const QStringRef &name, const LocationSpan &location)
+ {
+ const State &state = top();
+ if (state.property) {
+ State s(state.property->getValue(location),
+ state.property->getValue(location)->getProperty(name));
+ s.property->location = location;
+ push(s);
+ } else {
+ State s(state.object, state.object->getProperty(name));
s.property->location = location;
push(s);
@@ -114,21 +518,21 @@ class ProcessAST: protected AST::Visitor
};
public:
- ProcessAST(QDeclarativeScriptParser *parser);
+ ProcessAST(QDeclarativeScript::Parser *parser);
virtual ~ProcessAST();
void operator()(const QString &code, AST::Node *node);
protected:
- QDeclarativeParser::Object *defineObjectBinding(AST::UiQualifiedId *propertyName, bool onAssignment,
+ QDeclarativeScript::Object *defineObjectBinding(AST::UiQualifiedId *propertyName, bool onAssignment,
const QString &objectType,
AST::SourceLocation typeLocation,
LocationSpan location,
AST::UiObjectInitializer *initializer = 0);
- QDeclarativeParser::Variant getVariant(AST::Statement *stmt);
- QDeclarativeParser::Variant getVariant(AST::ExpressionNode *expr);
+ QDeclarativeScript::Variant getVariant(AST::Statement *stmt);
+ QDeclarativeScript::Variant getVariant(AST::ExpressionNode *expr);
LocationSpan location(AST::SourceLocation start, AST::SourceLocation end);
LocationSpan location(AST::UiQualifiedId *);
@@ -151,18 +555,24 @@ protected:
QString asString(AST::UiQualifiedId *node) const;
const State state() const;
- QDeclarativeParser::Object *currentObject() const;
+ QDeclarativeScript::Object *currentObject() const;
Property *currentProperty() const;
QString qualifiedNameId() const;
QString textAt(const AST::SourceLocation &loc) const
- { return _contents.mid(loc.offset, loc.length); }
+ { return _contents->mid(loc.offset, loc.length); }
+ QStringRef textRefAt(const AST::SourceLocation &loc) const
+ { return QStringRef(_contents, loc.offset, loc.length); }
QString textAt(const AST::SourceLocation &first,
const AST::SourceLocation &last) const
- { return _contents.mid(first.offset, last.offset + last.length - first.offset); }
+ { return _contents->mid(first.offset, last.offset + last.length - first.offset); }
+
+ QStringRef textRefAt(const AST::SourceLocation &first,
+ const AST::SourceLocation &last) const
+ { return QStringRef(_contents, first.offset, last.offset + last.length - first.offset); }
QString asString(AST::ExpressionNode *expr)
{
@@ -172,6 +582,14 @@ protected:
return textAt(expr->firstSourceLocation(), expr->lastSourceLocation());
}
+ QStringRef asStringRef(AST::ExpressionNode *expr)
+ {
+ if (! expr)
+ return QStringRef();
+
+ return textRefAt(expr->firstSourceLocation(), expr->lastSourceLocation());
+ }
+
QString asString(AST::Statement *stmt)
{
if (! stmt)
@@ -182,14 +600,22 @@ protected:
return s;
}
+ QStringRef asStringRef(AST::Statement *stmt)
+ {
+ if (! stmt)
+ return QStringRef();
+
+ return textRefAt(stmt->firstSourceLocation(), stmt->lastSourceLocation());
+ }
+
private:
- QDeclarativeScriptParser *_parser;
+ QDeclarativeScript::Parser *_parser;
StateStack _stateStack;
QStringList _scope;
- QString _contents;
+ const QString *_contents;
};
-ProcessAST::ProcessAST(QDeclarativeScriptParser *parser)
+ProcessAST::ProcessAST(QDeclarativeScript::Parser *parser)
: _parser(parser)
{
}
@@ -200,7 +626,7 @@ ProcessAST::~ProcessAST()
void ProcessAST::operator()(const QString &code, AST::Node *node)
{
- _contents = code;
+ _contents = &code;
accept(node);
}
@@ -217,7 +643,7 @@ const ProcessAST::State ProcessAST::state() const
return _stateStack.back();
}
-QDeclarativeParser::Object *ProcessAST::currentObject() const
+QDeclarativeScript::Object *ProcessAST::currentObject() const
{
return state().object;
}
@@ -237,7 +663,7 @@ QString ProcessAST::asString(AST::UiQualifiedId *node) const
QString s;
for (AST::UiQualifiedId *it = node; it; it = it->next) {
- s.append(it->name->asString());
+ s.append(it->name.toString());
if (it->next)
s.append(QLatin1Char('.'));
@@ -246,7 +672,7 @@ QString ProcessAST::asString(AST::UiQualifiedId *node) const
return s;
}
-QDeclarativeParser::Object *
+QDeclarativeScript::Object *
ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
bool onAssignment,
const QString &objectType,
@@ -262,11 +688,11 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
int propertyCount = 0;
for (AST::UiQualifiedId *name = propertyName; name; name = name->next){
++propertyCount;
- _stateStack.pushProperty(name->name->asString(),
+ _stateStack.pushProperty(name->name,
this->location(name));
}
- if (!onAssignment && propertyCount && currentProperty() && currentProperty()->values.count()) {
+ if (!onAssignment && propertyCount && currentProperty() && !currentProperty()->values.isEmpty()) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Property value set multiple times"));
error.setLine(this->location(propertyName).start.line);
@@ -303,9 +729,9 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
if (lastTypeDot >= 0)
resolvableObjectType.replace(QLatin1Char('.'),QLatin1Char('/'));
- QDeclarativeParser::Object *obj = new QDeclarativeParser::Object;
+ QDeclarativeScript::Object *obj = _parser->_pool.New<QDeclarativeScript::Object>();
- QDeclarativeScriptParser::TypeReference *typeRef = _parser->findOrCreateType(resolvableObjectType);
+ QDeclarativeScript::TypeReference *typeRef = _parser->findOrCreateType(resolvableObjectType);
obj->type = typeRef->id;
typeRef->refObjects.append(obj);
@@ -319,7 +745,7 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
if (propertyCount) {
Property *prop = currentProperty();
- QDeclarativeParser::Value *v = new QDeclarativeParser::Value;
+ QDeclarativeScript::Value *v = _parser->_pool.New<QDeclarativeScript::Value>();
v->object = obj;
v->location = obj->location;
if (onAssignment)
@@ -336,7 +762,7 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
_parser->setTree(obj);
} else {
const State state = _stateStack.top();
- QDeclarativeParser::Value *v = new QDeclarativeParser::Value;
+ QDeclarativeScript::Value *v = _parser->_pool.New<QDeclarativeScript::Value>();
v->object = obj;
v->location = obj->location;
if (state.property) {
@@ -390,18 +816,18 @@ bool ProcessAST::visit(AST::UiProgram *node)
bool ProcessAST::visit(AST::UiImport *node)
{
QString uri;
- QDeclarativeScriptParser::Import import;
+ QDeclarativeScript::Import import;
- if (node->fileName) {
- uri = node->fileName->asString();
+ if (!node->fileName.isNull()) {
+ uri = node->fileName.toString();
if (uri.endsWith(QLatin1String(".js"))) {
- import.type = QDeclarativeScriptParser::Import::Script;
+ import.type = QDeclarativeScript::Import::Script;
} else {
- import.type = QDeclarativeScriptParser::Import::File;
+ import.type = QDeclarativeScript::Import::File;
}
} else {
- import.type = QDeclarativeScriptParser::Import::Library;
+ import.type = QDeclarativeScript::Import::Library;
uri = asString(node->importUri);
}
@@ -409,8 +835,8 @@ bool ProcessAST::visit(AST::UiImport *node)
AST::SourceLocation endLoc = node->semicolonToken;
// Qualifier
- if (node->importId) {
- import.qualifier = node->importId->asString();
+ if (!node->importId.isNull()) {
+ import.qualifier = node->importId.toString();
if (!import.qualifier.at(0).isUpper()) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Invalid import qualifier ID"));
@@ -429,10 +855,10 @@ bool ProcessAST::visit(AST::UiImport *node)
}
// Check for script qualifier clashes
- bool isScript = import.type == QDeclarativeScriptParser::Import::Script;
+ bool isScript = import.type == QDeclarativeScript::Import::Script;
for (int ii = 0; ii < _parser->_imports.count(); ++ii) {
- const QDeclarativeScriptParser::Import &other = _parser->_imports.at(ii);
- bool otherIsScript = other.type == QDeclarativeScriptParser::Import::Script;
+ const QDeclarativeScript::Import &other = _parser->_imports.at(ii);
+ bool otherIsScript = other.type == QDeclarativeScript::Import::Script;
if ((isScript || otherIsScript) && import.qualifier == other.qualifier) {
QDeclarativeError error;
@@ -444,7 +870,7 @@ bool ProcessAST::visit(AST::UiImport *node)
}
}
- } else if (import.type == QDeclarativeScriptParser::Import::Script) {
+ } else if (import.type == QDeclarativeScript::Import::Script) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import requires a qualifier"));
error.setLine(node->fileNameToken.startLine);
@@ -455,7 +881,7 @@ bool ProcessAST::visit(AST::UiImport *node)
if (node->versionToken.isValid()) {
import.version = textAt(node->versionToken);
- } else if (import.type == QDeclarativeScriptParser::Import::Library) {
+ } else if (import.type == QDeclarativeScript::Import::Library) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Library import requires a version"));
error.setLine(node->importIdToken.startLine);
@@ -475,46 +901,61 @@ bool ProcessAST::visit(AST::UiImport *node)
bool ProcessAST::visit(AST::UiPublicMember *node)
{
- const struct TypeNameToType {
+ static const struct TypeNameToType {
const char *name;
+ int nameLength;
Object::DynamicProperty::Type type;
const char *qtName;
+ int qtNameLength;
} propTypeNameToTypes[] = {
- { "int", Object::DynamicProperty::Int, "int" },
- { "bool", Object::DynamicProperty::Bool, "bool" },
- { "double", Object::DynamicProperty::Real, "double" },
- { "real", Object::DynamicProperty::Real, "qreal" },
- { "string", Object::DynamicProperty::String, "QString" },
- { "url", Object::DynamicProperty::Url, "QUrl" },
- { "color", Object::DynamicProperty::Color, "QColor" },
+ { "int", strlen("int"), Object::DynamicProperty::Int, "int", strlen("int") },
+ { "bool", strlen("bool"), Object::DynamicProperty::Bool, "bool", strlen("bool") },
+ { "double", strlen("double"), Object::DynamicProperty::Real, "double", strlen("double") },
+ { "real", strlen("real"), Object::DynamicProperty::Real, "qreal", strlen("qreal") },
+ { "string", strlen("string"), Object::DynamicProperty::String, "QString", strlen("QString") },
+ { "url", strlen("url"), Object::DynamicProperty::Url, "QUrl", strlen("QUrl") },
+ { "color", strlen("color"), Object::DynamicProperty::Color, "QColor", strlen("QColor") },
// Internally QTime, QDate and QDateTime are all supported.
// To be more consistent with JavaScript we expose only
// QDateTime as it matches closely with the Date JS type.
// We also call it "date" to match.
- // { "time", Object::DynamicProperty::Time, "QTime" },
- // { "date", Object::DynamicProperty::Date, "QDate" },
- { "date", Object::DynamicProperty::DateTime, "QDateTime" },
- { "variant", Object::DynamicProperty::Variant, "QVariant" }
+ // { "time", strlen("time"), Object::DynamicProperty::Time, "QTime", strlen("QTime") },
+ // { "date", strlen("date"), Object::DynamicProperty::Date, "QDate", strlen("QDate") },
+ { "date", strlen("date"), Object::DynamicProperty::DateTime, "QDateTime", strlen("QDateTime") },
+ { "variant", strlen("variant"), Object::DynamicProperty::Variant, "QVariant", strlen("QVariant") }
};
- const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
- sizeof(propTypeNameToTypes[0]);
+ static const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
+ sizeof(propTypeNameToTypes[0]);
if(node->type == AST::UiPublicMember::Signal) {
- const QString name = node->name->asString();
-
- Object::DynamicSignal signal;
- signal.name = name.toUtf8();
+ Object::DynamicSignal *signal = _parser->_pool.New<Object::DynamicSignal>();
+ signal->name = node->name;
AST::UiParameterList *p = node->parameters;
+ int paramLength = 0;
+ while (p) { paramLength++; p = p->next; }
+ p = node->parameters;
+
+ if (paramLength) {
+ signal->parameterTypes = _parser->_pool.NewRawList<QHashedCStringRef>(paramLength);
+ signal->parameterNames = _parser->_pool.NewRawList<QHashedStringRef>(paramLength);
+ }
+
+ int index = 0;
while (p) {
- const QString memberType = p->type->asString();
- const char *qtType = 0;
- for(int ii = 0; !qtType && ii < propTypeNameToTypesCount; ++ii) {
- if(QLatin1String(propTypeNameToTypes[ii].name) == memberType)
- qtType = propTypeNameToTypes[ii].qtName;
+ const QStringRef &memberType = p->type;
+
+ const TypeNameToType *type = 0;
+ for(int typeIndex = 0; typeIndex < propTypeNameToTypesCount; ++typeIndex) {
+ const TypeNameToType *t = propTypeNameToTypes + typeIndex;
+ if (t->nameLength == memberType.length() &&
+ QHashedString::compare(memberType.constData(), t->name, t->nameLength)) {
+ type = t;
+ break;
+ }
}
- if (!qtType) {
+ if (!type) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Expected parameter type"));
error.setLine(node->typeToken.startLine);
@@ -523,39 +964,43 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
return false;
}
- signal.parameterTypes << qtType;
- signal.parameterNames << p->name->asString().toUtf8();
- p = p->finish();
+ signal->parameterTypes[index] = QHashedCStringRef(type->qtName, type->qtNameLength);
+ signal->parameterNames[index] = QHashedStringRef(p->name);
+ p = p->next;
+ index++;
}
- signal.location = location(node->typeToken, node->semicolonToken);
- _stateStack.top().object->dynamicSignals << signal;
+ signal->location = location(node->typeToken, node->semicolonToken);
+ _stateStack.top().object->dynamicSignals.append(signal);
} else {
- const QString memberType = node->memberType->asString();
- const QString name = node->name->asString();
+ const QStringRef &memberType = node->memberType;
+ const QStringRef &name = node->name;
bool typeFound = false;
Object::DynamicProperty::Type type;
- if (memberType == QLatin1String("alias")) {
+ if ((unsigned)memberType.length() == strlen("alias") &&
+ QHashedString::compare(memberType.constData(), "alias", strlen("alias"))) {
type = Object::DynamicProperty::Alias;
typeFound = true;
- }
+ }
for(int ii = 0; !typeFound && ii < propTypeNameToTypesCount; ++ii) {
- if(QLatin1String(propTypeNameToTypes[ii].name) == memberType) {
- type = propTypeNameToTypes[ii].type;
+ const TypeNameToType *t = propTypeNameToTypes + ii;
+ if (t->nameLength == memberType.length() &&
+ QHashedString::compare(memberType.constData(), t->name, t->nameLength)) {
+ type = t->type;
typeFound = true;
}
}
if (!typeFound && memberType.at(0).isUpper()) {
- QString typemodifier;
- if(node->typeModifier)
- typemodifier = node->typeModifier->asString();
- if (typemodifier.isEmpty()) {
+ const QStringRef &typeModifier = node->typeModifier;
+
+ if (typeModifier.isEmpty()) {
type = Object::DynamicProperty::Custom;
- } else if(typemodifier == QLatin1String("list")) {
+ } else if((unsigned)typeModifier.length() == strlen("list") &&
+ QHashedString::compare(typeModifier.constData(), "list", strlen("list"))) {
type = Object::DynamicProperty::CustomList;
} else {
QDeclarativeError error;
@@ -566,7 +1011,7 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
return false;
}
typeFound = true;
- } else if (node->typeModifier) {
+ } else if (!node->typeModifier.isNull()) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Unexpected property type modifier"));
error.setLine(node->typeModifierToken.startLine);
@@ -593,33 +1038,35 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
return false;
}
- Object::DynamicProperty property;
- property.isDefaultProperty = node->isDefaultMember;
- property.type = type;
+
+ Object::DynamicProperty *property = _parser->_pool.New<Object::DynamicProperty>();
+ property->isDefaultProperty = node->isDefaultMember;
+ property->type = type;
if (type >= Object::DynamicProperty::Custom) {
- QDeclarativeScriptParser::TypeReference *typeRef =
- _parser->findOrCreateType(memberType);
+ QDeclarativeScript::TypeReference *typeRef =
+ _parser->findOrCreateType(memberType.toString());
typeRef->refObjects.append(_stateStack.top().object);
+ property->customType = memberType;
}
- property.customType = memberType.toUtf8();
- property.name = name.toUtf8();
- property.location = location(node->firstSourceLocation(),
- node->lastSourceLocation());
+
+ property->name = QHashedStringRef(name);
+ property->location = location(node->firstSourceLocation(),
+ node->lastSourceLocation());
if (node->statement) { // default value
- property.defaultValue = new Property;
- property.defaultValue->parent = _stateStack.top().object;
- property.defaultValue->location =
+ property->defaultValue = _parser->_pool.New<Property>();
+ property->defaultValue->parent = _stateStack.top().object;
+ property->defaultValue->location =
location(node->statement->firstSourceLocation(),
node->statement->lastSourceLocation());
- QDeclarativeParser::Value *value = new QDeclarativeParser::Value;
+ QDeclarativeScript::Value *value = _parser->_pool.New<QDeclarativeScript::Value>();
value->location = location(node->statement->firstSourceLocation(),
node->statement->lastSourceLocation());
value->value = getVariant(node->statement);
- property.defaultValue->values << value;
+ property->defaultValue->values.append(value);
}
- _stateStack.top().object->dynamicProperties << property;
+ _stateStack.top().object->dynamicProperties.append(property);
// process QML-like initializers (e.g. property Object o: Object {})
accept(node->binding);
@@ -660,37 +1107,37 @@ bool ProcessAST::visit(AST::UiObjectBinding *node)
return false;
}
-QDeclarativeParser::Variant ProcessAST::getVariant(AST::Statement *stmt)
+QDeclarativeScript::Variant ProcessAST::getVariant(AST::Statement *stmt)
{
if (stmt) {
if (AST::ExpressionStatement *exprStmt = AST::cast<AST::ExpressionStatement *>(stmt))
return getVariant(exprStmt->expression);
- return QDeclarativeParser::Variant(asString(stmt), stmt);
+ return QDeclarativeScript::Variant(asStringRef(stmt), stmt);
}
- return QDeclarativeParser::Variant();
+ return QDeclarativeScript::Variant();
}
-QDeclarativeParser::Variant ProcessAST::getVariant(AST::ExpressionNode *expr)
+QDeclarativeScript::Variant ProcessAST::getVariant(AST::ExpressionNode *expr)
{
if (AST::StringLiteral *lit = AST::cast<AST::StringLiteral *>(expr)) {
- return QDeclarativeParser::Variant(lit->value->asString());
+ return QDeclarativeScript::Variant(lit);
} else if (expr->kind == AST::Node::Kind_TrueLiteral) {
- return QDeclarativeParser::Variant(true);
+ return QDeclarativeScript::Variant(true);
} else if (expr->kind == AST::Node::Kind_FalseLiteral) {
- return QDeclarativeParser::Variant(false);
+ return QDeclarativeScript::Variant(false);
} else if (AST::NumericLiteral *lit = AST::cast<AST::NumericLiteral *>(expr)) {
- return QDeclarativeParser::Variant(lit->value, asString(expr));
+ return QDeclarativeScript::Variant(lit->value, asStringRef(expr));
} else {
if (AST::UnaryMinusExpression *unaryMinus = AST::cast<AST::UnaryMinusExpression *>(expr)) {
if (AST::NumericLiteral *lit = AST::cast<AST::NumericLiteral *>(unaryMinus->expression)) {
- return QDeclarativeParser::Variant(-lit->value, asString(expr));
+ return QDeclarativeScript::Variant(-lit->value, asStringRef(expr));
}
}
- return QDeclarativeParser::Variant(asString(expr), expr);
+ return QDeclarativeScript::Variant(asStringRef(expr), expr);
}
}
@@ -702,13 +1149,13 @@ bool ProcessAST::visit(AST::UiScriptBinding *node)
AST::UiQualifiedId *propertyName = node->qualifiedId;
for (AST::UiQualifiedId *name = propertyName; name; name = name->next){
++propertyCount;
- _stateStack.pushProperty(name->name->asString(),
+ _stateStack.pushProperty(name->name,
location(name));
}
Property *prop = currentProperty();
- if (prop->values.count()) {
+ if (!prop->values.isEmpty()) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Property value set multiple times"));
error.setLine(this->location(propertyName).start.line);
@@ -717,18 +1164,17 @@ bool ProcessAST::visit(AST::UiScriptBinding *node)
return 0;
}
- QDeclarativeParser::Variant primitive;
+ QDeclarativeScript::Variant primitive;
if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement *>(node->statement)) {
primitive = getVariant(stmt->expression);
} else { // do binding
- primitive = QDeclarativeParser::Variant(asString(node->statement),
- node->statement);
+ primitive = QDeclarativeScript::Variant(asStringRef(node->statement), node->statement);
}
prop->location.range.length = prop->location.range.offset + prop->location.range.length - node->qualifiedId->identifierToken.offset;
prop->location.range.offset = node->qualifiedId->identifierToken.offset;
- QDeclarativeParser::Value *v = new QDeclarativeParser::Value;
+ QDeclarativeScript::Value *v = _parser->_pool.New<QDeclarativeScript::Value>();
v->value = primitive;
v->location = location(node->statement->firstSourceLocation(),
node->statement->lastSourceLocation());
@@ -748,13 +1194,13 @@ bool ProcessAST::visit(AST::UiArrayBinding *node)
AST::UiQualifiedId *propertyName = node->qualifiedId;
for (AST::UiQualifiedId *name = propertyName; name; name = name->next){
++propertyCount;
- _stateStack.pushProperty(name->name->asString(),
+ _stateStack.pushProperty(name->name,
location(name));
}
Property* prop = currentProperty();
- if (prop->values.count()) {
+ if (!prop->values.isEmpty()) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Property value set multiple times"));
error.setLine(this->location(propertyName).start.line);
@@ -777,26 +1223,26 @@ bool ProcessAST::visit(AST::UiArrayBinding *node)
bool ProcessAST::visit(AST::UiSourceElement *node)
{
- QDeclarativeParser::Object *obj = currentObject();
+ QDeclarativeScript::Object *obj = currentObject();
if (AST::FunctionDeclaration *funDecl = AST::cast<AST::FunctionDeclaration *>(node->sourceElement)) {
- Object::DynamicSlot slot;
- slot.location = location(funDecl->firstSourceLocation(), funDecl->lastSourceLocation());
+ Object::DynamicSlot *slot = _parser->_pool.New<Object::DynamicSlot>();
+ slot->location = location(funDecl->firstSourceLocation(), funDecl->lastSourceLocation());
AST::FormalParameterList *f = funDecl->formals;
while (f) {
- slot.parameterNames << f->name->asString().toUtf8();
- f = f->finish();
+ slot->parameterNames << f->name.toUtf8();
+ f = f->next;
}
AST::SourceLocation loc = funDecl->rparenToken;
loc.offset = loc.end();
loc.startColumn += 1;
QString body = textAt(loc, funDecl->rbraceToken);
- slot.name = funDecl->name->asString().toUtf8();
- slot.body = body;
- obj->dynamicSlots << slot;
+ slot->name = funDecl->name;
+ slot->body = body;
+ obj->dynamicSlots.append(slot);
} else {
QDeclarativeError error;
@@ -811,28 +1257,30 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
} // end of anonymous namespace
-QDeclarativeScriptParser::QDeclarativeScriptParser()
+QDeclarativeScript::Parser::Parser()
: root(0), data(0)
{
}
-QDeclarativeScriptParser::~QDeclarativeScriptParser()
+QDeclarativeScript::Parser::~Parser()
{
clear();
}
-class QDeclarativeScriptParserJsASTData
+namespace QDeclarativeScript {
+class ParserJsASTData
{
public:
- QDeclarativeScriptParserJsASTData(const QString &filename)
- : nodePool(filename, &engine) {}
+ ParserJsASTData(const QString &filename)
+ : filename(filename) {}
+ QString filename;
Engine engine;
- NodePool nodePool;
};
+}
-bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
+bool QDeclarativeScript::Parser::parse(const QByteArray &qmldata, const QUrl &url)
{
clear();
@@ -843,14 +1291,14 @@ bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
#ifndef QT_NO_TEXTCODEC
stream.setCodec("UTF-8");
#endif
- const QString code = stream.readAll();
+ QString *code = _pool.NewString(stream.readAll());
- data = new QDeclarativeScriptParserJsASTData(fileName);
+ data = new QDeclarativeScript::ParserJsASTData(fileName);
Lexer lexer(&data->engine);
- lexer.setCode(code, /*line = */ 1);
+ lexer.setCode(*code, /*line = */ 1);
- Parser parser(&data->engine);
+ QDeclarativeJS::Parser parser(&data->engine);
if (! parser.parse() || !_errors.isEmpty()) {
@@ -872,7 +1320,7 @@ bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
if (_errors.isEmpty()) {
ProcessAST process(this);
- process(code, parser.ast());
+ process(*code, parser.ast());
// Set the url for process errors
for(int ii = 0; ii < _errors.count(); ++ii)
@@ -882,22 +1330,22 @@ bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
return _errors.isEmpty();
}
-QList<QDeclarativeScriptParser::TypeReference*> QDeclarativeScriptParser::referencedTypes() const
+QList<QDeclarativeScript::TypeReference*> QDeclarativeScript::Parser::referencedTypes() const
{
return _refTypes;
}
-QDeclarativeParser::Object *QDeclarativeScriptParser::tree() const
+QDeclarativeScript::Object *QDeclarativeScript::Parser::tree() const
{
return root;
}
-QList<QDeclarativeScriptParser::Import> QDeclarativeScriptParser::imports() const
+QList<QDeclarativeScript::Import> QDeclarativeScript::Parser::imports() const
{
return _imports;
}
-QList<QDeclarativeError> QDeclarativeScriptParser::errors() const
+QList<QDeclarativeError> QDeclarativeScript::Parser::errors() const
{
return _errors;
}
@@ -910,13 +1358,13 @@ static void replaceWithSpace(QString &str, int idx, int n)
*data++ = space;
}
-static QDeclarativeParser::LocationSpan
+static QDeclarativeScript::LocationSpan
locationFromLexer(const QDeclarativeJS::Lexer &lex, int startLine, int startColumn, int startOffset)
{
- QDeclarativeParser::LocationSpan l;
+ QDeclarativeScript::LocationSpan l;
l.start.line = startLine; l.start.column = startColumn;
- l.end.line = lex.endLineNo(); l.end.column = lex.endColumnNo();
+ l.end.line = lex.tokenEndLine(); l.end.column = lex.tokenEndColumn();
l.range.offset = startOffset;
l.range.length = lex.tokenOffset() + lex.tokenLength() - startOffset;
@@ -928,9 +1376,9 @@ Searches for ".pragma <value>" declarations within \a script. Currently support
are:
library
*/
-QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extractPragmas(QString &script)
+QDeclarativeScript::Object::ScriptBlock::Pragmas QDeclarativeScript::Parser::extractPragmas(QString &script)
{
- QDeclarativeParser::Object::ScriptBlock::Pragmas rv = QDeclarativeParser::Object::ScriptBlock::None;
+ QDeclarativeScript::Object::ScriptBlock::Pragmas rv = QDeclarativeScript::Object::ScriptBlock::None;
const QString pragma(QLatin1String("pragma"));
const QString library(QLatin1String("library"));
@@ -945,30 +1393,30 @@ QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extra
return rv;
int startOffset = l.tokenOffset();
- int startLine = l.currentLineNo();
+ int startLine = l.tokenStartLine();
token = l.lex();
if (token != QDeclarativeJSGrammar::T_IDENTIFIER ||
- l.currentLineNo() != startLine ||
+ l.tokenStartLine() != startLine ||
script.mid(l.tokenOffset(), l.tokenLength()) != pragma)
return rv;
token = l.lex();
if (token != QDeclarativeJSGrammar::T_IDENTIFIER ||
- l.currentLineNo() != startLine)
+ l.tokenStartLine() != startLine)
return rv;
QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
int endOffset = l.tokenLength() + l.tokenOffset();
token = l.lex();
- if (l.currentLineNo() == startLine)
+ if (l.tokenStartLine() == startLine)
return rv;
if (pragmaValue == library) {
- rv |= QDeclarativeParser::Object::ScriptBlock::Shared;
+ rv |= QDeclarativeScript::Object::ScriptBlock::Shared;
replaceWithSpace(script, startOffset, endOffset - startOffset);
} else {
return rv;
@@ -977,7 +1425,7 @@ QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extra
return rv;
}
-#define CHECK_LINE if(l.currentLineNo() != startLine) return rv;
+#define CHECK_LINE if (l.tokenStartLine() != startLine) return rv;
#define CHECK_TOKEN(t) if (token != QDeclarativeJSGrammar:: t) return rv;
static const int uriTokens[] = {
@@ -1031,11 +1479,11 @@ static inline bool isUriToken(int token)
return false;
}
-QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMetaData(QString &script)
+QDeclarativeScript::Parser::JavaScriptMetaData QDeclarativeScript::Parser::extractMetaData(QString &script)
{
JavaScriptMetaData rv;
- QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = rv.pragmas;
+ QDeclarativeScript::Object::ScriptBlock::Pragmas &pragmas = rv.pragmas;
const QString pragma(QLatin1String("pragma"));
const QString js(QLatin1String(".js"));
@@ -1051,8 +1499,8 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
return rv;
int startOffset = l.tokenOffset();
- int startLine = l.startLineNo();
- int startColumn = l.startColumnNo();
+ int startLine = l.tokenStartLine();
+ int startColumn = l.tokenStartColumn();
token = l.lex();
@@ -1069,7 +1517,8 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
if (token == QDeclarativeJSGrammar::T_STRING_LITERAL) {
- QString file(l.characterBuffer(), l.characterCount());
+ QString file = l.tokenText();
+
if (!file.endsWith(js))
return rv;
@@ -1090,11 +1539,11 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
if (!importId.at(0).isUpper())
return rv;
- QDeclarativeParser::LocationSpan location =
+ QDeclarativeScript::LocationSpan location =
locationFromLexer(l, startLine, startColumn, startOffset);
token = l.lex();
- if (l.startLineNo() == startLine)
+ if (l.tokenStartLine() == startLine)
return rv;
replaceWithSpace(script, startOffset, endOffset - startOffset);
@@ -1115,7 +1564,7 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
if (!isUriToken(token))
return rv;
- uri.append(QString(l.characterBuffer(), l.characterCount()));
+ uri.append(l.tokenText());
token = l.lex();
CHECK_LINE;
@@ -1148,11 +1597,11 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
if (!importId.at(0).isUpper())
return rv;
- QDeclarativeParser::LocationSpan location =
+ QDeclarativeScript::LocationSpan location =
locationFromLexer(l, startLine, startColumn, startOffset);
token = l.lex();
- if (l.startLineNo() == startLine)
+ if (l.tokenStartLine() == startLine)
return rv;
replaceWithSpace(script, startOffset, endOffset - startOffset);
@@ -1179,14 +1628,14 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
int endOffset = l.tokenLength() + l.tokenOffset();
if (pragmaValue == library) {
- pragmas |= QDeclarativeParser::Object::ScriptBlock::Shared;
+ pragmas |= QDeclarativeScript::Object::ScriptBlock::Shared;
replaceWithSpace(script, startOffset, endOffset - startOffset);
} else {
return rv;
}
token = l.lex();
- if (l.currentLineNo() == startLine)
+ if (l.tokenStartLine() == startLine)
return rv;
} else {
@@ -1196,12 +1645,8 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
return rv;
}
-void QDeclarativeScriptParser::clear()
+void QDeclarativeScript::Parser::clear()
{
- if (root) {
- root->release();
- root = 0;
- }
_imports.clear();
qDeleteAll(_refTypes);
_refTypes.clear();
@@ -1211,9 +1656,11 @@ void QDeclarativeScriptParser::clear()
delete data;
data = 0;
}
+
+ _pool.clear();
}
-QDeclarativeScriptParser::TypeReference *QDeclarativeScriptParser::findOrCreateType(const QString &name)
+QDeclarativeScript::TypeReference *QDeclarativeScript::Parser::findOrCreateType(const QString &name)
{
TypeReference *type = 0;
int i = 0;
@@ -1231,7 +1678,7 @@ QDeclarativeScriptParser::TypeReference *QDeclarativeScriptParser::findOrCreateT
return type;
}
-void QDeclarativeScriptParser::setTree(QDeclarativeParser::Object *tree)
+void QDeclarativeScript::Parser::setTree(QDeclarativeScript::Object *tree)
{
Q_ASSERT(! root);
diff --git a/src/declarative/qml/qdeclarativescript_p.h b/src/declarative/qml/qdeclarativescript_p.h
new file mode 100644
index 0000000000..3aff31789a
--- /dev/null
+++ b/src/declarative/qml/qdeclarativescript_p.h
@@ -0,0 +1,526 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QDECLARATIVESCRIPT_P_H
+#define QDECLARATIVESCRIPT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtDeclarative/qdeclarativeerror.h>
+
+#include <private/qfieldlist_p.h>
+#include <private/qhashfield_p.h>
+#include <private/qfastmetabuilder_p.h>
+#include <private/qdeclarativepool_p.h>
+#include <private/qdeclarativepropertycache_p.h>
+
+#include <QtCore/QList>
+#include <QtCore/QUrl>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QByteArray;
+class QDeclarativePropertyCache;
+namespace QDeclarativeJS { namespace AST { class Node; class StringLiteral; } }
+namespace QDeclarativeCompilerTypes { class BindingReference; class ComponentCompileState; }
+
+namespace QDeclarativeScript {
+
+struct Location
+{
+ Location() : line(-1), column(-1) {}
+ int line;
+ int column;
+
+ inline bool operator<(const Location &other) {
+ return line < other.line ||
+ (line == other.line && column < other.column);
+ }
+};
+
+struct LocationRange
+{
+ LocationRange() : offset(0), length(0) {}
+ quint32 offset;
+ quint32 length;
+};
+
+struct LocationSpan
+{
+ Location start;
+ Location end;
+ LocationRange range;
+
+ bool operator<(LocationSpan &o) const {
+ return (start.line < o.start.line) ||
+ (start.line == o.start.line && start.column < o.start.column);
+ }
+};
+
+class Import
+{
+public:
+ Import() : type(Library) {}
+
+ enum Type { Library, File, Script };
+ Type type;
+
+ QString uri;
+ QString qualifier;
+ QString version;
+
+ void extractVersion(int *maj, int *min) const;
+
+ QDeclarativeScript::LocationSpan location;
+};
+
+class Object;
+class TypeReference
+{
+public:
+ TypeReference(int typeId, const QString &typeName) : id(typeId), name(typeName) {}
+
+ int id;
+ // type as it has been referenced in Qml
+ QString name;
+ // objects in parse tree referencing the type
+ QList<QDeclarativeScript::Object*> refObjects;
+};
+
+class Object;
+class Property;
+
+class Q_DECLARATIVE_EXPORT Variant
+{
+public:
+ enum Type {
+ Invalid,
+ Boolean,
+ Number,
+ String,
+ Script
+ };
+
+ Variant();
+ Variant(const Variant &);
+ explicit Variant(bool);
+ explicit Variant(double, const QStringRef &asWritten = QStringRef());
+ explicit Variant(QDeclarativeJS::AST::StringLiteral *);
+ explicit Variant(const QStringRef &asWritten, QDeclarativeJS::AST::Node *);
+ Variant &operator=(const Variant &);
+
+ Type type() const;
+
+ bool isBoolean() const { return type() == Boolean; }
+ bool isNumber() const { return type() == Number; }
+ bool isString() const { return type() == String; }
+ bool isScript() const { return type() == Script; }
+ bool isStringList() const;
+
+ bool asBoolean() const;
+ QString asString() const;
+ double asNumber() const;
+ QString asScript() const;
+ QDeclarativeJS::AST::Node *asAST() const;
+ QStringList asStringList() const;
+
+private:
+ Type t;
+ union {
+ bool b;
+ double d;
+ QDeclarativeJS::AST::StringLiteral *l;
+ QDeclarativeJS::AST::Node *n;
+ };
+ QStringRef asWritten;
+};
+
+class Value : public QDeclarativePool::POD
+{
+public:
+ Value();
+
+ enum Type {
+ // The type of this value assignment is not yet known
+ Unknown,
+ // This is used as a literal property assignment
+ Literal,
+ // This is used as a property binding assignment
+ PropertyBinding,
+ // This is used as a QDeclarativePropertyValueSource assignment
+ ValueSource,
+ // This is used as a QDeclarativePropertyValueInterceptor assignment
+ ValueInterceptor,
+ // This is used as a property QObject assignment
+ CreatedObject,
+ // This is used as a signal object assignment
+ SignalObject,
+ // This is used as a signal expression assignment
+ SignalExpression,
+ // This is used as an id assignment only
+ Id
+ };
+ Type type;
+
+ // ### Temporary (for id only)
+ QString primitive() const { return value.isString() ? value.asString() : value.asScript(); }
+
+ // Primitive value
+ Variant value;
+ // Object value
+ Object *object;
+
+ LocationSpan location;
+
+ // Used by compiler
+ QDeclarativeCompilerTypes::BindingReference *bindingReference;
+ int signalExpressionContextStack;
+
+ // Used in Property::ValueList lists
+ Value *nextValue;
+};
+
+class Property : public QDeclarativePool::POD
+{
+public:
+ Property();
+
+ // The Object to which this property is attached
+ Object *parent;
+
+ Object *getValue(const LocationSpan &);
+ void addValue(Value *v);
+ void addOnValue(Value *v);
+
+ // The QVariant::Type of the property, or 0 (QVariant::Invalid) if
+ // unknown.
+ int type;
+ // The metaobject index of this property, or -1 if unknown.
+ int index;
+ // The core data in the case of a regular property.
+ // XXX This has to be a value now as the synthCache may change during
+ // compilation which invalidates pointers. We should fix this.
+ QDeclarativePropertyCache::Data core;
+
+ // Returns true if this is an empty property - both value and values
+ // are unset.
+ bool isEmpty() const;
+
+ typedef QFieldList<Value, &Value::nextValue> ValueList;
+ // The list of values assigned to this property. Content in values
+ // and value are mutually exclusive
+ ValueList values;
+ // The list of values assigned to this property using the "on" syntax
+ ValueList onValues;
+ // The accessed property. This is used to represent dot properties.
+ // Content in value and values are mutually exclusive.
+ Object *value;
+ // The property name
+ const QHashedStringRef &name() const { return _name; }
+ void setName(const QString &n) { _name = QHashedStringRef(pool()->NewString(n)); }
+ void setName(const QHashedStringRef &n) { _name = n; }
+ // True if this property was accessed as the default property.
+ bool isDefault;
+ // True if the setting of this property will be deferred. Set by the
+ // QDeclarativeCompiler
+ bool isDeferred;
+ // True if this property is a value-type pseudo-property
+ bool isValueTypeSubProperty;
+ // True if this property is a property alias. Set by the
+ // QDeclarativeCompiler
+ bool isAlias;
+
+ // Used for scriptStringProperties
+ int scriptStringScope;
+
+ LocationSpan location;
+ LocationRange listValueRange;
+
+ // Used in Object::MainPropertyList
+ Property *nextMainProperty;
+
+ // Used in Object::PropertyList lists
+ Property *nextProperty;
+
+private:
+ friend class Object;
+ QHashedStringRef _name;
+};
+
+class Object : public QDeclarativePool::Class
+{
+public:
+ Object();
+ virtual ~Object();
+
+ // Type of the object. The integer is an index into the
+ // QDeclarativeCompiledData::types array, or -1 if the object is a property
+ // group.
+ int type;
+
+ // The fully-qualified name of this type
+ QByteArray typeName;
+ // The id assigned to the object (if any). Set by the QDeclarativeCompiler
+ QString id;
+ // The id index assigned to the object (if any). Set by the QDeclarativeCompiler
+ int idIndex;
+ // Custom parsed data
+ QByteArray custom;
+ // Bit mask of the properties assigned bindings
+ QByteArray bindingBitmask;
+ void setBindingBit(int);
+ // Returns the metaobject for this type, or 0 if not available.
+ // Internally selectd between the metatype and extObject variables
+ const QMetaObject *metaObject() const;
+
+ // The compile time metaobject for this type
+ const QMetaObject *metatype;
+ // The synthesized metaobject, if QML added signals or properties to
+ // this type. Otherwise null
+ QAbstractDynamicMetaObject extObject;
+ QByteArray metadata; // Generated by compiler
+ QByteArray synthdata; // Generated by compiler
+ QDeclarativePropertyCache *synthCache; // Generated by compiler
+
+ Property *getDefaultProperty();
+ // name ptr must be guarenteed to remain valid
+ Property *getProperty(const QHashedStringRef &name, bool create=true);
+ Property *getProperty(const QStringRef &name, bool create=true);
+ Property *getProperty(const QString &name, bool create=true);
+
+ Property *defaultProperty;
+
+ typedef QFieldList<Property, &Property::nextMainProperty> MainPropertyList;
+ MainPropertyList properties;
+ QHashField propertiesHashField;
+
+ // Output of the compilation phase (these properties continue to exist
+ // in either the defaultProperty or properties members too)
+ void addValueProperty(Property *);
+ void addSignalProperty(Property *);
+ void addAttachedProperty(Property *);
+ void addGroupedProperty(Property *);
+ void addValueTypeProperty(Property *);
+ void addScriptStringProperty(Property *);
+
+ typedef QFieldList<Property, &Property::nextProperty> PropertyList;
+ PropertyList valueProperties;
+ PropertyList signalProperties;
+ PropertyList attachedProperties;
+ PropertyList groupedProperties;
+ PropertyList valueTypeProperties;
+ PropertyList scriptStringProperties;
+
+ // Script blocks that were nested under this object
+ struct ScriptBlock {
+ enum Pragma {
+ None = 0x00000000,
+ Shared = 0x00000001
+ };
+ Q_DECLARE_FLAGS(Pragmas, Pragma)
+
+ QString code;
+ QString file;
+ Pragmas pragmas;
+ };
+
+ // The bytes to cast instances by to get to the QDeclarativeParserStatus
+ // interface. -1 indicates the type doesn't support this interface.
+ // Set by the QDeclarativeCompiler.
+ int parserStatusCast;
+
+ LocationSpan location;
+
+ struct DynamicProperty : public QDeclarativePool::POD
+ {
+ DynamicProperty();
+
+ enum Type { Variant, Int, Bool, Real, String, Url, Color, Time,
+ Date, DateTime, Alias, Custom, CustomList };
+
+ bool isDefaultProperty;
+ Type type;
+
+ QHashedStringRef customType;
+ QHashedStringRef name;
+ QDeclarativeScript::Property *defaultValue;
+ LocationSpan location;
+
+ // Used by Object::DynamicPropertyList
+ DynamicProperty *nextProperty;
+
+ // Used by the compiler
+ QByteArray *resolvedCustomTypeName;
+ QFastMetaBuilder::StringRef typeRef;
+ QFastMetaBuilder::StringRef nameRef;
+ QFastMetaBuilder::StringRef changedSignatureRef;
+ };
+
+ struct DynamicSignal : public QDeclarativePool::POD
+ {
+ DynamicSignal();
+
+ QHashedStringRef name;
+ QDeclarativePool::List<QHashedCStringRef> parameterTypes;
+ QDeclarativePool::List<QHashedStringRef> parameterNames;
+
+ int parameterTypesLength() const;
+ int parameterNamesLength() const;
+
+ // Used by Object::DynamicSignalList
+ DynamicSignal *nextSignal;
+
+ // Used by the compiler
+ QFastMetaBuilder::StringRef signatureRef;
+ QFastMetaBuilder::StringRef parameterNamesRef;
+ LocationSpan location;
+ };
+
+ struct DynamicSlot : public QDeclarativePool::Class
+ {
+ DynamicSlot();
+
+ QHashedStringRef name;
+ QString body;
+ QList<QByteArray> parameterNames;
+ LocationSpan location;
+
+ int parameterNamesLength() const;
+
+ // Used by Object::DynamicSlotList
+ DynamicSlot *nextSlot;
+
+ // Used by the compiler
+ QFastMetaBuilder::StringRef signatureRef;
+ QFastMetaBuilder::StringRef parameterNamesRef;
+ };
+
+ // The list of dynamic properties
+ typedef QFieldList<DynamicProperty, &DynamicProperty::nextProperty> DynamicPropertyList;
+ DynamicPropertyList dynamicProperties;
+ // The list of dynamic signals
+ typedef QFieldList<DynamicSignal, &DynamicSignal::nextSignal> DynamicSignalList;
+ DynamicSignalList dynamicSignals;
+ // The list of dynamic slots
+ typedef QFieldList<DynamicSlot, &DynamicSlot::nextSlot> DynamicSlotList;
+ DynamicSlotList dynamicSlots;
+
+ // Used by compiler
+ QDeclarativeCompilerTypes::ComponentCompileState *componentCompileState;
+
+ // Used by ComponentCompileState::AliasingObjectsList
+ Object *nextAliasingObject;
+ // Used by ComponentComppileState::IdList
+ Object *nextIdObject;
+};
+
+class ParserJsASTData;
+class Q_AUTOTEST_EXPORT Parser
+{
+public:
+ Parser();
+ ~Parser();
+
+ bool parse(const QByteArray &data, const QUrl &url = QUrl());
+
+ QList<TypeReference*> referencedTypes() const;
+
+ QDeclarativeScript::Object *tree() const;
+ QList<Import> imports() const;
+
+ void clear();
+
+ QList<QDeclarativeError> errors() const;
+
+ class JavaScriptMetaData {
+ public:
+ JavaScriptMetaData()
+ : pragmas(QDeclarativeScript::Object::ScriptBlock::None) {}
+
+ QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas;
+ QList<Import> imports;
+ };
+
+ static QDeclarativeScript::Object::ScriptBlock::Pragmas extractPragmas(QString &);
+ static JavaScriptMetaData extractMetaData(QString &);
+
+
+// ### private:
+ TypeReference *findOrCreateType(const QString &name);
+ void setTree(QDeclarativeScript::Object *tree);
+
+ void setScriptFile(const QString &filename) {_scriptFile = filename; }
+ QString scriptFile() const { return _scriptFile; }
+
+// ### private:
+ QList<QDeclarativeError> _errors;
+
+ QDeclarativePool _pool;
+ QDeclarativeScript::Object *root;
+ QList<Import> _imports;
+ QList<TypeReference*> _refTypes;
+ QString _scriptFile;
+ ParserJsASTData *data;
+};
+
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeScript::Object::ScriptBlock::Pragmas);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QDeclarativeScript::Variant)
+
+QT_END_HEADER
+
+#endif // QDECLARATIVESCRIPT_P_H
diff --git a/src/declarative/qml/qdeclarativescriptparser_p.h b/src/declarative/qml/qdeclarativescriptparser_p.h
deleted file mode 100644
index 73e797635a..0000000000
--- a/src/declarative/qml/qdeclarativescriptparser_p.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QDECLARATIVESCRIPTPARSER_P_H
-#define QDECLARATIVESCRIPTPARSER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qdeclarativeerror.h"
-#include "private/qdeclarativeparser_p.h"
-
-#include <QtCore/QList>
-#include <QtCore/QUrl>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QByteArray;
-
-class QDeclarativeScriptParserJsASTData;
-class Q_AUTOTEST_EXPORT QDeclarativeScriptParser
-{
-public:
- class Import
- {
- public:
- Import() : type(Library) {}
-
- enum Type { Library, File, Script };
- Type type;
-
- QString uri;
- QString qualifier;
- QString version;
-
- void extractVersion(int *maj, int *min) const;
-
- QDeclarativeParser::LocationSpan location;
- };
-
- class TypeReference
- {
- public:
- TypeReference(int typeId, const QString &typeName) : id(typeId), name(typeName) {}
-
- int id;
- // type as it has been referenced in Qml
- QString name;
- // objects in parse tree referencing the type
- QList<QDeclarativeParser::Object*> refObjects;
- };
-
- QDeclarativeScriptParser();
- ~QDeclarativeScriptParser();
-
- bool parse(const QByteArray &data, const QUrl &url = QUrl());
-
- QList<TypeReference*> referencedTypes() const;
-
- QDeclarativeParser::Object *tree() const;
- QList<Import> imports() const;
-
- void clear();
-
- QList<QDeclarativeError> errors() const;
-
- class JavaScriptMetaData {
- public:
- JavaScriptMetaData()
- : pragmas(QDeclarativeParser::Object::ScriptBlock::None) {}
-
- QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas;
- QList<Import> imports;
- };
-
- static QDeclarativeParser::Object::ScriptBlock::Pragmas extractPragmas(QString &);
- static JavaScriptMetaData extractMetaData(QString &);
-
-
-// ### private:
- TypeReference *findOrCreateType(const QString &name);
- void setTree(QDeclarativeParser::Object *tree);
-
- void setScriptFile(const QString &filename) {_scriptFile = filename; }
- QString scriptFile() const { return _scriptFile; }
-
-// ### private:
- QList<QDeclarativeError> _errors;
-
- QDeclarativeParser::Object *root;
- QList<Import> _imports;
- QList<TypeReference*> _refTypes;
- QString _scriptFile;
- QDeclarativeScriptParserJsASTData *data;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDECLARATIVESCRIPTPARSER_P_H
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index 97c5b38c20..8bb40ce7a5 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -51,9 +51,94 @@
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
+#include <QtCore/qdiriterator.h>
+
+#if defined (Q_OS_UNIX)
+#include <sys/types.h>
+#include <dirent.h>
+#endif
QT_BEGIN_NAMESPACE
+
+/*
+Returns the set of QML files in path (qmldir, *.qml, *.js). The caller
+is responsible for deleting the returned data.
+Returns 0 if the directory does not exist.
+*/
+#if defined (Q_OS_UNIX) && !defined(Q_OS_DARWIN)
+static QStringHash<bool> *qmlFilesInDirectory(const QString &path)
+{
+ QByteArray name(QFile::encodeName(path));
+ DIR *dd = opendir(name);
+ if (!dd)
+ return 0;
+
+ struct dirent *result;
+ union {
+ struct dirent d;
+ char b[offsetof (struct dirent, d_name) + NAME_MAX + 1];
+ } u;
+
+ QStringHash<bool> *files = new QStringHash<bool>;
+ while (readdir_r(dd, &u.d, &result) == 0 && result != 0) {
+ if (!strcmp(u.d.d_name, "qmldir")) {
+ files->insert(QLatin1String("qmldir"), true);
+ continue;
+ }
+ int len = strlen(u.d.d_name);
+ if (len < 4)
+ continue;
+ if (!strcmp(u.d.d_name+len-4, ".qml") || !strcmp(u.d.d_name+len-3, ".js"))
+ files->insert(QFile::decodeName(u.d.d_name), true);
+#if defined(Q_OS_DARWIN)
+ else if ((len > 6 && !strcmp(u.d.d_name+len-6, ".dylib")) || !strcmp(u.d.d_name+len-3, ".so")
+ || (len > 7 && !strcmp(u.d.d_name+len-7, ".bundle")))
+ files->insert(QFile::decodeName(u.d.d_name), true);
+#else // Unix
+ else if (!strcmp(u.d.d_name+len-3, ".so") || !strcmp(u.d.d_name+len-3, ".sl"))
+ files->insert(QFile::decodeName(u.d.d_name), true);
+#endif
+ }
+
+ closedir(dd);
+ return files;
+}
+#else
+static QStringHash<bool> *qmlFilesInDirectory(const QString &path)
+{
+ QDirIterator dir(path, QDir::Files);
+ if (!dir.hasNext())
+ return 0;
+ QStringHash<bool> *files = new QStringHash<bool>;
+ while (dir.hasNext()) {
+ dir.next();
+ QString fileName = dir.fileName();
+ if (fileName == QLatin1String("qmldir")
+ || fileName.endsWith(QLatin1String(".qml"))
+ || fileName.endsWith(QLatin1String(".js"))
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+ || fileName.endsWith(QLatin1String(".dll"))
+#elif defined(Q_OS_DARWIN)
+ || fileName.endsWith(QLatin1String(".dylib"))
+ || fileName.endsWith(QLatin1String(".so"))
+ || fileName.endsWith(QLatin1String(".bundle"))
+#else // Unix
+ || fileName.endsWith(QLatin1String(".so"))
+ || fileName.endsWith(QLatin1String(".sl"))
+#endif
+ ) {
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN)
+ fileName = fileName.toLower();
+#endif
+ files->insert(fileName, true);
+ }
+ }
+ return files;
+}
+#endif
+
+
/*!
\class QDeclarativeDataBlob
\brief The QDeclarativeDataBlob encapsulates a data request that can be issued to a QDeclarativeDataLoader.
@@ -723,6 +808,113 @@ QDeclarativeQmldirData *QDeclarativeTypeLoader::getQmldir(const QUrl &url)
}
/*!
+Returns the absolute filename of path via a directory cache for files named
+"qmldir", "*.qml", "*.js", and plugins.
+Returns a empty string if the path does not exist.
+*/
+QString QDeclarativeTypeLoader::absoluteFilePath(const QString &path)
+{
+ if (path.isEmpty())
+ return QString();
+ if (path.at(0) == QLatin1Char(':')) {
+ // qrc resource
+ QFileInfo fileInfo(path);
+ return fileInfo.isFile() ? fileInfo.absoluteFilePath() : QString();
+ }
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN)
+ QString lowPath = path.toLower();
+ int lastSlash = lowPath.lastIndexOf(QLatin1Char('/'));
+ QString dirPath = lowPath.left(lastSlash);
+#else
+ int lastSlash = path.lastIndexOf(QLatin1Char('/'));
+ QStringRef dirPath(&path, 0, lastSlash);
+#endif
+
+ StringSet **fileSet = m_importDirCache.value(QHashedStringRef(dirPath.constData(), dirPath.length()));
+ if (!fileSet) {
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN)
+ QHashedString dirPathString(dirPath);
+#else
+ QHashedString dirPathString(dirPath.toString());
+#endif
+ StringSet *files = qmlFilesInDirectory(dirPathString);
+ m_importDirCache.insert(dirPathString, files);
+ fileSet = m_importDirCache.value(dirPathString);
+ }
+ if (!(*fileSet))
+ return QString();
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN)
+ QString absoluteFilePath = (*fileSet)->contains(QHashedStringRef(lowPath.constData()+lastSlash+1, lowPath.length()-lastSlash-1)) ? path : QString();
+#else
+ QString absoluteFilePath = (*fileSet)->contains(QHashedStringRef(path.constData()+lastSlash+1, path.length()-lastSlash-1)) ? path : QString();
+#endif
+ if (absoluteFilePath.length() > 2 && absoluteFilePath.at(0) != QLatin1Char('/') && absoluteFilePath.at(1) != QLatin1Char(':'))
+ absoluteFilePath = QFileInfo(absoluteFilePath).absoluteFilePath();
+
+ return absoluteFilePath;
+}
+
+/*!
+Returns true if the path is a directory via a directory cache. Cache is
+shared with absoluteFilePath().
+*/
+bool QDeclarativeTypeLoader::directoryExists(const QString &path)
+{
+ if (path.isEmpty())
+ return false;
+ if (path.at(0) == QLatin1Char(':')) {
+ // qrc resource
+ QFileInfo fileInfo(path);
+ return fileInfo.exists() && fileInfo.isDir();
+ }
+
+ int length = path.length();
+ if (path.endsWith(QLatin1Char('/')))
+ --length;
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN)
+ QString dirPath = path.left(length).toLower();
+#else
+ QStringRef dirPath(&path, 0, length);
+#endif
+
+ StringSet **fileSet = m_importDirCache.value(QHashedStringRef(dirPath.constData(), dirPath.length()));
+ if (!fileSet) {
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_DARWIN)
+ QHashedString dirPathString(dirPath);
+#else
+ QHashedString dirPathString(dirPath.toString());
+#endif
+ StringSet *files = qmlFilesInDirectory(dirPathString);
+ m_importDirCache.insert(dirPathString, files);
+ fileSet = m_importDirCache.value(dirPathString);
+ }
+
+ return (*fileSet);
+}
+
+
+/*!
+Return a QDeclarativeDirParser for absoluteFilePath. The QDeclarativeDirParser may be cached.
+*/
+const QDeclarativeDirParser *QDeclarativeTypeLoader::qmlDirParser(const QString &absoluteFilePath)
+{
+ QDeclarativeDirParser *qmldirParser;
+ QDeclarativeDirParser **val = m_importQmlDirCache.value(absoluteFilePath);
+ if (!val) {
+ qmldirParser = new QDeclarativeDirParser;
+ qmldirParser->setFileSource(absoluteFilePath);
+ qmldirParser->setUrl(QUrl::fromLocalFile(absoluteFilePath));
+ qmldirParser->parse();
+ m_importQmlDirCache.insert(absoluteFilePath, qmldirParser);
+ } else {
+ qmldirParser = *val;
+ }
+
+ return qmldirParser;
+}
+
+/*!
Clears cached information about loaded files, including any type data, scripts
and qmldir information.
*/
@@ -734,17 +926,21 @@ void QDeclarativeTypeLoader::clearCache()
(*iter)->release();
for (QmldirCache::Iterator iter = m_qmldirCache.begin(); iter != m_qmldirCache.end(); ++iter)
(*iter)->release();
+ qDeleteAll(m_importDirCache);
+ qDeleteAll(m_importQmlDirCache);
m_typeCache.clear();
m_scriptCache.clear();
m_qmldirCache.clear();
+ m_importDirCache.clear();
+ m_importQmlDirCache.clear();
}
QDeclarativeTypeData::QDeclarativeTypeData(const QUrl &url, QDeclarativeTypeLoader::Options options,
QDeclarativeTypeLoader *manager)
-: QDeclarativeDataBlob(url, QmlFile), m_options(options), m_typesResolved(false),
- m_compiledData(0), m_typeLoader(manager)
+: QDeclarativeDataBlob(url, QmlFile), m_options(options), m_imports(manager), m_typesResolved(false),
+ m_compiledData(0), m_typeLoader(manager)
{
}
@@ -770,7 +966,7 @@ const QDeclarativeImports &QDeclarativeTypeData::imports() const
return m_imports;
}
-const QDeclarativeScriptParser &QDeclarativeTypeData::parser() const
+const QDeclarativeScript::Parser &QDeclarativeTypeData::parser() const
{
return scriptParser;
}
@@ -869,15 +1065,15 @@ void QDeclarativeTypeData::dataReceived(const QByteArray &data)
m_imports.setBaseUrl(finalUrl());
- foreach (const QDeclarativeScriptParser::Import &import, scriptParser.imports()) {
- if (import.type == QDeclarativeScriptParser::Import::File && import.qualifier.isEmpty()) {
+ foreach (const QDeclarativeScript::Import &import, scriptParser.imports()) {
+ if (import.type == QDeclarativeScript::Import::File && import.qualifier.isEmpty()) {
QUrl importUrl = finalUrl().resolved(QUrl(import.uri + QLatin1String("/qmldir")));
if (QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl).isEmpty()) {
QDeclarativeQmldirData *data = typeLoader()->getQmldir(importUrl);
addDependency(data);
m_qmldirs << data;
}
- } else if (import.type == QDeclarativeScriptParser::Import::Script) {
+ } else if (import.type == QDeclarativeScript::Import::Script) {
QUrl scriptUrl = finalUrl().resolved(QUrl(import.uri));
QDeclarativeScriptBlob *blob = typeLoader()->getScript(scriptUrl);
addDependency(blob);
@@ -928,7 +1124,7 @@ void QDeclarativeTypeData::compile()
m_compiledData->name = m_compiledData->url.toString();
QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Compiling, m_compiledData->name);
- QDeclarativeCompiler compiler;
+ QDeclarativeCompiler compiler(&scriptParser._pool);
if (!compiler.compile(typeLoader()->engine(), this, m_compiledData)) {
setError(compiler.errors());
m_compiledData->release();
@@ -948,11 +1144,11 @@ void QDeclarativeTypeData::resolveTypes()
QList<QDeclarativeError> errors;
if (QDeclarativeQmldirData *qmldir = qmldirForUrl(finalUrl().resolved(QUrl(QLatin1String("./qmldir"))))) {
m_imports.addImport(importDatabase, QLatin1String("."),
- QString(), -1, -1, QDeclarativeScriptParser::Import::File,
+ QString(), -1, -1, QDeclarativeScript::Import::File,
qmldir->dirComponents(), &errors);
} else {
m_imports.addImport(importDatabase, QLatin1String("."),
- QString(), -1, -1, QDeclarativeScriptParser::Import::File,
+ QString(), -1, -1, QDeclarativeScript::Import::File,
QDeclarativeDirComponents(), &errors);
}
@@ -972,12 +1168,12 @@ void QDeclarativeTypeData::resolveTypes()
return;
}
- foreach (const QDeclarativeScriptParser::Import &import, scriptParser.imports()) {
+ foreach (const QDeclarativeScript::Import &import, scriptParser.imports()) {
QDeclarativeDirComponents qmldircomponentsnetwork;
- if (import.type == QDeclarativeScriptParser::Import::Script)
+ if (import.type == QDeclarativeScript::Import::Script)
continue;
- if (import.type == QDeclarativeScriptParser::Import::File && import.qualifier.isEmpty()) {
+ if (import.type == QDeclarativeScript::Import::File && import.qualifier.isEmpty()) {
QUrl qmldirUrl = finalUrl().resolved(QUrl(import.uri + QLatin1String("/qmldir")));
if (QDeclarativeQmldirData *qmldir = qmldirForUrl(qmldirUrl))
qmldircomponentsnetwork = qmldir->dirComponents();
@@ -1008,18 +1204,16 @@ void QDeclarativeTypeData::resolveTypes()
}
}
- foreach (QDeclarativeScriptParser::TypeReference *parserRef, scriptParser.referencedTypes()) {
- QByteArray typeName = parserRef->name.toUtf8();
-
+ foreach (QDeclarativeScript::TypeReference *parserRef, scriptParser.referencedTypes()) {
TypeReference ref;
- QUrl url;
+ QString url;
int majorVersion;
int minorVersion;
QDeclarativeImportedNamespace *typeNamespace = 0;
QList<QDeclarativeError> errors;
- if (!m_imports.resolveType(typeName, &ref.type, &url, &majorVersion, &minorVersion,
+ if (!m_imports.resolveType(parserRef->name, &ref.type, &url, &majorVersion, &minorVersion,
&typeNamespace, &errors) || typeNamespace) {
// Known to not be a type:
// - known to be a namespace (Namespace {})
@@ -1042,7 +1236,7 @@ void QDeclarativeTypeData::resolveTypes()
}
if (!parserRef->refObjects.isEmpty()) {
- QDeclarativeParser::Object *obj = parserRef->refObjects.first();
+ QDeclarativeScript::Object *obj = parserRef->refObjects.first();
error.setLine(obj->location.start.line);
error.setColumn(obj->location.start.column);
}
@@ -1056,7 +1250,7 @@ void QDeclarativeTypeData::resolveTypes()
ref.majorVersion = majorVersion;
ref.minorVersion = minorVersion;
} else {
- ref.typeData = typeLoader()->get(url);
+ ref.typeData = typeLoader()->get(QUrl(url));
addDependency(ref.typeData);
}
@@ -1077,7 +1271,7 @@ QDeclarativeQmldirData *QDeclarativeTypeData::qmldirForUrl(const QUrl &url)
}
QDeclarativeScriptData::QDeclarativeScriptData(QDeclarativeEngine *engine)
-: QDeclarativeCleanup(engine), importCache(0), pragmas(QDeclarativeParser::Object::ScriptBlock::None),
+: QDeclarativeCleanup(engine), importCache(0), pragmas(QDeclarativeScript::Object::ScriptBlock::None),
m_loaded(false)
{
}
@@ -1103,8 +1297,8 @@ void QDeclarativeScriptData::clear()
}
QDeclarativeScriptBlob::QDeclarativeScriptBlob(const QUrl &url, QDeclarativeTypeLoader *loader)
-: QDeclarativeDataBlob(url, JavaScriptFile), m_pragmas(QDeclarativeParser::Object::ScriptBlock::None),
- m_scriptData(0), m_typeLoader(loader)
+: QDeclarativeDataBlob(url, JavaScriptFile), m_pragmas(QDeclarativeScript::Object::ScriptBlock::None),
+ m_imports(loader), m_scriptData(0), m_typeLoader(loader)
{
}
@@ -1116,7 +1310,7 @@ QDeclarativeScriptBlob::~QDeclarativeScriptBlob()
}
}
-QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptBlob::pragmas() const
+QDeclarativeScript::Object::ScriptBlock::Pragmas QDeclarativeScriptBlob::pragmas() const
{
return m_pragmas;
}
@@ -1148,17 +1342,17 @@ void QDeclarativeScriptBlob::dataReceived(const QByteArray &data)
m_source = QString::fromUtf8(data);
- QDeclarativeScriptParser::JavaScriptMetaData metadata =
- QDeclarativeScriptParser::extractMetaData(m_source);
+ QDeclarativeScript::Parser::JavaScriptMetaData metadata =
+ QDeclarativeScript::Parser::extractMetaData(m_source);
m_imports.setBaseUrl(finalUrl());
m_pragmas = metadata.pragmas;
- foreach (const QDeclarativeScriptParser::Import &import, metadata.imports) {
- Q_ASSERT(import.type != QDeclarativeScriptParser::Import::File);
+ foreach (const QDeclarativeScript::Import &import, metadata.imports) {
+ Q_ASSERT(import.type != QDeclarativeScript::Import::File);
- if (import.type == QDeclarativeScriptParser::Import::Script) {
+ if (import.type == QDeclarativeScript::Import::Script) {
QUrl scriptUrl = finalUrl().resolved(QUrl(import.uri));
QDeclarativeScriptBlob *blob = typeLoader()->getScript(scriptUrl);
addDependency(blob);
@@ -1170,7 +1364,7 @@ void QDeclarativeScriptBlob::dataReceived(const QByteArray &data)
blob->addref();
m_scripts << ref;
} else {
- Q_ASSERT(import.type == QDeclarativeScriptParser::Import::Library);
+ Q_ASSERT(import.type == QDeclarativeScript::Import::Library);
int vmaj = -1;
int vmin = -1;
import.extractVersion(&vmaj, &vmin);
diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h
index 1ca6f8c9c2..349a9f8428 100644
--- a/src/declarative/qml/qdeclarativetypeloader_p.h
+++ b/src/declarative/qml/qdeclarativetypeloader_p.h
@@ -59,9 +59,10 @@
#include <QtDeclarative/qdeclarativeerror.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <private/qdeclarativecleanup_p.h>
-#include <private/qdeclarativescriptparser_p.h>
+#include <private/qdeclarativescript_p.h>
#include <private/qdeclarativedirparser_p.h>
#include <private/qdeclarativeimport_p.h>
+#include "private/qhashedstring_p.h"
#include <private/qv8_p.h>
@@ -202,14 +203,24 @@ public:
QDeclarativeScriptBlob *getScript(const QUrl &);
QDeclarativeQmldirData *getQmldir(const QUrl &);
+
+ QString absoluteFilePath(const QString &path);
+ bool directoryExists(const QString &path);
+ const QDeclarativeDirParser *qmlDirParser(const QString &absoluteFilePath);
+
private:
typedef QHash<QUrl, QDeclarativeTypeData *> TypeCache;
typedef QHash<QUrl, QDeclarativeScriptBlob *> ScriptCache;
typedef QHash<QUrl, QDeclarativeQmldirData *> QmldirCache;
+ typedef QStringHash<bool> StringSet;
+ typedef QStringHash<StringSet*> ImportDirCache;
+ typedef QStringHash<QDeclarativeDirParser*> ImportQmlDirCache;
TypeCache m_typeCache;
ScriptCache m_scriptCache;
QmldirCache m_qmldirCache;
+ ImportDirCache m_importDirCache;
+ ImportQmlDirCache m_importQmlDirCache;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeTypeLoader::Options)
@@ -221,7 +232,7 @@ public:
{
TypeReference() : type(0), majorVersion(0), minorVersion(0), typeData(0) {}
- QDeclarativeParser::Location location;
+ QDeclarativeScript::Location location;
QDeclarativeType *type;
int majorVersion;
int minorVersion;
@@ -232,7 +243,7 @@ public:
{
ScriptReference() : script(0) {}
- QDeclarativeParser::Location location;
+ QDeclarativeScript::Location location;
QString qualifier;
QDeclarativeScriptBlob *script;
};
@@ -243,7 +254,7 @@ public:
QDeclarativeTypeLoader *typeLoader() const;
const QDeclarativeImports &imports() const;
- const QDeclarativeScriptParser &parser() const;
+ const QDeclarativeScript::Parser &parser() const;
const QList<TypeReference> &resolvedTypes() const;
const QList<ScriptReference> &resolvedScripts() const;
@@ -273,7 +284,7 @@ private:
QDeclarativeQmldirData *qmldirForUrl(const QUrl &);
- QDeclarativeScriptParser scriptParser;
+ QDeclarativeScript::Parser scriptParser;
QDeclarativeImports m_imports;
QList<ScriptReference> m_scripts;
@@ -298,7 +309,7 @@ public:
QUrl url;
QDeclarativeTypeNameCache *importCache;
QList<QDeclarativeScriptBlob *> scripts;
- QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas;
+ QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas;
protected:
virtual void clear(); // From QDeclarativeCleanup
@@ -324,12 +335,12 @@ public:
{
ScriptReference() : script(0) {}
- QDeclarativeParser::Location location;
+ QDeclarativeScript::Location location;
QString qualifier;
QDeclarativeScriptBlob *script;
};
- QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas() const;
+ QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas() const;
QString scriptSource() const;
QDeclarativeTypeLoader *typeLoader() const;
@@ -342,7 +353,7 @@ protected:
virtual void done();
private:
- QDeclarativeParser::Object::ScriptBlock::Pragmas m_pragmas;
+ QDeclarativeScript::Object::ScriptBlock::Pragmas m_pragmas;
QString m_source;
QDeclarativeImports m_imports;
diff --git a/src/declarative/qml/qdeclarativetypenamecache.cpp b/src/declarative/qml/qdeclarativetypenamecache.cpp
index 23183aa9fb..b7e4259b4c 100644
--- a/src/declarative/qml/qdeclarativetypenamecache.cpp
+++ b/src/declarative/qml/qdeclarativetypenamecache.cpp
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
QDeclarativeTypeNameCache::QDeclarativeTypeNameCache(QDeclarativeEngine *e)
-: QDeclarativeCleanup(e), engine(e), m_moduleApi(0)
+: QDeclarativeCleanup(e), engine(e)
{
}
@@ -57,52 +57,93 @@ QDeclarativeTypeNameCache::~QDeclarativeTypeNameCache()
void QDeclarativeTypeNameCache::clear()
{
- stringCache.clear();
- m_moduleApi = 0;
+ m_namedImports.clear();
+ m_anonymousImports.clear();
engine = 0;
}
-void QDeclarativeTypeNameCache::add(const QString &name, int importedScriptIndex)
+void QDeclarativeTypeNameCache::add(const QHashedString &name, int importedScriptIndex)
{
- if (stringCache.contains(name))
+ if (m_namedImports.contains(name))
return;
- Data data;
- data.importedScriptIndex = importedScriptIndex;
- stringCache.insert(name, data);
+ Import import;
+ import.scriptIndex = importedScriptIndex;
+ m_namedImports.insert(name, import);
}
-void QDeclarativeTypeNameCache::add(const QString &name, QDeclarativeType *type)
+QDeclarativeTypeNameCache::Result QDeclarativeTypeNameCache::query(const QHashedStringRef &name)
{
- if (stringCache.contains(name))
- return;
-
- Data data;
- data.type = type;
- stringCache.insert(name, data);
+ Import *i = m_namedImports.value(name);
+ if (i) {
+ if (i->scriptIndex != -1)
+ return Result(i->scriptIndex);
+ else
+ return Result((const void *)i);
+ }
+
+ for (int ii = 0; ii < m_anonymousImports.count(); ++ii) {
+ if (QDeclarativeType *type = m_anonymousImports.at(ii).type(name))
+ return Result(type);
+ }
+
+ return Result();
}
-void QDeclarativeTypeNameCache::add(const QString &name, QDeclarativeTypeNameCache *typeNamespace)
+QDeclarativeTypeNameCache::Result QDeclarativeTypeNameCache::query(const QHashedStringRef &name,
+ const void *importNamespace)
{
- if (stringCache.contains(name))
- return;
-
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ Q_ASSERT(importNamespace);
+ Import *i = (Import *)importNamespace;
+ Q_ASSERT(i->scriptIndex == -1);
+
+ for (int ii = 0; ii < i->modules.count(); ++ii) {
+ if (QDeclarativeType *type = i->modules.at(ii).type(name))
+ return Result(type);
+ }
+
+ return Result();
+}
- Data data;
- typeNamespace->addref();
- data.typeNamespace = typeNamespace;
- stringCache.insert(name, data);
+QDeclarativeTypeNameCache::Result QDeclarativeTypeNameCache::query(const QHashedV8String &name)
+{
+ Import *i = m_namedImports.value(name);
+ if (i) {
+ if (i->scriptIndex != -1)
+ return Result(i->scriptIndex);
+ else
+ return Result((const void *)i);
+ }
+
+ for (int ii = 0; ii < m_anonymousImports.count(); ++ii) {
+ if (QDeclarativeType *type = m_anonymousImports.at(ii).type(name))
+ return Result(type);
+ }
+
+ return Result();
}
-QDeclarativeTypeNameCache::Data *QDeclarativeTypeNameCache::data(const QString &id) const
+QDeclarativeTypeNameCache::Result QDeclarativeTypeNameCache::query(const QHashedV8String &name, const void *importNamespace)
{
- return stringCache.value(id);
+ Q_ASSERT(importNamespace);
+ Import *i = (Import *)importNamespace;
+ Q_ASSERT(i->scriptIndex == -1);
+
+ for (int ii = 0; ii < i->modules.count(); ++ii) {
+ if (QDeclarativeType *type = i->modules.at(ii).type(name))
+ return Result(type);
+ }
+
+ return Result();
}
-void QDeclarativeTypeNameCache::setModuleApi(QDeclarativeMetaType::ModuleApiInstance *api)
+QDeclarativeMetaType::ModuleApiInstance *QDeclarativeTypeNameCache::moduleApi(const void *importNamespace)
{
- m_moduleApi = api;
+ Q_ASSERT(importNamespace);
+ Import *i = (Import *)importNamespace;
+ Q_ASSERT(i->scriptIndex == -1);
+
+ return i->moduleApi;
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativetypenamecache_p.h b/src/declarative/qml/qdeclarativetypenamecache_p.h
index e89747b15a..a80bb6492c 100644
--- a/src/declarative/qml/qdeclarativetypenamecache_p.h
+++ b/src/declarative/qml/qdeclarativetypenamecache_p.h
@@ -59,6 +59,8 @@
#include <private/qhashedstring_p.h>
+#include <QtCore/qvector.h>
+
QT_BEGIN_NAMESPACE
class QDeclarativeType;
@@ -69,78 +71,89 @@ public:
QDeclarativeTypeNameCache(QDeclarativeEngine *);
virtual ~QDeclarativeTypeNameCache();
- struct Data {
- inline Data();
- inline Data(const Data &);
- inline ~Data();
- inline Data &operator=(const Data &);
- QDeclarativeType *type;
- QDeclarativeTypeNameCache *typeNamespace;
- int importedScriptIndex;
- };
+ inline bool isEmpty() const;
- void add(const QString &, int);
- void add(const QString &, QDeclarativeType *);
- void add(const QString &, QDeclarativeTypeNameCache *);
+ void add(const QHashedString &, int);
- Data *data(const QString &) const;
- inline Data *data(const QHashedV8String &) const;
- inline bool isEmpty() const;
+ struct Result {
+ inline Result();
+ inline Result(const void *importNamespace);
+ inline Result(QDeclarativeType *type);
+ inline Result(int scriptIndex);
+ inline Result(const Result &);
+
+ inline bool isValid() const;
- inline QDeclarativeMetaType::ModuleApiInstance *moduleApi() const;
- void setModuleApi(QDeclarativeMetaType::ModuleApiInstance *);
+ QDeclarativeType *type;
+ const void *importNamespace;
+ int scriptIndex;
+ };
+ Result query(const QHashedStringRef &);
+ Result query(const QHashedStringRef &, const void *importNamespace);
+ Result query(const QHashedV8String &);
+ Result query(const QHashedV8String &, const void *importNamespace);
+ QDeclarativeMetaType::ModuleApiInstance *moduleApi(const void *importNamespace);
protected:
virtual void clear();
private:
- typedef QStringHash<Data> StringCache;
+ friend class QDeclarativeImports;
- StringCache stringCache;
+ struct Import {
+ inline Import();
+ // Imported module
+ QDeclarativeMetaType::ModuleApiInstance *moduleApi;
+ QVector<QDeclarativeTypeModuleVersion> modules;
+
+ // Or, imported script
+ int scriptIndex;
+ };
+
+ QStringHash<Import> m_namedImports;
+ QVector<QDeclarativeTypeModuleVersion> m_anonymousImports;
QDeclarativeEngine *engine;
- QDeclarativeMetaType::ModuleApiInstance *m_moduleApi;
};
-QDeclarativeTypeNameCache::Data::Data()
-: type(0), typeNamespace(0), importedScriptIndex(-1)
+QDeclarativeTypeNameCache::Result::Result()
+: type(0), importNamespace(0), scriptIndex(-1)
{
}
-QDeclarativeTypeNameCache::Data::~Data()
+QDeclarativeTypeNameCache::Result::Result(const void *importNamespace)
+: type(0), importNamespace(importNamespace), scriptIndex(-1)
{
- if (typeNamespace) typeNamespace->release();
}
-bool QDeclarativeTypeNameCache::isEmpty() const
+QDeclarativeTypeNameCache::Result::Result(QDeclarativeType *type)
+: type(type), importNamespace(0), scriptIndex(-1)
{
- return stringCache.isEmpty();
}
-QDeclarativeTypeNameCache::Data::Data(const QDeclarativeTypeNameCache::Data &o)
-: type(o.type), typeNamespace(o.typeNamespace), importedScriptIndex(o.importedScriptIndex)
+QDeclarativeTypeNameCache::Result::Result(int scriptIndex)
+: type(0), importNamespace(0), scriptIndex(scriptIndex)
{
- if (typeNamespace) typeNamespace->addref();
}
-QDeclarativeTypeNameCache::Data &QDeclarativeTypeNameCache::Data::operator=(const QDeclarativeTypeNameCache::Data &o)
+QDeclarativeTypeNameCache::Result::Result(const Result &o)
+: type(o.type), importNamespace(o.importNamespace), scriptIndex(o.scriptIndex)
{
- if (o.typeNamespace) o.typeNamespace->addref();
- if (typeNamespace) typeNamespace->release();
- type = o.type;
- typeNamespace = o.typeNamespace;
- importedScriptIndex = o.importedScriptIndex;
- return *this;
}
-QDeclarativeMetaType::ModuleApiInstance *QDeclarativeTypeNameCache::moduleApi() const
+bool QDeclarativeTypeNameCache::Result::isValid() const
{
- return m_moduleApi;
+ return type || importNamespace || scriptIndex != -1;
}
-QDeclarativeTypeNameCache::Data *QDeclarativeTypeNameCache::data(const QHashedV8String &name) const
+QDeclarativeTypeNameCache::Import::Import()
+: scriptIndex(-1)
+{
+}
+
+bool QDeclarativeTypeNameCache::isEmpty() const
{
- return stringCache.value(name);
+ return m_namedImports.isEmpty() && m_anonymousImports.isEmpty();
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index 6708b60834..bf290869b4 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -45,6 +45,7 @@
#include "private/qdeclarativeboundsignal_p.h"
#include "private/qdeclarativestringconverters_p.h"
#include "private/qmetaobjectbuilder_p.h"
+#include "private/qfastmetabuilder_p.h"
#include "private/qdeclarativedata_p.h"
#include "qdeclarative.h"
#include "private/qdeclarativecustomparser_p.h"
@@ -240,7 +241,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
types.at(instr.type).createInstance(ctxt, bindings, &vmeErrors);
if (!o) {
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create object of type %1").arg(QString::fromLatin1(types.at(instr.type).className)), instr.line);
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create object of type %1").arg(types.at(instr.type).className), instr.line);
}
QDeclarativeData *ddata = QDeclarativeData::get(o);
@@ -356,7 +357,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QMetaObject mo;
const QByteArray &metadata = datas.at(instr.data);
- QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata);
+ QFastMetaBuilder::fromData(&mo, 0, metadata);
+// QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata);
+
const QDeclarativeVMEMetaData *data =
(const QDeclarativeVMEMetaData *)datas.at(instr.aliasData).constData();
@@ -631,9 +634,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QObject *assign = stack.pop();
QObject *target = stack.top();
int sigIdx = instr.signal;
- const QByteArray &pr = datas.at(sigIdx);
+ const QString &pr = primitives.at(sigIdx);
- QDeclarativeProperty prop(target, QString::fromUtf8(pr));
+ QDeclarativeProperty prop(target, pr);
if (prop.type() & QDeclarativeProperty::SignalProperty) {
QMetaMethod method = QDeclarativeMetaType::defaultMethod(assign);
@@ -646,7 +649,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QDeclarativePropertyPrivate::connect(target, prop.index(), assign, method.methodIndex());
} else {
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign an object to signal property %1").arg(QString::fromUtf8(pr)), instr.line);
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign an object to signal property %1").arg(pr), instr.line);
}
@@ -1037,7 +1040,7 @@ v8::Persistent<v8::Object> QDeclarativeVME::run(QDeclarativeContextData *parentC
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(parentCtxt->engine);
QV8Engine *v8engine = ep->v8engine();
- bool shared = script->pragmas & QDeclarativeParser::Object::ScriptBlock::Shared;
+ bool shared = script->pragmas & QDeclarativeScript::Object::ScriptBlock::Shared;
QDeclarativeContextData *effectiveCtxt = parentCtxt;
if (shared)
diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp
index fc9bb887e8..e6af0ba964 100644
--- a/src/declarative/qml/qdeclarativeworkerscript.cpp
+++ b/src/declarative/qml/qdeclarativeworkerscript.cpp
@@ -365,7 +365,7 @@ void QDeclarativeWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
if (f.open(QIODevice::ReadOnly)) {
QByteArray data = f.readAll();
QString sourceCode = QString::fromUtf8(data);
- QDeclarativeScriptParser::extractPragmas(sourceCode);
+ QDeclarativeScript::Parser::extractPragmas(sourceCode);
v8::HandleScope handle_scope;
v8::Context::Scope scope(workerEngine->context());
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 18d59f7769..7ef28c0231 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -1,6 +1,5 @@
INCLUDEPATH += $$PWD
SOURCES += \
- $$PWD/qdeclarativeparser.cpp \
$$PWD/qdeclarativeinstruction.cpp \
$$PWD/qdeclarativevmemetaobject.cpp \
$$PWD/qdeclarativeengine.cpp \
@@ -17,21 +16,19 @@ SOURCES += \
$$PWD/qdeclarativecompiler.cpp \
$$PWD/qdeclarativecompileddata.cpp \
$$PWD/qdeclarativeboundsignal.cpp \
- $$PWD/qdeclarativerefcount.cpp \
$$PWD/qdeclarativemetatype.cpp \
$$PWD/qdeclarativestringconverters.cpp \
$$PWD/qdeclarativeparserstatus.cpp \
$$PWD/qdeclarativetypeloader.cpp \
$$PWD/qdeclarativeinfo.cpp \
$$PWD/qdeclarativeerror.cpp \
- $$PWD/qdeclarativescriptparser.cpp \
+ $$PWD/qdeclarativescript.cpp \
$$PWD/qdeclarativeenginedebug.cpp \
$$PWD/qdeclarativerewrite.cpp \
$$PWD/qdeclarativevaluetype.cpp \
$$PWD/qdeclarativefastproperties.cpp \
$$PWD/qdeclarativexmlhttprequest.cpp \
$$PWD/qdeclarativesqldatabase.cpp \
- $$PWD/qmetaobjectbuilder.cpp \
$$PWD/qdeclarativewatcher.cpp \
$$PWD/qdeclarativecleanup.cpp \
$$PWD/qdeclarativepropertycache.cpp \
@@ -47,10 +44,8 @@ SOURCES += \
$$PWD/qdeclarativeextensionplugin.cpp \
$$PWD/qdeclarativeimport.cpp \
$$PWD/qdeclarativelist.cpp \
- $$PWD/qintrusivelist.cpp \
HEADERS += \
- $$PWD/qdeclarativeparser_p.h \
$$PWD/qdeclarativeglobal_p.h \
$$PWD/qdeclarativeinstruction_p.h \
$$PWD/qdeclarativevmemetaobject_p.h \
@@ -72,7 +67,6 @@ HEADERS += \
$$PWD/qdeclarativeengine_p.h \
$$PWD/qdeclarativeexpression_p.h \
$$PWD/qdeclarativeprivate.h \
- $$PWD/qdeclarativerefcount_p.h \
$$PWD/qdeclarativemetatype_p.h \
$$PWD/qdeclarativeengine.h \
$$PWD/qdeclarativecontext.h \
@@ -86,16 +80,13 @@ HEADERS += \
$$PWD/qdeclarativelist_p.h \
$$PWD/qdeclarativedata_p.h \
$$PWD/qdeclarativeerror.h \
- $$PWD/qdeclarativescriptparser_p.h \
+ $$PWD/qdeclarativescript_p.h \
$$PWD/qdeclarativeenginedebug_p.h \
$$PWD/qdeclarativerewrite_p.h \
- $$PWD/qpodvector_p.h \
- $$PWD/qbitfield_p.h \
$$PWD/qdeclarativevaluetype_p.h \
$$PWD/qdeclarativefastproperties_p.h \
$$PWD/qdeclarativexmlhttprequest_p.h \
$$PWD/qdeclarativesqldatabase_p.h \
- $$PWD/qmetaobjectbuilder_p.h \
$$PWD/qdeclarativewatcher_p.h \
$$PWD/qdeclarativecleanup_p.h \
$$PWD/qdeclarativepropertycache_p.h \
@@ -113,11 +104,11 @@ HEADERS += \
$$PWD/qdeclarativeimport_p.h \
$$PWD/qdeclarativeextensionplugin.h \
$$PWD/qdeclarativenullablevalue_p_p.h \
- $$PWD/qintrusivelist_p.h \
$$PWD/qdeclarativescriptstring_p.h
QT += sql
include(parser/parser.pri)
include(rewriter/rewriter.pri)
+include(ftw/ftw.pri)
include(v4/v4.pri)
include(v8/v8.pri)
diff --git a/src/declarative/qml/v4/qdeclarativev4compiler.cpp b/src/declarative/qml/v4/qdeclarativev4compiler.cpp
index 371edda6c9..fa4cd25952 100644
--- a/src/declarative/qml/v4/qdeclarativev4compiler.cpp
+++ b/src/declarative/qml/v4/qdeclarativev4compiler.cpp
@@ -85,17 +85,18 @@ void QDeclarativeV4CompilerPrivate::trace(int line, int column)
currentBlockMask = 0x00000001;
- for (int i = 0; i < blocks.size(); ++i) {
+ for (int i = 0; !_discarded && i < blocks.size(); ++i) {
IR::BasicBlock *block = blocks.at(i);
IR::BasicBlock *next = i + 1 < blocks.size() ? blocks.at(i + 1) : 0;
if (IR::Stmt *terminator = block->terminator()) {
if (IR::CJump *cj = terminator->asCJump()) {
if (cj->iffalse != next) {
- block->i(new IR::Jump(cj->iffalse));
+ IR::Jump *jump = _function->pool->New<IR::Jump>();
+ jump->init(cj->iffalse);
+ block->statements.append(jump);
}
} else if (IR::Jump *j = terminator->asJump()) {
if (j->target == next) {
- delete block->statements.back();
block->statements.resize(block->statements.size() - 1);
}
}
@@ -136,8 +137,10 @@ void QDeclarativeV4CompilerPrivate::trace(int line, int column)
blockop.block(currentBlockMask);
gen(blockop);
- foreach (IR::Stmt *s, block->statements)
- s->accept(this);
+ foreach (IR::Stmt *s, block->statements) {
+ if (! _discarded)
+ s->accept(this);
+ }
qSwap(usedSubscriptionIdsChanged, usic);
@@ -147,7 +150,7 @@ void QDeclarativeV4CompilerPrivate::trace(int line, int column)
return;
}
currentBlockMask <<= 1;
- } else {
+ } else if (! _discarded) {
const int adjust = bytecode.remove(blockopIndex);
// Correct patches
for (int ii = patchesCount; ii < patches.count(); ++ii)
@@ -163,20 +166,21 @@ void QDeclarativeV4CompilerPrivate::trace(int line, int column)
#endif
- // back patching
- foreach (const Patch &patch, patches) {
- Instr &instr = bytecode[patch.offset];
- instr.branchop.offset = patch.block->offset - patch.offset - instr.size();
- }
+ if (! _discarded) {
+ // back patching
+ foreach (const Patch &patch, patches) {
+ Instr &instr = bytecode[patch.offset];
+ instr.branchop.offset = patch.block->offset - patch.offset - instr.size();
+ }
- patches.clear();
+ patches.clear();
+ }
}
void QDeclarativeV4CompilerPrivate::trace(QVector<IR::BasicBlock *> *blocks)
{
- QList<IR::BasicBlock *> todo = QList<IR::BasicBlock *>::fromVector(_function->basicBlocks);
- while (! todo.isEmpty()) {
- IR::BasicBlock *block = todo.takeFirst();
+ for (int i = 0; i < _function->basicBlocks.size(); ++i) {
+ IR::BasicBlock *block = _function->basicBlocks.at(i);
while (! blocks->contains(block)) {
blocks->append(block);
@@ -270,7 +274,7 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
instr.load_id(currentReg, e->index);
gen(instr);
- _subscribeName << QLatin1String("$$$ID_") + e->id;
+ _subscribeName << QLatin1String("$$$ID_") + *e->id;
if (blockNeedsSubscription(_subscribeName)) {
Instr sub;
@@ -293,7 +297,7 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
} break;
case IR::Name::AttachType: {
- _subscribeName << e->id;
+ _subscribeName << *e->id;
Instr attached;
attached.common.type = Instr::LoadAttached;
@@ -306,7 +310,7 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
} break;
case IR::Name::Property: {
- _subscribeName << e->id;
+ _subscribeName << *e->id;
QMetaProperty prop = e->meta->property(e->index);
int fastFetchIndex = QDeclarativeFastProperties::instance()->accessorIndexForProperty(e->meta, e->index);
@@ -763,8 +767,9 @@ void QDeclarativeV4CompilerPrivate::visitBinop(IR::Binop *e)
void QDeclarativeV4CompilerPrivate::visitCall(IR::Call *call)
{
if (IR::Name *name = call->base->asName()) {
- if (call->args.size() == 1 && call->args.at(0)->type == IR::RealType) {
- traceExpression(call->args.at(0), currentReg);
+ IR::Expr *arg = call->onlyArgument();
+ if (arg != 0 && arg->type == IR::RealType) {
+ traceExpression(arg, currentReg);
Instr instr;
instr.common.type = Instr::Noop;
@@ -981,7 +986,6 @@ This does not clear the global "committed binding" states.
*/
void QDeclarativeV4CompilerPrivate::resetInstanceState()
{
- registerCleanups.clear();
data = committed.data;
exceptions = committed.exceptions;
usedSubscriptionIds.clear();
@@ -989,6 +993,7 @@ void QDeclarativeV4CompilerPrivate::resetInstanceState()
registeredStrings = committed.registeredStrings;
bytecode.clear();
patches.clear();
+ pool.clear();
currentReg = 0;
}
@@ -1003,7 +1008,7 @@ int QDeclarativeV4CompilerPrivate::commitCompile()
int rv = committed.count();
committed.offsets << committed.bytecode.count();
committed.dependencies << usedSubscriptionIds;
- committed.bytecode += bytecode.code();
+ committed.bytecode.append(bytecode.constData(), bytecode.size());
committed.data = data;
committed.exceptions = exceptions;
committed.subscriptionIds = subscriptionIds;
@@ -1032,11 +1037,10 @@ bool QDeclarativeV4CompilerPrivate::compile(QDeclarativeJS::AST::Node *node)
return false;
}
- IR::Module module;
- IR::Function *function = 0;
+ IR::Function thisFunction(&pool), *function = &thisFunction;
QDeclarativeV4IRBuilder irBuilder(expression, engine);
- if (!(function = irBuilder(&module, node)))
+ if (!irBuilder(function, node))
return false;
bool discarded = false;
@@ -1067,7 +1071,7 @@ bool QDeclarativeV4CompilerPrivate::compile(QDeclarativeJS::AST::Node *node)
}
// Returns a reg
-int QDeclarativeV4CompilerPrivate::registerLiteralString(quint8 reg, const QString &str)
+int QDeclarativeV4CompilerPrivate::registerLiteralString(quint8 reg, const QStringRef &str)
{
// ### string cleanup
@@ -1090,9 +1094,9 @@ int QDeclarativeV4CompilerPrivate::registerString(const QString &string)
{
Q_ASSERT(!string.isEmpty());
- QHash<QString, QPair<int, int> >::ConstIterator iter = registeredStrings.find(string);
+ QPair<int, int> *iter = registeredStrings.value(string);
- if (iter == registeredStrings.end()) {
+ if (!iter) {
quint32 len = string.length();
QByteArray lendata((const char *)&len, sizeof(quint32));
QByteArray strdata((const char *)string.constData(), string.length() * sizeof(QChar));
@@ -1100,7 +1104,8 @@ int QDeclarativeV4CompilerPrivate::registerString(const QString &string)
int rv = data.count();
data += strdata;
- iter = registeredStrings.insert(string, qMakePair(registeredStrings.count(), rv));
+ iter = &registeredStrings[string];
+ *iter = qMakePair(registeredStrings.count(), rv);
}
Instr reg;
@@ -1118,12 +1123,12 @@ bool QDeclarativeV4CompilerPrivate::blockNeedsSubscription(const QStringList &su
{
QString str = sub.join(QLatin1String("."));
- QHash<QString, int>::ConstIterator iter = subscriptionIds.find(str);
- if (iter == subscriptionIds.end())
+ int *iter = subscriptionIds.value(str);
+ if (!iter)
return true;
- QHash<int, quint32>::ConstIterator uiter = usedSubscriptionIds.find(*iter);
- if (uiter == usedSubscriptionIds.end())
+ quint32 *uiter = usedSubscriptionIds.value(*iter);
+ if (!uiter)
return true;
else
return !(*uiter & currentBlockMask);
@@ -1132,11 +1137,15 @@ bool QDeclarativeV4CompilerPrivate::blockNeedsSubscription(const QStringList &su
int QDeclarativeV4CompilerPrivate::subscriptionIndex(const QStringList &sub)
{
QString str = sub.join(QLatin1String("."));
- QHash<QString, int>::ConstIterator iter = subscriptionIds.find(str);
- if (iter == subscriptionIds.end())
- iter = subscriptionIds.insert(str, subscriptionIds.count());
- if (!(usedSubscriptionIds[*iter] & currentBlockMask)) {
- usedSubscriptionIds[*iter] |= currentBlockMask;
+ int *iter = subscriptionIds.value(str);
+ if (!iter) {
+ int count = subscriptionIds.count();
+ iter = &subscriptionIds[str];
+ *iter = count;
+ }
+ quint32 &u = usedSubscriptionIds[*iter];
+ if (!(u & currentBlockMask)) {
+ u |= currentBlockMask;
usedSubscriptionIdsChanged = true;
}
return *iter;
@@ -1146,11 +1155,11 @@ quint32 QDeclarativeV4CompilerPrivate::subscriptionBlockMask(const QStringList &
{
QString str = sub.join(QLatin1String("."));
- QHash<QString, int>::ConstIterator iter = subscriptionIds.find(str);
- Q_ASSERT(iter != subscriptionIds.end());
+ int *iter = subscriptionIds.value(str);
+ Q_ASSERT(iter != 0);
- QHash<int, quint32>::ConstIterator uiter = usedSubscriptionIds.find(*iter);
- Q_ASSERT(uiter != usedSubscriptionIds.end());
+ quint32 *uiter = usedSubscriptionIds.value(*iter);
+ Q_ASSERT(uiter != 0);
return *uiter;
}
@@ -1225,9 +1234,9 @@ QByteArray QDeclarativeV4CompilerPrivate::buildSignalTable() const
QHash<int, QList<QPair<int, quint32> > > table;
for (int ii = 0; ii < committed.count(); ++ii) {
- const QHash<int, quint32> &deps = committed.dependencies.at(ii);
- for (QHash<int, quint32>::ConstIterator iter = deps.begin(); iter != deps.end(); ++iter)
- table[iter.key()].append(qMakePair(ii, iter.value()));
+ const QDeclarativeAssociationList<int, quint32> &deps = committed.dependencies.at(ii);
+ for (QDeclarativeAssociationList<int, quint32>::const_iterator iter = deps.begin(); iter != deps.end(); ++iter)
+ table[iter->first].append(qMakePair(ii, iter->second));
}
QVector<quint32> header;
@@ -1278,8 +1287,10 @@ QByteArray QDeclarativeV4Compiler::program() const
}
- QByteArray bytecode = bc.code();
- bytecode += d->committed.bytecode;
+ QByteArray bytecode;
+ bytecode.reserve(bc.size() + d->committed.bytecode.size());
+ bytecode.append(bc.constData(), bc.size());
+ bytecode.append(d->committed.bytecode.constData(), d->committed.bytecode.size());
QByteArray data = d->committed.data;
while (data.count() % 4) data.append('\0');
@@ -1308,13 +1319,12 @@ QByteArray QDeclarativeV4Compiler::program() const
if (bindingsDump()) {
qWarning().nospace() << "Subscription slots:";
- for (QHash<QString, int>::ConstIterator iter = d->committed.subscriptionIds.begin();
+ for (QDeclarativeAssociationList<QString, int>::ConstIterator iter = d->committed.subscriptionIds.begin();
iter != d->committed.subscriptionIds.end();
++iter) {
- qWarning().nospace() << " " << iter.value() << "\t-> " << iter.key();
+ qWarning().nospace() << " " << iter->first << "\t-> " << iter->second;
}
-
QDeclarativeV4Compiler::dump(programData);
}
diff --git a/src/declarative/qml/v4/qdeclarativev4compiler_p.h b/src/declarative/qml/v4/qdeclarativev4compiler_p.h
index cc93f4dbf2..0ed78bfdfc 100644
--- a/src/declarative/qml/v4/qdeclarativev4compiler_p.h
+++ b/src/declarative/qml/v4/qdeclarativev4compiler_p.h
@@ -53,8 +53,9 @@
// We mean it.
//
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativebinding_p.h"
+#include <private/qdeclarativeexpression_p.h>
+#include <private/qdeclarativebinding_p.h>
+#include <private/qdeclarativecompiler_p.h>
QT_BEGIN_HEADER
@@ -73,11 +74,12 @@ public:
struct Expression
{
- QDeclarativeParser::Object *component;
- QDeclarativeParser::Object *context;
- QDeclarativeParser::Property *property;
- QDeclarativeParser::Variant expression;
- QHash<QString, QDeclarativeParser::Object *> ids;
+ Expression(const QDeclarativeImports &imp) : imports(imp) {}
+ QDeclarativeScript::Object *component;
+ QDeclarativeScript::Object *context;
+ QDeclarativeScript::Property *property;
+ QDeclarativeScript::Variant expression;
+ QDeclarativeCompilerTypes::IdList *ids;
QDeclarativeTypeNameCache *importCache;
QDeclarativeImports imports;
};
diff --git a/src/declarative/qml/v4/qdeclarativev4compiler_p_p.h b/src/declarative/qml/v4/qdeclarativev4compiler_p_p.h
index 1d9414dce6..eab609a45d 100644
--- a/src/declarative/qml/v4/qdeclarativev4compiler_p_p.h
+++ b/src/declarative/qml/v4/qdeclarativev4compiler_p_p.h
@@ -55,7 +55,7 @@
#include "qdeclarativev4instruction_p.h"
#include "qdeclarativev4ir_p.h"
-#include <private/qdeclarativeparser_p.h>
+#include <private/qdeclarativescript_p.h>
#include <private/qdeclarativeimport_p.h>
#include <private/qdeclarativeengine_p.h>
@@ -93,6 +93,54 @@ inline bool operator==(const QDeclarative1AnchorLine& a, const QDeclarative1Anch
}
+template <typename _Key, typename _Value>
+class QDeclarativeAssociationList
+{
+public:
+ typedef QVarLengthArray<QPair<_Key, _Value>, 8> Container;
+ typedef typename Container::const_iterator const_iterator;
+ typedef typename Container::const_iterator ConstIterator;
+
+ const_iterator begin() const { return _container.begin(); }
+ const_iterator end() const { return _container.end(); }
+ int count() const { return _container.count(); }
+ void clear() { _container.clear(); }
+
+ _Value *value(const _Key &key) {
+ for (int i = 0; i < _container.size(); ++i) {
+ QPair<_Key, _Value> &p = _container[i];
+ if (p.first == key)
+ return &p.second;
+ }
+ return 0;
+ }
+
+ _Value &operator[](const _Key &key) {
+ for (int i = 0; i < _container.size(); ++i) {
+ QPair<_Key, _Value> &p = _container[i];
+ if (p.first == key)
+ return p.second;
+ }
+ int index = _container.size();
+ _container.append(qMakePair(key, _Value()));
+ return _container[index].second;
+ }
+
+ void insert(const _Key &key, _Value &value) {
+ for (int i = 0; i < _container.size(); ++i) {
+ QPair<_Key, _Value> &p = _container[i];
+ if (p.first == key) {
+ p.second = value;
+ return;
+ }
+ }
+ _container.append(qMakePair(key, value));
+ }
+
+private:
+ Container _container;
+};
+
class QDeclarativeV4CompilerPrivate: protected QDeclarativeJS::IR::ExprVisitor,
protected QDeclarativeJS::IR::StmtVisitor
{
@@ -109,11 +157,9 @@ public:
bool compile(QDeclarativeJS::AST::Node *);
- QHash<int, QPair<int, int> > registerCleanups;
-
- int registerLiteralString(quint8 reg, const QString &);
+ int registerLiteralString(quint8 reg, const QStringRef &);
int registerString(const QString &);
- QHash<QString, QPair<int, int> > registeredStrings;
+ QDeclarativeAssociationList<QString, QPair<int, int> > registeredStrings;
QByteArray data;
bool blockNeedsSubscription(const QStringList &);
@@ -124,9 +170,9 @@ public:
quint8 exceptionId(QDeclarativeJS::AST::ExpressionNode *);
QVector<quint64> exceptions;
- QHash<int, quint32> usedSubscriptionIds;
+ QDeclarativeAssociationList<int, quint32> usedSubscriptionIds;
- QHash<QString, int> subscriptionIds;
+ QDeclarativeAssociationList<QString, int> subscriptionIds;
QDeclarativeJS::Bytecode bytecode;
// back patching
@@ -137,19 +183,20 @@ public:
: block(block), offset(index) {}
};
QVector<Patch> patches;
+ QDeclarativePool pool;
// Committed binding data
struct {
QList<int> offsets;
- QList<QHash<int, quint32> > dependencies;
+ QList<QDeclarativeAssociationList<int, quint32> > dependencies;
//QDeclarativeJS::Bytecode bytecode;
QByteArray bytecode;
QByteArray data;
- QHash<QString, int> subscriptionIds;
+ QDeclarativeAssociationList<QString, int> subscriptionIds;
QVector<quint64> exceptions;
- QHash<QString, QPair<int, int> > registeredStrings;
+ QDeclarativeAssociationList<QString, QPair<int, int> > registeredStrings;
int count() const { return offsets.count(); }
} committed;
diff --git a/src/declarative/qml/v4/qdeclarativev4instruction.cpp b/src/declarative/qml/v4/qdeclarativev4instruction.cpp
index a520a3584a..dd6892369b 100644
--- a/src/declarative/qml/v4/qdeclarativev4instruction.cpp
+++ b/src/declarative/qml/v4/qdeclarativev4instruction.cpp
@@ -530,12 +530,6 @@ void Bytecode::append(const Instr &instr)
d.append(it, instr.size());
}
-void Bytecode::append(const QVector<Instr> &instrs)
-{
- foreach (const Instr &i, instrs)
- append(i);
-}
-
int Bytecode::remove(int offset)
{
const Instr *instr = (const Instr *) (d.begin() + offset);
diff --git a/src/declarative/qml/v4/qdeclarativev4instruction_p.h b/src/declarative/qml/v4/qdeclarativev4instruction_p.h
index e3ac9027f7..6efe9332d1 100644
--- a/src/declarative/qml/v4/qdeclarativev4instruction_p.h
+++ b/src/declarative/qml/v4/qdeclarativev4instruction_p.h
@@ -56,6 +56,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qvector.h>
+#include <QtCore/qvarlengtharray.h>
QT_BEGIN_HEADER
@@ -414,21 +415,27 @@ class Bytecode
public:
Bytecode();
- QByteArray code() const { return d; }
const char *constData() const { return d.constData(); }
int size() const { return d.size(); }
int count() const { return d.count(); }
void clear() { d.clear(); }
bool isEmpty() const { return d.isEmpty(); }
void append(const Instr &instr);
- void append(const QVector<Instr> &instrs);
+
+ template <typename _It>
+ void append(_It it, _It last)
+ {
+ for (; it != last; ++it)
+ append(*it);
+ }
+
int remove(int index);
const Instr &operator[](int offset) const;
Instr &operator[](int offset);
private:
- QByteArray d;
+ QVarLengthArray<char, 4 * 1024> d;
#ifdef QML_THREADED_INTERPRETER
void **decodeInstr;
#endif
diff --git a/src/declarative/qml/v4/qdeclarativev4ir.cpp b/src/declarative/qml/v4/qdeclarativev4ir.cpp
index 86eeeec12c..7490efe2aa 100644
--- a/src/declarative/qml/v4/qdeclarativev4ir.cpp
+++ b/src/declarative/qml/v4/qdeclarativev4ir.cpp
@@ -165,10 +165,11 @@ void String::dump(QTextStream &out)
out << '"' << escape(value) << '"';
}
-QString String::escape(const QString &s)
+QString String::escape(const QStringRef &s)
{
QString r;
- foreach (const QChar &ch, s) {
+ for (int i = 0; i < s.length(); ++i) {
+ const QChar ch = s.at(i);
if (ch == QLatin1Char('\n'))
r += QLatin1String("\\n");
else if (ch == QLatin1Char('\r'))
@@ -185,29 +186,30 @@ QString String::escape(const QString &s)
return r;
}
-Name::Name(Name *base, Type type, const QString &id, Symbol symbol, quint32 line, quint32 column)
-: Expr(type)
- , base(base)
- , id(id)
- , symbol(symbol)
- , ptr(0)
- , index(-1)
- , storage(MemberStorage)
- , builtin(NoBuiltinSymbol)
- , line(line)
- , column(column)
+void Name::init(Name *base, Type type, const QString *id, Symbol symbol, quint32 line, quint32 column)
{
- if (id.length() == 8 && id == QLatin1String("Math.sin")) {
+ this->type = type;
+ this->base = base;
+ this->id = id;
+ this->symbol = symbol;
+ this->ptr = 0;
+ this->index = -1;
+ this->storage = MemberStorage;
+ this->builtin = NoBuiltinSymbol;
+ this->line = line;
+ this->column = column;
+
+ if (id->length() == 8 && *id == QLatin1String("Math.sin")) {
builtin = MathSinBultinFunction;
- } else if (id.length() == 8 && id == QLatin1String("Math.cos")) {
+ } else if (id->length() == 8 && *id == QLatin1String("Math.cos")) {
builtin = MathCosBultinFunction;
- } else if (id.length() == 10 && id == QLatin1String("Math.round")) {
+ } else if (id->length() == 10 && *id == QLatin1String("Math.round")) {
builtin = MathRoundBultinFunction;
- } else if (id.length() == 10 && id == QLatin1String("Math.floor)")) {
+ } else if (id->length() == 10 && *id == QLatin1String("Math.floor)")) {
builtin = MathFloorBultinFunction;
- } else if (id.length() == 7 && id == QLatin1String("Math.PI")) {
+ } else if (id->length() == 7 && *id == QLatin1String("Math.PI")) {
builtin = MathPIBuiltinConstant;
- type = RealType;
+ this->type = RealType;
}
}
@@ -218,7 +220,7 @@ void Name::dump(QTextStream &out)
out << '.';
}
- out << id;
+ out << *id;
}
void Temp::dump(QTextStream &out)
@@ -318,10 +320,10 @@ void Call::dump(QTextStream &out)
{
base->dump(out);
out << '(';
- for (int i = 0; i < args.size(); ++i) {
- if (i)
+ for (ExprList *it = args; it; it = it->next) {
+ if (it != args)
out << ", ";
- args.at(i)->dump(out);
+ it->expr->dump(out);
}
out << ')';
}
@@ -396,7 +398,11 @@ void Ret::dump(QTextStream &out, Mode)
Function::~Function()
{
qDeleteAll(basicBlocks);
- qDeleteAll(temps);
+}
+
+QString *Function::newString(const QString &text)
+{
+ return pool->NewString(text);
}
BasicBlock *Function::newBasicBlock()
@@ -407,12 +413,7 @@ BasicBlock *Function::newBasicBlock()
void Function::dump(QTextStream &out)
{
- QString fname;
- if (name)
- fname = name->asString();
- else
- fname = QLatin1String("$anonymous");
- out << "function " << fname << "() {" << endl;
+ out << "function () {" << endl;
foreach (BasicBlock *bb, basicBlocks) {
bb->dump(out);
}
@@ -421,7 +422,9 @@ void Function::dump(QTextStream &out)
Temp *BasicBlock::TEMP(Type type, int index)
{
- return function->e(new Temp(type, index));
+ Temp *e = function->pool->New<Temp>();
+ e->init(type, index);
+ return e;
}
Temp *BasicBlock::TEMP(Type type)
@@ -436,12 +439,16 @@ Expr *BasicBlock::CONST(double value)
Expr *BasicBlock::CONST(Type type, double value)
{
- return function->e(new Const(type, value));
+ Const *e = function->pool->New<Const>();
+ e->init(type, value);
+ return e;
}
-Expr *BasicBlock::STRING(const QString &value)
-{
- return function->e(new String(value));
+Expr *BasicBlock::STRING(const QStringRef &value)
+{
+ String *e = function->pool->New<String>();
+ e->init(value);
+ return e;
}
Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column)
@@ -451,7 +458,11 @@ Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column)
Name *BasicBlock::NAME(Name *base, const QString &id, quint32 line, quint32 column)
{
- return function->e(new Name(base, InvalidType, id, Name::Unbound, line, column));
+ Name *e = function->pool->New<Name>();
+ e->init(base, InvalidType,
+ function->newString(id),
+ Name::Unbound, line, column);
+ return e;
}
Name *BasicBlock::SYMBOL(Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage,
@@ -465,44 +476,56 @@ Name *BasicBlock::SYMBOL(Type type, const QString &id, const QMetaObject *meta,
Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage,
quint32 line, quint32 column)
{
- Name *name = new Name(base, type, id, Name::Property, line, column);
+ Name *name = function->pool->New<Name>();
+ name->init(base, type, function->newString(id),
+ Name::Property, line, column);
name->meta = meta;
name->index = index;
name->storage = storage;
- return function->e(name);
+ return name;
}
Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index,
quint32 line, quint32 column)
{
- Name *name = new Name(base, type, id, Name::Property, line, column);
+ Name *name = function->pool->New<Name>();
+ name->init(base, type, function->newString(id),
+ Name::Property, line, column);
name->meta = meta;
name->index = index;
- return function->e(name);
+ return name;
}
-Name *BasicBlock::ID_OBJECT(const QString &id, const QDeclarativeParser::Object *object, quint32 line, quint32 column)
+Name *BasicBlock::ID_OBJECT(const QString &id, const QDeclarativeScript::Object *object, quint32 line, quint32 column)
{
- Name *name = new Name(/*base = */ 0, IR::ObjectType, id, Name::IdObject, line, column);
+ Name *name = function->pool->New<Name>();
+ name->init(/*base = */ 0, IR::ObjectType,
+ function->newString(id),
+ Name::IdObject, line, column);
name->idObject = object;
name->index = object->idIndex;
name->storage = Name::IdStorage;
- return function->e(name);
+ return name;
}
Name *BasicBlock::ATTACH_TYPE(const QString &id, const QDeclarativeType *attachType, Name::Storage storage,
quint32 line, quint32 column)
{
- Name *name = new Name(/*base = */ 0, IR::AttachType, id, Name::AttachType, line, column);
+ Name *name = function->pool->New<Name>();
+ name->init(/*base = */ 0, IR::AttachType,
+ function->newString(id),
+ Name::AttachType, line, column);
name->declarativeType = attachType;
name->storage = storage;
- return function->e(name);
+ return name;
}
Expr *BasicBlock::UNOP(AluOp op, Expr *expr)
{
- return function->e(new Unop(op, expr));
+ Unop *e = function->pool->New<Unop>();
+ e->init(op, expr);
+ return e;
}
Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
@@ -545,45 +568,65 @@ Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
}
}
- return function->e(new Binop(op, left, right));
+ Binop *e = function->pool->New<Binop>();
+ e->init(op, left, right);
+ return e;
}
-Expr *BasicBlock::CALL(Expr *base, const QVector<Expr *> &args)
+Expr *BasicBlock::CALL(Expr *base, ExprList *args)
{
- return function->e(new Call(base, args));
+ Call *e = function->pool->New<Call>();
+ e->init(base, args);
+ return e;
}
Stmt *BasicBlock::EXP(Expr *expr)
{
- return i(new Exp(expr));
+ Exp *s = function->pool->New<Exp>();
+ s->init(expr);
+ statements.append(s);
+ return s;
}
Stmt *BasicBlock::MOVE(Expr *target, Expr *source, bool isMoveForReturn)
{
- return i(new Move(target, source, isMoveForReturn));
+ Move *s = function->pool->New<Move>();
+ s->init(target, source, isMoveForReturn);
+ statements.append(s);
+ return s;
}
Stmt *BasicBlock::JUMP(BasicBlock *target)
{
if (isTerminated())
return 0;
- else
- return i(new Jump(target));
+
+ Jump *s = function->pool->New<Jump>();
+ s->init(target);
+ statements.append(s);
+ return s;
}
Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
{
if (isTerminated())
return 0;
- return i(new CJump(cond, iftrue, iffalse));
+
+ CJump *s = function->pool->New<CJump>();
+ s->init(cond, iftrue, iffalse);
+ statements.append(s);
+ return s;
}
Stmt *BasicBlock::RET(Expr *expr, Type type, quint32 line, quint32 column)
{
if (isTerminated())
return 0;
- else
- return i(new Ret(expr, type, line, column));
+
+ Ret *s = function->pool->New<Ret>();
+ s->init(expr, type, line, column);
+ statements.append(s);
+ return s;
}
void BasicBlock::dump(QTextStream &out)
@@ -596,14 +639,6 @@ void BasicBlock::dump(QTextStream &out)
}
}
-void Module::dump(QTextStream &out)
-{
- foreach (Function *fun, functions) {
- fun->dump(out);
- out << endl;
- }
-}
-
#ifdef DEBUG_IR_STRUCTURE
static const char *symbolname(Name::Symbol s)
diff --git a/src/declarative/qml/v4/qdeclarativev4ir_p.h b/src/declarative/qml/v4/qdeclarativev4ir_p.h
index 87891bfc4e..2c8f658378 100644
--- a/src/declarative/qml/v4/qdeclarativev4ir_p.h
+++ b/src/declarative/qml/v4/qdeclarativev4ir_p.h
@@ -55,12 +55,13 @@
#include <private/qdeclarativejsast_p.h>
#include <private/qdeclarativejsengine_p.h>
-#include <private/qdeclarativeparser_p.h>
+#include <private/qdeclarativescript_p.h>
#include <private/qdeclarativeimport_p.h>
#include <private/qdeclarativeengine_p.h>
#include <private/qdeclarativev4compiler_p.h>
-#include <QtCore/qvector.h>
+#include <qdeclarativepool_p.h>
+#include <QtCore/qvarlengtharray.h>
// #define DEBUG_IR_STRUCTURE
@@ -77,7 +78,6 @@ namespace IR {
struct BasicBlock;
struct Function;
-struct Module;
struct Stmt;
struct Expr;
@@ -175,10 +175,10 @@ struct StmtVisitor {
virtual void visitRet(Ret *) {}
};
-struct Expr {
+struct Expr: QDeclarativePool::POD {
Type type;
- Expr(Type type): type(type) {}
+ Expr(): type(InvalidType) {}
virtual ~Expr() {}
virtual void accept(ExprVisitor *) = 0;
virtual Const *asConst() { return 0; }
@@ -191,9 +191,25 @@ struct Expr {
virtual void dump(QTextStream &out) = 0;
};
+struct ExprList: QDeclarativePool::POD {
+ Expr *expr;
+ ExprList *next;
+
+ void init(Expr *expr, ExprList *next = 0)
+ {
+ this->expr = expr;
+ this->next = next;
+ }
+};
+
struct Const: Expr {
double value;
- Const(Type type, double value): Expr(type), value(value) {}
+
+ void init(Type type, double value)
+ {
+ this->type = type;
+ this->value = value;
+ }
virtual void accept(ExprVisitor *v) { v->visitConst(this); }
virtual Const *asConst() { return this; }
@@ -202,14 +218,19 @@ struct Const: Expr {
};
struct String: Expr {
- QString value;
- String(const QString &value): Expr(StringType), value(value) {}
+ QStringRef value;
+
+ void init(const QStringRef &value)
+ {
+ this->type = StringType;
+ this->value = value;
+ }
virtual void accept(ExprVisitor *v) { v->visitString(this); }
virtual String *asString() { return this; }
virtual void dump(QTextStream &out);
- static QString escape(const QString &s);
+ static QString escape(const QStringRef &s);
};
enum BuiltinSymbol {
@@ -240,13 +261,13 @@ struct Name: Expr {
};
Name *base;
- QString id;
+ const QString *id;
Symbol symbol;
union {
void *ptr;
const QMetaObject *meta;
const QDeclarativeType *declarativeType;
- const QDeclarativeParser::Object *idObject;
+ const QDeclarativeScript::Object *idObject;
};
int index;
Storage storage;
@@ -254,7 +275,7 @@ struct Name: Expr {
quint32 line;
quint32 column;
- Name(Name *base, Type type, const QString &id, Symbol symbol, quint32 line, quint32 column);
+ void init(Name *base, Type type, const QString *id, Symbol symbol, quint32 line, quint32 column);
inline bool is(Symbol s) const { return s == symbol; }
inline bool isNot(Symbol s) const { return s != symbol; }
@@ -267,7 +288,12 @@ struct Name: Expr {
struct Temp: Expr {
int index;
- Temp(Type type, int index): Expr(type), index(index) {}
+
+ void init(Type type, int index)
+ {
+ this->type = type;
+ this->index = index;
+ }
virtual void accept(ExprVisitor *v) { v->visitTemp(this); }
virtual Temp *asTemp() { return this; }
@@ -279,8 +305,12 @@ struct Unop: Expr {
AluOp op;
Expr *expr;
- Unop(AluOp op, Expr *expr)
- : Expr(typeForOp(op, expr)), op(op), expr(expr) {}
+ void init(AluOp op, Expr *expr)
+ {
+ this->typeForOp(op, expr);
+ this->op = op;
+ this->expr = expr;
+ }
virtual void accept(ExprVisitor *v) { v->visitUnop(this); }
virtual Unop *asUnop() { return this; }
@@ -295,8 +325,14 @@ struct Binop: Expr {
AluOp op;
Expr *left;
Expr *right;
- Binop(AluOp op, Expr *left, Expr *right)
- : Expr(typeForOp(op, left, right)), op(op), left(left), right(right) {}
+
+ void init(AluOp op, Expr *left, Expr *right)
+ {
+ this->type = typeForOp(op, left, right);
+ this->op = op;
+ this->left = left;
+ this->right = right;
+ }
virtual void accept(ExprVisitor *v) { v->visitBinop(this); }
virtual Binop *asBinop() { return this; }
@@ -309,10 +345,20 @@ private:
struct Call: Expr {
Expr *base;
- QVector<Expr *> args;
+ ExprList *args;
- Call(Expr *base, const QVector<Expr *> &args)
- : Expr(typeForFunction(base)), base(base), args(args) {}
+ void init(Expr *base, ExprList *args)
+ {
+ this->type = typeForFunction(base);
+ this->base = base;
+ this->args = args;
+ }
+
+ Expr *onlyArgument() const {
+ if (args && ! args->next)
+ return args->expr;
+ return 0;
+ }
virtual void accept(ExprVisitor *v) { v->visitCall(this); }
virtual Call *asCall() { return this; }
@@ -323,7 +369,7 @@ private:
static Type typeForFunction(Expr *base);
};
-struct Stmt {
+struct Stmt: QDeclarativePool::POD {
enum Mode {
HIR,
MIR
@@ -343,7 +389,11 @@ struct Stmt {
struct Exp: Stmt {
Expr *expr;
- Exp(Expr *expr): expr(expr) {}
+
+ void init(Expr *expr)
+ {
+ this->expr = expr;
+ }
virtual void accept(StmtVisitor *v) { v->visitExp(this); }
virtual Exp *asExp() { return this; }
@@ -355,7 +405,13 @@ struct Move: Stmt {
Expr *target;
Expr *source;
bool isMoveForReturn;
- Move(Expr *target, Expr *source, bool isMoveForReturn): target(target), source(source), isMoveForReturn(isMoveForReturn) {}
+
+ void init(Expr *target, Expr *source, bool isMoveForReturn)
+ {
+ this->target = target;
+ this->source = source;
+ this->isMoveForReturn = isMoveForReturn;
+ }
virtual void accept(StmtVisitor *v) { v->visitMove(this); }
virtual Move *asMove() { return this; }
@@ -365,7 +421,11 @@ struct Move: Stmt {
struct Jump: Stmt {
BasicBlock *target;
- Jump(BasicBlock *target): target(target) {}
+
+ void init(BasicBlock *target)
+ {
+ this->target = target;
+ }
virtual Stmt *asTerminator() { return this; }
@@ -379,8 +439,13 @@ struct CJump: Stmt {
Expr *cond;
BasicBlock *iftrue;
BasicBlock *iffalse;
- CJump(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
- : cond(cond), iftrue(iftrue), iffalse(iffalse) {}
+
+ void init(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
+ {
+ this->cond = cond;
+ this->iftrue = iftrue;
+ this->iffalse = iffalse;
+ }
virtual Stmt *asTerminator() { return this; }
@@ -395,7 +460,14 @@ struct Ret: Stmt {
Type type;
quint32 line;
quint32 column;
- Ret(Expr *expr, Type type, quint32 line, quint32 column): expr(expr), type(type), line(line), column(column) {}
+
+ void init(Expr *expr, Type type, quint32 line, quint32 column)
+ {
+ this->expr = expr;
+ this->type = type;
+ this->line = line;
+ this->column = column;
+ }
virtual Stmt *asTerminator() { return this; }
@@ -406,19 +478,19 @@ struct Ret: Stmt {
};
struct Function {
- Module *module;
- const NameId *name;
+ QDeclarativePool *pool;
+ QVarLengthArray<BasicBlock *, 8> basicBlocks;
int tempCount;
- QVector<BasicBlock *> basicBlocks;
- QVector<Expr *> temps;
- template <typename BB> inline BB i(BB i) { basicBlocks.append(i); return i; }
- template <typename E> inline E e(E e) { temps.append(e); return e; }
+ Function(QDeclarativePool *pool)
+ : pool(pool), tempCount(0) {}
- Function(Module *module, const NameId *name = 0): module(module), name(name), tempCount(0) {}
~Function();
BasicBlock *newBasicBlock();
+ QString *newString(const QString &text);
+
+ inline BasicBlock *i(BasicBlock *block) { basicBlocks.append(block); return block; }
virtual void dump(QTextStream &out);
};
@@ -426,11 +498,11 @@ struct Function {
struct BasicBlock {
Function *function;
int index;
- QVector<Stmt *> statements;
int offset;
+ QVarLengthArray<Stmt *, 32> statements;
BasicBlock(Function *function, int index): function(function), index(index), offset(-1) {}
- ~BasicBlock() { qDeleteAll(statements); }
+ ~BasicBlock() {}
template <typename Instr> inline Instr i(Instr i) { statements.append(i); return i; }
@@ -439,8 +511,8 @@ struct BasicBlock {
}
inline Stmt *terminator() const {
- if (! statements.isEmpty() && statements.last()->asTerminator() != 0)
- return statements.last();
+ if (! statements.isEmpty() && statements.at(statements.size() - 1)->asTerminator() != 0)
+ return statements.at(statements.size() - 1);
return 0;
}
@@ -455,19 +527,19 @@ struct BasicBlock {
Expr *CONST(double value);
Expr *CONST(Type type, double value);
- Expr *STRING(const QString &value);
+ Expr *STRING(const QStringRef &value);
Name *NAME(const QString &id, quint32 line, quint32 column);
Name *NAME(Name *base, const QString &id, quint32 line, quint32 column);
Name *SYMBOL(Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage, quint32 line, quint32 column);
Name *SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index, quint32 line, quint32 column);
Name *SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage, quint32 line, quint32 column);
- Name *ID_OBJECT(const QString &id, const QDeclarativeParser::Object *object, quint32 line, quint32 column);
+ Name *ID_OBJECT(const QString &id, const QDeclarativeScript::Object *object, quint32 line, quint32 column);
Name *ATTACH_TYPE(const QString &id, const QDeclarativeType *attachType, Name::Storage storage, quint32 line, quint32 column);
Expr *UNOP(AluOp op, Expr *expr);
Expr *BINOP(AluOp op, Expr *left, Expr *right);
- Expr *CALL(Expr *base, const QVector<Expr *> &args);
+ Expr *CALL(Expr *base, ExprList *args);
Stmt *EXP(Expr *expr);
Stmt *MOVE(Expr *target, Expr *source, bool = false);
@@ -479,19 +551,6 @@ struct BasicBlock {
virtual void dump(QTextStream &out);
};
-struct Module {
- QVector<Function *> functions;
-
- Module() {}
- ~Module() { qDeleteAll(functions); }
-
- template <typename BB> inline BB i(BB i) { functions.append(i); return i; }
-
- Function *newFunction(const NameId *name = 0) { return i(new Function(this, name)); }
-
- virtual void dump(QTextStream &out);
-};
-
#ifdef DEBUG_IR_STRUCTURE
struct IRDump : public ExprVisitor,
public StmtVisitor
diff --git a/src/declarative/qml/v4/qdeclarativev4irbuilder.cpp b/src/declarative/qml/v4/qdeclarativev4irbuilder.cpp
index bddfca18b4..9237a3e1e9 100644
--- a/src/declarative/qml/v4/qdeclarativev4irbuilder.cpp
+++ b/src/declarative/qml/v4/qdeclarativev4irbuilder.cpp
@@ -44,6 +44,7 @@
#include <private/qsganchors_p_p.h> // For AnchorLine
#include <private/qdeclarativetypenamecache_p.h>
+#include <private/qdeclarativeutils_p.h>
DEFINE_BOOL_CONFIG_OPTION(qmlVerboseCompiler, QML_VERBOSE_COMPILER)
@@ -85,19 +86,15 @@ static IR::Type irTypeFromVariantType(int t, QDeclarativeEnginePrivate *engine,
QDeclarativeV4IRBuilder::QDeclarativeV4IRBuilder(const QDeclarativeV4Compiler::Expression *expr,
QDeclarativeEnginePrivate *engine)
-: m_expression(expr), m_engine(engine), _module(0), _function(0), _block(0), _discard(false)
+: m_expression(expr), m_engine(engine), _function(0), _block(0), _discard(false)
{
}
-QDeclarativeJS::IR::Function *
-QDeclarativeV4IRBuilder::operator()(QDeclarativeJS::IR::Module *module,
+bool QDeclarativeV4IRBuilder::operator()(QDeclarativeJS::IR::Function *function,
QDeclarativeJS::AST::Node *ast)
{
bool discarded = false;
- qSwap(_module, module);
-
- IR::Function *function = _module->newFunction();
IR::BasicBlock *block = function->newBasicBlock();
qSwap(_discard, discarded);
@@ -130,17 +127,15 @@ QDeclarativeV4IRBuilder::operator()(QDeclarativeJS::IR::Module *module,
qSwap(_function, function);
qSwap(_discard, discarded);
- qSwap(_module, module);
-
- return discarded?0:function;
+ return !discarded;
}
-bool QDeclarativeV4IRBuilder::buildName(QStringList &name,
+bool QDeclarativeV4IRBuilder::buildName(QList<QStringRef> &name,
AST::Node *node,
QList<AST::ExpressionNode *> *nodes)
{
if (node->kind == AST::Node::Kind_IdentifierExpression) {
- name << static_cast<AST::IdentifierExpression*>(node)->name->asString();
+ name << static_cast<AST::IdentifierExpression*>(node)->name;
if (nodes) *nodes << static_cast<AST::IdentifierExpression*>(node);
} else if (node->kind == AST::Node::Kind_FieldMemberExpression) {
AST::FieldMemberExpression *expr =
@@ -149,7 +144,7 @@ bool QDeclarativeV4IRBuilder::buildName(QStringList &name,
if (!buildName(name, expr->base, nodes))
return false;
- name << expr->name->asString();
+ name << expr->name;
if (nodes) *nodes << expr;
} else {
return false;
@@ -341,27 +336,28 @@ bool QDeclarativeV4IRBuilder::visit(AST::UiFormal *)
// JS
-bool QDeclarativeV4IRBuilder::visit(AST::Program *ast)
+bool QDeclarativeV4IRBuilder::visit(AST::Program *)
{
- _function = _module->newFunction();
- _block = _function->newBasicBlock();
- accept(ast->elements);
+ Q_ASSERT(!"unreachable");
return false;
}
bool QDeclarativeV4IRBuilder::visit(AST::SourceElements *)
{
+ Q_ASSERT(!"unreachable");
return false;
}
bool QDeclarativeV4IRBuilder::visit(AST::FunctionSourceElement *)
{
- return true; // look inside
+ Q_ASSERT(!"unreachable");
+ return false;
}
bool QDeclarativeV4IRBuilder::visit(AST::StatementSourceElement *)
{
- return true; // look inside
+ Q_ASSERT(!"unreachable");
+ return false;
}
// object literals
@@ -432,76 +428,75 @@ bool QDeclarativeV4IRBuilder::visit(AST::IdentifierExpression *ast)
const quint32 line = ast->identifierToken.startLine;
const quint32 column = ast->identifierToken.startColumn;
- const QString name = ast->name->asString();
+ const QString name = ast->name.toString();
if (name.at(0) == QLatin1Char('u') && name.length() == 9 && name == QLatin1String("undefined")) {
_expr.code = _block->CONST(IR::UndefinedType, 0); // ### undefined value
} else if (m_engine->v8engine()->illegalNames().contains(name) ) {
if (qmlVerboseCompiler()) qWarning() << "*** illegal symbol:" << name;
return false;
- } else if (const QDeclarativeParser::Object *obj = m_expression->ids.value(name)) {
+ } else if (const QDeclarativeScript::Object *obj = m_expression->ids->value(name)) {
IR::Name *code = _block->ID_OBJECT(name, obj, line, column);
if (obj == m_expression->component)
code->storage = IR::Name::RootStorage;
_expr.code = code;
- } else if (QDeclarativeTypeNameCache::Data *typeNameData = m_expression->importCache->data(name)) {
- if (typeNameData->importedScriptIndex != -1) {
- // We don't support invoking imported scripts
- } else if (typeNameData->type) {
- _expr.code = _block->ATTACH_TYPE(name, typeNameData->type, IR::Name::ScopeStorage, line, column);
- } else if (typeNameData->typeNamespace) {
- // We don't support namespaces
- } else {
- Q_ASSERT(!"Unreachable");
- }
} else {
- bool found = false;
- if (m_expression->context != m_expression->component) {
- // RootStorage is more efficient than ScopeStorage, so prefer that if they are the same
- QDeclarativePropertyCache *cache = m_expression->context->synthCache;
- const QMetaObject *metaObject = m_expression->context->metaObject();
- if (!cache) cache = m_engine->cache(metaObject);
+ QDeclarativeTypeNameCache::Result r = m_expression->importCache->query(name);
+ if (r.isValid()) {
+ if (r.type) {
+ _expr.code = _block->ATTACH_TYPE(name, r.type, IR::Name::ScopeStorage, line, column);
+ }
+ // We don't support anything else
+ } else {
+ bool found = false;
- QDeclarativePropertyCache::Data *data = cache->property(name);
+ if (m_expression->context != m_expression->component) {
+ // RootStorage is more efficient than ScopeStorage, so prefer that if they are the same
+ QDeclarativePropertyCache *cache = m_expression->context->synthCache;
+ const QMetaObject *metaObject = m_expression->context->metaObject();
+ if (!cache) cache = m_engine->cache(metaObject);
+
+ QDeclarativePropertyCache::Data *data = cache->property(name);
- if (data && data->revision != 0) {
- if (qmlVerboseCompiler())
- qWarning() << "*** versioned symbol:" << name;
- discard();
- return false;
+ if (data && data->revision != 0) {
+ if (qmlVerboseCompiler())
+ qWarning() << "*** versioned symbol:" << name;
+ discard();
+ return false;
+ }
+
+ if (data && !data->isFunction()) {
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine, metaObject);
+ _expr.code = _block->SYMBOL(irType, name, metaObject, data->coreIndex, IR::Name::ScopeStorage, line, column);
+ found = true;
+ }
}
- if (data && !data->isFunction()) {
- IR::Type irType = irTypeFromVariantType(data->propType, m_engine, metaObject);
- _expr.code = _block->SYMBOL(irType, name, metaObject, data->coreIndex, IR::Name::ScopeStorage, line, column);
- found = true;
- }
- }
+ if (!found) {
+ QDeclarativePropertyCache *cache = m_expression->component->synthCache;
+ const QMetaObject *metaObject = m_expression->component->metaObject();
+ if (!cache) cache = m_engine->cache(metaObject);
- if (!found) {
- QDeclarativePropertyCache *cache = m_expression->component->synthCache;
- const QMetaObject *metaObject = m_expression->component->metaObject();
- if (!cache) cache = m_engine->cache(metaObject);
+ QDeclarativePropertyCache::Data *data = cache->property(name);
- QDeclarativePropertyCache::Data *data = cache->property(name);
+ if (data && data->revision != 0) {
+ if (qmlVerboseCompiler())
+ qWarning() << "*** versioned symbol:" << name;
+ discard();
+ return false;
+ }
- if (data && data->revision != 0) {
- if (qmlVerboseCompiler())
- qWarning() << "*** versioned symbol:" << name;
- discard();
- return false;
+ if (data && !data->isFunction()) {
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine, metaObject);
+ _expr.code = _block->SYMBOL(irType, name, metaObject, data->coreIndex, IR::Name::RootStorage, line, column);
+ found = true;
+ }
}
- if (data && !data->isFunction()) {
- IR::Type irType = irTypeFromVariantType(data->propType, m_engine, metaObject);
- _expr.code = _block->SYMBOL(irType, name, metaObject, data->coreIndex, IR::Name::RootStorage, line, column);
- found = true;
- }
+ if (!found && qmlVerboseCompiler())
+ qWarning() << "*** unknown symbol:" << name;
}
-
- if (!found && qmlVerboseCompiler())
- qWarning() << "*** unknown symbol:" << name;
}
if (_expr.code && _expr.hint == ExprResult::cx) {
@@ -544,7 +539,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::FalseLiteral *)
bool QDeclarativeV4IRBuilder::visit(AST::StringLiteral *ast)
{
// ### TODO: cx format
- _expr.code = _block->STRING(ast->value->asString());
+ _expr.code = _block->STRING(ast->value);
return false;
}
@@ -581,14 +576,14 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
const quint32 line = ast->identifierToken.startLine;
const quint32 column = ast->identifierToken.startColumn;
- QString name = ast->name->asString();
+ QString name = ast->name.toString();
switch(baseName->symbol) {
case IR::Name::Unbound:
break;
case IR::Name::AttachType:
- if (name.at(0).isUpper()) {
+ if (QDeclarativeUtils::isUpper(name.at(0))) {
QByteArray utf8Name = name.toUtf8();
const char *enumName = utf8Name.constData();
@@ -606,7 +601,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
if (!found && qmlVerboseCompiler())
qWarning() << "*** unresolved enum:"
- << (baseName->id + QLatin1String(".") + ast->name->asString());
+ << (*baseName->id + QLatin1String(".") + ast->name.toString());
} else if(const QMetaObject *attachedMeta = baseName->declarativeType->attachedPropertiesType()) {
QDeclarativePropertyCache *cache = m_engine->cache(attachedMeta);
QDeclarativePropertyCache::Data *data = cache->property(name);
@@ -617,7 +612,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
if(!data->isFinal()) {
if (qmlVerboseCompiler())
qWarning() << "*** non-final attached property:"
- << (baseName->id + QLatin1String(".") + ast->name->asString());
+ << (*baseName->id + QLatin1String(".") + ast->name.toString());
return false; // We don't know enough about this property
}
@@ -627,7 +622,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
break;
case IR::Name::IdObject: {
- const QDeclarativeParser::Object *idObject = baseName->idObject;
+ const QDeclarativeScript::Object *idObject = baseName->idObject;
QDeclarativePropertyCache *cache =
idObject->synthCache?idObject->synthCache:m_engine->cache(idObject->metaObject());
@@ -663,7 +658,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
if(!data->isFinal()) {
if (qmlVerboseCompiler())
qWarning() << "*** non-final property access:"
- << (baseName->id + QLatin1String(".") + ast->name->asString());
+ << (*baseName->id + QLatin1String(".") + ast->name.toString());
return false; // We don't know enough about this property
}
@@ -683,6 +678,11 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
return false;
}
+bool QDeclarativeV4IRBuilder::preVisit(AST::Node *)
+{
+ return ! _discard;
+}
+
bool QDeclarativeV4IRBuilder::visit(AST::NewMemberExpression *)
{
return false;
@@ -695,18 +695,30 @@ bool QDeclarativeV4IRBuilder::visit(AST::NewExpression *)
bool QDeclarativeV4IRBuilder::visit(AST::CallExpression *ast)
{
- QStringList names;
+ QList<QStringRef> names;
QList<AST::ExpressionNode *> nameNodes;
+
+ names.reserve(4);
+ nameNodes.reserve(4);
+
if (buildName(names, ast->base, &nameNodes)) {
//ExprResult base = expression(ast->base);
- const QString id = names.join(QLatin1String("."));
- const quint32 line = nameNodes.last()->firstSourceLocation().startLine;
- const quint32 column = nameNodes.last()->firstSourceLocation().startColumn;
- IR::Expr *base = _block->NAME(id, line, column);
-
- QVector<IR::Expr *> args;
- for (AST::ArgumentList *it = ast->arguments; it; it = it->next)
- args.append(expression(it->expression));
+ QString id;
+ for (int i = 0; i < names.size(); ++i) {
+ if (! i)
+ id += QLatin1Char('.');
+ id += names.at(i);
+ }
+ const AST::SourceLocation loc = nameNodes.last()->firstSourceLocation();
+ IR::Expr *base = _block->NAME(id, loc.startLine, loc.startColumn);
+
+ IR::ExprList *args = 0, **argsInserter = &args;
+ for (AST::ArgumentList *it = ast->arguments; it; it = it->next) {
+ IR::Expr *arg = expression(it->expression);
+ *argsInserter = _function->pool->New<IR::ExprList>();
+ (*argsInserter)->init(arg);
+ argsInserter = &(*argsInserter)->next;
+ }
IR::Temp *r = _block->TEMP(IR::InvalidType);
IR::Expr *call = _block->CALL(base, args);
diff --git a/src/declarative/qml/v4/qdeclarativev4irbuilder_p.h b/src/declarative/qml/v4/qdeclarativev4irbuilder_p.h
index 69f9cbabed..004e3a1a11 100644
--- a/src/declarative/qml/v4/qdeclarativev4irbuilder_p.h
+++ b/src/declarative/qml/v4/qdeclarativev4irbuilder_p.h
@@ -55,7 +55,7 @@ class QDeclarativeV4IRBuilder : public QDeclarativeJS::AST::Visitor
public:
QDeclarativeV4IRBuilder(const QDeclarativeV4Compiler::Expression *, QDeclarativeEnginePrivate *);
- QDeclarativeJS::IR::Function *operator()(QDeclarativeJS::IR::Module *, QDeclarativeJS::AST::Node *);
+ bool operator()(QDeclarativeJS::IR::Function *, QDeclarativeJS::AST::Node *);
protected:
struct ExprResult {
@@ -115,6 +115,8 @@ protected:
void implicitCvt(ExprResult &expr, QDeclarativeJS::IR::Type type);
+ virtual bool preVisit(QDeclarativeJS::AST::Node *ast);
+
// QML
virtual bool visit(QDeclarativeJS::AST::UiProgram *ast);
virtual bool visit(QDeclarativeJS::AST::UiImportList *ast);
@@ -220,14 +222,13 @@ protected:
virtual bool visit(QDeclarativeJS::AST::DebuggerStatement *ast);
private:
- bool buildName(QStringList &name, QDeclarativeJS::AST::Node *node,
+ bool buildName(QList<QStringRef> &name, QDeclarativeJS::AST::Node *node,
QList<QDeclarativeJS::AST::ExpressionNode *> *nodes);
void discard();
const QDeclarativeV4Compiler::Expression *m_expression;
QDeclarativeEnginePrivate *m_engine;
- QDeclarativeJS::IR::Module *_module;
QDeclarativeJS::IR::Function *_function;
QDeclarativeJS::IR::BasicBlock *_block;
bool _discard;
diff --git a/src/declarative/qml/v8/qhashedstring.cpp b/src/declarative/qml/v8/qhashedstring.cpp
deleted file mode 100644
index 2e2af98ff4..0000000000
--- a/src/declarative/qml/v8/qhashedstring.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qhashedstring_p.h"
-
-inline unsigned stringHash(const QChar* data, unsigned length)
-{
- return v8::String::ComputeHash((uint16_t *)data, length);
-}
-
-void QHashedString::computeHash() const
-{
- m_hash = stringHash(constData(), length());
-}
-
-void QHashedStringRef::computeHash() const
-{
- m_hash = stringHash(m_data, m_length);
-}
-
-/*
- A QHash has initially around pow(2, MinNumBits) buckets. For
- example, if MinNumBits is 4, it has 17 buckets.
-*/
-const int MinNumBits = 4;
-
-/*
- The prime_deltas array is a table of selected prime values, even
- though it doesn't look like one. The primes we are using are 1,
- 2, 5, 11, 17, 37, 67, 131, 257, ..., i.e. primes in the immediate
- surrounding of a power of two.
-
- The primeForNumBits() function returns the prime associated to a
- power of two. For example, primeForNumBits(8) returns 257.
-*/
-
-static const uchar prime_deltas[] = {
- 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
- 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
-};
-
-static inline int primeForNumBits(int numBits)
-{
- return (1 << numBits) + prime_deltas[numBits];
-}
-
-void QStringHashData::rehash()
-{
- numBits = qMax(MinNumBits, numBits + 1);
- numBuckets = primeForNumBits(numBits);
-
- delete [] buckets;
- buckets = new QStringHashNode *[numBuckets];
- ::memset(buckets, 0, sizeof(QStringHashNode *) * numBuckets);
-
- QStringHashNode *nodeList = nodes;
- while (nodeList) {
- int bucket = nodeList->key.hash() % numBuckets;
- nodeList->next = buckets[bucket];
- buckets[bucket] = nodeList;
-
- nodeList = nodeList->nlist;
- }
-}
-
diff --git a/src/declarative/qml/v8/qhashedstring_p.h b/src/declarative/qml/v8/qhashedstring_p.h
deleted file mode 100644
index e0ca1d466a..0000000000
--- a/src/declarative/qml/v8/qhashedstring_p.h
+++ /dev/null
@@ -1,664 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QHASHEDSTRING_P_H
-#define QHASHEDSTRING_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qstring.h>
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QHashedStringRef;
-class QHashedString : public QString
-{
-public:
- inline QHashedString();
- inline QHashedString(const QString &string);
- inline QHashedString(const QString &string, quint32);
- inline QHashedString(const QHashedString &string);
-
- inline QHashedString &operator=(const QHashedString &string);
- inline bool operator==(const QHashedString &string) const;
- inline bool operator==(const QHashedStringRef &string) const;
-
- inline quint32 hash() const;
- inline quint32 existingHash() const;
-
- static inline bool isUpper(const QChar &);
-private:
- friend class QHashedStringRef;
-
- void computeHash() const;
- mutable quint32 m_hash;
-};
-
-class QHashedV8String
-{
-public:
- inline QHashedV8String();
- explicit inline QHashedV8String(v8::Handle<v8::String>);
- inline QHashedV8String(const QHashedV8String &string);
- inline QHashedV8String &operator=(const QHashedV8String &other);
-
- inline bool operator==(const QHashedV8String &string);
-
- inline quint32 hash() const;
- inline int length() const;
- inline quint32 symbolId() const;
-
- inline v8::Handle<v8::String> string() const;
-
-private:
- v8::String::CompleteHashData m_hash;
- v8::Handle<v8::String> m_string;
-};
-
-class QHashedStringRef
-{
-public:
- inline QHashedStringRef();
- inline QHashedStringRef(const QString &);
- inline QHashedStringRef(const QChar *, int);
- inline QHashedStringRef(const QChar *, int, quint32);
- inline QHashedStringRef(const QHashedString &);
- inline QHashedStringRef(const QHashedStringRef &);
-
- inline bool operator==(const QHashedString &string) const;
- inline bool operator==(const QHashedStringRef &string) const;
-
- inline quint32 hash() const;
-
- inline const QChar *constData() const;
- inline quint32 length() const;
- inline bool startsWithUpper() const;
-
-private:
- friend class QHashedString;
-
- void computeHash() const;
-
- const QChar *m_data;
- quint32 m_length;
- mutable quint32 m_hash;
-};
-
-class QStringHashData;
-class QStringHashNode
-{
-public:
- QStringHashNode(const QHashedString &key)
- : nlist(0), next(0), key(key), symbolId(0) {
- }
-
- QStringHashNode *nlist;
- QStringHashNode *next;
- QHashedString key;
- quint32 symbolId;
-
- inline bool equals(v8::Handle<v8::String> string) {
- return string->Equals((uint16_t*)key.constData(), key.length());
- }
-};
-
-struct QStringHashData
-{
-public:
- QStringHashData()
- : nodes(0), buckets(0), numBuckets(0), size(0), numBits(0) {}
-
- QStringHashNode *nodes;
- QStringHashNode **buckets;
- int numBuckets;
- int size;
- short numBits;
-
- void rehash();
-};
-
-template<class T>
-class QStringHash
-{
-private:
- struct Node : public QStringHashNode {
- Node(const QHashedString &key, const T &value) : QStringHashNode(key), value(value) {}
- T value;
- };
-
- QStringHashData data;
-
- inline Node *findNode(const QHashedStringRef &) const;
- inline Node *findNode(const QHashedV8String &) const;
- inline Node *findSymbolNode(const QHashedV8String &) const;
- Node *createNode(const QHashedString &, const T &);
-
-public:
- inline QStringHash();
- inline QStringHash(const QStringHash &);
- inline ~QStringHash();
-
- QStringHash &operator=(const QStringHash<T> &);
-
- inline bool isEmpty() const;
- inline void clear();
- inline int count() const;
-
- inline void insert(const QString &, const T &);
- inline void insert(const QHashedString &, const T &);
- inline void insert(const QHashedStringRef &, const T &);
-
- inline T *value(const QString &) const;
- inline T *value(const QHashedString &) const;
- inline T *value(const QHashedStringRef &) const;
- inline T *value(const QHashedV8String &) const;
-
- inline bool contains(const QString &) const;
- inline bool contains(const QHashedString &) const;
- inline bool contains(const QHashedStringRef &) const;
-
- T &operator[](const QString &);
- T &operator[](const QHashedString &);
- T &operator[](const QHashedStringRef &);
-
- class ConstIterator {
- public:
- ConstIterator() : n(0) {}
- ConstIterator(Node *n) : n(n) {}
-
- ConstIterator &operator++() { n = (Node *)n->nlist; return *this; }
- bool operator==(const ConstIterator &o) const { return n == o.n; }
- bool operator!=(const ConstIterator &o) const { return n != o.n; }
-
- const QHashedString &key() const { return n->key; }
- const T &value() const { return n->value; }
- const T &operator*() const { return n->value; }
- private:
- Node *n;
- };
-
- ConstIterator begin() const { return ConstIterator((Node *)data.nodes); }
- ConstIterator end() const { return ConstIterator(); }
-};
-
-template<class T>
-QStringHash<T>::QStringHash()
-{
-}
-
-template<class T>
-QStringHash<T>::QStringHash(const QStringHash<T> &other)
-: data(other.data)
-{
- data.nodes = 0;
- data.buckets = 0;
-
- QStringHashNode *n = other.data.nodes;
- while (n) {
- Node *o = (Node *)n;
- Node *mynode = new Node(o->key, o->value);
- mynode->nlist = data.nodes;
- data.nodes = mynode;
- n = o->nlist;
- }
-
- data.rehash();
-}
-
-template<class T>
-QStringHash<T> &QStringHash<T>::operator=(const QStringHash<T> &other)
-{
- if (&other == this)
- return *this;
-
- clear();
- data = other.data;
- data.nodes = 0;
- data.buckets = 0;
-
- QStringHashNode *n = other.data.nodes;
- while (n) {
- Node *o = (Node *)n;
- Node *mynode = new Node(o->key, o->value);
- mynode->nlist = data.nodes;
- data.nodes = mynode;
- n = o->nlist;
- }
-
- data.rehash();
-
- return *this;
-}
-
-template<class T>
-QStringHash<T>::~QStringHash()
-{
- clear();
-}
-
-template<class T>
-void QStringHash<T>::clear()
-{
- QStringHashNode *n = data.nodes;
- while (n) {
- Node *o = (Node *)n;
- n = n->nlist;
- delete o;
- }
-
- delete [] data.buckets;
-
- data = QStringHashData();
-}
-
-template<class T>
-bool QStringHash<T>::isEmpty() const
-{
- return data.nodes == 0;
-}
-
-template<class T>
-int QStringHash<T>::count() const
-{
- return data.size;
-}
-
-template<class T>
-typename QStringHash<T>::Node *QStringHash<T>::createNode(const QHashedString &key, const T &value)
-{
- if (data.size == data.numBuckets)
- data.rehash();
-
- Node *n = new Node(key, value);
- n->nlist = data.nodes;
- data.nodes = n;
-
- int bucket = key.hash() % data.numBuckets;
- n->next = data.buckets[bucket];
- data.buckets[bucket] = n;
-
- data.size++;
-
- return n;
-}
-
-template<class T>
-void QStringHash<T>::insert(const QString &key, const T &value)
-{
- QHashedStringRef ch(key);
- Node *n = findNode(key);
- if (n) n->value = value;
- else createNode(QHashedString(key, ch.hash()), value);
-}
-
-template<class T>
-void QStringHash<T>::insert(const QHashedString &key, const T &value)
-{
- Node *n = findNode(key);
- if (n) n->value = value;
- else createNode(key, value);
-}
-
-template<class T>
-void QStringHash<T>::insert(const QHashedStringRef &key, const T &value)
-{
- Node *n = findNode(key);
- if (n) n->value = value;
- else createNode(key, value);
-}
-
-template<class T>
-typename QStringHash<T>::Node *QStringHash<T>::findNode(const QHashedStringRef &string) const
-{
- QStringHashNode *node = 0;
- if (data.numBuckets) {
- node = data.buckets[string.hash() % data.numBuckets];
- while (node && !(node->key == string))
- node = node->next;
- }
-
- return (Node *)node;
-}
-
-template<class T>
-typename QStringHash<T>::Node *QStringHash<T>::findNode(const QHashedV8String &string) const
-{
- QStringHashNode *node = 0;
- if (data.numBuckets) {
- quint32 hash = string.hash();
- node = data.buckets[hash % data.numBuckets];
- int length = string.length();
- while (node && (length != node->key.length() || hash != node->key.hash() || !node->equals(string.string())))
- node = node->next;
- }
-
- return (Node *)node;
-}
-
-template<class T>
-typename QStringHash<T>::Node *QStringHash<T>::findSymbolNode(const QHashedV8String &string) const
-{
- Q_ASSERT(string.symbolId() != 0);
-
- QStringHashNode *node = 0;
- if (data.numBuckets) {
- quint32 hash = string.hash();
- quint32 symbolId = string.symbolId();
- node = data.buckets[hash % data.numBuckets];
- int length = string.length();
- while (node && (length != node->key.length() || hash != node->key.hash() ||
- !(node->symbolId == symbolId || node->equals(string.string()))))
- node = node->next;
- if (node)
- node->symbolId = symbolId;
- }
-
- return (Node *)node;
-}
-
-template<class T>
-T *QStringHash<T>::value(const QString &key) const
-{
- Node *n = findNode(key);
- return n?&n->value:0;
-}
-
-template<class T>
-T *QStringHash<T>::value(const QHashedString &key) const
-{
- Node *n = findNode(key);
- return n?&n->value:0;
-}
-
-template<class T>
-T *QStringHash<T>::value(const QHashedStringRef &key) const
-{
- Node *n = findNode(key);
- return n?&n->value:0;
-}
-
-template<class T>
-T *QStringHash<T>::value(const QHashedV8String &string) const
-{
- Node *n = string.symbolId()?findSymbolNode(string):findNode(string);
- return n?&n->value:0;
-}
-
-template<class T>
-bool QStringHash<T>::contains(const QString &s) const
-{
- return 0 != value(s);
-}
-
-template<class T>
-bool QStringHash<T>::contains(const QHashedString &s) const
-{
- return 0 != value(s);
-}
-template<class T>
-bool QStringHash<T>::contains(const QHashedStringRef &s) const
-{
- return 0 != value(s);
-}
-
-template<class T>
-T &QStringHash<T>::operator[](const QString &key)
-{
- QHashedStringRef cs(key);
- Node *n = findNode(cs);
- if (n) return n->value;
- else return createNode(QHashedString(key, cs.hash()), T())->value;
-}
-
-template<class T>
-T &QStringHash<T>::operator[](const QHashedString &key)
-{
- Node *n = findNode(key);
- if (n) return n->value;
- else return createNode(key, T())->value;
-}
-
-template<class T>
-T &QStringHash<T>::operator[](const QHashedStringRef &key)
-{
- Node *n = findNode(key);
- if (n) return n->value;
- else return createNode(key, T())->value;
-}
-
-inline uint qHash(const QHashedString &string)
-{
- return uint(string.hash());
-}
-
-inline uint qHash(const QHashedStringRef &string)
-{
- return uint(string.hash());
-}
-
-QHashedString::QHashedString()
-: QString(), m_hash(0)
-{
-}
-
-QHashedString::QHashedString(const QString &string)
-: QString(string), m_hash(0)
-{
-}
-
-QHashedString::QHashedString(const QString &string, quint32 hash)
-: QString(string), m_hash(hash)
-{
-}
-
-QHashedString::QHashedString(const QHashedString &string)
-: QString(string), m_hash(string.m_hash)
-{
-}
-
-QHashedString &QHashedString::operator=(const QHashedString &string)
-{
- static_cast<QString &>(*this) = string;
- m_hash = string.m_hash;
- return *this;
-}
-
-bool QHashedString::operator==(const QHashedString &string) const
-{
- return (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
- static_cast<const QString &>(*this) == static_cast<const QString &>(string);
-}
-
-bool QHashedString::operator==(const QHashedStringRef &string) const
-{
- return (uint)length() == string.m_length &&
- (string.m_hash == m_hash || !string.m_hash || !m_hash) &&
- 0 == ::memcmp(constData(), string.m_data, string.m_length * sizeof(QChar));
-}
-
-quint32 QHashedString::hash() const
-{
- if (!m_hash) computeHash();
- return m_hash;
-}
-
-quint32 QHashedString::existingHash() const
-{
- return m_hash;
-}
-
-bool QHashedString::isUpper(const QChar &qc)
-{
- ushort c = qc.unicode();
- // Optimize for _, a-z and A-Z.
- return ((c != '_' ) && (!(c >= 'a' && c <= 'z')) &&
- ((c >= 'A' && c <= 'Z') || QChar::category(c) == QChar::Letter_Uppercase));
-}
-
-QHashedV8String::QHashedV8String()
-{
-}
-
-QHashedV8String::QHashedV8String(v8::Handle<v8::String> string)
-: m_hash(string->CompleteHash()), m_string(string)
-{
- Q_ASSERT(!m_string.IsEmpty());
-}
-
-QHashedV8String::QHashedV8String(const QHashedV8String &string)
-: m_hash(string.m_hash), m_string(string.m_string)
-{
-}
-
-QHashedV8String &QHashedV8String::operator=(const QHashedV8String &other)
-{
- m_hash = other.m_hash;
- m_string = other.m_string;
- return *this;
-}
-
-bool QHashedV8String::operator==(const QHashedV8String &string)
-{
- return m_hash.hash == string.m_hash.hash && m_hash.length == string.m_hash.length &&
- m_string.IsEmpty() == m_string.IsEmpty() &&
- (m_string.IsEmpty() || m_string->StrictEquals(string.m_string));
-}
-
-quint32 QHashedV8String::hash() const
-{
- return m_hash.hash;
-}
-
-int QHashedV8String::length() const
-{
- return m_hash.length;
-}
-
-quint32 QHashedV8String::symbolId() const
-{
- return m_hash.symbol_id;
-}
-
-v8::Handle<v8::String> QHashedV8String::string() const
-{
- return m_string;
-}
-
-QHashedStringRef::QHashedStringRef()
-: m_data(0), m_length(0), m_hash(0)
-{
-}
-
-QHashedStringRef::QHashedStringRef(const QString &str)
-: m_data(str.constData()), m_length(str.length()), m_hash(0)
-{
-}
-
-QHashedStringRef::QHashedStringRef(const QChar *data, int length)
-: m_data(data), m_length(length), m_hash(0)
-{
-}
-
-QHashedStringRef::QHashedStringRef(const QChar *data, int length, quint32 hash)
-: m_data(data), m_length(length), m_hash(hash)
-{
-}
-
-QHashedStringRef::QHashedStringRef(const QHashedString &string)
-: m_data(string.constData()), m_length(string.length()), m_hash(string.m_hash)
-{
-}
-
-QHashedStringRef::QHashedStringRef(const QHashedStringRef &string)
-: m_data(string.m_data), m_length(string.m_length), m_hash(string.m_hash)
-{
-}
-
-bool QHashedStringRef::operator==(const QHashedString &string) const
-{
- return m_length == (uint)string.length() &&
- (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
- 0 == ::memcmp(string.constData(), m_data, m_length * sizeof(QChar));
-}
-
-bool QHashedStringRef::operator==(const QHashedStringRef &string) const
-{
- return m_length == string.m_length &&
- (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
- 0 == ::memcmp(string.m_data, m_data, m_length * sizeof(QChar));
-}
-
-const QChar *QHashedStringRef::constData() const
-{
- return m_data;
-}
-
-quint32 QHashedStringRef::length() const
-{
- return m_length;
-}
-
-bool QHashedStringRef::startsWithUpper() const
-{
- if (m_length < 1) return false;
- return QHashedString::isUpper(m_data[0]);
-}
-
-quint32 QHashedStringRef::hash() const
-{
- if (!m_hash) computeHash();
- return m_hash;
-}
-
-QT_END_NAMESPACE
-
-#endif // QHASHEDSTRING_P_H
diff --git a/src/declarative/qml/v8/qv8_p.h b/src/declarative/qml/v8/qv8_p.h
index 8df007e804..d41fb559f7 100644
--- a/src/declarative/qml/v8/qv8_p.h
+++ b/src/declarative/qml/v8/qv8_p.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../../../3rdparty/v8/include/v8.h"
+#include <private/v8.h>
diff --git a/src/declarative/qml/v8/qv8contextwrapper.cpp b/src/declarative/qml/v8/qv8contextwrapper.cpp
index f41c994a0d..29857b2585 100644
--- a/src/declarative/qml/v8/qv8contextwrapper.cpp
+++ b/src/declarative/qml/v8/qv8contextwrapper.cpp
@@ -282,19 +282,19 @@ v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property,
if (context->imports && QV8Engine::startsWithUpper(property)) {
// Search for attached properties, enums and imported scripts
- QDeclarativeTypeNameCache::Data *data = context->imports->data(propertystring);
-
- if (data) {
- if (data->importedScriptIndex != -1) {
- int index = data->importedScriptIndex;
+ QDeclarativeTypeNameCache::Result r = context->imports->query(propertystring);
+
+ if (r.isValid()) {
+ if (r.scriptIndex != -1) {
+ int index = r.scriptIndex;
if (index < context->importedScripts.count())
return context->importedScripts.at(index);
else
return v8::Undefined();
- } else if (data->type) {
- return engine->typeWrapper()->newObject(scopeObject, data->type);
- } else if (data->typeNamespace) {
- return engine->typeWrapper()->newObject(scopeObject, data->typeNamespace);
+ } else if (r.type) {
+ return engine->typeWrapper()->newObject(scopeObject, r.type);
+ } else if (r.importNamespace) {
+ return engine->typeWrapper()->newObject(scopeObject, context->imports, r.importNamespace);
}
Q_ASSERT(!"Unreachable");
}
diff --git a/src/declarative/qml/v8/qv8debug_p.h b/src/declarative/qml/v8/qv8debug_p.h
index 51208aac8e..e6bfdb7845 100644
--- a/src/declarative/qml/v8/qv8debug_p.h
+++ b/src/declarative/qml/v8/qv8debug_p.h
@@ -1 +1 @@
-#include "../../../3rdparty/v8/include/v8-debug.h"
+#include <private/v8-debug.h>
diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp
index 4f5caa13f4..8eaf9024ea 100644
--- a/src/declarative/qml/v8/qv8engine.cpp
+++ b/src/declarative/qml/v8/qv8engine.cpp
@@ -391,7 +391,7 @@ QNetworkAccessManager *QV8Engine::networkAccessManager()
return QDeclarativeEnginePrivate::get(m_engine)->getNetworkAccessManager();
}
-const QSet<QString> &QV8Engine::illegalNames() const
+const QStringHash<bool> &QV8Engine::illegalNames() const
{
return m_illegalNames;
}
@@ -561,7 +561,7 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
v8::Local<v8::Value> names = m_getOwnPropertyNames->Call(global, 1, args);
v8::Local<v8::Array> namesArray = v8::Local<v8::Array>::Cast(names);
for (quint32 ii = 0; ii < namesArray->Length(); ++ii)
- m_illegalNames.insert(toString(namesArray->Get(ii)));
+ m_illegalNames.insert(toString(namesArray->Get(ii)), true);
}
{
diff --git a/src/declarative/qml/v8/qv8engine_p.h b/src/declarative/qml/v8/qv8engine_p.h
index 43ef9821ac..bd5f360748 100644
--- a/src/declarative/qml/v8/qv8engine_p.h
+++ b/src/declarative/qml/v8/qv8engine_p.h
@@ -330,7 +330,7 @@ public:
virtual QNetworkAccessManager *networkAccessManager();
// Return the list of illegal id names (the names of the properties on the global object)
- const QSet<QString> &illegalNames() const;
+ const QStringHash<bool> &illegalNames() const;
inline void collectGarbage() { gc(); }
static void gc();
@@ -419,7 +419,7 @@ protected:
QVector<Deletable *> m_extensionData;
Deletable *m_listModelData;
- QSet<QString> m_illegalNames;
+ QStringHash<bool> m_illegalNames;
Exception m_exception;
diff --git a/src/declarative/qml/v8/qv8include.cpp b/src/declarative/qml/v8/qv8include.cpp
index 1d68e8e4be..2e23914f2d 100644
--- a/src/declarative/qml/v8/qv8include.cpp
+++ b/src/declarative/qml/v8/qv8include.cpp
@@ -130,7 +130,7 @@ void QV8Include::finished()
QByteArray data = m_reply->readAll();
QString code = QString::fromUtf8(data);
- QDeclarativeScriptParser::extractPragmas(code);
+ QDeclarativeScript::Parser::extractPragmas(code);
QDeclarativeContextData *importContext = new QDeclarativeContextData;
importContext->isInternal = true;
@@ -203,7 +203,7 @@ v8::Handle<v8::Value> QV8Include::include(const v8::Arguments &args)
if (f.open(QIODevice::ReadOnly)) {
QByteArray data = f.readAll();
QString code = QString::fromUtf8(data);
- QDeclarativeScriptParser::extractPragmas(code);
+ QDeclarativeScript::Parser::extractPragmas(code);
QDeclarativeContextData *importContext = new QDeclarativeContextData;
importContext->isInternal = true;
diff --git a/src/declarative/qml/v8/qv8qobjectwrapper.cpp b/src/declarative/qml/v8/qv8qobjectwrapper.cpp
index c7ed0116e1..52e106494c 100644
--- a/src/declarative/qml/v8/qv8qobjectwrapper.cpp
+++ b/src/declarative/qml/v8/qv8qobjectwrapper.cpp
@@ -280,8 +280,8 @@ void QV8QObjectWrapper::init(QV8Engine *engine)
{
v8::Local<v8::Object> prototype = engine->global()->Get(v8::String::New("Function"))->ToObject()->Get(v8::String::New("prototype"))->ToObject();
- prototype->Set(v8::String::New("connect"), V8FUNCTION(Connect, engine));
- prototype->Set(v8::String::New("disconnect"), V8FUNCTION(Disconnect, engine));
+ prototype->Set(v8::String::New("connect"), V8FUNCTION(Connect, engine), v8::DontEnum);
+ prototype->Set(v8::String::New("disconnect"), V8FUNCTION(Disconnect, engine), v8::DontEnum);
}
}
@@ -618,14 +618,20 @@ v8::Handle<v8::Value> QV8QObjectWrapper::Getter(v8::Local<v8::String> property,
if (QV8Engine::startsWithUpper(property)) {
// Check for attached properties
QDeclarativeContextData *context = v8engine->callingContext();
- QDeclarativeTypeNameCache::Data *data =
- context && (context->imports)?context->imports->data(propertystring):0;
-
- if (data) {
- if (data->type) {
- return v8engine->typeWrapper()->newObject(object, data->type, QV8TypeWrapper::ExcludeEnums);
- } else if (data->typeNamespace) {
- return v8engine->typeWrapper()->newObject(object, data->typeNamespace, QV8TypeWrapper::ExcludeEnums);
+
+ if (context && context->imports) {
+ QDeclarativeTypeNameCache::Result r = context->imports->query(propertystring);
+
+ if (r.isValid()) {
+ if (r.scriptIndex != -1) {
+ return v8::Undefined();
+ } else if (r.type) {
+ return v8engine->typeWrapper()->newObject(object, r.type, QV8TypeWrapper::ExcludeEnums);
+ } else if (r.importNamespace) {
+ return v8engine->typeWrapper()->newObject(object, context->imports, r.importNamespace,
+ QV8TypeWrapper::ExcludeEnums);
+ }
+ Q_ASSERT(!"Unreachable");
}
}
}
diff --git a/src/declarative/qml/v8/qv8typewrapper.cpp b/src/declarative/qml/v8/qv8typewrapper.cpp
index c51a2eeb7f..f46aaab320 100644
--- a/src/declarative/qml/v8/qv8typewrapper.cpp
+++ b/src/declarative/qml/v8/qv8typewrapper.cpp
@@ -45,6 +45,9 @@
#include <private/qdeclarativeengine_p.h>
#include <private/qdeclarativecontext_p.h>
+#include <private/qjsvalue_p.h>
+#include <private/qscript_impl_p.h>
+
QT_BEGIN_NAMESPACE
class QV8TypeResource : public QV8ObjectResource
@@ -58,12 +61,14 @@ public:
QV8TypeWrapper::TypeNameMode mode;
QDeclarativeGuard<QObject> object;
+
QDeclarativeType *type;
QDeclarativeTypeNameCache *typeNamespace;
+ const void *importNamespace;
};
QV8TypeResource::QV8TypeResource(QV8Engine *engine)
-: QV8ObjectResource(engine), mode(QV8TypeWrapper::IncludeEnums), type(0), typeNamespace(0)
+: QV8ObjectResource(engine), mode(QV8TypeWrapper::IncludeEnums), type(0), typeNamespace(0), importNamespace(0)
{
}
@@ -95,6 +100,7 @@ void QV8TypeWrapper::init(QV8Engine *engine)
m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
}
+// Returns a type wrapper for type t on o. This allows access of enums, and attached properties.
v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QDeclarativeType *t, TypeNameMode mode)
{
Q_ASSERT(t);
@@ -106,14 +112,18 @@ v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QDeclarativeType *t,
return rv;
}
-v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QDeclarativeTypeNameCache *t, TypeNameMode mode)
+// Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a
+// namespace.
+v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QDeclarativeTypeNameCache *t,
+ const void *importNamespace, TypeNameMode mode)
{
Q_ASSERT(t);
+ Q_ASSERT(importNamespace);
// XXX NewInstance() should be optimized
v8::Local<v8::Object> rv = m_constructor->NewInstance();
QV8TypeResource *r = new QV8TypeResource(m_engine);
t->addref();
- r->mode = mode; r->object = o; r->typeNamespace = t;
+ r->mode = mode; r->object = o; r->typeNamespace = t; r->importNamespace = importNamespace;
rv->SetExternalResource(r);
return rv;
}
@@ -136,19 +146,9 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property,
QDeclarativeType *type = resource->type;
if (QV8Engine::startsWithUpper(property)) {
- if (resource->mode == IncludeEnums) {
- QString name = v8engine->toString(property);
-
- // ### Optimize
- QByteArray enumName = name.toUtf8();
- const QMetaObject *metaObject = type->baseMetaObject();
- for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
- QMetaEnum e = metaObject->enumerator(ii);
- int value = e.keyToValue(enumName.constData());
- if (value != -1)
- return v8::Integer::New(value);
- }
- }
+ int value = type->enumValue(propertystring);
+ if (-1 != value)
+ return v8::Integer::New(value);
// Fall through to return empty handle
@@ -164,14 +164,15 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property,
// Fall through to return empty handle
} else if (resource->typeNamespace) {
+ Q_ASSERT(resource->importNamespace);
+ QDeclarativeTypeNameCache::Result r = resource->typeNamespace->query(propertystring,
+ resource->importNamespace);
- QDeclarativeTypeNameCache *typeNamespace = resource->typeNamespace;
- QDeclarativeTypeNameCache::Data *d = typeNamespace->data(propertystring);
- Q_ASSERT(!d || !d->typeNamespace); // Nested namespaces not supported
+ if (r.isValid()) {
+ Q_ASSERT(r.type);
- if (d && d->type) {
- return v8engine->typeWrapper()->newObject(object, d->type, resource->mode);
- } else if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = typeNamespace->moduleApi()) {
+ return v8engine->typeWrapper()->newObject(object, r.type, resource->mode);
+ } else if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi(resource->importNamespace)) {
if (moduleApi->scriptCallback) {
moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine());
@@ -184,8 +185,31 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property,
}
if (moduleApi->qobjectApi) {
+ // check for enum value
+ if (QV8Engine::startsWithUpper(property)) {
+ if (resource->mode == IncludeEnums) {
+ QString name = v8engine->toString(property);
+
+ // ### Optimize
+ QByteArray enumName = name.toUtf8();
+ const QMetaObject *metaObject = moduleApi->qobjectApi->metaObject();
+ for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
+ QMetaEnum e = metaObject->enumerator(ii);
+ int value = e.keyToValue(enumName.constData());
+ if (value != -1)
+ return v8::Integer::New(value);
+ }
+ }
+ }
+
+ // check for property.
v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(moduleApi->qobjectApi, propertystring, QV8QObjectWrapper::IgnoreRevision);
return rv;
+ } else if (moduleApi->scriptApi.isValid()) {
+ // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable.
+ QJSValuePrivate *apiprivate = QJSValuePrivate::get(moduleApi->scriptApi);
+ QScopedPointer<QJSValuePrivate> propertyValue(apiprivate->property(property).give());
+ return propertyValue->asV8Value(v8engine);
} else {
return v8::Handle<v8::Value>();
}
@@ -212,8 +236,6 @@ v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property,
QV8Engine *v8engine = resource->engine;
- // XXX TODO: Implement writes to module API objects
-
QHashedV8String propertystring(property);
if (resource->type && resource->object) {
@@ -224,7 +246,7 @@ v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property,
v8engine->qobjectWrapper()->setProperty(ao, propertystring, value,
QV8QObjectWrapper::IgnoreRevision);
} else if (resource->typeNamespace) {
- if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi()) {
+ if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi(resource->importNamespace)) {
if (moduleApi->scriptCallback) {
moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine());
moduleApi->scriptCallback = 0;
@@ -235,9 +257,20 @@ v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property,
moduleApi->qobjectCallback = 0;
}
- if (moduleApi->qobjectApi)
+ if (moduleApi->qobjectApi) {
v8engine->qobjectWrapper()->setProperty(moduleApi->qobjectApi, propertystring, value,
QV8QObjectWrapper::IgnoreRevision);
+ } else if (moduleApi->scriptApi.isValid()) {
+ QScopedPointer<QJSValuePrivate> setvalp(new QJSValuePrivate(v8engine, value));
+ QJSValuePrivate *apiprivate = QJSValuePrivate::get(moduleApi->scriptApi);
+ if (apiprivate->propertyFlags(property) & QJSValue::ReadOnly) {
+ QString error = QLatin1String("Cannot assign to read-only property \"") +
+ v8engine->toString(property) + QLatin1Char('\"');
+ v8::ThrowException(v8::Exception::Error(v8engine->toString(error)));
+ } else {
+ apiprivate->setProperty(property, setvalp.data());
+ }
+ }
}
}
diff --git a/src/declarative/qml/v8/qv8typewrapper_p.h b/src/declarative/qml/v8/qv8typewrapper_p.h
index e7403dfa40..2e79946a6e 100644
--- a/src/declarative/qml/v8/qv8typewrapper_p.h
+++ b/src/declarative/qml/v8/qv8typewrapper_p.h
@@ -73,7 +73,8 @@ public:
enum TypeNameMode { IncludeEnums, ExcludeEnums };
v8::Local<v8::Object> newObject(QObject *, QDeclarativeType *, TypeNameMode = IncludeEnums);
- v8::Local<v8::Object> newObject(QObject *, QDeclarativeTypeNameCache *, TypeNameMode = IncludeEnums);
+ v8::Local<v8::Object> newObject(QObject *, QDeclarativeTypeNameCache *, const void *,
+ TypeNameMode = IncludeEnums);
private:
static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
diff --git a/src/declarative/qml/v8/v8.pri b/src/declarative/qml/v8/v8.pri
index 9349742c78..175efd6b6c 100644
--- a/src/declarative/qml/v8/v8.pri
+++ b/src/declarative/qml/v8/v8.pri
@@ -8,7 +8,6 @@ HEADERS += \
$$PWD/qv8debug_p.h \
$$PWD/qv8stringwrapper_p.h \
$$PWD/qv8engine_p.h \
- $$PWD/qhashedstring_p.h \
$$PWD/qv8contextwrapper_p.h \
$$PWD/qv8qobjectwrapper_p.h \
$$PWD/qv8typewrapper_p.h \
@@ -25,7 +24,6 @@ HEADERS += \
SOURCES += \
$$PWD/qv8stringwrapper.cpp \
$$PWD/qv8engine.cpp \
- $$PWD/qhashedstring.cpp \
$$PWD/qv8contextwrapper.cpp \
$$PWD/qv8qobjectwrapper.cpp \
$$PWD/qv8typewrapper.cpp \
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 11e1c7cc0a..6cdba7c5d9 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -827,12 +827,8 @@ void QDeclarativeScriptActionPrivate::execute()
QDeclarativeScriptString scriptStr = hasRunScriptScript ? runScriptScript : script;
- const QString &str = scriptStr.script();
- if (!str.isEmpty()) {
- QDeclarativeExpression expr(scriptStr.context(), scriptStr.scopeObject(), str);
- QDeclarativeData *ddata = QDeclarativeData::get(q);
- if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty())
- expr.setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber);
+ if (!scriptStr.script().isEmpty()) {
+ QDeclarativeExpression expr(scriptStr);
expr.evaluate();
if (expr.hasError())
qmlInfo(q) << expr.error();
diff --git a/src/declarative/util/qdeclarativeconnections.cpp b/src/declarative/util/qdeclarativeconnections.cpp
index 6559d4bb20..57bb79c302 100644
--- a/src/declarative/util/qdeclarativeconnections.cpp
+++ b/src/declarative/util/qdeclarativeconnections.cpp
@@ -220,7 +220,7 @@ QDeclarativeConnectionsParser::compile(const QList<QDeclarativeCustomParserPrope
error(props.at(ii), QDeclarativeConnections::tr("Connections: syntax error"));
return QByteArray();
} else {
- QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(value);
+ QDeclarativeScript::Variant v = qvariant_cast<QDeclarativeScript::Variant>(value);
if (v.isScript()) {
ds << propName;
ds << v.asScript();
diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp
index 7a1dec88f0..f7a7738172 100644
--- a/src/declarative/util/qdeclarativefontloader.cpp
+++ b/src/declarative/util/qdeclarativefontloader.cpp
@@ -193,10 +193,9 @@ void QDeclarativeFontLoader::setSource(const QUrl &url)
Q_D(QDeclarativeFontLoader);
if (url == d->url)
return;
- d->url = qmlContext(this)->resolvedUrl(url);
+ d->url = url;
emit sourceChanged();
-#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
if (!localFile.isEmpty()) {
if (!d->fonts.contains(d->url)) {
@@ -211,9 +210,7 @@ void QDeclarativeFontLoader::setSource(const QUrl &url)
} else {
updateFontInfo(QFontDatabase::applicationFontFamilies(d->fonts[d->url]->id).at(0), Ready);
}
- } else
-#endif
- {
+ } else {
if (!d->fonts.contains(d->url)) {
QDeclarativeFontObject *fo = new QDeclarativeFontObject;
d->fonts[d->url] = fo;
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index 15d87c828d..3add850570 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -46,7 +46,7 @@
#include "parser/qdeclarativejsengine_p.h"
#include <qdeclarativecustomparser_p.h>
-#include <qdeclarativeparser_p.h>
+#include <qdeclarativescript_p.h>
#include <qdeclarativeengine_p.h>
#include <qdeclarativecontext.h>
#include <qdeclarativeinfo.h>
@@ -822,8 +822,8 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser
} else {
- QDeclarativeParser::Variant variant =
- qvariant_cast<QDeclarativeParser::Variant>(value);
+ QDeclarativeScript::Variant variant =
+ qvariant_cast<QDeclarativeScript::Variant>(value);
int ref = data.count();
@@ -837,7 +837,7 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser
d += char(variant.asBoolean());
} else if (variant.isScript()) {
if (definesEmptyList(variant.asScript())) {
- d[0] = char(QDeclarativeParser::Variant::Invalid); // marks empty list
+ d[0] = char(QDeclarativeScript::Variant::Invalid); // marks empty list
} else {
QByteArray script = variant.asScript().toUtf8();
int v = evaluateEnum(script);
@@ -847,14 +847,14 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser
AST::StringLiteral *literal = 0;
if (AST::CallExpression *callExpr = AST::cast<AST::CallExpression *>(node)) {
if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(callExpr->base)) {
- if (idExpr->name->asString() == QLatin1String("QT_TR_NOOP")) {
+ if (idExpr->name == QLatin1String("QT_TR_NOOP") || idExpr->name == QLatin1String("QT_TRID_NOOP")) {
if (callExpr->arguments && !callExpr->arguments->next)
literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->expression);
if (!literal) {
- error(prop, QDeclarativeListModel::tr("ListElement: improperly specified QT_TR_NOOP"));
+ error(prop, QDeclarativeListModel::tr("ListElement: improperly specified %1").arg(idExpr->name.toString()));
return false;
}
- } else if (idExpr->name->asString() == QLatin1String("QT_TRANSLATE_NOOP")) {
+ } else if (idExpr->name == QLatin1String("QT_TRANSLATE_NOOP")) {
if (callExpr->arguments && callExpr->arguments->next && !callExpr->arguments->next->next)
literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->next->expression);
if (!literal) {
@@ -866,14 +866,14 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser
}
if (literal) {
- d[0] = char(QDeclarativeParser::Variant::String);
- d += literal->value->asString().toUtf8();
+ d[0] = char(QDeclarativeScript::Variant::String);
+ d += literal->value.toUtf8();
} else {
error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value"));
return false;
}
} else {
- d[0] = char(QDeclarativeParser::Variant::Number);
+ d[0] = char(QDeclarativeScript::Variant::Number);
d += QByteArray::number(v);
}
}
@@ -932,6 +932,7 @@ void QDeclarativeListModelParser::setCustomData(QObject *obj, const QByteArray &
QDeclarativeListModel *rv = static_cast<QDeclarativeListModel *>(obj);
ModelNode *root = new ModelNode(rv->m_nested);
+ rv->m_nested->m_ownsRoot = true;
rv->m_nested->_root = root;
QStack<ModelNode *> nodes;
nodes << root;
@@ -963,17 +964,17 @@ void QDeclarativeListModelParser::setCustomData(QObject *obj, const QByteArray &
case ListInstruction::Value:
{
ModelNode *n = nodes.top();
- switch (QDeclarativeParser::Variant::Type(data[instr.dataIdx])) {
- case QDeclarativeParser::Variant::Invalid:
+ switch (QDeclarativeScript::Variant::Type(data[instr.dataIdx])) {
+ case QDeclarativeScript::Variant::Invalid:
n->isArray = true;
break;
- case QDeclarativeParser::Variant::Boolean:
+ case QDeclarativeScript::Variant::Boolean:
n->values.append(bool(data[1 + instr.dataIdx]));
break;
- case QDeclarativeParser::Variant::Number:
+ case QDeclarativeScript::Variant::Number:
n->values.append(QByteArray(data + 1 + instr.dataIdx).toDouble());
break;
- case QDeclarativeParser::Variant::String:
+ case QDeclarativeScript::Variant::String:
n->values.append(QString::fromUtf8(data + 1 + instr.dataIdx));
break;
default:
diff --git a/src/declarative/util/qdeclarativepackage_p.h b/src/declarative/util/qdeclarativepackage_p.h
index df6bfe9b91..8ae88488d0 100644
--- a/src/declarative/util/qdeclarativepackage_p.h
+++ b/src/declarative/util/qdeclarativepackage_p.h
@@ -58,7 +58,7 @@ class Q_AUTOTEST_EXPORT QDeclarativePackage : public QObject
Q_DECLARE_PRIVATE(QDeclarativePackage)
Q_CLASSINFO("DefaultProperty", "data")
- Q_PROPERTY(QDeclarativeListProperty<QObject> data READ data SCRIPTABLE false)
+ Q_PROPERTY(QDeclarativeListProperty<QObject> data READ data)
public:
QDeclarativePackage(QObject *parent=0);
diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp
index d03cd3bb1a..039803002c 100644
--- a/src/declarative/util/qdeclarativepropertychanges.cpp
+++ b/src/declarative/util/qdeclarativepropertychanges.cpp
@@ -48,7 +48,7 @@
#include <qdeclarativeinfo.h>
#include <qdeclarativecustomparser_p.h>
-#include <qdeclarativeparser_p.h>
+#include <qdeclarativescript_p.h>
#include <qdeclarativeexpression.h>
#include <qdeclarativebinding_p.h>
#include <qdeclarativecontext.h>
@@ -279,22 +279,22 @@ QDeclarativePropertyChangesParser::compile(const QList<QDeclarativeCustomParserP
ds << data.count();
for(int ii = 0; ii < data.count(); ++ii) {
- QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(data.at(ii).second);
+ QDeclarativeScript::Variant v = qvariant_cast<QDeclarativeScript::Variant>(data.at(ii).second);
QVariant var;
bool isScript = v.isScript();
QDeclarativeBinding::Identifier id = 0;
switch(v.type()) {
- case QDeclarativeParser::Variant::Boolean:
+ case QDeclarativeScript::Variant::Boolean:
var = QVariant(v.asBoolean());
break;
- case QDeclarativeParser::Variant::Number:
+ case QDeclarativeScript::Variant::Number:
var = QVariant(v.asNumber());
break;
- case QDeclarativeParser::Variant::String:
+ case QDeclarativeScript::Variant::String:
var = QVariant(v.asString());
break;
- case QDeclarativeParser::Variant::Invalid:
- case QDeclarativeParser::Variant::Script:
+ case QDeclarativeScript::Variant::Invalid:
+ case QDeclarativeScript::Variant::Script:
var = QVariant(v.asScript());
{
// Pre-rewrite the expression
diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp
index 32f36105fc..4f198a537e 100644
--- a/src/declarative/util/qdeclarativestateoperations.cpp
+++ b/src/declarative/util/qdeclarativestateoperations.cpp
@@ -131,12 +131,8 @@ void QDeclarativeStateChangeScript::setName(const QString &n)
void QDeclarativeStateChangeScript::execute(Reason)
{
Q_D(QDeclarativeStateChangeScript);
- const QString &script = d->script.script();
- if (!script.isEmpty()) {
- QDeclarativeExpression expr(d->script.context(), d->script.scopeObject(), script);
- QDeclarativeData *ddata = QDeclarativeData::get(this);
- if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty())
- expr.setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber);
+ if (!d->script.script().isEmpty()) {
+ QDeclarativeExpression expr(d->script);
expr.evaluate();
if (expr.hasError())
qmlInfo(this, expr.error());
diff --git a/src/declarative/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch b/src/declarative/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch
deleted file mode 100644
index 1fb3b90733..0000000000
--- a/src/declarative/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch
+++ /dev/null
@@ -1,343 +0,0 @@
-From e13ce09287a56c920d5ffdc5d4662d49f1838f16 Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Mon, 23 May 2011 15:47:20 +1000
-Subject: [PATCH 01/13] Add hashing and comparison methods to v8::String
-
-This allows us to more rapidly search for a v8::String inside
-a hash of QStrings.
----
- include/v8.h | 44 ++++++++++++++++++++++++++++++
- src/api.cc | 43 +++++++++++++++++++++++++++++
- src/heap-inl.h | 2 +
- src/heap.cc | 3 ++
- src/objects-inl.h | 1 +
- src/objects.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
- src/objects.h | 15 +++++++++-
- 7 files changed, 182 insertions(+), 3 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index d15d024..bbd29e9 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -994,6 +994,48 @@ class String : public Primitive {
- V8EXPORT int Utf8Length() const;
-
- /**
-+ * Returns the hash of this string.
-+ */
-+ V8EXPORT uint32_t Hash() const;
-+
-+ struct CompleteHashData {
-+ CompleteHashData() : length(0), hash(0), symbol_id(0) {}
-+ int length;
-+ uint32_t hash;
-+ uint32_t symbol_id;
-+ };
-+
-+ /**
-+ * Returns the "complete" hash of the string. This is
-+ * all the information about the string needed to implement
-+ * a very efficient hash keyed on the string.
-+ *
-+ * The members of CompleteHashData are:
-+ * length: The length of the string. Equivalent to Length()
-+ * hash: The hash of the string. Equivalent to Hash()
-+ * symbol_id: If the string is a sequential symbol, the symbol
-+ * id, otherwise 0. If the symbol ids of two strings are
-+ * the same (and non-zero) the two strings are identical.
-+ * If the symbol ids are different the strings may still be
-+ * identical, but an Equals() check must be performed.
-+ */
-+ V8EXPORT CompleteHashData CompleteHash() const;
-+
-+ /**
-+ * Compute a hash value for the passed UTF16 string
-+ * data.
-+ */
-+ V8EXPORT static uint32_t ComputeHash(uint16_t *string, int length);
-+ V8EXPORT static uint32_t ComputeHash(char *string, int length);
-+
-+ /**
-+ * Returns true if this string is equal to the external
-+ * string data provided.
-+ */
-+ V8EXPORT bool Equals(uint16_t *string, int length);
-+ V8EXPORT bool Equals(char *string, int length);
-+
-+ /**
- * Write the contents of the string to an external buffer.
- * If no arguments are given, expects the buffer to be large
- * enough to hold the entire string and NULL terminator. Copies
-@@ -1023,6 +1065,8 @@ class String : public Primitive {
- HINT_MANY_WRITES_EXPECTED = 1
- };
-
-+ V8EXPORT uint16_t GetCharacter(int index);
-+
- V8EXPORT int Write(uint16_t* buffer,
- int start = 0,
- int length = -1,
-diff --git a/src/api.cc b/src/api.cc
-index a2373cd..381935b 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -3284,6 +3284,49 @@ int String::Utf8Length() const {
- return str->Utf8Length();
- }
-
-+uint32_t String::Hash() const {
-+ i::Handle<i::String> str = Utils::OpenHandle(this);
-+ if (IsDeadCheck(str->GetIsolate(), "v8::String::Hash()")) return 0;
-+ return str->Hash();
-+}
-+
-+String::CompleteHashData String::CompleteHash() const {
-+ i::Handle<i::String> str = Utils::OpenHandle(this);
-+ if (IsDeadCheck(str->GetIsolate(), "v8::String::CompleteHash()")) return CompleteHashData();
-+ CompleteHashData result;
-+ result.length = str->length();
-+ result.hash = str->Hash();
-+ if (str->IsSeqString())
-+ result.symbol_id = i::SeqString::cast(*str)->symbol_id();
-+ return result;
-+}
-+
-+uint32_t String::ComputeHash(uint16_t *string, int length) {
-+ return i::HashSequentialString<i::uc16>(string, length) >> i::String::kHashShift;
-+}
-+
-+uint32_t String::ComputeHash(char *string, int length) {
-+ return i::HashSequentialString<char>(string, length) >> i::String::kHashShift;
-+}
-+
-+uint16_t String::GetCharacter(int index)
-+{
-+ i::Handle<i::String> str = Utils::OpenHandle(this);
-+ return str->Get(index);
-+}
-+
-+bool String::Equals(uint16_t *string, int length) {
-+ i::Handle<i::String> str = Utils::OpenHandle(this);
-+ if (IsDeadCheck(str->GetIsolate(), "v8::String::Equals()")) return 0;
-+ return str->SlowEqualsExternal(string, length);
-+}
-+
-+bool String::Equals(char *string, int length)
-+{
-+ i::Handle<i::String> str = Utils::OpenHandle(this);
-+ if (IsDeadCheck(str->GetIsolate(), "v8::String::Equals()")) return 0;
-+ return str->SlowEqualsExternal(string, length);
-+}
-
- int String::WriteUtf8(char* buffer,
- int capacity,
-diff --git a/src/heap-inl.h b/src/heap-inl.h
-index 99737ed..f4fce7b 100644
---- a/src/heap-inl.h
-+++ b/src/heap-inl.h
-@@ -93,6 +93,7 @@ MaybeObject* Heap::AllocateAsciiSymbol(Vector<const char> str,
- String* answer = String::cast(result);
- answer->set_length(str.length());
- answer->set_hash_field(hash_field);
-+ SeqString::cast(answer)->set_symbol_id(0);
-
- ASSERT_EQ(size, answer->Size());
-
-@@ -126,6 +127,7 @@ MaybeObject* Heap::AllocateTwoByteSymbol(Vector<const uc16> str,
- String* answer = String::cast(result);
- answer->set_length(str.length());
- answer->set_hash_field(hash_field);
-+ SeqString::cast(answer)->set_symbol_id(0);
-
- ASSERT_EQ(size, answer->Size());
-
-diff --git a/src/heap.cc b/src/heap.cc
-index 2b6c11f..930c97b 100644
---- a/src/heap.cc
-+++ b/src/heap.cc
-@@ -3519,6 +3519,7 @@ MaybeObject* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer,
- String* answer = String::cast(result);
- answer->set_length(chars);
- answer->set_hash_field(hash_field);
-+ SeqString::cast(result)->set_symbol_id(0);
-
- ASSERT_EQ(size, answer->Size());
-
-@@ -3561,6 +3562,7 @@ MaybeObject* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
- HeapObject::cast(result)->set_map(ascii_string_map());
- String::cast(result)->set_length(length);
- String::cast(result)->set_hash_field(String::kEmptyHashField);
-+ SeqString::cast(result)->set_symbol_id(0);
- ASSERT_EQ(size, HeapObject::cast(result)->Size());
- return result;
- }
-@@ -3596,6 +3598,7 @@ MaybeObject* Heap::AllocateRawTwoByteString(int length,
- HeapObject::cast(result)->set_map(string_map());
- String::cast(result)->set_length(length);
- String::cast(result)->set_hash_field(String::kEmptyHashField);
-+ SeqString::cast(result)->set_symbol_id(0);
- ASSERT_EQ(size, HeapObject::cast(result)->Size());
- return result;
- }
-diff --git a/src/objects-inl.h b/src/objects-inl.h
-index 65aec5d..c82080d 100644
---- a/src/objects-inl.h
-+++ b/src/objects-inl.h
-@@ -1924,6 +1924,7 @@ INT_ACCESSORS(ExternalArray, length, kLengthOffset)
-
-
- SMI_ACCESSORS(String, length, kLengthOffset)
-+SMI_ACCESSORS(SeqString, symbol_id, kSymbolIdOffset)
-
-
- uint32_t String::hash_field() {
-diff --git a/src/objects.cc b/src/objects.cc
-index df61956..dc4b260 100644
---- a/src/objects.cc
-+++ b/src/objects.cc
-@@ -5346,6 +5346,66 @@ static inline bool CompareStringContentsPartial(Isolate* isolate,
- }
- }
-
-+bool String::SlowEqualsExternal(uc16 *string, int length) {
-+ int len = this->length();
-+ if (len != length) return false;
-+ if (len == 0) return true;
-+
-+ // We know the strings are both non-empty. Compare the first chars
-+ // before we try to flatten the strings.
-+ if (this->Get(0) != string[0]) return false;
-+
-+ String* lhs = this->TryFlattenGetString();
-+
-+ if (lhs->IsFlat()) {
-+ if (lhs->IsAsciiRepresentation()) {
-+ Vector<const char> vec1 = lhs->ToAsciiVector();
-+ VectorIterator<char> buf1(vec1);
-+ VectorIterator<uc16> ib(string, length);
-+ return CompareStringContents(&buf1, &ib);
-+ } else {
-+ Vector<const uc16> vec1 = lhs->ToUC16Vector();
-+ Vector<const uc16> vec2(string, length);
-+ return CompareRawStringContents(vec1, vec2);
-+ }
-+ } else {
-+ Isolate* isolate = GetIsolate();
-+ isolate->objects_string_compare_buffer_a()->Reset(0, lhs);
-+ VectorIterator<uc16> ib(string, length);
-+ return CompareStringContents(isolate->objects_string_compare_buffer_a(), &ib);
-+ }
-+}
-+
-+bool String::SlowEqualsExternal(char *string, int length)
-+{
-+ int len = this->length();
-+ if (len != length) return false;
-+ if (len == 0) return true;
-+
-+ // We know the strings are both non-empty. Compare the first chars
-+ // before we try to flatten the strings.
-+ if (this->Get(0) != string[0]) return false;
-+
-+ String* lhs = this->TryFlattenGetString();
-+
-+ if (StringShape(lhs).IsSequentialAscii()) {
-+ const char* str1 = SeqAsciiString::cast(lhs)->GetChars();
-+ return CompareRawStringContents(Vector<const char>(str1, len),
-+ Vector<const char>(string, len));
-+ }
-+
-+ if (lhs->IsFlat()) {
-+ Vector<const uc16> vec1 = lhs->ToUC16Vector();
-+ VectorIterator<const uc16> buf1(vec1);
-+ VectorIterator<char> buf2(string, length);
-+ return CompareStringContents(&buf1, &buf2);
-+ } else {
-+ Isolate* isolate = GetIsolate();
-+ isolate->objects_string_compare_buffer_a()->Reset(0, lhs);
-+ VectorIterator<char> ib(string, length);
-+ return CompareStringContents(isolate->objects_string_compare_buffer_a(), &ib);
-+ }
-+}
-
- bool String::SlowEquals(String* other) {
- // Fast check: negative check with lengths.
-@@ -8655,9 +8715,24 @@ class AsciiSymbolKey : public SequentialSymbolKey<char> {
-
- MaybeObject* AsObject() {
- if (hash_field_ == 0) Hash();
-- return HEAP->AllocateAsciiSymbol(string_, hash_field_);
-+ MaybeObject *result = HEAP->AllocateAsciiSymbol(string_, hash_field_);
-+ if (!result->IsFailure() && result->ToObjectUnchecked()->IsSeqString()) {
-+ while (true) {
-+ Atomic32 my_symbol_id = next_symbol_id;
-+ if (my_symbol_id > Smi::kMaxValue)
-+ break;
-+ if (my_symbol_id == NoBarrier_CompareAndSwap(&next_symbol_id, my_symbol_id, my_symbol_id + 1)) {
-+ SeqString::cast(result->ToObjectUnchecked())->set_symbol_id(my_symbol_id);
-+ break;
-+ }
-+ }
-+ }
-+ return result;
- }
-+
-+ static Atomic32 next_symbol_id;
- };
-+Atomic32 AsciiSymbolKey::next_symbol_id = 1;
-
-
- class TwoByteSymbolKey : public SequentialSymbolKey<uc16> {
-diff --git a/src/objects.h b/src/objects.h
-index e966b3d..6e26f57 100644
---- a/src/objects.h
-+++ b/src/objects.h
-@@ -5359,6 +5359,9 @@ class String: public HeapObject {
- bool IsAsciiEqualTo(Vector<const char> str);
- bool IsTwoByteEqualTo(Vector<const uc16> str);
-
-+ bool SlowEqualsExternal(uc16 *string, int length);
-+ bool SlowEqualsExternal(char *string, int length);
-+
- // Return a UTF8 representation of the string. The string is null
- // terminated but may optionally contain nulls. Length is returned
- // in length_output if length_output is not a null pointer The string
-@@ -5610,9 +5613,17 @@ class String: public HeapObject {
- class SeqString: public String {
- public:
-
-+ // Get and set the symbol id of the string
-+ inline int symbol_id();
-+ inline void set_symbol_id(int value);
-+
- // Casting.
- static inline SeqString* cast(Object* obj);
-
-+ // Layout description.
-+ static const int kSymbolIdOffset = String::kSize;
-+ static const int kSize = kSymbolIdOffset + kPointerSize;
-+
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
- };
-@@ -5647,7 +5658,7 @@ class SeqAsciiString: public SeqString {
- }
-
- // Layout description.
-- static const int kHeaderSize = String::kSize;
-+ static const int kHeaderSize = SeqString::kSize;
- static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize);
-
- // Maximal memory usage for a single sequential ASCII string.
-@@ -5701,7 +5712,7 @@ class SeqTwoByteString: public SeqString {
- }
-
- // Layout description.
-- static const int kHeaderSize = String::kSize;
-+ static const int kHeaderSize = SeqString::kSize;
- static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize);
-
- // Maximal memory usage for a single sequential two-byte string.
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0002-Add-a-bit-field-3-to-Map.patch b/src/declarative/v8/0002-Add-a-bit-field-3-to-Map.patch
deleted file mode 100644
index daf8b35570..0000000000
--- a/src/declarative/v8/0002-Add-a-bit-field-3-to-Map.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 7c9cfff80b7864d5687432d424074e51712c4a07 Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Mon, 23 May 2011 15:55:26 +1000
-Subject: [PATCH 02/13] Add a bit field 3 to Map
-
-Bit field 3 will be used to add QML specific map flags.
----
- src/heap.cc | 2 ++
- src/objects-inl.h | 10 ++++++++++
- src/objects.cc | 2 ++
- src/objects.h | 9 ++++++++-
- 4 files changed, 22 insertions(+), 1 deletions(-)
-
-diff --git a/src/heap.cc b/src/heap.cc
-index 930c97b..900f462 100644
---- a/src/heap.cc
-+++ b/src/heap.cc
-@@ -1573,6 +1573,7 @@ MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type,
- reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
- reinterpret_cast<Map*>(result)->set_bit_field(0);
- reinterpret_cast<Map*>(result)->set_bit_field2(0);
-+ reinterpret_cast<Map*>(result)->set_bit_field3(0);
- return result;
- }
-
-@@ -1599,6 +1600,7 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type, int instance_size) {
- map->set_unused_property_fields(0);
- map->set_bit_field(0);
- map->set_bit_field2((1 << Map::kIsExtensible) | (1 << Map::kHasFastElements));
-+ map->set_bit_field3(0);
-
- // If the map object is aligned fill the padding area with Smi 0 objects.
- if (Map::kPadStart < Map::kSize) {
-diff --git a/src/objects-inl.h b/src/objects-inl.h
-index c82080d..cce3edd 100644
---- a/src/objects-inl.h
-+++ b/src/objects-inl.h
-@@ -2430,6 +2430,16 @@ void Map::set_bit_field2(byte value) {
- }
-
-
-+byte Map::bit_field3() {
-+ return READ_BYTE_FIELD(this, kBitField3Offset);
-+}
-+
-+
-+void Map::set_bit_field3(byte value) {
-+ WRITE_BYTE_FIELD(this, kBitField3Offset, value);
-+}
-+
-+
- void Map::set_non_instance_prototype(bool value) {
- if (value) {
- set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
-diff --git a/src/objects.cc b/src/objects.cc
-index dc4b260..79d7240 100644
---- a/src/objects.cc
-+++ b/src/objects.cc
-@@ -3614,6 +3614,7 @@ MaybeObject* Map::CopyDropDescriptors() {
- }
- Map::cast(result)->set_bit_field(bit_field());
- Map::cast(result)->set_bit_field2(bit_field2());
-+ Map::cast(result)->set_bit_field3(bit_field3());
- Map::cast(result)->set_is_shared(false);
- Map::cast(result)->ClearCodeCache(heap);
- return result;
-@@ -3642,6 +3643,7 @@ MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode,
-
- Map::cast(result)->set_bit_field(bit_field());
- Map::cast(result)->set_bit_field2(bit_field2());
-+ Map::cast(result)->set_bit_field3(bit_field3());
-
- Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP);
-
-diff --git a/src/objects.h b/src/objects.h
-index 6e26f57..07e1089 100644
---- a/src/objects.h
-+++ b/src/objects.h
-@@ -3597,6 +3597,10 @@ class Map: public HeapObject {
- inline byte bit_field2();
- inline void set_bit_field2(byte value);
-
-+ // Bit field 3.
-+ inline byte bit_field3();
-+ inline void set_bit_field3(byte value);
-+
- // Tells whether the object in the prototype property will be used
- // for instances created from this function. If the prototype
- // property is set to a value that is not a JSObject, the prototype
-@@ -3844,7 +3848,7 @@ class Map: public HeapObject {
- // Layout description.
- static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
- static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
-- static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;
-+ static const int kPrototypeOffset = POINTER_SIZE_ALIGN(kInstanceAttributesOffset + 2 * kIntSize);
- static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
- static const int kInstanceDescriptorsOffset =
- kConstructorOffset + kPointerSize;
-@@ -3876,6 +3880,7 @@ class Map: public HeapObject {
- static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1;
- static const int kBitFieldOffset = kInstanceAttributesOffset + 2;
- static const int kBitField2Offset = kInstanceAttributesOffset + 3;
-+ static const int kBitField3Offset = kInstanceAttributesOffset + 4;
-
- STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);
-
-@@ -3898,6 +3903,8 @@ class Map: public HeapObject {
- static const int kIsShared = 5;
- static const int kHasExternalArrayElements = 6;
-
-+ // Bit positions for bit field 3
-+
- // Layout of the default cache. It holds alternating name and code objects.
- static const int kCodeCacheEntrySize = 2;
- static const int kCodeCacheEntryNameOffset = 0;
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch b/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch
deleted file mode 100644
index 1c81b2af9d..0000000000
--- a/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch
+++ /dev/null
@@ -1,364 +0,0 @@
-From ae8688b53d67044f2c9b0cce25fc282b078610c1 Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Mon, 23 May 2011 16:21:02 +1000
-Subject: [PATCH 03/13] Add a "fallback" mode for named property interceptors
-
-By default interceptors are called before the normal property
-resolution on objects. When an interceptor is installed as a
-"fallback" interceptor, it is only called if the object doesn't
-already have the property.
-
-In the case of a global object having an fallback interceptor,
-the interceptor is not invoked at all for var or function
-declarations.
----
- include/v8.h | 8 ++++++++
- src/api.cc | 29 +++++++++++++++++++++++++++++
- src/factory.cc | 4 ++++
- src/handles.cc | 6 ++++--
- src/handles.h | 3 ++-
- src/objects-inl.h | 16 ++++++++++++++++
- src/objects.cc | 22 ++++++++++++++++------
- src/objects.h | 18 ++++++++++++++----
- src/runtime.cc | 11 ++++++-----
- 9 files changed, 99 insertions(+), 18 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index bbd29e9..85452aa 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -2169,6 +2169,7 @@ class V8EXPORT FunctionTemplate : public Template {
- NamedPropertyQuery query,
- NamedPropertyDeleter remover,
- NamedPropertyEnumerator enumerator,
-+ bool is_fallback,
- Handle<Value> data);
- void SetIndexedInstancePropertyHandler(IndexedPropertyGetter getter,
- IndexedPropertySetter setter,
-@@ -2253,6 +2254,13 @@ class V8EXPORT ObjectTemplate : public Template {
- NamedPropertyEnumerator enumerator = 0,
- Handle<Value> data = Handle<Value>());
-
-+ void SetFallbackPropertyHandler(NamedPropertyGetter getter,
-+ NamedPropertySetter setter = 0,
-+ NamedPropertyQuery query = 0,
-+ NamedPropertyDeleter deleter = 0,
-+ NamedPropertyEnumerator enumerator = 0,
-+ Handle<Value> data = Handle<Value>());
-+
- /**
- * Sets an indexed property handler on the object template.
- *
-diff --git a/src/api.cc b/src/api.cc
-index 381935b..8b0b32a 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -981,6 +981,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler(
- NamedPropertyQuery query,
- NamedPropertyDeleter remover,
- NamedPropertyEnumerator enumerator,
-+ bool is_fallback,
- Handle<Value> data) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- if (IsDeadCheck(isolate,
-@@ -999,6 +1000,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler(
- if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
- if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
- if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
-+ obj->set_is_fallback(i::Smi::FromInt(is_fallback));
-
- if (data.IsEmpty()) data = v8::Undefined();
- obj->set_data(*Utils::OpenHandle(*data));
-@@ -1143,6 +1145,33 @@ void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
- query,
- remover,
- enumerator,
-+ false,
-+ data);
-+}
-+
-+
-+void ObjectTemplate::SetFallbackPropertyHandler(NamedPropertyGetter getter,
-+ NamedPropertySetter setter,
-+ NamedPropertyQuery query,
-+ NamedPropertyDeleter remover,
-+ NamedPropertyEnumerator enumerator,
-+ Handle<Value> data) {
-+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetFallbackPropertyHandler()")) {
-+ return;
-+ }
-+ ENTER_V8(isolate);
-+ i::HandleScope scope(isolate);
-+ EnsureConstructor(this);
-+ i::FunctionTemplateInfo* constructor =
-+ i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
-+ i::Handle<i::FunctionTemplateInfo> cons(constructor);
-+ Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
-+ setter,
-+ query,
-+ remover,
-+ enumerator,
-+ true,
- data);
- }
-
-diff --git a/src/factory.cc b/src/factory.cc
-index 7dee66f..dcdc645 100644
---- a/src/factory.cc
-+++ b/src/factory.cc
-@@ -1058,6 +1058,10 @@ Handle<JSFunction> Factory::CreateApiFunction(
- // Set interceptor information in the map.
- if (!obj->named_property_handler()->IsUndefined()) {
- map->set_has_named_interceptor();
-+
-+ InterceptorInfo *nph = InterceptorInfo::cast(obj->named_property_handler());
-+ bool is_fallback = nph->is_fallback()->IsUndefined()?false:nph->is_fallback()->value();
-+ map->set_named_interceptor_is_fallback(is_fallback);
- }
- if (!obj->indexed_property_handler()->IsUndefined()) {
- map->set_has_indexed_interceptor();
-diff --git a/src/handles.cc b/src/handles.cc
-index 326de86..dd3a86c 100644
---- a/src/handles.cc
-+++ b/src/handles.cc
-@@ -262,9 +262,11 @@ Handle<Object> SetProperty(Handle<JSObject> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes,
-- StrictModeFlag strict_mode) {
-+ StrictModeFlag strict_mode,
-+ bool skip_fallback_interceptor) {
- CALL_HEAP_FUNCTION(object->GetIsolate(),
-- object->SetProperty(*key, *value, attributes, strict_mode),
-+ object->SetProperty(*key, *value, attributes, strict_mode,
-+ skip_fallback_interceptor),
- Object);
- }
-
-diff --git a/src/handles.h b/src/handles.h
-index 3839f37..4b42506 100644
---- a/src/handles.h
-+++ b/src/handles.h
-@@ -188,7 +188,8 @@ Handle<Object> SetProperty(Handle<JSObject> object,
- Handle<String> key,
- Handle<Object> value,
- PropertyAttributes attributes,
-- StrictModeFlag strict_mode);
-+ StrictModeFlag strict_mode,
-+ bool skip_fallback_interceptor = false);
-
- Handle<Object> SetProperty(Handle<Object> object,
- Handle<Object> key,
-diff --git a/src/objects-inl.h b/src/objects-inl.h
-index cce3edd..6aaca2f 100644
---- a/src/objects-inl.h
-+++ b/src/objects-inl.h
-@@ -2521,6 +2521,21 @@ bool Map::is_shared() {
- }
-
-
-+void Map::set_named_interceptor_is_fallback(bool value)
-+{
-+ if (value) {
-+ set_bit_field3(bit_field3() | (1 << kNamedInterceptorIsFallback));
-+ } else {
-+ set_bit_field3(bit_field3() & ~(1 << kNamedInterceptorIsFallback));
-+ }
-+}
-+
-+bool Map::named_interceptor_is_fallback()
-+{
-+ return ((1 << kNamedInterceptorIsFallback) & bit_field3()) != 0;
-+}
-+
-+
- JSFunction* Map::unchecked_constructor() {
- return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
- }
-@@ -2970,6 +2985,7 @@ ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
- ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
- ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
- ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
-+ACCESSORS(InterceptorInfo, is_fallback, Smi, kFallbackOffset)
-
- ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
- ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
-diff --git a/src/objects.cc b/src/objects.cc
-index 79d7240..15e2cdb 100644
---- a/src/objects.cc
-+++ b/src/objects.cc
-@@ -1712,9 +1712,10 @@ MaybeObject* JSObject::SetPropertyWithInterceptor(
- MaybeObject* JSObject::SetProperty(String* name,
- Object* value,
- PropertyAttributes attributes,
-- StrictModeFlag strict_mode) {
-+ StrictModeFlag strict_mode,
-+ bool skip_fallback_interceptor) {
- LookupResult result;
-- LocalLookup(name, &result);
-+ LocalLookup(name, &result, skip_fallback_interceptor);
- return SetProperty(&result, name, value, attributes, strict_mode);
- }
-
-@@ -3148,7 +3149,8 @@ AccessorDescriptor* Map::FindAccessor(String* name) {
- }
-
-
--void JSObject::LocalLookup(String* name, LookupResult* result) {
-+void JSObject::LocalLookup(String* name, LookupResult* result,
-+ bool skip_fallback_interceptor) {
- ASSERT(name->IsString());
-
- Heap* heap = GetHeap();
-@@ -3174,22 +3176,30 @@ void JSObject::LocalLookup(String* name, LookupResult* result) {
- }
-
- // Check for lookup interceptor except when bootstrapping.
-- if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) {
-+ bool wouldIntercept = HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive();
-+ if (wouldIntercept && !map()->named_interceptor_is_fallback()) {
- result->InterceptorResult(this);
- return;
- }
-
- LocalLookupRealNamedProperty(name, result);
-+
-+ if (wouldIntercept && !skip_fallback_interceptor && !result->IsProperty() &&
-+ map()->named_interceptor_is_fallback()) {
-+ result->InterceptorResult(this);
-+ return;
-+ }
- }
-
-
--void JSObject::Lookup(String* name, LookupResult* result) {
-+void JSObject::Lookup(String* name, LookupResult* result,
-+ bool skip_fallback_interceptor) {
- // Ecma-262 3rd 8.6.2.4
- Heap* heap = GetHeap();
- for (Object* current = this;
- current != heap->null_value();
- current = JSObject::cast(current)->GetPrototype()) {
-- JSObject::cast(current)->LocalLookup(name, result);
-+ JSObject::cast(current)->LocalLookup(name, result, skip_fallback_interceptor);
- if (result->IsProperty()) return;
- }
- result->NotFound();
-diff --git a/src/objects.h b/src/objects.h
-index 07e1089..a209cd0 100644
---- a/src/objects.h
-+++ b/src/objects.h
-@@ -1405,7 +1405,8 @@ class JSObject: public HeapObject {
- MUST_USE_RESULT MaybeObject* SetProperty(String* key,
- Object* value,
- PropertyAttributes attributes,
-- StrictModeFlag strict_mode);
-+ StrictModeFlag strict_mode,
-+ bool skip_fallback_interceptor = false);
- MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
- String* key,
- Object* value,
-@@ -1637,8 +1638,8 @@ class JSObject: public HeapObject {
-
- // Lookup a property. If found, the result is valid and has
- // detailed information.
-- void LocalLookup(String* name, LookupResult* result);
-- void Lookup(String* name, LookupResult* result);
-+ void LocalLookup(String* name, LookupResult* result, bool skip_fallback_interceptor = false);
-+ void Lookup(String* name, LookupResult* result, bool skip_fallback_interceptor = false);
-
- // The following lookup functions skip interceptors.
- void LocalLookupRealNamedProperty(String* name, LookupResult* result);
-@@ -3714,6 +3715,12 @@ class Map: public HeapObject {
- inline void set_is_access_check_needed(bool access_check_needed);
- inline bool is_access_check_needed();
-
-+
-+ // Whether the named interceptor is a fallback interceptor or not
-+ inline void set_named_interceptor_is_fallback(bool value);
-+ inline bool named_interceptor_is_fallback();
-+
-+
- // [prototype]: implicit prototype object.
- DECL_ACCESSORS(prototype, Object)
-
-@@ -3904,6 +3911,7 @@ class Map: public HeapObject {
- static const int kHasExternalArrayElements = 6;
-
- // Bit positions for bit field 3
-+ static const int kNamedInterceptorIsFallback = 0;
-
- // Layout of the default cache. It holds alternating name and code objects.
- static const int kCodeCacheEntrySize = 2;
-@@ -6276,6 +6284,7 @@ class InterceptorInfo: public Struct {
- DECL_ACCESSORS(deleter, Object)
- DECL_ACCESSORS(enumerator, Object)
- DECL_ACCESSORS(data, Object)
-+ DECL_ACCESSORS(is_fallback, Smi)
-
- static inline InterceptorInfo* cast(Object* obj);
-
-@@ -6295,7 +6304,8 @@ class InterceptorInfo: public Struct {
- static const int kDeleterOffset = kQueryOffset + kPointerSize;
- static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
- static const int kDataOffset = kEnumeratorOffset + kPointerSize;
-- static const int kSize = kDataOffset + kPointerSize;
-+ static const int kFallbackOffset = kDataOffset + kPointerSize;
-+ static const int kSize = kFallbackOffset + kPointerSize;
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
-diff --git a/src/runtime.cc b/src/runtime.cc
-index 7335da8..660352c 100644
---- a/src/runtime.cc
-+++ b/src/runtime.cc
-@@ -1097,7 +1097,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
- // Lookup the property in the global object, and don't set the
- // value of the variable if the property is already there.
- LookupResult lookup;
-- global->Lookup(*name, &lookup);
-+ global->Lookup(*name, &lookup, true);
- if (lookup.IsProperty()) {
- // Determine if the property is local by comparing the holder
- // against the global object. The information will be used to
-@@ -1152,7 +1152,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
- }
-
- LookupResult lookup;
-- global->LocalLookup(*name, &lookup);
-+ global->LocalLookup(*name, &lookup, true);
-
- PropertyAttributes attributes = is_const_property
- ? static_cast<PropertyAttributes>(base | READ_ONLY)
-@@ -1196,7 +1196,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
- name,
- value,
- attributes,
-- strict_mode));
-+ strict_mode,
-+ true));
- }
- }
-
-@@ -1343,7 +1344,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
- JSObject* real_holder = global;
- LookupResult lookup;
- while (true) {
-- real_holder->LocalLookup(*name, &lookup);
-+ real_holder->LocalLookup(*name, &lookup, true);
- if (lookup.IsProperty()) {
- // Determine if this is a redeclaration of something read-only.
- if (lookup.IsReadOnly()) {
-@@ -1400,7 +1401,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
-
- global = isolate->context()->global();
- if (assign) {
-- return global->SetProperty(*name, args[2], attributes, strict_mode);
-+ return global->SetProperty(*name, args[2], attributes, strict_mode, true);
- }
- return isolate->heap()->undefined_value();
- }
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0004-Generalize-external-object-resources.patch b/src/declarative/v8/0004-Generalize-external-object-resources.patch
deleted file mode 100644
index 6b85666cf0..0000000000
--- a/src/declarative/v8/0004-Generalize-external-object-resources.patch
+++ /dev/null
@@ -1,894 +0,0 @@
-From 4827116b12c50f6662794017c5a662b5dbb2da0b Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Mon, 23 May 2011 16:55:35 +1000
-Subject: [PATCH 04/13] Generalize external object resources
-
-V8 was already able to manage and finalize an external string
-resource. This change generalizes that mechanism to handle a
-single generic external resource - a v8::Object::ExternalResource
-derived instance - on normal JSObject's.
-
-This is useful for mapping C++ objects to JS objects where the
-C++ object's memory is effectively owned by the JS Object, and
-thus needs to destroyed when the JS Object is garbage collected.
-The V8 mailing list suggests using a weak persistent handle for
-this purpose, but that seems to incur a fairly massive performance
-penalty for short lived objects as weak persistent handle callbacks
-are not called until the object has been promoted into the old
-object space.
----
- include/v8.h | 25 ++++++
- src/api.cc | 64 ++++++++++++++-
- src/extensions/externalize-string-extension.cc | 4 +-
- src/factory.cc | 11 +++
- src/heap-inl.h | 101 +++++++++++++++---------
- src/heap.cc | 68 ++++++++--------
- src/heap.h | 42 +++++-----
- src/liveobjectlist.cc | 4 +-
- src/mark-compact.cc | 21 +++---
- src/objects-inl.h | 41 +++++++++-
- src/objects.h | 14 +++-
- 11 files changed, 280 insertions(+), 115 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 85452aa..7f06ae7 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -1630,6 +1630,25 @@ class Object : public Value {
- /** Sets a native pointer in an internal field. */
- V8EXPORT void SetPointerInInternalField(int index, void* value);
-
-+ class V8EXPORT ExternalResource { // NOLINT
-+ public:
-+ ExternalResource() {}
-+ virtual ~ExternalResource() {}
-+
-+ protected:
-+ virtual void Dispose() { delete this; }
-+
-+ private:
-+ // Disallow copying and assigning.
-+ ExternalResource(const ExternalResource&);
-+ void operator=(const ExternalResource&);
-+
-+ friend class v8::internal::Heap;
-+ };
-+
-+ V8EXPORT void SetExternalResource(ExternalResource *);
-+ V8EXPORT ExternalResource *GetExternalResource();
-+
- // Testers for local properties.
- V8EXPORT bool HasRealNamedProperty(Handle<String> key);
- V8EXPORT bool HasRealIndexedProperty(uint32_t index);
-@@ -2331,6 +2350,12 @@ class V8EXPORT ObjectTemplate : public Template {
- */
- void SetInternalFieldCount(int value);
-
-+ /**
-+ * Sets whether the object can store an "external resource" object.
-+ */
-+ bool HasExternalResource();
-+ void SetHasExternalResource(bool value);
-+
- private:
- ObjectTemplate();
- static Local<ObjectTemplate> New(Handle<FunctionTemplate> constructor);
-diff --git a/src/api.cc b/src/api.cc
-index 8b0b32a..1a6fbbb 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -1294,6 +1294,34 @@ void ObjectTemplate::SetInternalFieldCount(int value) {
- }
-
-
-+bool ObjectTemplate::HasExternalResource()
-+{
-+ if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
-+ "v8::ObjectTemplate::HasExternalResource()")) {
-+ return 0;
-+ }
-+ return !Utils::OpenHandle(this)->has_external_resource()->IsUndefined();
-+}
-+
-+
-+void ObjectTemplate::SetHasExternalResource(bool value)
-+{
-+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetHasExternalResource()")) {
-+ return;
-+ }
-+ ENTER_V8(isolate);
-+ if (value) {
-+ EnsureConstructor(this);
-+ }
-+ if (value) {
-+ Utils::OpenHandle(this)->set_has_external_resource(i::Smi::FromInt(1));
-+ } else {
-+ Utils::OpenHandle(this)->set_has_external_resource(Utils::OpenHandle(this)->GetHeap()->undefined_value());
-+ }
-+}
-+
-+
- // --- S c r i p t D a t a ---
-
-
-@@ -3652,6 +3680,34 @@ void v8::Object::SetPointerInInternalField(int index, void* value) {
- }
-
-
-+void v8::Object::SetExternalResource(v8::Object::ExternalResource *resource) {
-+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ ENTER_V8(isolate);
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ if (CanBeEncodedAsSmi(resource)) {
-+ obj->SetExternalResourceObject(EncodeAsSmi(resource));
-+ } else {
-+ obj->SetExternalResourceObject(*isolate->factory()->NewProxy(static_cast<i::Address>((void *)resource)));
-+ }
-+ if (!obj->IsSymbol()) {
-+ isolate->heap()->external_resource_table()->AddObject(*obj);
-+ }
-+}
-+
-+
-+v8::Object::ExternalResource *v8::Object::GetExternalResource() {
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ i::Object* value = obj->GetExternalResourceObject();
-+ if (value->IsSmi()) {
-+ return reinterpret_cast<v8::Object::ExternalResource*>(i::Internals::GetExternalPointerFromSmi(value));
-+ } else if (value->IsProxy()) {
-+ return reinterpret_cast<v8::Object::ExternalResource*>(i::Proxy::cast(value)->proxy());
-+ } else {
-+ return NULL;
-+ }
-+}
-+
-+
- // --- E n v i r o n m e n t ---
-
-
-@@ -4144,7 +4200,7 @@ Local<String> v8::String::NewExternal(
- LOG_API(isolate, "String::NewExternal");
- ENTER_V8(isolate);
- i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
-- isolate->heap()->external_string_table()->AddString(*result);
-+ isolate->heap()->external_resource_table()->AddString(*result);
- return Utils::ToLocal(result);
- }
-
-@@ -4162,7 +4218,7 @@ bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
- }
- bool result = obj->MakeExternal(resource);
- if (result && !obj->IsSymbol()) {
-- isolate->heap()->external_string_table()->AddString(*obj);
-+ isolate->heap()->external_resource_table()->AddString(*obj);
- }
- return result;
- }
-@@ -4175,7 +4231,7 @@ Local<String> v8::String::NewExternal(
- LOG_API(isolate, "String::NewExternal");
- ENTER_V8(isolate);
- i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
-- isolate->heap()->external_string_table()->AddString(*result);
-+ isolate->heap()->external_resource_table()->AddString(*result);
- return Utils::ToLocal(result);
- }
-
-@@ -4194,7 +4250,7 @@ bool v8::String::MakeExternal(
- }
- bool result = obj->MakeExternal(resource);
- if (result && !obj->IsSymbol()) {
-- isolate->heap()->external_string_table()->AddString(*obj);
-+ isolate->heap()->external_resource_table()->AddString(*obj);
- }
- return result;
- }
-diff --git a/src/extensions/externalize-string-extension.cc b/src/extensions/externalize-string-extension.cc
-index b3f83fe..8e50904 100644
---- a/src/extensions/externalize-string-extension.cc
-+++ b/src/extensions/externalize-string-extension.cc
-@@ -100,7 +100,7 @@ v8::Handle<v8::Value> ExternalizeStringExtension::Externalize(
- data, string->length());
- result = string->MakeExternal(resource);
- if (result && !string->IsSymbol()) {
-- HEAP->external_string_table()->AddString(*string);
-+ HEAP->external_resource_table()->AddString(*string);
- }
- if (!result) delete resource;
- } else {
-@@ -110,7 +110,7 @@ v8::Handle<v8::Value> ExternalizeStringExtension::Externalize(
- data, string->length());
- result = string->MakeExternal(resource);
- if (result && !string->IsSymbol()) {
-- HEAP->external_string_table()->AddString(*string);
-+ HEAP->external_resource_table()->AddString(*string);
- }
- if (!result) delete resource;
- }
-diff --git a/src/factory.cc b/src/factory.cc
-index dcdc645..d530a75 100644
---- a/src/factory.cc
-+++ b/src/factory.cc
-@@ -997,15 +997,21 @@ Handle<JSFunction> Factory::CreateApiFunction(
- Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi();
-
- int internal_field_count = 0;
-+ bool has_external_resource = false;
-+
- if (!obj->instance_template()->IsUndefined()) {
- Handle<ObjectTemplateInfo> instance_template =
- Handle<ObjectTemplateInfo>(
- ObjectTemplateInfo::cast(obj->instance_template()));
- internal_field_count =
- Smi::cast(instance_template->internal_field_count())->value();
-+ has_external_resource =
-+ !instance_template->has_external_resource()->IsUndefined();
- }
-
- int instance_size = kPointerSize * internal_field_count;
-+ if (has_external_resource) instance_size += kPointerSize;
-+
- InstanceType type = INVALID_TYPE;
- switch (instance_type) {
- case JavaScriptObject:
-@@ -1040,6 +1046,11 @@ Handle<JSFunction> Factory::CreateApiFunction(
-
- Handle<Map> map = Handle<Map>(result->initial_map());
-
-+ // Mark as having external data object if needed
-+ if (has_external_resource) {
-+ map->set_has_external_resource(true);
-+ }
-+
- // Mark as undetectable if needed.
- if (obj->undetectable()) {
- map->set_is_undetectable();
-diff --git a/src/heap-inl.h b/src/heap-inl.h
-index f4fce7b..58e7adf 100644
---- a/src/heap-inl.h
-+++ b/src/heap-inl.h
-@@ -205,21 +205,36 @@ MaybeObject* Heap::NumberFromUint32(uint32_t value) {
- }
-
-
--void Heap::FinalizeExternalString(String* string) {
-- ASSERT(string->IsExternalString());
-- v8::String::ExternalStringResourceBase** resource_addr =
-- reinterpret_cast<v8::String::ExternalStringResourceBase**>(
-- reinterpret_cast<byte*>(string) +
-- ExternalString::kResourceOffset -
-- kHeapObjectTag);
--
-- // Dispose of the C++ object if it has not already been disposed.
-- if (*resource_addr != NULL) {
-- (*resource_addr)->Dispose();
-- }
-+void Heap::FinalizeExternalString(HeapObject* string) {
-+ ASSERT(string->IsExternalString() || string->map()->has_external_resource());
-+
-+ if (string->IsExternalString()) {
-+ v8::String::ExternalStringResourceBase** resource_addr =
-+ reinterpret_cast<v8::String::ExternalStringResourceBase**>(
-+ reinterpret_cast<byte*>(string) +
-+ ExternalString::kResourceOffset -
-+ kHeapObjectTag);
-+
-+ // Dispose of the C++ object if it has not already been disposed.
-+ if (*resource_addr != NULL) {
-+ (*resource_addr)->Dispose();
-+ }
-
-- // Clear the resource pointer in the string.
-- *resource_addr = NULL;
-+ // Clear the resource pointer in the string.
-+ *resource_addr = NULL;
-+ } else {
-+ JSObject *object = JSObject::cast(string);
-+ Object *value = object->GetExternalResourceObject();
-+ v8::Object::ExternalResource *resource = 0;
-+ if (value->IsSmi()) {
-+ resource = reinterpret_cast<v8::Object::ExternalResource*>(Internals::GetExternalPointerFromSmi(value));
-+ } else if (value->IsProxy()) {
-+ resource = reinterpret_cast<v8::Object::ExternalResource*>(Proxy::cast(value)->proxy());
-+ }
-+ if (resource) {
-+ resource->Dispose();
-+ }
-+ }
- }
-
-
-@@ -556,53 +571,63 @@ inline bool Heap::allow_allocation(bool new_state) {
- #endif
-
-
--void ExternalStringTable::AddString(String* string) {
-- ASSERT(string->IsExternalString());
-+void ExternalResourceTable::AddString(String* string) {
-+ ASSERT(string->IsExternalString() );
- if (heap_->InNewSpace(string)) {
-- new_space_strings_.Add(string);
-+ new_space_objects_.Add(string);
-+ } else {
-+ old_space_objects_.Add(string);
-+ }
-+}
-+
-+
-+void ExternalResourceTable::AddObject(HeapObject* object) {
-+ ASSERT(object->map()->has_external_resource());
-+ if (heap_->InNewSpace(object)) {
-+ new_space_objects_.Add(object);
- } else {
-- old_space_strings_.Add(string);
-+ old_space_objects_.Add(object);
- }
- }
-
-
--void ExternalStringTable::Iterate(ObjectVisitor* v) {
-- if (!new_space_strings_.is_empty()) {
-- Object** start = &new_space_strings_[0];
-- v->VisitPointers(start, start + new_space_strings_.length());
-+void ExternalResourceTable::Iterate(ObjectVisitor* v) {
-+ if (!new_space_objects_.is_empty()) {
-+ Object** start = &new_space_objects_[0];
-+ v->VisitPointers(start, start + new_space_objects_.length());
- }
-- if (!old_space_strings_.is_empty()) {
-- Object** start = &old_space_strings_[0];
-- v->VisitPointers(start, start + old_space_strings_.length());
-+ if (!old_space_objects_.is_empty()) {
-+ Object** start = &old_space_objects_[0];
-+ v->VisitPointers(start, start + old_space_objects_.length());
- }
- }
-
-
- // Verify() is inline to avoid ifdef-s around its calls in release
- // mode.
--void ExternalStringTable::Verify() {
-+void ExternalResourceTable::Verify() {
- #ifdef DEBUG
-- for (int i = 0; i < new_space_strings_.length(); ++i) {
-- ASSERT(heap_->InNewSpace(new_space_strings_[i]));
-- ASSERT(new_space_strings_[i] != HEAP->raw_unchecked_null_value());
-+ for (int i = 0; i < new_space_objects_.length(); ++i) {
-+ ASSERT(heap_->InNewSpace(new_space_objects_[i]));
-+ ASSERT(new_space_objects_[i] != HEAP->raw_unchecked_null_value());
- }
-- for (int i = 0; i < old_space_strings_.length(); ++i) {
-- ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
-- ASSERT(old_space_strings_[i] != HEAP->raw_unchecked_null_value());
-+ for (int i = 0; i < old_space_objects_.length(); ++i) {
-+ ASSERT(!heap_->InNewSpace(old_space_objects_[i]));
-+ ASSERT(old_space_objects_[i] != HEAP->raw_unchecked_null_value());
- }
- #endif
- }
-
-
--void ExternalStringTable::AddOldString(String* string) {
-- ASSERT(string->IsExternalString());
-- ASSERT(!heap_->InNewSpace(string));
-- old_space_strings_.Add(string);
-+void ExternalResourceTable::AddOldObject(HeapObject* object) {
-+ ASSERT(object->IsExternalString() || object->map()->has_external_resource());
-+ ASSERT(!heap_->InNewSpace(object));
-+ old_space_objects_.Add(object);
- }
-
-
--void ExternalStringTable::ShrinkNewStrings(int position) {
-- new_space_strings_.Rewind(position);
-+void ExternalResourceTable::ShrinkNewObjects(int position) {
-+ new_space_objects_.Rewind(position);
- Verify();
- }
-
-diff --git a/src/heap.cc b/src/heap.cc
-index 900f462..bf2940e 100644
---- a/src/heap.cc
-+++ b/src/heap.cc
-@@ -155,7 +155,7 @@ Heap::Heap()
- memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
- global_contexts_list_ = NULL;
- mark_compact_collector_.heap_ = this;
-- external_string_table_.heap_ = this;
-+ external_resource_table_.heap_ = this;
- }
-
-
-@@ -1030,8 +1030,8 @@ void Heap::Scavenge() {
-
- new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
-
-- UpdateNewSpaceReferencesInExternalStringTable(
-- &UpdateNewSpaceReferenceInExternalStringTableEntry);
-+ UpdateNewSpaceReferencesInExternalResourceTable(
-+ &UpdateNewSpaceReferenceInExternalResourceTableEntry);
-
- LiveObjectList::UpdateReferencesForScavengeGC();
- isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
-@@ -1053,38 +1053,38 @@ void Heap::Scavenge() {
- }
-
-
--String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
-- Object** p) {
-+HeapObject* Heap::UpdateNewSpaceReferenceInExternalResourceTableEntry(Heap* heap,
-+ Object** p) {
- MapWord first_word = HeapObject::cast(*p)->map_word();
-
- if (!first_word.IsForwardingAddress()) {
- // Unreachable external string can be finalized.
-- heap->FinalizeExternalString(String::cast(*p));
-+ heap->FinalizeExternalString(HeapObject::cast(*p));
- return NULL;
- }
-
- // String is still reachable.
-- return String::cast(first_word.ToForwardingAddress());
-+ return HeapObject::cast(first_word.ToForwardingAddress());
- }
-
-
--void Heap::UpdateNewSpaceReferencesInExternalStringTable(
-- ExternalStringTableUpdaterCallback updater_func) {
-- external_string_table_.Verify();
-+void Heap::UpdateNewSpaceReferencesInExternalResourceTable(
-+ ExternalResourceTableUpdaterCallback updater_func) {
-+ external_resource_table_.Verify();
-
-- if (external_string_table_.new_space_strings_.is_empty()) return;
-+ if (external_resource_table_.new_space_objects_.is_empty()) return;
-
-- Object** start = &external_string_table_.new_space_strings_[0];
-- Object** end = start + external_string_table_.new_space_strings_.length();
-+ Object** start = &external_resource_table_.new_space_objects_[0];
-+ Object** end = start + external_resource_table_.new_space_objects_.length();
- Object** last = start;
-
- for (Object** p = start; p < end; ++p) {
- ASSERT(InFromSpace(*p));
-- String* target = updater_func(this, p);
-+ HeapObject* target = updater_func(this, p);
-
- if (target == NULL) continue;
-
-- ASSERT(target->IsExternalString());
-+ ASSERT(target->IsExternalString() || target->map()->has_external_resource());
-
- if (InNewSpace(target)) {
- // String is still in new space. Update the table entry.
-@@ -1092,12 +1092,12 @@ void Heap::UpdateNewSpaceReferencesInExternalStringTable(
- ++last;
- } else {
- // String got promoted. Move it to the old string list.
-- external_string_table_.AddOldString(target);
-+ external_resource_table_.AddOldObject(target);
- }
- }
-
- ASSERT(last <= end);
-- external_string_table_.ShrinkNewStrings(static_cast<int>(last - start));
-+ external_resource_table_.ShrinkNewObjects(static_cast<int>(last - start));
- }
-
-
-@@ -4468,7 +4468,7 @@ void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) {
- v->Synchronize("symbol_table");
- if (mode != VISIT_ALL_IN_SCAVENGE) {
- // Scavenge collections have special processing for this.
-- external_string_table_.Iterate(v);
-+ external_resource_table_.Iterate(v);
- }
- v->Synchronize("external_string_table");
- }
-@@ -4970,7 +4970,7 @@ void Heap::TearDown() {
-
- isolate_->global_handles()->TearDown();
-
-- external_string_table_.TearDown();
-+ external_resource_table_.TearDown();
-
- new_space_.TearDown();
-
-@@ -5835,31 +5835,31 @@ void TranscendentalCache::Clear() {
- }
-
-
--void ExternalStringTable::CleanUp() {
-+void ExternalResourceTable::CleanUp() {
- int last = 0;
-- for (int i = 0; i < new_space_strings_.length(); ++i) {
-- if (new_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
-- if (heap_->InNewSpace(new_space_strings_[i])) {
-- new_space_strings_[last++] = new_space_strings_[i];
-+ for (int i = 0; i < new_space_objects_.length(); ++i) {
-+ if (new_space_objects_[i] == heap_->raw_unchecked_null_value()) continue;
-+ if (heap_->InNewSpace(new_space_objects_[i])) {
-+ new_space_objects_[last++] = new_space_objects_[i];
- } else {
-- old_space_strings_.Add(new_space_strings_[i]);
-+ old_space_objects_.Add(new_space_objects_[i]);
- }
- }
-- new_space_strings_.Rewind(last);
-+ new_space_objects_.Rewind(last);
- last = 0;
-- for (int i = 0; i < old_space_strings_.length(); ++i) {
-- if (old_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
-- ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
-- old_space_strings_[last++] = old_space_strings_[i];
-+ for (int i = 0; i < old_space_objects_.length(); ++i) {
-+ if (old_space_objects_[i] == heap_->raw_unchecked_null_value()) continue;
-+ ASSERT(!heap_->InNewSpace(old_space_objects_[i]));
-+ old_space_objects_[last++] = old_space_objects_[i];
- }
-- old_space_strings_.Rewind(last);
-+ old_space_objects_.Rewind(last);
- Verify();
- }
-
-
--void ExternalStringTable::TearDown() {
-- new_space_strings_.Free();
-- old_space_strings_.Free();
-+void ExternalResourceTable::TearDown() {
-+ new_space_objects_.Free();
-+ old_space_objects_.Free();
- }
-
-
-diff --git a/src/heap.h b/src/heap.h
-index ae4e9e7..8cbf378 100644
---- a/src/heap.h
-+++ b/src/heap.h
-@@ -237,8 +237,8 @@ class Isolate;
- class WeakObjectRetainer;
-
-
--typedef String* (*ExternalStringTableUpdaterCallback)(Heap* heap,
-- Object** pointer);
-+typedef HeapObject* (*ExternalResourceTableUpdaterCallback)(Heap* heap,
-+ Object** pointer);
-
- typedef bool (*DirtyRegionCallback)(Heap* heap,
- Address start,
-@@ -284,43 +284,45 @@ class PromotionQueue {
- };
-
-
--// External strings table is a place where all external strings are
--// registered. We need to keep track of such strings to properly
--// finalize them.
--class ExternalStringTable {
-+// External resource table is a place where all external strings and
-+// objects with an external resource are registered. We need to keep
-+// track of such strings to properly finalize them.
-+class ExternalResourceTable {
- public:
- // Registers an external string.
- inline void AddString(String* string);
-+ // Registers an external object.
-+ inline void AddObject(HeapObject* object);
-
- inline void Iterate(ObjectVisitor* v);
-
- // Restores internal invariant and gets rid of collected strings.
-- // Must be called after each Iterate() that modified the strings.
-+ // Must be called after each Iterate() that modified the objects.
- void CleanUp();
-
- // Destroys all allocated memory.
- void TearDown();
-
- private:
-- ExternalStringTable() { }
-+ ExternalResourceTable() { }
-
- friend class Heap;
-
- inline void Verify();
-
-- inline void AddOldString(String* string);
-+ inline void AddOldObject(HeapObject* object);
-
- // Notifies the table that only a prefix of the new list is valid.
-- inline void ShrinkNewStrings(int position);
-+ inline void ShrinkNewObjects(int position);
-
- // To speed up scavenge collections new space string are kept
- // separate from old space strings.
-- List<Object*> new_space_strings_;
-- List<Object*> old_space_strings_;
-+ List<Object*> new_space_objects_;
-+ List<Object*> old_space_objects_;
-
- Heap* heap_;
-
-- DISALLOW_COPY_AND_ASSIGN(ExternalStringTable);
-+ DISALLOW_COPY_AND_ASSIGN(ExternalResourceTable);
- };
-
-
-@@ -753,7 +755,7 @@ class Heap {
-
- // Finalizes an external string by deleting the associated external
- // data and clearing the resource pointer.
-- inline void FinalizeExternalString(String* string);
-+ inline void FinalizeExternalString(HeapObject* string);
-
- // Allocates an uninitialized object. The memory is non-executable if the
- // hardware and OS allow.
-@@ -1191,8 +1193,8 @@ class Heap {
- survived_since_last_expansion_ += survived;
- }
-
-- void UpdateNewSpaceReferencesInExternalStringTable(
-- ExternalStringTableUpdaterCallback updater_func);
-+ void UpdateNewSpaceReferencesInExternalResourceTable(
-+ ExternalResourceTableUpdaterCallback updater_func);
-
- void ProcessWeakReferences(WeakObjectRetainer* retainer);
-
-@@ -1228,8 +1230,8 @@ class Heap {
- return &mark_compact_collector_;
- }
-
-- ExternalStringTable* external_string_table() {
-- return &external_string_table_;
-+ ExternalResourceTable* external_resource_table() {
-+ return &external_resource_table_;
- }
-
- inline Isolate* isolate();
-@@ -1462,7 +1464,7 @@ class Heap {
- // Performs a minor collection in new generation.
- void Scavenge();
-
-- static String* UpdateNewSpaceReferenceInExternalStringTableEntry(
-+ static HeapObject* UpdateNewSpaceReferenceInExternalResourceTableEntry(
- Heap* heap,
- Object** pointer);
-
-@@ -1593,7 +1595,7 @@ class Heap {
- // configured through the API until it is setup.
- bool configured_;
-
-- ExternalStringTable external_string_table_;
-+ ExternalResourceTable external_resource_table_;
-
- bool is_safe_to_read_maps_;
-
-diff --git a/src/liveobjectlist.cc b/src/liveobjectlist.cc
-index 5795a6b..8866e58 100644
---- a/src/liveobjectlist.cc
-+++ b/src/liveobjectlist.cc
-@@ -1989,7 +1989,7 @@ Object* LiveObjectList::PrintObj(int obj_id) {
- ASSERT(resource->IsAscii());
- Handle<String> dump_string =
- Factory::NewExternalStringFromAscii(resource);
-- ExternalStringTable::AddString(*dump_string);
-+ ExternalResourceTable::AddString(*dump_string);
- return *dump_string;
- } else {
- delete resource;
-@@ -2193,7 +2193,7 @@ Object* LiveObjectList::GetPathPrivate(HeapObject* obj1, HeapObject* obj2) {
- ASSERT(resource->IsAscii());
- Handle<String> path_string =
- Factory::NewExternalStringFromAscii(resource);
-- ExternalStringTable::AddString(*path_string);
-+ ExternalResourceTable::AddString(*path_string);
- return *path_string;
- } else {
- delete resource;
-diff --git a/src/mark-compact.cc b/src/mark-compact.cc
-index 68a5062..1b1e361 100644
---- a/src/mark-compact.cc
-+++ b/src/mark-compact.cc
-@@ -163,7 +163,7 @@ void MarkCompactCollector::Finish() {
- // objects (empty string, illegal builtin).
- heap()->isolate()->stub_cache()->Clear();
-
-- heap()->external_string_table_.CleanUp();
-+ heap()->external_resource_table_.CleanUp();
-
- // If we've just compacted old space there's no reason to check the
- // fragmentation limit. Just return.
-@@ -1019,8 +1019,9 @@ class SymbolTableCleaner : public ObjectVisitor {
-
- // Since no objects have yet been moved we can safely access the map of
- // the object.
-- if ((*p)->IsExternalString()) {
-- heap_->FinalizeExternalString(String::cast(*p));
-+ if ((*p)->IsExternalString() ||
-+ (*p)->IsHeapObject() && HeapObject::cast(*p)->map()->has_external_resource()) {
-+ heap_->FinalizeExternalString(HeapObject::cast(*p));
- }
- // Set the entry to null_value (as deleted).
- *p = heap_->raw_unchecked_null_value();
-@@ -1433,8 +1434,8 @@ void MarkCompactCollector::MarkLiveObjects() {
- SymbolTableCleaner v(heap());
- symbol_table->IterateElements(&v);
- symbol_table->ElementsRemoved(v.PointersRemoved());
-- heap()->external_string_table_.Iterate(&v);
-- heap()->external_string_table_.CleanUp();
-+ heap()->external_resource_table_.Iterate(&v);
-+ heap()->external_resource_table_.CleanUp();
-
- // Process the weak references.
- MarkCompactWeakObjectRetainer mark_compact_object_retainer;
-@@ -1948,11 +1949,11 @@ static void UpdatePointerToNewGen(HeapObject** p) {
- }
-
-
--static String* UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
-- Object** p) {
-+static HeapObject* UpdateNewSpaceReferenceInExternalResourceTableEntry(Heap* heap,
-+ Object** p) {
- Address old_addr = HeapObject::cast(*p)->address();
- Address new_addr = Memory::Address_at(old_addr);
-- return String::cast(HeapObject::FromAddress(new_addr));
-+ return HeapObject::FromAddress(new_addr);
- }
-
-
-@@ -2083,8 +2084,8 @@ static void SweepNewSpace(Heap* heap, NewSpace* space) {
- updating_visitor.VisitPointer(heap->global_contexts_list_address());
-
- // Update pointers from external string table.
-- heap->UpdateNewSpaceReferencesInExternalStringTable(
-- &UpdateNewSpaceReferenceInExternalStringTableEntry);
-+ heap->UpdateNewSpaceReferencesInExternalResourceTable(
-+ &UpdateNewSpaceReferenceInExternalResourceTableEntry);
-
- // All pointers were updated. Update auxiliary allocation info.
- heap->IncrementYoungSurvivorsCounter(survivors_size);
-diff --git a/src/objects-inl.h b/src/objects-inl.h
-index 6aaca2f..231b835 100644
---- a/src/objects-inl.h
-+++ b/src/objects-inl.h
-@@ -1392,13 +1392,13 @@ int JSObject::GetInternalFieldCount() {
- // Make sure to adjust for the number of in-object properties. These
- // properties do contribute to the size, but are not internal fields.
- return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
-- map()->inobject_properties();
-+ map()->inobject_properties() - map()->has_external_resource()?1:0;
- }
-
-
- int JSObject::GetInternalFieldOffset(int index) {
- ASSERT(index < GetInternalFieldCount() && index >= 0);
-- return GetHeaderSize() + (kPointerSize * index);
-+ return GetHeaderSize() + (kPointerSize * (index + map()->has_external_resource()?1:0));
- }
-
-
-@@ -1407,7 +1407,7 @@ Object* JSObject::GetInternalField(int index) {
- // Internal objects do follow immediately after the header, whereas in-object
- // properties are at the end of the object. Therefore there is no need
- // to adjust the index here.
-- return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
-+ return READ_FIELD(this, GetHeaderSize() + (kPointerSize * (index + map()->has_external_resource()?1:0)));
- }
-
-
-@@ -1416,12 +1416,29 @@ void JSObject::SetInternalField(int index, Object* value) {
- // Internal objects do follow immediately after the header, whereas in-object
- // properties are at the end of the object. Therefore there is no need
- // to adjust the index here.
-- int offset = GetHeaderSize() + (kPointerSize * index);
-+ int offset = GetHeaderSize() + (kPointerSize * (index + map()->has_external_resource()?1:0));
- WRITE_FIELD(this, offset, value);
- WRITE_BARRIER(this, offset);
- }
-
-
-+void JSObject::SetExternalResourceObject(Object *value) {
-+ ASSERT(map()->has_external_resource());
-+ int offset = GetHeaderSize();
-+ WRITE_FIELD(this, offset, value);
-+ WRITE_BARRIER(this, offset);
-+}
-+
-+
-+Object *JSObject::GetExternalResourceObject() {
-+ if (map()->has_external_resource()) {
-+ return READ_FIELD(this, GetHeaderSize());
-+ } else {
-+ return GetHeap()->undefined_value();
-+ }
-+}
-+
-+
- // Access fast-case object properties at index. The use of these routines
- // is needed to correctly distinguish between properties stored in-object and
- // properties stored in the properties array.
-@@ -2521,6 +2538,20 @@ bool Map::is_shared() {
- }
-
-
-+void Map::set_has_external_resource(bool value) {
-+ if (value) {
-+ set_bit_field3(bit_field3() | (1 << kHasExternalResource));
-+ } else {
-+ set_bit_field3(bit_field3() & ~(1 << kHasExternalResource));
-+ }
-+}
-+
-+bool Map::has_external_resource()
-+{
-+ return ((1 << kHasExternalResource) & bit_field3()) != 0;
-+}
-+
-+
- void Map::set_named_interceptor_is_fallback(bool value)
- {
- if (value) {
-@@ -3017,6 +3048,8 @@ ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
- ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
- ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
- kInternalFieldCountOffset)
-+ACCESSORS(ObjectTemplateInfo, has_external_resource, Object,
-+ kHasExternalResourceOffset)
-
- ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
- ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
-diff --git a/src/objects.h b/src/objects.h
-index a209cd0..1bdb5c7 100644
---- a/src/objects.h
-+++ b/src/objects.h
-@@ -1636,6 +1636,9 @@ class JSObject: public HeapObject {
- inline Object* GetInternalField(int index);
- inline void SetInternalField(int index, Object* value);
-
-+ inline void SetExternalResourceObject(Object *);
-+ inline Object *GetExternalResourceObject();
-+
- // Lookup a property. If found, the result is valid and has
- // detailed information.
- void LocalLookup(String* name, LookupResult* result, bool skip_fallback_interceptor = false);
-@@ -3715,6 +3718,12 @@ class Map: public HeapObject {
- inline void set_is_access_check_needed(bool access_check_needed);
- inline bool is_access_check_needed();
-
-+
-+ // Tells whether the instance has the space for an external resource
-+ // object
-+ inline void set_has_external_resource(bool value);
-+ inline bool has_external_resource();
-+
-
- // Whether the named interceptor is a fallback interceptor or not
- inline void set_named_interceptor_is_fallback(bool value);
-@@ -3912,6 +3921,7 @@ class Map: public HeapObject {
-
- // Bit positions for bit field 3
- static const int kNamedInterceptorIsFallback = 0;
-+ static const int kHasExternalResource = 1;
-
- // Layout of the default cache. It holds alternating name and code objects.
- static const int kCodeCacheEntrySize = 2;
-@@ -6426,6 +6436,7 @@ class ObjectTemplateInfo: public TemplateInfo {
- public:
- DECL_ACCESSORS(constructor, Object)
- DECL_ACCESSORS(internal_field_count, Object)
-+ DECL_ACCESSORS(has_external_resource, Object)
-
- static inline ObjectTemplateInfo* cast(Object* obj);
-
-@@ -6442,7 +6453,8 @@ class ObjectTemplateInfo: public TemplateInfo {
- static const int kConstructorOffset = TemplateInfo::kHeaderSize;
- static const int kInternalFieldCountOffset =
- kConstructorOffset + kPointerSize;
-- static const int kSize = kInternalFieldCountOffset + kPointerSize;
-+ static const int kHasExternalResourceOffset = kInternalFieldCountOffset + kPointerSize;
-+ static const int kSize = kHasExternalResourceOffset + kPointerSize;
- };
-
-
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0005-Introduce-a-QML-compilation-mode.patch b/src/declarative/v8/0005-Introduce-a-QML-compilation-mode.patch
deleted file mode 100644
index 2dfd3d9699..0000000000
--- a/src/declarative/v8/0005-Introduce-a-QML-compilation-mode.patch
+++ /dev/null
@@ -1,1777 +0,0 @@
-From fd7d475e298e5b63cd6383c78cc900635c82aa38 Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Mon, 23 May 2011 18:26:19 +1000
-Subject: [PATCH 05/13] Introduce a QML compilation mode
-
-In QML mode, there is a second global object - known as the QML
-global object. During property resolution, if a property is not
-present on the JS global object, it is resolve on the QML global
-object.
-
-This global object behavior is only enabled if a script is being
-compiled in QML mode. The object to use as the QML global object
-is passed as a parameter to the Script::Run() method. Any function
-closures etc. created during the run will retain a reference to this
-object, so different objects can be passed in different script
-runs.
----
- include/v8.h | 18 ++++++++--
- src/api.cc | 52 ++++++++++++++++++++++++-----
- src/arm/code-stubs-arm.cc | 4 ++
- src/arm/full-codegen-arm.cc | 26 ++++++++------
- src/arm/lithium-arm.cc | 2 +-
- src/arm/lithium-arm.h | 6 +++-
- src/arm/lithium-codegen-arm.cc | 7 ++--
- src/arm/macro-assembler-arm.h | 5 +++
- src/ast-inl.h | 5 +++
- src/ast.h | 1 +
- src/code-stubs.h | 2 +-
- src/compiler.cc | 15 +++++++-
- src/compiler.h | 22 ++++++++++--
- src/contexts.cc | 23 +++++++++++++
- src/contexts.h | 4 ++
- src/execution.cc | 28 +++++++++++++--
- src/execution.h | 6 +++
- src/full-codegen.cc | 3 +-
- src/full-codegen.h | 1 +
- src/heap.cc | 2 +
- src/hydrogen-instructions.h | 10 ++++-
- src/hydrogen.cc | 2 +
- src/ia32/code-stubs-ia32.cc | 7 ++++
- src/ia32/full-codegen-ia32.cc | 26 ++++++++------
- src/ia32/lithium-codegen-ia32.cc | 7 ++--
- src/ia32/lithium-ia32.cc | 2 +-
- src/ia32/lithium-ia32.h | 6 +++-
- src/ia32/macro-assembler-ia32.h | 5 +++
- src/objects-inl.h | 12 +++++++
- src/objects.h | 5 +++
- src/parser.cc | 27 +++++++++++++--
- src/parser.h | 4 ++-
- src/prettyprinter.cc | 3 ++
- src/runtime.cc | 68 ++++++++++++++++++++++++-------------
- src/runtime.h | 8 ++--
- src/scopes.cc | 10 +++++
- src/scopes.h | 7 ++++
- src/variables.cc | 3 +-
- src/variables.h | 5 +++
- src/x64/code-stubs-x64.cc | 4 ++
- src/x64/full-codegen-x64.cc | 26 ++++++++------
- src/x64/lithium-codegen-x64.cc | 7 ++--
- src/x64/lithium-x64.cc | 2 +-
- src/x64/lithium-x64.h | 6 +++
- src/x64/macro-assembler-x64.h | 5 +++
- 45 files changed, 391 insertions(+), 108 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 7f06ae7..a858eae 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -577,6 +577,10 @@ class ScriptOrigin {
- */
- class V8EXPORT Script {
- public:
-+ enum CompileFlags {
-+ Default = 0x00,
-+ QmlMode = 0x01
-+ };
-
- /**
- * Compiles the specified script (context-independent).
-@@ -596,7 +600,8 @@ class V8EXPORT Script {
- static Local<Script> New(Handle<String> source,
- ScriptOrigin* origin = NULL,
- ScriptData* pre_data = NULL,
-- Handle<String> script_data = Handle<String>());
-+ Handle<String> script_data = Handle<String>(),
-+ CompileFlags = Default);
-
- /**
- * Compiles the specified script using the specified file name
-@@ -609,7 +614,8 @@ class V8EXPORT Script {
- * will use the currently entered context).
- */
- static Local<Script> New(Handle<String> source,
-- Handle<Value> file_name);
-+ Handle<Value> file_name,
-+ CompileFlags = Default);
-
- /**
- * Compiles the specified script (bound to current context).
-@@ -630,7 +636,8 @@ class V8EXPORT Script {
- static Local<Script> Compile(Handle<String> source,
- ScriptOrigin* origin = NULL,
- ScriptData* pre_data = NULL,
-- Handle<String> script_data = Handle<String>());
-+ Handle<String> script_data = Handle<String>(),
-+ CompileFlags = Default);
-
- /**
- * Compiles the specified script using the specified file name
-@@ -647,7 +654,8 @@ class V8EXPORT Script {
- */
- static Local<Script> Compile(Handle<String> source,
- Handle<Value> file_name,
-- Handle<String> script_data = Handle<String>());
-+ Handle<String> script_data = Handle<String>(),
-+ CompileFlags = Default);
-
- /**
- * Runs the script returning the resulting value. If the script is
-@@ -657,6 +665,7 @@ class V8EXPORT Script {
- * compiled.
- */
- Local<Value> Run();
-+ Local<Value> Run(Handle<Object> qml);
-
- /**
- * Returns the script id value.
-@@ -3326,6 +3335,7 @@ class V8EXPORT Context {
- * JavaScript frames an empty handle is returned.
- */
- static Local<Context> GetCalling();
-+ static Local<Object> GetCallingQmlGlobal();
-
- /**
- * Sets the security token for the context. To access an object in
-diff --git a/src/api.cc b/src/api.cc
-index 1a6fbbb..39767f4 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -1372,7 +1372,8 @@ ScriptData* ScriptData::New(const char* data, int length) {
- Local<Script> Script::New(v8::Handle<String> source,
- v8::ScriptOrigin* origin,
- v8::ScriptData* pre_data,
-- v8::Handle<String> script_data) {
-+ v8::Handle<String> script_data,
-+ v8::Script::CompileFlags compile_flags) {
- i::Isolate* isolate = i::Isolate::Current();
- ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
- LOG_API(isolate, "Script::New");
-@@ -1409,7 +1410,8 @@ Local<Script> Script::New(v8::Handle<String> source,
- NULL,
- pre_data_impl,
- Utils::OpenHandle(*script_data),
-- i::NOT_NATIVES_CODE);
-+ i::NOT_NATIVES_CODE,
-+ compile_flags);
- has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
- return Local<Script>(ToApi<Script>(result));
-@@ -1417,21 +1419,23 @@ Local<Script> Script::New(v8::Handle<String> source,
-
-
- Local<Script> Script::New(v8::Handle<String> source,
-- v8::Handle<Value> file_name) {
-+ v8::Handle<Value> file_name,
-+ v8::Script::CompileFlags compile_flags) {
- ScriptOrigin origin(file_name);
-- return New(source, &origin);
-+ return New(source, &origin, 0, Handle<String>(), compile_flags);
- }
-
-
- Local<Script> Script::Compile(v8::Handle<String> source,
- v8::ScriptOrigin* origin,
- v8::ScriptData* pre_data,
-- v8::Handle<String> script_data) {
-+ v8::Handle<String> script_data,
-+ v8::Script::CompileFlags compile_flags) {
- i::Isolate* isolate = i::Isolate::Current();
- ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
- LOG_API(isolate, "Script::Compile");
- ENTER_V8(isolate);
-- Local<Script> generic = New(source, origin, pre_data, script_data);
-+ Local<Script> generic = New(source, origin, pre_data, script_data, compile_flags);
- if (generic.IsEmpty())
- return generic;
- i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
-@@ -1447,13 +1451,18 @@ Local<Script> Script::Compile(v8::Handle<String> source,
-
- Local<Script> Script::Compile(v8::Handle<String> source,
- v8::Handle<Value> file_name,
-- v8::Handle<String> script_data) {
-+ v8::Handle<String> script_data,
-+ v8::Script::CompileFlags compile_flags) {
- ScriptOrigin origin(file_name);
-- return Compile(source, &origin, 0, script_data);
-+ return Compile(source, &origin, 0, script_data, compile_flags);
- }
-
-
- Local<Value> Script::Run() {
-+ return Run(Handle<Object>());
-+}
-+
-+Local<Value> Script::Run(Handle<Object> qml) {
- i::Isolate* isolate = i::Isolate::Current();
- ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
- LOG_API(isolate, "Script::Run");
-@@ -1472,10 +1481,11 @@ Local<Value> Script::Run() {
- fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
- }
- EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> qmlglobal = Utils::OpenHandle(*qml);
- i::Handle<i::Object> receiver(
- isolate->context()->global_proxy(), isolate);
- i::Handle<i::Object> result =
-- i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
-+ i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception, qmlglobal);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
- raw_result = *result;
- }
-@@ -3943,6 +3953,30 @@ v8::Local<v8::Context> Context::GetCalling() {
- }
-
-
-+v8::Local<v8::Object> Context::GetCallingQmlGlobal() {
-+ i::Isolate* isolate = i::Isolate::Current();
-+ if (IsDeadCheck(isolate, "v8::Context::GetCallingQmlGlobal()")) {
-+ return Local<Object>();
-+ }
-+
-+ i::Context *context = isolate->context();
-+ if (!context->qml_global()->IsUndefined()) {
-+ i::Handle<i::Object> qmlglobal(context->qml_global());
-+ return Utils::ToLocal(i::Handle<i::JSObject>::cast(qmlglobal));
-+ }
-+
-+ i::JavaScriptFrameIterator it;
-+ if (it.done()) return Local<Object>();
-+ context = i::Context::cast(it.frame()->context());
-+ if (!context->qml_global()->IsUndefined()) {
-+ i::Handle<i::Object> qmlglobal(context->qml_global());
-+ return Utils::ToLocal(i::Handle<i::JSObject>::cast(qmlglobal));
-+ } else {
-+ return Local<Object>();
-+ }
-+}
-+
-+
- v8::Local<v8::Object> Context::Global() {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
- return Local<v8::Object>();
-diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
-index 8c147f9..a2626bf 100644
---- a/src/arm/code-stubs-arm.cc
-+++ b/src/arm/code-stubs-arm.cc
-@@ -166,6 +166,10 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
- __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ str(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX)));
-
-+ // Copy the qml global object from the surrounding context.
-+ __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
-+ __ str(r1, MemOperand(r0, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
-+
- // Initialize the rest of the slots to undefined.
- __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
- for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
-diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
-index 871b453..a69f10d 100644
---- a/src/arm/full-codegen-arm.cc
-+++ b/src/arm/full-codegen-arm.cc
-@@ -154,12 +154,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
-
- // Possibly allocate a local context.
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
-- if (heap_slots > 0) {
-+ if (heap_slots > 0 ||
-+ (scope()->is_qml_mode() && scope()->is_global_scope())) {
- Comment cmnt(masm_, "[ Allocate local context");
- // Argument to NewContext is the function, which is in r1.
- __ push(r1);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
-- FastNewContextStub stub(heap_slots);
-+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
- __ CallStub(&stub);
- } else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -1247,9 +1248,9 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
- __ bind(&fast);
- }
-
-- __ ldr(r0, GlobalObjectOperand());
-+ __ ldr(r0, slot->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- __ mov(r2, Operand(slot->var()->name()));
-- RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
-+ RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF || slot->var()->is_qml_global())
- ? RelocInfo::CODE_TARGET
- : RelocInfo::CODE_TARGET_CONTEXT;
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-@@ -1268,10 +1269,10 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
- Comment cmnt(masm_, "Global variable");
- // Use inline caching. Variable name is passed in r2 and the global
- // object (receiver) in r0.
-- __ ldr(r0, GlobalObjectOperand());
-+ __ ldr(r0, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- __ mov(r2, Operand(var->name()));
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
-+ EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
- context()->Plug(r0);
-
- } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
-@@ -1893,11 +1894,11 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
- // assignment. Right-hand-side value is passed in r0, variable name in
- // r2, and the global object in r1.
- __ mov(r2, Operand(var->name()));
-- __ ldr(r1, GlobalObjectOperand());
-+ __ ldr(r1, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- Handle<Code> ic = is_strict_mode()
- ? isolate()->builtins()->StoreIC_Initialize_Strict()
- : isolate()->builtins()->StoreIC_Initialize();
-- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
-+ EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
-
- } else if (op == Token::INIT_CONST) {
- // Like var declarations, const declarations are hoisted to function
-@@ -2184,10 +2185,13 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
- // Push the strict mode flag.
- __ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
- __ push(r1);
-+ // Push the qml mode flag.
-+ __ mov(r1, Operand(Smi::FromInt(is_qml_mode())));
-+ __ push(r1);
-
- __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
- ? Runtime::kResolvePossiblyDirectEvalNoLookup
-- : Runtime::kResolvePossiblyDirectEval, 4);
-+ : Runtime::kResolvePossiblyDirectEval, 5);
- }
-
-
-@@ -2263,9 +2267,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
- context()->DropAndPlug(1, r0);
- } else if (var != NULL && !var->is_this() && var->is_global()) {
- // Push global object as receiver for the call IC.
-- __ ldr(r0, GlobalObjectOperand());
-+ __ ldr(r0, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- __ push(r0);
-- EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
-+ EmitCallWithIC(expr, var->name(), var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
- } else if (var != NULL && var->AsSlot() != NULL &&
- var->AsSlot()->type() == Slot::LOOKUP) {
- // Call to a lookup slot (dynamically introduced variable).
-diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
-index 3f1d15b..8406a96 100644
---- a/src/arm/lithium-arm.cc
-+++ b/src/arm/lithium-arm.cc
-@@ -1195,7 +1195,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
-
- LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
- LOperand* context = UseRegisterAtStart(instr->value());
-- return DefineAsRegister(new LGlobalObject(context));
-+ return DefineAsRegister(new LGlobalObject(context, instr->qml_global()));
- }
-
-
-diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
-index 6da7c86..10b901f 100644
---- a/src/arm/lithium-arm.h
-+++ b/src/arm/lithium-arm.h
-@@ -1378,13 +1378,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
-
- class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
- public:
-- explicit LGlobalObject(LOperand* context) {
-+ explicit LGlobalObject(LOperand* context, bool qml_global) {
- inputs_[0] = context;
-+ qml_global_ = qml_global;
- }
-
- DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
-
- LOperand* context() { return InputAt(0); }
-+ bool qml_global() { return qml_global_; }
-+ private:
-+ bool qml_global_;
- };
-
-
-diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
-index 4912449..db114ea 100644
---- a/src/arm/lithium-codegen-arm.cc
-+++ b/src/arm/lithium-codegen-arm.cc
-@@ -166,12 +166,13 @@ bool LCodeGen::GeneratePrologue() {
-
- // Possibly allocate a local context.
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
-- if (heap_slots > 0) {
-+ if (heap_slots > 0 ||
-+ (scope()->is_qml_mode() && scope()->is_global_scope())) {
- Comment(";;; Allocate local context");
- // Argument to NewContext is the function, which is in r1.
- __ push(r1);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
-- FastNewContextStub stub(heap_slots);
-+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
- __ CallStub(&stub);
- } else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -2664,7 +2665,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
- void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
- Register context = ToRegister(instr->context());
- Register result = ToRegister(instr->result());
-- __ ldr(result, ContextOperand(cp, Context::GLOBAL_INDEX));
-+ __ ldr(result, ContextOperand(cp, instr->qml_global()?Context::QML_GLOBAL_INDEX:Context::GLOBAL_INDEX));
- }
-
-
-diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
-index ab5efb0..d40cdbc 100644
---- a/src/arm/macro-assembler-arm.h
-+++ b/src/arm/macro-assembler-arm.h
-@@ -1056,6 +1056,11 @@ static inline MemOperand GlobalObjectOperand() {
- }
-
-
-+static inline MemOperand QmlGlobalObjectOperand() {
-+ return ContextOperand(cp, Context::QML_GLOBAL_INDEX);
-+}
-+
-+
- #ifdef GENERATED_CODE_COVERAGE
- #define CODE_COVERAGE_STRINGIFY(x) #x
- #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
-diff --git a/src/ast-inl.h b/src/ast-inl.h
-index d80684a..adc5a1f 100644
---- a/src/ast-inl.h
-+++ b/src/ast-inl.h
-@@ -106,6 +106,11 @@ bool FunctionLiteral::strict_mode() const {
- }
-
-
-+bool FunctionLiteral::qml_mode() const {
-+ return scope()->is_qml_mode();
-+}
-+
-+
- } } // namespace v8::internal
-
- #endif // V8_AST_INL_H_
-diff --git a/src/ast.h b/src/ast.h
-index 65a25a9..f790dc0 100644
---- a/src/ast.h
-+++ b/src/ast.h
-@@ -1712,6 +1712,7 @@ class FunctionLiteral: public Expression {
- int end_position() const { return end_position_; }
- bool is_expression() const { return is_expression_; }
- bool strict_mode() const;
-+ bool qml_mode() const;
-
- int materialized_literal_count() { return materialized_literal_count_; }
- int expected_property_count() { return expected_property_count_; }
-diff --git a/src/code-stubs.h b/src/code-stubs.h
-index 56ef072..37e5383 100644
---- a/src/code-stubs.h
-+++ b/src/code-stubs.h
-@@ -303,7 +303,7 @@ class FastNewContextStub : public CodeStub {
- static const int kMaximumSlots = 64;
-
- explicit FastNewContextStub(int slots) : slots_(slots) {
-- ASSERT(slots_ > 0 && slots <= kMaximumSlots);
-+ ASSERT(slots_ >= 0 && slots <= kMaximumSlots);
- }
-
- void Generate(MacroAssembler* masm);
-diff --git a/src/compiler.cc b/src/compiler.cc
-index 86d5de3..d2191b9 100755
---- a/src/compiler.cc
-+++ b/src/compiler.cc
-@@ -462,7 +462,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
- v8::Extension* extension,
- ScriptDataImpl* input_pre_data,
- Handle<Object> script_data,
-- NativesFlag natives) {
-+ NativesFlag natives,
-+ v8::Script::CompileFlags compile_flags) {
- Isolate* isolate = source->GetIsolate();
- int source_length = source->length();
- isolate->counters()->total_load_size()->Increment(source_length);
-@@ -523,6 +524,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
- info.MarkAsGlobal();
- info.SetExtension(extension);
- info.SetPreParseData(pre_data);
-+ if (compile_flags & v8::Script::QmlMode) info.MarkAsQmlMode();
- if (natives == NATIVES_CODE) info.MarkAsAllowingNativesSyntax();
- result = MakeFunctionInfo(&info);
- if (extension == NULL && !result.is_null()) {
-@@ -543,7 +545,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
- Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
- Handle<Context> context,
- bool is_global,
-- StrictModeFlag strict_mode) {
-+ StrictModeFlag strict_mode,
-+ bool qml_mode) {
- Isolate* isolate = source->GetIsolate();
- int source_length = source->length();
- isolate->counters()->total_eval_size()->Increment(source_length);
-@@ -567,6 +570,7 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
- CompilationInfo info(script);
- info.MarkAsEval();
- if (is_global) info.MarkAsGlobal();
-+ if (qml_mode) info.MarkAsQmlMode();
- if (strict_mode == kStrictMode) info.MarkAsStrictMode();
- info.SetCallingContext(context);
- result = MakeFunctionInfo(&info);
-@@ -610,6 +614,12 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
- info->MarkAsStrictMode();
- }
-
-+ // After parsing we know function's qml mode. Remember it.
-+ if (info->function()->qml_mode()) {
-+ shared->set_qml_mode(true);
-+ info->MarkAsQmlMode();
-+ }
-+
- // Compile the code.
- if (!MakeCode(info)) {
- if (!isolate->has_pending_exception()) {
-@@ -755,6 +765,7 @@ void Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
- *lit->this_property_assignments());
- function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
- function_info->set_strict_mode(lit->strict_mode());
-+ function_info->set_qml_mode(lit->qml_mode());
- }
-
-
-diff --git a/src/compiler.h b/src/compiler.h
-index e75e869..17cd369 100644
---- a/src/compiler.h
-+++ b/src/compiler.h
-@@ -54,6 +54,7 @@ class CompilationInfo BASE_EMBEDDED {
- bool is_global() const { return (flags_ & IsGlobal::mask()) != 0; }
- bool is_strict_mode() const { return (flags_ & IsStrictMode::mask()) != 0; }
- bool is_in_loop() const { return (flags_ & IsInLoop::mask()) != 0; }
-+ bool is_qml_mode() const { return (flags_ & IsQmlMode::mask()) != 0; }
- FunctionLiteral* function() const { return function_; }
- Scope* scope() const { return scope_; }
- Handle<Code> code() const { return code_; }
-@@ -83,6 +84,9 @@ class CompilationInfo BASE_EMBEDDED {
- ASSERT(is_lazy());
- flags_ |= IsInLoop::encode(true);
- }
-+ void MarkAsQmlMode() {
-+ flags_ |= IsQmlMode::encode(true);
-+ }
- void MarkAsAllowingNativesSyntax() {
- flags_ |= IsNativesSyntaxAllowed::encode(true);
- }
-@@ -141,6 +145,7 @@ class CompilationInfo BASE_EMBEDDED {
-
- // Determine whether or not we can adaptively optimize.
- bool AllowOptimize() {
-+ // XXX - fix qml mode optimizations
- return V8::UseCrankshaft() && !closure_.is_null();
- }
-
-@@ -163,8 +168,13 @@ class CompilationInfo BASE_EMBEDDED {
-
- void Initialize(Mode mode) {
- mode_ = V8::UseCrankshaft() ? mode : NONOPT;
-- if (!shared_info_.is_null() && shared_info_->strict_mode()) {
-- MarkAsStrictMode();
-+ if (!shared_info_.is_null()) {
-+ if (shared_info_->strict_mode()) {
-+ MarkAsStrictMode();
-+ }
-+ if (shared_info_->qml_mode()) {
-+ MarkAsQmlMode();
-+ }
- }
- }
-
-@@ -187,6 +197,8 @@ class CompilationInfo BASE_EMBEDDED {
- class IsStrictMode: public BitField<bool, 4, 1> {};
- // Native syntax (%-stuff) allowed?
- class IsNativesSyntaxAllowed: public BitField<bool, 5, 1> {};
-+ // Qml mode
-+ class IsQmlMode: public BitField<bool, 6, 1> {};
-
- unsigned flags_;
-
-@@ -252,13 +264,15 @@ class Compiler : public AllStatic {
- v8::Extension* extension,
- ScriptDataImpl* pre_data,
- Handle<Object> script_data,
-- NativesFlag is_natives_code);
-+ NativesFlag is_natives_code,
-+ v8::Script::CompileFlags compile_flags = v8::Script::Default);
-
- // Compile a String source within a context for Eval.
- static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
- Handle<Context> context,
- bool is_global,
-- StrictModeFlag strict_mode);
-+ StrictModeFlag strict_mode,
-+ bool qml_mode);
-
- // Compile from function info (used for lazy compilation). Returns true on
- // success and false if the compilation resulted in a stack overflow.
-diff --git a/src/contexts.cc b/src/contexts.cc
-index 520f3dd..da5cacb 100644
---- a/src/contexts.cc
-+++ b/src/contexts.cc
-@@ -89,6 +89,8 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
- PrintF(")\n");
- }
-
-+ Handle<JSObject> qml_global;
-+
- do {
- if (FLAG_trace_contexts) {
- PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
-@@ -119,6 +121,10 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
- }
- }
-
-+ if (qml_global.is_null() && !context->qml_global()->IsUndefined()) {
-+ qml_global = Handle<JSObject>(context->qml_global(), isolate);
-+ }
-+
- if (context->is_function_context()) {
- // we have context-local slots
-
-@@ -198,6 +204,23 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
- }
- } while (follow_context_chain);
-
-+ if (!qml_global.is_null()) {
-+ if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0) {
-+ *attributes = qml_global->GetLocalPropertyAttribute(*name);
-+ } else {
-+ *attributes = qml_global->GetPropertyAttribute(*name);
-+ }
-+
-+ if (*attributes != ABSENT) {
-+ // property found
-+ if (FLAG_trace_contexts) {
-+ PrintF("=> found property in qml global object %p\n",
-+ reinterpret_cast<void*>(*qml_global));
-+ }
-+ return qml_global;
-+ }
-+ }
-+
- // slot not found
- if (FLAG_trace_contexts) {
- PrintF("=> no property/slot found\n");
-diff --git a/src/contexts.h b/src/contexts.h
-index e46619e..57d8e7b 100644
---- a/src/contexts.h
-+++ b/src/contexts.h
-@@ -182,6 +182,7 @@ class Context: public FixedArray {
- FCONTEXT_INDEX,
- PREVIOUS_INDEX,
- EXTENSION_INDEX,
-+ QML_GLOBAL_INDEX,
- GLOBAL_INDEX,
- MIN_CONTEXT_SLOTS,
-
-@@ -273,6 +274,9 @@ class Context: public FixedArray {
- }
- void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); }
-
-+ JSObject *qml_global() { return reinterpret_cast<JSObject *>(get(QML_GLOBAL_INDEX)); }
-+ void set_qml_global(JSObject *qml_global) { set(QML_GLOBAL_INDEX, qml_global); }
-+
- // Returns a JSGlobalProxy object or null.
- JSObject* global_proxy();
- void set_global_proxy(JSObject* global);
-diff --git a/src/execution.cc b/src/execution.cc
-index eb26438..1632076 100644
---- a/src/execution.cc
-+++ b/src/execution.cc
-@@ -70,7 +70,8 @@ static Handle<Object> Invoke(bool construct,
- Handle<Object> receiver,
- int argc,
- Object*** args,
-- bool* has_pending_exception) {
-+ bool* has_pending_exception,
-+ Handle<Object> qml) {
- Isolate* isolate = func->GetIsolate();
-
- // Entering JavaScript.
-@@ -107,6 +108,12 @@ static Handle<Object> Invoke(bool construct,
- // make the current one is indeed a global object.
- ASSERT(func->context()->global()->IsGlobalObject());
-
-+ Handle<JSObject> oldqml;
-+ if (!qml.is_null()) {
-+ oldqml = Handle<JSObject>(func->context()->qml_global());
-+ func->context()->set_qml_global(JSObject::cast(*qml));
-+ }
-+
- {
- // Save and restore context around invocation and block the
- // allocation of handles without explicit handle scopes.
-@@ -122,6 +129,9 @@ static Handle<Object> Invoke(bool construct,
- receiver_pointer, argc, args);
- }
-
-+ if (!qml.is_null())
-+ func->context()->set_qml_global(*oldqml);
-+
- #ifdef DEBUG
- value->Verify();
- #endif
-@@ -150,14 +160,24 @@ Handle<Object> Execution::Call(Handle<JSFunction> func,
- int argc,
- Object*** args,
- bool* pending_exception) {
-- return Invoke(false, func, receiver, argc, args, pending_exception);
-+ return Invoke(false, func, receiver, argc, args, pending_exception, Handle<Object>());
-+}
-+
-+
-+Handle<Object> Execution::Call(Handle<JSFunction> func,
-+ Handle<Object> receiver,
-+ int argc,
-+ Object*** args,
-+ bool* pending_exception,
-+ Handle<Object> qml) {
-+ return Invoke(false, func, receiver, argc, args, pending_exception, qml);
- }
-
-
- Handle<Object> Execution::New(Handle<JSFunction> func, int argc,
- Object*** args, bool* pending_exception) {
- return Invoke(true, func, Isolate::Current()->global(), argc, args,
-- pending_exception);
-+ pending_exception, Handle<Object>());
- }
-
-
-@@ -175,7 +195,7 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func,
- catcher.SetCaptureMessage(false);
-
- Handle<Object> result = Invoke(false, func, receiver, argc, args,
-- caught_exception);
-+ caught_exception, Handle<Object>());
-
- if (*caught_exception) {
- ASSERT(catcher.HasCaught());
-diff --git a/src/execution.h b/src/execution.h
-index d4b80d2..a476eb4 100644
---- a/src/execution.h
-+++ b/src/execution.h
-@@ -56,6 +56,12 @@ class Execution : public AllStatic {
- int argc,
- Object*** args,
- bool* pending_exception);
-+ static Handle<Object> Call(Handle<JSFunction> func,
-+ Handle<Object> receiver,
-+ int argc,
-+ Object*** args,
-+ bool* pending_exception,
-+ Handle<Object> qml);
-
- // Construct object from function, the caller supplies an array of
- // arguments. Arguments are Object* type. After function returns,
-diff --git a/src/full-codegen.cc b/src/full-codegen.cc
-index d6ba56e..2eaef0f 100644
---- a/src/full-codegen.cc
-+++ b/src/full-codegen.cc
-@@ -542,7 +542,7 @@ void FullCodeGenerator::VisitDeclarations(
- // Do nothing in case of no declared global functions or variables.
- if (globals > 0) {
- Handle<FixedArray> array =
-- isolate()->factory()->NewFixedArray(2 * globals, TENURED);
-+ isolate()->factory()->NewFixedArray(3 * globals, TENURED);
- for (int j = 0, i = 0; i < length; i++) {
- Declaration* decl = declarations->at(i);
- Variable* var = decl->proxy()->var();
-@@ -567,6 +567,7 @@ void FullCodeGenerator::VisitDeclarations(
- }
- array->set(j++, *function);
- }
-+ array->set(j++, Smi::FromInt(var->is_qml_global()));
- }
- }
- // Invoke the platform-dependent code generator to do the actual
-diff --git a/src/full-codegen.h b/src/full-codegen.h
-index d6ed1b9..e3241aa 100644
---- a/src/full-codegen.h
-+++ b/src/full-codegen.h
-@@ -505,6 +505,7 @@ class FullCodeGenerator: public AstVisitor {
- StrictModeFlag strict_mode_flag() {
- return is_strict_mode() ? kStrictMode : kNonStrictMode;
- }
-+ bool is_qml_mode() { return function()->qml_mode(); }
- FunctionLiteral* function() { return info_->function(); }
- Scope* scope() { return info_->scope(); }
-
-diff --git a/src/heap.cc b/src/heap.cc
-index bf2940e..da958c2 100644
---- a/src/heap.cc
-+++ b/src/heap.cc
-@@ -3795,6 +3795,7 @@ MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) {
- context->set_previous(NULL);
- context->set_extension(NULL);
- context->set_global(function->context()->global());
-+ context->set_qml_global(function->context()->qml_global());
- ASSERT(!context->IsGlobalContext());
- ASSERT(context->is_function_context());
- ASSERT(result->IsContext());
-@@ -3817,6 +3818,7 @@ MaybeObject* Heap::AllocateWithContext(Context* previous,
- context->set_previous(previous);
- context->set_extension(extension);
- context->set_global(previous->global());
-+ context->set_qml_global(previous->qml_global());
- ASSERT(!context->IsGlobalContext());
- ASSERT(!context->is_function_context());
- ASSERT(result->IsContext());
-diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
-index a623775..52455bc 100644
---- a/src/hydrogen-instructions.h
-+++ b/src/hydrogen-instructions.h
-@@ -1148,7 +1148,7 @@ class HOuterContext: public HUnaryOperation {
-
- class HGlobalObject: public HUnaryOperation {
- public:
-- explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
-+ explicit HGlobalObject(HValue* context) : HUnaryOperation(context), qml_global_(false) {
- set_representation(Representation::Tagged());
- SetFlag(kUseGVN);
- }
-@@ -1159,8 +1159,14 @@ class HGlobalObject: public HUnaryOperation {
- return Representation::Tagged();
- }
-
-+ bool qml_global() { return qml_global_; }
-+ void set_qml_global(bool v) { qml_global_ = v; }
-+
- protected:
- virtual bool DataEquals(HValue* other) { return true; }
-+
-+ private:
-+ bool qml_global_;
- };
-
-
-@@ -1177,7 +1183,7 @@ class HGlobalReceiver: public HUnaryOperation {
- virtual Representation RequiredInputRepresentation(int index) const {
- return Representation::Tagged();
- }
--
-+
- protected:
- virtual bool DataEquals(HValue* other) { return true; }
- };
-diff --git a/src/hydrogen.cc b/src/hydrogen.cc
-index 73ea97d..d17e304 100644
---- a/src/hydrogen.cc
-+++ b/src/hydrogen.cc
-@@ -2918,6 +2918,7 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
- HContext* context = new(zone()) HContext;
- AddInstruction(context);
- HGlobalObject* global_object = new(zone()) HGlobalObject(context);
-+ if (variable->is_qml_global()) global_object->set_qml_global(true);
- AddInstruction(global_object);
- HLoadGlobalGeneric* instr =
- new(zone()) HLoadGlobalGeneric(context,
-@@ -3307,6 +3308,7 @@ void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
- HContext* context = new(zone()) HContext;
- AddInstruction(context);
- HGlobalObject* global_object = new(zone()) HGlobalObject(context);
-+ if (var->is_qml_global()) global_object->set_qml_global(true);
- AddInstruction(global_object);
- HStoreGlobalGeneric* instr =
- new(zone()) HStoreGlobalGeneric(context,
-diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
-index 5d32095..afa599e 100644
---- a/src/ia32/code-stubs-ia32.cc
-+++ b/src/ia32/code-stubs-ia32.cc
-@@ -147,6 +147,13 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
- __ mov(ebx, Operand(ebx, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx);
-
-+ // Copy the qml global object from the surrounding context. We go through the
-+ // context in the function (ecx) to match the allocation behavior we have
-+ // in the runtime system (see Heap::AllocateFunctionContext).
-+ __ mov(ebx, FieldOperand(ecx, JSFunction::kContextOffset));
-+ __ mov(ebx, Operand(ebx, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
-+ __ mov(Operand(eax, Context::SlotOffset(Context::QML_GLOBAL_INDEX)), ebx);
-+
- // Initialize the rest of the slots to undefined.
- __ mov(ebx, factory->undefined_value());
- for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
-diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
-index 5d153a8..0ddcde2 100644
---- a/src/ia32/full-codegen-ia32.cc
-+++ b/src/ia32/full-codegen-ia32.cc
-@@ -142,12 +142,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
-
- // Possibly allocate a local context.
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
-- if (heap_slots > 0) {
-+ if (heap_slots > 0 ||
-+ (scope()->is_qml_mode() && scope()->is_global_scope())) {
- Comment cmnt(masm_, "[ Allocate local context");
- // Argument to NewContext is the function, which is still in edi.
- __ push(edi);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
-- FastNewContextStub stub(heap_slots);
-+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
- __ CallStub(&stub);
- } else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -1107,10 +1108,10 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
-
- // All extension objects were empty and it is safe to use a global
- // load IC call.
-- __ mov(eax, GlobalObjectOperand());
-+ __ mov(eax, slot->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- __ mov(ecx, slot->var()->name());
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-- RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
-+ RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF || slot->var()->is_qml_global())
- ? RelocInfo::CODE_TARGET
- : RelocInfo::CODE_TARGET_CONTEXT;
- EmitCallIC(ic, mode);
-@@ -1214,10 +1215,10 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
- Comment cmnt(masm_, "Global variable");
- // Use inline caching. Variable name is passed in ecx and the global
- // object on the stack.
-- __ mov(eax, GlobalObjectOperand());
-+ __ mov(eax, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- __ mov(ecx, var->name());
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
-+ EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
- context()->Plug(eax);
-
- } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
-@@ -1837,11 +1838,11 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
- // assignment. Right-hand-side value is passed in eax, variable name in
- // ecx, and the global object on the stack.
- __ mov(ecx, var->name());
-- __ mov(edx, GlobalObjectOperand());
-+ __ mov(edx, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- Handle<Code> ic = is_strict_mode()
- ? isolate()->builtins()->StoreIC_Initialize_Strict()
- : isolate()->builtins()->StoreIC_Initialize();
-- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
-+ EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
-
- } else if (op == Token::INIT_CONST) {
- // Like var declarations, const declarations are hoisted to function
-@@ -2113,9 +2114,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
- // Push the strict mode flag.
- __ push(Immediate(Smi::FromInt(strict_mode_flag())));
-
-+ // Push the qml mode flag
-+ __ push(Immediate(Smi::FromInt(is_qml_mode())));
-+
- __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
- ? Runtime::kResolvePossiblyDirectEvalNoLookup
-- : Runtime::kResolvePossiblyDirectEval, 4);
-+ : Runtime::kResolvePossiblyDirectEval, 5);
- }
-
-
-@@ -2188,8 +2192,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
- context()->DropAndPlug(1, eax);
- } else if (var != NULL && !var->is_this() && var->is_global()) {
- // Push global object as receiver for the call IC.
-- __ push(GlobalObjectOperand());
-- EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
-+ __ push(var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
-+ EmitCallWithIC(expr, var->name(), var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
- } else if (var != NULL && var->AsSlot() != NULL &&
- var->AsSlot()->type() == Slot::LOOKUP) {
- // Call to a lookup slot (dynamically introduced variable).
-diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
-index 0f96f78..c1da075 100644
---- a/src/ia32/lithium-codegen-ia32.cc
-+++ b/src/ia32/lithium-codegen-ia32.cc
-@@ -159,12 +159,13 @@ bool LCodeGen::GeneratePrologue() {
-
- // Possibly allocate a local context.
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
-- if (heap_slots > 0) {
-+ if (heap_slots > 0 ||
-+ (scope()->is_qml_mode() && scope()->is_global_scope())) {
- Comment(";;; Allocate local context");
- // Argument to NewContext is the function, which is still in edi.
- __ push(edi);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
-- FastNewContextStub stub(heap_slots);
-+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
- __ CallStub(&stub);
- } else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -2525,7 +2526,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
- void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
- Register context = ToRegister(instr->context());
- Register result = ToRegister(instr->result());
-- __ mov(result, Operand(context, Context::SlotOffset(Context::GLOBAL_INDEX)));
-+ __ mov(result, Operand(context, Context::SlotOffset(instr->qml_global()?Context::QML_GLOBAL_INDEX:Context::GLOBAL_INDEX)));
- }
-
-
-diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
-index 9ccd189..8e98b73 100644
---- a/src/ia32/lithium-ia32.cc
-+++ b/src/ia32/lithium-ia32.cc
-@@ -1205,7 +1205,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
-
- LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
- LOperand* context = UseRegisterAtStart(instr->value());
-- return DefineAsRegister(new LGlobalObject(context));
-+ return DefineAsRegister(new LGlobalObject(context, instr->qml_global()));
- }
-
-
-diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
-index 9ace8f8..95ed001 100644
---- a/src/ia32/lithium-ia32.h
-+++ b/src/ia32/lithium-ia32.h
-@@ -1416,13 +1416,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
-
- class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
- public:
-- explicit LGlobalObject(LOperand* context) {
-+ explicit LGlobalObject(LOperand* context, bool qml_global) {
- inputs_[0] = context;
-+ qml_global_ = qml_global;
- }
-
- DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
-
- LOperand* context() { return InputAt(0); }
-+ bool qml_global() { return qml_global_; }
-+ private:
-+ bool qml_global_;
- };
-
-
-diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
-index b986264..f8479ae 100644
---- a/src/ia32/macro-assembler-ia32.h
-+++ b/src/ia32/macro-assembler-ia32.h
-@@ -778,6 +778,11 @@ static inline Operand GlobalObjectOperand() {
- }
-
-
-+static inline Operand QmlGlobalObjectOperand() {
-+ return ContextOperand(esi, Context::QML_GLOBAL_INDEX);
-+}
-+
-+
- // Generates an Operand for saving parameters after PrepareCallApiFunction.
- Operand ApiParameterOperand(int index);
-
-diff --git a/src/objects-inl.h b/src/objects-inl.h
-index 231b835..1c7f83e 100644
---- a/src/objects-inl.h
-+++ b/src/objects-inl.h
-@@ -3242,6 +3242,18 @@ void SharedFunctionInfo::set_strict_mode(bool value) {
- }
-
-
-+bool SharedFunctionInfo::qml_mode() {
-+ return BooleanBit::get(compiler_hints(), kQmlModeFunction);
-+}
-+
-+
-+void SharedFunctionInfo::set_qml_mode(bool value) {
-+ set_compiler_hints(BooleanBit::set(compiler_hints(),
-+ kQmlModeFunction,
-+ value));
-+}
-+
-+
- ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
- ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
-
-diff --git a/src/objects.h b/src/objects.h
-index 1bdb5c7..edbc47a 100644
---- a/src/objects.h
-+++ b/src/objects.h
-@@ -4331,6 +4331,10 @@ class SharedFunctionInfo: public HeapObject {
- inline bool strict_mode();
- inline void set_strict_mode(bool value);
-
-+ // Indicates whether the function is a qml mode function
-+ inline bool qml_mode();
-+ inline void set_qml_mode(bool value);
-+
- // Indicates whether or not the code in the shared function support
- // deoptimization.
- inline bool has_deoptimization_support();
-@@ -4511,6 +4515,7 @@ class SharedFunctionInfo: public HeapObject {
- static const int kCodeAgeMask = 0x7;
- static const int kOptimizationDisabled = 6;
- static const int kStrictModeFunction = 7;
-+ static const int kQmlModeFunction = 8;
-
- private:
- #if V8_HOST_ARCH_32_BIT
-diff --git a/src/parser.cc b/src/parser.cc
-index a84ec6f..7f5c361 100644
---- a/src/parser.cc
-+++ b/src/parser.cc
-@@ -593,7 +593,8 @@ Parser::Parser(Handle<Script> script,
-
- FunctionLiteral* Parser::ParseProgram(Handle<String> source,
- bool in_global_context,
-- StrictModeFlag strict_mode) {
-+ StrictModeFlag strict_mode,
-+ bool qml_mode) {
- CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
-
- HistogramTimerScope timer(isolate()->counters()->parse());
-@@ -609,11 +610,11 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
- ExternalTwoByteStringUC16CharacterStream stream(
- Handle<ExternalTwoByteString>::cast(source), 0, source->length());
- scanner_.Initialize(&stream);
-- return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
-+ return DoParseProgram(source, in_global_context, strict_mode, qml_mode, &zone_scope);
- } else {
- GenericStringUC16CharacterStream stream(source, 0, source->length());
- scanner_.Initialize(&stream);
-- return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
-+ return DoParseProgram(source, in_global_context, strict_mode, qml_mode, &zone_scope);
- }
- }
-
-@@ -621,6 +622,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
- FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
- bool in_global_context,
- StrictModeFlag strict_mode,
-+ bool qml_mode,
- ZoneScope* zone_scope) {
- ASSERT(target_stack_ == NULL);
- if (pre_data_ != NULL) pre_data_->Initialize();
-@@ -641,6 +643,9 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
- if (strict_mode == kStrictMode) {
- top_scope_->EnableStrictMode();
- }
-+ if (qml_mode) {
-+ scope->EnableQmlMode();
-+ }
- ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
- bool ok = true;
- int beg_loc = scanner().location().beg_pos;
-@@ -729,6 +734,9 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
- if (shared_info->strict_mode()) {
- top_scope_->EnableStrictMode();
- }
-+ if (shared_info->qml_mode()) {
-+ top_scope_->EnableQmlMode();
-+ }
-
- FunctionLiteralType type =
- shared_info->is_expression() ? EXPRESSION : DECLARATION;
-@@ -1661,6 +1669,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
- arguments->Add(value);
- value = NULL; // zap the value to avoid the unnecessary assignment
-
-+ int qml_mode = 0;
-+ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name))
-+ qml_mode = 1;
-+ arguments->Add(NewNumberLiteral(qml_mode));
-+
- // Construct the call to Runtime_InitializeConstGlobal
- // and add it to the initialization statement block.
- // Note that the function does different things depending on
-@@ -1676,6 +1689,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
- arguments->Add(NewNumberLiteral(
- top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode));
-
-+ int qml_mode = 0;
-+ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name))
-+ qml_mode = 1;
-+ arguments->Add(NewNumberLiteral(qml_mode));
-+
- // Be careful not to assign a value to the global variable if
- // we're in a with. The initialization value should not
- // necessarily be stored in the global object in that case,
-@@ -5157,7 +5175,8 @@ bool ParserApi::Parse(CompilationInfo* info) {
- Handle<String> source = Handle<String>(String::cast(script->source()));
- result = parser.ParseProgram(source,
- info->is_global(),
-- info->StrictMode());
-+ info->StrictMode(),
-+ info->is_qml_mode());
- }
- }
-
-diff --git a/src/parser.h b/src/parser.h
-index 64f1303..4d45e45 100644
---- a/src/parser.h
-+++ b/src/parser.h
-@@ -431,7 +431,8 @@ class Parser {
- // Returns NULL if parsing failed.
- FunctionLiteral* ParseProgram(Handle<String> source,
- bool in_global_context,
-- StrictModeFlag strict_mode);
-+ StrictModeFlag strict_mode,
-+ bool qml_mode);
-
- FunctionLiteral* ParseLazy(CompilationInfo* info);
-
-@@ -464,6 +465,7 @@ class Parser {
- FunctionLiteral* DoParseProgram(Handle<String> source,
- bool in_global_context,
- StrictModeFlag strict_mode,
-+ bool qml_mode,
- ZoneScope* zone_scope);
-
- // Report syntax error
-diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
-index c777ab4..1964e02 100644
---- a/src/prettyprinter.cc
-+++ b/src/prettyprinter.cc
-@@ -656,6 +656,9 @@ void AstPrinter::PrintLiteralWithModeIndented(const char* info,
- EmbeddedVector<char, 256> buf;
- int pos = OS::SNPrintF(buf, "%s (mode = %s", info,
- Variable::Mode2String(var->mode()));
-+ if (var->is_qml_global()) {
-+ pos += OS::SNPrintF(buf + pos, ":QML");
-+ }
- OS::SNPrintF(buf + pos, ")");
- PrintLiteralIndented(buf.start(), value, true);
- }
-diff --git a/src/runtime.cc b/src/runtime.cc
-index 660352c..827d954 100644
---- a/src/runtime.cc
-+++ b/src/runtime.cc
-@@ -1065,8 +1065,6 @@ static Failure* ThrowRedeclarationError(Isolate* isolate,
- RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
- ASSERT(args.length() == 4);
- HandleScope scope(isolate);
-- Handle<GlobalObject> global = Handle<GlobalObject>(
-- isolate->context()->global());
-
- Handle<Context> context = args.at<Context>(0);
- CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
-@@ -1075,6 +1073,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
- static_cast<StrictModeFlag>(Smi::cast(args[3])->value());
- ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
-
-+ Handle<JSObject> js_global = Handle<JSObject>(isolate->context()->global());
-+ Handle<JSObject> qml_global = Handle<JSObject>(isolate->context()->qml_global());
-+
- // Compute the property attributes. According to ECMA-262, section
- // 13, page 71, the property must be read-only and
- // non-deletable. However, neither SpiderMonkey nor KJS creates the
-@@ -1083,10 +1084,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
-
- // Traverse the name/value pairs and set the properties.
- int length = pairs->length();
-- for (int i = 0; i < length; i += 2) {
-+ for (int i = 0; i < length; i += 3) {
- HandleScope scope(isolate);
- Handle<String> name(String::cast(pairs->get(i)));
- Handle<Object> value(pairs->get(i + 1), isolate);
-+ Handle<Smi> is_qml_global(Smi::cast(pairs->get(i + 2)));
-+
-+ Handle<JSObject> global = is_qml_global->value()?qml_global:js_global;
-
- // We have to declare a global const property. To capture we only
- // assign to it when evaluating the assignment for "const x =
-@@ -1316,20 +1320,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
- NoHandleAllocation nha;
- // args[0] == name
- // args[1] == strict_mode
-- // args[2] == value (optional)
-+ // args[2] == qml_mode
-+ // args[3] == value (optional)
-
- // Determine if we need to assign to the variable if it already
- // exists (based on the number of arguments).
-- RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
-- bool assign = args.length() == 3;
-+ RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
-+ bool assign = args.length() == 4;
-
- CONVERT_ARG_CHECKED(String, name, 0);
-- GlobalObject* global = isolate->context()->global();
- RUNTIME_ASSERT(args[1]->IsSmi());
- StrictModeFlag strict_mode =
- static_cast<StrictModeFlag>(Smi::cast(args[1])->value());
- ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
-
-+ RUNTIME_ASSERT(args[2]->IsSmi());
-+ int qml_mode = Smi::cast(args[2])->value();
-+
-+ JSObject* global = qml_mode?isolate->context()->qml_global():isolate->context()->global();
-+
- // According to ECMA-262, section 12.2, page 62, the property must
- // not be deletable.
- PropertyAttributes attributes = DONT_DELETE;
-@@ -1350,7 +1359,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
- if (lookup.IsReadOnly()) {
- // If we found readonly property on one of hidden prototypes,
- // just shadow it.
-- if (real_holder != isolate->context()->global()) break;
-+ if (real_holder != global) break;
- return ThrowRedeclarationError(isolate, "const", name);
- }
-
-@@ -1372,7 +1381,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
- // overwrite it with a variable declaration we must throw a
- // re-declaration error. However if we found readonly property
- // on one of hidden prototypes, just shadow it.
-- if (real_holder != isolate->context()->global()) break;
-+ if (real_holder != global) break;
- return ThrowRedeclarationError(isolate, "const", name);
- }
- }
-@@ -1384,7 +1393,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
- }
-
- // Assign the value (or undefined) to the property.
-- Object* value = (assign) ? args[2] : isolate->heap()->undefined_value();
-+ Object* value = (assign) ? args[3] : isolate->heap()->undefined_value();
- return real_holder->SetProperty(
- &lookup, *name, value, attributes, strict_mode);
- }
-@@ -1399,9 +1408,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
- real_holder = JSObject::cast(proto);
- }
-
-- global = isolate->context()->global();
-+ global = qml_mode?isolate->context()->qml_global():isolate->context()->global();
- if (assign) {
-- return global->SetProperty(*name, args[2], attributes, strict_mode, true);
-+ return global->SetProperty(*name, args[3], attributes, strict_mode, true);
- }
- return isolate->heap()->undefined_value();
- }
-@@ -1411,12 +1420,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
- // All constants are declared with an initial value. The name
- // of the constant is the first argument and the initial value
- // is the second.
-- RUNTIME_ASSERT(args.length() == 2);
-+ RUNTIME_ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(String, name, 0);
- Handle<Object> value = args.at<Object>(1);
-
-+ RUNTIME_ASSERT(args[2]->IsSmi());
-+ int qml_mode = Smi::cast(args[2])->value();
-+
- // Get the current global object from top.
-- GlobalObject* global = isolate->context()->global();
-+ JSObject* global = qml_mode?isolate->context()->qml_global():isolate->context()->global();
-
- // According to ECMA-262, section 12.2, page 62, the property must
- // not be deletable. Since it's a const, it must be READ_ONLY too.
-@@ -1456,7 +1468,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
- // with setting the value because the property is either absent or
- // read-only. We also have to do redo the lookup.
- HandleScope handle_scope(isolate);
-- Handle<GlobalObject> global(isolate->context()->global());
-+ Handle<JSObject> global(qml_mode?isolate->context()->qml_global():isolate->context()->global());
-
- // BUG 1213575: Handle the case where we have to set a read-only
- // property through an interceptor and only do it if it's
-@@ -8160,7 +8172,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
- Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source,
- context,
- true,
-- kNonStrictMode);
-+ kNonStrictMode,
-+ false);
- if (shared.is_null()) return Failure::Exception();
- Handle<JSFunction> fun =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
-@@ -8173,14 +8186,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
- static ObjectPair CompileGlobalEval(Isolate* isolate,
- Handle<String> source,
- Handle<Object> receiver,
-- StrictModeFlag strict_mode) {
-+ StrictModeFlag strict_mode,
-+ bool qml_mode) {
- // Deal with a normal eval call with a string argument. Compile it
- // and return the compiled function bound in the local context.
- Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
- source,
- Handle<Context>(isolate->context()),
- isolate->context()->IsGlobalContext(),
-- strict_mode);
-+ strict_mode,
-+ qml_mode);
- if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
- Handle<JSFunction> compiled =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(
-@@ -8190,7 +8205,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
-
-
- RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
-- ASSERT(args.length() == 4);
-+ ASSERT(args.length() == 5);
-
- HandleScope scope(isolate);
- Handle<Object> callee = args.at<Object>(0);
-@@ -8257,16 +8272,18 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
- }
-
- ASSERT(args[3]->IsSmi());
-+ ASSERT(args[4]->IsSmi());
- return CompileGlobalEval(isolate,
- args.at<String>(1),
- args.at<Object>(2),
- static_cast<StrictModeFlag>(
-- Smi::cast(args[3])->value()));
-+ Smi::cast(args[3])->value()),
-+ Smi::cast(args[4])->value());
- }
-
-
- RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
-- ASSERT(args.length() == 4);
-+ ASSERT(args.length() == 5);
-
- HandleScope scope(isolate);
- Handle<Object> callee = args.at<Object>(0);
-@@ -8280,11 +8297,13 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
- }
-
- ASSERT(args[3]->IsSmi());
-+ ASSERT(args[4]->IsSmi());
- return CompileGlobalEval(isolate,
- args.at<String>(1),
- args.at<Object>(2),
- static_cast<StrictModeFlag>(
-- Smi::cast(args[3])->value()));
-+ Smi::cast(args[3])->value()),
-+ Smi::cast(args[4])->value());
- }
-
-
-@@ -10633,7 +10652,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
- Compiler::CompileEval(function_source,
- context,
- context->IsGlobalContext(),
-- kNonStrictMode);
-+ kNonStrictMode,
-+ false);
- if (shared.is_null()) return Failure::Exception();
- Handle<JSFunction> compiled_function =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context);
-@@ -10722,7 +10742,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
- // Currently, the eval code will be executed in non-strict mode,
- // even in the strict code context.
- Handle<SharedFunctionInfo> shared =
-- Compiler::CompileEval(source, context, is_global, kNonStrictMode);
-+ Compiler::CompileEval(source, context, is_global, kNonStrictMode, false);
- if (shared.is_null()) return Failure::Exception();
- Handle<JSFunction> compiled_function =
- Handle<JSFunction>(
-diff --git a/src/runtime.h b/src/runtime.h
-index bf1ba68..5e97173 100644
---- a/src/runtime.h
-+++ b/src/runtime.h
-@@ -241,8 +241,8 @@ namespace internal {
- \
- /* Eval */ \
- F(GlobalReceiver, 1, 1) \
-- F(ResolvePossiblyDirectEval, 4, 2) \
-- F(ResolvePossiblyDirectEvalNoLookup, 4, 2) \
-+ F(ResolvePossiblyDirectEval, 5, 2) \
-+ F(ResolvePossiblyDirectEvalNoLookup, 5, 2) \
- \
- F(SetProperty, -1 /* 4 or 5 */, 1) \
- F(DefineOrRedefineDataProperty, 4, 1) \
-@@ -296,8 +296,8 @@ namespace internal {
- /* Declarations and initialization */ \
- F(DeclareGlobals, 4, 1) \
- F(DeclareContextSlot, 4, 1) \
-- F(InitializeVarGlobal, -1 /* 2 or 3 */, 1) \
-- F(InitializeConstGlobal, 2, 1) \
-+ F(InitializeVarGlobal, -1 /* 3 or 4 */, 1) \
-+ F(InitializeConstGlobal, 3, 1) \
- F(InitializeConstContextSlot, 3, 1) \
- F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
- \
-diff --git a/src/scopes.cc b/src/scopes.cc
-index 8df93c5..734a217 100644
---- a/src/scopes.cc
-+++ b/src/scopes.cc
-@@ -198,6 +198,7 @@ void Scope::SetDefaults(Type type,
- scope_calls_eval_ = false;
- // Inherit the strict mode from the parent scope.
- strict_mode_ = (outer_scope != NULL) && outer_scope->strict_mode_;
-+ qml_mode_ = (outer_scope != NULL) && outer_scope->qml_mode_;
- outer_scope_calls_eval_ = false;
- inner_scope_calls_eval_ = false;
- outer_scope_is_eval_scope_ = false;
-@@ -796,6 +797,10 @@ void Scope::ResolveVariable(Scope* global_scope,
- ASSERT(global_scope != NULL);
- var = global_scope->DeclareGlobal(proxy->name());
-
-+ if (qml_mode_ && !Isolate::Current()->global()->HasProperty(*(proxy->name()))) {
-+ var->set_is_qml_global(true);
-+ }
-+
- } else if (scope_inside_with_) {
- // If we are inside a with statement we give up and look up
- // the variable at runtime.
-@@ -816,6 +821,8 @@ void Scope::ResolveVariable(Scope* global_scope,
- // variables.
- if (context->GlobalIfNotShadowedByEval(proxy->name())) {
- var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
-+ if (qml_mode_ && !Isolate::Current()->global()->HasProperty(*(proxy->name())))
-+ var->set_is_qml_global(true);
-
- } else {
- var = NonLocal(proxy->name(), Variable::DYNAMIC);
-@@ -827,6 +834,9 @@ void Scope::ResolveVariable(Scope* global_scope,
- // variable is global unless it is shadowed by eval-introduced
- // variables.
- var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
-+
-+ if (qml_mode_ && !Isolate::Current()->global()->HasProperty(*(proxy->name())))
-+ var->set_is_qml_global(true);
- }
- }
- }
-diff --git a/src/scopes.h b/src/scopes.h
-index a0e56a4..6dd3f65 100644
---- a/src/scopes.h
-+++ b/src/scopes.h
-@@ -210,6 +210,11 @@ class Scope: public ZoneObject {
- strict_mode_ = FLAG_strict_mode;
- }
-
-+ // Enable qml mode for this scope
-+ void EnableQmlMode() {
-+ qml_mode_ = true;
-+ }
-+
- // ---------------------------------------------------------------------------
- // Predicates.
-
-@@ -218,6 +223,7 @@ class Scope: public ZoneObject {
- bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
- bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
- bool is_strict_mode() const { return strict_mode_; }
-+ bool is_qml_mode() const { return qml_mode_; }
-
- // Information about which scopes calls eval.
- bool calls_eval() const { return scope_calls_eval_; }
-@@ -376,6 +382,7 @@ class Scope: public ZoneObject {
- bool scope_contains_with_; // this scope contains a 'with' statement
- bool scope_calls_eval_; // this scope contains an 'eval' call
- bool strict_mode_; // this scope is a strict mode scope
-+ bool qml_mode_; // this scope is a qml mode scope
-
- // Computed via PropagateScopeInfo.
- bool outer_scope_calls_eval_;
-diff --git a/src/variables.cc b/src/variables.cc
-index 0502722..190baf6 100644
---- a/src/variables.cc
-+++ b/src/variables.cc
-@@ -99,7 +99,8 @@ Variable::Variable(Scope* scope,
- rewrite_(NULL),
- is_valid_LHS_(is_valid_LHS),
- is_accessed_from_inner_scope_(false),
-- is_used_(false) {
-+ is_used_(false),
-+ is_qml_global_(false) {
- // names must be canonicalized for fast equality checks
- ASSERT(name->IsSymbol());
- }
-diff --git a/src/variables.h b/src/variables.h
-index b1ff0db..0b31d1a 100644
---- a/src/variables.h
-+++ b/src/variables.h
-@@ -141,6 +141,8 @@ class Variable: public ZoneObject {
- Expression* rewrite() const { return rewrite_; }
- void set_rewrite(Expression* expr) { rewrite_ = expr; }
-
-+ bool is_qml_global() const { return is_qml_global_; }
-+ void set_is_qml_global(bool is_qml_global) { is_qml_global_ = is_qml_global; }
- private:
- Scope* scope_;
- Handle<String> name_;
-@@ -159,6 +161,9 @@ class Variable: public ZoneObject {
- // Usage info.
- bool is_accessed_from_inner_scope_; // set by variable resolver
- bool is_used_;
-+
-+ // QML info
-+ bool is_qml_global_;
- };
-
-
-diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
-index c365385..d923494 100644
---- a/src/x64/code-stubs-x64.cc
-+++ b/src/x64/code-stubs-x64.cc
-@@ -140,6 +140,10 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
- __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
- __ movq(Operand(rax, Context::SlotOffset(Context::GLOBAL_INDEX)), rbx);
-
-+ // Copy the qml global object from the surrounding context.
-+ __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
-+ __ movq(Operand(rax, Context::SlotOffset(Context::QML_GLOBAL_INDEX)), rbx);
-+
- // Initialize the rest of the slots to undefined.
- __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
- for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
-diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
-index 97168cd..c45cdb6 100644
---- a/src/x64/full-codegen-x64.cc
-+++ b/src/x64/full-codegen-x64.cc
-@@ -141,12 +141,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
-
- // Possibly allocate a local context.
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
-- if (heap_slots > 0) {
-+ if (heap_slots > 0 ||
-+ (scope()->is_qml_mode() && scope()->is_global_scope())) {
- Comment cmnt(masm_, "[ Allocate local context");
- // Argument to NewContext is the function, which is still in rdi.
- __ push(rdi);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
-- FastNewContextStub stub(heap_slots);
-+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
- __ CallStub(&stub);
- } else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -1119,10 +1120,10 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
-
- // All extension objects were empty and it is safe to use a global
- // load IC call.
-- __ movq(rax, GlobalObjectOperand());
-+ __ movq(rax, slot->var()->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
- __ Move(rcx, slot->var()->name());
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-- RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
-+ RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF || slot->var()->is_qml_global())
- ? RelocInfo::CODE_TARGET
- : RelocInfo::CODE_TARGET_CONTEXT;
- EmitCallIC(ic, mode);
-@@ -1227,9 +1228,9 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
- // Use inline caching. Variable name is passed in rcx and the global
- // object on the stack.
- __ Move(rcx, var->name());
-- __ movq(rax, GlobalObjectOperand());
-+ __ movq(rax, var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
-+ EmitCallIC(ic, var->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT);
- context()->Plug(rax);
-
- } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
-@@ -1806,11 +1807,11 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
- // assignment. Right-hand-side value is passed in rax, variable name in
- // rcx, and the global object on the stack.
- __ Move(rcx, var->name());
-- __ movq(rdx, GlobalObjectOperand());
-+ __ movq(rdx, var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
- Handle<Code> ic = is_strict_mode()
- ? isolate()->builtins()->StoreIC_Initialize_Strict()
- : isolate()->builtins()->StoreIC_Initialize();
-- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
-+ EmitCallIC(ic, var->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT);
-
- } else if (op == Token::INIT_CONST) {
- // Like var declarations, const declarations are hoisted to function
-@@ -2085,9 +2086,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
- // Push the strict mode flag.
- __ Push(Smi::FromInt(strict_mode_flag()));
-
-+ // Push the qml mode flag
-+ __ Push(Smi::FromInt(is_qml_mode()));
-+
- __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
- ? Runtime::kResolvePossiblyDirectEvalNoLookup
-- : Runtime::kResolvePossiblyDirectEval, 4);
-+ : Runtime::kResolvePossiblyDirectEval, 5);
- }
-
-
-@@ -2160,8 +2164,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
- } else if (var != NULL && !var->is_this() && var->is_global()) {
- // Call to a global variable.
- // Push global object as receiver for the call IC lookup.
-- __ push(GlobalObjectOperand());
-- EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
-+ __ push(var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
-+ EmitCallWithIC(expr, var->name(), var->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT);
- } else if (var != NULL && var->AsSlot() != NULL &&
- var->AsSlot()->type() == Slot::LOOKUP) {
- // Call to a lookup slot (dynamically introduced variable).
-diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
-index 202e7a2..45acbdf 100644
---- a/src/x64/lithium-codegen-x64.cc
-+++ b/src/x64/lithium-codegen-x64.cc
-@@ -174,12 +174,13 @@ bool LCodeGen::GeneratePrologue() {
-
- // Possibly allocate a local context.
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
-- if (heap_slots > 0) {
-+ if (heap_slots > 0 ||
-+ (scope()->is_qml_mode() && scope()->is_global_scope())) {
- Comment(";;; Allocate local context");
- // Argument to NewContext is the function, which is still in rdi.
- __ push(rdi);
- if (heap_slots <= FastNewContextStub::kMaximumSlots) {
-- FastNewContextStub stub(heap_slots);
-+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
- __ CallStub(&stub);
- } else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -2540,7 +2541,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
-
- void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
- Register result = ToRegister(instr->result());
-- __ movq(result, GlobalObjectOperand());
-+ __ movq(result, instr->qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- }
-
-
-diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
-index 07ca3a5..00feeac 100644
---- a/src/x64/lithium-x64.cc
-+++ b/src/x64/lithium-x64.cc
-@@ -1194,7 +1194,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
-
-
- LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
-- return DefineAsRegister(new LGlobalObject);
-+ return DefineAsRegister(new LGlobalObject(instr->qml_global()));
- }
-
-
-diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
-index 15bb894..16f754c 100644
---- a/src/x64/lithium-x64.h
-+++ b/src/x64/lithium-x64.h
-@@ -1365,7 +1365,13 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
-
- class LGlobalObject: public LTemplateInstruction<1, 0, 0> {
- public:
-+ explicit LGlobalObject(bool qml_global) : qml_global_(qml_global) {}
-+
- DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
-+
-+ bool qml_global() { return qml_global_; }
-+ private:
-+ bool qml_global_;
- };
-
-
-diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
-index 4c17720..aa284ed 100644
---- a/src/x64/macro-assembler-x64.h
-+++ b/src/x64/macro-assembler-x64.h
-@@ -1233,6 +1233,11 @@ static inline Operand GlobalObjectOperand() {
- }
-
-
-+static inline Operand QmlGlobalObjectOperand() {
-+ return ContextOperand(rsi, Context::QML_GLOBAL_INDEX);
-+}
-+
-+
- // Provides access to exit frame stack space (not GCed).
- static inline Operand StackSpaceOperand(int index) {
- #ifdef _WIN64
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0006-Allow-access-to-the-calling-script-data.patch b/src/declarative/v8/0006-Allow-access-to-the-calling-script-data.patch
deleted file mode 100644
index b9c44654cd..0000000000
--- a/src/declarative/v8/0006-Allow-access-to-the-calling-script-data.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From f890f0d1a1e5bd62711815489c87755a4f382436 Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Wed, 25 May 2011 10:36:13 +1000
-Subject: [PATCH 06/13] Allow access to the calling script data
-
----
- include/v8.h | 1 +
- src/api.cc | 12 ++++++++++++
- 2 files changed, 13 insertions(+), 0 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index a858eae..9aba4a8 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -3336,6 +3336,7 @@ class V8EXPORT Context {
- */
- static Local<Context> GetCalling();
- static Local<Object> GetCallingQmlGlobal();
-+ static Local<Value> GetCallingScriptData();
-
- /**
- * Sets the security token for the context. To access an object in
-diff --git a/src/api.cc b/src/api.cc
-index 39767f4..ff74efb 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -3976,6 +3976,18 @@ v8::Local<v8::Object> Context::GetCallingQmlGlobal() {
- }
- }
-
-+v8::Local<v8::Value> Context::GetCallingScriptData()
-+{
-+ i::Isolate* isolate = i::Isolate::Current();
-+ if (IsDeadCheck(isolate, "v8::Context::GetCallingScriptData()")) {
-+ return Local<Object>();
-+ }
-+
-+ i::JavaScriptFrameIterator it;
-+ if (it.done()) return Local<Object>();
-+ i::Handle<i::Script> script(i::Script::cast(i::JSFunction::cast(it.frame()->function())->shared()->script()));
-+ return Utils::ToLocal(i::Handle<i::Object>(script->data()));
-+}
-
- v8::Local<v8::Object> Context::Global() {
- if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0007-Fix-warnings.patch b/src/declarative/v8/0007-Fix-warnings.patch
deleted file mode 100644
index 60fb24c138..0000000000
--- a/src/declarative/v8/0007-Fix-warnings.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From dac5d9db84cf20564621c679937ca7b9c6a8e880 Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Fri, 27 May 2011 13:04:15 +1000
-Subject: [PATCH 07/13] Fix warnings
-
----
- include/v8.h | 16 ++++++++--------
- 1 files changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 9aba4a8..8891dab 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -2415,7 +2415,7 @@ class V8EXPORT Extension { // NOLINT
- const char** deps = 0);
- virtual ~Extension() { }
- virtual v8::Handle<v8::FunctionTemplate>
-- GetNativeFunction(v8::Handle<v8::String> name) {
-+ GetNativeFunction(v8::Handle<v8::String>) {
- return v8::Handle<v8::FunctionTemplate>();
- }
-
-@@ -3721,13 +3721,13 @@ class Internals {
- return *reinterpret_cast<T*>(addr);
- }
-
-- static inline bool CanCastToHeapObject(void* o) { return false; }
-- static inline bool CanCastToHeapObject(Context* o) { return true; }
-- static inline bool CanCastToHeapObject(String* o) { return true; }
-- static inline bool CanCastToHeapObject(Object* o) { return true; }
-- static inline bool CanCastToHeapObject(Message* o) { return true; }
-- static inline bool CanCastToHeapObject(StackTrace* o) { return true; }
-- static inline bool CanCastToHeapObject(StackFrame* o) { return true; }
-+ static inline bool CanCastToHeapObject(void*) { return false; }
-+ static inline bool CanCastToHeapObject(Context*) { return true; }
-+ static inline bool CanCastToHeapObject(String*) { return true; }
-+ static inline bool CanCastToHeapObject(Object*) { return true; }
-+ static inline bool CanCastToHeapObject(Message*) { return true; }
-+ static inline bool CanCastToHeapObject(StackTrace*) { return true; }
-+ static inline bool CanCastToHeapObject(StackFrame*) { return true; }
- };
-
- } // namespace internal
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0008-Add-custom-object-compare-callback.patch b/src/declarative/v8/0008-Add-custom-object-compare-callback.patch
deleted file mode 100644
index fdb0895f06..0000000000
--- a/src/declarative/v8/0008-Add-custom-object-compare-callback.patch
+++ /dev/null
@@ -1,489 +0,0 @@
-From bec11b8b7f89d135e7d9a823ac4fe98c70d017cf Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Mon, 27 Jun 2011 14:57:28 +1000
-Subject: [PATCH 08/13] Add custom object compare callback
-
-A global custom object comparison callback can be set with:
- V8::SetUserObjectComparisonCallbackFunction()
-When two JSObjects are compared (== or !=), if either one has
-the MarkAsUseUserObjectComparison() bit set, the custom comparison
-callback is invoked to do the actual comparison.
-
-This is useful when you have "value" objects that you want to
-compare as equal, even though they are actually different JS object
-instances.
----
- include/v8.h | 13 +++++++++++++
- src/api.cc | 19 +++++++++++++++++++
- src/arm/code-stubs-arm.cc | 42 ++++++++++++++++++++++++++++++++++++++++--
- src/factory.cc | 8 ++++++++
- src/ia32/code-stubs-ia32.cc | 40 ++++++++++++++++++++++++++++++++++++++++
- src/isolate.h | 8 ++++++++
- src/objects-inl.h | 15 +++++++++++++++
- src/objects.h | 10 +++++++++-
- src/runtime.cc | 23 +++++++++++++++++++++++
- src/runtime.h | 1 +
- src/top.cc | 5 +++++
- src/x64/code-stubs-x64.cc | 37 +++++++++++++++++++++++++++++++++++++
- 12 files changed, 218 insertions(+), 3 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 8891dab..d5d6972 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -2365,6 +2365,12 @@ class V8EXPORT ObjectTemplate : public Template {
- bool HasExternalResource();
- void SetHasExternalResource(bool value);
-
-+ /**
-+ * Mark object instances of the template as using the user object
-+ * comparison callback.
-+ */
-+ void MarkAsUseUserObjectComparison();
-+
- private:
- ObjectTemplate();
- static Local<ObjectTemplate> New(Handle<FunctionTemplate> constructor);
-@@ -2565,6 +2571,10 @@ typedef void (*FailedAccessCheckCallback)(Local<Object> target,
- AccessType type,
- Local<Value> data);
-
-+// --- U s e r O b j e c t C o m p a r i s o n C a l l b a c k ---
-+typedef bool (*UserObjectComparisonCallback)(Local<Object> lhs,
-+ Local<Object> rhs);
-+
- // --- G a r b a g e C o l l e c t i o n C a l l b a c k s
-
- /**
-@@ -2815,6 +2825,9 @@ class V8EXPORT V8 {
- /** Callback function for reporting failed access checks.*/
- static void SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback);
-
-+ /** Callback for user object comparisons */
-+ static void SetUserObjectComparisonCallbackFunction(UserObjectComparisonCallback);
-+
- /**
- * Enables the host application to receive a notification before a
- * garbage collection. Allocations are not allowed in the
-diff --git a/src/api.cc b/src/api.cc
-index ff74efb..2436031 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -1321,6 +1321,16 @@ void ObjectTemplate::SetHasExternalResource(bool value)
- }
- }
-
-+void ObjectTemplate::MarkAsUseUserObjectComparison()
-+{
-+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUseUserObjectComparison()")) {
-+ return;
-+ }
-+ ENTER_V8(isolate);
-+ EnsureConstructor(this);
-+ Utils::OpenHandle(this)->set_use_user_object_comparison(i::Smi::FromInt(1));
-+}
-
- // --- S c r i p t D a t a ---
-
-@@ -4632,6 +4642,15 @@ void V8::SetFailedAccessCheckCallbackFunction(
- isolate->SetFailedAccessCheckCallback(callback);
- }
-
-+void V8::SetUserObjectComparisonCallbackFunction(
-+ UserObjectComparisonCallback callback) {
-+ i::Isolate* isolate = i::Isolate::Current();
-+ if (IsDeadCheck(isolate, "v8::V8::SetUserObjectComparisonCallbackFunction()")) {
-+ return;
-+ }
-+ isolate->SetUserObjectComparisonCallback(callback);
-+}
-+
- void V8::AddObjectGroup(Persistent<Value>* objects,
- size_t length,
- RetainedObjectInfo* info) {
-diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
-index a2626bf..749c9be 100644
---- a/src/arm/code-stubs-arm.cc
-+++ b/src/arm/code-stubs-arm.cc
-@@ -1563,6 +1563,36 @@ void CompareStub::Generate(MacroAssembler* masm) {
- // NOTICE! This code is only reached after a smi-fast-case check, so
- // it is certain that at least one operand isn't a smi.
-
-+ {
-+ Label not_user_equal, user_equal;
-+ __ and_(r2, r1, Operand(r0));
-+ __ tst(r2, Operand(kSmiTagMask));
-+ __ b(eq, &not_user_equal);
-+
-+ __ CompareObjectType(r0, r2, r4, JS_OBJECT_TYPE);
-+ __ b(ne, &not_user_equal);
-+
-+ __ CompareObjectType(r1, r3, r4, JS_OBJECT_TYPE);
-+ __ b(ne, &not_user_equal);
-+
-+ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField3Offset));
-+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison));
-+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison));
-+ __ b(eq, &user_equal);
-+
-+ __ ldrb(r3, FieldMemOperand(r3, Map::kBitField3Offset));
-+ __ and_(r3, r3, Operand(1 << Map::kUseUserObjectComparison));
-+ __ cmp(r3, Operand(1 << Map::kUseUserObjectComparison));
-+ __ b(ne, &not_user_equal);
-+
-+ __ bind(&user_equal);
-+
-+ __ Push(r0, r1);
-+ __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1);
-+
-+ __ bind(&not_user_equal);
-+ }
-+
- // Handle the case where the objects are identical. Either returns the answer
- // or goes to slow. Only falls through if the objects were not identical.
- EmitIdenticalObjectComparison(masm, &slow, cc_, never_nan_nan_);
-@@ -5802,10 +5832,18 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
- __ tst(r2, Operand(kSmiTagMask));
- __ b(eq, &miss);
-
-- __ CompareObjectType(r0, r2, r2, JS_OBJECT_TYPE);
-+ __ CompareObjectType(r0, r2, r3, JS_OBJECT_TYPE);
- __ b(ne, &miss);
-- __ CompareObjectType(r1, r2, r2, JS_OBJECT_TYPE);
-+ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField3Offset));
-+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison));
-+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison));
-+ __ b(eq, &miss);
-+ __ CompareObjectType(r1, r2, r3, JS_OBJECT_TYPE);
- __ b(ne, &miss);
-+ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField3Offset));
-+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison));
-+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison));
-+ __ b(eq, &miss);
-
- ASSERT(GetCondition() == eq);
- __ sub(r0, r0, Operand(r1));
-diff --git a/src/factory.cc b/src/factory.cc
-index d530a75..6f8c7de 100644
---- a/src/factory.cc
-+++ b/src/factory.cc
-@@ -998,6 +998,7 @@ Handle<JSFunction> Factory::CreateApiFunction(
-
- int internal_field_count = 0;
- bool has_external_resource = false;
-+ bool use_user_object_comparison = false;
-
- if (!obj->instance_template()->IsUndefined()) {
- Handle<ObjectTemplateInfo> instance_template =
-@@ -1007,6 +1008,8 @@ Handle<JSFunction> Factory::CreateApiFunction(
- Smi::cast(instance_template->internal_field_count())->value();
- has_external_resource =
- !instance_template->has_external_resource()->IsUndefined();
-+ use_user_object_comparison =
-+ !instance_template->use_user_object_comparison()->IsUndefined();
- }
-
- int instance_size = kPointerSize * internal_field_count;
-@@ -1051,6 +1054,11 @@ Handle<JSFunction> Factory::CreateApiFunction(
- map->set_has_external_resource(true);
- }
-
-+ // Mark as using user object comparison if needed
-+ if (use_user_object_comparison) {
-+ map->set_use_user_object_comparison(true);
-+ }
-+
- // Mark as undetectable if needed.
- if (obj->undetectable()) {
- map->set_is_undetectable();
-diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
-index afa599e..0964ab9 100644
---- a/src/ia32/code-stubs-ia32.cc
-+++ b/src/ia32/code-stubs-ia32.cc
-@@ -3447,6 +3447,40 @@ void CompareStub::Generate(MacroAssembler* masm) {
- __ Assert(not_zero, "Unexpected smi operands.");
- }
-
-+ {
-+ NearLabel not_user_equal, user_equal;
-+ __ test(eax, Immediate(kSmiTagMask));
-+ __ j(zero, &not_user_equal);
-+ __ test(edx, Immediate(kSmiTagMask));
-+ __ j(zero, &not_user_equal);
-+
-+ __ CmpObjectType(eax, JS_OBJECT_TYPE, ebx);
-+ __ j(not_equal, &not_user_equal);
-+
-+ __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx);
-+ __ j(not_equal, &not_user_equal);
-+
-+ __ test_b(FieldOperand(ebx, Map::kBitField3Offset),
-+ 1 << Map::kUseUserObjectComparison);
-+ __ j(not_zero, &user_equal);
-+ __ test_b(FieldOperand(ecx, Map::kBitField3Offset),
-+ 1 << Map::kUseUserObjectComparison);
-+ __ j(not_zero, &user_equal);
-+
-+ __ jmp(&not_user_equal);
-+
-+ __ bind(&user_equal);
-+
-+ __ pop(ebx); // Return address.
-+ __ push(eax);
-+ __ push(edx);
-+ __ push(ebx);
-+ __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1);
-+
-+ __ bind(&not_user_equal);
-+ }
-+
-+
- // NOTICE! This code is only reached after a smi-fast-case check, so
- // it is certain that at least one operand isn't a smi.
-
-@@ -5592,8 +5626,14 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
-
- __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx);
- __ j(not_equal, &miss, not_taken);
-+ __ test_b(FieldOperand(ecx, Map::kBitField3Offset),
-+ 1 << Map::kUseUserObjectComparison);
-+ __ j(not_zero, &miss);
- __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx);
- __ j(not_equal, &miss, not_taken);
-+ __ test_b(FieldOperand(ecx, Map::kBitField3Offset),
-+ 1 << Map::kUseUserObjectComparison);
-+ __ j(not_zero, &miss);
-
- ASSERT(GetCondition() == equal);
- __ sub(eax, Operand(edx));
-diff --git a/src/isolate.h b/src/isolate.h
-index 35ffcb4..8130397 100644
---- a/src/isolate.h
-+++ b/src/isolate.h
-@@ -267,6 +267,9 @@ class ThreadLocalTop BASE_EMBEDDED {
- // Call back function to report unsafe JS accesses.
- v8::FailedAccessCheckCallback failed_access_check_callback_;
-
-+ // Call back function for user object comparisons
-+ v8::UserObjectComparisonCallback user_object_comparison_callback_;
-+
- private:
- void InitializeInternal();
-
-@@ -699,6 +702,11 @@ class Isolate {
- void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
- void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
-
-+ void SetUserObjectComparisonCallback(v8::UserObjectComparisonCallback callback);
-+ inline v8::UserObjectComparisonCallback UserObjectComparisonCallback() {
-+ return thread_local_top()->user_object_comparison_callback_;
-+ }
-+
- // Exception throwing support. The caller should use the result
- // of Throw() as its return value.
- Failure* Throw(Object* exception, MessageLocation* location = NULL);
-diff --git a/src/objects-inl.h b/src/objects-inl.h
-index 1c7f83e..1765441 100644
---- a/src/objects-inl.h
-+++ b/src/objects-inl.h
-@@ -2552,6 +2552,19 @@ bool Map::has_external_resource()
- }
-
-
-+void Map::set_use_user_object_comparison(bool value) {
-+ if (value) {
-+ set_bit_field3(bit_field3() | (1 << kUseUserObjectComparison));
-+ } else {
-+ set_bit_field3(bit_field3() & ~(1 << kUseUserObjectComparison));
-+ }
-+}
-+
-+bool Map::use_user_object_comparison() {
-+ return ((1 << kUseUserObjectComparison) & bit_field3()) != 0;
-+}
-+
-+
- void Map::set_named_interceptor_is_fallback(bool value)
- {
- if (value) {
-@@ -3050,6 +3063,8 @@ ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
- kInternalFieldCountOffset)
- ACCESSORS(ObjectTemplateInfo, has_external_resource, Object,
- kHasExternalResourceOffset)
-+ACCESSORS(ObjectTemplateInfo, use_user_object_comparison, Object,
-+ kUseUserObjectComparisonOffset)
-
- ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
- ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
-diff --git a/src/objects.h b/src/objects.h
-index edbc47a..e75e9f1 100644
---- a/src/objects.h
-+++ b/src/objects.h
-@@ -3724,6 +3724,11 @@ class Map: public HeapObject {
- inline void set_has_external_resource(bool value);
- inline bool has_external_resource();
-
-+
-+ // Tells whether the user object comparison callback should be used for
-+ // comparisons involving this object
-+ inline void set_use_user_object_comparison(bool value);
-+ inline bool use_user_object_comparison();
-
- // Whether the named interceptor is a fallback interceptor or not
- inline void set_named_interceptor_is_fallback(bool value);
-@@ -3922,6 +3927,7 @@ class Map: public HeapObject {
- // Bit positions for bit field 3
- static const int kNamedInterceptorIsFallback = 0;
- static const int kHasExternalResource = 1;
-+ static const int kUseUserObjectComparison = 2;
-
- // Layout of the default cache. It holds alternating name and code objects.
- static const int kCodeCacheEntrySize = 2;
-@@ -6442,6 +6448,7 @@ class ObjectTemplateInfo: public TemplateInfo {
- DECL_ACCESSORS(constructor, Object)
- DECL_ACCESSORS(internal_field_count, Object)
- DECL_ACCESSORS(has_external_resource, Object)
-+ DECL_ACCESSORS(use_user_object_comparison, Object)
-
- static inline ObjectTemplateInfo* cast(Object* obj);
-
-@@ -6459,7 +6466,8 @@ class ObjectTemplateInfo: public TemplateInfo {
- static const int kInternalFieldCountOffset =
- kConstructorOffset + kPointerSize;
- static const int kHasExternalResourceOffset = kInternalFieldCountOffset + kPointerSize;
-- static const int kSize = kHasExternalResourceOffset + kPointerSize;
-+ static const int kUseUserObjectComparisonOffset = kHasExternalResourceOffset + kPointerSize;
-+ static const int kSize = kUseUserObjectComparisonOffset + kPointerSize;
- };
-
-
-diff --git a/src/runtime.cc b/src/runtime.cc
-index 827d954..d552ddb 100644
---- a/src/runtime.cc
-+++ b/src/runtime.cc
-@@ -6279,6 +6279,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
- }
-
-
-+RUNTIME_FUNCTION(MaybeObject*, Runtime_UserObjectEquals) {
-+ NoHandleAllocation ha;
-+ ASSERT(args.length() == 2);
-+
-+ CONVERT_CHECKED(JSObject, lhs, args[1]);
-+ CONVERT_CHECKED(JSObject, rhs, args[0]);
-+
-+ bool result;
-+
-+ v8::UserObjectComparisonCallback callback = isolate->UserObjectComparisonCallback();
-+ if (callback) {
-+ HandleScope scope(isolate);
-+ Handle<JSObject> lhs_handle(lhs);
-+ Handle<JSObject> rhs_handle(rhs);
-+ result = callback(v8::Utils::ToLocal(lhs_handle), v8::Utils::ToLocal(rhs_handle));
-+ } else {
-+ result = (lhs == rhs);
-+ }
-+
-+ return Smi::FromInt(result?0:1);
-+}
-+
-+
- RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
- NoHandleAllocation ha;
- ASSERT(args.length() == 3);
-diff --git a/src/runtime.h b/src/runtime.h
-index 5e97173..0d754f9 100644
---- a/src/runtime.h
-+++ b/src/runtime.h
-@@ -146,6 +146,7 @@ namespace internal {
- /* Comparisons */ \
- F(NumberEquals, 2, 1) \
- F(StringEquals, 2, 1) \
-+ F(UserObjectEquals, 2, 1) \
- \
- F(NumberCompare, 3, 1) \
- F(SmiLexicographicCompare, 2, 1) \
-diff --git a/src/top.cc b/src/top.cc
-index e078ee9..c345383 100644
---- a/src/top.cc
-+++ b/src/top.cc
-@@ -68,6 +68,7 @@ void ThreadLocalTop::InitializeInternal() {
- thread_id_ = ThreadId::Invalid();
- external_caught_exception_ = false;
- failed_access_check_callback_ = NULL;
-+ user_object_comparison_callback_ = NULL;
- save_context_ = NULL;
- catcher_ = NULL;
- }
-@@ -387,6 +388,10 @@ void Isolate::SetFailedAccessCheckCallback(
- thread_local_top()->failed_access_check_callback_ = callback;
- }
-
-+void Isolate::SetUserObjectComparisonCallback(
-+ v8::UserObjectComparisonCallback callback) {
-+ thread_local_top()->user_object_comparison_callback_ = callback;
-+}
-
- void Isolate::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) {
- if (!thread_local_top()->failed_access_check_callback_) return;
-diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
-index d923494..10b9b56 100644
---- a/src/x64/code-stubs-x64.cc
-+++ b/src/x64/code-stubs-x64.cc
-@@ -2443,6 +2443,37 @@ void CompareStub::Generate(MacroAssembler* masm) {
- __ bind(&ok);
- }
-
-+ {
-+ NearLabel not_user_equal, user_equal;
-+ __ JumpIfSmi(rax, &not_user_equal);
-+ __ JumpIfSmi(rdx, &not_user_equal);
-+
-+ __ CmpObjectType(rax, JS_OBJECT_TYPE, rbx);
-+ __ j(not_equal, &not_user_equal);
-+
-+ __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx);
-+ __ j(not_equal, &not_user_equal);
-+
-+ __ testb(FieldOperand(rbx, Map::kBitField3Offset),
-+ Immediate(1 << Map::kUseUserObjectComparison));
-+ __ j(not_zero, &user_equal);
-+ __ testb(FieldOperand(rcx, Map::kBitField3Offset),
-+ Immediate(1 << Map::kUseUserObjectComparison));
-+ __ j(not_zero, &user_equal);
-+
-+ __ jmp(&not_user_equal);
-+
-+ __ bind(&user_equal);
-+
-+ __ pop(rbx); // Return address.
-+ __ push(rax);
-+ __ push(rdx);
-+ __ push(rbx);
-+ __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1);
-+
-+ __ bind(&not_user_equal);
-+ }
-+
- // The compare stub returns a positive, negative, or zero 64-bit integer
- // value in rax, corresponding to result of comparing the two inputs.
- // NOTICE! This code is only reached after a smi-fast-case check, so
-@@ -4471,8 +4502,14 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
-
- __ CmpObjectType(rax, JS_OBJECT_TYPE, rcx);
- __ j(not_equal, &miss, not_taken);
-+ __ testb(FieldOperand(rcx, Map::kBitField3Offset),
-+ Immediate(1 << Map::kUseUserObjectComparison));
-+ __ j(not_zero, &miss);
- __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx);
- __ j(not_equal, &miss, not_taken);
-+ __ testb(FieldOperand(rcx, Map::kBitField3Offset),
-+ Immediate(1 << Map::kUseUserObjectComparison));
-+ __ j(not_zero, &miss);
-
- ASSERT(GetCondition() == equal);
- __ subq(rax, rdx);
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch b/src/declarative/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch
deleted file mode 100644
index 89ec7b96bc..0000000000
--- a/src/declarative/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch
+++ /dev/null
@@ -1,286 +0,0 @@
-From 4183b973ed3bd603784c798dfa63ba48f6b68003 Mon Sep 17 00:00:00 2001
-From: ager@chromium.org <ager@chromium.org>
-Date: Wed, 4 May 2011 13:03:08 +0000
-Subject: [PATCH 09/13] Add CallAsFunction method to the Object class in the API
-
-Patch by Peter Varga.
-
-BUG=v8:1336
-TEST=cctest/test-api/CallAsFunction
-
-Review URL: http://codereview.chromium.org/6883045
-
-git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7781 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
----
- include/v8.h | 8 +++
- src/api.cc | 31 +++++++++++
- src/execution.cc | 24 ++++++++
- src/execution.h | 2 +
- test/cctest/test-api.cc | 135 ++++++++++++++++++++++++++++++++++-------------
- 5 files changed, 163 insertions(+), 37 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index d5d6972..8a8e1cd 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -1757,6 +1757,14 @@ class Object : public Value {
- V8EXPORT ExternalArrayType GetIndexedPropertiesExternalArrayDataType();
- V8EXPORT int GetIndexedPropertiesExternalArrayDataLength();
-
-+ /**
-+ * Call an Object as a function if a callback is set by the
-+ * ObjectTemplate::SetCallAsFunctionHandler method.
-+ */
-+ V8EXPORT Local<Value> CallAsFunction(Handle<Object> recv,
-+ int argc,
-+ Handle<Value> argv[]);
-+
- V8EXPORT static Local<Object> New();
- static inline Object* Cast(Value* obj);
- private:
-diff --git a/src/api.cc b/src/api.cc
-index 2436031..e412e51 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -3259,6 +3259,37 @@ int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
- }
-
-
-+Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
-+ v8::Handle<v8::Value> argv[]) {
-+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
-+ return Local<v8::Value>());
-+ LOG_API(isolate, "Object::CallAsFunction");
-+ ENTER_V8(isolate);
-+ HandleScope scope;
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
-+ STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
-+ i::Object*** args = reinterpret_cast<i::Object***>(argv);
-+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
-+ if (obj->IsJSFunction()) {
-+ fun = i::Handle<i::JSFunction>::cast(obj);
-+ } else {
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> delegate =
-+ i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
-+ fun = i::Handle<i::JSFunction>::cast(delegate);
-+ recv_obj = obj;
-+ }
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> returned =
-+ i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
-+ return scope.Close(Utils::ToLocal(returned));
-+}
-+
-+
- Local<v8::Object> Function::NewInstance() const {
- return NewInstance(0, NULL);
- }
-diff --git a/src/execution.cc b/src/execution.cc
-index 1632076..894d741 100644
---- a/src/execution.cc
-+++ b/src/execution.cc
-@@ -254,6 +254,30 @@ Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
- }
-
-
-+Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object,
-+ bool* has_pending_exception) {
-+ ASSERT(!object->IsJSFunction());
-+ Isolate* isolate = Isolate::Current();
-+
-+ // Objects created through the API can have an instance-call handler
-+ // that should be used when calling the object as a function.
-+ if (object->IsHeapObject() &&
-+ HeapObject::cast(*object)->map()->has_instance_call_handler()) {
-+ return Handle<JSFunction>(
-+ isolate->global_context()->call_as_function_delegate());
-+ }
-+
-+ // If the Object doesn't have an instance-call handler we should
-+ // throw a non-callable exception.
-+ i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
-+ "called_non_callable", i::HandleVector<i::Object>(&object, 1));
-+ isolate->Throw(*error_obj);
-+ *has_pending_exception = true;
-+
-+ return isolate->factory()->undefined_value();
-+}
-+
-+
- Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
- ASSERT(!object->IsJSFunction());
- Isolate* isolate = Isolate::Current();
-diff --git a/src/execution.h b/src/execution.h
-index a476eb4..0a0be51 100644
---- a/src/execution.h
-+++ b/src/execution.h
-@@ -144,6 +144,8 @@ class Execution : public AllStatic {
- // Get a function delegate (or undefined) for the given non-function
- // object. Used for support calling objects as functions.
- static Handle<Object> GetFunctionDelegate(Handle<Object> object);
-+ static Handle<Object> TryGetFunctionDelegate(Handle<Object> object,
-+ bool* has_pending_exception);
-
- // Get a function delegate (or undefined) for the given non-function
- // object. Used for support calling objects as constructors.
-diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
-index d7621d1..693d51e 100644
---- a/test/cctest/test-api.cc
-+++ b/test/cctest/test-api.cc
-@@ -6962,50 +6962,111 @@ THREADED_TEST(CallAsFunction) {
- v8::HandleScope scope;
- LocalContext context;
-
-- Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
-- Local<ObjectTemplate> instance_template = t->InstanceTemplate();
-- instance_template->SetCallAsFunctionHandler(call_as_function);
-- Local<v8::Object> instance = t->GetFunction()->NewInstance();
-- context->Global()->Set(v8_str("obj"), instance);
-- v8::TryCatch try_catch;
-- Local<Value> value;
-- CHECK(!try_catch.HasCaught());
-+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
-+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
-+ instance_template->SetCallAsFunctionHandler(call_as_function);
-+ Local<v8::Object> instance = t->GetFunction()->NewInstance();
-+ context->Global()->Set(v8_str("obj"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-
-- value = CompileRun("obj(42)");
-- CHECK(!try_catch.HasCaught());
-- CHECK_EQ(42, value->Int32Value());
-+ value = CompileRun("obj(42)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(42, value->Int32Value());
-
-- value = CompileRun("(function(o){return o(49)})(obj)");
-- CHECK(!try_catch.HasCaught());
-- CHECK_EQ(49, value->Int32Value());
-+ value = CompileRun("(function(o){return o(49)})(obj)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(49, value->Int32Value());
-
-- // test special case of call as function
-- value = CompileRun("[obj]['0'](45)");
-- CHECK(!try_catch.HasCaught());
-- CHECK_EQ(45, value->Int32Value());
-+ // test special case of call as function
-+ value = CompileRun("[obj]['0'](45)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(45, value->Int32Value());
-
-- value = CompileRun("obj.call = Function.prototype.call;"
-- "obj.call(null, 87)");
-- CHECK(!try_catch.HasCaught());
-- CHECK_EQ(87, value->Int32Value());
-+ value = CompileRun("obj.call = Function.prototype.call;"
-+ "obj.call(null, 87)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(87, value->Int32Value());
-
-- // Regression tests for bug #1116356: Calling call through call/apply
-- // must work for non-function receivers.
-- const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])";
-- value = CompileRun(apply_99);
-- CHECK(!try_catch.HasCaught());
-- CHECK_EQ(99, value->Int32Value());
-+ // Regression tests for bug #1116356: Calling call through call/apply
-+ // must work for non-function receivers.
-+ const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])";
-+ value = CompileRun(apply_99);
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(99, value->Int32Value());
-
-- const char* call_17 = "Function.prototype.call.call(obj, this, 17)";
-- value = CompileRun(call_17);
-- CHECK(!try_catch.HasCaught());
-- CHECK_EQ(17, value->Int32Value());
-+ const char* call_17 = "Function.prototype.call.call(obj, this, 17)";
-+ value = CompileRun(call_17);
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(17, value->Int32Value());
-
-- // Check that the call-as-function handler can be called through
-- // new.
-- value = CompileRun("new obj(43)");
-- CHECK(!try_catch.HasCaught());
-- CHECK_EQ(-43, value->Int32Value());
-+ // Check that the call-as-function handler can be called through
-+ // new.
-+ value = CompileRun("new obj(43)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(-43, value->Int32Value());
-+
-+ // Check that the call-as-function handler can be called through
-+ // the API.
-+ v8::Handle<Value> args[] = { v8_num(28) };
-+ value = instance->CallAsFunction(instance, 1, args);
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(28, value->Int32Value());
-+ }
-+
-+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
-+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
-+ Local<v8::Object> instance = t->GetFunction()->NewInstance();
-+ context->Global()->Set(v8_str("obj2"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ // Call an object without call-as-function handler through the JS
-+ value = CompileRun("obj2(28)");
-+ CHECK(value.IsEmpty());
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value1(try_catch.Exception());
-+ CHECK_EQ(*exception_value1,
-+ "TypeError: Property 'obj2' of object "
-+ "#<Object> is not a function");
-+ try_catch.Reset();
-+
-+ // Call an object without call-as-function handler through the API
-+ value = CompileRun("obj2(28)");
-+ v8::Handle<Value> args[] = { v8_num(28) };
-+ value = instance->CallAsFunction(instance, 1, args);
-+ CHECK(value.IsEmpty());
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value2(try_catch.Exception());
-+ CHECK_EQ(*exception_value2, "TypeError: [object Object] is not a function");
-+ try_catch.Reset();
-+ }
-+
-+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
-+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
-+ instance_template->SetCallAsFunctionHandler(ThrowValue);
-+ Local<v8::Object> instance = t->GetFunction()->NewInstance();
-+ context->Global()->Set(v8_str("obj3"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ // Catch the exception which is thrown by call-as-function handler
-+ value = CompileRun("obj3(22)");
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value1(try_catch.Exception());
-+ CHECK_EQ(*exception_value1, "22");
-+ try_catch.Reset();
-+
-+ v8::Handle<Value> args[] = { v8_num(23) };
-+ value = instance->CallAsFunction(instance, 1, args);
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value2(try_catch.Exception());
-+ CHECK_EQ(*exception_value2, "23");
-+ try_catch.Reset();
-+ }
- }
-
-
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch b/src/declarative/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch
deleted file mode 100644
index 09c2d4af1a..0000000000
--- a/src/declarative/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch
+++ /dev/null
@@ -1,397 +0,0 @@
-From 3d6d4249878f7960eac4c9c94e0f2529f9a58c4a Mon Sep 17 00:00:00 2001
-From: ager@chromium.org <ager@chromium.org>
-Date: Fri, 6 May 2011 11:07:52 +0000
-Subject: [PATCH 10/13] Implement CallAsConstructor method for Object in the API
-
-Patch by Peter Varga.
-
-BUG=v8:1348
-TEST=cctest/test-api/ConstructorForObject
-
-Review URL: http://codereview.chromium.org/6902108
-
-git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7803 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
----
- include/v8.h | 8 ++
- src/api.cc | 41 +++++++++-
- src/execution.cc | 28 +++++++
- src/execution.h | 2 +
- test/cctest/test-api.cc | 205 +++++++++++++++++++++++++++++++++++++++++++++--
- 5 files changed, 276 insertions(+), 8 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 8a8e1cd..84462b5 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -1765,6 +1765,14 @@ class Object : public Value {
- int argc,
- Handle<Value> argv[]);
-
-+ /**
-+ * Call an Object as a consturctor if a callback is set by the
-+ * ObjectTemplate::SetCallAsFunctionHandler method.
-+ * Note: This method behaves like the Function::NewInstance method.
-+ */
-+ V8EXPORT Local<Value> CallAsConstructor(int argc,
-+ Handle<Value> argv[]);
-+
- V8EXPORT static Local<Object> New();
- static inline Object* Cast(Value* obj);
- private:
-diff --git a/src/api.cc b/src/api.cc
-index e412e51..1a585d6 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -3266,7 +3266,7 @@ Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
- return Local<v8::Value>());
- LOG_API(isolate, "Object::CallAsFunction");
- ENTER_V8(isolate);
-- HandleScope scope;
-+ i::HandleScope scope(isolate);
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
- i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
- STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
-@@ -3286,7 +3286,44 @@ Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
- i::Handle<i::Object> returned =
- i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
-- return scope.Close(Utils::ToLocal(returned));
-+ return Utils::ToLocal(scope.CloseAndEscape(returned));
-+}
-+
-+
-+Local<v8::Value> Object::CallAsConstructor(int argc,
-+ v8::Handle<v8::Value> argv[]) {
-+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
-+ return Local<v8::Object>());
-+ LOG_API(isolate, "Object::CallAsConstructor");
-+ ENTER_V8(isolate);
-+ i::HandleScope scope(isolate);
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
-+ i::Object*** args = reinterpret_cast<i::Object***>(argv);
-+ if (obj->IsJSFunction()) {
-+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> returned =
-+ i::Execution::New(fun, argc, args, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
-+ return Utils::ToLocal(scope.CloseAndEscape(
-+ i::Handle<i::JSObject>::cast(returned)));
-+ }
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> delegate =
-+ i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
-+ if (!delegate->IsUndefined()) {
-+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> returned =
-+ i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
-+ ASSERT(!delegate->IsUndefined());
-+ return Utils::ToLocal(scope.CloseAndEscape(returned));
-+ }
-+ return Local<v8::Object>();
- }
-
-
-diff --git a/src/execution.cc b/src/execution.cc
-index 894d741..afb352c 100644
---- a/src/execution.cc
-+++ b/src/execution.cc
-@@ -297,6 +297,34 @@ Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
- }
-
-
-+Handle<Object> Execution::TryGetConstructorDelegate(
-+ Handle<Object> object,
-+ bool* has_pending_exception) {
-+ ASSERT(!object->IsJSFunction());
-+ Isolate* isolate = Isolate::Current();
-+
-+ // If you return a function from here, it will be called when an
-+ // attempt is made to call the given object as a constructor.
-+
-+ // Objects created through the API can have an instance-call handler
-+ // that should be used when calling the object as a function.
-+ if (object->IsHeapObject() &&
-+ HeapObject::cast(*object)->map()->has_instance_call_handler()) {
-+ return Handle<JSFunction>(
-+ isolate->global_context()->call_as_constructor_delegate());
-+ }
-+
-+ // If the Object doesn't have an instance-call handler we should
-+ // throw a non-callable exception.
-+ i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
-+ "called_non_callable", i::HandleVector<i::Object>(&object, 1));
-+ isolate->Throw(*error_obj);
-+ *has_pending_exception = true;
-+
-+ return isolate->factory()->undefined_value();
-+}
-+
-+
- bool StackGuard::IsStackOverflow() {
- ExecutionAccess access(isolate_);
- return (thread_local_.jslimit_ != kInterruptLimit &&
-diff --git a/src/execution.h b/src/execution.h
-index 0a0be51..ec2a195 100644
---- a/src/execution.h
-+++ b/src/execution.h
-@@ -150,6 +150,8 @@ class Execution : public AllStatic {
- // Get a function delegate (or undefined) for the given non-function
- // object. Used for support calling objects as constructors.
- static Handle<Object> GetConstructorDelegate(Handle<Object> object);
-+ static Handle<Object> TryGetConstructorDelegate(Handle<Object> object,
-+ bool* has_pending_exception);
- };
-
-
-diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
-index 693d51e..1334f63 100644
---- a/test/cctest/test-api.cc
-+++ b/test/cctest/test-api.cc
-@@ -6746,6 +6746,200 @@ THREADED_TEST(Constructor) {
- CHECK(value->BooleanValue());
- }
-
-+
-+static Handle<Value> ConstructorCallback(const Arguments& args) {
-+ ApiTestFuzzer::Fuzz();
-+ Local<Object> This;
-+
-+ if (args.IsConstructCall()) {
-+ Local<Object> Holder = args.Holder();
-+ This = Object::New();
-+ Local<Value> proto = Holder->GetPrototype();
-+ if (proto->IsObject()) {
-+ This->SetPrototype(proto);
-+ }
-+ } else {
-+ This = args.This();
-+ }
-+
-+ This->Set(v8_str("a"), args[0]);
-+ return This;
-+}
-+
-+
-+static Handle<Value> FakeConstructorCallback(const Arguments& args) {
-+ ApiTestFuzzer::Fuzz();
-+ return args[0];
-+}
-+
-+
-+THREADED_TEST(ConstructorForObject) {
-+ v8::HandleScope handle_scope;
-+ LocalContext context;
-+
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ instance_template->SetCallAsFunctionHandler(ConstructorCallback);
-+ Local<Object> instance = instance_template->NewInstance();
-+ context->Global()->Set(v8_str("obj"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ // Call the Object's constructor with a 32-bit signed integer.
-+ value = CompileRun("(function() { var o = new obj(28); return o.a; })()");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsInt32());
-+ CHECK_EQ(28, value->Int32Value());
-+
-+ Local<Value> args1[] = { v8_num(28) };
-+ Local<Value> value_obj1 = instance->CallAsConstructor(1, args1);
-+ CHECK(value_obj1->IsObject());
-+ Local<Object> object1 = Local<Object>::Cast(value_obj1);
-+ value = object1->Get(v8_str("a"));
-+ CHECK(value->IsInt32());
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(28, value->Int32Value());
-+
-+ // Call the Object's constructor with a String.
-+ value = CompileRun(
-+ "(function() { var o = new obj('tipli'); return o.a; })()");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsString());
-+ String::AsciiValue string_value1(value->ToString());
-+ CHECK_EQ("tipli", *string_value1);
-+
-+ Local<Value> args2[] = { v8_str("tipli") };
-+ Local<Value> value_obj2 = instance->CallAsConstructor(1, args2);
-+ CHECK(value_obj2->IsObject());
-+ Local<Object> object2 = Local<Object>::Cast(value_obj2);
-+ value = object2->Get(v8_str("a"));
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsString());
-+ String::AsciiValue string_value2(value->ToString());
-+ CHECK_EQ("tipli", *string_value2);
-+
-+ // Call the Object's constructor with a Boolean.
-+ value = CompileRun("(function() { var o = new obj(true); return o.a; })()");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsBoolean());
-+ CHECK_EQ(true, value->BooleanValue());
-+
-+ Handle<Value> args3[] = { v8::Boolean::New(true) };
-+ Local<Value> value_obj3 = instance->CallAsConstructor(1, args3);
-+ CHECK(value_obj3->IsObject());
-+ Local<Object> object3 = Local<Object>::Cast(value_obj3);
-+ value = object3->Get(v8_str("a"));
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsBoolean());
-+ CHECK_EQ(true, value->BooleanValue());
-+
-+ // Call the Object's constructor with undefined.
-+ Handle<Value> args4[] = { v8::Undefined() };
-+ Local<Value> value_obj4 = instance->CallAsConstructor(1, args4);
-+ CHECK(value_obj4->IsObject());
-+ Local<Object> object4 = Local<Object>::Cast(value_obj4);
-+ value = object4->Get(v8_str("a"));
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsUndefined());
-+
-+ // Call the Object's constructor with null.
-+ Handle<Value> args5[] = { v8::Null() };
-+ Local<Value> value_obj5 = instance->CallAsConstructor(1, args5);
-+ CHECK(value_obj5->IsObject());
-+ Local<Object> object5 = Local<Object>::Cast(value_obj5);
-+ value = object5->Get(v8_str("a"));
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsNull());
-+ }
-+
-+ // Check exception handling when there is no constructor set for the Object.
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ Local<Object> instance = instance_template->NewInstance();
-+ context->Global()->Set(v8_str("obj2"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ value = CompileRun("new obj2(28)");
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value1(try_catch.Exception());
-+ CHECK_EQ("TypeError: object is not a function", *exception_value1);
-+ try_catch.Reset();
-+
-+ Local<Value> args[] = { v8_num(29) };
-+ value = instance->CallAsConstructor(1, args);
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value2(try_catch.Exception());
-+ CHECK_EQ("TypeError: #<Object> is not a function", *exception_value2);
-+ try_catch.Reset();
-+ }
-+
-+ // Check the case when constructor throws exception.
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ instance_template->SetCallAsFunctionHandler(ThrowValue);
-+ Local<Object> instance = instance_template->NewInstance();
-+ context->Global()->Set(v8_str("obj3"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ value = CompileRun("new obj3(22)");
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value1(try_catch.Exception());
-+ CHECK_EQ("22", *exception_value1);
-+ try_catch.Reset();
-+
-+ Local<Value> args[] = { v8_num(23) };
-+ value = instance->CallAsConstructor(1, args);
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value2(try_catch.Exception());
-+ CHECK_EQ("23", *exception_value2);
-+ try_catch.Reset();
-+ }
-+
-+ // Check whether constructor returns with an object or non-object.
-+ { Local<FunctionTemplate> function_template =
-+ FunctionTemplate::New(FakeConstructorCallback);
-+ Local<Function> function = function_template->GetFunction();
-+ Local<Object> instance1 = function;
-+ context->Global()->Set(v8_str("obj4"), instance1);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ CHECK(instance1->IsObject());
-+ CHECK(instance1->IsFunction());
-+
-+ value = CompileRun("new obj4(28)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsObject());
-+
-+ Local<Value> args1[] = { v8_num(28) };
-+ value = instance1->CallAsConstructor(1, args1);
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsObject());
-+
-+ Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ instance_template->SetCallAsFunctionHandler(FakeConstructorCallback);
-+ Local<Object> instance2 = instance_template->NewInstance();
-+ context->Global()->Set(v8_str("obj5"), instance2);
-+ CHECK(!try_catch.HasCaught());
-+
-+ CHECK(instance2->IsObject());
-+ CHECK(!instance2->IsFunction());
-+
-+ value = CompileRun("new obj5(28)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(!value->IsObject());
-+
-+ Local<Value> args2[] = { v8_num(28) };
-+ value = instance2->CallAsConstructor(1, args2);
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(!value->IsObject());
-+ }
-+}
-+
-+
- THREADED_TEST(FunctionDescriptorException) {
- v8::HandleScope handle_scope;
- LocalContext context;
-@@ -7028,9 +7222,8 @@ THREADED_TEST(CallAsFunction) {
- CHECK(value.IsEmpty());
- CHECK(try_catch.HasCaught());
- String::AsciiValue exception_value1(try_catch.Exception());
-- CHECK_EQ(*exception_value1,
-- "TypeError: Property 'obj2' of object "
-- "#<Object> is not a function");
-+ CHECK_EQ("TypeError: Property 'obj2' of object #<Object> is not a function",
-+ *exception_value1);
- try_catch.Reset();
-
- // Call an object without call-as-function handler through the API
-@@ -7040,7 +7233,7 @@ THREADED_TEST(CallAsFunction) {
- CHECK(value.IsEmpty());
- CHECK(try_catch.HasCaught());
- String::AsciiValue exception_value2(try_catch.Exception());
-- CHECK_EQ(*exception_value2, "TypeError: [object Object] is not a function");
-+ CHECK_EQ("TypeError: [object Object] is not a function", *exception_value2);
- try_catch.Reset();
- }
-
-@@ -7057,14 +7250,14 @@ THREADED_TEST(CallAsFunction) {
- value = CompileRun("obj3(22)");
- CHECK(try_catch.HasCaught());
- String::AsciiValue exception_value1(try_catch.Exception());
-- CHECK_EQ(*exception_value1, "22");
-+ CHECK_EQ("22", *exception_value1);
- try_catch.Reset();
-
- v8::Handle<Value> args[] = { v8_num(23) };
- value = instance->CallAsFunction(instance, 1, args);
- CHECK(try_catch.HasCaught());
- String::AsciiValue exception_value2(try_catch.Exception());
-- CHECK_EQ(*exception_value2, "23");
-+ CHECK_EQ("23", *exception_value2);
- try_catch.Reset();
- }
- }
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch b/src/declarative/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch
deleted file mode 100644
index f4a15bf97a..0000000000
--- a/src/declarative/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From f22d0312faeb93ced8747d9aae8c6d77e11b4aba Mon Sep 17 00:00:00 2001
-From: Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
-Date: Tue, 7 Dec 2010 11:56:42 +0100
-Subject: [PATCH 11/13] QtScript/V8: Add new v8 api to check if a value is an error.
-
-New function v8::Value::IsError was created.
-
-This API is experimental and added only for the purposes of our
-research.
----
- include/v8.h | 5 +++++
- src/api.cc | 6 ++++++
- src/heap.h | 1 +
- 3 files changed, 12 insertions(+), 0 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 84462b5..08b0ec2 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -937,6 +937,11 @@ class Value : public Data {
- */
- V8EXPORT bool IsRegExp() const;
-
-+ /**
-+ * Returns true if this value is an Error.
-+ */
-+ V8EXPORT bool IsError() const;
-+
- V8EXPORT Local<Boolean> ToBoolean() const;
- V8EXPORT Local<Number> ToNumber() const;
- V8EXPORT Local<String> ToString() const;
-diff --git a/src/api.cc b/src/api.cc
-index 1a585d6..bd435eb 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -2108,6 +2108,12 @@ bool Value::IsRegExp() const {
- return obj->IsJSRegExp();
- }
-
-+bool Value::IsError() const {
-+ if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsError()")) return false;
-+ i::Handle<i::Object> obj = Utils::OpenHandle(this);
-+ return obj->HasSpecificClassOf(HEAP->Error_symbol());
-+}
-+
-
- Local<String> Value::ToString() const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
-diff --git a/src/heap.h b/src/heap.h
-index 8cbf378..db90bb9 100644
---- a/src/heap.h
-+++ b/src/heap.h
-@@ -169,6 +169,7 @@ inline Heap* _inline_get_heap_();
- V(string_symbol, "string") \
- V(String_symbol, "String") \
- V(Date_symbol, "Date") \
-+ V(Error_symbol, "Error") \
- V(this_symbol, "this") \
- V(to_string_symbol, "toString") \
- V(char_at_symbol, "CharAt") \
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch b/src/declarative/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch
deleted file mode 100644
index e4c46b0cbf..0000000000
--- a/src/declarative/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 472c04c9e7a64e8734c76d2cf97a7cc5b773b788 Mon Sep 17 00:00:00 2001
-From: ager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
-Date: Mon, 9 May 2011 15:24:48 +0000
-Subject: [PATCH 12/13] Add IsCallable method for Object in the API
-
-Patch by Peter Varga.
-
-BUG=none
-TEST=cctest/test-api/CallableObject
-
-Review URL: http://codereview.chromium.org/6964005
-
-git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7828 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
----
- include/v8.h | 7 +++++++
- src/api.cc | 11 +++++++++++
- test/cctest/test-api.cc | 43 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 61 insertions(+), 0 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 08b0ec2..4194d4a 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -1763,6 +1763,13 @@ class Object : public Value {
- V8EXPORT int GetIndexedPropertiesExternalArrayDataLength();
-
- /**
-+ * Checks whether a callback is set by the
-+ * ObjectTemplate::SetCallAsFunctionHandler method.
-+ * When an Object is callable this method returns true.
-+ */
-+ V8EXPORT bool IsCallable();
-+
-+ /**
- * Call an Object as a function if a callback is set by the
- * ObjectTemplate::SetCallAsFunctionHandler method.
- */
-diff --git a/src/api.cc b/src/api.cc
-index bd435eb..a5a637f 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -3265,6 +3265,17 @@ int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
- }
-
-
-+bool v8::Object::IsCallable() {
-+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
-+ ENTER_V8(isolate);
-+ i::HandleScope scope(isolate);
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ if (obj->IsJSFunction()) return true;
-+ return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
-+}
-+
-+
- Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
- v8::Handle<v8::Value> argv[]) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
-index 1334f63..45db5a1 100644
---- a/test/cctest/test-api.cc
-+++ b/test/cctest/test-api.cc
-@@ -7263,6 +7263,49 @@ THREADED_TEST(CallAsFunction) {
- }
-
-
-+// Check whether a non-function object is callable.
-+THREADED_TEST(CallableObject) {
-+ v8::HandleScope scope;
-+ LocalContext context;
-+
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ instance_template->SetCallAsFunctionHandler(call_as_function);
-+ Local<Object> instance = instance_template->NewInstance();
-+ v8::TryCatch try_catch;
-+
-+ CHECK(instance->IsCallable());
-+ CHECK(!try_catch.HasCaught());
-+ }
-+
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ Local<Object> instance = instance_template->NewInstance();
-+ v8::TryCatch try_catch;
-+
-+ CHECK(!instance->IsCallable());
-+ CHECK(!try_catch.HasCaught());
-+ }
-+
-+ { Local<FunctionTemplate> function_template =
-+ FunctionTemplate::New(call_as_function);
-+ Local<Function> function = function_template->GetFunction();
-+ Local<Object> instance = function;
-+ v8::TryCatch try_catch;
-+
-+ CHECK(instance->IsCallable());
-+ CHECK(!try_catch.HasCaught());
-+ }
-+
-+ { Local<FunctionTemplate> function_template = FunctionTemplate::New();
-+ Local<Function> function = function_template->GetFunction();
-+ Local<Object> instance = function;
-+ v8::TryCatch try_catch;
-+
-+ CHECK(instance->IsCallable());
-+ CHECK(!try_catch.HasCaught());
-+ }
-+}
-+
-+
- static int CountHandles() {
- return v8::HandleScope::NumberOfHandles();
- }
---
-1.7.2.3
-
diff --git a/src/declarative/v8/0013-Remove-execute-flag-from-v8-debug.h.patch b/src/declarative/v8/0013-Remove-execute-flag-from-v8-debug.h.patch
deleted file mode 100644
index 0a769921cd..0000000000
--- a/src/declarative/v8/0013-Remove-execute-flag-from-v8-debug.h.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-From dc2cad4f8fc88c52fcea09b8d0262d35cd32dc44 Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Thu, 25 Aug 2011 11:09:58 +1000
-Subject: [PATCH 13/13] Remove execute flag from v8-debug.h
-
----
- 0 files changed, 0 insertions(+), 0 deletions(-)
- mode change 100755 => 100644 include/v8-debug.h
-
-diff --git a/include/v8-debug.h b/include/v8-debug.h
-old mode 100755
-new mode 100644
---
-1.7.2.3
-
diff --git a/src/declarative/v8/README b/src/declarative/v8/README
deleted file mode 100644
index 2dc39705aa..0000000000
--- a/src/declarative/v8/README
+++ /dev/null
@@ -1 +0,0 @@
-These patches apply cleanly against v8 at 2eaa4b29586fdbd5d41f7b7d9e72ecca6d53dbd2
diff --git a/src/declarative/v8/v8.pri b/src/declarative/v8/v8.pri
deleted file mode 100644
index c526fccbe6..0000000000
--- a/src/declarative/v8/v8.pri
+++ /dev/null
@@ -1,253 +0,0 @@
-equals(QT_ARCH, x86_64)|contains(CONFIG, x86_64):CONFIG += arch_x86_64
-else:equals(QT_ARCH, "i386"):CONFIG += arch_i386
-else:equals(QT_ARCH, "arm"):CONFIG += arch_arm
-
-include($$PWD/v8base.pri)
-
-V8_GENERATED_SOURCES_DIR = generated
-
-DEFINES += V8_SHARED BUILDING_V8_SHARED
-
-# this maybe removed in future
-DEFINES += ENABLE_DEBUGGER_SUPPORT
-
-# this is needed by crankshaft ( http://code.google.com/p/v8/issues/detail?id=1271 )
-DEFINES += ENABLE_VMSTATE_TRACKING ENABLE_LOGGING_AND_PROFILING
-
-CONFIG(debug, debug|release) {
- DEFINES += DEBUG V8_ENABLE_CHECKS OBJECT_PRINT ENABLE_DISASSEMBLER
-} else {
- DEFINES += NDEBUG
-}
-
-INCLUDEPATH += \
- $$V8DIR/src
-
-# $$V8DIR/include
-
-V8SOURCES = \
- $$V8DIR/src/accessors.cc \
- $$V8DIR/src/allocation.cc \
- $$V8DIR/src/api.cc \
- $$V8DIR/src/assembler.cc \
- $$V8DIR/src/ast.cc \
- $$V8DIR/src/atomicops_internals_x86_gcc.cc \
- $$V8DIR/src/bignum.cc \
- $$V8DIR/src/bignum-dtoa.cc \
- $$V8DIR/src/bootstrapper.cc \
- $$V8DIR/src/builtins.cc \
- $$V8DIR/src/cached-powers.cc \
- $$V8DIR/src/checks.cc \
- $$V8DIR/src/circular-queue.cc \
- $$V8DIR/src/code-stubs.cc \
- $$V8DIR/src/codegen.cc \
- $$V8DIR/src/compilation-cache.cc \
- $$V8DIR/src/compiler.cc \
- $$V8DIR/src/contexts.cc \
- $$V8DIR/src/conversions.cc \
- $$V8DIR/src/counters.cc \
- $$V8DIR/src/cpu-profiler.cc \
- $$V8DIR/src/data-flow.cc \
- $$V8DIR/src/dateparser.cc \
- $$V8DIR/src/debug-agent.cc \
- $$V8DIR/src/debug.cc \
- $$V8DIR/src/deoptimizer.cc \
- $$V8DIR/src/disassembler.cc \
- $$V8DIR/src/diy-fp.cc \
- $$V8DIR/src/dtoa.cc \
- $$V8DIR/src/execution.cc \
- $$V8DIR/src/factory.cc \
- $$V8DIR/src/flags.cc \
- $$V8DIR/src/frame-element.cc \
- $$V8DIR/src/frames.cc \
- $$V8DIR/src/full-codegen.cc \
- $$V8DIR/src/func-name-inferrer.cc \
- $$V8DIR/src/gdb-jit.cc \
- $$V8DIR/src/global-handles.cc \
- $$V8DIR/src/fast-dtoa.cc \
- $$V8DIR/src/fixed-dtoa.cc \
- $$V8DIR/src/handles.cc \
- $$V8DIR/src/hashmap.cc \
- $$V8DIR/src/heap-profiler.cc \
- $$V8DIR/src/heap.cc \
- $$V8DIR/src/hydrogen.cc \
- $$V8DIR/src/hydrogen-instructions.cc \
- $$V8DIR/src/ic.cc \
- $$V8DIR/src/inspector.cc \
- $$V8DIR/src/interpreter-irregexp.cc \
- $$V8DIR/src/isolate.cc \
- $$V8DIR/src/jsregexp.cc \
- $$V8DIR/src/lithium-allocator.cc \
- $$V8DIR/src/lithium.cc \
- $$V8DIR/src/liveedit.cc \
- $$V8DIR/src/liveobjectlist.cc \
- $$V8DIR/src/log-utils.cc \
- $$V8DIR/src/log.cc \
- $$V8DIR/src/mark-compact.cc \
- $$V8DIR/src/messages.cc \
- $$V8DIR/src/objects.cc \
- $$V8DIR/src/objects-printer.cc \
- $$V8DIR/src/objects-visiting.cc \
- $$V8DIR/src/parser.cc \
- $$V8DIR/src/preparser.cc \
- $$V8DIR/src/preparse-data.cc \
- $$V8DIR/src/profile-generator.cc \
- $$V8DIR/src/property.cc \
- $$V8DIR/src/regexp-macro-assembler-irregexp.cc \
- $$V8DIR/src/regexp-macro-assembler.cc \
- $$V8DIR/src/regexp-stack.cc \
- $$V8DIR/src/rewriter.cc \
- $$V8DIR/src/runtime.cc \
- $$V8DIR/src/runtime-profiler.cc \
- $$V8DIR/src/safepoint-table.cc \
- $$V8DIR/src/scanner-base.cc \
- $$V8DIR/src/scanner.cc \
- $$V8DIR/src/scopeinfo.cc \
- $$V8DIR/src/scopes.cc \
- $$V8DIR/src/serialize.cc \
- $$V8DIR/src/snapshot-common.cc \
- $$V8DIR/src/spaces.cc \
- $$V8DIR/src/string-search.cc \
- $$V8DIR/src/string-stream.cc \
- $$V8DIR/src/strtod.cc \
- $$V8DIR/src/stub-cache.cc \
- $$V8DIR/src/token.cc \
- $$V8DIR/src/top.cc \
- $$V8DIR/src/type-info.cc \
- $$V8DIR/src/unicode.cc \
- $$V8DIR/src/utils.cc \
- $$V8DIR/src/v8-counters.cc \
- $$V8DIR/src/v8.cc \
- $$V8DIR/src/v8threads.cc \
- $$V8DIR/src/variables.cc \
- $$V8DIR/src/version.cc \
- $$V8DIR/src/zone.cc \
- $$V8DIR/src/extensions/gc-extension.cc \
- $$V8DIR/src/extensions/externalize-string-extension.cc
-
-V8SOURCES += \
- $$V8DIR/src/snapshot-empty.cc \
-
-arch_arm {
-DEFINES += V8_TARGET_ARCH_ARM
-V8SOURCES += \
- $$V8DIR/src/arm/builtins-arm.cc \
- $$V8DIR/src/arm/code-stubs-arm.cc \
- $$V8DIR/src/arm/codegen-arm.cc \
- $$V8DIR/src/arm/constants-arm.cc \
- $$V8DIR/src/arm/cpu-arm.cc \
- $$V8DIR/src/arm/debug-arm.cc \
- $$V8DIR/src/arm/deoptimizer-arm.cc \
- $$V8DIR/src/arm/disasm-arm.cc \
- $$V8DIR/src/arm/frames-arm.cc \
- $$V8DIR/src/arm/full-codegen-arm.cc \
- $$V8DIR/src/arm/ic-arm.cc \
- $$V8DIR/src/arm/lithium-arm.cc \
- $$V8DIR/src/arm/lithium-codegen-arm.cc \
- $$V8DIR/src/arm/lithium-gap-resolver-arm.cc \
- $$V8DIR/src/arm/macro-assembler-arm.cc \
- $$V8DIR/src/arm/regexp-macro-assembler-arm.cc \
- $$V8DIR/src/arm/stub-cache-arm.cc \
- $$V8DIR/src/arm/assembler-arm.cc
-}
-
-arch_i386 {
-DEFINES += V8_TARGET_ARCH_IA32
-V8SOURCES += \
- $$V8DIR/src/ia32/assembler-ia32.cc \
- $$V8DIR/src/ia32/builtins-ia32.cc \
- $$V8DIR/src/ia32/code-stubs-ia32.cc \
- $$V8DIR/src/ia32/codegen-ia32.cc \
- $$V8DIR/src/ia32/cpu-ia32.cc \
- $$V8DIR/src/ia32/debug-ia32.cc \
- $$V8DIR/src/ia32/deoptimizer-ia32.cc \
- $$V8DIR/src/ia32/disasm-ia32.cc \
- $$V8DIR/src/ia32/frames-ia32.cc \
- $$V8DIR/src/ia32/full-codegen-ia32.cc \
- $$V8DIR/src/ia32/ic-ia32.cc \
- $$V8DIR/src/ia32/lithium-codegen-ia32.cc \
- $$V8DIR/src/ia32/lithium-gap-resolver-ia32.cc \
- $$V8DIR/src/ia32/lithium-ia32.cc \
- $$V8DIR/src/ia32/macro-assembler-ia32.cc \
- $$V8DIR/src/ia32/regexp-macro-assembler-ia32.cc \
- $$V8DIR/src/ia32/stub-cache-ia32.cc
-}
-
-# FIXME Should we use QT_CONFIG instead? What about 32 bit Macs?
-arch_x86_64 {
-DEFINES += V8_TARGET_ARCH_X64
-V8SOURCES += \
- $$V8DIR/src/x64/assembler-x64.cc \
- $$V8DIR/src/x64/builtins-x64.cc \
- $$V8DIR/src/x64/code-stubs-x64.cc \
- $$V8DIR/src/x64/codegen-x64.cc \
- $$V8DIR/src/x64/cpu-x64.cc \
- $$V8DIR/src/x64/debug-x64.cc \
- $$V8DIR/src/x64/deoptimizer-x64.cc \
- $$V8DIR/src/x64/disasm-x64.cc \
- $$V8DIR/src/x64/frames-x64.cc \
- $$V8DIR/src/x64/full-codegen-x64.cc \
- $$V8DIR/src/x64/ic-x64.cc \
- $$V8DIR/src/x64/lithium-codegen-x64.cc \
- $$V8DIR/src/x64/lithium-gap-resolver-x64.cc \
- $$V8DIR/src/x64/lithium-x64.cc \
- $$V8DIR/src/x64/macro-assembler-x64.cc \
- $$V8DIR/src/x64/regexp-macro-assembler-x64.cc \
- $$V8DIR/src/x64/stub-cache-x64.cc
-}
-
-unix:!symbian:!macx {
-V8SOURCES += \
- $$V8DIR/src/platform-linux.cc \
- $$V8DIR/src/platform-posix.cc
-}
-
-#os:macos
-macx {
-V8SOURCES += \
- $$V8DIR/src/platform-macos.cc \
- $$V8DIR/src/platform-posix.cc
-}
-
-win32 {
-V8SOURCES += \
- $$V8DIR/src/platform-win32.cc
-}
-
-#mode:debug
-CONFIG(debug) {
- V8SOURCES += \
- $$V8DIR/src/objects-debug.cc \
- $$V8DIR/src/prettyprinter.cc \
- $$V8DIR/src/regexp-macro-assembler-tracer.cc
-}
-
-V8_LIBRARY_FILES = \
- $$V8DIR/src/runtime.js \
- $$V8DIR/src/v8natives.js \
- $$V8DIR/src/array.js \
- $$V8DIR/src/string.js \
- $$V8DIR/src/uri.js \
- $$V8DIR/src/math.js \
- $$V8DIR/src/messages.js \
- $$V8DIR/src/apinatives.js \
- $$V8DIR/src/date.js \
- $$V8DIR/src/regexp.js \
- $$V8DIR/src/json.js \
- $$V8DIR/src/liveedit-debugger.js \
- $$V8DIR/src/mirror-debugger.js \
- $$V8DIR/src/debug-debugger.js
-
-SOURCES += $$V8SOURCES
-
-v8_js2c.commands = python $$V8DIR/tools/js2c.py $$V8_GENERATED_SOURCES_DIR/libraries.cpp $$V8_GENERATED_SOURCES_DIR/libraries-empty.cpp CORE
-v8_js2c.commands += $$V8DIR/src/macros.py ${QMAKE_FILE_IN}
-v8_js2c.output = $$V8_GENERATED_SOURCES_DIR/libraries.cpp
-v8_js2c.input = V8_LIBRARY_FILES
-v8_js2c.variable_out = SOURCES
-v8_js2c.dependency_type = TYPE_C
-v8_js2c.depends = $$V8DIR/tools/js2c.py $$V8DIR/src/macros.py
-v8_js2c.CONFIG += combine
-v8_js2c.name = generating[v8] ${QMAKE_FILE_IN}
-silent:v8_js2c.commands = @echo generating[v8] ${QMAKE_FILE_IN} && $$v8_js2c.commands
-QMAKE_EXTRA_COMPILERS += v8_js2c
diff --git a/src/declarative/v8/v8base.pri b/src/declarative/v8/v8base.pri
deleted file mode 100644
index 9cea5cf575..0000000000
--- a/src/declarative/v8/v8base.pri
+++ /dev/null
@@ -1,19 +0,0 @@
-V8DIR = $$(V8DIR)
-isEmpty(V8DIR) {
- V8DIR = $$PWD/../../3rdparty/v8
-} else {
- message(using external V8 from $$V8DIR)
-}
-
-*-g++*: {
- QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter
- QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
-
- # mksnapshot hangs if gcc 4.5 is used
- # for reference look at http://code.google.com/p/v8/issues/detail?id=884
- equals(QT_GCC_MAJOR_VERSION, 4): equals(QT_GCC_MINOR_VERSION, 5) {
- message(because of a bug in gcc / v8 we need to add -fno-strict-aliasing)
- QMAKE_CFLAGS += -fno-strict-aliasing
- QMAKE_CXXFLAGS += -fno-strict-aliasing
- }
-}
diff --git a/src/declarative/v8/wrapcc.pl b/src/declarative/v8/wrapcc.pl
deleted file mode 100755
index 27f5f867b0..0000000000
--- a/src/declarative/v8/wrapcc.pl
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/perl
-#############################################################################
-##
-## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-## All rights reserved.
-## Contact: Nokia Corporation (qt-info@nokia.com)
-##
-## This file is part of the translations module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## GNU Lesser General Public License Usage
-## This file may be used under the terms of the GNU Lesser General Public
-## License version 2.1 as published by the Free Software Foundation and
-## appearing in the file LICENSE.LGPL included in the packaging of this
-## file. Please review the following information to ensure the GNU Lesser
-## General Public License version 2.1 requirements will be met:
-## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-##
-## In addition, as a special exception, Nokia gives you certain additional
-## rights. These rights are described in the Nokia Qt LGPL Exception
-## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU General
-## Public License version 3.0 as published by the Free Software Foundation
-## and appearing in the file LICENSE.GPL included in the packaging of this
-## file. Please review the following information to ensure the GNU General
-## Public License version 3.0 requirements will be met:
-## http://www.gnu.org/copyleft/gpl.html.
-##
-## Other Usage
-## Alternatively, this file may be used in accordance with the terms and
-## conditions contained in a signed written agreement between you and Nokia.
-##
-##
-##
-##
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-scalar(@ARGV) == 2 or die "Usage: $0 INFILE OUTFILE";
-my $inFile = $ARGV[0];
-my $outFile = $ARGV[1];
-open FILE, ">", $outFile or die "Error: could not open $outFile for writing";
-print FILE "#include \"$inFile\"\n";
-close FILE;
diff --git a/src/imports/gestures/gestures.pro b/src/imports/gestures/gestures.pro
index 3b735efac5..e7095956b2 100644
--- a/src/imports/gestures/gestures.pro
+++ b/src/imports/gestures/gestures.pro
@@ -2,7 +2,7 @@ TARGET = qmlgesturesplugin
TARGETPATH = Qt/labs/gestures
include(../qimportbase.pri)
-QT += core-private gui-private declarative-private qtquick1 qtquick1-private widgets-private
+QT += core-private gui-private declarative-private qtquick1 qtquick1-private widgets-private v8-private
SOURCES += qdeclarativegesturearea.cpp plugin.cpp
HEADERS += qdeclarativegesturearea_p.h
diff --git a/src/imports/gestures/qdeclarativegesturearea.cpp b/src/imports/gestures/qdeclarativegesturearea.cpp
index c0d88a3318..1631831c7f 100644
--- a/src/imports/gestures/qdeclarativegesturearea.cpp
+++ b/src/imports/gestures/qdeclarativegesturearea.cpp
@@ -46,6 +46,7 @@
#include <qdeclarativeinfo.h>
#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativescript_p.h>
#include <QtQuick1/private/qdeclarativeitem_p.h>
#include <QtCore/qdebug.h>
@@ -196,7 +197,7 @@ QDeclarativeGestureAreaParser::compile(const QList<QDeclarativeCustomParserPrope
error(props.at(ii), QDeclarativeGestureArea::tr("GestureArea: syntax error"));
return QByteArray();
} else {
- QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(value);
+ QDeclarativeScript::Variant v = qvariant_cast<QDeclarativeScript::Variant>(value);
if (v.isScript()) {
ds << propName;
ds << int(type);
diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro
index 79906563f8..74dab8dcf3 100644
--- a/src/imports/particles/particles.pro
+++ b/src/imports/particles/particles.pro
@@ -9,7 +9,7 @@ SOURCES += \
particles.cpp \
V1/qdeclarativeparticles.cpp
-QT += declarative opengl core gui declarative-private core-private gui-private qtquick1 qtquick1-private widgets-private
+QT += declarative opengl core gui declarative-private core-private gui-private qtquick1 qtquick1-private widgets-private v8-private
OTHER_FILES += \
qmldir
diff --git a/src/imports/testlib/testlib.pro b/src/imports/testlib/testlib.pro
index 5adde2ae85..da072d34b1 100644
--- a/src/imports/testlib/testlib.pro
+++ b/src/imports/testlib/testlib.pro
@@ -21,7 +21,7 @@ symbian {
}
-QT += declarative qmltest qmltest-private declarative-private core-private testlib
+QT += declarative qmltest qmltest-private v8-private declarative-private core-private testlib
SOURCES += main.cpp
HEADERS +=
diff --git a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
index 3cb35e5738..8dcc076630 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
@@ -47,7 +47,7 @@
#include <QtDeclarative/QDeclarativeEngine>
#include <QtDeclarative/QDeclarativeComponent>
-#include <QtDeclarative/private/qdeclarativedebughelper_p.h>
+#include <QtCore/private/qabstractanimation_p.h>
#include "QtDeclarative/private/qdeclarativeinspectorservice_p.h"
#include <QtWidgets/QVBoxLayout>
@@ -180,7 +180,8 @@ void AbstractViewInspector::animationSpeedChangeRequested(qreal factor)
}
const float effectiveFactor = m_animationPaused ? 0 : factor;
- QDeclarativeDebugHelper::setAnimationSlowDownFactor(effectiveFactor);
+ QUnifiedTimer::instance()->setSlowModeEnabled(effectiveFactor != 1.0);
+ QUnifiedTimer::instance()->setSlowdownFactor(effectiveFactor);
}
void AbstractViewInspector::animationPausedChangeRequested(bool paused)
@@ -191,7 +192,8 @@ void AbstractViewInspector::animationPausedChangeRequested(bool paused)
}
const float effectiveFactor = paused ? 0 : m_slowDownFactor;
- QDeclarativeDebugHelper::setAnimationSlowDownFactor(effectiveFactor);
+ QUnifiedTimer::instance()->setSlowModeEnabled(effectiveFactor != 1.0);
+ QUnifiedTimer::instance()->setSlowdownFactor(effectiveFactor);
}
void AbstractViewInspector::setShowAppOnTop(bool appOnTop)
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
index d547422cb0..c165832013 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
+++ b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
@@ -1,7 +1,7 @@
load(qt_module)
TARGET = qmldbg_inspector
-QT += declarative-private core-private gui-private opengl-private qtquick1 widgets widgets-private
+QT += declarative-private core-private gui-private opengl-private qtquick1 widgets widgets-private v8-private
load(qt_plugin)
diff --git a/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp
index bb9ad52fee..497e51db4d 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp
@@ -46,7 +46,6 @@
#include "sgselectiontool.h"
#include <QtDeclarative/private/qdeclarativeinspectorservice_p.h>
-#include <QtDeclarative/private/qdeclarativedebughelper_p.h>
#include <QtDeclarative/private/qsgitem_p.h>
#include <QtDeclarative/QSGView>
diff --git a/src/qmltest/qmltest.pro b/src/qmltest/qmltest.pro
index 418136aa0a..b19ad55092 100644
--- a/src/qmltest/qmltest.pro
+++ b/src/qmltest/qmltest.pro
@@ -4,7 +4,7 @@ TARGET = QtQuickTest
QPRO_PWD = $$PWD
CONFIG += module
-CONFIG += dll warn_on
+CONFIG += dll warn_on declarative_debug
MODULE_PRI += ../../modules/qt_qmltest.pri
QT += testlib-private declarative testlib qtquick1
diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp
index 7f16eddc7e..c7d9747a3e 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -67,15 +67,6 @@
QT_BEGIN_NAMESPACE
-// Copied from qdeclarativedebughelper_p.h in Qt, to avoid a dependency
-// on a private header from Qt.
-class Q_DECLARATIVE_EXPORT QDeclarativeDebugHelper
-{
-public:
- static QJSEngine *getScriptEngine(QDeclarativeEngine *engine);
- static void setAnimationSlowDownFactor(qreal factor);
- static void enableDebugging();
-};
class QTestRootObject : public QObject
{
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp
index 534c57e1c2..80c3f8b3d5 100644
--- a/src/qmltest/quicktestresult.cpp
+++ b/src/qmltest/quicktestresult.cpp
@@ -442,14 +442,14 @@ bool QuickTestResult::compare
void QuickTestResult::skipSingle
(const QString &message, const QString &file, int line)
{
- QTestResult::addSkip(message.toLatin1().constData(), QTest::SkipSingle,
+ QTestResult::addSkip(message.toLatin1().constData(),
qtest_fixFile(file).toLatin1().constData(), line);
}
void QuickTestResult::skipAll
(const QString &message, const QString &file, int line)
{
- QTestResult::addSkip(message.toLatin1().constData(), QTest::SkipAll,
+ QTestResult::addSkip(message.toLatin1().constData(),
qtest_fixFile(file).toLatin1().constData(), line);
QTestResult::setSkipCurrentTest(true);
}
diff --git a/src/qtquick1/graphicsitems/qdeclarativeitem.cpp b/src/qtquick1/graphicsitems/qdeclarativeitem.cpp
index b32898fe38..c719067e2e 100644
--- a/src/qtquick1/graphicsitems/qdeclarativeitem.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativeitem.cpp
@@ -3665,8 +3665,8 @@ void QDeclarativeItem::setSize(const QSizeF &size)
bool QDeclarativeItem::hasActiveFocus() const
{
Q_D(const QDeclarativeItem);
- return focusItem() == this ||
- (d->flags & QGraphicsItem::ItemIsFocusScope && focusItem() != 0);
+ return (focusItem() && focusItem()->isVisible()) && (focusItem() == this ||
+ (d->flags & QGraphicsItem::ItemIsFocusScope && focusItem() != 0));
}
/*!
diff --git a/src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp
index 5d8a3d4b37..f76a4d9f08 100644
--- a/src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -1379,7 +1379,7 @@ void QDeclarative1VisualDataModel::_q_rowsMoved(const QModelIndex &sourceParent,
Q_D(QDeclarative1VisualDataModel);
const int count = sourceEnd - sourceStart + 1;
if (destinationParent == d->m_root && sourceParent == d->m_root) {
- _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow-1, count);
+ _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow-count, count);
} else if (sourceParent == d->m_root) {
_q_itemsRemoved(sourceStart, count);
} else if (destinationParent == d->m_root) {
diff --git a/src/qtquick1/qtquick1.pro b/src/qtquick1/qtquick1.pro
index 2e3113e214..66f2c848f2 100644
--- a/src/qtquick1/qtquick1.pro
+++ b/src/qtquick1/qtquick1.pro
@@ -7,7 +7,8 @@ CONFIG += module
CONFIG += dll warn_on
MODULE_PRI += ../../modules/qt_qtquick1.pri
-QT += testlib-private declarative testlib declarative-private core-private gui-private network widgets-private
+QT += testlib-private declarative testlib declarative-private core-private gui-private network widgets-private v8-private
+DEFINES += QT_NO_URL_CAST_FROM_STRING
load(qt_module_config)
diff --git a/src/qtquick1/util/qdeclarativeconnections.cpp b/src/qtquick1/util/qdeclarativeconnections.cpp
index 5fc019c4c1..54f51acd12 100644
--- a/src/qtquick1/util/qdeclarativeconnections.cpp
+++ b/src/qtquick1/util/qdeclarativeconnections.cpp
@@ -223,7 +223,7 @@ QDeclarative1ConnectionsParser::compile(const QList<QDeclarativeCustomParserProp
error(props.at(ii), QDeclarative1Connections::tr("Connections: syntax error"));
return QByteArray();
} else {
- QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(value);
+ QDeclarativeScript::Variant v = qvariant_cast<QDeclarativeScript::Variant>(value);
if (v.isScript()) {
ds << propName;
ds << v.asScript();
diff --git a/src/qtquick1/util/qdeclarativelistmodel.cpp b/src/qtquick1/util/qdeclarativelistmodel.cpp
index d5aa75bec5..5c31a8bd79 100644
--- a/src/qtquick1/util/qdeclarativelistmodel.cpp
+++ b/src/qtquick1/util/qdeclarativelistmodel.cpp
@@ -44,7 +44,7 @@
#include "QtQuick1/private/qdeclarativeopenmetaobject_p.h"
#include <QtDeclarative/private/qdeclarativecustomparser_p.h>
-#include <QtDeclarative/private/qdeclarativeparser_p.h>
+#include <QtDeclarative/private/qdeclarativescript_p.h>
#include <QtDeclarative/private/qdeclarativeengine_p.h>
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtDeclarative/qdeclarativeinfo.h>
@@ -787,6 +787,7 @@ void QDeclarative1ListModelParser::setCustomData(QObject *obj, const QByteArray
QDeclarative1ListModel *rv = static_cast<QDeclarative1ListModel *>(obj);
ModelNode *root = new ModelNode(rv->m_nested);
+ rv->m_nested->m_ownsRoot = true;
rv->m_nested->_root = root;
QStack<ModelNode *> nodes;
nodes << root;
diff --git a/src/qtquick1/util/qdeclarativepropertychanges.cpp b/src/qtquick1/util/qdeclarativepropertychanges.cpp
index 776701e58f..fc063cafb0 100644
--- a/src/qtquick1/util/qdeclarativepropertychanges.cpp
+++ b/src/qtquick1/util/qdeclarativepropertychanges.cpp
@@ -48,7 +48,7 @@
#include <QtDeclarative/qdeclarativeinfo.h>
#include <QtDeclarative/private/qdeclarativecustomparser_p.h>
-#include <QtDeclarative/private/qdeclarativeparser_p.h>
+#include <QtDeclarative/private/qdeclarativescript_p.h>
#include <QtDeclarative/qdeclarativeexpression.h>
#include <QtDeclarative/private/qdeclarativebinding_p.h>
#include <QtDeclarative/qdeclarativecontext.h>
@@ -282,22 +282,22 @@ QDeclarative1PropertyChangesParser::compile(const QList<QDeclarativeCustomParser
ds << data.count();
for(int ii = 0; ii < data.count(); ++ii) {
- QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(data.at(ii).second);
+ QDeclarativeScript::Variant v = qvariant_cast<QDeclarativeScript::Variant>(data.at(ii).second);
QVariant var;
bool isScript = v.isScript();
QDeclarativeBinding::Identifier id = 0;
switch(v.type()) {
- case QDeclarativeParser::Variant::Boolean:
+ case QDeclarativeScript::Variant::Boolean:
var = QVariant(v.asBoolean());
break;
- case QDeclarativeParser::Variant::Number:
+ case QDeclarativeScript::Variant::Number:
var = QVariant(v.asNumber());
break;
- case QDeclarativeParser::Variant::String:
+ case QDeclarativeScript::Variant::String:
var = QVariant(v.asString());
break;
- case QDeclarativeParser::Variant::Invalid:
- case QDeclarativeParser::Variant::Script:
+ case QDeclarativeScript::Variant::Invalid:
+ case QDeclarativeScript::Variant::Script:
var = QVariant(v.asScript());
{
// Pre-rewrite the expression
diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro
index a99656a3ee..5c5e76d78a 100644
--- a/tests/auto/declarative/declarative.pro
+++ b/tests/auto/declarative/declarative.pro
@@ -33,7 +33,6 @@ PRIVATETESTS += \
qdeclarativeconnection \
qdeclarativedebug \
qdeclarativedebugclient \
- qdeclarativedebughelper \
qdeclarativedebugservice \
qdeclarativeecmascript \
qdeclarativeimageprovider \
@@ -54,8 +53,7 @@ PRIVATETESTS += \
qdeclarativeworkerscript \
qdeclarativexmllistmodel \
qpacketprotocol \
- qdeclarativev4 \
- v8
+ qdeclarativev4
SGTESTS = \
qsganimatedimage \
diff --git a/tests/auto/declarative/examples/examples.pro b/tests/auto/declarative/examples/examples.pro
index 297559ef97..75adbb53ba 100644
--- a/tests/auto/declarative/examples/examples.pro
+++ b/tests/auto/declarative/examples/examples.pro
@@ -18,6 +18,6 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private widgets-private
+QT += core-private gui-private declarative-private qtquick1-private widgets-private v8-private
qpa:CONFIG+=insignificant_test # QTBUG-20990, aborts
diff --git a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro b/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro
index 2669e5a8e3..049e1b3acb 100644
--- a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro
+++ b/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro
@@ -13,4 +13,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private
diff --git a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro b/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro
index e0720aa6fd..03ba50ad15 100644
--- a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro
+++ b/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro
@@ -13,4 +13,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private
diff --git a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro
index 49150c8481..7cd78ab1fc 100644
--- a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro
+++ b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private
diff --git a/tests/auto/declarative/qdeclarativedebug/qdeclarativedebug.pro b/tests/auto/declarative/qdeclarativedebug/qdeclarativedebug.pro
index cd5577219d..6187020a38 100644
--- a/tests/auto/declarative/qdeclarativedebug/qdeclarativedebug.pro
+++ b/tests/auto/declarative/qdeclarativedebug/qdeclarativedebug.pro
@@ -6,6 +6,6 @@ HEADERS += ../shared/debugutil_p.h
SOURCES += tst_qdeclarativedebug.cpp \
../shared/debugutil.cpp
-CONFIG += parallel_test
+CONFIG += parallel_test declarative_debug
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
index ade51c43f6..b47579ea6a 100644
--- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
+++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
@@ -55,11 +55,9 @@
#include <private/qdeclarativebinding_p.h>
#include <private/qdeclarativedebug_p.h>
#include <private/qdeclarativeenginedebug_p.h>
-#include <private/qdeclarativedebugclient_p.h>
#include <private/qdeclarativedebugservice_p.h>
#include <private/qdeclarativemetatype_p.h>
#include <private/qdeclarativeproperty_p.h>
-#include <private/qdeclarativedebughelper_p.h>
#include "../../../shared/util.h"
#include "../shared/debugutil_p.h"
@@ -296,9 +294,6 @@ void tst_QDeclarativeDebug::initTestCase()
qRegisterMetaType<QDeclarativeDebugWatch::State>();
qmlRegisterType<NonScriptProperty>("Test", 1, 0, "NonScriptPropertyElement");
- QTest::ignoreMessage(QtWarningMsg, "Qml debugging is enabled. Only use this in a safe environment!");
- QDeclarativeDebugHelper::enableDebugging();
-
QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Waiting for connection on port 3768...");
m_engine = new QDeclarativeEngine(this);
@@ -1089,7 +1084,7 @@ void tst_QDeclarativeDebug::setBindingInStates()
// change the binding
- QDeclarativeDebugObjectReference state = obj.children()[0];
+ QDeclarativeDebugObjectReference state = obj.children()[1];
QCOMPARE(state.className(), QString("State"));
QVERIFY(state.children().count() > 0);
@@ -1173,7 +1168,7 @@ void tst_QDeclarativeDebug::queryObjectTree()
// check state
- QDeclarativeDebugObjectReference state = obj.children()[0];
+ QDeclarativeDebugObjectReference state = obj.children()[1];
QCOMPARE(state.className(), QString("State"));
QVERIFY(state.children().count() > 0);
@@ -1189,7 +1184,7 @@ void tst_QDeclarativeDebug::queryObjectTree()
// check transition
- QDeclarativeDebugObjectReference transition = obj.children()[1];
+ QDeclarativeDebugObjectReference transition = obj.children()[0];
QCOMPARE(transition.className(), QString("Transition"));
QCOMPARE(findProperty(transition.properties(),"from").value().toString(), QString("*"));
QCOMPARE(findProperty(transition.properties(),"to").value(), findProperty(state.properties(),"name").value());
diff --git a/tests/auto/declarative/qdeclarativedebugclient/qdeclarativedebugclient.pro b/tests/auto/declarative/qdeclarativedebugclient/qdeclarativedebugclient.pro
index 189133a526..28e25e9450 100644
--- a/tests/auto/declarative/qdeclarativedebugclient/qdeclarativedebugclient.pro
+++ b/tests/auto/declarative/qdeclarativedebugclient/qdeclarativedebugclient.pro
@@ -5,4 +5,8 @@ macx:CONFIG -= app_bundle
HEADERS += ../shared/debugutil_p.h
SOURCES += tst_qdeclarativedebugclient.cpp \
../shared/debugutil.cpp
+
+CONFIG += declarative_debug
+
QT += core-private gui-private declarative-private
+
diff --git a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp
index d41cfa3d4d..d7f53c9620 100644
--- a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp
+++ b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp
@@ -49,9 +49,7 @@
#include <private/qdeclarativedebug_p.h>
#include <private/qdeclarativeenginedebug_p.h>
-#include <private/qdeclarativedebugclient_p.h>
#include <private/qdeclarativedebugservice_p.h>
-#include <private/qdeclarativedebughelper_p.h>
#include "../../../shared/util.h"
#include "../shared/debugutil_p.h"
@@ -73,9 +71,6 @@ private slots:
void tst_QDeclarativeDebugClient::initTestCase()
{
- QTest::ignoreMessage(QtWarningMsg, "Qml debugging is enabled. Only use this in a safe environment!");
- QDeclarativeDebugHelper::enableDebugging();
-
QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Waiting for connection on port 13770...");
new QDeclarativeEngine(this);
diff --git a/tests/auto/declarative/qdeclarativedebughelper/qdeclarativedebughelper.pro b/tests/auto/declarative/qdeclarativedebughelper/qdeclarativedebughelper.pro
deleted file mode 100644
index 1e62c12363..0000000000
--- a/tests/auto/declarative/qdeclarativedebughelper/qdeclarativedebughelper.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += network declarative
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qdeclarativedebughelper.cpp
-QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativedebughelper/tst_qdeclarativedebughelper.cpp b/tests/auto/declarative/qdeclarativedebughelper/tst_qdeclarativedebughelper.cpp
deleted file mode 100644
index f67d5c5a89..0000000000
--- a/tests/auto/declarative/qdeclarativedebughelper/tst_qdeclarativedebughelper.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qtest.h>
-
-#include <QDeclarativeEngine>
-#include <private/qdeclarativeengine_p.h>
-#include <QAbstractAnimation>
-#include <private/qabstractanimation_p.h>
-
-// We have copied the header which is used in the qmljsdebugger (part of QtCreator)
-// to catch BC changes. Don't update it unless you know what you are doing!
-#include "private_headers/qdeclarativedebughelper_p.h"
-
-class tst_qdeclarativedebughelper : public QObject {
- Q_OBJECT
-private slots:
- void setAnimationSlowDownFactor();
- void enableDebugging();
-};
-
-class TestAnimation : public QAbstractAnimation {
-public:
- int updateCalled;
-
- TestAnimation() : updateCalled(0) {}
-
- virtual void updateCurrentTime(int /*currentTime*/) {
- updateCalled++;
- }
- virtual int duration() const {
- return 100;
- }
-};
-
-void tst_qdeclarativedebughelper::setAnimationSlowDownFactor()
-{
- TestAnimation animation;
-
- // first check whether setup works
- QCOMPARE(animation.updateCalled, 0);
- animation.start();
- QTest::qWait(animation.totalDuration() + 150);
-#ifdef Q_OS_WIN
- if (animation.state() != QAbstractAnimation::Stopped)
- QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort);
-#endif
- QCOMPARE(animation.state(), QAbstractAnimation::Stopped);
- QVERIFY(animation.updateCalled > 1);
-
- // check if we can pause all animations
- animation.updateCalled = 0;
- QDeclarativeDebugHelper::setAnimationSlowDownFactor(0.0);
- animation.start();
- QTest::qWait(animation.totalDuration() + 150);
- QVERIFY(animation.updateCalled <= 1); // updateCurrentTime seems to be called at least once
-
- // now run them again
- animation.updateCalled = 0;
- QDeclarativeDebugHelper::setAnimationSlowDownFactor(2.0);
- animation.start();
- QTest::qWait(animation.totalDuration() + 150);
- QVERIFY(animation.updateCalled > 1);
-}
-
-void tst_qdeclarativedebughelper::enableDebugging()
-{
- QTest::ignoreMessage(QtWarningMsg, "Qml debugging is enabled. Only use this in a safe environment!");
- QDeclarativeDebugHelper::enableDebugging();
-}
-
-QTEST_MAIN(tst_qdeclarativedebughelper)
-
-#include "tst_qdeclarativedebughelper.moc"
-
diff --git a/tests/auto/declarative/qdeclarativedebugservice/qdeclarativedebugservice.pro b/tests/auto/declarative/qdeclarativedebugservice/qdeclarativedebugservice.pro
index 785e8a7bf1..999e19279b 100644
--- a/tests/auto/declarative/qdeclarativedebugservice/qdeclarativedebugservice.pro
+++ b/tests/auto/declarative/qdeclarativedebugservice/qdeclarativedebugservice.pro
@@ -6,6 +6,6 @@ HEADERS += ../shared/debugutil_p.h
SOURCES += tst_qdeclarativedebugservice.cpp \
../shared/debugutil.cpp
-CONFIG += parallel_test
+CONFIG += parallel_test declarative_debug
QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp
index 3fa8bba682..74f549c076 100644
--- a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp
+++ b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp
@@ -46,7 +46,6 @@
#include <QThread>
#include <QtDeclarative/qdeclarativeengine.h>
-#include <private/qdeclarativedebughelper_p.h>
#include <private/qdeclarativedebug_p.h>
#include <private/qdeclarativeenginedebug_p.h>
@@ -76,9 +75,6 @@ private slots:
void tst_QDeclarativeDebugService::initTestCase()
{
- QTest::ignoreMessage(QtWarningMsg, "Qml debugging is enabled. Only use this in a safe environment!");
- QDeclarativeDebugHelper::enableDebugging();
-
QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Waiting for connection on port 13769...");
new QDeclarativeEngine(this);
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMajorVersionFail.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMajorVersionFail.qml
index fb050f65bc..fb050f65bc 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMajorVersionFail.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMajorVersionFail.qml
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMinorVersionFail.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMinorVersionFail.qml
index e06be667f7..e06be667f7 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMinorVersionFail.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMinorVersionFail.qml
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApi.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApi.qml
index 67e8c1b08a..718a64652d 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApi.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApi.qml
@@ -1,7 +1,6 @@
import QtQuick 2.0
import Qt.test 1.0 as QtTest // module API installed into existing uri
-import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri
import Qt.test.qobjectApi 1.0 as QtTestQObjectApi // qobject module API installed into new uri
import Qt.test.qobjectApi 1.3 as QtTestMinorVersionQObjectApi // qobject module API installed into existing uri with new minor version
import Qt.test.qobjectApi 2.0 as QtTestMajorVersionQObjectApi // qobject module API installed into existing uri with new major version
@@ -9,7 +8,6 @@ import Qt.test.qobjectApiParented 1.0 as QtTestParentedQObjectApi // qobject (wi
QtObject {
property int existingUriTest: QtTest.qobjectTestProperty
- property int scriptTest: QtTestScriptApi.scriptTestProperty
property int qobjectTest: QtTestQObjectApi.qobjectTestProperty
property int qobjectMethodTest: 2
property int qobjectMinorVersionTest: QtTestMinorVersionQObjectApi.qobjectTestProperty
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiCaching.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiCaching.qml
index f6ce2058a7..56a55e4e9b 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiCaching.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiCaching.qml
@@ -1,12 +1,10 @@
import QtQuick 2.0
import Qt.test 1.0 as QtTest // module API installed into existing uri
-import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri
import Qt.test.qobjectApiParented 1.0 as QtTestParentedQObjectApi // qobject (with parent) module API installed into a new uri
QtObject {
property int existingUriTest: QtTest.qobjectTestProperty
- property int scriptTest: QtTestScriptApi.scriptTestProperty
property int qobjectParentedTest: QtTestParentedQObjectApi.qobjectTestProperty
}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiEnums.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiEnums.qml
new file mode 100644
index 0000000000..da5ffd5e76
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiEnums.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+import Qt.test.qobjectApi 1.0 as QtTestQObjectApi // qobject module API installed into new uri
+
+QtObject {
+ property int enumValue: QtTestQObjectApi.EnumValue2;
+ property int enumMethod: QtTestQObjectApi.qobjectEnumTestMethod(QtTestQObjectApi.EnumValue1);
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiWriting.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiWriting.qml
index 500c35e211..be647ca57f 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiWriting.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiWriting.qml
@@ -1,6 +1,5 @@
import QtQuick 2.0
-
-import Qt.test 1.0 as QtTest // module API installed into existing uri
+import Qt.test 1.0 as QtTest // qobject module API installed into existing uri
QtObject {
property int firstProperty: 1
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApi.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApi.qml
new file mode 100644
index 0000000000..7c4e20489d
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApi.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri
+
+QtObject {
+ property int scriptTest: QtTestScriptApi.scriptTestProperty // script module api's only provide properties.
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiCaching.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiCaching.qml
new file mode 100644
index 0000000000..90974b5969
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiCaching.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri
+
+QtObject {
+ property int scriptTest: QtTestScriptApi.scriptTestProperty
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiWriting.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiWriting.qml
new file mode 100644
index 0000000000..02461d59ed
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiWriting.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.0
+import Qt.test.scriptApi 1.0 as QtTestScriptApi
+import Qt.test.scriptApi 2.0 as QtTestScriptApi2
+
+QtObject {
+ property int firstProperty
+ property int readBack
+
+ property int secondProperty
+ property int unchanged
+
+ onFirstPropertyChanged: {
+ if (QtTestScriptApi.scriptTestProperty != firstProperty) {
+ QtTestScriptApi.scriptTestProperty = firstProperty;
+ readBack = QtTestScriptApi.scriptTestProperty;
+ }
+ }
+
+ onSecondPropertyChanged: {
+ if (QtTestScriptApi2.scriptTestProperty != secondProperty) {
+ QtTestScriptApi2.scriptTestProperty = secondProperty;
+ unchanged = QtTestScriptApi2.scriptTestProperty;
+ }
+ }
+
+ Component.onCompleted: {
+ firstProperty = QtTestScriptApi.scriptTestProperty;
+ readBack = QtTestScriptApi.scriptTestProperty;
+ secondProperty = QtTestScriptApi2.scriptTestProperty;
+ unchanged = QtTestScriptApi2.scriptTestProperty;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro
index 4b7aff339c..5dfcfa6e1b 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro
+++ b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro
@@ -22,4 +22,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
index 160a57215b..05d5510033 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
@@ -111,6 +111,21 @@ static QJSValue script_api(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
return v;
}
+static QJSValue readonly_script_api(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(engine)
+
+ static int testProperty = 42;
+ QJSValue v = scriptEngine->newObject();
+ v.setProperty("scriptTestProperty", testProperty++);
+
+ // now freeze it so that it's read-only
+ QJSValue freezeFunction = scriptEngine->evaluate("(function(obj) { return Object.freeze(obj); })");
+ v = freezeFunction.call(QJSValue(), (QJSValueList() << v));
+
+ return v;
+}
+
static QObject *qobject_api(QDeclarativeEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
@@ -166,6 +181,7 @@ void registerTypes()
qmlRegisterModuleApi("Qt.test",1,0,script_api); // register (script) module API for an existing uri which contains elements
qmlRegisterModuleApi("Qt.test",1,0,qobject_api); // register (qobject) for an existing uri for which another module API was previously regd. Should replace!
qmlRegisterModuleApi("Qt.test.scriptApi",1,0,script_api); // register (script) module API for a uri which doesn't contain elements
+ qmlRegisterModuleApi("Qt.test.scriptApi",2,0,readonly_script_api); // register (script) module API for a uri which doesn't contain elements - will be made read-only
qmlRegisterModuleApi("Qt.test.qobjectApi",1,0,qobject_api); // register (qobject) module API for a uri which doesn't contain elements
qmlRegisterModuleApi("Qt.test.qobjectApi",1,3,qobject_api); // register (qobject) module API for a uri which doesn't contain elements, minor version set
qmlRegisterModuleApi("Qt.test.qobjectApi",2,0,qobject_api); // register (qobject) module API for a uri which doesn't contain elements, major version set
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
index afb361e2d7..2738ee3d60 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
@@ -934,6 +934,7 @@ private:
class testQObjectApi : public QObject
{
Q_OBJECT
+ Q_ENUMS(MyEnum)
Q_PROPERTY (int qobjectTestProperty READ qobjectTestProperty NOTIFY qobjectTestPropertyChanged)
Q_PROPERTY (int qobjectTestWritableProperty READ qobjectTestWritableProperty WRITE setQObjectTestWritableProperty NOTIFY qobjectTestWritablePropertyChanged)
@@ -945,7 +946,9 @@ public:
~testQObjectApi() {}
- Q_INVOKABLE int qobjectTestMethod() { m_methodCallCount += 1; return m_methodCallCount; }
+ enum MyEnum { EnumValue1 = 25, EnumValue2 = 42 };
+ Q_INVOKABLE int qobjectEnumTestMethod(MyEnum val) { return (static_cast<int>(val) + 5); }
+ Q_INVOKABLE int qobjectTestMethod(int increment = 1) { m_methodCallCount += increment; return m_methodCallCount; }
int qobjectTestProperty() const { return m_testProperty; }
void setQObjectTestProperty(int tp) { m_testProperty = tp; emit qobjectTestPropertyChanged(tp); }
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 3efe18909c..f14db0a330 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -145,6 +145,7 @@ private slots:
void numberAssignment();
void propertySplicing();
void signalWithUnknownTypes();
+ void moduleApi_data();
void moduleApi();
void importScripts();
void scarceResources();
@@ -2735,55 +2736,153 @@ void tst_qdeclarativeecmascript::signalWithUnknownTypes()
delete object;
}
+void tst_qdeclarativeecmascript::moduleApi_data()
+{
+ QTest::addColumn<QUrl>("testfile");
+ QTest::addColumn<QString>("errorMessage");
+ QTest::addColumn<QStringList>("warningMessages");
+ QTest::addColumn<QStringList>("readProperties");
+ QTest::addColumn<QVariantList>("readExpectedValues");
+ QTest::addColumn<QStringList>("writeProperties");
+ QTest::addColumn<QVariantList>("writeValues");
+ QTest::addColumn<QStringList>("readBackProperties");
+ QTest::addColumn<QVariantList>("readBackExpectedValues");
+
+ QTest::newRow("qobject, register + read + method")
+ << TEST_FILE("moduleapi/qobjectModuleApi.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << "existingUriTest" << "qobjectTest" << "qobjectMethodTest"
+ << "qobjectMinorVersionTest" << "qobjectMajorVersionTest" << "qobjectParentedTest")
+ << (QVariantList() << 20 << 20 << 1 << 20 << 20 << 26)
+ << QStringList()
+ << QVariantList()
+ << QStringList()
+ << QVariantList();
+
+ QTest::newRow("script, register + read")
+ << TEST_FILE("moduleapi/scriptModuleApi.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << "scriptTest")
+ << (QVariantList() << 13)
+ << QStringList()
+ << QVariantList()
+ << QStringList()
+ << QVariantList();
+
+ QTest::newRow("qobject, caching + read")
+ << TEST_FILE("moduleapi/qobjectModuleApiCaching.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << "existingUriTest" << "qobjectParentedTest")
+ << (QVariantList() << 20 << 26) // 26, shouldn't have incremented to 27.
+ << QStringList()
+ << QVariantList()
+ << QStringList()
+ << QVariantList();
+
+ QTest::newRow("script, caching + read")
+ << TEST_FILE("moduleapi/scriptModuleApiCaching.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << "scriptTest")
+ << (QVariantList() << 13) // 13, shouldn't have incremented to 14.
+ << QStringList()
+ << QVariantList()
+ << QStringList()
+ << QVariantList();
+
+ QTest::newRow("qobject, writing + readonly constraints")
+ << TEST_FILE("moduleapi/qobjectModuleApiWriting.qml")
+ << QString()
+ << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("moduleapi/qobjectModuleApiWriting.qml").toLocalFile() + QLatin1String(":14: Error: Cannot assign to read-only property \"qobjectTestProperty\"")))
+ << (QStringList() << "readOnlyProperty" << "writableProperty")
+ << (QVariantList() << 20 << 50)
+ << (QStringList() << "firstProperty" << "writableProperty")
+ << (QVariantList() << 30 << 30)
+ << (QStringList() << "readOnlyProperty" << "writableProperty")
+ << (QVariantList() << 20 << 30);
+
+ QTest::newRow("script, writing + readonly constraints")
+ << TEST_FILE("moduleapi/scriptModuleApiWriting.qml")
+ << QString()
+ << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("moduleapi/scriptModuleApiWriting.qml").toLocalFile() + QLatin1String(":21: Error: Cannot assign to read-only property \"scriptTestProperty\"")))
+ << (QStringList() << "readBack" << "unchanged")
+ << (QVariantList() << 13 << 42)
+ << (QStringList() << "firstProperty" << "secondProperty")
+ << (QVariantList() << 30 << 30)
+ << (QStringList() << "readBack" << "unchanged")
+ << (QVariantList() << 30 << 42);
+
+ QTest::newRow("qobject module API enum values in JS")
+ << TEST_FILE("moduleapi/qobjectModuleApiEnums.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << "enumValue" << "enumMethod")
+ << (QVariantList() << 42 << 30)
+ << QStringList()
+ << QVariantList()
+ << QStringList()
+ << QVariantList();
+
+ QTest::newRow("qobject, invalid major version fail")
+ << TEST_FILE("moduleapi/moduleApiMajorVersionFail.qml")
+ << QString("QDeclarativeComponent: Component is not ready")
+ << QStringList()
+ << QStringList()
+ << QVariantList()
+ << QStringList()
+ << QVariantList()
+ << QStringList()
+ << QVariantList();
+
+ QTest::newRow("qobject, invalid minor version fail")
+ << TEST_FILE("moduleapi/moduleApiMinorVersionFail.qml")
+ << QString("QDeclarativeComponent: Component is not ready")
+ << QStringList()
+ << QStringList()
+ << QVariantList()
+ << QStringList()
+ << QVariantList()
+ << QStringList()
+ << QVariantList();
+}
+
void tst_qdeclarativeecmascript::moduleApi()
{
- QDeclarativeComponent component(&engine, TEST_FILE("moduleApi.qml"));
- QObject *object = component.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("existingUriTest").toInt(), 20);
+ QFETCH(QUrl, testfile);
+ QFETCH(QString, errorMessage);
+ QFETCH(QStringList, warningMessages);
+ QFETCH(QStringList, readProperties);
+ QFETCH(QVariantList, readExpectedValues);
+ QFETCH(QStringList, writeProperties);
+ QFETCH(QVariantList, writeValues);
+ QFETCH(QStringList, readBackProperties);
+ QFETCH(QVariantList, readBackExpectedValues);
- QEXPECT_FAIL("", "QTBUG-17318", Continue);
- QCOMPARE(object->property("scriptTest").toInt(), 13);
- QCOMPARE(object->property("qobjectTest").toInt(), 20);
- QCOMPARE(object->property("qobjectMethodTest").toInt(), 1); // first call of method, so count = 1.
- QCOMPARE(object->property("qobjectMinorVersionTest").toInt(), 20);
- QCOMPARE(object->property("qobjectMajorVersionTest").toInt(), 20);
- QCOMPARE(object->property("qobjectParentedTest").toInt(), 26);
- delete object;
+ QDeclarativeComponent component(&engine, testfile);
- // test that caching of module apis works correctly.
- QDeclarativeComponent componentTwo(&engine, TEST_FILE("moduleApiCaching.qml"));
- object = componentTwo.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("existingUriTest").toInt(), 20);
- QEXPECT_FAIL("", "QTBUG-17318", Continue);
- QCOMPARE(object->property("scriptTest").toInt(), 13); // shouldn't have incremented.
- QCOMPARE(object->property("qobjectParentedTest").toInt(), 26); // shouldn't have incremented.
- delete object;
+ if (!errorMessage.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, errorMessage.toAscii().constData());
- // test that writing to a property of module apis works correctly.
- QDeclarativeComponent componentThree(&engine, TEST_FILE("moduleApiWriting.qml"));
- QString expectedWarning = QLatin1String("file://") + TEST_FILE("moduleApiWriting.qml").toLocalFile() + QLatin1String(":15: Error: Cannot assign to read-only property \"qobjectTestProperty\"");
- QTest::ignoreMessage(QtWarningMsg, expectedWarning.toAscii().constData());
- object = componentThree.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("readOnlyProperty").toInt(), 20);
- QCOMPARE(object->property("writableProperty").toInt(), 50);
- QVERIFY(object->setProperty("firstProperty", QVariant(30))); // shouldn't affect value of readOnlyProperty
- QVERIFY(object->setProperty("writableProperty", QVariant(30))); // SHOULD affect value of writableProperty
- QCOMPARE(object->property("readOnlyProperty").toInt(), 20);
- QCOMPARE(object->property("writableProperty").toInt(), 30);
- delete object;
+ if (warningMessages.size())
+ foreach (const QString &warning, warningMessages)
+ QTest::ignoreMessage(QtWarningMsg, warning.toAscii().constData());
- QDeclarativeComponent failOne(&engine, TEST_FILE("moduleApiMajorVersionFail.qml"));
- QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
- object = failOne.create();
- QVERIFY(object == 0); // should have failed: invalid major version
-
- QDeclarativeComponent failTwo(&engine, TEST_FILE("moduleApiMinorVersionFail.qml"));
- QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
- object = failTwo.create();
- QVERIFY(object == 0); // should have failed: invalid minor version
+ QObject *object = component.create();
+ if (!errorMessage.isEmpty()) {
+ QVERIFY(object == 0);
+ } else {
+ QVERIFY(object != 0);
+ for (int i = 0; i < readProperties.size(); ++i)
+ QCOMPARE(object->property(readProperties.at(i).toAscii().constData()), readExpectedValues.at(i));
+ for (int i = 0; i < writeProperties.size(); ++i)
+ QVERIFY(object->setProperty(writeProperties.at(i).toAscii().constData(), writeValues.at(i)));
+ for (int i = 0; i < readBackProperties.size(); ++i)
+ QCOMPARE(object->property(readBackProperties.at(i).toAscii().constData()), readBackExpectedValues.at(i));
+ delete object;
+ }
}
void tst_qdeclarativeecmascript::importScripts()
diff --git a/tests/auto/declarative/qdeclarativefontloader/data/daniel.ttf b/tests/auto/declarative/qdeclarativefontloader/data/daniel.ttf
new file mode 100644
index 0000000000..aae50d5035
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativefontloader/data/daniel.ttf
Binary files differ
diff --git a/tests/auto/declarative/qdeclarativefontloader/data/dummy.ttf b/tests/auto/declarative/qdeclarativefontloader/data/dummy.ttf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativefontloader/data/dummy.ttf
diff --git a/tests/auto/declarative/qdeclarativefontloader/data/tarzeau_ocr_a.ttf b/tests/auto/declarative/qdeclarativefontloader/data/tarzeau_ocr_a.ttf
new file mode 100644
index 0000000000..cf93f9651f
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativefontloader/data/tarzeau_ocr_a.ttf
Binary files differ
diff --git a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro
new file mode 100644
index 0000000000..946e5a8a16
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro
@@ -0,0 +1,18 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative gui network
+macx:CONFIG -= app_bundle
+
+HEADERS += ../../declarative/shared/testhttpserver.h
+SOURCES += tst_qdeclarativefontloader.cpp ../../declarative/shared/testhttpserver.cpp
+
+symbian: {
+ importFiles.files = data
+ importFiles.path = .
+ DEPLOYMENT += importFiles
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+}
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
new file mode 100644
index 0000000000..29fe0329bb
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QtTest/QSignalSpy>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/private/qdeclarativefontloader_p.h>
+#include "../../../shared/util.h"
+#include "../../declarative/shared/testhttpserver.h"
+
+#define SERVER_PORT 14448
+
+#ifdef Q_OS_SYMBIAN
+// In Symbian OS test data is located in applications private dir
+#define SRCDIR "."
+#endif
+
+class tst_qdeclarativefontloader : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qdeclarativefontloader();
+
+private slots:
+ void init();
+ void noFont();
+ void namedFont();
+ void localFont();
+ void failLocalFont();
+ void webFont();
+ void redirWebFont();
+ void failWebFont();
+ void changeFont();
+
+private:
+ QDeclarativeEngine engine;
+ TestHTTPServer server;
+};
+
+tst_qdeclarativefontloader::tst_qdeclarativefontloader() :
+ server(SERVER_PORT)
+{
+ server.serveDirectory(SRCDIR "/data");
+}
+
+void tst_qdeclarativefontloader::init()
+{
+ QVERIFY(server.isValid());
+}
+
+void tst_qdeclarativefontloader::noFont()
+{
+ QString componentStr = "import QtQuick 2.0\nFontLoader { }";
+ QDeclarativeComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
+
+ QVERIFY(fontObject != 0);
+ QCOMPARE(fontObject->name(), QString(""));
+ QCOMPARE(fontObject->source(), QUrl(""));
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Null);
+
+ delete fontObject;
+}
+
+void tst_qdeclarativefontloader::namedFont()
+{
+ QString componentStr = "import QtQuick 2.0\nFontLoader { name: \"Helvetica\" }";
+ QDeclarativeComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
+
+ QVERIFY(fontObject != 0);
+ QCOMPARE(fontObject->source(), QUrl(""));
+ QCOMPARE(fontObject->name(), QString("Helvetica"));
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+}
+
+void tst_qdeclarativefontloader::localFont()
+{
+ QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" SRCDIR "/data/tarzeau_ocr_a.ttf\" }";
+ QDeclarativeComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
+
+ QVERIFY(fontObject != 0);
+ QVERIFY(fontObject->source() != QUrl(""));
+ QTRY_COMPARE(fontObject->name(), QString("OCRA"));
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+}
+
+void tst_qdeclarativefontloader::failLocalFont()
+{
+ QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + QUrl::fromLocalFile(SRCDIR "/data/dummy.ttf").toString() + "\" }";
+ QTest::ignoreMessage(QtWarningMsg, QString("file::2:1: QML FontLoader: Cannot load font: \"" + QUrl::fromLocalFile(SRCDIR "/data/dummy.ttf").toString() + "\"").toUtf8().constData());
+ QDeclarativeComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
+
+ QVERIFY(fontObject != 0);
+ QVERIFY(fontObject->source() != QUrl(""));
+ QTRY_COMPARE(fontObject->name(), QString(""));
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Error);
+}
+
+void tst_qdeclarativefontloader::webFont()
+{
+ QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"http://localhost:14448/tarzeau_ocr_a.ttf\" }";
+ QDeclarativeComponent component(&engine);
+
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
+
+ QVERIFY(fontObject != 0);
+ QVERIFY(fontObject->source() != QUrl(""));
+ QTRY_COMPARE(fontObject->name(), QString("OCRA"));
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+}
+
+void tst_qdeclarativefontloader::redirWebFont()
+{
+ server.addRedirect("olddir/oldname.ttf","../tarzeau_ocr_a.ttf");
+
+ QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"http://localhost:14448/olddir/oldname.ttf\" }";
+ QDeclarativeComponent component(&engine);
+
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
+
+ QVERIFY(fontObject != 0);
+ QVERIFY(fontObject->source() != QUrl(""));
+ QTRY_COMPARE(fontObject->name(), QString("OCRA"));
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+}
+
+void tst_qdeclarativefontloader::failWebFont()
+{
+ QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"http://localhost:14448/nonexist.ttf\" }";
+ QTest::ignoreMessage(QtWarningMsg, "file::2:1: QML FontLoader: Cannot load font: \"http://localhost:14448/nonexist.ttf\"");
+ QDeclarativeComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
+
+ QVERIFY(fontObject != 0);
+ QVERIFY(fontObject->source() != QUrl(""));
+ QTRY_COMPARE(fontObject->name(), QString(""));
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Error);
+}
+
+void tst_qdeclarativefontloader::changeFont()
+{
+ QString componentStr = "import QtQuick 2.0\nFontLoader { source: font }";
+ QDeclarativeContext *ctxt = engine.rootContext();
+ ctxt->setContextProperty("font", QUrl::fromLocalFile(SRCDIR "/data/tarzeau_ocr_a.ttf"));
+ QDeclarativeComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
+
+ QVERIFY(fontObject != 0);
+
+ QSignalSpy nameSpy(fontObject, SIGNAL(nameChanged()));
+ QSignalSpy statusSpy(fontObject, SIGNAL(statusChanged()));
+
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+ QCOMPARE(nameSpy.count(), 0);
+ QCOMPARE(statusSpy.count(), 0);
+ QTRY_COMPARE(fontObject->name(), QString("OCRA"));
+
+ ctxt->setContextProperty("font", "http://localhost:14448/daniel.ttf");
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Loading);
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+ QCOMPARE(nameSpy.count(), 1);
+ QCOMPARE(statusSpy.count(), 2);
+ QTRY_COMPARE(fontObject->name(), QString("Daniel"));
+
+ ctxt->setContextProperty("font", QUrl::fromLocalFile(SRCDIR "/data/tarzeau_ocr_a.ttf"));
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+ QCOMPARE(nameSpy.count(), 2);
+ QCOMPARE(statusSpy.count(), 2);
+ QTRY_COMPARE(fontObject->name(), QString("OCRA"));
+
+ ctxt->setContextProperty("font", "http://localhost:14448/daniel.ttf");
+ QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
+ QCOMPARE(nameSpy.count(), 3);
+ QCOMPARE(statusSpy.count(), 2);
+ QTRY_COMPARE(fontObject->name(), QString("Daniel"));
+}
+
+QTEST_MAIN(tst_qdeclarativefontloader)
+
+#include "tst_qdeclarativefontloader.moc"
diff --git a/tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro b/tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro
index a4cdd81266..7cff542838 100644
--- a/tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro
+++ b/tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro
@@ -9,4 +9,4 @@ macx:CONFIG -= app_bundle
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/empty.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/empty.errors.txt
index d416e76ae2..620db2bbba 100644
--- a/tests/auto/declarative/qdeclarativelanguage/data/empty.errors.txt
+++ b/tests/auto/declarative/qdeclarativelanguage/data/empty.errors.txt
@@ -1,2 +1,2 @@
-0:0:Expected token `numeric literal'
-0:0:Expected a qualified name id
+1:1:Expected token `numeric literal'
+1:1:Expected a qualified name id
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/signal.2.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/signal.2.errors.txt
index fce89285ec..0d4c33d750 100644
--- a/tests/auto/declarative/qdeclarativelanguage/data/signal.2.errors.txt
+++ b/tests/auto/declarative/qdeclarativelanguage/data/signal.2.errors.txt
@@ -1 +1 @@
-4:21:Unexpected token `;'
+4:21:Unexpected token `,'
diff --git a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro
index 71d2066608..e6006aed00 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro
+++ b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro
@@ -20,4 +20,4 @@ symbian: {
}
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro
index 83ea7992ed..4575c581ae 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro
+++ b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private
diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
index 946a3a5692..0c3b75ac98 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
@@ -219,6 +219,11 @@ void tst_qdeclarativelistmodel::static_i18n_data()
<< QVariant(QString("hello"))
<< QString();
+ QTest::newRow("QT_TRID_NOOP")
+ << QString::fromUtf8("ListElement { foo: QT_TRID_NOOP(\"qtn_1st_text\") }")
+ << QVariant(QString("qtn_1st_text"))
+ << QString();
+
QTest::newRow("QT_TR_NOOP extra param")
<< QString::fromUtf8("ListElement { foo: QT_TR_NOOP(\"hello\",\"world\") }")
<< QVariant(QString())
@@ -228,6 +233,11 @@ void tst_qdeclarativelistmodel::static_i18n_data()
<< "ListElement { foo: QT_TRANSLATE_NOOP() }"
<< QVariant(QString())
<< QString("ListElement: improperly specified QT_TRANSLATE_NOOP");
+
+ QTest::newRow("QT_TRID_NOOP missing param")
+ << QString::fromUtf8("ListElement { foo: QT_TRID_NOOP() }")
+ << QVariant(QString())
+ << QString("ListElement: improperly specified QT_TRID_NOOP");
}
void tst_qdeclarativelistmodel::static_i18n()
diff --git a/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro b/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro
index fd55ed5160..99291c1f2d 100644
--- a/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro
+++ b/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro
index 304e168e00..69ebb8e668 100644
--- a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro
+++ b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro
@@ -16,4 +16,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
index c8f8e9139b..27d2c0c1b2 100644
--- a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
+++ b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro b/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro
index f2b5928915..63944117d6 100644
--- a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro
+++ b/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro
index a51eaf34de..c22e8cc9e7 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro
+++ b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro
@@ -15,4 +15,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro b/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro
index 9823c21836..d21c12ad42 100644
--- a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro
+++ b/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro
@@ -13,4 +13,4 @@ symbian: {
}
CONFIG += parallel_test
-QT += core-private gui-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private
diff --git a/tests/auto/declarative/qdeclarativev4/qdeclarativev4.pro b/tests/auto/declarative/qdeclarativev4/qdeclarativev4.pro
index 9b66edff41..0701d95902 100644
--- a/tests/auto/declarative/qdeclarativev4/qdeclarativev4.pro
+++ b/tests/auto/declarative/qdeclarativev4/qdeclarativev4.pro
@@ -16,4 +16,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro b/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro
index f1c64398e9..79bac3998e 100644
--- a/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro
+++ b/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro
@@ -17,4 +17,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro b/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro
index d7dfe96c65..aae48ca14e 100644
--- a/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro
+++ b/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
index 139d4b4e0b..6733d3595e 100644
--- a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
+++ b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
@@ -18,4 +18,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qjsengine/tst_qjsengine.cpp b/tests/auto/declarative/qjsengine/tst_qjsengine.cpp
index d2f4b3b6ac..a6b4251c36 100644
--- a/tests/auto/declarative/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/declarative/qjsengine/tst_qjsengine.cpp
@@ -325,6 +325,7 @@ private slots:
void dateRoundtripQtJSQt();
void dateConversionJSQt();
void dateConversionQtJS();
+ void functionPrototypeExtensions();
};
tst_QJSEngine::tst_QJSEngine()
@@ -6478,6 +6479,24 @@ void tst_QJSEngine::scriptValueFromQMetaObject()
}
#endif
+void tst_QJSEngine::functionPrototypeExtensions()
+{
+ // QJS adds connect and disconnect properties to Function.prototype.
+ QJSEngine eng;
+ QJSValue funProto = eng.globalObject().property("Function").property("prototype");
+ QVERIFY(funProto.isFunction());
+ QVERIFY(funProto.property("connect").isFunction());
+ QCOMPARE(funProto.propertyFlags("connect"), QJSValue::SkipInEnumeration);
+ QVERIFY(funProto.property("disconnect").isFunction());
+ QCOMPARE(funProto.propertyFlags("disconnect"), QJSValue::SkipInEnumeration);
+
+ // No properties should appear in for-in statements.
+ QJSValue props = eng.evaluate("props = []; for (var p in Function.prototype) props.push(p); props");
+ QVERIFY(!eng.hasUncaughtException());
+ QVERIFY(props.isArray());
+ QCOMPARE(props.property("length").toInt32(), 0);
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"
diff --git a/tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro b/tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro
index b32235aec0..1c2130d5cf 100644
--- a/tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro
+++ b/tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro
@@ -7,4 +7,4 @@ SOURCES += tst_qpacketprotocol.cpp \
../shared/debugutil.cpp
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qsgflickable/qsgflickable.pro b/tests/auto/declarative/qsgflickable/qsgflickable.pro
index d5e5767e90..8aa66bacb8 100644
--- a/tests/auto/declarative/qsgflickable/qsgflickable.pro
+++ b/tests/auto/declarative/qsgflickable/qsgflickable.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qsgflipable/qsgflipable.pro b/tests/auto/declarative/qsgflipable/qsgflipable.pro
index c3998c1f9c..e28de1b610 100644
--- a/tests/auto/declarative/qsgflipable/qsgflipable.pro
+++ b/tests/auto/declarative/qsgflipable/qsgflipable.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qsggridview/qsggridview.pro b/tests/auto/declarative/qsggridview/qsggridview.pro
index a8b3484f0d..00c7d96529 100644
--- a/tests/auto/declarative/qsggridview/qsggridview.pro
+++ b/tests/auto/declarative/qsggridview/qsggridview.pro
@@ -14,5 +14,5 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
QT += opengl-private
diff --git a/tests/auto/declarative/qsgitem/tst_qsgitem.cpp b/tests/auto/declarative/qsgitem/tst_qsgitem.cpp
index 7a612c433b..05e59a69f0 100644
--- a/tests/auto/declarative/qsgitem/tst_qsgitem.cpp
+++ b/tests/auto/declarative/qsgitem/tst_qsgitem.cpp
@@ -127,6 +127,9 @@ private slots:
void wheelEvent_data();
void wheelEvent();
+ void hoverEvent_data();
+ void hoverEvent();
+ void hoverEventInParent();
private:
void ensureFocus(QWidget *w) {
@@ -894,6 +897,151 @@ void tst_qsgitem::wheelEvent()
delete canvas;
}
+class HoverItem : public QSGItem
+{
+Q_OBJECT
+public:
+ HoverItem(QSGItem *parent = 0)
+ : QSGItem(parent), hoverEnterCount(0), hoverMoveCount(0), hoverLeaveCount(0)
+ { }
+ void resetCounters() {
+ hoverEnterCount = 0;
+ hoverMoveCount = 0;
+ hoverLeaveCount = 0;
+ }
+ int hoverEnterCount;
+ int hoverMoveCount;
+ int hoverLeaveCount;
+protected:
+ virtual void hoverEnterEvent(QHoverEvent *event) {
+ event->accept();
+ ++hoverEnterCount;
+ }
+ virtual void hoverMoveEvent(QHoverEvent *event) {
+ event->accept();
+ ++hoverMoveCount;
+ }
+ virtual void hoverLeaveEvent(QHoverEvent *event) {
+ event->accept();
+ ++hoverLeaveCount;
+ }
+};
+
+void tst_qsgitem::hoverEvent_data()
+{
+ QTest::addColumn<bool>("visible");
+ QTest::addColumn<bool>("enabled");
+ QTest::addColumn<bool>("acceptHoverEvents");
+
+ QTest::newRow("visible, enabled, accept hover") << true << true << true;
+ QTest::newRow("visible, disabled, accept hover") << true << false << true;
+ QTest::newRow("invisible, enabled, accept hover") << false << true << true;
+ QTest::newRow("invisible, disabled, accept hover") << false << false << true;
+
+ QTest::newRow("visible, enabled, not accept hover") << true << true << false;
+ QTest::newRow("visible, disabled, not accept hover") << true << false << false;
+ QTest::newRow("invisible, enabled, not accept hover") << false << true << false;
+ QTest::newRow("invisible, disabled, not accept hover") << false << false << false;
+}
+
+// ### For some unknown reason QTest::mouseMove() isn't working correctly.
+static void sendMouseMove(QObject *object, const QPoint &position)
+{
+ QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, 0);
+ QApplication::sendEvent(object, &moveEvent);
+}
+
+void tst_qsgitem::hoverEvent()
+{
+ QFETCH(bool, visible);
+ QFETCH(bool, enabled);
+ QFETCH(bool, acceptHoverEvents);
+
+ QSGCanvas *canvas = new QSGCanvas();
+ canvas->resize(200, 200);
+ canvas->show();
+
+ HoverItem *item = new HoverItem;
+ item->setSize(QSizeF(100, 100));
+ item->setParentItem(canvas->rootItem());
+
+ item->setEnabled(enabled);
+ item->setVisible(visible);
+ item->setAcceptHoverEvents(acceptHoverEvents);
+
+ const QPoint outside(150, 150);
+ const QPoint inside(50, 50);
+ const QPoint anotherInside(51, 51);
+
+ sendMouseMove(canvas, outside);
+ item->resetCounters();
+
+ // Enter, then move twice inside, then leave.
+ sendMouseMove(canvas, inside);
+ sendMouseMove(canvas, anotherInside);
+ sendMouseMove(canvas, inside);
+ sendMouseMove(canvas, outside);
+
+ const bool shouldReceiveHoverEvents = visible && enabled && acceptHoverEvents;
+ if (shouldReceiveHoverEvents) {
+ QCOMPARE(item->hoverEnterCount, 1);
+ QCOMPARE(item->hoverMoveCount, 2);
+ QCOMPARE(item->hoverLeaveCount, 1);
+ } else {
+ QCOMPARE(item->hoverEnterCount, 0);
+ QCOMPARE(item->hoverMoveCount, 0);
+ QCOMPARE(item->hoverLeaveCount, 0);
+ }
+
+ delete canvas;
+}
+
+void tst_qsgitem::hoverEventInParent()
+{
+ QSGCanvas *canvas = new QSGCanvas();
+ canvas->resize(200, 200);
+ canvas->show();
+
+ HoverItem *parentItem = new HoverItem(canvas->rootItem());
+ parentItem->setSize(QSizeF(200, 200));
+ parentItem->setAcceptHoverEvents(true);
+
+ HoverItem *leftItem = new HoverItem(parentItem);
+ leftItem->setSize(QSizeF(100, 200));
+ leftItem->setAcceptHoverEvents(true);
+
+ HoverItem *rightItem = new HoverItem(parentItem);
+ rightItem->setSize(QSizeF(100, 200));
+ rightItem->setPos(QPointF(100, 0));
+ rightItem->setAcceptHoverEvents(true);
+
+ const QPoint insideLeft(50, 100);
+ const QPoint insideRight(150, 100);
+
+ sendMouseMove(canvas, insideLeft);
+ parentItem->resetCounters();
+ leftItem->resetCounters();
+ rightItem->resetCounters();
+
+ sendMouseMove(canvas, insideRight);
+ QCOMPARE(parentItem->hoverEnterCount, 0);
+ QCOMPARE(parentItem->hoverLeaveCount, 0);
+ QCOMPARE(leftItem->hoverEnterCount, 0);
+ QCOMPARE(leftItem->hoverLeaveCount, 1);
+ QCOMPARE(rightItem->hoverEnterCount, 1);
+ QCOMPARE(rightItem->hoverLeaveCount, 0);
+
+ sendMouseMove(canvas, insideLeft);
+ QCOMPARE(parentItem->hoverEnterCount, 0);
+ QCOMPARE(parentItem->hoverLeaveCount, 0);
+ QCOMPARE(leftItem->hoverEnterCount, 1);
+ QCOMPARE(leftItem->hoverLeaveCount, 1);
+ QCOMPARE(rightItem->hoverEnterCount, 1);
+ QCOMPARE(rightItem->hoverLeaveCount, 1);
+
+ delete canvas;
+}
+
QTEST_MAIN(tst_qsgitem)
#include "tst_qsgitem.moc"
diff --git a/tests/auto/declarative/qsglistview/qsglistview.pro b/tests/auto/declarative/qsglistview/qsglistview.pro
index 3e18e9b467..4c781887ce 100644
--- a/tests/auto/declarative/qsglistview/qsglistview.pro
+++ b/tests/auto/declarative/qsglistview/qsglistview.pro
@@ -14,5 +14,5 @@ symbian: {
}
CONFIG += parallel_test
-QT += core-private gui-private declarative-private widgets widgets-private
+QT += core-private gui-private declarative-private widgets widgets-private v8-private
QT += opengl-private
diff --git a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp
index 94d6cf3d45..1eecd58278 100644
--- a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp
+++ b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp
@@ -1124,6 +1124,7 @@ void tst_QSGListView::enforceRange_withoutHighlight()
QSGView *canvas = createView();
canvas->show();
+ QTest::qWaitForWindowShown(canvas);
TestModel model;
model.addItem("Item 0", "a");
diff --git a/tests/auto/declarative/qsgpathview/qsgpathview.pro b/tests/auto/declarative/qsgpathview/qsgpathview.pro
index eb188666bb..ae0b1ed630 100644
--- a/tests/auto/declarative/qsgpathview/qsgpathview.pro
+++ b/tests/auto/declarative/qsgpathview/qsgpathview.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qsgpositioners/qsgpositioners.pro b/tests/auto/declarative/qsgpositioners/qsgpositioners.pro
index bf8110ffd4..ae470fa2fc 100644
--- a/tests/auto/declarative/qsgpositioners/qsgpositioners.pro
+++ b/tests/auto/declarative/qsgpositioners/qsgpositioners.pro
@@ -13,5 +13,5 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
QT += opengl-private
diff --git a/tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp b/tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp
index 137e6acd77..0a1c4dff77 100644
--- a/tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp
+++ b/tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp
@@ -160,7 +160,7 @@ void tst_qsgpositioners::test_horizontal_rtl()
// Change the width of the row and check that items stay to the right
row->setWidth(200);
- QCOMPARE(one->x(), 150.0);
+ QTRY_COMPARE(one->x(), 150.0);
QCOMPARE(one->y(), 0.0);
QCOMPARE(two->x(), 130.0);
QCOMPARE(two->y(), 0.0);
@@ -580,7 +580,7 @@ void tst_qsgpositioners::test_grid_rightToLeft()
// Change the width of the grid and check that items stay to the right
grid->setWidth(200);
- QCOMPARE(one->x(), 150.0);
+ QTRY_COMPARE(one->x(), 150.0);
QCOMPARE(one->y(), 0.0);
QCOMPARE(two->x(), 130.0);
QCOMPARE(two->y(), 0.0);
@@ -1086,16 +1086,16 @@ void tst_qsgpositioners::test_flow_resize()
QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
QVERIFY(five != 0);
- QCOMPARE(one->x(), 0.0);
- QCOMPARE(one->y(), 0.0);
- QCOMPARE(two->x(), 50.0);
- QCOMPARE(two->y(), 0.0);
- QCOMPARE(three->x(), 70.0);
- QCOMPARE(three->y(), 0.0);
- QCOMPARE(four->x(), 0.0);
- QCOMPARE(four->y(), 50.0);
- QCOMPARE(five->x(), 50.0);
- QCOMPARE(five->y(), 50.0);
+ QTRY_COMPARE(one->x(), 0.0);
+ QTRY_COMPARE(one->y(), 0.0);
+ QTRY_COMPARE(two->x(), 50.0);
+ QTRY_COMPARE(two->y(), 0.0);
+ QTRY_COMPARE(three->x(), 70.0);
+ QTRY_COMPARE(three->y(), 0.0);
+ QTRY_COMPARE(four->x(), 0.0);
+ QTRY_COMPARE(four->y(), 50.0);
+ QTRY_COMPARE(five->x(), 50.0);
+ QTRY_COMPARE(five->y(), 50.0);
delete canvas;
}
@@ -1110,7 +1110,7 @@ void tst_qsgpositioners::test_flow_resize_rightToLeft()
root->setProperty("testRightToLeft", true);
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
- QVERIFY(one != 0);
+ QTRY_VERIFY(one != 0);
QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
QVERIFY(two != 0);
QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
@@ -1294,7 +1294,7 @@ void tst_qsgpositioners::test_mirroring()
break;
QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
- QVERIFY(itemA->x() != itemB->x());
+ QTRY_VERIFY(itemA->x() != itemB->x());
}
QSGItemPrivate* rootPrivateB = QSGItemPrivate::get(rootB);
@@ -1311,7 +1311,7 @@ void tst_qsgpositioners::test_mirroring()
break;
QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
- QCOMPARE(itemA->x(), itemB->x());
+ QTRY_COMPARE(itemA->x(), itemB->x());
}
rootA->setProperty("testRightToLeft", false); // layoutDirection: Qt.LeftToRight
@@ -1324,7 +1324,7 @@ void tst_qsgpositioners::test_mirroring()
break;
QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
- QCOMPARE(itemA->x(), itemB->x());
+ QTRY_COMPARE(itemA->x(), itemB->x());
}
delete canvasA;
delete canvasB;
@@ -1428,12 +1428,9 @@ void tst_qsgpositioners::test_attachedproperties_dynamic()
row->metaObject()->invokeMethod(row, "createSubRect");
- posIndex = rect1->property("index").toInt();
- QVERIFY(posIndex == 1);
- isFirst = rect1->property("firstItem").toBool();
- QVERIFY(isFirst == false);
- isLast = rect1->property("lastItem").toBool();
- QVERIFY(isLast == false);
+ QTRY_VERIFY(rect1->property("index").toInt() == 1);
+ QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
+ QTRY_VERIFY(rect1->property("lastItem").toBool() == false);
QSGRectangle *rect2 = canvas->rootObject()->findChild<QSGRectangle *>("rect2");
QVERIFY(rect2 != 0);
@@ -1449,12 +1446,9 @@ void tst_qsgpositioners::test_attachedproperties_dynamic()
qApp->processEvents(QEventLoop::DeferredDeletion);
- posIndex = rect1->property("index").toInt();
- QVERIFY(posIndex == 1);
- isFirst = rect1->property("firstItem").toBool();
- QVERIFY(isFirst == false);
- isLast = rect1->property("lastItem").toBool();
- QVERIFY(isLast == true);
+ QTRY_VERIFY(rect1->property("index").toInt() == 1);
+ QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
+ QTRY_VERIFY(rect1->property("lastItem").toBool() == true);
delete canvas;
}
@@ -1464,6 +1458,8 @@ QSGView *tst_qsgpositioners::createView(const QString &filename)
QSGView *canvas = new QSGView(0);
canvas->setSource(QUrl::fromLocalFile(filename));
+ canvas->show();
+ QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
return canvas;
}
diff --git a/tests/auto/declarative/qsgtext/qsgtext.pro b/tests/auto/declarative/qsgtext/qsgtext.pro
index 5254d1ebeb..4aa90f459c 100644
--- a/tests/auto/declarative/qsgtext/qsgtext.pro
+++ b/tests/auto/declarative/qsgtext/qsgtext.pro
@@ -19,5 +19,5 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
QT += opengl-private
diff --git a/tests/auto/declarative/qsgtextedit/qsgtextedit.pro b/tests/auto/declarative/qsgtextedit/qsgtextedit.pro
index 491bb2d3f3..4e233f3a10 100644
--- a/tests/auto/declarative/qsgtextedit/qsgtextedit.pro
+++ b/tests/auto/declarative/qsgtextedit/qsgtextedit.pro
@@ -12,7 +12,7 @@ symbian: {
} else {
DEFINES += SRCDIR=\\\"$$PWD\\\"
}
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
QT += opengl-private
qpa:CONFIG+=insignificant_test # QTBUG-21010, fails unstably
diff --git a/tests/auto/declarative/qsgtextinput/qsgtextinput.pro b/tests/auto/declarative/qsgtextinput/qsgtextinput.pro
index 56a811fa6d..fceef18487 100644
--- a/tests/auto/declarative/qsgtextinput/qsgtextinput.pro
+++ b/tests/auto/declarative/qsgtextinput/qsgtextinput.pro
@@ -12,5 +12,5 @@ symbian: {
DEFINES += SRCDIR=\\\"$$PWD\\\"
}
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
QT += opengl-private
diff --git a/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp b/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp
index 3cc0dc196b..32e59c2a6d 100644
--- a/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp
+++ b/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp
@@ -2197,7 +2197,7 @@ public:
virtual QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data)
{
nbPaint++;
- return QSGTextInput::updatePaintNode(node, data);
+// return QSGTextInput::updatePaintNode(node, data);
}
int nbPaint;
};
diff --git a/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro b/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro
index 8f433c1208..7770f8ff0f 100644
--- a/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro
+++ b/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp b/tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp
index 7470153933..40fddef21b 100644
--- a/tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp
+++ b/tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp
@@ -38,6 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "../../../shared/util.h"
#include <qtest.h>
#include <QtTest/QSignalSpy>
#include <QStandardItemModel>
@@ -88,6 +89,13 @@ public:
list << "one" << "two" << "three" << "four";
}
+ void emitMove(int sourceFirst, int sourceLast, int destinationChild) {
+ emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild);
+ emit endMoveRows();
+ }
+
+ QStringList list;
+
public slots:
void set(int idx, QString string) {
list[idx] = string;
@@ -103,9 +111,6 @@ protected:
return list.at(index.row());
return QVariant();
}
-
-private:
- QStringList list;
};
@@ -125,6 +130,8 @@ private slots:
void singleRole();
void modelProperties();
void noDelegate();
+ void qaimRowsMoved();
+ void qaimRowsMoved_data();
private:
QDeclarativeEngine engine;
@@ -538,6 +545,72 @@ void tst_qsgvisualdatamodel::noDelegate()
}
+void tst_qsgvisualdatamodel::qaimRowsMoved()
+{
+ // Test parameters passed in QAIM::rowsMoved() signal are converted correctly
+ // when translated and emitted as the QListModelInterface::itemsMoved() signal
+ QFETCH(int, sourceFirst);
+ QFETCH(int, sourceLast);
+ QFETCH(int, destinationChild);
+ QFETCH(int, expectFrom);
+ QFETCH(int, expectTo);
+ QFETCH(int, expectCount);
+
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/visualdatamodel.qml"));
+
+ SingleRoleModel model;
+ model.list.clear();
+ for (int i=0; i<30; i++)
+ model.list << ("item " + i);
+ engine.rootContext()->setContextProperty("myModel", &model);
+
+ QSGVisualDataModel *obj = qobject_cast<QSGVisualDataModel*>(c.create());
+ QVERIFY(obj != 0);
+
+ QSignalSpy spy(obj, SIGNAL(itemsMoved(int,int,int)));
+ model.emitMove(sourceFirst, sourceLast, destinationChild);
+ QTRY_COMPARE(spy.count(), 1);
+
+ QCOMPARE(spy[0].count(), 3);
+ QCOMPARE(spy[0][0].toInt(), expectFrom);
+ QCOMPARE(spy[0][1].toInt(), expectTo);
+ QCOMPARE(spy[0][2].toInt(), expectCount);
+
+ delete obj;
+}
+
+void tst_qsgvisualdatamodel::qaimRowsMoved_data()
+{
+ QTest::addColumn<int>("sourceFirst");
+ QTest::addColumn<int>("sourceLast");
+ QTest::addColumn<int>("destinationChild");
+ QTest::addColumn<int>("expectFrom");
+ QTest::addColumn<int>("expectTo");
+ QTest::addColumn<int>("expectCount");
+
+ QTest::newRow("move 1 forward")
+ << 1 << 1 << 6
+ << 1 << 5 << 1;
+
+ QTest::newRow("move 1 backwards")
+ << 4 << 4 << 1
+ << 4 << 1 << 1;
+
+ QTest::newRow("move multiple forwards")
+ << 0 << 2 << 13
+ << 0 << 10 << 3;
+
+ QTest::newRow("move multiple forwards, with same to")
+ << 0 << 1 << 3
+ << 0 << 1 << 2;
+
+ QTest::newRow("move multiple backwards")
+ << 10 << 14 << 1
+ << 10 << 1 << 5;
+}
+
+
template<typename T>
T *tst_qsgvisualdatamodel::findItem(QSGItem *parent, const QString &objectName, int index)
{
diff --git a/tests/auto/declarative/v8/Makefile.nonqt b/tests/auto/declarative/v8/Makefile.nonqt
deleted file mode 100644
index 7ab695ba6a..0000000000
--- a/tests/auto/declarative/v8/Makefile.nonqt
+++ /dev/null
@@ -1,11 +0,0 @@
-release-m32:
- g++ -o v8test_release_m32 -m32 -O2 v8main.cpp v8test.cpp -lpthread -L../../../../src/3rdparty/v8/ -lv8
-
-debug-m32:
- g++ -o v8test_debug_m32 -m32 -g v8main.cpp v8test.cpp -lpthread -L../../../../src/3rdparty/v8/ -lv8_g
-
-release:
- g++ -o v8test_release -O2 v8main.cpp v8test.cpp -lpthread -L../../../../src/3rdparty/v8/ -lv8
-
-debug:
- g++ -o v8test_debug -g v8main.cpp v8test.cpp -lpthread -L../../../../src/3rdparty/v8/ -lv8_g
diff --git a/tests/auto/declarative/v8/README.txt b/tests/auto/declarative/v8/README.txt
deleted file mode 100644
index a5df6201be..0000000000
--- a/tests/auto/declarative/v8/README.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-The v8 tests are actually implemented in v8test.[h|cpp]. There are also QtTest
-(tst_v8.cpp) and non-Qt (v8main.cpp) stubs provided to run these tests. This
-is done to allow the tests to be run both in the Qt CI system, and manually
-without a build of Qt. The latter is necessary to run them against more exotic
-build of V8, like the ARM simulator.
-
-To build the non-Qt version of the tests, first build a debug or release V8
-library under src/3rdparty/v8 using scons, and then use the Makefile.nonqt
-makefile selecting one of the following targets:
- release: Build the tests with -O2 and link against libv8
- debug: Build the tests with -g and link against libv8_g
- release-m32: Build the tests with -O2 -m32 and link against libv8
- debug-m32: Build the tests with -g -m32 and link against libv8_g
diff --git a/tests/auto/declarative/v8/tst_v8.cpp b/tests/auto/declarative/v8/tst_v8.cpp
deleted file mode 100644
index 32d100e968..0000000000
--- a/tests/auto/declarative/v8/tst_v8.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qtest.h>
-#include "v8test.h"
-
-using namespace v8;
-
-class tst_v8 : public QObject
-{
- Q_OBJECT
-public:
- tst_v8() {}
-
-private slots:
- void initTestCase() {}
- void cleanupTestCase() {}
-
- void eval();
- void userobjectcompare();
-};
-
-void tst_v8::eval()
-{
- QVERIFY(v8test_eval());
-}
-
-void tst_v8::userobjectcompare()
-{
- QVERIFY(v8test_userobjectcompare());
-}
-
-int main(int argc, char *argv[])
-{
- V8::SetFlagsFromCommandLine(&argc, argv, true);
-
- QCoreApplication app(argc, argv);
- tst_v8 tc;
- return QTest::qExec(&tc, argc, argv);
-}
-
-#include "tst_v8.moc"
diff --git a/tests/auto/declarative/v8/v8.pro b/tests/auto/declarative/v8/v8.pro
deleted file mode 100644
index bd6dfa9d5c..0000000000
--- a/tests/auto/declarative/v8/v8.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-load(qttest_p4)
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_v8.cpp v8test.cpp
-HEADERS += v8test.h
-
-CONFIG += parallel_test
-
-QT += declarative
-DEFINES += USING_V8_SHARED
diff --git a/tests/auto/declarative/v8/v8main.cpp b/tests/auto/declarative/v8/v8main.cpp
deleted file mode 100644
index 5930f53f90..0000000000
--- a/tests/auto/declarative/v8/v8main.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "v8test.h"
-#include <stdio.h>
-
-#define RUN_TEST(testname) { \
- if (!v8test_ ## testname()) \
- printf ("Test %s FAILED\n", # testname); \
-}
-
-int main(int argc, char *argv[])
-{
- v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
-
- RUN_TEST(eval);
- RUN_TEST(userobjectcompare);
-
- return -1;
-}
diff --git a/tests/auto/declarative/v8/v8test.cpp b/tests/auto/declarative/v8/v8test.cpp
deleted file mode 100644
index 27d39c5970..0000000000
--- a/tests/auto/declarative/v8/v8test.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "v8test.h"
-
-using namespace v8;
-
-#define BEGINTEST() bool _testPassed = true;
-#define ENDTEST() return _testPassed;
-
-#define VERIFY(expr) { \
- if (!(expr)) { \
- fprintf(stderr, "FAIL: %s:%d %s\n", __FILE__, __LINE__, # expr); \
- _testPassed = false; \
- goto cleanup; \
- } \
-}
-
-
-bool v8test_eval()
-{
- BEGINTEST();
-
- HandleScope handle_scope;
- Persistent<Context> context = Context::New();
- Context::Scope context_scope(context);
-
- Local<Object> qmlglobal = Object::New();
- qmlglobal->Set(String::New("a"), Integer::New(1922));
-
- Local<Script> script = Script::Compile(String::New("eval(\"a\")"), NULL, NULL,
- Handle<String>(), Script::QmlMode);
-
- TryCatch tc;
- Local<Value> result = script->Run(qmlglobal);
-
- VERIFY(!tc.HasCaught());
- VERIFY(result->Int32Value() == 1922);
-
-cleanup:
- context.Dispose();
-
- ENDTEST();
-}
-
-static int userObjectComparisonCalled = 0;
-static bool userObjectComparisonReturn = false;
-static Local<Object> expectedLhs;
-static Local<Object> expectedRhs;
-static bool expectedObjectsCompared = false;
-
-#define SET_EXPECTED(lhs, rhs) { \
- expectedObjectsCompared = false; \
- expectedLhs = lhs; \
- expectedRhs = rhs; \
-}
-
-static bool UserObjectComparison(Local<Object> lhs, Local<Object> rhs)
-{
- userObjectComparisonCalled++;
-
- expectedObjectsCompared = (lhs == expectedLhs && rhs == expectedRhs);
-
- return userObjectComparisonReturn;
-}
-
-inline bool runscript(const char *source) {
- Local<Script> script = Script::Compile(String::New(source));
- Local<Value> result = script->Run();
- return result->BooleanValue();
-}
-
-bool v8test_userobjectcompare()
-{
- BEGINTEST();
-
- HandleScope handle_scope;
- Persistent<Context> context = Context::New();
- Context::Scope context_scope(context);
-
- V8::SetUserObjectComparisonCallbackFunction(UserObjectComparison);
-
- Local<ObjectTemplate> ot = ObjectTemplate::New();
- ot->MarkAsUseUserObjectComparison();
-
- Local<Object> uoc1 = ot->NewInstance();
- Local<Object> uoc2 = ot->NewInstance();
- context->Global()->Set(String::New("uoc1a"), uoc1);
- context->Global()->Set(String::New("uoc1b"), uoc1);
- context->Global()->Set(String::New("uoc2"), uoc2);
- Local<Object> obj1 = Object::New();
- context->Global()->Set(String::New("obj1a"), obj1);
- context->Global()->Set(String::New("obj1b"), obj1);
- context->Global()->Set(String::New("obj2"), Object::New());
- Local<String> string1 = String::New("Hello World");
- context->Global()->Set(String::New("string1a"), string1);
- context->Global()->Set(String::New("string1b"), string1);
- context->Global()->Set(String::New("string2"), v8::String::New("Goodbye World"));
-
- // XXX Opportunity for optimization - don't invoke user callback if objects are
- // equal.
-#if 0
- userObjectComparisonCalled = 0; userObjectComparisonReturn = false;
- VERIFY(true == runscript("uoc1a == uoc1b"));
- VERIFY(userObjectComparisonCalled == 0);
-#endif
-
- // Comparing two uoc objects invokes uoc
- userObjectComparisonCalled = 0;
- userObjectComparisonReturn = false;
- VERIFY(false == runscript("uoc1a == uoc2"));
- VERIFY(userObjectComparisonCalled == 1);
-
- VERIFY(false == runscript("uoc2 == uoc1a"));
- VERIFY(userObjectComparisonCalled == 2);
- userObjectComparisonReturn = true;
- VERIFY(true == runscript("uoc1a == uoc2"));
- VERIFY(userObjectComparisonCalled == 3);
- VERIFY(true == runscript("uoc2 == uoc1a"));
- VERIFY(userObjectComparisonCalled == 4);
-
- // != on two uoc object invokes uoc
- userObjectComparisonCalled = 0;
- userObjectComparisonReturn = false;
- VERIFY(true == runscript("uoc1a != uoc2"));
- VERIFY(userObjectComparisonCalled == 1);
- VERIFY(true == runscript("uoc2 != uoc1a"));
- VERIFY(userObjectComparisonCalled == 2);
- userObjectComparisonReturn = true;
- VERIFY(false == runscript("uoc1a != uoc2"));
- VERIFY(userObjectComparisonCalled == 3);
- VERIFY(false == runscript("uoc2 != uoc1a"));
- VERIFY(userObjectComparisonCalled == 4);
-
- // Comparison against a non-object doesn't invoke uoc
- userObjectComparisonCalled = 0;
- userObjectComparisonReturn = false;
- VERIFY(false == runscript("uoc1a == string1a"));
- VERIFY(userObjectComparisonCalled == 0);
- VERIFY(false == runscript("string1a == uoc1a"));
- VERIFY(userObjectComparisonCalled == 0);
- VERIFY(false == runscript("2 == uoc1a"));
- VERIFY(userObjectComparisonCalled == 0);
- VERIFY(true == runscript("uoc1a != string1a"));
- VERIFY(userObjectComparisonCalled == 0);
- VERIFY(true == runscript("string1a != uoc1a"));
- VERIFY(userObjectComparisonCalled == 0);
- VERIFY(true == runscript("2 != uoc1a"));
- VERIFY(userObjectComparisonCalled == 0);
-
- // Comparison against a non-uoc-object still invokes uoc
- userObjectComparisonCalled = 0;
- userObjectComparisonReturn = false;
- VERIFY(false == runscript("uoc1a == obj1a"));
- VERIFY(userObjectComparisonCalled == 1);
- VERIFY(false == runscript("obj1a == uoc1a"));
- VERIFY(userObjectComparisonCalled == 2);
- userObjectComparisonReturn = true;
- VERIFY(true == runscript("uoc1a == obj1a"));
- VERIFY(userObjectComparisonCalled == 3);
- VERIFY(true == runscript("obj1a == uoc1a"));
- VERIFY(userObjectComparisonCalled == 4);
-
- // != comparison against a non-uoc-object still invokes uoc
- userObjectComparisonCalled = 0;
- userObjectComparisonReturn = false;
- VERIFY(true == runscript("uoc1a != obj1a"));
- VERIFY(userObjectComparisonCalled == 1);
- VERIFY(true == runscript("obj1a != uoc1a"));
- VERIFY(userObjectComparisonCalled == 2);
- userObjectComparisonReturn = true;
- VERIFY(false == runscript("uoc1a != obj1a"));
- VERIFY(userObjectComparisonCalled == 3);
- VERIFY(false == runscript("obj1a != uoc1a"));
- VERIFY(userObjectComparisonCalled == 4);
-
- // Comparing two non-uoc objects does not invoke uoc
- userObjectComparisonCalled = 0;
- userObjectComparisonReturn = false;
- VERIFY(true == runscript("obj1a == obj1a"));
- VERIFY(true == runscript("obj1a == obj1b"));
- VERIFY(false == runscript("obj1a == obj2"));
- VERIFY(false == runscript("obj1a == string1a"));
- VERIFY(true == runscript("string1a == string1a"));
- VERIFY(true == runscript("string1a == string1b"));
- VERIFY(false == runscript("string1a == string2"));
- VERIFY(userObjectComparisonCalled == 0);
-
- // Correct lhs and rhs passed to uoc
- userObjectComparisonCalled = 0;
- userObjectComparisonReturn = false;
- SET_EXPECTED(uoc1, uoc2);
- VERIFY(false == runscript("uoc1a == uoc2"));
- VERIFY(true == expectedObjectsCompared);
- SET_EXPECTED(uoc2, uoc1);
- VERIFY(false == runscript("uoc2 == uoc1a"));
- VERIFY(true == expectedObjectsCompared);
- SET_EXPECTED(uoc1, uoc2);
- VERIFY(true == runscript("uoc1a != uoc2"));
- VERIFY(true == expectedObjectsCompared);
- SET_EXPECTED(uoc2, uoc1);
- VERIFY(true == runscript("uoc2 != uoc1a"));
- VERIFY(true == expectedObjectsCompared);
- SET_EXPECTED(uoc1, obj1);
- VERIFY(false == runscript("uoc1a == obj1a"));
- VERIFY(true == expectedObjectsCompared);
- SET_EXPECTED(obj1, uoc1);
- VERIFY(false == runscript("obj1a == uoc1a"));
- VERIFY(true == expectedObjectsCompared);
-
-cleanup:
- V8::SetUserObjectComparisonCallbackFunction(0);
- context.Dispose();
-
- ENDTEST();
-}
diff --git a/tests/auto/declarative/v8/v8test.h b/tests/auto/declarative/v8/v8test.h
deleted file mode 100644
index 31acefc8b3..0000000000
--- a/tests/auto/declarative/v8/v8test.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef V8TEST_H
-#define V8TEST_H
-
-#include "../../../../src/3rdparty/v8/include/v8.h"
-
-bool v8test_eval();
-bool v8test_userobjectcompare();
-
-#endif // V8TEST_H
-
diff --git a/tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro b/tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro
index 12b545811d..dc87f68769 100644
--- a/tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro
+++ b/tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro
@@ -13,4 +13,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro b/tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro
index 2daebc7a54..c6e87ca9ca 100644
--- a/tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro
+++ b/tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro
@@ -13,4 +13,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro b/tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro
index 4fd4ddd8b0..15512bd749 100644
--- a/tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro
+++ b/tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro
@@ -13,4 +13,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro b/tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro
index 6c3bec845a..3dc73e622c 100644
--- a/tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro
+++ b/tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro b/tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro
index c01478380b..8c9d1872db 100644
--- a/tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro
+++ b/tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro b/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro
index 22d015c798..6ec02c54b5 100644
--- a/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro
+++ b/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro
@@ -14,5 +14,5 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
qpa:contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21012 fails on exit (X11-specific)
diff --git a/tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro b/tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro
index eb125599e1..48c4d21df7 100644
--- a/tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro
+++ b/tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro b/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro
index 459f80bec2..05bb55a4b2 100644
--- a/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro
+++ b/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro
@@ -14,5 +14,5 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
qpa:contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21012 fails on exit (X11-specific)
diff --git a/tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp
index b244a24613..5b71f23f36 100644
--- a/tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp
+++ b/tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp
@@ -91,6 +91,7 @@ private slots:
void testQtQuick11Attributes();
void testQtQuick11Attributes_data();
void qtbug_16871();
+ void qtbug_21045();
private:
QDeclarativeEngine engine;
};
@@ -1365,6 +1366,18 @@ void tst_QDeclarativeItem::qtbug_16871()
delete o;
}
+void tst_QDeclarativeItem::qtbug_21045()
+{
+ QDeclarativeComponent component(&engine);
+ QGraphicsScene scene;
+ component.setData("import QtQuick 1.1\nItem{visible: false; focus: true}", QUrl::fromLocalFile("file:"));
+ QObject *o = component.create();
+ QDeclarativeItem* i = qobject_cast<QDeclarativeItem*>(o);
+ QVERIFY(i);
+ scene.addItem(i);
+ QVERIFY(!i->hasActiveFocus());
+}
+
QTEST_MAIN(tst_QDeclarativeItem)
#include "tst_qdeclarativeitem.moc"
diff --git a/tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro b/tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro
index 5eb154dad2..8b3f848ff6 100644
--- a/tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro
+++ b/tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro
@@ -14,4 +14,4 @@ symbian: {
}
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro b/tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro
index 4233096a2d..e37ad5c493 100644
--- a/tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro
+++ b/tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro b/tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro
index cf4ebfbf39..b01f8a31d4 100644
--- a/tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro
+++ b/tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro
@@ -13,4 +13,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro b/tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
index 99094cf101..1afe01ff4e 100644
--- a/tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
+++ b/tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro b/tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro
index 56f9c2df17..c3ceed0c84 100644
--- a/tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro
+++ b/tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro b/tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro
index b80ab88f01..bdf151a849 100644
--- a/tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro
+++ b/tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro
@@ -13,4 +13,4 @@ symbian: {
}
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro b/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro
index ad9a667d57..6253806984 100644
--- a/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro
+++ b/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro
@@ -19,4 +19,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro b/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro
index 2d5461ffc1..4e18222663 100644
--- a/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro
+++ b/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro
@@ -12,4 +12,4 @@ symbian: {
} else {
DEFINES += SRCDIR=\\\"$$PWD\\\"
}
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro b/tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro
index d39da270a3..f18c054132 100644
--- a/tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro
+++ b/tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro
@@ -12,4 +12,4 @@ symbian: {
DEFINES += SRCDIR=\\\"$$PWD\\\"
}
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro b/tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro
index ca214b1210..67be35f510 100644
--- a/tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro
+++ b/tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro
@@ -17,4 +17,4 @@ symbian: {
}
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private widgets-private
+QT += core-private gui-private declarative-private qtquick1-private widgets-private v8-private
diff --git a/tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro b/tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro
index a5a0add30f..3f116e1f37 100644
--- a/tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro
+++ b/tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro
@@ -14,4 +14,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
index 6acfe35dca..e8894a8564 100644
--- a/tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
+++ b/tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
@@ -18,4 +18,4 @@ symbian: {
CONFIG += parallel_test
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private declarative-private qtquick1-private
diff --git a/tests/benchmarks/declarative/compilation/tst_compilation.cpp b/tests/benchmarks/declarative/compilation/tst_compilation.cpp
index 98008d8bf8..9b4f9a70e8 100644
--- a/tests/benchmarks/declarative/compilation/tst_compilation.cpp
+++ b/tests/benchmarks/declarative/compilation/tst_compilation.cpp
@@ -44,10 +44,10 @@
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/private/qdeclarativejsengine_p.h>
-#include <QtDeclarative/private/qdeclarativejsnodepool_p.h>
+#include <QtDeclarative/private/qdeclarativejsmemorypool_p.h>
#include <QtDeclarative/private/qdeclarativejsparser_p.h>
#include <QtDeclarative/private/qdeclarativejslexer_p.h>
-#include <QtDeclarative/private/qdeclarativescriptparser_p.h>
+#include <QtDeclarative/private/qdeclarativescript_p.h>
#include <QFile>
#include <QDebug>
@@ -154,7 +154,7 @@ void tst_compilation::scriptparser()
QUrl url = QUrl::fromLocalFile(file);
QBENCHMARK {
- QDeclarativeScriptParser parser;
+ QDeclarativeScript::Parser parser;
parser.parse(data, url);
parser.tree();
}
diff --git a/tests/benchmarks/declarative/creation/creation.pro b/tests/benchmarks/declarative/creation/creation.pro
index 74cb47fb73..8241ace5a6 100644
--- a/tests/benchmarks/declarative/creation/creation.pro
+++ b/tests/benchmarks/declarative/creation/creation.pro
@@ -1,7 +1,7 @@
load(qttest_p4)
TEMPLATE = app
TARGET = tst_creation
-QT += declarative
+QT += declarative qtquick1
macx:CONFIG -= app_bundle
SOURCES += tst_creation.cpp
@@ -13,3 +13,5 @@ symbian {
} else {
DEFINES += SRCDIR=\\\"$$PWD\\\"
}
+
+QT += core-private gui-private declarative-private qtquick1-private
diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp
index 4085688845..6659eb5989 100644
--- a/tests/benchmarks/declarative/creation/tst_creation.cpp
+++ b/tests/benchmarks/declarative/creation/tst_creation.cpp
@@ -48,7 +48,7 @@
#include <QGraphicsItem>
#include <QDeclarativeItem>
#include <QDeclarativeContext>
-#include <private/qdeclarativetextinput_p.h>
+#include <QtQuick1/private/qdeclarativetextinput_p.h>
#include <private/qobject_p.h>
#ifdef Q_OS_SYMBIAN
@@ -111,7 +111,7 @@ tst_creation::tst_creation()
qmlRegisterType<TestType>("Qt.test", 1, 0, "TestType");
//get rid of initialization effects
- QDeclarativeTextInput te;
+ QDeclarative1TextInput te;
}
inline QUrl TEST_FILE(const QString &filename)
@@ -206,7 +206,7 @@ void tst_creation::qobject_10tree_cpp()
void tst_creation::qobject_qmltype()
{
- QDeclarativeType *t = QDeclarativeMetaType::qmlType("Qt/QtObject", 4, 7);
+ QDeclarativeType *t = QDeclarativeMetaType::qmlType("QtQuick/QtObject", 2, 0);
QBENCHMARK {
QObject *obj = t->create();
@@ -350,7 +350,7 @@ void tst_creation::elements_data()
void tst_creation::elements()
{
QFETCH(QByteArray, type);
- QDeclarativeType *t = QDeclarativeMetaType::qmlType(type, 4, 7);
+ QDeclarativeType *t = QDeclarativeMetaType::qmlType(type, 2, 0);
if (!t || !t->isCreatable())
QSKIP("Non-creatable type", SkipSingle);
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index c553070123..c53fd3c7fd 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -540,6 +540,19 @@ int main(int argc, char *argv[])
engine.addImportPath(pluginImportPath);
}
+ // load the QtQuick 1 plugin
+ {
+ QByteArray code("import QtQuick 1.0\nQtObject {}");
+ QDeclarativeComponent c(&engine);
+ c.setData(code, QUrl::fromLocalFile(pluginImportPath + "/loadqtquick1.qml"));
+ c.create();
+ if (!c.errors().isEmpty()) {
+ foreach (const QDeclarativeError &error, c.errors())
+ qWarning() << error.toString();
+ return EXIT_IMPORTERROR;
+ }
+ }
+
// find all QMetaObjects reachable from the builtin module
QSet<const QMetaObject *> defaultReachable = collectReachableMetaObjects();
QList<QDeclarativeType *> defaultTypes = QDeclarativeMetaType::qmlTypes();
diff --git a/tools/qmlplugindump/qmlplugindump.pro b/tools/qmlplugindump/qmlplugindump.pro
index 0ac3a70c14..49134a05ab 100644
--- a/tools/qmlplugindump/qmlplugindump.pro
+++ b/tools/qmlplugindump/qmlplugindump.pro
@@ -2,7 +2,7 @@ TEMPLATE = app
CONFIG += qt uic console
DESTDIR = $$QT.declarative.bins
-QT += declarative declarative-private core-private
+QT += declarative declarative-private qtquick1 core-private
TARGET = qmlplugindump
diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp
index 0139f591a6..cd40ea5f8c 100644
--- a/tools/qmlscene/main.cpp
+++ b/tools/qmlscene/main.cpp
@@ -321,6 +321,7 @@ static void checkAndAdaptVersion(const QUrl &url)
}
QRegExp quick1("^\\s*import +QtQuick +1\\.");
+ QRegExp quick2("^\\s*import +QtQuick +2\\.");
QRegExp qt47("^\\s*import +Qt +4\\.7");
QString envToWrite;
@@ -328,16 +329,20 @@ static void checkAndAdaptVersion(const QUrl &url)
QTextStream stream(&f);
bool codeFound= false;
- while (!codeFound && envToWrite.isEmpty()) {
+ while (!codeFound) {
QString line = stream.readLine();
if (line.contains("{"))
codeFound = true;
- if (quick1.indexIn(line) >= 0) {
+ if (envToWrite.isEmpty() && quick1.indexIn(line) >= 0) {
envToWrite = QLatin1String("quick1");
compat = QLatin1String("QtQuick 1.0");
- } else if (qt47.indexIn(line) >= 0) {
+ } else if (envToWrite.isEmpty() && qt47.indexIn(line) >= 0) {
envToWrite = QLatin1String("qt");
compat = QLatin1String("Qt 4.7");
+ } else if (quick2.indexIn(line) >= 0) {
+ envToWrite.clear();
+ compat.clear();
+ break;
}
}
diff --git a/tools/qmlviewer/qml.pri b/tools/qmlviewer/qml.pri
index f5d3f80feb..e84dfb5c9b 100644
--- a/tools/qmlviewer/qml.pri
+++ b/tools/qmlviewer/qml.pri
@@ -1,4 +1,4 @@
-QT += core-private gui-private declarative-private network sql
+QT += core-private gui-private v8-private declarative-private network sql
contains(QT_CONFIG, opengl) {
QT += opengl
DEFINES += GL_SUPPORTED