aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerMIPS.h32
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.cpp14
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.h1
-rw-r--r--src/imports/localstorage/plugin.cpp27
-rw-r--r--src/imports/testlib/TestCase.qml7
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel.cpp2
-rw-r--r--src/particles/qquickcustomparticle.cpp4
-rw-r--r--src/particles/qquickv4particledata_p.h2
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp2
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp4
-rw-r--r--src/qml/compiler/qv4codegen.cpp3
-rw-r--r--src/qml/compiler/qv4compileddata.cpp2
-rw-r--r--src/qml/compiler/qv4compiler.cpp6
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp2
-rw-r--r--src/qml/compiler/qv4isel_p.cpp2
-rw-r--r--src/qml/debugger/qqmldebugserver.cpp4
-rw-r--r--src/qml/debugger/qqmlenginedebugservice.cpp13
-rw-r--r--src/qml/debugger/qv4debugservice.cpp2
-rw-r--r--src/qml/jit/qv4assembler.cpp20
-rw-r--r--src/qml/jit/qv4assembler_p.h12
-rw-r--r--src/qml/jit/qv4binop.cpp4
-rw-r--r--src/qml/jit/qv4isel_masm.cpp11
-rw-r--r--src/qml/jit/qv4regalloc.cpp2
-rw-r--r--src/qml/jit/qv4targetplatform_p.h65
-rw-r--r--src/qml/jsapi/qjsengine.cpp6
-rw-r--r--src/qml/jsapi/qjsvalue.cpp28
-rw-r--r--src/qml/jsapi/qjsvalue_p.h2
-rw-r--r--src/qml/jsruntime/jsruntime.pri5
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp27
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h10
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp11
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h4
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp61
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h4
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp13
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp11
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4context.cpp19
-rw-r--r--src/qml/jsruntime/qv4context_p.h17
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp9
-rw-r--r--src/qml/jsruntime/qv4dataview_p.h6
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp166
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h23
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp5
-rw-r--r--src/qml/jsruntime/qv4engine.cpp318
-rw-r--r--src/qml/jsruntime/qv4engine_p.h167
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp61
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h22
-rw-r--r--src/qml/jsruntime/qv4function.cpp4
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp95
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h55
-rw-r--r--src/qml/jsruntime/qv4global_p.h4
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp11
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4include.cpp10
-rw-r--r--src/qml/jsruntime/qv4include_p.h2
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h2
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp57
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h28
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp67
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h20
-rw-r--r--src/qml/jsruntime/qv4managed.cpp4
-rw-r--r--src/qml/jsruntime/qv4managed_p.h101
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp3
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp9
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4object.cpp47
-rw-r--r--src/qml/jsruntime/qv4object_p.h79
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp21
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp23
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h4
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp4
-rw-r--r--src/qml/jsruntime/qv4persistent_p.h7
-rw-r--r--src/qml/jsruntime/qv4profiling.cpp3
-rw-r--r--src/qml/jsruntime/qv4property_p.h9
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp59
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h16
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp2
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp34
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h12
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp33
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h7
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h27
-rw-r--r--src/qml/jsruntime/qv4script.cpp10
-rw-r--r--src/qml/jsruntime/qv4script_p.h8
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp24
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h5
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp20
-rw-r--r--src/qml/jsruntime/qv4serialize_p.h2
-rw-r--r--src/qml/jsruntime/qv4sparsearray_p.h12
-rw-r--r--src/qml/jsruntime/qv4string.cpp2
-rw-r--r--src/qml/jsruntime/qv4string_p.h14
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp26
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp17
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h8
-rw-r--r--src/qml/jsruntime/qv4typedvalue_p.h (renamed from src/qml/qml/qqmlabstractexpression.cpp)72
-rw-r--r--src/qml/jsruntime/qv4value.cpp64
-rw-r--r--src/qml/jsruntime/qv4value_inl_p.h293
-rw-r--r--src/qml/jsruntime/qv4value_p.h246
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp5
-rw-r--r--src/qml/memory/memory.pri14
-rw-r--r--src/qml/memory/qv4heap_p.h128
-rw-r--r--src/qml/memory/qv4mm.cpp (renamed from src/qml/jsruntime/qv4mm.cpp)6
-rw-r--r--src/qml/memory/qv4mm_p.h (renamed from src/qml/jsruntime/qv4mm_p.h)6
-rw-r--r--src/qml/qml.pro4
-rw-r--r--src/qml/qml/qml.pri2
-rw-r--r--src/qml/qml/qqmlabstractbinding.cpp116
-rw-r--r--src/qml/qml/qqmlabstractbinding_p.h86
-rw-r--r--src/qml/qml/qqmlabstractexpression_p.h116
-rw-r--r--src/qml/qml/qqmlbinding.cpp238
-rw-r--r--src/qml/qml/qqmlbinding_p.h54
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp26
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h11
-rw-r--r--src/qml/qml/qqmlcomponent.cpp18
-rw-r--r--src/qml/qml/qqmlcontext.cpp10
-rw-r--r--src/qml/qml/qqmlcontext_p.h6
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp18
-rw-r--r--src/qml/qml/qqmlcontextwrapper_p.h8
-rw-r--r--src/qml/qml/qqmldata_p.h3
-rw-r--r--src/qml/qml/qqmlengine.cpp36
-rw-r--r--src/qml/qml/qqmlengine.h4
-rw-r--r--src/qml/qml/qqmlexpression.cpp30
-rw-r--r--src/qml/qml/qqmlexpression_p.h10
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp86
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h43
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp8
-rw-r--r--src/qml/qml/qqmllistwrapper_p.h6
-rw-r--r--src/qml/qml/qqmllocale.cpp32
-rw-r--r--src/qml/qml/qqmllocale_p.h2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp12
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp36
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp12
-rw-r--r--src/qml/qml/qqmlproperty.cpp251
-rw-r--r--src/qml/qml/qqmlproperty_p.h28
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp2
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h4
-rw-r--r--src/qml/qml/qqmltypeloader_p.h2
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp2
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp6
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h4
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding.cpp70
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding_p.h17
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp69
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h4
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp10
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h2
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp59
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp21
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h6
-rw-r--r--src/qml/qml/v8/qv4domerrors.cpp2
-rw-r--r--src/qml/qml/v8/qv4sqlerrors.cpp2
-rw-r--r--src/qml/qml/v8/qv8engine.cpp18
-rw-r--r--src/qml/qml/v8/qv8engine_p.h2
-rw-r--r--src/qml/types/qqmlbind.cpp14
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp33
-rw-r--r--src/qml/types/qqmllistmodel.cpp26
-rw-r--r--src/qml/types/qquickworkerscript.cpp2
-rw-r--r--src/qml/util/qqmladaptormodel.cpp2
-rw-r--r--src/qmldevtools/qmldevtools.pro1
-rw-r--r--src/qmltest/quicktestresult.cpp14
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp2
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp18
-rw-r--r--src/quick/items/context2d/qquickcontext2d_p.h2
-rw-r--r--src/quick/items/qquickimage_p.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp18
-rw-r--r--src/quick/items/qquickitemview.cpp2
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp1
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h12
-rw-r--r--src/quick/items/qquickloader.cpp2
-rw-r--r--src/quick/items/qquickloader_p_p.h2
-rw-r--r--src/quick/items/qquickpainteditem_p.h2
-rw-r--r--src/quick/items/qquickpathview.cpp159
-rw-r--r--src/quick/items/qquickpathview_p_p.h1
-rw-r--r--src/quick/items/qquickpositioners.cpp298
-rw-r--r--src/quick/items/qquickpositioners_p.h38
-rw-r--r--src/quick/items/qquickpositioners_p_p.h25
-rw-r--r--src/quick/items/qquickrepeater.cpp21
-rw-r--r--src/quick/items/qquickstateoperations.cpp56
-rw-r--r--src/quick/items/qquicktext.cpp260
-rw-r--r--src/quick/items/qquicktext_p.h31
-rw-r--r--src/quick/items/qquicktext_p_p.h17
-rw-r--r--src/quick/items/qquicktextedit.cpp210
-rw-r--r--src/quick/items/qquicktextedit_p.h33
-rw-r--r--src/quick/items/qquicktextedit_p_p.h18
-rw-r--r--src/quick/items/qquicktextinput.cpp399
-rw-r--r--src/quick/items/qquicktextinput_p.h69
-rw-r--r--src/quick/items/qquicktextinput_p_p.h24
-rw-r--r--src/quick/items/qquickview.cpp18
-rw-r--r--src/quick/items/qquickwindow.cpp37
-rw-r--r--src/quick/items/qquickwindow.h3
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp33
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp7
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp11
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp16
-rw-r--r--src/quick/scenegraph/qsgrenderloop_p.h2
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp51
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop_p.h1
-rw-r--r--src/quick/util/qquickanimatorjob.cpp5
-rw-r--r--src/quick/util/qquickanimatorjob_p.h1
-rw-r--r--src/quick/util/qquickimageprovider.cpp125
-rw-r--r--src/quick/util/qquickimageprovider.h32
-rw-r--r--src/quick/util/qquickpixmapcache.cpp240
-rw-r--r--src/quick/util/qquickpropertychanges.cpp20
-rw-r--r--src/quick/util/qquickstate.cpp31
-rw-r--r--src/quick/util/qquicktimeline.cpp2
-rw-r--r--src/quick/util/qquicktransitionmanager.cpp10
-rw-r--r--src/quick/util/qquickutilmodule.cpp8
-rw-r--r--src/quick/util/qquickvalidator.cpp221
-rw-r--r--src/quick/util/qquickvalidator_p.h83
-rw-r--r--src/quick/util/util.pri6
-rw-r--r--src/quickwidgets/qquickwidget.cpp18
216 files changed, 4362 insertions, 3152 deletions
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h b/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h
index 03f8e2d71a..734e779c70 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h
+++ b/src/3rdparty/masm/assembler/MacroAssemblerMIPS.h
@@ -359,6 +359,12 @@ public:
}
}
+ void mul32(Address src, RegisterID dest)
+ {
+ load32(src, dataTempRegister);
+ mul32(dataTempRegister, dest);
+ }
+
void neg32(RegisterID srcDest)
{
m_assembler.subu(srcDest, MIPSRegisters::zero, srcDest);
@@ -420,6 +426,12 @@ public:
store32(dataTempRegister, dest.m_ptr);
}
+ void or32(Address src, RegisterID dest)
+ {
+ load32(src, dataTempRegister);
+ or32(dataTempRegister, dest);
+ }
+
void rshift32(RegisterID shiftAmount, RegisterID dest)
{
m_assembler.srav(dest, dest, shiftAmount);
@@ -615,6 +627,12 @@ public:
m_assembler.xorInsn(dest, src, immTempRegister);
}
+ void xor32(Address src, RegisterID dest)
+ {
+ load32(src, dataTempRegister);
+ xor32(dataTempRegister, dest);
+ }
+
void sqrtDouble(FPRegisterID src, FPRegisterID dst)
{
m_assembler.sqrtd(dst, src);
@@ -2519,6 +2537,18 @@ public:
m_assembler.cvtdw(dest, fpTempRegister);
}
+ void convertUInt32ToDouble(RegisterID src, FPRegisterID dest, RegisterID scratch)
+ {
+ m_assembler.mtc1(src, fpTempRegister);
+ m_assembler.bltz(src, 2);
+ m_assembler.cvtdw(dest, fpTempRegister);
+ m_assembler.beq(MIPSRegisters::zero, MIPSRegisters::zero, 4);
+ m_assembler.lui(scratch, 0x4f80);
+ m_assembler.mtc1(scratch, fpTempRegister);
+ m_assembler.cvtds(fpTempRegister, fpTempRegister);
+ m_assembler.addd(dest, dest, fpTempRegister);
+ }
+
void convertFloatToDouble(FPRegisterID src, FPRegisterID dst)
{
m_assembler.cvtds(dst, src);
@@ -2761,7 +2791,7 @@ public:
return CodeLocationLabel();
}
- static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel instructionStart, Address, void* initialValue)
+ static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel, Address, void*)
{
UNREACHABLE_FOR_PLATFORM();
}
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
index 80b32e64ef..0f4a5bda54 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
@@ -788,6 +788,20 @@ QVariant QQuickFolderListModel::get(int idx, const QString &property) const
return QVariant();
}
+/*!
+ \qmlmethod int FolderListModel::indexOf(url file)
+ \since 5.6
+
+ Get the index of the given file URL if the model contains it,
+ or -1 if not.
+*/
+int QQuickFolderListModel::indexOf(const QUrl &file) const
+{
+ Q_D(const QQuickFolderListModel);
+ FileProperty toFind(QFileInfo(file.toLocalFile()));
+ return d->data.indexOf(toFind);
+}
+
#include "moc_qquickfolderlistmodel.cpp"
//![code]
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h
index 63ed528556..0001b2fdf3 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.h
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h
@@ -132,6 +132,7 @@ public:
Q_INVOKABLE bool isFolder(int index) const;
Q_INVOKABLE QVariant get(int idx, const QString &property) const;
+ Q_INVOKABLE int indexOf(const QUrl &file) const;
//![parserstatus]
virtual void classBegin();
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index b0ba3f9228..22a3eed39d 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -126,7 +126,7 @@ public:
~QQmlSqlDatabaseWrapper() {
}
- static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
};
}
@@ -214,7 +214,7 @@ static QString qmlsqldatabase_databaseFile(const QString& connectionName, QV4::E
return qmlsqldatabase_databasesPath(engine) + QDir::separator() + connectionName;
}
-static ReturnedValue qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, ExecutionEngine *v4, quint32 index, bool *hasProperty = 0)
+static ReturnedValue qmlsqldatabase_rows_index(const QQmlSqlDatabaseWrapper *r, ExecutionEngine *v4, quint32 index, bool *hasProperty = 0)
{
Scope scope(v4);
@@ -238,15 +238,14 @@ static ReturnedValue qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, Execut
}
}
-ReturnedValue QQmlSqlDatabaseWrapper::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue QQmlSqlDatabaseWrapper::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
- QV4::Scope scope(static_cast<QQmlSqlDatabaseWrapper *>(m)->engine());
Q_ASSERT(m->as<QQmlSqlDatabaseWrapper>());
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, static_cast<QQmlSqlDatabaseWrapper *>(m));
+ const QQmlSqlDatabaseWrapper *r = static_cast<const QQmlSqlDatabaseWrapper *>(m);
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
return Object::getIndexed(m, index, hasProperty);
- return qmlsqldatabase_rows_index(r, scope.engine, index, hasProperty);
+ return qmlsqldatabase_rows_index(r, r->engine(), index, hasProperty);
}
static ReturnedValue qmlsqldatabase_rows_item(CallContext *ctx)
@@ -285,13 +284,13 @@ static ReturnedValue qmlsqldatabase_executeSql(CallContext *ctx)
if (query.prepare(sql)) {
if (ctx->argc() > 1) {
ScopedValue values(scope, ctx->args()[1]);
- if (values->asArrayObject()) {
+ if (values->as<ArrayObject>()) {
ScopedArrayObject array(scope, values);
quint32 size = array->getLength();
QV4::ScopedValue v(scope);
for (quint32 ii = 0; ii < size; ++ii)
query.bindValue(ii, scope.engine->toVariant((v = array->getIndexed(ii)), -1));
- } else if (values->asObject()) {
+ } else if (values->as<Object>()) {
ScopedObject object(scope, values);
ObjectIterator it(scope, object, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly);
ScopedValue key(scope);
@@ -304,7 +303,7 @@ static ReturnedValue qmlsqldatabase_executeSql(CallContext *ctx)
if (key->isString()) {
query.bindValue(key->stringValue()->toQString(), v);
} else {
- assert(key->isInteger());
+ Q_ASSERT(key->isInteger());
query.bindValue(key->integerValue(), v);
}
}
@@ -401,7 +400,7 @@ static ReturnedValue qmlsqldatabase_changeVersion(CallContext *ctx)
db.transaction();
ScopedCallData callData(scope, 1);
- callData->thisObject = scope.engine->globalObject();
+ callData->thisObject = scope.engine->globalObject;
callData->args[0] = w;
TransactionRollback rollbackOnException(&db, &w->d()->inTransaction);
@@ -433,7 +432,7 @@ static ReturnedValue qmlsqldatabase_transaction_shared(CallContext *ctx, bool re
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
V4THROW_REFERENCE("Not a SQLDatabase object");
- FunctionObject *callback = ctx->argc() ? ctx->args()[0].asFunctionObject() : 0;
+ const FunctionObject *callback = ctx->argc() ? ctx->args()[0].as<FunctionObject>() : 0;
if (!callback)
V4THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR, QQmlEngine::tr("transaction: missing callback"));
@@ -450,7 +449,7 @@ static ReturnedValue qmlsqldatabase_transaction_shared(CallContext *ctx, bool re
db.transaction();
if (callback) {
ScopedCallData callData(scope, 1);
- callData->thisObject = scope.engine->globalObject();
+ callData->thisObject = scope.engine->globalObject;
callData->args[0] = w;
TransactionRollback rollbackOnException(&db, &w->d()->inTransaction);
callback->call(callData);
@@ -673,7 +672,7 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
QString dbversion = (v = (*args)[1])->toQStringNoThrow();
QString dbdescription = (v = (*args)[2])->toQStringNoThrow();
int dbestimatedsize = (v = (*args)[3])->toInt32();
- FunctionObject *dbcreationCallback = (v = (*args)[4])->asFunctionObject();
+ FunctionObject *dbcreationCallback = (v = (*args)[4])->as<FunctionObject>();
QCryptographicHash md5(QCryptographicHash::Md5);
md5.addData(dbname.toUtf8());
@@ -724,7 +723,7 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
if (created && dbcreationCallback) {
Scope scope(ctx);
ScopedCallData callData(scope, 1);
- callData->thisObject = scope.engine->globalObject();
+ callData->thisObject = scope.engine->globalObject;
callData->args[0] = db;
dbcreationCallback->call(callData);
}
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml
index 039ee63f07..4c48611e79 100644
--- a/src/imports/testlib/TestCase.qml
+++ b/src/imports/testlib/TestCase.qml
@@ -613,12 +613,19 @@ Item {
\li blue(x, y) Returns the blue channel value of the pixel at \a x, \a y position
\li alpha(x, y) Returns the alpha channel value of the pixel at \a x, \a y position
\li pixel(x, y) Returns the color value of the pixel at \a x, \a y position
+ \li equals(image) Returns \c true if this image is identical to \a image -
+ see \l QImage::operator== (since 5.6)
+
For example:
\code
var image = grabImage(rect);
compare(image.red(10, 10), 255);
compare(image.pixel(20, 20), Qt.rgba(255, 0, 0, 255));
+
+ rect.width += 10;
+ var newImage = grabImage(rect);
+ verify(!newImage.equals(image));
\endcode
\endlist
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
index b078edcbc6..832f484c13 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
@@ -36,7 +36,7 @@
#include <qqmlcontext.h>
#include <private/qqmlengine_p.h>
#include <private/qv8engine_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4engine_p.h>
#include <private/qv4object_p.h>
diff --git a/src/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp
index 32cde7c126..5e244ba02c 100644
--- a/src/particles/qquickcustomparticle.cpp
+++ b/src/particles/qquickcustomparticle.cpp
@@ -370,10 +370,10 @@ QQuickShaderEffectNode* QQuickCustomParticle::buildCustomNodes()
}
}
- NodeHashConstIt it = m_nodes.begin();
+ NodeHashConstIt it = m_nodes.cbegin();
rootNode = it.value();
rootNode->setFlag(QSGNode::OwnsMaterial, true);
- const NodeHashConstIt cend = m_nodes.end();
+ NodeHashConstIt cend = m_nodes.cend();
for (++it; it != cend; ++it)
rootNode->appendChildNode(it.value());
diff --git a/src/particles/qquickv4particledata_p.h b/src/particles/qquickv4particledata_p.h
index f211ec7e7d..c29c7e1134 100644
--- a/src/particles/qquickv4particledata_p.h
+++ b/src/particles/qquickv4particledata_p.h
@@ -36,7 +36,7 @@
#include <private/qv8engine_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 63833504f1..cc9da2817a 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -33,7 +33,7 @@
#include "qqmlirbuilder_p.h"
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4compileddata_p.h>
#include <private/qqmljsparser_p.h>
#include <private/qqmljslexer_p.h>
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 21846775a3..03e2aa295c 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1022,10 +1022,10 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
}
}
- QHash<QString, QStringList>::ConstIterator entry = customSignals.find(propertyName);
+ QHash<QString, QStringList>::ConstIterator entry = customSignals.constFind(propertyName);
if (entry == customSignals.constEnd() && propertyName.endsWith(QStringLiteral("Changed"))) {
QString alternateName = propertyName.mid(0, propertyName.length() - static_cast<int>(strlen("Changed")));
- entry = customSignals.find(alternateName);
+ entry = customSignals.constFind(alternateName);
}
if (entry == customSignals.constEnd()) {
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 9168889c8c..ea82d07e69 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -33,6 +33,7 @@
#include "qv4codegen_p.h"
#include "qv4util_p.h"
+#include "qv4engine_p.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
@@ -43,7 +44,7 @@
#include <QtCore/QStack>
#include <private/qqmljsast_p.h>
#include <private/qv4string_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#ifndef V4_BOOTSTRAP
#include <qv4context_p.h>
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 5d954eb4fc..20db5edaa3 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -33,7 +33,7 @@
#include "qv4compileddata_p.h"
#include "qv4jsir_p.h"
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#ifndef V4_BOOTSTRAP
#include <private/qv4engine_p.h>
#include <private/qv4function_p.h>
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 450889c275..9e4c7560c1 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -35,7 +35,7 @@
#include <qv4compileddata_p.h>
#include <qv4isel_p.h>
#include <private/qv4string_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
QV4::Compiler::StringTableGenerator::StringTableGenerator()
{
@@ -44,8 +44,8 @@ QV4::Compiler::StringTableGenerator::StringTableGenerator()
int QV4::Compiler::StringTableGenerator::registerString(const QString &str)
{
- QHash<QString, int>::ConstIterator it = stringToId.find(str);
- if (it != stringToId.end())
+ QHash<QString, int>::ConstIterator it = stringToId.constFind(str);
+ if (it != stringToId.cend())
return *it;
stringToId.insert(str, strings.size());
strings.append(str);
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index eb78a0c054..b084c9a1fc 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -1444,7 +1444,7 @@ ptrdiff_t InstructionSelection::addInstructionHelper(Instr::Type type, Instr &in
void InstructionSelection::patchJumpAddresses()
{
typedef QHash<IR::BasicBlock *, QVector<ptrdiff_t> >::ConstIterator PatchIt;
- for (PatchIt i = _patches.begin(), ei = _patches.end(); i != ei; ++i) {
+ for (PatchIt i = _patches.cbegin(), ei = _patches.cend(); i != ei; ++i) {
Q_ASSERT(_addrs.contains(i.key()));
ptrdiff_t target = _addrs.value(i.key());
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp
index 54b184b4eb..46b9c784d2 100644
--- a/src/qml/compiler/qv4isel_p.cpp
+++ b/src/qml/compiler/qv4isel_p.cpp
@@ -36,7 +36,7 @@
#include "qv4jsir_p.h"
#include "qv4isel_p.h"
#include "qv4isel_util_p.h"
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#ifndef V4_BOOTSTRAP
#include <private/qqmlpropertycache_p.h>
#endif
diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp
index b0302181ee..d79028b3fe 100644
--- a/src/qml/debugger/qqmldebugserver.cpp
+++ b/src/qml/debugger/qqmldebugserver.cpp
@@ -422,8 +422,8 @@ QQmlDebugServer::QQmlDebugServer()
QString pluginName;
QStringList lstjsDebugArguments = appD->qmljsDebugArgumentsString()
.split(QLatin1Char(','));
- QStringList::const_iterator argsItEnd = lstjsDebugArguments.end();
- QStringList::const_iterator argsIt = lstjsDebugArguments.begin();
+ QStringList::const_iterator argsItEnd = lstjsDebugArguments.cend();
+ QStringList::const_iterator argsIt = lstjsDebugArguments.cbegin();
for (; argsIt != argsItEnd; ++argsIt) {
const QString strArgument = *argsIt;
if (strArgument.startsWith(QLatin1String("port:"))) {
diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp
index da01d00f17..a7ef450606 100644
--- a/src/qml/debugger/qqmlenginedebugservice.cpp
+++ b/src/qml/debugger/qqmlenginedebugservice.cpp
@@ -644,11 +644,9 @@ bool QQmlEngineDebugService::setBinding(int objectId,
filename, line, column);
QQmlPropertyPrivate::takeSignalExpression(property, qmlExpression);
} else if (property.isProperty()) {
- QQmlBinding *binding = new QQmlBinding(expression.toString(), object, QQmlContextData::get(context), filename, line, column);;
+ QQmlBinding *binding = new QQmlBinding(expression.toString(), object, QQmlContextData::get(context), filename, line, column);
binding->setTarget(property);
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::setBinding(property, binding);
- if (oldBinding)
- oldBinding->destroy();
+ QQmlPropertyPrivate::setBinding(binding);
binding->update();
} else {
ok = false;
@@ -679,12 +677,7 @@ bool QQmlEngineDebugService::resetBinding(int objectId, const QString &propertyN
if (object->property(parentProperty.toLatin1()).isValid()) {
QQmlProperty property(object, propertyName);
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(property);
- if (oldBinding) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::setBinding(property, 0);
- if (oldBinding)
- oldBinding->destroy();
- }
+ QQmlPropertyPrivate::removeBinding(property, QQmlPropertyPrivate::DestroyOldBinding);
if (property.isResettable()) {
// Note: this will reset the property in any case, without regard to states
// Right now almost no QQuickItem has reset methods for its properties (with the
diff --git a/src/qml/debugger/qv4debugservice.cpp b/src/qml/debugger/qv4debugservice.cpp
index 32b7b38285..e736dd9059 100644
--- a/src/qml/debugger/qv4debugservice.cpp
+++ b/src/qml/debugger/qv4debugservice.cpp
@@ -230,7 +230,7 @@ protected:
virtual void addObject(const QString &name, const QV4::Value &value)
{
QV4::Scope scope(engine());
- QV4::ScopedObject obj(scope, value.asObject());
+ QV4::ScopedObject obj(scope, value.as<QV4::Object>());
int ref = cachedObjectRef(obj);
if (ref != -1) {
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index 09e5b14c97..b5765b5705 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -241,16 +241,16 @@ void Assembler::enterStandardStackFrame(const RegisterInformation &regularRegist
subPtr(TrustedImm32(frameSize), StackPointerRegister);
Address slotAddr(StackFrameRegister, 0);
- for (int i = 0, ei = regularRegistersToSave.size(); i < ei; ++i) {
- Q_ASSERT(regularRegistersToSave.at(i).isRegularRegister());
- slotAddr.offset -= RegisterSize;
- storePtr(regularRegistersToSave.at(i).reg<RegisterID>(), slotAddr);
- }
for (int i = 0, ei = fpRegistersToSave.size(); i < ei; ++i) {
Q_ASSERT(fpRegistersToSave.at(i).isFloatingPoint());
slotAddr.offset -= sizeof(double);
JSC::MacroAssembler::storeDouble(fpRegistersToSave.at(i).reg<FPRegisterID>(), slotAddr);
}
+ for (int i = 0, ei = regularRegistersToSave.size(); i < ei; ++i) {
+ Q_ASSERT(regularRegistersToSave.at(i).isRegularRegister());
+ slotAddr.offset -= RegisterSize;
+ storePtr(regularRegistersToSave.at(i).reg<RegisterID>(), slotAddr);
+ }
}
void Assembler::leaveStandardStackFrame(const RegisterInformation &regularRegistersToSave,
@@ -259,16 +259,16 @@ void Assembler::leaveStandardStackFrame(const RegisterInformation &regularRegist
Address slotAddr(StackFrameRegister, -regularRegistersToSave.size() * RegisterSize - fpRegistersToSave.size() * sizeof(double));
// restore the callee saved registers
- for (int i = fpRegistersToSave.size() - 1; i >= 0; --i) {
- Q_ASSERT(fpRegistersToSave.at(i).isFloatingPoint());
- JSC::MacroAssembler::loadDouble(slotAddr, fpRegistersToSave.at(i).reg<FPRegisterID>());
- slotAddr.offset += sizeof(double);
- }
for (int i = regularRegistersToSave.size() - 1; i >= 0; --i) {
Q_ASSERT(regularRegistersToSave.at(i).isRegularRegister());
loadPtr(slotAddr, regularRegistersToSave.at(i).reg<RegisterID>());
slotAddr.offset += RegisterSize;
}
+ for (int i = fpRegistersToSave.size() - 1; i >= 0; --i) {
+ Q_ASSERT(fpRegistersToSave.at(i).isFloatingPoint());
+ JSC::MacroAssembler::loadDouble(slotAddr, fpRegistersToSave.at(i).reg<FPRegisterID>());
+ slotAddr.offset += sizeof(double);
+ }
Q_ASSERT(slotAddr.offset == 0);
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 3b65acb26c..f4b44ce882 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -565,6 +565,8 @@ public:
moveIntsToDouble(JSC::ARMRegisters::r0, JSC::ARMRegisters::r1, dest, FPGpr0);
#elif defined(Q_PROCESSOR_X86)
moveIntsToDouble(JSC::X86Registers::eax, JSC::X86Registers::edx, dest, FPGpr0);
+#elif defined(Q_PROCESSOR_MIPS)
+ moveIntsToDouble(JSC::MIPSRegisters::v0, JSC::MIPSRegisters::v1, dest, FPGpr0);
#else
subPtr(TrustedImm32(sizeof(QV4::Value)), StackPointerRegister);
Pointer tmp(StackPointerRegister, 0);
@@ -595,6 +597,14 @@ public:
destination.offset += 4;
store32(JSC::ARMRegisters::r1, destination);
}
+#elif defined(Q_PROCESSOR_MIPS)
+ void storeReturnValue(const Pointer &dest)
+ {
+ Pointer destination = dest;
+ store32(JSC::MIPSRegisters::v0, destination);
+ destination.offset += 4;
+ store32(JSC::MIPSRegisters::v1, destination);
+ }
#endif
void storeReturnValue(IR::Expr *target)
@@ -820,6 +830,8 @@ public:
else
#if OS(WINDOWS) && CPU(X86_64)
loadArgumentOnStack<argumentNumber>(value, argumentNumber);
+#elif CPU(MIPS) // Stack space for 4 arguments needs to be allocated for MIPS platforms.
+ loadArgumentOnStack<argumentNumber>(value, argumentNumber + 4);
#else // Sanity:
loadArgumentOnStack<argumentNumber - RegisterArgumentCount>(value, argumentNumber);
#endif
diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp
index c6c8023cd7..e4a2846f32 100644
--- a/src/qml/jit/qv4binop.cpp
+++ b/src/qml/jit/qv4binop.cpp
@@ -415,8 +415,8 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta
case IR::OpAdd: as->add32(l, r, targetReg); break;
case IR::OpMul: as->mul32(l, r, targetReg); break;
-#if CPU(ARM) || CPU(X86) || CPU(X86_64)
- // The ARM assembler will generate an and with 0x1f for us, and Intel will do it on the CPU.
+#if CPU(ARM) || CPU(X86) || CPU(X86_64) || CPU(MIPS)
+ // The ARM assembler will generate an and with 0x1f for us, MIPS and Intel will do it on the CPU.
case IR::OpLShift: as->lshift32(l, r, targetReg); break;
case IR::OpRShift: as->rshift32(l, r, targetReg); break;
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index da511cd1eb..236422c5fd 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -1383,11 +1383,14 @@ void InstructionSelection::visitRet(IR::Ret *s)
// this only happens if the method doesn't have a return statement and can
// only exit through an exception
} else if (IR::Temp *t = s->expr->asTemp()) {
-#if CPU(X86) || CPU(ARM)
+#if CPU(X86) || CPU(ARM) || CPU(MIPS)
# if CPU(X86)
Assembler::RegisterID lowReg = JSC::X86Registers::eax;
Assembler::RegisterID highReg = JSC::X86Registers::edx;
+# elif CPU(MIPS)
+ Assembler::RegisterID lowReg = JSC::MIPSRegisters::v0;
+ Assembler::RegisterID highReg = JSC::MIPSRegisters::v1;
# else // CPU(ARM)
Assembler::RegisterID lowReg = JSC::ARMRegisters::r0;
Assembler::RegisterID highReg = JSC::ARMRegisters::r1;
@@ -1477,6 +1480,9 @@ void InstructionSelection::visitRet(IR::Ret *s)
#elif CPU(ARM)
_as->move(Assembler::TrustedImm32(retVal.int_32), JSC::ARMRegisters::r0);
_as->move(Assembler::TrustedImm32(retVal.tag), JSC::ARMRegisters::r1);
+#elif CPU(MIPS)
+ _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::MIPSRegisters::v0);
+ _as->move(Assembler::TrustedImm32(retVal.tag), JSC::MIPSRegisters::v1);
#else
_as->move(Assembler::TrustedImm64(retVal.val), Assembler::ReturnValueRegister);
#endif
@@ -1504,6 +1510,9 @@ void InstructionSelection::visitRet(IR::Ret *s)
#elif CPU(ARM)
_as->move(Assembler::TrustedImm32(retVal.int_32), JSC::ARMRegisters::r0);
_as->move(Assembler::TrustedImm32(retVal.tag), JSC::ARMRegisters::r1);
+#elif CPU(MIPS)
+ _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::MIPSRegisters::v0);
+ _as->move(Assembler::TrustedImm32(retVal.tag), JSC::MIPSRegisters::v1);
#else
_as->move(Assembler::TrustedImm64(retVal.val), Assembler::ReturnValueRegister);
#endif
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index ae06a99d2a..48b7badd56 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -35,7 +35,7 @@
#include <QtCore/QDebug>
#include "qv4regalloc_p.h"
#include "qv4alloca_p.h"
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <algorithm>
#if defined(Q_CC_MINGW)
diff --git a/src/qml/jit/qv4targetplatform_p.h b/src/qml/jit/qv4targetplatform_p.h
index 05741f0ae5..76c768e4f9 100644
--- a/src/qml/jit/qv4targetplatform_p.h
+++ b/src/qml/jit/qv4targetplatform_p.h
@@ -346,6 +346,71 @@ public:
static void platformLeaveStandardStackFrame(JSC::MacroAssembler *as) { as->pop(JSC::ARMRegisters::lr); }
#endif // Linux on ARM (32 bit)
+#if defined(Q_PROCESSOR_MIPS_32) && defined(Q_OS_LINUX)
+ enum { RegAllocIsSupported = 1 };
+
+ static const JSC::MacroAssembler::RegisterID StackFrameRegister = JSC::MIPSRegisters::fp;
+ static const JSC::MacroAssembler::RegisterID StackPointerRegister = JSC::MIPSRegisters::sp;
+ static const JSC::MacroAssembler::RegisterID LocalsRegister = JSC::MIPSRegisters::s0;
+ static const JSC::MacroAssembler::RegisterID EngineRegister = JSC::MIPSRegisters::s1;
+ static const JSC::MacroAssembler::RegisterID ReturnValueRegister = JSC::MIPSRegisters::v0;
+ static const JSC::MacroAssembler::RegisterID ScratchRegister = JSC::MIPSRegisters::s2;
+ static const JSC::MacroAssembler::FPRegisterID FPGpr0 = JSC::MIPSRegisters::f0;
+ static const JSC::MacroAssembler::FPRegisterID FPGpr1 = JSC::MIPSRegisters::f2;
+
+ static RegisterInformation getPlatformRegisterInfo()
+ {
+ typedef RegisterInfo RI;
+ return RegisterInformation()
+ // Note: t0, t1, t2, t3 and f16 are already used by MacroAssemblerMIPS.
+ << RI(JSC::MIPSRegisters::t4, QStringLiteral("t4"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::t5, QStringLiteral("t5"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::t6, QStringLiteral("t6"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::t7, QStringLiteral("t7"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::t8, QStringLiteral("t8"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::s0, QStringLiteral("s0"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
+ << RI(JSC::MIPSRegisters::s1, QStringLiteral("s1"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
+ << RI(JSC::MIPSRegisters::s2, QStringLiteral("s2"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
+ << RI(JSC::MIPSRegisters::s3, QStringLiteral("s3"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f4, QStringLiteral("f4"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f6, QStringLiteral("f6"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f8, QStringLiteral("f8"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f10, QStringLiteral("f10"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f18, QStringLiteral("f18"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f20, QStringLiteral("f20"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f22, QStringLiteral("f22"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f24, QStringLiteral("f24"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f26, QStringLiteral("f26"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
+ << RI(JSC::MIPSRegisters::f28, QStringLiteral("f28"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
+ ;
+ }
+
+#undef HAVE_ALU_OPS_WITH_MEM_OPERAND
+#undef VALUE_FITS_IN_REGISTER
+ static const int RegisterSize = 4;
+
+#define ARGUMENTS_IN_REGISTERS
+ static const int RegisterArgumentCount = 4;
+ static JSC::MacroAssembler::RegisterID registerForArgument(int index)
+ {
+ static JSC::MacroAssembler::RegisterID regs[RegisterArgumentCount] = {
+ JSC::MIPSRegisters::a0,
+ JSC::MIPSRegisters::a1,
+ JSC::MIPSRegisters::a2,
+ JSC::MIPSRegisters::a3
+ };
+
+ Q_ASSERT(index >= 0 && index < RegisterArgumentCount);
+ return regs[index];
+ };
+
+ static const int StackAlignment = 8;
+ static const int StackShadowSpace = 4 * RegisterSize; // Stack space for 4 argument registers.
+ static const int StackSpaceAllocatedUponFunctionEntry = 1 * RegisterSize; // Registers saved in platformEnterStandardStackFrame below.
+ static void platformEnterStandardStackFrame(JSC::MacroAssembler *as) { as->push(JSC::MIPSRegisters::ra); }
+ static void platformLeaveStandardStackFrame(JSC::MacroAssembler *as) { as->pop(JSC::MIPSRegisters::ra); }
+#endif // Linux on MIPS (32 bit)
+
public: // utility functions
static RegisterInformation getRegisterInfo()
{
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index ee27c21aed..a02458b8bd 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -271,7 +271,7 @@ void QJSEngine::installTranslatorFunctions(const QJSValue &object)
if (val)
obj = val;
if (!obj)
- obj = scope.engine->globalObject();
+ obj = scope.engine->globalObject;
#ifndef QT_NO_TRANSLATION
obj->defineDefaultProperty(QStringLiteral("qsTranslate"), QV4::GlobalExtensions::method_qsTranslate);
obj->defineDefaultProperty(QStringLiteral("QT_TRANSLATE_NOOP"), QV4::GlobalExtensions::method_qsTranslateNoOp);
@@ -281,7 +281,7 @@ void QJSEngine::installTranslatorFunctions(const QJSValue &object)
obj->defineDefaultProperty(QStringLiteral("QT_TRID_NOOP"), QV4::GlobalExtensions::method_qsTrIdNoOp);
// string prototype extension
- scope.engine->stringPrototype.asObject()->defineDefaultProperty(QStringLiteral("arg"),
+ scope.engine->stringPrototype()->defineDefaultProperty(QStringLiteral("arg"),
QV4::GlobalExtensions::method_string_arg);
#endif
}
@@ -414,7 +414,7 @@ QJSValue QJSEngine::globalObject() const
{
Q_D(const QJSEngine);
QV4::Scope scope(d->m_v4Engine);
- QV4::ScopedValue v(scope, d->m_v4Engine->globalObject());
+ QV4::ScopedValue v(scope, d->m_v4Engine->globalObject);
return QJSValue(d->m_v4Engine, v->asReturnedValue());
}
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 50669c46a8..a9333ed8a9 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -37,13 +37,14 @@
#include "qjsengine.h"
#include "qjsvalue.h"
#include "qjsvalue_p.h"
-#include "qv4value_inl_p.h"
+#include "qv4value_p.h"
#include "qv4object_p.h"
#include "qv4functionobject_p.h"
#include "qv4dateobject_p.h"
#include "qv4runtime_p.h"
#include "qv4variantobject_p.h"
#include "qv4regexpobject_p.h"
+#include "qv4errorobject_p.h"
#include "private/qv8engine_p.h"
#include <private/qv4mm_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -317,8 +318,7 @@ bool QJSValue::isError() const
QV4::Value *val = QJSValuePrivate::getValue(this);
if (!val)
return false;
- Object *o = val->asObject();
- return o && o->asErrorObject();
+ return val->as<ErrorObject>();
}
/*!
@@ -332,7 +332,7 @@ bool QJSValue::isArray() const
QV4::Value *val = QJSValuePrivate::getValue(this);
if (!val)
return false;
- return val->asArrayObject();
+ return val->as<ArrayObject>();
}
/*!
@@ -349,7 +349,7 @@ bool QJSValue::isObject() const
QV4::Value *val = QJSValuePrivate::getValue(this);
if (!val)
return false;
- return val->asObject();
+ return val->as<Object>();
}
/*!
@@ -363,7 +363,7 @@ bool QJSValue::isCallable() const
QV4::Value *val = QJSValuePrivate::getValue(this);
if (!val)
return false;
- return val->asFunctionObject();
+ return val->as<FunctionObject>();
}
/*!
@@ -589,7 +589,7 @@ QVariant QJSValue::toVariant() const
QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch);
Q_ASSERT(val);
- if (Object *o = val->asObject())
+ if (Object *o = val->as<Object>())
return o->engine()->toVariant(*val, /*typeHint*/ -1, /*createJSValueForObjects*/ false);
if (val->isString())
@@ -628,7 +628,7 @@ QJSValue QJSValue::call(const QJSValueList &args)
if (!val)
return QJSValue();
- FunctionObject *f = val->asFunctionObject();
+ FunctionObject *f = val->as<FunctionObject>();
if (!f)
return QJSValue();
@@ -637,7 +637,7 @@ QJSValue QJSValue::call(const QJSValueList &args)
Scope scope(engine);
ScopedCallData callData(scope, args.length());
- callData->thisObject = engine->globalObject()->asReturnedValue();
+ callData->thisObject = engine->globalObject;
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
@@ -679,7 +679,7 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
if (!val)
return QJSValue();
- FunctionObject *f = val->asFunctionObject();
+ FunctionObject *f = val->as<FunctionObject>();
if (!f)
return QJSValue();
@@ -733,7 +733,7 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
if (!val)
return QJSValue();
- FunctionObject *f = val->asFunctionObject();
+ FunctionObject *f = val->as<FunctionObject>();
if (!f)
return QJSValue();
@@ -789,7 +789,7 @@ QJSValue QJSValue::prototype() const
if (!engine)
return QJSValue();
QV4::Scope scope(engine);
- ScopedObject o(scope, QJSValuePrivate::getValue(this)->asObject());
+ ScopedObject o(scope, QJSValuePrivate::getValue(this)->as<Object>());
if (!o)
return QJSValue();
ScopedObject p(scope, o->prototype());
@@ -1224,7 +1224,7 @@ QDateTime QJSValue::toDateTime() const
{
QV4::Value *val = QJSValuePrivate::getValue(this);
if (val) {
- QV4::DateObject *date = val->asDateObject();
+ QV4::DateObject *date = val->as<DateObject>();
if (date)
return date->toQDateTime();
}
@@ -1238,7 +1238,7 @@ QDateTime QJSValue::toDateTime() const
bool QJSValue::isDate() const
{
QV4::Value *val = QJSValuePrivate::getValue(this);
- return val && val->asDateObject();
+ return val && val->as<DateObject>();
}
/*!
diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h
index 93a28a4a5f..08dc184412 100644
--- a/src/qml/jsapi/qjsvalue_p.h
+++ b/src/qml/jsapi/qjsvalue_p.h
@@ -47,7 +47,7 @@
#include <qjsvalue.h>
#include <private/qtqmlglobal_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4string_p.h>
#include <private/qv4engine_p.h>
#include <private/qv4object_p.h>
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index ef44ca6f4d..51bcc19c6e 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -10,7 +10,6 @@ SOURCES += \
$$PWD/qv4lookup.cpp \
$$PWD/qv4identifier.cpp \
$$PWD/qv4identifiertable.cpp \
- $$PWD/qv4mm.cpp \
$$PWD/qv4managed.cpp \
$$PWD/qv4internalclass.cpp \
$$PWD/qv4sparsearray.cpp \
@@ -57,7 +56,6 @@ HEADERS += \
$$PWD/qv4lookup_p.h \
$$PWD/qv4identifier_p.h \
$$PWD/qv4identifiertable_p.h \
- $$PWD/qv4mm_p.h \
$$PWD/qv4managed_p.h \
$$PWD/qv4internalclass_p.h \
$$PWD/qv4sparsearray_p.h \
@@ -85,6 +83,7 @@ HEADERS += \
$$PWD/qv4serialize_p.h \
$$PWD/qv4script_p.h \
$$PWD/qv4scopedvalue_p.h \
+ $$PWD/qv4typedvalue_p.h \
$$PWD/qv4util_p.h \
$$PWD/qv4executableallocator_p.h \
$$PWD/qv4sequenceobject_p.h \
@@ -102,7 +101,7 @@ HEADERS += \
HEADERS += \
$$PWD/qv4runtime_p.h \
- $$PWD/qv4value_inl_p.h \
+ $$PWD/qv4value_p.h \
$$PWD/qv4string_p.h \
$$PWD/qv4value_p.h
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 92c77570af..69053f117c 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -33,6 +33,7 @@
#include <qv4argumentsobject_p.h>
#include <qv4alloca_p.h>
#include <qv4scopedvalue_p.h>
+#include "qv4string_p.h"
using namespace QV4;
@@ -40,7 +41,7 @@ DEFINE_OBJECT_VTABLE(ArgumentsObject);
Heap::ArgumentsObject::ArgumentsObject(QV4::CallContext *context)
: Heap::Object(context->d()->strictMode ? context->d()->engine->strictArgumentsObjectClass : context->d()->engine->argumentsObjectClass,
- context->d()->engine->objectPrototype.asObject())
+ context->d()->engine->objectPrototype())
, context(context->d())
, fullyCreated(false)
{
@@ -55,10 +56,10 @@ Heap::ArgumentsObject::ArgumentsObject(QV4::CallContext *context)
if (context->d()->strictMode) {
Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(context->d()->engine->id_callee));
Q_ASSERT(CallerPropertyIndex == args->internalClass()->find(context->d()->engine->id_caller));
- args->propertyAt(CalleePropertyIndex)->value = v4->thrower;
- args->propertyAt(CalleePropertyIndex)->set = v4->thrower;
- args->propertyAt(CallerPropertyIndex)->value = v4->thrower;
- args->propertyAt(CallerPropertyIndex)->set = v4->thrower;
+ args->propertyAt(CalleePropertyIndex)->value = v4->thrower();
+ args->propertyAt(CalleePropertyIndex)->set = v4->thrower();
+ args->propertyAt(CallerPropertyIndex)->value = v4->thrower();
+ args->propertyAt(CallerPropertyIndex)->set = v4->thrower();
args->arrayReserve(context->argc());
args->arrayPut(0, context->args(), context->argc());
@@ -144,9 +145,9 @@ bool ArgumentsObject::defineOwnProperty(ExecutionEngine *engine, uint index, con
return result;
}
-ReturnedValue ArgumentsObject::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue ArgumentsObject::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
- ArgumentsObject *args = static_cast<ArgumentsObject *>(m);
+ const ArgumentsObject *args = static_cast<const ArgumentsObject *>(m);
if (args->fullyCreated())
return Object::getIndexed(m, index, hasProperty);
@@ -199,11 +200,11 @@ PropertyAttributes ArgumentsObject::queryIndexed(const Managed *m, uint index)
DEFINE_OBJECT_VTABLE(ArgumentsGetterFunction);
-ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
+ReturnedValue ArgumentsGetterFunction::call(const Managed *getter, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<ArgumentsGetterFunction *>(getter)->engine();
+ ExecutionEngine *v4 = static_cast<const ArgumentsGetterFunction *>(getter)->engine();
Scope scope(v4);
- Scoped<ArgumentsGetterFunction> g(scope, static_cast<ArgumentsGetterFunction *>(getter));
+ Scoped<ArgumentsGetterFunction> g(scope, static_cast<const ArgumentsGetterFunction *>(getter));
Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>());
if (!o)
return v4->throwTypeError();
@@ -214,11 +215,11 @@ ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
DEFINE_OBJECT_VTABLE(ArgumentsSetterFunction);
-ReturnedValue ArgumentsSetterFunction::call(Managed *setter, CallData *callData)
+ReturnedValue ArgumentsSetterFunction::call(const Managed *setter, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<ArgumentsSetterFunction *>(setter)->engine();
+ ExecutionEngine *v4 = static_cast<const ArgumentsSetterFunction *>(setter)->engine();
Scope scope(v4);
- Scoped<ArgumentsSetterFunction> s(scope, static_cast<ArgumentsSetterFunction *>(setter));
+ Scoped<ArgumentsSetterFunction> s(scope, static_cast<const ArgumentsSetterFunction *>(setter));
Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>());
if (!o)
return v4->throwTypeError();
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 43cd6d1dee..19659429a7 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -59,9 +59,9 @@ struct ArgumentsObject : Object {
CallerPropertyIndex = 3
};
ArgumentsObject(QV4::CallContext *context);
- CallContext *context;
+ Pointer<CallContext> context;
bool fullyCreated;
- MemberData *mappedArguments;
+ Pointer<MemberData> mappedArguments;
};
}
@@ -71,7 +71,7 @@ struct ArgumentsGetterFunction: FunctionObject
V4_OBJECT2(ArgumentsGetterFunction, FunctionObject)
uint index() const { return d()->index; }
- static ReturnedValue call(Managed *that, CallData *d);
+ static ReturnedValue call(const Managed *that, CallData *d);
};
inline
@@ -86,7 +86,7 @@ struct ArgumentsSetterFunction: FunctionObject
V4_OBJECT2(ArgumentsSetterFunction, FunctionObject)
uint index() const { return d()->index; }
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
inline
@@ -111,7 +111,7 @@ struct ArgumentsObject: Object {
}
bool defineOwnProperty(ExecutionEngine *engine, uint index, const Property *desc, PropertyAttributes attrs);
- static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
static void putIndexed(Managed *m, uint index, const Value &value);
static bool deleteIndexedProperty(Managed *m, uint index);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index 11664f1194..975f0121b9 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -33,6 +33,7 @@
#include "qv4arraybuffer_p.h"
#include "qv4typedarray_p.h"
#include "qv4dataview_p.h"
+#include "qv4string_p.h"
using namespace QV4;
@@ -44,9 +45,9 @@ Heap::ArrayBufferCtor::ArrayBufferCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue ArrayBufferCtor::construct(Managed *m, CallData *callData)
+ReturnedValue ArrayBufferCtor::construct(const Managed *m, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<Object *>(m)->engine();
+ ExecutionEngine *v4 = static_cast<const Object *>(m)->engine();
Scope scope(v4);
ScopedValue l(scope, callData->argument(0));
@@ -64,7 +65,7 @@ ReturnedValue ArrayBufferCtor::construct(Managed *m, CallData *callData)
}
-ReturnedValue ArrayBufferCtor::call(Managed *that, CallData *callData)
+ReturnedValue ArrayBufferCtor::call(const Managed *that, CallData *callData)
{
return construct(that, callData);
}
@@ -83,7 +84,7 @@ ReturnedValue ArrayBufferCtor::method_isView(CallContext *ctx)
Heap::ArrayBuffer::ArrayBuffer(ExecutionEngine *e, size_t length)
- : Heap::Object(e->emptyClass, e->arrayBufferPrototype.asObject())
+ : Heap::Object(e->emptyClass, e->arrayBufferPrototype())
{
data = QTypedArrayData<char>::allocate(length + 1);
if (!data) {
@@ -96,7 +97,7 @@ Heap::ArrayBuffer::ArrayBuffer(ExecutionEngine *e, size_t length)
}
Heap::ArrayBuffer::ArrayBuffer(ExecutionEngine *e, const QByteArray& array)
- : Heap::Object(e->emptyClass, e->arrayBufferPrototype.asObject())
+ : Heap::Object(e->emptyClass, e->arrayBufferPrototype())
, data(const_cast<QByteArray&>(array).data_ptr())
{
data->ref.ref();
diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h
index fe3150618d..a7f9e92c80 100644
--- a/src/qml/jsruntime/qv4arraybuffer_p.h
+++ b/src/qml/jsruntime/qv4arraybuffer_p.h
@@ -61,8 +61,8 @@ struct ArrayBufferCtor: FunctionObject
{
V4_OBJECT2(ArrayBufferCtor, FunctionObject)
- static ReturnedValue construct(Managed *m, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
static ReturnedValue method_isView(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index afcfa00905..627aed0192 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -33,13 +33,14 @@
#include "qv4arraydata_p.h"
#include "qv4object_p.h"
#include "qv4functionobject_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4runtime_p.h"
#include "qv4argumentsobject_p.h"
+#include "qv4string_p.h"
using namespace QV4;
-const QV4::ManagedVTable QV4::ArrayData::static_vtbl = {
+const QV4::VTable QV4::ArrayData::static_vtbl = {
0,
QV4::ArrayData::IsExecutionContext,
QV4::ArrayData::IsString,
@@ -230,7 +231,7 @@ ReturnedValue SimpleArrayData::get(const Heap::ArrayData *d, uint index)
bool SimpleArrayData::put(Object *o, uint index, const Value &value)
{
- Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
Q_ASSERT(index >= dd->len || !dd->attrs || !dd->attrs[index].isAccessor());
// ### honour attributes
dd->data(index) = value;
@@ -244,7 +245,7 @@ bool SimpleArrayData::put(Object *o, uint index, const Value &value)
bool SimpleArrayData::del(Object *o, uint index)
{
- Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (index >= dd->len)
return true;
@@ -266,12 +267,12 @@ void SimpleArrayData::setAttribute(Object *o, uint index, PropertyAttributes att
void SimpleArrayData::push_front(Object *o, const Value *values, uint n)
{
- Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
Q_ASSERT(!dd->attrs);
if (dd->len + n > dd->alloc) {
realloc(o, Heap::ArrayData::Simple, dd->len + n, false);
Q_ASSERT(o->d()->arrayData->type == Heap::ArrayData::Simple);
- dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
dd->offset = (dd->offset - n) % dd->alloc;
dd->len += n;
@@ -281,7 +282,7 @@ void SimpleArrayData::push_front(Object *o, const Value *values, uint n)
ReturnedValue SimpleArrayData::pop_front(Object *o)
{
- Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
Q_ASSERT(!dd->attrs);
if (!dd->len)
return Encode::undefined();
@@ -294,7 +295,7 @@ ReturnedValue SimpleArrayData::pop_front(Object *o)
uint SimpleArrayData::truncate(Object *o, uint newLen)
{
- Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (dd->len < newLen)
return newLen;
@@ -318,10 +319,10 @@ uint SimpleArrayData::length(const Heap::ArrayData *d)
bool SimpleArrayData::putArray(Object *o, uint index, const Value *values, uint n)
{
- Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (index + n > dd->alloc) {
reallocate(o, index + n + 1, false);
- dd = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
for (uint i = dd->len; i < index; ++i)
dd->data(i) = Primitive::emptyValue();
@@ -369,13 +370,13 @@ Heap::ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttr
uint SparseArrayData::allocate(Object *o, bool doubleSlot)
{
Q_ASSERT(o->d()->arrayData->type == Heap::ArrayData::Sparse);
- Heap::SparseArrayData *dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (doubleSlot) {
uint *last = &dd->freeList;
while (1) {
if (*last == UINT_MAX) {
reallocate(o, dd->alloc + 2, true);
- dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
last = &dd->freeList;
Q_ASSERT(*last != UINT_MAX);
}
@@ -393,7 +394,7 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
} else {
if (dd->freeList == UINT_MAX) {
reallocate(o, dd->alloc + 1, false);
- dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
uint idx = dd->freeList;
Q_ASSERT(idx != UINT_MAX);
@@ -418,12 +419,12 @@ bool SparseArrayData::put(Object *o, uint index, const Value &value)
if (value.isEmpty())
return true;
- Heap::SparseArrayData *s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Heap::SparseArrayData *s = o->d()->arrayData.cast<Heap::SparseArrayData>();
SparseArrayNode *n = s->sparse->insert(index);
Q_ASSERT(n->value == UINT_MAX || !s->attrs || !s->attrs[n->value].isAccessor());
if (n->value == UINT_MAX)
n->value = allocate(o);
- s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ s = o->d()->arrayData.cast<Heap::SparseArrayData>();
s->arrayData[n->value] = value;
if (s->attrs)
s->attrs[n->value] = Attr_Data;
@@ -432,7 +433,7 @@ bool SparseArrayData::put(Object *o, uint index, const Value &value)
bool SparseArrayData::del(Object *o, uint index)
{
- Heap::SparseArrayData *dd = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Heap::SparseArrayData *dd = o->d()->arrayData.cast<Heap::SparseArrayData>();
SparseArrayNode *n = dd->sparse->findNode(index);
if (!n)
@@ -468,28 +469,28 @@ bool SparseArrayData::del(Object *o, uint index)
void SparseArrayData::setAttribute(Object *o, uint index, PropertyAttributes attrs)
{
- Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Heap::SparseArrayData *d = o->d()->arrayData.cast<Heap::SparseArrayData>();
SparseArrayNode *n = d->sparse->insert(index);
if (n->value == UINT_MAX) {
n->value = allocate(o, attrs.isAccessor());
- d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ d = o->d()->arrayData.cast<Heap::SparseArrayData>();
}
else if (attrs.isAccessor() != d->attrs[n->value].isAccessor()) {
// need to convert the slot
free(o->arrayData(), n->value);
n->value = allocate(o, attrs.isAccessor());
- d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ d = o->d()->arrayData.cast<Heap::SparseArrayData>();
}
d->attrs[n->value] = attrs;
}
void SparseArrayData::push_front(Object *o, const Value *values, uint n)
{
- Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Heap::SparseArrayData *d = o->d()->arrayData.cast<Heap::SparseArrayData>();
Q_ASSERT(!d->attrs);
for (int i = n - 1; i >= 0; --i) {
uint idx = allocate(o);
- d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ d = o->d()->arrayData.cast<Heap::SparseArrayData>();
d->arrayData[idx] = values[i];
d->sparse->push_front(idx);
}
@@ -497,7 +498,7 @@ void SparseArrayData::push_front(Object *o, const Value *values, uint n)
ReturnedValue SparseArrayData::pop_front(Object *o)
{
- Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Heap::SparseArrayData *d = o->d()->arrayData.cast<Heap::SparseArrayData>();
Q_ASSERT(!d->attrs);
uint idx = d->sparse->pop_front();
ReturnedValue v;
@@ -512,7 +513,7 @@ ReturnedValue SparseArrayData::pop_front(Object *o)
uint SparseArrayData::truncate(Object *o, uint newLen)
{
- Heap::SparseArrayData *d = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Heap::SparseArrayData *d = o->d()->arrayData.cast<Heap::SparseArrayData>();
SparseArrayNode *begin = d->sparse->lowerBound(newLen);
if (begin != d->sparse->end()) {
SparseArrayNode *it = d->sparse->end()->previousNode();
@@ -606,11 +607,11 @@ uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n)
Property *ArrayData::insert(Object *o, uint index, bool isAccessor)
{
if (!isAccessor && o->d()->arrayData->type != Heap::ArrayData::Sparse) {
- Heap::SimpleArrayData *d = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *d = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (index < 0x1000 || index < d->len + (d->len >> 2)) {
if (index >= d->alloc) {
o->arrayReserve(index + 1);
- d = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ d = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
if (index >= d->len) {
// mark possible hole in the array
@@ -623,11 +624,11 @@ Property *ArrayData::insert(Object *o, uint index, bool isAccessor)
}
o->initSparseArray();
- Heap::SparseArrayData *s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Heap::SparseArrayData *s = o->d()->arrayData.cast<Heap::SparseArrayData>();
SparseArrayNode *n = s->sparse->insert(index);
if (n->value == UINT_MAX)
n->value = SparseArrayData::allocate(o, isAccessor);
- s = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ s = o->d()->arrayData.cast<Heap::SparseArrayData>();
return reinterpret_cast<Property *>(s->arrayData + n->value);
}
@@ -737,7 +738,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
if (!arrayData || !arrayData->length())
return;
- if (!(comparefn.isUndefined() || comparefn.asObject())) {
+ if (!(comparefn.isUndefined() || comparefn.as<Object>())) {
engine->throwTypeError();
return;
}
@@ -755,7 +756,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
thisObject->setArrayData(0);
ArrayData::realloc(thisObject, Heap::ArrayData::Simple, sparse->sparse()->nEntries(), sparse->attrs() ? true : false);
- Heap::SimpleArrayData *d = static_cast<Heap::SimpleArrayData *>(thisObject->d()->arrayData);
+ Heap::SimpleArrayData *d = thisObject->d()->arrayData.cast<Heap::SimpleArrayData>();
SparseArrayNode *n = sparse->sparse()->begin();
uint i = 0;
@@ -795,7 +796,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
}
} else {
- Heap::SimpleArrayData *d = static_cast<Heap::SimpleArrayData *>(thisObject->d()->arrayData);
+ Heap::SimpleArrayData *d = thisObject->d()->arrayData.cast<Heap::SimpleArrayData>();
if (len > d->len)
len = d->len;
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index 915e862bbb..667827d1e9 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -47,7 +47,7 @@ namespace QV4 {
Q_MANAGED_CHECK \
typedef QV4::Heap::DataClass Data; \
static const QV4::ArrayVTable static_vtbl; \
- static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
+ static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \
V4_MANAGED_SIZE_TEST \
const Data *d() const { return static_cast<const Data *>(m); } \
Data *d() { return static_cast<Data *>(m); }
@@ -57,7 +57,7 @@ struct ArrayData;
struct ArrayVTable
{
- ManagedVTable managedVTable;
+ VTable vTable;
uint type;
Heap::ArrayData *(*reallocate)(Object *o, uint n, bool enforceAttributes);
ReturnedValue (*get)(const Heap::ArrayData *d, uint index);
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 231eb93dd5..986ceead1c 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -37,6 +37,7 @@
#include "qv4scopedvalue_p.h"
#include "qv4argumentsobject_p.h"
#include "qv4runtime_p.h"
+#include "qv4string_p.h"
using namespace QV4;
@@ -47,9 +48,9 @@ Heap::ArrayCtor::ArrayCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData)
+ReturnedValue ArrayCtor::construct(const Managed *m, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<ArrayCtor *>(m)->engine();
+ ExecutionEngine *v4 = static_cast<const ArrayCtor *>(m)->engine();
Scope scope(v4);
ScopedArrayObject a(scope, v4->newArrayObject());
uint len;
@@ -72,7 +73,7 @@ ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData)
return a.asReturnedValue();
}
-ReturnedValue ArrayCtor::call(Managed *that, CallData *callData)
+ReturnedValue ArrayCtor::call(const Managed *that, CallData *callData)
{
return construct(that, callData);
}
@@ -110,7 +111,7 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
ReturnedValue ArrayPrototype::method_isArray(CallContext *ctx)
{
- bool isArray = ctx->argc() && ctx->args()[0].asArrayObject();
+ bool isArray = ctx->argc() && ctx->args()[0].as<ArrayObject>();
return Encode(isArray);
}
@@ -194,7 +195,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
QString R;
// ### FIXME
- if (ArrayObject *a = self->asArrayObject()) {
+ if (ArrayObject *a = self->as<ArrayObject>()) {
ScopedValue e(scope);
for (uint i = 0; i < a->getLength(); ++i) {
if (i)
@@ -619,7 +620,7 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
return Encode(-1);
} else {
Q_ASSERT(instance->arrayType() == Heap::ArrayData::Simple || instance->arrayType() == Heap::ArrayData::Complex);
- Heap::SimpleArrayData *sa = static_cast<Heap::SimpleArrayData *>(instance->d()->arrayData);
+ Heap::SimpleArrayData *sa = instance->d()->arrayData.cast<Heap::SimpleArrayData>();
if (len > sa->len)
len = sa->len;
uint idx = fromIndex;
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index 4e67eb2e31..422a0de675 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -53,8 +53,8 @@ struct ArrayCtor: FunctionObject
{
V4_OBJECT2(ArrayCtor, FunctionObject)
- static ReturnedValue construct(Managed *m, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
struct ArrayPrototype: ArrayObject
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index 9c293e783b..a70e45068a 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -32,6 +32,7 @@
****************************************************************************/
#include "qv4booleanobject_p.h"
+#include "qv4string_p.h"
using namespace QV4;
@@ -43,14 +44,14 @@ Heap::BooleanCtor::BooleanCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue BooleanCtor::construct(Managed *m, CallData *callData)
+ReturnedValue BooleanCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<BooleanCtor *>(m)->engine());
+ Scope scope(static_cast<const BooleanCtor *>(m)->engine());
bool n = callData->argc ? callData->args[0].toBoolean() : false;
return Encode(scope.engine->newBooleanObject(n));
}
-ReturnedValue BooleanCtor::call(Managed *, CallData *callData)
+ReturnedValue BooleanCtor::call(const Managed *, CallData *callData)
{
bool value = callData->argc ? callData->args[0].toBoolean() : 0;
return Encode(value);
@@ -73,7 +74,7 @@ ReturnedValue BooleanPrototype::method_toString(CallContext *ctx)
if (ctx->thisObject().isBoolean()) {
result = ctx->thisObject().booleanValue();
} else {
- BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>();
+ const BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>();
if (!thisObject)
return ctx->engine()->throwTypeError();
result = thisObject->value();
@@ -87,7 +88,7 @@ ReturnedValue BooleanPrototype::method_valueOf(CallContext *ctx)
if (ctx->thisObject().isBoolean())
return ctx->thisObject().asReturnedValue();
- BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>();
+ const BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>();
if (!thisObject)
return ctx->engine()->throwTypeError();
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index 903261bdce..77b5a74fde 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -53,8 +53,8 @@ struct BooleanCtor: FunctionObject
{
V4_OBJECT2(BooleanCtor, FunctionObject)
- static ReturnedValue construct(Managed *, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
struct BooleanPrototype: BooleanObject
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 9330f10780..0951015dde 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -36,10 +36,11 @@
#include <qv4context_p.h>
#include <qv4object_p.h>
#include <qv4objectproto_p.h>
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include <qv4argumentsobject_p.h>
#include "qv4function_p.h"
#include "qv4errorobject_p.h"
+#include "qv4string_p.h"
using namespace QV4;
@@ -105,7 +106,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
Scope scope(this);
// find the right context to create the binding on
- ScopedObject activation(scope, d()->engine->globalObject());
+ ScopedObject activation(scope, d()->engine->globalObject);
ScopedContext ctx(scope, this);
while (ctx) {
if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
@@ -130,7 +131,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
Heap::GlobalContext::GlobalContext(ExecutionEngine *eng)
: Heap::ExecutionContext(eng, Heap::ExecutionContext::Type_GlobalContext)
{
- global = eng->globalObject()->d();
+ global = eng->globalObject->d();
}
Heap::WithContext::WithContext(ExecutionEngine *engine, QV4::Object *with)
@@ -153,7 +154,7 @@ Heap::CatchContext::CatchContext(ExecutionEngine *engine, QV4::String *exception
lookups = parent->lookups;
compilationUnit = parent->compilationUnit;
- this->exceptionVarName = exceptionVarName;
+ this->exceptionVarName = exceptionVarName->d();
this->exceptionValue = exceptionValue;
}
@@ -216,7 +217,7 @@ bool ExecutionContext::deleteProperty(String *name)
return withObject->deleteProperty(name);
} else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext) {
Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx->d());
- if (c->exceptionVarName->isEqualTo(name))
+ if (c->exceptionVarName->isEqualTo(name->d()))
return false;
} else if (ctx->d()->type >= Heap::ExecutionContext::Type_CallContext) {
Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
@@ -289,7 +290,7 @@ void ExecutionContext::setProperty(String *name, const Value &value)
w->put(name, value);
return;
}
- } else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext && static_cast<Heap::CatchContext *>(ctx->d())->exceptionVarName->isEqualTo(name)) {
+ } else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext && static_cast<Heap::CatchContext *>(ctx->d())->exceptionVarName->isEqualTo(name->d())) {
static_cast<Heap::CatchContext *>(ctx->d())->exceptionValue = value;
return;
} else {
@@ -332,7 +333,7 @@ void ExecutionContext::setProperty(String *name, const Value &value)
engine()->throwReferenceError(n);
return;
}
- d()->engine->globalObject()->put(name, value);
+ d()->engine->globalObject->put(name, value);
}
ReturnedValue ExecutionContext::getProperty(String *name)
@@ -362,7 +363,7 @@ ReturnedValue ExecutionContext::getProperty(String *name)
else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext) {
hasCatchScope = true;
Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx->d());
- if (c->exceptionVarName->isEqualTo(name))
+ if (c->exceptionVarName->isEqualTo(name->d()))
return c->exceptionValue.asReturnedValue();
}
@@ -430,7 +431,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Heap::Object **
else if (ctx->d()->type == Heap::ExecutionContext::Type_CatchContext) {
hasCatchScope = true;
Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx->d());
- if (c->exceptionVarName->isEqualTo(name))
+ if (c->exceptionVarName->isEqualTo(name->d()))
return c->exceptionValue.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 8392dd836d..c35263ba7e 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -45,6 +45,7 @@ struct CompilationUnit;
struct Function;
}
+struct Identifier;
struct CallContext;
struct CatchContext;
struct WithContext;
@@ -84,8 +85,8 @@ struct ExecutionContext : Base {
CallData *callData;
ExecutionEngine *engine;
- ExecutionContext *parent;
- ExecutionContext *outer;
+ Pointer<ExecutionContext> parent;
+ Pointer<ExecutionContext> outer;
Lookup *lookups;
CompiledData::CompilationUnit *compilationUnit;
@@ -104,25 +105,25 @@ struct CallContext : ExecutionContext {
}
CallContext(ExecutionEngine *engine, QV4::Object *qml, QV4::FunctionObject *function);
- FunctionObject *function;
+ Pointer<FunctionObject> function;
Value *locals;
- Object *activation;
+ Pointer<Object> activation;
};
struct GlobalContext : ExecutionContext {
GlobalContext(ExecutionEngine *engine);
- Object *global;
+ Pointer<Object> global;
};
struct CatchContext : ExecutionContext {
CatchContext(ExecutionEngine *engine, QV4::String *exceptionVarName, const Value &exceptionValue);
- StringValue exceptionVarName;
+ Pointer<String> exceptionVarName;
Value exceptionValue;
};
struct WithContext : ExecutionContext {
WithContext(ExecutionEngine *engine, QV4::Object *with);
- Object *withObject;
+ Pointer<Object> withObject;
};
@@ -160,7 +161,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
static void markObjects(Heap::Base *m, ExecutionEngine *e);
- const Value &thisObject() const {
+ Value &thisObject() const {
return d()->callData->thisObject;
}
int argc() const {
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index 8a66c2cbfc..7d1a13c8fe 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -33,6 +33,7 @@
#include "qv4dataview_p.h"
#include "qv4arraybuffer_p.h"
+#include "qv4string_p.h"
#include "qendian.h"
@@ -46,9 +47,9 @@ Heap::DataViewCtor::DataViewCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue DataViewCtor::construct(Managed *m, CallData *callData)
+ReturnedValue DataViewCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<Object *>(m)->engine());
+ Scope scope(static_cast<const Object *>(m)->engine());
Scoped<ArrayBuffer> buffer(scope, callData->argument(0));
if (!buffer)
return scope.engine->throwTypeError();
@@ -69,14 +70,14 @@ ReturnedValue DataViewCtor::construct(Managed *m, CallData *callData)
}
-ReturnedValue DataViewCtor::call(Managed *that, CallData *callData)
+ReturnedValue DataViewCtor::call(const Managed *that, CallData *callData)
{
return construct(that, callData);
}
Heap::DataView::DataView(ExecutionEngine *e)
- : Heap::Object(e->emptyClass, e->dataViewPrototype.asObject()),
+ : Heap::Object(e->emptyClass, e->dataViewPrototype()),
buffer(0),
byteLength(0),
byteOffset(0)
diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h
index 3f0c1e9e23..e98239396a 100644
--- a/src/qml/jsruntime/qv4dataview_p.h
+++ b/src/qml/jsruntime/qv4dataview_p.h
@@ -48,7 +48,7 @@ struct DataViewCtor : FunctionObject {
struct DataView : Object {
DataView(ExecutionEngine *e);
- ArrayBuffer *buffer;
+ Pointer<ArrayBuffer> buffer;
uint byteLength;
uint byteOffset;
};
@@ -59,8 +59,8 @@ struct DataViewCtor: FunctionObject
{
V4_OBJECT2(DataViewCtor, FunctionObject)
- static ReturnedValue construct(Managed *m, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
struct DataView : Object
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 451ef2486d..87f45c460f 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -36,6 +36,7 @@
#include "qv4objectproto_p.h"
#include "qv4scopedvalue_p.h"
#include "qv4runtime_p.h"
+#include "qv4string_p.h"
#include <QtCore/QDebug>
#include <QtCore/QDateTime>
@@ -628,14 +629,14 @@ static double getLocalTZA()
DEFINE_OBJECT_VTABLE(DateObject);
Heap::DateObject::DateObject(QV4::ExecutionEngine *engine, const QDateTime &date)
- : Heap::Object(engine->emptyClass, engine->datePrototype.asObject())
+ : Heap::Object(engine->emptyClass, engine->datePrototype())
{
- value.setDouble(date.isValid() ? date.toMSecsSinceEpoch() : qSNaN());
+ this->date = date.isValid() ? date.toMSecsSinceEpoch() : qSNaN();
}
QDateTime DateObject::toQDateTime() const
{
- return ToDateTime(date().asDouble(), Qt::LocalTime);
+ return ToDateTime(date(), Qt::LocalTime);
}
DEFINE_OBJECT_VTABLE(DateCtor);
@@ -645,9 +646,9 @@ Heap::DateCtor::DateCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue DateCtor::construct(Managed *m, CallData *callData)
+ReturnedValue DateCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<DateCtor *>(m)->engine());
+ Scope scope(static_cast<const DateCtor *>(m)->engine());
double t = 0;
if (callData->argc == 0)
@@ -655,15 +656,16 @@ ReturnedValue DateCtor::construct(Managed *m, CallData *callData)
else if (callData->argc == 1) {
ScopedValue arg(scope, callData->args[0]);
- if (DateObject *d = arg->asDateObject())
- arg = d->date();
- else
+ if (DateObject *d = arg->as<DateObject>()) {
+ t = d->date();
+ } else {
arg = RuntimeHelpers::toPrimitive(arg, PREFERREDTYPE_HINT);
- if (arg->isString())
- t = ParseString(arg->stringValue()->toQString());
- else
- t = TimeClip(arg->toNumber());
+ if (arg->isString())
+ t = ParseString(arg->stringValue()->toQString());
+ else
+ t = TimeClip(arg->toNumber());
+ }
}
else { // d.argc > 1
@@ -683,10 +685,10 @@ ReturnedValue DateCtor::construct(Managed *m, CallData *callData)
return Encode(scope.engine->newDateObject(Primitive::fromDouble(t)));
}
-ReturnedValue DateCtor::call(Managed *m, CallData *)
+ReturnedValue DateCtor::call(const Managed *m, CallData *)
{
double t = currentTime();
- return static_cast<DateCtor *>(m)->engine()->newString(ToString(t))->asReturnedValue();
+ return static_cast<const DateCtor *>(m)->engine()->newString(ToString(t))->asReturnedValue();
}
void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
@@ -752,8 +754,8 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
double DatePrototype::getThisDate(ExecutionContext *ctx)
{
- if (DateObject *thisObject = ctx->thisObject().asDateObject())
- return thisObject->date().asDouble();
+ if (DateObject *thisObject = ctx->thisObject().as<DateObject>())
+ return thisObject->date();
else {
ctx->engine()->throwTypeError();
return 0;
@@ -994,8 +996,8 @@ ReturnedValue DatePrototype::method_setTime(CallContext *ctx)
return ctx->engine()->throwTypeError();
double t = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
- self->date().setDouble(TimeClip(t));
- return self->date().asReturnedValue();
+ self->setDate(TimeClip(t));
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx)
@@ -1005,175 +1007,175 @@ ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx)
if (!self)
return ctx->engine()->throwTypeError();
- double t = LocalTime(self->date().asDouble());
+ double t = LocalTime(self->date());
double ms = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
- self->date().setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
- return self->date().asReturnedValue();
+ self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
double ms = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
- self->date().setDouble(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))));
- return self->date().asReturnedValue();
+ self->setDate(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))));
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = LocalTime(self->date().asDouble());
+ double t = LocalTime(self->date());
double sec = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
double sec = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = LocalTime(self->date().asDouble());
+ double t = LocalTime(self->date());
double min = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber();
double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
double min = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber();
double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setHours(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = LocalTime(self->date().asDouble());
+ double t = LocalTime(self->date());
double hour = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber();
double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber();
double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
double hour = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber();
double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber();
double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(hour, min, sec, ms)));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setDate(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = LocalTime(self->date().asDouble());
+ double t = LocalTime(self->date());
double date = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
double date = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setMonth(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = LocalTime(self->date().asDouble());
+ double t = LocalTime(self->date());
double month = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
double month = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
if (std::isnan(t))
t = 0;
else
@@ -1189,49 +1191,49 @@ ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
r = UTC(MakeDate(r, TimeWithinDay(t)));
r = TimeClip(r);
}
- self->date().setDouble(r);
- return self->date().asReturnedValue();
+ self->setDate(r);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber();
double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber();
t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = LocalTime(self->date().asDouble());
+ double t = LocalTime(self->date());
if (std::isnan(t))
t = 0;
double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN();
double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber();
double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
- self->date().setDouble(t);
- return self->date().asReturnedValue();
+ self->setDate(t);
+ return Encode(self->date());
}
ReturnedValue DatePrototype::method_toUTCString(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
return ctx->d()->engine->newString(ToUTCString(t))->asReturnedValue();
}
@@ -1250,11 +1252,11 @@ static void addZeroPrefixedInt(QString &str, int num, int nDigits)
ReturnedValue DatePrototype::method_toISOString(CallContext *ctx)
{
- DateObject *self = ctx->thisObject().asDateObject();
+ DateObject *self = ctx->thisObject().as<DateObject>();
if (!self)
return ctx->engine()->throwTypeError();
- double t = self->date().asDouble();
+ double t = self->date();
if (!std::isfinite(t))
return ctx->engine()->throwRangeError(ctx->thisObject());
@@ -1297,7 +1299,7 @@ ReturnedValue DatePrototype::method_toJSON(CallContext *ctx)
ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("toISOString")));
ScopedValue v(scope, O->objectValue()->get(s));
- FunctionObject *toIso = v->asFunctionObject();
+ FunctionObject *toIso = v->as<FunctionObject>();
if (!toIso)
return ctx->engine()->throwTypeError();
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index dad3689054..133a8d27e8 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -49,18 +49,19 @@ struct DateObject : Object {
DateObject(InternalClass *ic, QV4::Object *prototype)
: Object(ic, prototype)
{
- value = Encode(qSNaN());
+ date = qSNaN();
}
DateObject(QV4::ExecutionEngine *engine, const Value &date)
- : Object(engine->emptyClass, engine->datePrototype.asObject())
+ : Object(engine->emptyClass, engine->datePrototype())
{
- value = date;
+ this->date = date.toNumber();
}
DateObject(QV4::ExecutionEngine *engine, const QDateTime &date);
- Value value;
+ double date;
};
+
struct DateCtor : FunctionObject {
DateCtor(QV4::ExecutionContext *scope);
};
@@ -72,19 +73,23 @@ struct DateObject: Object {
Q_MANAGED_TYPE(DateObject)
- Value date() const { return d()->value; }
- Value &date() { return d()->value; }
- void setDate(const Value &date) { d()->value = date; }
+ double date() const { return d()->date; }
+ void setDate(double date) { d()->date = date; }
QDateTime toQDateTime() const;
};
+template<>
+inline const DateObject *Value::as() const {
+ return isManaged() && m && m->vtable->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : 0;
+}
+
struct DateCtor: FunctionObject
{
V4_OBJECT2(DateCtor, FunctionObject)
- static ReturnedValue construct(Managed *, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *);
+ static ReturnedValue construct(const Managed *, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *);
};
struct DatePrototype: DateObject
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index 36e7a3558c..cd9e1e3936 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -40,6 +40,7 @@
#include "qv4script_p.h"
#include "qv4objectiterator_p.h"
#include "qv4identifier_p.h"
+#include "qv4string_p.h"
#include <iostream>
#include <algorithm>
@@ -469,7 +470,7 @@ void Debugger::collectThrownValue(Collector *collector)
void run()
{
Scope scope(engine);
- ScopedValue v(scope, engine->exceptionValue);
+ ScopedValue v(scope, *engine->exceptionValue);
collector->collect(QStringLiteral("exception"), v);
}
};
@@ -793,7 +794,7 @@ void Debugger::Collector::collect(const QString &name, const ScopedValue &value)
addBoolean(name, value->booleanValue());
break;
case Value::Managed_Type:
- if (String *s = value->asString())
+ if (const String *s = value->as<String>())
addString(name, s->toQString());
else
addObject(name, value);
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index ba6f5a3b79..eacd4220cd 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -32,7 +32,7 @@
****************************************************************************/
#include <qv4engine_p.h>
#include <qv4context_p.h>
-#include <qv4value_inl_p.h>
+#include <qv4value_p.h>
#include <qv4object_p.h>
#include <qv4objectproto_p.h>
#include <qv4objectiterator_p.h>
@@ -48,7 +48,7 @@
#include <qv4regexp_p.h>
#include <qv4variantobject_p.h>
#include <qv4runtime_p.h>
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include <qv4argumentsobject_p.h>
#include <qv4dateobject_p.h>
#include <qv4jsonobject_p.h>
@@ -192,6 +192,7 @@ QQmlEngine *ExecutionEngine::qmlEngine() const
ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
: current(0)
+ , hasException(false)
, memoryManager(new QV4::MemoryManager(this))
, executableAllocator(new QV4::ExecutableAllocator)
, regExpAllocator(new QV4::ExecutableAllocator)
@@ -210,9 +211,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
{
MemoryManager::GCBlocker gcBlocker(memoryManager);
- exceptionValue = Encode::undefined();
- hasException = false;
-
if (!factory) {
#ifdef V4_ENABLE_JIT
@@ -236,6 +234,12 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
jsStackBase = (Value *)jsStack->base();
jsStackTop = jsStackBase;
+ exceptionValue = jsAlloca(1);
+ globalObject = static_cast<Object *>(jsAlloca(1));
+ jsObjects = jsAlloca(NJSObjects);
+ typedArrayPrototype = static_cast<Object *>(jsAlloca(NTypedArrayTypes));
+ typedArrayCtors = static_cast<FunctionObject *>(jsAlloca(NTypedArrayTypes));
+
#ifdef V4_USE_VALGRIND
VALGRIND_MAKE_MEM_UNDEFINED(jsStackBase, 2*JSStackLimit);
#endif
@@ -246,8 +250,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
if (!recheckCStackLimits())
qFatal("Fatal: Not enough stack space available for QML. Please increase the process stack size to more than %d KBytes.", MinimumStackSize);
- Scope scope(this);
-
identifierTable = new IdentifierTable(this);
classPool = new InternalClassPool;
@@ -291,29 +293,29 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
id_buffer = newIdentifier(QStringLiteral("buffer"));
id_lastIndex = newIdentifier(QStringLiteral("lastIndex"));
- objectPrototype = memoryManager->alloc<ObjectPrototype>(emptyClass, (QV4::Object *)0);
+ jsObjects[ObjectProto] = memoryManager->alloc<ObjectPrototype>(emptyClass, (QV4::Object *)0);
arrayClass = emptyClass->addMember(id_length, Attr_NotConfigurable|Attr_NotEnumerable);
- arrayPrototype = memoryManager->alloc<ArrayPrototype>(arrayClass, objectPrototype.asObject());
+ jsObjects[ArrayProto] = memoryManager->alloc<ArrayPrototype>(arrayClass, objectPrototype());
InternalClass *argsClass = emptyClass->addMember(id_length, Attr_NotEnumerable);
argumentsObjectClass = argsClass->addMember(id_callee, Attr_Data|Attr_NotEnumerable);
strictArgumentsObjectClass = argsClass->addMember(id_callee, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
strictArgumentsObjectClass = strictArgumentsObjectClass->addMember(id_caller, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
- m_globalObject = newObject();
- Q_ASSERT(globalObject()->d()->vtable);
+ *static_cast<Value *>(globalObject) = newObject();
+ Q_ASSERT(globalObject->d()->vtable);
initRootContext();
- stringPrototype = memoryManager->alloc<StringPrototype>(emptyClass, objectPrototype.asObject());
- numberPrototype = memoryManager->alloc<NumberPrototype>(emptyClass, objectPrototype.asObject());
- booleanPrototype = memoryManager->alloc<BooleanPrototype>(emptyClass, objectPrototype.asObject());
- datePrototype = memoryManager->alloc<DatePrototype>(emptyClass, objectPrototype.asObject());
+ jsObjects[StringProto] = memoryManager->alloc<StringPrototype>(emptyClass, objectPrototype());
+ jsObjects[NumberProto] = memoryManager->alloc<NumberPrototype>(emptyClass, objectPrototype());
+ jsObjects[BooleanProto] = memoryManager->alloc<BooleanPrototype>(emptyClass, objectPrototype());
+ jsObjects[DateProto] = memoryManager->alloc<DatePrototype>(emptyClass, objectPrototype());
uint index;
InternalClass *functionProtoClass = emptyClass->addMember(id_prototype, Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
- functionPrototype = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype.asObject());
+ jsObjects[FunctionProto] = memoryManager->alloc<FunctionPrototype>(functionProtoClass, objectPrototype());
functionClass = emptyClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
simpleScriptFunctionClass = functionClass->addMember(id_name, Attr_ReadOnly, &index);
@@ -323,131 +325,132 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
protoClass = emptyClass->addMember(id_constructor, Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_ProtoConstructor);
- regExpPrototype = memoryManager->alloc<RegExpPrototype>(this);
+ jsObjects[RegExpProto] = memoryManager->alloc<RegExpPrototype>(this);
regExpExecArrayClass = arrayClass->addMember(id_index, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayIndex);
regExpExecArrayClass = regExpExecArrayClass->addMember(id_input, Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayInput);
- errorPrototype = memoryManager->alloc<ErrorPrototype>(emptyClass, objectPrototype.asObject());
- evalErrorPrototype = memoryManager->alloc<EvalErrorPrototype>(emptyClass, errorPrototype.asObject());
- rangeErrorPrototype = memoryManager->alloc<RangeErrorPrototype>(emptyClass, errorPrototype.asObject());
- referenceErrorPrototype = memoryManager->alloc<ReferenceErrorPrototype>(emptyClass, errorPrototype.asObject());
- syntaxErrorPrototype = memoryManager->alloc<SyntaxErrorPrototype>(emptyClass, errorPrototype.asObject());
- typeErrorPrototype = memoryManager->alloc<TypeErrorPrototype>(emptyClass, errorPrototype.asObject());
- uRIErrorPrototype = memoryManager->alloc<URIErrorPrototype>(emptyClass, errorPrototype.asObject());
+ jsObjects[ErrorProto] = memoryManager->alloc<ErrorPrototype>(emptyClass, objectPrototype());
+ jsObjects[EvalErrorProto] = memoryManager->alloc<EvalErrorPrototype>(emptyClass, errorPrototype());
+ jsObjects[RangeErrorProto] = memoryManager->alloc<RangeErrorPrototype>(emptyClass, errorPrototype());
+ jsObjects[ReferenceErrorProto] = memoryManager->alloc<ReferenceErrorPrototype>(emptyClass, errorPrototype());
+ jsObjects[SyntaxErrorProto] = memoryManager->alloc<SyntaxErrorPrototype>(emptyClass, errorPrototype());
+ jsObjects[TypeErrorProto] = memoryManager->alloc<TypeErrorPrototype>(emptyClass, errorPrototype());
+ jsObjects[URIErrorProto] = memoryManager->alloc<URIErrorPrototype>(emptyClass, errorPrototype());
- variantPrototype = memoryManager->alloc<VariantPrototype>(emptyClass, objectPrototype.asObject());
- Q_ASSERT(variantPrototype.asObject()->prototype() == objectPrototype.asObject()->d());
+ jsObjects[VariantProto] = memoryManager->alloc<VariantPrototype>(emptyClass, objectPrototype());
+ Q_ASSERT(variantPrototype()->prototype() == objectPrototype()->d());
- sequencePrototype = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype.asObject()));
+ Scope scope(this);
+ jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->alloc<SequencePrototype>(arrayClass, arrayPrototype()));
ScopedContext global(scope, rootContext());
- objectCtor = memoryManager->alloc<ObjectCtor>(global);
- stringCtor = memoryManager->alloc<StringCtor>(global);
- numberCtor = memoryManager->alloc<NumberCtor>(global);
- booleanCtor = memoryManager->alloc<BooleanCtor>(global);
- arrayCtor = memoryManager->alloc<ArrayCtor>(global);
- functionCtor = memoryManager->alloc<FunctionCtor>(global);
- dateCtor = memoryManager->alloc<DateCtor>(global);
- regExpCtor = memoryManager->alloc<RegExpCtor>(global);
- errorCtor = memoryManager->alloc<ErrorCtor>(global);
- evalErrorCtor = memoryManager->alloc<EvalErrorCtor>(global);
- rangeErrorCtor = memoryManager->alloc<RangeErrorCtor>(global);
- referenceErrorCtor = memoryManager->alloc<ReferenceErrorCtor>(global);
- syntaxErrorCtor = memoryManager->alloc<SyntaxErrorCtor>(global);
- typeErrorCtor = memoryManager->alloc<TypeErrorCtor>(global);
- uRIErrorCtor = memoryManager->alloc<URIErrorCtor>(global);
-
- static_cast<ObjectPrototype *>(objectPrototype.asObject())->init(this, objectCtor.asObject());
- static_cast<StringPrototype *>(stringPrototype.asObject())->init(this, stringCtor.asObject());
- static_cast<NumberPrototype *>(numberPrototype.asObject())->init(this, numberCtor.asObject());
- static_cast<BooleanPrototype *>(booleanPrototype.asObject())->init(this, booleanCtor.asObject());
- static_cast<ArrayPrototype *>(arrayPrototype.asObject())->init(this, arrayCtor.asObject());
- static_cast<DatePrototype *>(datePrototype.asObject())->init(this, dateCtor.asObject());
- static_cast<FunctionPrototype *>(functionPrototype.asObject())->init(this, functionCtor.asObject());
- static_cast<RegExpPrototype *>(regExpPrototype.asObject())->init(this, regExpCtor.asObject());
- static_cast<ErrorPrototype *>(errorPrototype.asObject())->init(this, errorCtor.asObject());
- static_cast<EvalErrorPrototype *>(evalErrorPrototype.asObject())->init(this, evalErrorCtor.asObject());
- static_cast<RangeErrorPrototype *>(rangeErrorPrototype.asObject())->init(this, rangeErrorCtor.asObject());
- static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype.asObject())->init(this, referenceErrorCtor.asObject());
- static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype.asObject())->init(this, syntaxErrorCtor.asObject());
- static_cast<TypeErrorPrototype *>(typeErrorPrototype.asObject())->init(this, typeErrorCtor.asObject());
- static_cast<URIErrorPrototype *>(uRIErrorPrototype.asObject())->init(this, uRIErrorCtor.asObject());
-
- static_cast<VariantPrototype *>(variantPrototype.asObject())->init();
- sequencePrototype.cast<SequencePrototype>()->init();
+ jsObjects[Object_Ctor] = memoryManager->alloc<ObjectCtor>(global);
+ jsObjects[String_Ctor] = memoryManager->alloc<StringCtor>(global);
+ jsObjects[Number_Ctor] = memoryManager->alloc<NumberCtor>(global);
+ jsObjects[Boolean_Ctor] = memoryManager->alloc<BooleanCtor>(global);
+ jsObjects[Array_Ctor] = memoryManager->alloc<ArrayCtor>(global);
+ jsObjects[Function_Ctor] = memoryManager->alloc<FunctionCtor>(global);
+ jsObjects[Date_Ctor] = memoryManager->alloc<DateCtor>(global);
+ jsObjects[RegExp_Ctor] = memoryManager->alloc<RegExpCtor>(global);
+ jsObjects[Error_Ctor] = memoryManager->alloc<ErrorCtor>(global);
+ jsObjects[EvalError_Ctor] = memoryManager->alloc<EvalErrorCtor>(global);
+ jsObjects[RangeError_Ctor] = memoryManager->alloc<RangeErrorCtor>(global);
+ jsObjects[ReferenceError_Ctor] = memoryManager->alloc<ReferenceErrorCtor>(global);
+ jsObjects[SyntaxError_Ctor] = memoryManager->alloc<SyntaxErrorCtor>(global);
+ jsObjects[TypeError_Ctor] = memoryManager->alloc<TypeErrorCtor>(global);
+ jsObjects[URIError_Ctor] = memoryManager->alloc<URIErrorCtor>(global);
+
+ static_cast<ObjectPrototype *>(objectPrototype())->init(this, objectCtor());
+ static_cast<StringPrototype *>(stringPrototype())->init(this, stringCtor());
+ static_cast<NumberPrototype *>(numberPrototype())->init(this, numberCtor());
+ static_cast<BooleanPrototype *>(booleanPrototype())->init(this, booleanCtor());
+ static_cast<ArrayPrototype *>(arrayPrototype())->init(this, arrayCtor());
+ static_cast<DatePrototype *>(datePrototype())->init(this, dateCtor());
+ static_cast<FunctionPrototype *>(functionPrototype())->init(this, functionCtor());
+ static_cast<RegExpPrototype *>(regExpPrototype())->init(this, regExpCtor());
+ static_cast<ErrorPrototype *>(errorPrototype())->init(this, errorCtor());
+ static_cast<EvalErrorPrototype *>(evalErrorPrototype())->init(this, evalErrorCtor());
+ static_cast<RangeErrorPrototype *>(rangeErrorPrototype())->init(this, rangeErrorCtor());
+ static_cast<ReferenceErrorPrototype *>(referenceErrorPrototype())->init(this, referenceErrorCtor());
+ static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype())->init(this, syntaxErrorCtor());
+ static_cast<TypeErrorPrototype *>(typeErrorPrototype())->init(this, typeErrorCtor());
+ static_cast<URIErrorPrototype *>(uRIErrorPrototype())->init(this, uRIErrorCtor());
+
+ static_cast<VariantPrototype *>(variantPrototype())->init();
+ sequencePrototype()->cast<SequencePrototype>()->init();
// typed arrays
- arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(global);
- arrayBufferPrototype = memoryManager->alloc<ArrayBufferPrototype>(emptyClass, objectPrototype.asObject());
- static_cast<ArrayBufferPrototype *>(arrayBufferPrototype.asObject())->init(this, arrayBufferCtor.asObject());
+ jsObjects[ArrayBuffer_Ctor] = memoryManager->alloc<ArrayBufferCtor>(global);
+ jsObjects[ArrayBufferProto] = memoryManager->alloc<ArrayBufferPrototype>(emptyClass, objectPrototype());
+ static_cast<ArrayBufferPrototype *>(arrayBufferPrototype())->init(this, arrayBufferCtor());
- dataViewCtor = memoryManager->alloc<DataViewCtor>(global);
- dataViewPrototype = memoryManager->alloc<DataViewPrototype>(emptyClass, objectPrototype.asObject());
- static_cast<DataViewPrototype *>(dataViewPrototype.asObject())->init(this, dataViewCtor.asObject());
+ jsObjects[DataView_Ctor] = memoryManager->alloc<DataViewCtor>(global);
+ jsObjects[DataViewProto] = memoryManager->alloc<DataViewPrototype>(emptyClass, objectPrototype());
+ static_cast<DataViewPrototype *>(dataViewPrototype())->init(this, dataViewCtor());
for (int i = 0; i < Heap::TypedArray::NTypes; ++i) {
- typedArrayCtors[i] = memoryManager->alloc<TypedArrayCtor>(global, Heap::TypedArray::Type(i));
- typedArrayPrototype[i] = memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i));
- typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].asObject()));
+ static_cast<Value &>(typedArrayCtors[i]) = memoryManager->alloc<TypedArrayCtor>(global, Heap::TypedArray::Type(i));
+ static_cast<Value &>(typedArrayPrototype[i]) = memoryManager->alloc<TypedArrayPrototype>(this, Heap::TypedArray::Type(i));
+ typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].as<Object>()));
}
//
// set up the global object
//
- rootContext()->global = globalObject()->d();
- rootContext()->callData->thisObject = globalObject();
- Q_ASSERT(globalObject()->d()->vtable);
-
- globalObject()->defineDefaultProperty(QStringLiteral("Object"), objectCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("String"), stringCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("Number"), numberCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("Boolean"), booleanCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("Array"), arrayCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("Function"), functionCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("Date"), dateCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("RegExp"), regExpCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("Error"), errorCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("EvalError"), evalErrorCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("RangeError"), rangeErrorCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("ReferenceError"), referenceErrorCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("SyntaxError"), syntaxErrorCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("TypeError"), typeErrorCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("URIError"), uRIErrorCtor);
-
- globalObject()->defineDefaultProperty(QStringLiteral("ArrayBuffer"), arrayBufferCtor);
- globalObject()->defineDefaultProperty(QStringLiteral("DataView"), dataViewCtor);
+ rootContext()->global = globalObject->d();
+ rootContext()->callData->thisObject = globalObject;
+ Q_ASSERT(globalObject->d()->vtable);
+
+ globalObject->defineDefaultProperty(QStringLiteral("Object"), *objectCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("String"), *stringCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("Number"), *numberCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("Boolean"), *booleanCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("Array"), *arrayCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("Function"), *functionCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("Date"), *dateCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("RegExp"), *regExpCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("Error"), *errorCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("EvalError"), *evalErrorCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("RangeError"), *rangeErrorCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("ReferenceError"), *referenceErrorCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("SyntaxError"), *syntaxErrorCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("TypeError"), *typeErrorCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("URIError"), *uRIErrorCtor());
+
+ globalObject->defineDefaultProperty(QStringLiteral("ArrayBuffer"), *arrayBufferCtor());
+ globalObject->defineDefaultProperty(QStringLiteral("DataView"), *dataViewCtor());
ScopedString str(scope);
for (int i = 0; i < Heap::TypedArray::NTypes; ++i)
- globalObject()->defineDefaultProperty((str = typedArrayCtors[i].asFunctionObject()->name())->toQString(), typedArrayCtors[i]);
+ globalObject->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name())->toQString(), typedArrayCtors[i]);
ScopedObject o(scope);
- globalObject()->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->alloc<MathObject>(this)));
- globalObject()->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->alloc<JsonObject>(this)));
+ globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->alloc<MathObject>(this)));
+ globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->alloc<JsonObject>(this)));
- globalObject()->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue());
- globalObject()->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN()));
- globalObject()->defineReadonlyProperty(QStringLiteral("Infinity"), Primitive::fromDouble(Q_INFINITY));
+ globalObject->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue());
+ globalObject->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN()));
+ globalObject->defineReadonlyProperty(QStringLiteral("Infinity"), Primitive::fromDouble(Q_INFINITY));
- evalFunction = memoryManager->alloc<EvalFunction>(global);
- globalObject()->defineDefaultProperty(QStringLiteral("eval"), (o = evalFunction));
+ jsObjects[Eval_Function] = memoryManager->alloc<EvalFunction>(global);
+ globalObject->defineDefaultProperty(QStringLiteral("eval"), *evalFunction());
- globalObject()->defineDefaultProperty(QStringLiteral("parseInt"), GlobalFunctions::method_parseInt, 2);
- globalObject()->defineDefaultProperty(QStringLiteral("parseFloat"), GlobalFunctions::method_parseFloat, 1);
- globalObject()->defineDefaultProperty(QStringLiteral("isNaN"), GlobalFunctions::method_isNaN, 1);
- globalObject()->defineDefaultProperty(QStringLiteral("isFinite"), GlobalFunctions::method_isFinite, 1);
- globalObject()->defineDefaultProperty(QStringLiteral("decodeURI"), GlobalFunctions::method_decodeURI, 1);
- globalObject()->defineDefaultProperty(QStringLiteral("decodeURIComponent"), GlobalFunctions::method_decodeURIComponent, 1);
- globalObject()->defineDefaultProperty(QStringLiteral("encodeURI"), GlobalFunctions::method_encodeURI, 1);
- globalObject()->defineDefaultProperty(QStringLiteral("encodeURIComponent"), GlobalFunctions::method_encodeURIComponent, 1);
- globalObject()->defineDefaultProperty(QStringLiteral("escape"), GlobalFunctions::method_escape, 1);
- globalObject()->defineDefaultProperty(QStringLiteral("unescape"), GlobalFunctions::method_unescape, 1);
+ globalObject->defineDefaultProperty(QStringLiteral("parseInt"), GlobalFunctions::method_parseInt, 2);
+ globalObject->defineDefaultProperty(QStringLiteral("parseFloat"), GlobalFunctions::method_parseFloat, 1);
+ globalObject->defineDefaultProperty(QStringLiteral("isNaN"), GlobalFunctions::method_isNaN, 1);
+ globalObject->defineDefaultProperty(QStringLiteral("isFinite"), GlobalFunctions::method_isFinite, 1);
+ globalObject->defineDefaultProperty(QStringLiteral("decodeURI"), GlobalFunctions::method_decodeURI, 1);
+ globalObject->defineDefaultProperty(QStringLiteral("decodeURIComponent"), GlobalFunctions::method_decodeURIComponent, 1);
+ globalObject->defineDefaultProperty(QStringLiteral("encodeURI"), GlobalFunctions::method_encodeURI, 1);
+ globalObject->defineDefaultProperty(QStringLiteral("encodeURIComponent"), GlobalFunctions::method_encodeURIComponent, 1);
+ globalObject->defineDefaultProperty(QStringLiteral("escape"), GlobalFunctions::method_escape, 1);
+ globalObject->defineDefaultProperty(QStringLiteral("unescape"), GlobalFunctions::method_unescape, 1);
ScopedString name(scope, newString(QStringLiteral("thrower")));
- thrower = BuiltinFunction::create(global, name, ::throwTypeError);
+ jsObjects[ThrowerObject] = BuiltinFunction::create(global, name, ::throwTypeError);
}
ExecutionEngine::~ExecutionEngine()
@@ -499,7 +502,7 @@ void ExecutionEngine::initRootContext()
r->d()->callData = reinterpret_cast<CallData *>(r->d() + 1);
r->d()->callData->tag = QV4::Value::_Integer_Type;
r->d()->callData->argc = 0;
- r->d()->callData->thisObject = globalObject();
+ r->d()->callData->thisObject = globalObject;
r->d()->callData->args[0] = Encode::undefined();
m_rootContext = r->d();
@@ -648,7 +651,7 @@ Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re)
Heap::Object *ExecutionEngine::newErrorObject(const Value &value)
{
Scope scope(this);
- ScopedObject object(scope, memoryManager->alloc<ErrorObject>(emptyClass, errorPrototype.asObject(), value));
+ ScopedObject object(scope, memoryManager->alloc<ErrorObject>(emptyClass, errorPrototype(), value));
return object->d();
}
@@ -884,8 +887,6 @@ void ExecutionEngine::markObjects()
{
identifierTable->mark(this);
- globalObject()->mark(this);
-
for (int i = 0; i < nArgumentsAccessors; ++i) {
const Property &pd = argumentsAccessors[i];
if (Heap::FunctionObject *getter = pd.getter())
@@ -941,53 +942,9 @@ void ExecutionEngine::markObjects()
id_buffer->mark(this);
id_lastIndex->mark(this);
- objectCtor.mark(this);
- stringCtor.mark(this);
- numberCtor.mark(this);
- booleanCtor.mark(this);
- arrayCtor.mark(this);
- functionCtor.mark(this);
- dateCtor.mark(this);
- regExpCtor.mark(this);
- errorCtor.mark(this);
- evalErrorCtor.mark(this);
- rangeErrorCtor.mark(this);
- referenceErrorCtor.mark(this);
- syntaxErrorCtor.mark(this);
- typeErrorCtor.mark(this);
- uRIErrorCtor.mark(this);
- arrayBufferCtor.mark(this);
- dataViewCtor.mark(this);
for (int i = 0; i < Heap::TypedArray::NTypes; ++i)
typedArrayCtors[i].mark(this);
- objectPrototype.mark(this);
- arrayPrototype.mark(this);
- stringPrototype.mark(this);
- numberPrototype.mark(this);
- booleanPrototype.mark(this);
- datePrototype.mark(this);
- functionPrototype.mark(this);
- regExpPrototype.mark(this);
- errorPrototype.mark(this);
- evalErrorPrototype.mark(this);
- rangeErrorPrototype.mark(this);
- referenceErrorPrototype.mark(this);
- syntaxErrorPrototype.mark(this);
- typeErrorPrototype.mark(this);
- uRIErrorPrototype.mark(this);
- variantPrototype.mark(this);
- sequencePrototype.mark(this);
-
- arrayBufferPrototype.mark(this);
- dataViewPrototype.mark(this);
- for (int i = 0; i < Heap::TypedArray::NTypes; ++i)
- typedArrayPrototype[i].mark(this);
-
- exceptionValue.mark(this);
-
- thrower->mark(this);
-
if (m_qmlExtensions)
m_qmlExtensions->markObjects(this);
@@ -1015,7 +972,7 @@ ReturnedValue ExecutionEngine::throwError(const Value &value)
return Encode::undefined();
hasException = true;
- exceptionValue = value;
+ *exceptionValue = value;
QV4::Scope scope(this);
QV4::Scoped<ErrorObject> error(scope, value);
if (!!error)
@@ -1036,8 +993,8 @@ ReturnedValue ExecutionEngine::catchException(StackTrace *trace)
*trace = exceptionStackTrace;
exceptionStackTrace.clear();
hasException = false;
- ReturnedValue res = exceptionValue.asReturnedValue();
- exceptionValue = Primitive::emptyValue();
+ ReturnedValue res = exceptionValue->asReturnedValue();
+ *exceptionValue = Primitive::emptyValue();
return res;
}
@@ -1193,7 +1150,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
Q_ASSERT (!value.isEmpty());
QV4::Scope scope(e);
- if (QV4::VariantObject *v = value.as<QV4::VariantObject>())
+ if (const QV4::VariantObject *v = value.as<QV4::VariantObject>())
return v->d()->data;
if (typeHint == QVariant::Bool)
@@ -1205,10 +1162,10 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
if (typeHint == qMetaTypeId<QJSValue>())
return QVariant::fromValue(QJSValue(e, value.asReturnedValue()));
- if (value.asObject()) {
+ if (value.as<Object>()) {
QV4::ScopedObject object(scope, value);
if (typeHint == QMetaType::QJsonObject
- && !value.asArrayObject() && !value.asFunctionObject()) {
+ && !value.as<ArrayObject>() && !value.as<FunctionObject>()) {
return QVariant::fromValue(QV4::JsonObject::toJsonObject(object));
} else if (QV4::QObjectWrapper *wrapper = object->as<QV4::QObjectWrapper>()) {
return qVariantFromValue<QObject *>(wrapper->object());
@@ -1224,7 +1181,7 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return QV4::SequencePrototype::toVariant(object);
}
- if (value.asArrayObject()) {
+ if (value.as<ArrayObject>()) {
QV4::ScopedArrayObject a(scope, value);
if (typeHint == qMetaTypeId<QList<QObject *> >()) {
QList<QObject *> list;
@@ -1262,11 +1219,11 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return value.asDouble();
if (value.isString())
return value.stringValue()->toQString();
- if (QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>())
+ if (const QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>())
return ld->d()->locale;
- if (QV4::DateObject *d = value.asDateObject())
+ if (const QV4::DateObject *d = value.as<DateObject>())
return d->toQDateTime();
- if (QV4::ArrayBuffer *d = value.as<ArrayBuffer>())
+ if (const QV4::ArrayBuffer *d = value.as<ArrayBuffer>())
return d->asByteArray();
// NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)!
@@ -1293,7 +1250,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4Objec
// Avoid recursion.
// For compatibility with QVariant{List,Map} conversion, we return an
// empty object (and no error is thrown).
- if (o->asArrayObject())
+ if (o->as<ArrayObject>())
return QVariantList();
return QVariantMap();
}
@@ -1301,7 +1258,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4Objec
QVariant result;
- if (o->asArrayObject()) {
+ if (o->as<ArrayObject>()) {
QV4::Scope scope(e);
QV4::ScopedArrayObject a(scope, o->asReturnedValue());
QV4::ScopedValue v(scope);
@@ -1314,7 +1271,7 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4Objec
}
result = list;
- } else if (!o->asFunctionObject()) {
+ } else if (!o->as<FunctionObject>()) {
QVariantMap map;
QV4::Scope scope(e);
QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
@@ -1625,11 +1582,10 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data)
return 0;
}
-void ExecutionEngine::assertObjectBelongsToEngine(const Value &v)
+void ExecutionEngine::assertObjectBelongsToEngine(const Heap::Base &baseObject)
{
- Q_UNUSED(v);
- Q_ASSERT(!v.isObject() || v.objectValue()->engine() == this);
- Q_UNUSED(v);
+ Q_ASSERT(!baseObject.vtable->isObject || static_cast<const Heap::Object&>(baseObject).internalClass->engine == this);
+ Q_UNUSED(baseObject);
}
// Converts a JS value to a meta-type.
@@ -1689,22 +1645,22 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da
}
return true;
case QMetaType::QDateTime:
- if (QV4::DateObject *d = value.asDateObject()) {
+ if (const QV4::DateObject *d = value.as<DateObject>()) {
*reinterpret_cast<QDateTime *>(data) = d->toQDateTime();
return true;
} break;
case QMetaType::QDate:
- if (QV4::DateObject *d = value.asDateObject()) {
+ if (const QV4::DateObject *d = value.as<DateObject>()) {
*reinterpret_cast<QDate *>(data) = d->toQDateTime().date();
return true;
} break;
case QMetaType::QRegExp:
- if (QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) {
+ if (const QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) {
*reinterpret_cast<QRegExp *>(data) = r->toQRegExp();
return true;
} break;
case QMetaType::QObjectStar: {
- QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>();
+ const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>();
if (qobjectWrapper || value.isNull()) {
*reinterpret_cast<QObject* *>(data) = qtObjectFromJS(scope.engine, value);
return true;
@@ -1783,7 +1739,7 @@ bool ExecutionEngine::metaTypeFromJS(const QV4::Value &value, int type, void *da
}
#endif
- // Try to use magic; for compatibility with qscriptvalue_cast.
+ // Try to use magic; for compatibility with qjsvalue_cast.
QByteArray name = QMetaType::typeName(type);
if (convertToNativeQObject(this, value, name, reinterpret_cast<void* *>(data)))
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index c0c88abaa5..79aafeb268 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -37,6 +37,8 @@
#include "private/qv4isel_p.h"
#include "qv4managed_p.h"
#include "qv4context_p.h"
+#include "qv4typedvalue_p.h"
+#include "qv4internalclass_p.h"
#include <private/qintrusivelist_p.h>
namespace WTF {
@@ -106,14 +108,19 @@ public:
--jsStackTop;
return jsStackTop->heapObject();
}
+ Value *jsAlloca(int nValues) {
+ Value *ptr = jsStackTop;
+ jsStackTop = ptr + nValues;
+ memset(ptr, 0, nValues*sizeof(Value));
+ return ptr;
+ }
IdentifierTable *identifierTable;
QV4::Debugging::Debugger *debugger;
QV4::Profiling::Profiler *profiler;
- Value m_globalObject;
- Object *globalObject() { return reinterpret_cast<Object *>(&m_globalObject); }
+ Object *globalObject;
Function *globalCode;
@@ -121,47 +128,92 @@ public:
QQmlEngine *qmlEngine() const;
QV8Engine *v8Engine;
- Value objectCtor;
- Value stringCtor;
- Value numberCtor;
- Value booleanCtor;
- Value arrayCtor;
- Value functionCtor;
- Value dateCtor;
- Value regExpCtor;
- Value errorCtor;
- Value evalErrorCtor;
- Value rangeErrorCtor;
- Value referenceErrorCtor;
- Value syntaxErrorCtor;
- Value typeErrorCtor;
- Value uRIErrorCtor;
- Value arrayBufferCtor;
- Value dataViewCtor;
- enum { NTypedArrayTypes = 9 }; // avoid header dependency
- Value typedArrayCtors[NTypedArrayTypes];
-
- Value objectPrototype;
- Value arrayPrototype;
- Value stringPrototype;
- Value numberPrototype;
- Value booleanPrototype;
- Value datePrototype;
- Value functionPrototype;
- Value regExpPrototype;
- Value errorPrototype;
- Value evalErrorPrototype;
- Value rangeErrorPrototype;
- Value referenceErrorPrototype;
- Value syntaxErrorPrototype;
- Value typeErrorPrototype;
- Value uRIErrorPrototype;
- Value variantPrototype;
- Value sequencePrototype;
-
- Value arrayBufferPrototype;
- Value dataViewPrototype;
- Value typedArrayPrototype[NTypedArrayTypes]; // TypedArray::NValues, avoid including the header here
+ enum JSObjects {
+ ObjectProto,
+ ArrayProto,
+ StringProto,
+ NumberProto,
+ BooleanProto,
+ DateProto,
+ FunctionProto,
+ RegExpProto,
+ ErrorProto,
+ EvalErrorProto,
+ RangeErrorProto,
+ ReferenceErrorProto,
+ SyntaxErrorProto,
+ TypeErrorProto,
+ URIErrorProto,
+ VariantProto,
+ SequenceProto,
+ ArrayBufferProto,
+ DataViewProto,
+
+ Object_Ctor,
+ String_Ctor,
+ Number_Ctor,
+ Boolean_Ctor,
+ Array_Ctor,
+ Function_Ctor,
+ Date_Ctor,
+ RegExp_Ctor,
+ Error_Ctor,
+ EvalError_Ctor,
+ RangeError_Ctor,
+ ReferenceError_Ctor,
+ SyntaxError_Ctor,
+ TypeError_Ctor,
+ URIError_Ctor,
+ ArrayBuffer_Ctor,
+ DataView_Ctor,
+
+ Eval_Function,
+ ThrowerObject,
+ NJSObjects
+ };
+ Value *jsObjects;
+ enum { NTypedArrayTypes = 9 }; // == TypedArray::NValues, avoid header dependency
+
+ FunctionObject *objectCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Object_Ctor); }
+ FunctionObject *stringCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + String_Ctor); }
+ FunctionObject *numberCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Number_Ctor); }
+ FunctionObject *booleanCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Boolean_Ctor); }
+ FunctionObject *arrayCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Array_Ctor); }
+ FunctionObject *functionCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Function_Ctor); }
+ FunctionObject *dateCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Date_Ctor); }
+ FunctionObject *regExpCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + RegExp_Ctor); }
+ FunctionObject *errorCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Error_Ctor); }
+ FunctionObject *evalErrorCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + EvalError_Ctor); }
+ FunctionObject *rangeErrorCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + RangeError_Ctor); }
+ FunctionObject *referenceErrorCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + ReferenceError_Ctor); }
+ FunctionObject *syntaxErrorCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + SyntaxError_Ctor); }
+ FunctionObject *typeErrorCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + TypeError_Ctor); }
+ FunctionObject *uRIErrorCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + URIError_Ctor); }
+ FunctionObject *arrayBufferCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + ArrayBuffer_Ctor); }
+ FunctionObject *dataViewCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + DataView_Ctor); }
+ FunctionObject *typedArrayCtors;
+
+ Object *objectPrototype() const { return reinterpret_cast<Object *>(jsObjects + ObjectProto); }
+ Object *arrayPrototype() const { return reinterpret_cast<Object *>(jsObjects + ArrayProto); }
+ Object *stringPrototype() const { return reinterpret_cast<Object *>(jsObjects + StringProto); }
+ Object *numberPrototype() const { return reinterpret_cast<Object *>(jsObjects + NumberProto); }
+ Object *booleanPrototype() const { return reinterpret_cast<Object *>(jsObjects + BooleanProto); }
+ Object *datePrototype() const { return reinterpret_cast<Object *>(jsObjects + DateProto); }
+ Object *functionPrototype() const { return reinterpret_cast<Object *>(jsObjects + FunctionProto); }
+ Object *regExpPrototype() const { return reinterpret_cast<Object *>(jsObjects + RegExpProto); }
+ Object *errorPrototype() const { return reinterpret_cast<Object *>(jsObjects + ErrorProto); }
+ Object *evalErrorPrototype() const { return reinterpret_cast<Object *>(jsObjects + EvalErrorProto); }
+ Object *rangeErrorPrototype() const { return reinterpret_cast<Object *>(jsObjects + RangeErrorProto); }
+ Object *referenceErrorPrototype() const { return reinterpret_cast<Object *>(jsObjects + ReferenceErrorProto); }
+ Object *syntaxErrorPrototype() const { return reinterpret_cast<Object *>(jsObjects + SyntaxErrorProto); }
+ Object *typeErrorPrototype() const { return reinterpret_cast<Object *>(jsObjects + TypeErrorProto); }
+ Object *uRIErrorPrototype() const { return reinterpret_cast<Object *>(jsObjects + URIErrorProto); }
+ Object *variantPrototype() const { return reinterpret_cast<Object *>(jsObjects + VariantProto); }
+ Object *sequencePrototype() const { return reinterpret_cast<Object *>(jsObjects + SequenceProto); }
+
+ Object *arrayBufferPrototype() const { return reinterpret_cast<Object *>(jsObjects + ArrayBufferProto); }
+ Object *dataViewPrototype() const { return reinterpret_cast<Object *>(jsObjects + DataViewProto); }
+ Object *typedArrayPrototype;
InternalClassPool *classPool;
InternalClass *emptyClass;
@@ -177,8 +229,8 @@ public:
InternalClass *argumentsObjectClass;
InternalClass *strictArgumentsObjectClass;
- Heap::EvalFunction *evalFunction;
- Heap::FunctionObject *thrower;
+ EvalFunction *evalFunction() const { return reinterpret_cast<EvalFunction *>(jsObjects + Eval_Function); }
+ FunctionObject *thrower() const { return reinterpret_cast<FunctionObject *>(jsObjects + ThrowerObject); }
Property *argumentsAccessors;
int nArgumentsAccessors;
@@ -310,7 +362,7 @@ public:
bool recheckCStackLimits();
// Exception handling
- Value exceptionValue;
+ Value *exceptionValue;
StackTrace exceptionStackTrace;
ReturnedValue throwError(const Value &value);
@@ -340,7 +392,7 @@ public:
bool metaTypeFromJS(const Value &value, int type, void *data);
QV4::ReturnedValue metaTypeToJS(int type, const void *data);
- void assertObjectBelongsToEngine(const Value &v);
+ void assertObjectBelongsToEngine(const Heap::Base &baseObject);
private:
QmlExtensions *m_qmlExtensions;
@@ -376,29 +428,26 @@ Heap::ExecutionContext::ExecutionContext(ExecutionEngine *engine, ContextType t)
}
-// ### Remove me
inline
-void Managed::mark(QV4::ExecutionEngine *engine)
+void Heap::Base::mark(QV4::ExecutionEngine *engine)
{
Q_ASSERT(inUse());
- if (markBit())
+ if (isMarked())
return;
#ifndef QT_NO_DEBUG
engine->assertObjectBelongsToEngine(*this);
#endif
- d()->setMarkBit();
- engine->pushForGC(d());
+ setMarkBit();
+ engine->pushForGC(this);
}
-
-inline
-void Heap::Base::mark(QV4::ExecutionEngine *engine)
+inline void Value::mark(ExecutionEngine *e)
{
- Q_ASSERT(inUse());
- if (isMarked())
+ if (!val)
return;
- setMarkBit();
- engine->pushForGC(this);
+ Managed *m = as<Managed>();
+ if (m)
+ m->d()->mark(e);
}
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 9034dee6a0..2f9e09205a 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -33,11 +33,14 @@
#include "qv4errorobject_p.h"
-#include "qv4mm_p.h"
+#include <QtCore/qnumeric.h>
+#include <QtCore/qmath.h>
#include <QtCore/QDateTime>
#include <QtCore/QStringList>
#include <QtCore/QDebug>
+#include "qv4string_p.h"
+#include <private/qv4mm_p.h>
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
@@ -179,57 +182,57 @@ DEFINE_OBJECT_VTABLE(ErrorObject);
DEFINE_OBJECT_VTABLE(SyntaxErrorObject);
Heap::SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const Value &msg)
- : Heap::ErrorObject(engine->emptyClass, engine->syntaxErrorPrototype.asObject(), msg, SyntaxError)
+ : Heap::ErrorObject(engine->emptyClass, engine->syntaxErrorPrototype(), msg, SyntaxError)
{
}
Heap::SyntaxErrorObject::SyntaxErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
- : Heap::ErrorObject(engine->emptyClass, engine->syntaxErrorPrototype.asObject(), msg, fileName, lineNumber, columnNumber, SyntaxError)
+ : Heap::ErrorObject(engine->emptyClass, engine->syntaxErrorPrototype(), msg, fileName, lineNumber, columnNumber, SyntaxError)
{
}
Heap::EvalErrorObject::EvalErrorObject(ExecutionEngine *engine, const Value &message)
- : Heap::ErrorObject(engine->emptyClass, engine->evalErrorPrototype.asObject(), message, EvalError)
+ : Heap::ErrorObject(engine->emptyClass, engine->evalErrorPrototype(), message, EvalError)
{
}
Heap::RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const Value &message)
- : Heap::ErrorObject(engine->emptyClass, engine->rangeErrorPrototype.asObject(), message, RangeError)
+ : Heap::ErrorObject(engine->emptyClass, engine->rangeErrorPrototype(), message, RangeError)
{
}
Heap::RangeErrorObject::RangeErrorObject(ExecutionEngine *engine, const QString &message)
- : Heap::ErrorObject(engine->emptyClass, engine->rangeErrorPrototype.asObject(), message, RangeError)
+ : Heap::ErrorObject(engine->emptyClass, engine->rangeErrorPrototype(), message, RangeError)
{
}
Heap::ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const Value &message)
- : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype.asObject(), message, ReferenceError)
+ : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype(), message, ReferenceError)
{
}
Heap::ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &message)
- : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype.asObject(), message, ReferenceError)
+ : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype(), message, ReferenceError)
{
}
Heap::ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber, int columnNumber)
- : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype.asObject(), msg, fileName, lineNumber, columnNumber, ReferenceError)
+ : Heap::ErrorObject(engine->emptyClass, engine->referenceErrorPrototype(), msg, fileName, lineNumber, columnNumber, ReferenceError)
{
}
Heap::TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const Value &message)
- : Heap::ErrorObject(engine->emptyClass, engine->typeErrorPrototype.asObject(), message, TypeError)
+ : Heap::ErrorObject(engine->emptyClass, engine->typeErrorPrototype(), message, TypeError)
{
}
Heap::TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const QString &message)
- : Heap::ErrorObject(engine->emptyClass, engine->typeErrorPrototype.asObject(), message, TypeError)
+ : Heap::ErrorObject(engine->emptyClass, engine->typeErrorPrototype(), message, TypeError)
{
}
Heap::URIErrorObject::URIErrorObject(ExecutionEngine *engine, const Value &message)
- : Heap::ErrorObject(engine->emptyClass, engine->uRIErrorPrototype.asObject(), message, URIError)
+ : Heap::ErrorObject(engine->emptyClass, engine->uRIErrorPrototype(), message, URIError)
{
}
@@ -251,16 +254,16 @@ Heap::ErrorCtor::ErrorCtor(QV4::ExecutionContext *scope, const QString &name)
{
}
-ReturnedValue ErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue ErrorCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<ErrorCtor *>(m)->engine());
+ Scope scope(static_cast<const ErrorCtor *>(m)->engine());
ScopedValue v(scope, callData->argument(0));
return Encode(scope.engine->newErrorObject(v));
}
-ReturnedValue ErrorCtor::call(Managed *that, CallData *callData)
+ReturnedValue ErrorCtor::call(const Managed *that, CallData *callData)
{
- return static_cast<Object *>(that)->construct(callData);
+ return static_cast<const Object *>(that)->construct(callData);
}
Heap::EvalErrorCtor::EvalErrorCtor(QV4::ExecutionContext *scope)
@@ -268,9 +271,9 @@ Heap::EvalErrorCtor::EvalErrorCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue EvalErrorCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<EvalErrorCtor *>(m)->engine());
+ Scope scope(static_cast<const EvalErrorCtor *>(m)->engine());
ScopedValue v(scope, callData->argument(0));
return (scope.engine->memoryManager->alloc<EvalErrorObject>(scope.engine, v))->asReturnedValue();
}
@@ -280,9 +283,9 @@ Heap::RangeErrorCtor::RangeErrorCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue RangeErrorCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<RangeErrorCtor *>(m)->engine());
+ Scope scope(static_cast<const RangeErrorCtor *>(m)->engine());
ScopedValue v(scope, callData->argument(0));
return (scope.engine->memoryManager->alloc<RangeErrorObject>(scope.engine, v))->asReturnedValue();
}
@@ -292,9 +295,9 @@ Heap::ReferenceErrorCtor::ReferenceErrorCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue ReferenceErrorCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<ReferenceErrorCtor *>(m)->engine());
+ Scope scope(static_cast<const ReferenceErrorCtor *>(m)->engine());
ScopedValue v(scope, callData->argument(0));
return (scope.engine->memoryManager->alloc<ReferenceErrorObject>(scope.engine, v))->asReturnedValue();
}
@@ -304,9 +307,9 @@ Heap::SyntaxErrorCtor::SyntaxErrorCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue SyntaxErrorCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<SyntaxErrorCtor *>(m)->engine());
+ Scope scope(static_cast<const SyntaxErrorCtor *>(m)->engine());
ScopedValue v(scope, callData->argument(0));
return (scope.engine->memoryManager->alloc<SyntaxErrorObject>(scope.engine, v))->asReturnedValue();
}
@@ -316,9 +319,9 @@ Heap::TypeErrorCtor::TypeErrorCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue TypeErrorCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<TypeErrorCtor *>(m)->engine());
+ Scope scope(static_cast<const TypeErrorCtor *>(m)->engine());
ScopedValue v(scope, callData->argument(0));
return (scope.engine->memoryManager->alloc<TypeErrorObject>(scope.engine, v))->asReturnedValue();
}
@@ -328,9 +331,9 @@ Heap::URIErrorCtor::URIErrorCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue URIErrorCtor::construct(Managed *m, CallData *callData)
+ReturnedValue URIErrorCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<URIErrorCtor *>(m)->engine());
+ Scope scope(static_cast<const URIErrorCtor *>(m)->engine());
ScopedValue v(scope, callData->argument(0));
return (scope.engine->memoryManager->alloc<URIErrorObject>(scope.engine, v))->asReturnedValue();
}
@@ -351,7 +354,7 @@ ReturnedValue ErrorPrototype::method_toString(CallContext *ctx)
{
Scope scope(ctx);
- Object *o = ctx->thisObject().asObject();
+ Object *o = ctx->thisObject().as<Object>();
if (!o)
return ctx->engine()->throwTypeError();
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 071f5b8c9a..da2c978e5f 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -62,7 +62,7 @@ struct ErrorObject : Object {
ErrorType errorType;
StackTrace stackTrace;
- String *stack;
+ Pointer<String> stack;
};
struct EvalErrorObject : ErrorObject {
@@ -141,8 +141,8 @@ struct ErrorObject: Object {
};
template<>
-inline ErrorObject *value_cast(const Value &v) {
- return v.asErrorObject();
+inline const ErrorObject *Value::as() const {
+ return isManaged() && m && m->vtable->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : 0;
}
struct EvalErrorObject: ErrorObject {
@@ -183,50 +183,50 @@ struct ErrorCtor: FunctionObject
{
V4_OBJECT2(ErrorCtor, FunctionObject)
- static ReturnedValue construct(Managed *, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
struct EvalErrorCtor: ErrorCtor
{
V4_OBJECT2(EvalErrorCtor, ErrorCtor)
- static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
};
struct RangeErrorCtor: ErrorCtor
{
V4_OBJECT2(RangeErrorCtor, ErrorCtor)
- static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
};
struct ReferenceErrorCtor: ErrorCtor
{
V4_OBJECT2(ReferenceErrorCtor, ErrorCtor)
- static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
};
struct SyntaxErrorCtor: ErrorCtor
{
V4_OBJECT2(SyntaxErrorCtor, ErrorCtor)
- static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
};
struct TypeErrorCtor: ErrorCtor
{
V4_OBJECT2(TypeErrorCtor, ErrorCtor)
- static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
};
struct URIErrorCtor: ErrorCtor
{
V4_OBJECT2(URIErrorCtor, ErrorCtor)
- static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index efe6c7c226..a18a2d4919 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -34,10 +34,10 @@
#include "qv4function_p.h"
#include "qv4managed_p.h"
#include "qv4string_p.h"
-#include "qv4value_inl_p.h"
+#include "qv4value_p.h"
#include "qv4engine_p.h"
#include "qv4lookup_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 0a12d013ac..27b7448102 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -37,7 +37,7 @@
#include "qv4objectproto_p.h"
#include "qv4stringobject_p.h"
#include "qv4function_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4arrayobject_p.h"
#include "qv4scopedvalue_p.h"
@@ -63,7 +63,7 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(FunctionObject);
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, QV4::String *name, bool createProto)
- : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject())
+ : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype())
, scope(scope->d())
, function(Q_NULLPTR)
{
@@ -73,7 +73,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, QV4::String *
}
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, Function *function, bool createProto)
- : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject())
+ : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype())
, scope(scope->d())
, function(Q_NULLPTR)
{
@@ -84,7 +84,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, Function *fun
}
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString &name, bool createProto)
- : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject())
+ : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype())
, scope(scope->d())
, function(Q_NULLPTR)
{
@@ -95,7 +95,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const QString
}
Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, bool createProto)
- : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype.asObject())
+ : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype())
, scope(scope)
, function(Q_NULLPTR)
{
@@ -106,7 +106,7 @@ Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const QString &nam
}
Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const ReturnedValue name)
- : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype.asObject())
+ : Heap::Object(scope->d()->engine->functionClass, scope->d()->engine->functionPrototype())
, scope(scope->d())
, function(Q_NULLPTR)
{
@@ -117,7 +117,7 @@ Heap::FunctionObject::FunctionObject(QV4::ExecutionContext *scope, const Returne
}
Heap::FunctionObject::FunctionObject(ExecutionContext *scope, const ReturnedValue name)
- : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype.asObject())
+ : Heap::Object(scope->engine->functionClass, scope->engine->functionPrototype())
, scope(scope)
, function(Q_NULLPTR)
{
@@ -152,7 +152,7 @@ void FunctionObject::init(String *n, bool createProto)
ensureMemberIndex(s.engine, Heap::FunctionObject::Index_Prototype);
if (createProto) {
- ScopedObject proto(s, scope()->engine->newObject(s.engine->protoClass, s.engine->objectPrototype.asObject()));
+ ScopedObject proto(s, scope()->engine->newObject(s.engine->protoClass, s.engine->objectPrototype()));
proto->ensureMemberIndex(s.engine, Heap::FunctionObject::Index_ProtoConstructor);
proto->memberData()->data[Heap::FunctionObject::Index_ProtoConstructor] = this->asReturnedValue();
memberData()->data[Heap::FunctionObject::Index_Prototype] = proto.asReturnedValue();
@@ -164,7 +164,7 @@ void FunctionObject::init(String *n, bool createProto)
defineReadonlyProperty(s.engine->id_name, v);
}
-ReturnedValue FunctionObject::name()
+ReturnedValue FunctionObject::name() const
{
return get(scope()->engine->id_name);
}
@@ -177,13 +177,12 @@ ReturnedValue FunctionObject::newInstance()
return construct(callData);
}
-ReturnedValue FunctionObject::construct(Managed *that, CallData *)
+ReturnedValue FunctionObject::construct(const Managed *that, CallData *)
{
- static_cast<FunctionObject *>(that)->internalClass()->engine->throwTypeError();
- return Encode::undefined();
+ return static_cast<const FunctionObject *>(that)->engine()->throwTypeError();
}
-ReturnedValue FunctionObject::call(Managed *, CallData *)
+ReturnedValue FunctionObject::call(const Managed *, CallData *)
{
return Encode::undefined();
}
@@ -237,10 +236,10 @@ Heap::FunctionCtor::FunctionCtor(QV4::ExecutionContext *scope)
}
// 15.3.2
-ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
+ReturnedValue FunctionCtor::construct(const Managed *that, CallData *callData)
{
- Scope scope(static_cast<Object *>(that)->engine());
- Scoped<FunctionCtor> f(scope, static_cast<FunctionCtor *>(that));
+ Scope scope(static_cast<const Object *>(that)->engine());
+ Scoped<FunctionCtor> f(scope, static_cast<const FunctionCtor *>(that));
ScopedContext ctx(scope, scope.engine->currentContext());
QString arguments;
QString body;
@@ -287,7 +286,7 @@ ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
}
// 15.3.1: This is equivalent to new Function(...)
-ReturnedValue FunctionCtor::call(Managed *that, CallData *callData)
+ReturnedValue FunctionCtor::call(const Managed *that, CallData *callData)
{
return construct(that, callData);
}
@@ -318,7 +317,7 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor)
ReturnedValue FunctionPrototype::method_toString(CallContext *ctx)
{
- FunctionObject *fun = ctx->thisObject().asFunctionObject();
+ FunctionObject *fun = ctx->thisObject().as<FunctionObject>();
if (!fun)
return ctx->engine()->throwTypeError();
@@ -328,7 +327,7 @@ ReturnedValue FunctionPrototype::method_toString(CallContext *ctx)
ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
{
Scope scope(ctx);
- ScopedFunctionObject o(scope, ctx->thisObject().asFunctionObject());
+ ScopedFunctionObject o(scope, ctx->thisObject().as<FunctionObject>());
if (!o)
return ctx->engine()->throwTypeError();
@@ -370,7 +369,7 @@ ReturnedValue FunctionPrototype::method_call(CallContext *ctx)
{
Scope scope(ctx);
- ScopedFunctionObject o(scope, ctx->thisObject().asFunctionObject());
+ ScopedFunctionObject o(scope, ctx->thisObject().as<FunctionObject>());
if (!o)
return ctx->engine()->throwTypeError();
@@ -409,15 +408,15 @@ Heap::ScriptFunction::ScriptFunction(QV4::ExecutionContext *scope, Function *fun
{
}
-ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
+ReturnedValue ScriptFunction::construct(const Managed *that, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<Object *>(that)->engine();
+ ExecutionEngine *v4 = static_cast<const Object *>(that)->engine();
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
Scope scope(v4);
- Scoped<ScriptFunction> f(scope, static_cast<ScriptFunction *>(that));
+ Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that));
InternalClass *ic = scope.engine->emptyClass;
ScopedObject proto(scope, f->protoForConstructor());
@@ -441,15 +440,15 @@ ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
return obj.asReturnedValue();
}
-ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
+ReturnedValue ScriptFunction::call(const Managed *that, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<Object *>(that)->engine();
+ ExecutionEngine *v4 = static_cast<const Object *>(that)->engine();
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
Scope scope(v4);
- Scoped<ScriptFunction> f(scope, static_cast<ScriptFunction *>(that));
+ Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that));
ScopedContext context(scope, v4->currentContext());
Scoped<CallContext> ctx(scope, context->newCallContext(f, callData));
@@ -466,7 +465,7 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
DEFINE_OBJECT_VTABLE(SimpleScriptFunction);
Heap::SimpleScriptFunction::SimpleScriptFunction(QV4::ExecutionContext *scope, Function *function, bool createProto)
- : Heap::FunctionObject(function->compilationUnit->engine->simpleScriptFunctionClass, function->compilationUnit->engine->functionPrototype.asObject())
+ : Heap::FunctionObject(function->compilationUnit->engine->simpleScriptFunctionClass, function->compilationUnit->engine->functionPrototype())
{
this->scope = scope->d();
@@ -490,22 +489,22 @@ Heap::SimpleScriptFunction::SimpleScriptFunction(QV4::ExecutionContext *scope, F
if (scope->d()->strictMode) {
ScopedProperty pd(s);
- pd->value = s.engine->thrower;
- pd->set = s.engine->thrower;
+ pd->value = s.engine->thrower();
+ pd->set = s.engine->thrower();
f->insertMember(scope->d()->engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
f->insertMember(scope->d()->engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
}
-ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
+ReturnedValue SimpleScriptFunction::construct(const Managed *that, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<Object *>(that)->engine();
+ ExecutionEngine *v4 = static_cast<const Object *>(that)->engine();
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
Scope scope(v4);
- Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that));
+ Scoped<SimpleScriptFunction> f(scope, static_cast<const SimpleScriptFunction *>(that));
InternalClass *ic = scope.engine->emptyClass;
ScopedObject proto(scope, f->protoForConstructor());
@@ -536,15 +535,15 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData)
return result.asReturnedValue();
}
-ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
+ReturnedValue SimpleScriptFunction::call(const Managed *that, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<SimpleScriptFunction *>(that)->internalClass()->engine;
+ ExecutionEngine *v4 = static_cast<const SimpleScriptFunction *>(that)->internalClass()->engine;
if (v4->hasException)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
Scope scope(v4);
- Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that));
+ Scoped<SimpleScriptFunction> f(scope, static_cast<const SimpleScriptFunction *>(that));
ExecutionContextSaver ctxSaver(scope, v4->currentContext());
@@ -575,7 +574,7 @@ Heap::Object *SimpleScriptFunction::protoForConstructor()
ScopedObject p(scope, protoProperty());
if (p)
return p->d();
- return scope.engine->objectPrototype.asObject()->d();
+ return scope.engine->objectPrototype()->d();
}
@@ -588,14 +587,14 @@ Heap::BuiltinFunction::BuiltinFunction(QV4::ExecutionContext *scope, QV4::String
{
}
-ReturnedValue BuiltinFunction::construct(Managed *f, CallData *)
+ReturnedValue BuiltinFunction::construct(const Managed *f, CallData *)
{
- return static_cast<BuiltinFunction *>(f)->internalClass()->engine->throwTypeError();
+ return static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError();
}
-ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData)
+ReturnedValue BuiltinFunction::call(const Managed *that, CallData *callData)
{
- BuiltinFunction *f = static_cast<BuiltinFunction *>(that);
+ const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that);
ExecutionEngine *v4 = f->internalClass()->engine;
if (v4->hasException)
return Encode::undefined();
@@ -614,9 +613,9 @@ ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData)
return f->d()->code(sctx);
}
-ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData)
+ReturnedValue IndexedBuiltinFunction::call(const Managed *that, CallData *callData)
{
- IndexedBuiltinFunction *f = static_cast<IndexedBuiltinFunction *>(that);
+ const IndexedBuiltinFunction *f = static_cast<const IndexedBuiltinFunction *>(that);
ExecutionEngine *v4 = f->internalClass()->engine;
if (v4->hasException)
return Encode::undefined();
@@ -659,15 +658,15 @@ Heap::BoundFunction::BoundFunction(QV4::ExecutionContext *scope, QV4::FunctionOb
f->defineReadonlyProperty(s.engine->id_length, Primitive::fromInt32(len));
ScopedProperty pd(s);
- pd->value = s.engine->thrower;
- pd->set = s.engine->thrower;
+ pd->value = s.engine->thrower();
+ pd->set = s.engine->thrower();
f->insertMember(s.engine->id_arguments, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
f->insertMember(s.engine->id_caller, pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
-ReturnedValue BoundFunction::call(Managed *that, CallData *dd)
+ReturnedValue BoundFunction::call(const Managed *that, CallData *dd)
{
- BoundFunction *f = static_cast<BoundFunction *>(that);
+ const BoundFunction *f = static_cast<const BoundFunction *>(that);
Scope scope(f->engine());
if (scope.hasException())
return Encode::undefined();
@@ -685,9 +684,9 @@ ReturnedValue BoundFunction::call(Managed *that, CallData *dd)
return t->call(callData);
}
-ReturnedValue BoundFunction::construct(Managed *that, CallData *dd)
+ReturnedValue BoundFunction::construct(const Managed *that, CallData *dd)
{
- BoundFunction *f = static_cast<BoundFunction *>(that);
+ const BoundFunction *f = static_cast<const BoundFunction *>(that);
Scope scope(f->engine());
if (scope.hasException())
return Encode::undefined();
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 252ff40a1a..67a929554b 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -36,7 +36,7 @@
#include "qv4object_p.h"
#include "qv4function_p.h"
#include "qv4context_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
QT_BEGIN_NAMESPACE
@@ -65,7 +65,7 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; }
bool needsActivation() const { return function ? function->needsActivation() : false; }
- ExecutionContext *scope;
+ Pointer<ExecutionContext> scope;
Function *function;
};
@@ -102,9 +102,9 @@ struct ScriptFunction : SimpleScriptFunction {
struct BoundFunction : FunctionObject {
BoundFunction(QV4::ExecutionContext *scope, QV4::FunctionObject *target, const Value &boundThis, QV4::MemberData *boundArgs);
- FunctionObject *target;
+ Pointer<FunctionObject> target;
Value boundThis;
- MemberData *boundArgs;
+ Pointer<MemberData> boundArgs;
};
}
@@ -117,10 +117,10 @@ struct Q_QML_EXPORT FunctionObject: Object {
Q_MANAGED_TYPE(FunctionObject)
V4_NEEDS_DESTROY
- Heap::ExecutionContext *scope() { return d()->scope; }
- Function *function() { return d()->function; }
+ Heap::ExecutionContext *scope() const { return d()->scope; }
+ Function *function() const { return d()->function; }
- ReturnedValue name();
+ ReturnedValue name() const;
unsigned int formalParameterCount() { return d()->formalParameterCount(); }
unsigned int varCount() { return d()->varCount(); }
@@ -130,12 +130,8 @@ struct Q_QML_EXPORT FunctionObject: Object {
using Object::construct;
using Object::call;
- static ReturnedValue construct(Managed *that, CallData *);
- static ReturnedValue call(Managed *that, CallData *d);
-
- static FunctionObject *cast(const Value &v) {
- return v.asFunctionObject();
- }
+ static ReturnedValue construct(const Managed *that, CallData *);
+ static ReturnedValue call(const Managed *that, CallData *d);
static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true);
@@ -152,16 +148,17 @@ struct Q_QML_EXPORT FunctionObject: Object {
};
template<>
-inline FunctionObject *value_cast(const Value &v) {
- return v.asFunctionObject();
+inline const FunctionObject *Value::as() const {
+ return isManaged() && m && m->vtable->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : 0;
}
+
struct FunctionCtor: FunctionObject
{
V4_OBJECT2(FunctionCtor, FunctionObject)
- static ReturnedValue construct(Managed *that, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *that, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
struct FunctionPrototype: FunctionObject
@@ -184,20 +181,20 @@ struct Q_QML_EXPORT BuiltinFunction: FunctionObject {
return scope->engine()->memoryManager->alloc<BuiltinFunction>(scope, name, code);
}
- static ReturnedValue construct(Managed *, CallData *);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *, CallData *);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
struct IndexedBuiltinFunction: FunctionObject
{
V4_OBJECT2(IndexedBuiltinFunction, FunctionObject)
- static ReturnedValue construct(Managed *m, CallData *)
+ static ReturnedValue construct(const Managed *m, CallData *)
{
- return static_cast<IndexedBuiltinFunction *>(m)->engine()->throwTypeError();
+ return static_cast<const IndexedBuiltinFunction *>(m)->engine()->throwTypeError();
}
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
Heap::IndexedBuiltinFunction::IndexedBuiltinFunction(QV4::ExecutionContext *scope, uint index,
@@ -212,8 +209,8 @@ Heap::IndexedBuiltinFunction::IndexedBuiltinFunction(QV4::ExecutionContext *scop
struct SimpleScriptFunction: FunctionObject {
V4_OBJECT2(SimpleScriptFunction, FunctionObject)
- static ReturnedValue construct(Managed *, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
Heap::Object *protoForConstructor();
};
@@ -221,8 +218,8 @@ struct SimpleScriptFunction: FunctionObject {
struct ScriptFunction: SimpleScriptFunction {
V4_OBJECT2(ScriptFunction, FunctionObject)
- static ReturnedValue construct(Managed *, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
@@ -234,12 +231,12 @@ struct BoundFunction: FunctionObject {
return scope->engine()->memoryManager->alloc<BoundFunction>(scope, target, boundThis, boundArgs);
}
- Heap::FunctionObject *target() { return d()->target; }
+ Heap::FunctionObject *target() const { return d()->target; }
Value boundThis() const { return d()->boundThis; }
Heap::MemberData *boundArgs() const { return d()->boundArgs; }
- static ReturnedValue construct(Managed *, CallData *d);
- static ReturnedValue call(Managed *that, CallData *dd);
+ static ReturnedValue construct(const Managed *, CallData *d);
+ static ReturnedValue call(const Managed *that, CallData *dd);
static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 4b08194b60..9f37ede2c1 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -88,6 +88,8 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
#define V4_ENABLE_JIT
#endif
+#elif defined(Q_PROCESSOR_MIPS_32) && defined(Q_OS_LINUX)
+#define V4_ENABLE_JIT
#endif
// Black list some platforms
@@ -168,7 +170,7 @@ struct Property;
struct Value;
struct Lookup;
struct ArrayData;
-struct ManagedVTable;
+struct VTable;
struct BooleanObject;
struct NumberObject;
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 8e33cec57f..9b85067d26 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -32,13 +32,14 @@
****************************************************************************/
#include "qv4globalobject_p.h"
-#include "qv4mm_p.h"
-#include "qv4value_inl_p.h"
+#include <private/qv4mm_p.h>
+#include "qv4value_p.h"
#include "qv4context_p.h"
#include "qv4function_p.h"
#include "qv4debugging_p.h"
#include "qv4script_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4string_p.h"
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
@@ -346,7 +347,7 @@ Heap::EvalFunction::EvalFunction(QV4::ExecutionContext *scope)
f->defineReadonlyProperty(s.engine->id_length, Primitive::fromInt32(1));
}
-ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
+ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall) const
{
if (callData->argc < 1)
return Encode::undefined();
@@ -399,10 +400,10 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
}
-ReturnedValue EvalFunction::call(Managed *that, CallData *callData)
+ReturnedValue EvalFunction::call(const Managed *that, CallData *callData)
{
// indirect call
- return static_cast<EvalFunction *>(that)->evalCall(callData, false);
+ return static_cast<const EvalFunction *>(that)->evalCall(callData, false);
}
diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h
index 74de233b47..ba1d5d2e0b 100644
--- a/src/qml/jsruntime/qv4globalobject_p.h
+++ b/src/qml/jsruntime/qv4globalobject_p.h
@@ -52,10 +52,10 @@ struct Q_QML_EXPORT EvalFunction : FunctionObject
{
V4_OBJECT2(EvalFunction, FunctionObject)
- ReturnedValue evalCall(CallData *callData, bool directCall);
+ ReturnedValue evalCall(CallData *callData, bool directCall) const;
using Object::construct;
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
struct GlobalFunctions
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index e4bd460966..9bbcc0e21b 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -54,7 +54,7 @@ QV4Include::QV4Include(const QUrl &url, QV4::ExecutionEngine *engine, QQmlContex
: v4(engine), m_network(0), m_reply(0), m_url(url), m_redirectCount(0), m_context(context)
{
m_qmlglobal.set(engine, qmlglobal);
- if (callback.asFunctionObject())
+ if (callback.as<QV4::FunctionObject>())
m_callbackFunction.set(engine, callback);
m_resultObject.set(v4, resultValue(v4));
@@ -94,14 +94,14 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
{
if (!callback.isObject())
return;
- QV4::ExecutionEngine *v4 = callback.asObject()->engine();
+ QV4::ExecutionEngine *v4 = callback.as<QV4::Object>()->engine();
QV4::Scope scope(v4);
QV4::ScopedFunctionObject f(scope, callback);
if (!f)
return;
QV4::ScopedCallData callData(scope, 1);
- callData->thisObject = v4->globalObject()->asReturnedValue();
+ callData->thisObject = v4->globalObject->asReturnedValue();
callData->args[0] = status;
f->call(callData);
if (scope.hasException())
@@ -184,7 +184,7 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
QUrl url(scope.engine->resolvedUrl(ctx->args()[0].toQStringNoThrow()));
QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue());
- if (ctx->argc() >= 2 && ctx->args()[1].asFunctionObject())
+ if (ctx->argc() >= 2 && ctx->args()[1].as<QV4::FunctionObject>())
callbackFunction = ctx->args()[1];
QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
@@ -224,7 +224,7 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
QV4::ScopedValue ex(scope, scope.engine->catchException());
result = resultValue(scope.engine, Exception);
QV4::ScopedString exception(scope, scope.engine->newString(QStringLiteral("exception")));
- result->asObject()->put(exception, ex);
+ result->as<QV4::Object>()->put(exception, ex);
} else {
result = resultValue(scope.engine, Ok);
}
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index 5dc94e8555..5ef4442b03 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -50,7 +50,7 @@
#include <private/qqmlcontext_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4context_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index 3289058cb7..80590fe72e 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -46,7 +46,7 @@ struct String;
struct ExecutionEngine;
struct Object;
struct Identifier;
-struct ManagedVTable;
+struct VTable;
struct PropertyHashData;
struct PropertyHash
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index e7905974df..95d08d7a10 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -38,8 +38,8 @@
#include <qv4objectiterator_p.h>
#include <qv4scopedvalue_p.h>
#include <qv4runtime_p.h>
+#include "qv4string_p.h"
-#include <qjsondocument.h>
#include <qstack.h>
#include <qstringlist.h>
@@ -62,33 +62,6 @@ static int indent = 0;
DEFINE_OBJECT_VTABLE(JsonObject);
-class JsonParser
-{
-public:
- JsonParser(ExecutionEngine *engine, const QChar *json, int length);
-
- ReturnedValue parse(QJsonParseError *error);
-
-private:
- inline bool eatSpace();
- inline QChar nextToken();
-
- ReturnedValue parseObject();
- ReturnedValue parseArray();
- bool parseMember(Object *o);
- bool parseString(QString *string);
- bool parseValue(Value *val);
- bool parseNumber(Value *val);
-
- ExecutionEngine *engine;
- const QChar *head;
- const QChar *json;
- const QChar *end;
-
- int nestingLevel;
- QJsonParseError::ParseError lastError;
-};
-
static const int nestingLimit = 1024;
@@ -728,11 +701,11 @@ QString Stringify::Str(const QString &key, const Value &v)
o = value->asReturnedValue();
if (o) {
- if (NumberObject *n = o->asNumberObject())
+ if (NumberObject *n = o->as<NumberObject>())
value = Encode(n->value());
- else if (StringObject *so = o->asStringObject())
+ else if (StringObject *so = o->as<StringObject>())
value = so->d()->value;
- else if (BooleanObject *b =o->asBooleanObject())
+ else if (BooleanObject *b = o->as<BooleanObject>())
value = Encode(b->value());
}
@@ -750,8 +723,8 @@ QString Stringify::Str(const QString &key, const Value &v)
o = value->asReturnedValue();
if (o) {
- if (!o->asFunctionObject()) {
- if (o->asArrayObject()) {
+ if (!o->as<FunctionObject>()) {
+ if (o->as<ArrayObject>()) {
return JA(static_cast<ArrayObject *>(o.getPointer()));
} else {
return JO(o);
@@ -879,7 +852,7 @@ QString Stringify::JA(ArrayObject *a)
Heap::JsonObject::JsonObject(ExecutionEngine *e)
- : Heap::Object(e->emptyClass, e->objectPrototype.asObject())
+ : Heap::Object(e->emptyClass, e->objectPrototype())
{
Scope scope(e);
ScopedObject o(scope, this);
@@ -915,13 +888,13 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
ScopedObject o(scope, ctx->argument(1));
if (o) {
- stringify.replacerFunction = o->asFunctionObject();
+ stringify.replacerFunction = o->as<FunctionObject>();
if (o->isArrayObject()) {
uint arrayLen = o->getLength();
ScopedValue v(scope);
for (uint i = 0; i < arrayLen; ++i) {
v = o->getIndexed(i);
- if (v->asNumberObject() || v->asStringObject() || v->isNumber())
+ if (v->as<NumberObject>() || v->as<StringObject>() || v->isNumber())
v = RuntimeHelpers::toString(scope.engine, v);
if (v->isString()) {
String *s = v->stringValue();
@@ -933,9 +906,9 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
}
ScopedValue s(scope, ctx->argument(2));
- if (NumberObject *n = s->asNumberObject())
+ if (NumberObject *n = s->as<NumberObject>())
s = Encode(n->value());
- else if (StringObject *so = s->asStringObject())
+ else if (StringObject *so = s->as<StringObject>())
s = so->d()->value;
if (s->isNumber()) {
@@ -986,7 +959,7 @@ QJsonValue JsonObject::toJsonValue(const Value &value, V4ObjectSet &visitedObjec
return QJsonValue(value.toQString());
Q_ASSERT(value.isObject());
- Scope scope(value.asObject()->engine());
+ Scope scope(value.as<Object>()->engine());
ScopedArrayObject a(scope, value);
if (a)
return toJsonArray(a, visitedObjects);
@@ -1012,7 +985,7 @@ QV4::ReturnedValue JsonObject::fromJsonObject(ExecutionEngine *engine, const QJs
QJsonObject JsonObject::toJsonObject(Object *o, V4ObjectSet &visitedObjects)
{
QJsonObject result;
- if (!o || o->asFunctionObject())
+ if (!o || o->as<FunctionObject>())
return result;
Scope scope(o->engine());
@@ -1035,7 +1008,7 @@ QJsonObject JsonObject::toJsonObject(Object *o, V4ObjectSet &visitedObjects)
break;
QString key = name->toQStringNoThrow();
- if (!val->asFunctionObject())
+ if (!val->as<FunctionObject>())
result.insert(key, toJsonValue(val, visitedObjects));
}
@@ -1078,7 +1051,7 @@ QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects)
quint32 length = a->getLength();
for (quint32 i = 0; i < length; ++i) {
v = a->getIndexed(i);
- if (v->asFunctionObject())
+ if (v->as<FunctionObject>())
v = Encode::null();
result.append(toJsonValue(v, visitedObjects));
}
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index 81a783ee92..b8b9cf3093 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -37,6 +37,7 @@
#include <qjsonarray.h>
#include <qjsonobject.h>
#include <qjsonvalue.h>
+#include <qjsondocument.h>
QT_BEGIN_NAMESPACE
@@ -79,6 +80,33 @@ private:
};
+class JsonParser
+{
+public:
+ JsonParser(ExecutionEngine *engine, const QChar *json, int length);
+
+ ReturnedValue parse(QJsonParseError *error);
+
+private:
+ inline bool eatSpace();
+ inline QChar nextToken();
+
+ ReturnedValue parseObject();
+ ReturnedValue parseArray();
+ bool parseMember(Object *o);
+ bool parseString(QString *string);
+ bool parseValue(Value *val);
+ bool parseNumber(Value *val);
+
+ ExecutionEngine *engine;
+ const QChar *head;
+ const QChar *json;
+ const QChar *end;
+
+ int nestingLevel;
+ QJsonParseError::ParseError lastError;
+};
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 82b20337cb..3cc77d2e3d 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -33,6 +33,7 @@
#include "qv4lookup_p.h"
#include "qv4functionobject_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4string_p.h"
QT_BEGIN_NAMESPACE
@@ -72,7 +73,7 @@ ReturnedValue Lookup::lookup(const Value &thisObject, Object *o, PropertyAttribu
return Primitive::emptyValue().asReturnedValue();
}
-ReturnedValue Lookup::lookup(Object *thisObject, PropertyAttributes *attrs)
+ReturnedValue Lookup::lookup(const Object *thisObject, PropertyAttributes *attrs)
{
Heap::Object *obj = thisObject->d();
ExecutionEngine *engine = thisObject->engine();
@@ -123,7 +124,7 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const Value &object, cons
ScopedObject o(scope, object);
if (!o) {
if (idx < UINT_MAX) {
- if (String *str = object.asString()) {
+ if (const String *str = object.as<String>()) {
if (idx >= (uint)str->toQString().length()) {
return Encode::undefined();
}
@@ -168,7 +169,7 @@ ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const Value &object, con
Object *o = object.objectValue();
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
- Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (idx < s->len)
if (!s->data(idx).isEmpty())
return s->data(idx).asReturnedValue();
@@ -200,7 +201,7 @@ void Lookup::indexedSetterFallback(Lookup *l, const Value &object, const Value &
uint idx = index.asArrayIndex();
if (idx < UINT_MAX) {
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
- Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (idx < s->len) {
s->data(idx) = value;
return;
@@ -224,7 +225,7 @@ void Lookup::indexedSetterObjectInt(Lookup *l, const Value &object, const Value
Object *o = object.objectValue();
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
- Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (idx < s->len) {
s->data(idx) = v;
return;
@@ -235,7 +236,7 @@ void Lookup::indexedSetterObjectInt(Lookup *l, const Value &object, const Value
ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object)
{
- if (Object *o = object.asObject())
+ if (const Object *o = object.as<Object>())
return o->getLookup(l);
Object *proto;
@@ -244,11 +245,11 @@ ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Va
case Value::Null_Type:
return engine->throwTypeError();
case Value::Boolean_Type:
- proto = engine->booleanPrototype.asObject();
+ proto = engine->booleanPrototype();
break;
case Value::Managed_Type: {
Q_ASSERT(object.isString());
- proto = engine->stringPrototype.asObject();
+ proto = engine->stringPrototype();
Scope scope(engine);
ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[l->nameIndex]);
if (name->equals(engine->id_length)) {
@@ -260,7 +261,7 @@ ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Va
}
case Value::Integer_Type:
default: // Number
- proto = engine->numberPrototype.asObject();
+ proto = engine->numberPrototype();
}
PropertyAttributes attrs;
@@ -291,7 +292,7 @@ ReturnedValue Lookup::getterTwoClasses(Lookup *l, ExecutionEngine *engine, const
Lookup l1 = *l;
if (l1.getter == Lookup::getter0 || l1.getter == Lookup::getter1) {
- if (Object *o = object.asObject()) {
+ if (const Object *o = object.as<Object>()) {
ReturnedValue v = o->getLookup(l);
Lookup l2 = *l;
@@ -560,7 +561,7 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engin
ReturnedValue Lookup::stringLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object)
{
- if (String *s = object.asString())
+ if (const String *s = object.as<String>())
return Encode(s->d()->length());
l->getter = getterGeneric;
@@ -569,7 +570,7 @@ ReturnedValue Lookup::stringLengthGetter(Lookup *l, ExecutionEngine *engine, con
ReturnedValue Lookup::arrayLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object)
{
- if (ArrayObject *a = object.asArrayObject())
+ if (const ArrayObject *a = object.as<ArrayObject>())
return a->memberData()->data[Heap::ArrayObject::LengthPropertyIndex].asReturnedValue();
l->getter = getterGeneric;
@@ -579,7 +580,7 @@ ReturnedValue Lookup::arrayLengthGetter(Lookup *l, ExecutionEngine *engine, cons
ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionEngine *engine)
{
- Object *o = engine->globalObject();
+ Object *o = engine->globalObject;
PropertyAttributes attrs;
ReturnedValue v = l->lookup(o, &attrs);
if (v != Primitive::emptyValue().asReturnedValue()) {
@@ -608,7 +609,7 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionEngine *engine)
{
- Object *o = engine->globalObject();
+ Object *o = engine->globalObject;
if (l->classList[0] == o->internalClass())
return o->memberData()->data[l->index].asReturnedValue();
@@ -618,7 +619,7 @@ ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionEngine *engine)
{
- Object *o = engine->globalObject();
+ Object *o = engine->globalObject;
if (l->classList[0] == o->internalClass() &&
l->classList[1] == o->prototype()->internalClass)
return o->prototype()->memberData->data[l->index].asReturnedValue();
@@ -629,7 +630,7 @@ ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionEngine *engine)
{
- Heap::Object *o = engine->globalObject()->d();
+ Heap::Object *o = engine->globalObject->d();
if (l->classList[0] == o->internalClass) {
o = o->prototype;
if (l->classList[1] == o->internalClass) {
@@ -645,7 +646,7 @@ ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionEngine *engine)
{
- Object *o = engine->globalObject();
+ Object *o = engine->globalObject;
if (l->classList[0] == o->internalClass()) {
Scope scope(o->engine());
ScopedFunctionObject getter(scope, o->propertyAt(l->index)->getter());
@@ -662,7 +663,7 @@ ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionEngine *engine)
{
- Object *o = engine->globalObject();
+ Object *o = engine->globalObject;
if (l->classList[0] == o->internalClass() &&
l->classList[1] == o->prototype()->internalClass) {
Scope scope(o->engine());
@@ -680,7 +681,7 @@ ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine)
{
- Heap::Object *o = engine->globalObject()->d();
+ Heap::Object *o = engine->globalObject->d();
if (l->classList[0] == o->internalClass) {
o = o->prototype;
if (l->classList[1] == o->internalClass) {
@@ -701,7 +702,7 @@ ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine)
return globalGetterGeneric(l, engine);
}
-void Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value)
+void Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
Scope scope(engine);
ScopedObject o(scope, object);
@@ -716,11 +717,11 @@ void Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, const Value &obje
o->setLookup(l, value);
}
-void Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value)
+void Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
Lookup l1 = *l;
- if (Object *o = object.asObject()) {
+ if (Object *o = object.as<Object>()) {
o->setLookup(l, value);
if (l->setter == Lookup::setter0) {
@@ -735,7 +736,7 @@ void Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &o
setterFallback(l, engine, object, value);
}
-void Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value)
+void Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
QV4::Scope scope(engine);
QV4::ScopedObject o(scope, object.toObject(scope.engine));
@@ -745,9 +746,9 @@ void Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, const Value &obj
}
}
-void Lookup::setter0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value)
+void Lookup::setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.asManaged());
+ Object *o = object.as<Object>();
if (o && o->internalClass() == l->classList[0]) {
o->memberData()->data[l->index] = value;
return;
@@ -756,9 +757,9 @@ void Lookup::setter0(Lookup *l, ExecutionEngine *engine, const Value &object, co
setterTwoClasses(l, engine, object, value);
}
-void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value)
+void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.asManaged());
+ Object *o = object.as<Object>();
if (o && o->internalClass() == l->classList[0]) {
if (!o->prototype()) {
if (!o->memberData() || l->index >= o->memberData()->size)
@@ -773,9 +774,9 @@ void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, const Value &obje
setterFallback(l, engine, object, value);
}
-void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value)
+void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.asManaged());
+ Object *o = object.as<Object>();
if (o && o->internalClass() == l->classList[0]) {
Heap::Object *p = o->prototype();
if (p && p->internalClass == l->classList[1]) {
@@ -791,9 +792,9 @@ void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, const Value &obje
setterFallback(l, engine, object, value);
}
-void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value)
+void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.asManaged());
+ Object *o = object.as<Object>();
if (o && o->internalClass() == l->classList[0]) {
Heap::Object *p = o->prototype();
if (p && p->internalClass == l->classList[1]) {
@@ -812,9 +813,9 @@ void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, const Value &obje
setterFallback(l, engine, object, value);
}
-void Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value)
+void Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.asManaged());
+ Object *o = object.as<Object>();
if (o) {
if (o->internalClass() == l->classList[0]) {
o->memberData()->data[l->index] = value;
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index 88397dc36c..232e909c48 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -51,7 +51,7 @@ struct Lookup {
void (*indexedSetter)(Lookup *l, const Value &object, const Value &index, const Value &v);
ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const Value &object);
ReturnedValue (*globalGetter)(Lookup *l, ExecutionEngine *engine);
- void (*setter)(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &v);
+ void (*setter)(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v);
};
union {
ExecutionEngine *engine;
@@ -107,17 +107,17 @@ struct Lookup {
static ReturnedValue globalGetterAccessor1(Lookup *l, ExecutionEngine *engine);
static ReturnedValue globalGetterAccessor2(Lookup *l, ExecutionEngine *engine);
- static void setterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value);
- static void setterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value);
- static void setterFallback(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value);
- static void setter0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value);
- static void setterInsert0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value);
- static void setterInsert1(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value);
- static void setterInsert2(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value);
- static void setter0setter0(Lookup *l, ExecutionEngine *engine, const Value &object, const Value &value);
+ static void setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static void setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static void setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static void setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static void setterInsert0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static void setterInsert1(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static void setterInsert2(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static void setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
ReturnedValue lookup(const Value &thisObject, Object *obj, PropertyAttributes *attrs);
- ReturnedValue lookup(Object *obj, PropertyAttributes *attrs);
+ ReturnedValue lookup(const Object *obj, PropertyAttributes *attrs);
};
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index c4b9fc597e..546190086e 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -32,13 +32,13 @@
****************************************************************************/
#include "qv4managed_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4errorobject_p.h"
using namespace QV4;
-const ManagedVTable Managed::static_vtbl =
+const VTable Managed::static_vtbl =
{
0,
Managed::IsExecutionContext,
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 0fe5c7ee49..7cce80d087 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -35,7 +35,7 @@
#include "qv4global_p.h"
#include "qv4value_p.h"
-#include "qv4internalclass_p.h"
+#include <private/qv4heap_p.h>
QT_BEGIN_NAMESPACE
@@ -65,8 +65,8 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
Q_MANAGED_CHECK \
typedef QV4::Heap::DataClass Data; \
typedef superClass SuperClass; \
- static const QV4::ManagedVTable static_vtbl; \
- static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl; } \
+ static const QV4::VTable static_vtbl; \
+ static inline const QV4::VTable *staticVTable() { return &static_vtbl; } \
V4_MANAGED_SIZE_TEST \
QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m); }
@@ -86,23 +86,6 @@ struct GCDeletable
bool lastCall;
};
-struct ManagedVTable
-{
- const ManagedVTable * const parent;
- uint isExecutionContext : 1;
- uint isString : 1;
- uint isObject : 1;
- uint isFunctionObject : 1;
- uint isErrorObject : 1;
- uint isArrayData : 1;
- uint unused : 18;
- uint type : 8;
- const char *className;
- void (*destroy)(Heap::Base *);
- void (*markObjects)(Heap::Base *, ExecutionEngine *e);
- bool (*isEqualTo)(Managed *m, Managed *other);
-};
-
#define DEFINE_MANAGED_VTABLE_INT(classname, parentVTable) \
{ \
parentVTable, \
@@ -121,7 +104,7 @@ struct ManagedVTable
}
#define DEFINE_MANAGED_VTABLE(classname) \
-const QV4::ManagedVTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0)
+const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0)
struct Q_QML_PRIVATE_EXPORT Managed : Value
{
@@ -141,8 +124,6 @@ private:
public:
- inline void mark(QV4::ExecutionEngine *engine);
-
enum Type {
Type_Invalid,
Type_String,
@@ -167,46 +148,6 @@ public:
};
Q_MANAGED_TYPE(Invalid)
- template <typename T>
- T *as() {
- Q_ASSERT(d()->vtable);
-#if !defined(QT_NO_QOBJECT_CHECK)
- static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(this));
-#endif
- const ManagedVTable *vt = d()->vtable;
- while (vt) {
- if (vt == T::staticVTable())
- return static_cast<T *>(this);
- vt = vt->parent;
- }
- return 0;
- }
- template <typename T>
- const T *as() const {
- Q_ASSERT(d()->vtable);
-#if !defined(QT_NO_QOBJECT_CHECK)
- static_cast<T *>(this)->qt_check_for_QMANAGED_macro(static_cast<T *>(const_cast<Managed *>(this)));
-#endif
- const ManagedVTable *vt = d()->vtable;
- while (vt) {
- if (vt == T::staticVTable())
- return static_cast<T *>(this);
- vt = vt->parent;
- }
- return 0;
- }
-
- String *asString() { return d()->vtable->isString ? reinterpret_cast<String *>(this) : 0; }
- Object *asObject() { return d()->vtable->isObject ? reinterpret_cast<Object *>(this) : 0; }
- ArrayObject *asArrayObject() { return d()->vtable->type == Type_ArrayObject ? reinterpret_cast<ArrayObject *>(this) : 0; }
- FunctionObject *asFunctionObject() { return d()->vtable->isFunctionObject ? reinterpret_cast<FunctionObject *>(this) : 0; }
- BooleanObject *asBooleanObject() { return d()->vtable->type == Type_BooleanObject ? reinterpret_cast<BooleanObject *>(this) : 0; }
- NumberObject *asNumberObject() { return d()->vtable->type == Type_NumberObject ? reinterpret_cast<NumberObject *>(this) : 0; }
- StringObject *asStringObject() { return d()->vtable->type == Type_StringObject ? reinterpret_cast<StringObject *>(this) : 0; }
- DateObject *asDateObject() { return d()->vtable->type == Type_DateObject ? reinterpret_cast<DateObject *>(this) : 0; }
- ErrorObject *asErrorObject() { return d()->vtable->isErrorObject ? reinterpret_cast<ErrorObject *>(this) : 0; }
- ArgumentsObject *asArgumentsObject() { return d()->vtable->type == Type_ArgumentsObject ? reinterpret_cast<ArgumentsObject *>(this) : 0; }
-
bool isListType() const { return d()->vtable->type == Type_QmlSequence; }
bool isArrayObject() const { return d()->vtable->type == Type_ArrayObject; }
@@ -231,37 +172,15 @@ private:
template<>
-inline Managed *value_cast(const Value &v) {
- return v.asManaged();
-}
-
-template<typename T>
-inline T *managed_cast(Managed *m)
-{
- return m ? m->as<T>() : 0;
+inline const Managed *Value::as() const {
+ if (isManaged())
+ return managed();
+ return 0;
}
template<>
-inline String *managed_cast(Managed *m)
-{
- return m ? m->asString() : 0;
-}
-template<>
-inline Object *managed_cast(Managed *m)
-{
- return m ? m->asObject() : 0;
-}
-template<>
-inline FunctionObject *managed_cast(Managed *m)
-{
- return m ? m->asFunctionObject() : 0;
-}
-
-inline Value Value::fromManaged(Managed *m)
-{
- if (!m)
- return QV4::Primitive::undefinedValue();
- return *m;
+inline const Object *Value::as() const {
+ return isManaged() && m && m->vtable->isObject ? objectValue() : 0;
}
}
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index 473e05bf88..c498160c36 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -48,7 +48,7 @@ DEFINE_OBJECT_VTABLE(MathObject);
static const double qt_PI = 2.0 * ::asin(1.0);
Heap::MathObject::MathObject(ExecutionEngine *e)
- : Heap::Object(e->emptyClass, e->objectPrototype.asObject())
+ : Heap::Object(e->emptyClass, e->objectPrototype())
{
Scope scope(e);
ScopedObject m(scope, this);
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp
index 03dfee3dcf..5ec5cb1f58 100644
--- a/src/qml/jsruntime/qv4memberdata.cpp
+++ b/src/qml/jsruntime/qv4memberdata.cpp
@@ -32,7 +32,8 @@
****************************************************************************/
#include "qv4memberdata_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
+#include "qv4value_p.h"
using namespace QV4;
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 89ff110b20..3b71971433 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -33,6 +33,7 @@
#include "qv4numberobject_p.h"
#include "qv4runtime_p.h"
+#include "qv4string_p.h"
#include <QtCore/qnumeric.h>
#include <QtCore/qmath.h>
@@ -50,14 +51,14 @@ Heap::NumberCtor::NumberCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue NumberCtor::construct(Managed *m, CallData *callData)
+ReturnedValue NumberCtor::construct(const Managed *m, CallData *callData)
{
Scope scope(m->cast<NumberCtor>()->engine());
double dbl = callData->argc ? callData->args[0].toNumber() : 0.;
return Encode(scope.engine->newNumberObject(dbl));
}
-ReturnedValue NumberCtor::call(Managed *, CallData *callData)
+ReturnedValue NumberCtor::call(const Managed *, CallData *callData)
{
double dbl = callData->argc ? callData->args[0].toNumber() : 0.;
return Encode(dbl);
@@ -97,7 +98,7 @@ inline ReturnedValue thisNumberValue(ExecutionContext *ctx)
{
if (ctx->thisObject().isNumber())
return ctx->thisObject().asReturnedValue();
- NumberObject *n = ctx->thisObject().asNumberObject();
+ NumberObject *n = ctx->thisObject().as<NumberObject>();
if (!n)
return ctx->engine()->throwTypeError();
return Encode(n->value());
@@ -107,7 +108,7 @@ inline double thisNumber(ExecutionContext *ctx)
{
if (ctx->thisObject().isNumber())
return ctx->thisObject().asDouble();
- NumberObject *n = ctx->thisObject().asNumberObject();
+ NumberObject *n = ctx->thisObject().as<NumberObject>();
if (!n)
return ctx->engine()->throwTypeError();
return n->value();
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index 205995701b..04798d31fc 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -53,8 +53,8 @@ struct NumberCtor: FunctionObject
{
V4_OBJECT2(NumberCtor, FunctionObject)
- static ReturnedValue construct(Managed *that, CallData *callData);
- static ReturnedValue call(Managed *, CallData *callData);
+ static ReturnedValue construct(const Managed *that, CallData *callData);
+ static ReturnedValue call(const Managed *, CallData *callData);
};
struct NumberPrototype: NumberObject
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 211fd1812e..148c7829bd 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -37,12 +37,13 @@
#include "qv4objectproto_p.h"
#include "qv4stringobject_p.h"
#include "qv4argumentsobject_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4lookup_p.h"
#include "qv4scopedvalue_p.h"
#include "qv4memberdata_p.h"
#include "qv4objectiterator_p.h"
#include "qv4identifier_p.h"
+#include "qv4string_p.h"
#include <stdint.h>
@@ -356,7 +357,7 @@ bool Object::hasOwnProperty(uint index) const
return true;
if (isStringObject()) {
- String *s = static_cast<const StringObject *>(this)->d()->value.asString();
+ String *s = static_cast<const StringObject *>(this)->d()->value.as<String>();
if (index < (uint)s->d()->length())
return true;
}
@@ -365,24 +366,24 @@ bool Object::hasOwnProperty(uint index) const
return false;
}
-ReturnedValue Object::construct(Managed *m, CallData *)
+ReturnedValue Object::construct(const Managed *m, CallData *)
{
- return static_cast<Object *>(m)->engine()->throwTypeError();
+ return static_cast<const Object *>(m)->engine()->throwTypeError();
}
-ReturnedValue Object::call(Managed *m, CallData *)
+ReturnedValue Object::call(const Managed *m, CallData *)
{
- return static_cast<Object *>(m)->engine()->throwTypeError();
+ return static_cast<const Object *>(m)->engine()->throwTypeError();
}
-ReturnedValue Object::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue Object::get(const Managed *m, String *name, bool *hasProperty)
{
- return static_cast<Object *>(m)->internalGet(name, hasProperty);
+ return static_cast<const Object *>(m)->internalGet(name, hasProperty);
}
-ReturnedValue Object::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue Object::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
- return static_cast<Object *>(m)->internalGetIndexed(index, hasProperty);
+ return static_cast<const Object *>(m)->internalGetIndexed(index, hasProperty);
}
void Object::put(Managed *m, String *name, const Value &value)
@@ -416,7 +417,7 @@ PropertyAttributes Object::queryIndexed(const Managed *m, uint index)
return o->arrayData()->attributes(index);
if (o->isStringObject()) {
- String *s = static_cast<const StringObject *>(o)->d()->value.asString();
+ String *s = static_cast<const StringObject *>(o)->d()->value.as<String>();
if (index < (uint)s->d()->length())
return (Attr_NotWritable|Attr_NotConfigurable);
}
@@ -433,9 +434,9 @@ bool Object::deleteIndexedProperty(Managed *m, uint index)
return static_cast<Object *>(m)->internalDeleteIndexedProperty(index);
}
-ReturnedValue Object::getLookup(Managed *m, Lookup *l)
+ReturnedValue Object::getLookup(const Managed *m, Lookup *l)
{
- Object *o = static_cast<Object *>(m);
+ const Object *o = static_cast<const Object *>(m);
PropertyAttributes attrs;
ReturnedValue v = l->lookup(o, &attrs);
if (v != Primitive::emptyValue().asReturnedValue()) {
@@ -531,7 +532,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name
while (it->arrayNode != o->sparseEnd()) {
int k = it->arrayNode->key();
uint pidx = it->arrayNode->value;
- Heap::SparseArrayData *sa = static_cast<Heap::SparseArrayData *>(o->d()->arrayData);
+ Heap::SparseArrayData *sa = o->d()->arrayData.cast<Heap::SparseArrayData>();
Property *p = reinterpret_cast<Property *>(sa->arrayData + pidx);
it->arrayNode = it->arrayNode->nextNode();
PropertyAttributes a = sa->attrs ? sa->attrs[pidx] : Attr_Data;
@@ -548,7 +549,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name
}
// dense arrays
while (it->arrayIndex < o->d()->arrayData->len) {
- Heap::SimpleArrayData *sa = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
+ Heap::SimpleArrayData *sa = o->d()->arrayData.cast<Heap::SimpleArrayData>();
Value &val = sa->data(it->arrayIndex);
PropertyAttributes a = o->arrayData()->attributes(it->arrayIndex);
++it->arrayIndex;
@@ -585,7 +586,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name
}
// Section 8.12.3
-ReturnedValue Object::internalGet(String *name, bool *hasProperty)
+ReturnedValue Object::internalGet(String *name, bool *hasProperty) const
{
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -611,7 +612,7 @@ ReturnedValue Object::internalGet(String *name, bool *hasProperty)
return Encode::undefined();
}
-ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty)
+ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) const
{
Property *pd = 0;
PropertyAttributes attrs;
@@ -710,7 +711,7 @@ void Object::internalPut(String *name, const Value &value)
// Clause 5
if (pd && attrs.isAccessor()) {
- assert(pd->setter() != 0);
+ Q_ASSERT(pd->setter() != 0);
Scope scope(engine());
ScopedFunctionObject setter(scope, pd->setter());
@@ -784,7 +785,7 @@ void Object::internalPutIndexed(uint index, const Value &value)
// Clause 5
if (pd && attrs.isAccessor()) {
- assert(pd->setter() != 0);
+ Q_ASSERT(pd->setter() != 0);
Scope scope(engine());
ScopedFunctionObject setter(scope, pd->setter());
@@ -1137,7 +1138,7 @@ void Object::initSparseArray()
DEFINE_OBJECT_VTABLE(ArrayObject);
Heap::ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
- : Heap::Object(engine->arrayClass, engine->arrayPrototype.asObject())
+ : Heap::Object(engine->arrayClass, engine->arrayPrototype())
{
init();
Scope scope(engine);
@@ -1155,14 +1156,14 @@ Heap::ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list)
a->setArrayLengthUnchecked(len);
}
-ReturnedValue ArrayObject::getLookup(Managed *m, Lookup *l)
+ReturnedValue ArrayObject::getLookup(const Managed *m, Lookup *l)
{
- Scope scope(static_cast<Object *>(m)->engine());
+ Scope scope(static_cast<const Object *>(m)->engine());
ScopedString name(scope, scope.engine->currentContext()->compilationUnit->runtimeStrings[l->nameIndex]);
if (name->equals(scope.engine->id_length)) {
// special case, as the property is on the object itself
l->getter = Lookup::arrayLengthGetter;
- ArrayObject *a = static_cast<ArrayObject *>(m);
+ const ArrayObject *a = static_cast<const ArrayObject *>(m);
return a->memberData()->data[Heap::ArrayObject::LengthPropertyIndex].asReturnedValue();
}
return Object::getLookup(m, l);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 71a997e133..e5055e20c0 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -36,6 +36,9 @@
#include "qv4managed_p.h"
#include "qv4memberdata_p.h"
#include "qv4arraydata_p.h"
+#include "qv4engine_p.h"
+#include "qv4scopedvalue_p.h"
+#include "qv4value_p.h"
QT_BEGIN_NAMESPACE
@@ -44,20 +47,16 @@ namespace QV4 {
namespace Heap {
struct Object : Base {
- Object(ExecutionEngine *engine)
- : internalClass(engine->emptyClass),
- prototype(static_cast<Object *>(engine->objectPrototype.m))
- {
- }
+ inline Object(ExecutionEngine *engine);
Object(InternalClass *internal, QV4::Object *prototype);
const Property *propertyAt(uint index) const { return reinterpret_cast<const Property *>(memberData->data + index); }
Property *propertyAt(uint index) { return reinterpret_cast<Property *>(memberData->data + index); }
InternalClass *internalClass;
- Heap::Object *prototype;
- MemberData *memberData;
- ArrayData *arrayData;
+ Pointer<Object> prototype;
+ Pointer<MemberData> memberData;
+ Pointer<ArrayData> arrayData;
};
}
@@ -67,7 +66,7 @@ struct Object : Base {
Q_MANAGED_CHECK \
typedef superClass SuperClass; \
static const QV4::ObjectVTable static_vtbl; \
- static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
+ static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \
V4_MANAGED_SIZE_TEST \
Data *d() const { return static_cast<Data *>(m); }
@@ -77,24 +76,24 @@ struct Object : Base {
typedef QV4::Heap::DataClass Data; \
typedef superClass SuperClass; \
static const QV4::ObjectVTable static_vtbl; \
- static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
+ static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \
V4_MANAGED_SIZE_TEST \
QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m); }
struct ObjectVTable
{
- ManagedVTable managedVTable;
- ReturnedValue (*call)(Managed *, CallData *data);
- ReturnedValue (*construct)(Managed *, CallData *data);
- ReturnedValue (*get)(Managed *, String *name, bool *hasProperty);
- ReturnedValue (*getIndexed)(Managed *, uint index, bool *hasProperty);
+ VTable vTable;
+ ReturnedValue (*call)(const Managed *, CallData *data);
+ ReturnedValue (*construct)(const Managed *, CallData *data);
+ ReturnedValue (*get)(const Managed *, String *name, bool *hasProperty);
+ ReturnedValue (*getIndexed)(const Managed *, uint index, bool *hasProperty);
void (*put)(Managed *, String *name, const Value &value);
void (*putIndexed)(Managed *, uint index, const Value &value);
PropertyAttributes (*query)(const Managed *, String *name);
PropertyAttributes (*queryIndexed)(const Managed *, uint index);
bool (*deleteProperty)(Managed *m, String *name);
bool (*deleteIndexedProperty)(Managed *m, uint index);
- ReturnedValue (*getLookup)(Managed *m, Lookup *l);
+ ReturnedValue (*getLookup)(const Managed *m, Lookup *l);
void (*setLookup)(Managed *m, Lookup *l, const Value &v);
uint (*getLength)(const Managed *m);
void (*advanceIterator)(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
@@ -103,7 +102,7 @@ struct ObjectVTable
#define DEFINE_OBJECT_VTABLE(classname) \
const QV4::ObjectVTable classname::static_vtbl = \
{ \
- DEFINE_MANAGED_VTABLE_INT(classname, &classname::SuperClass::static_vtbl == &Object::static_vtbl ? 0 : &classname::SuperClass::static_vtbl.managedVTable), \
+ DEFINE_MANAGED_VTABLE_INT(classname, &classname::SuperClass::static_vtbl == &Object::static_vtbl ? 0 : &classname::SuperClass::static_vtbl.vTable), \
call, \
construct, \
get, \
@@ -272,9 +271,9 @@ public:
}
void ensureMemberIndex(uint idx);
- inline ReturnedValue get(String *name, bool *hasProperty = 0)
+ inline ReturnedValue get(String *name, bool *hasProperty = 0) const
{ return vtable()->get(this, name, hasProperty); }
- inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0)
+ inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0) const
{ return vtable()->getIndexed(this, idx, hasProperty); }
inline void put(String *name, const Value &v)
{ vtable()->put(this, name, v); }
@@ -288,7 +287,7 @@ public:
{ return vtable()->deleteProperty(this, name); }
bool deleteIndexedProperty(uint index)
{ return vtable()->deleteIndexedProperty(this, index); }
- ReturnedValue getLookup(Lookup *l)
+ ReturnedValue getLookup(Lookup *l) const
{ return vtable()->getLookup(this, l); }
void setLookup(Lookup *l, const Value &v)
{ vtable()->setLookup(this, l, v); }
@@ -296,30 +295,30 @@ public:
{ vtable()->advanceIterator(this, it, name, index, p, attributes); }
uint getLength() const { return vtable()->getLength(this); }
- inline ReturnedValue construct(CallData *d)
+ inline ReturnedValue construct(CallData *d) const
{ return vtable()->construct(this, d); }
- inline ReturnedValue call(CallData *d)
+ inline ReturnedValue call(CallData *d) const
{ return vtable()->call(this, d); }
protected:
static void markObjects(Heap::Base *that, ExecutionEngine *e);
- static ReturnedValue construct(Managed *m, CallData *);
- static ReturnedValue call(Managed *m, CallData *);
- static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
- static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue construct(const Managed *m, CallData *);
+ static ReturnedValue call(const Managed *m, CallData *);
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static void putIndexed(Managed *m, uint index, const Value &value);
static PropertyAttributes query(const Managed *m, String *name);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
static bool deleteProperty(Managed *m, String *name);
static bool deleteIndexedProperty(Managed *m, uint index);
- static ReturnedValue getLookup(Managed *m, Lookup *l);
+ static ReturnedValue getLookup(const Managed *m, Lookup *l);
static void setLookup(Managed *m, Lookup *l, const Value &v);
static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
static uint getLength(const Managed *m);
private:
- ReturnedValue internalGet(String *name, bool *hasProperty);
- ReturnedValue internalGetIndexed(uint index, bool *hasProperty);
+ ReturnedValue internalGet(String *name, bool *hasProperty) const;
+ ReturnedValue internalGetIndexed(uint index, bool *hasProperty) const;
void internalPut(String *name, const Value &value);
void internalPutIndexed(uint index, const Value &value);
bool internalDeleteProperty(String *name);
@@ -331,6 +330,12 @@ private:
namespace Heap {
+inline Object::Object(ExecutionEngine *engine)
+ : internalClass(engine->emptyClass),
+ prototype(static_cast<Object *>(engine->objectPrototype()->m))
+{
+}
+
struct BooleanObject : Object {
BooleanObject(InternalClass *ic, QV4::Object *prototype)
: Object(ic, prototype),
@@ -339,7 +344,7 @@ struct BooleanObject : Object {
}
BooleanObject(ExecutionEngine *engine, bool b)
- : Object(engine->emptyClass, engine->booleanPrototype.asObject()),
+ : Object(engine->emptyClass, engine->booleanPrototype()),
b(b)
{
}
@@ -354,7 +359,7 @@ struct NumberObject : Object {
}
NumberObject(ExecutionEngine *engine, double val)
- : Object(engine->emptyClass, engine->numberPrototype.asObject()),
+ : Object(engine->emptyClass, engine->numberPrototype()),
value(val)
{
}
@@ -367,7 +372,7 @@ struct ArrayObject : Object {
};
ArrayObject(ExecutionEngine *engine)
- : Heap::Object(engine->arrayClass, engine->arrayPrototype.asObject())
+ : Heap::Object(engine->arrayClass, engine->arrayPrototype())
{ init(); }
ArrayObject(ExecutionEngine *engine, const QStringList &list);
ArrayObject(InternalClass *ic, QV4::Object *prototype)
@@ -400,7 +405,7 @@ struct ArrayObject: Object {
void init(ExecutionEngine *engine);
- static ReturnedValue getLookup(Managed *m, Lookup *l);
+ static ReturnedValue getLookup(const Managed *m, Lookup *l);
using Object::getLength;
static uint getLength(const Managed *m);
@@ -454,14 +459,10 @@ inline void Object::arraySet(uint index, const Value &value)
setArrayLengthUnchecked(index + 1);
}
-template<>
-inline Object *value_cast(const Value &v) {
- return v.asObject();
-}
template<>
-inline ArrayObject *value_cast(const Value &v) {
- return v.asArrayObject();
+inline const ArrayObject *Value::as() const {
+ return isManaged() && m && m->vtable->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : 0;
}
#ifndef V4_BOOTSTRAP
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index f36ee554a7..3901101855 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -35,6 +35,7 @@
#include "qv4stringobject_p.h"
#include "qv4identifier_p.h"
#include "qv4argumentsobject_p.h"
+#include "qv4string_p.h"
using namespace QV4;
@@ -83,7 +84,7 @@ void ObjectIterator::next(Heap::String **name, uint *index, Property *pd, Proper
*name = 0;
*index = UINT_MAX;
- if (!object->asObject()) {
+ if (!object->as<Object>()) {
*attrs = PropertyAttributes();
return;
}
@@ -92,19 +93,19 @@ void ObjectIterator::next(Heap::String **name, uint *index, Property *pd, Proper
ScopedString n(scope);
while (1) {
- if (!current->asObject())
+ if (!current->as<Object>())
break;
while (1) {
- current->asObject()->advanceIterator(this, name, index, pd, attrs);
+ current->as<Object>()->advanceIterator(this, name, index, pd, attrs);
if (attrs->isEmpty())
break;
// check the property is not already defined earlier in the proto chain
if (current->heapObject() != object->heapObject()) {
- o = object->asObject();
+ o = object->as<Object>();
n = *name;
bool shadowed = false;
- while (o->asObject()->d() != current->heapObject()) {
+ while (o->d() != current->heapObject()) {
if ((!!n && o->hasOwnProperty(n)) ||
(*index != UINT_MAX && o->hasOwnProperty(*index))) {
shadowed = true;
@@ -131,7 +132,7 @@ void ObjectIterator::next(Heap::String **name, uint *index, Property *pd, Proper
ReturnedValue ObjectIterator::nextPropertyName(Value *value)
{
- if (!object->asObject())
+ if (!object->as<Object>())
return Encode::null();
PropertyAttributes attrs;
@@ -147,13 +148,13 @@ ReturnedValue ObjectIterator::nextPropertyName(Value *value)
if (!!name)
return name->asReturnedValue();
- assert(index < UINT_MAX);
+ Q_ASSERT(index < UINT_MAX);
return Encode(index);
}
ReturnedValue ObjectIterator::nextPropertyNameAsString(Value *value)
{
- if (!object->asObject())
+ if (!object->as<Object>())
return Encode::null();
PropertyAttributes attrs;
@@ -169,13 +170,13 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString(Value *value)
if (!!name)
return name->asReturnedValue();
- assert(index < UINT_MAX);
+ Q_ASSERT(index < UINT_MAX);
return Encode(engine->newString(QString::number(index)));
}
ReturnedValue ObjectIterator::nextPropertyNameAsString()
{
- if (!object->asObject())
+ if (!object->as<Object>())
return Encode::null();
PropertyAttributes attrs;
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 9356ea434e..bac5da709e 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -34,10 +34,11 @@
#include "qv4objectproto_p.h"
#include "qv4argumentsobject_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4scopedvalue_p.h"
#include "qv4runtime_p.h"
#include "qv4objectiterator_p.h"
+#include "qv4string_p.h"
#include <QtCore/QDateTime>
#include <QtCore/QStringList>
@@ -52,9 +53,9 @@ Heap::ObjectCtor::ObjectCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData)
+ReturnedValue ObjectCtor::construct(const Managed *that, CallData *callData)
{
- ObjectCtor *ctor = static_cast<ObjectCtor *>(that);
+ const ObjectCtor *ctor = static_cast<const ObjectCtor *>(that);
ExecutionEngine *v4 = ctor->engine();
Scope scope(v4);
if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) {
@@ -67,9 +68,9 @@ ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData)
return RuntimeHelpers::toObject(scope.engine, callData->args[0]);
}
-ReturnedValue ObjectCtor::call(Managed *m, CallData *callData)
+ReturnedValue ObjectCtor::call(const Managed *m, CallData *callData)
{
- ObjectCtor *ctor = static_cast<ObjectCtor *>(m);
+ const ObjectCtor *ctor = static_cast<const ObjectCtor *>(m);
ExecutionEngine *v4 = ctor->engine();
if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull())
return v4->newObject()->asReturnedValue();
@@ -163,7 +164,7 @@ ReturnedValue ObjectPrototype::method_create(CallContext *ctx)
return ctx->engine()->throwTypeError();
ScopedObject newObject(scope, ctx->d()->engine->newObject());
- newObject->setPrototype(O->asObject());
+ newObject->setPrototype(O->as<Object>());
if (ctx->argc() > 1 && !ctx->args()[1].isUndefined()) {
ctx->d()->callData->args[0] = newObject.asReturnedValue();
@@ -484,7 +485,7 @@ ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx)
if (!o) {
if (!ctx->thisObject().isUndefined())
return Encode::undefined();
- o = ctx->d()->engine->globalObject();
+ o = ctx->d()->engine->globalObject;
}
ScopedProperty pd(scope);
@@ -512,7 +513,7 @@ ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx)
if (!o) {
if (!ctx->thisObject().isUndefined())
return Encode::undefined();
- o = ctx->d()->engine->globalObject();
+ o = ctx->d()->engine->globalObject;
}
ScopedProperty pd(scope);
@@ -525,7 +526,7 @@ ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx)
ReturnedValue ObjectPrototype::method_get_proto(CallContext *ctx)
{
Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject().asObject());
+ ScopedObject o(scope, ctx->thisObject().as<Object>());
if (!o)
return ctx->engine()->throwTypeError();
@@ -580,7 +581,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value
if (o->hasProperty(engine->id_get)) {
ScopedValue get(scope, o->get(engine->id_get));
- FunctionObject *f = get->asFunctionObject();
+ FunctionObject *f = get->as<FunctionObject>();
if (f || get->isUndefined()) {
desc->value = get;
} else {
@@ -592,7 +593,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value
if (o->hasProperty(engine->id_set)) {
ScopedValue set(scope, o->get(engine->id_set));
- FunctionObject *f = set->asFunctionObject();
+ FunctionObject *f = set->as<FunctionObject>();
if (f || set->isUndefined()) {
desc->set = set;
} else {
diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h
index 4e96681017..d571e50cd4 100644
--- a/src/qml/jsruntime/qv4objectproto_p.h
+++ b/src/qml/jsruntime/qv4objectproto_p.h
@@ -53,8 +53,8 @@ struct ObjectCtor: FunctionObject
{
V4_OBJECT2(ObjectCtor, FunctionObject)
- static ReturnedValue construct(Managed *that, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *that, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
struct ObjectPrototype: Object
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp
index 88dc1946b8..f7e88dddd6 100644
--- a/src/qml/jsruntime/qv4persistent.cpp
+++ b/src/qml/jsruntime/qv4persistent.cpp
@@ -32,7 +32,7 @@
****************************************************************************/
#include "qv4persistent_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4object_p.h"
#include "PageAllocation.h"
@@ -190,7 +190,7 @@ void PersistentValueStorage::mark(ExecutionEngine *e)
Page *p = static_cast<Page *>(firstPage);
while (p) {
for (int i = 0; i < kEntriesPerPage; ++i) {
- if (Managed *m = p->values[i].asManaged())
+ if (Managed *m = p->values[i].as<Managed>())
m->mark(e);
}
drainMarkStack(e, markBase);
diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h
index 7cac2ed95f..fe50b0ebfc 100644
--- a/src/qml/jsruntime/qv4persistent_p.h
+++ b/src/qml/jsruntime/qv4persistent_p.h
@@ -33,7 +33,8 @@
#ifndef QV4PERSISTENT_H
#define QV4PERSISTENT_H
-#include "qv4value_inl_p.h"
+#include "qv4value_p.h"
+#include "qv4managed_p.h"
QT_BEGIN_NAMESPACE
@@ -96,7 +97,7 @@ public:
Managed *asManaged() const {
if (!val)
return 0;
- return val->asManaged();
+ return val->as<Managed>();
}
ExecutionEngine *engine() const {
@@ -138,7 +139,7 @@ public:
Managed *asManaged() const {
if (!val)
return 0;
- return val->asManaged();
+ return val->as<Managed>();
}
ExecutionEngine *engine() const {
diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp
index a7019d0558..d2628c7bd0 100644
--- a/src/qml/jsruntime/qv4profiling.cpp
+++ b/src/qml/jsruntime/qv4profiling.cpp
@@ -32,7 +32,8 @@
****************************************************************************/
#include "qv4profiling_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
+#include <private/qv4string_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h
index 1b55abd1f7..34d9cdadeb 100644
--- a/src/qml/jsruntime/qv4property_p.h
+++ b/src/qml/jsruntime/qv4property_p.h
@@ -35,7 +35,6 @@
#include "qv4global_p.h"
#include "qv4value_p.h"
-#include "qv4internalclass_p.h"
QT_BEGIN_NAMESPACE
@@ -73,8 +72,8 @@ struct Property {
inline Heap::FunctionObject *getter() const { return value.isManaged() ? reinterpret_cast<Heap::FunctionObject *>(value.heapObject()) : 0; }
inline Heap::FunctionObject *setter() const { return set.isManaged() ? reinterpret_cast<Heap::FunctionObject *>(set.heapObject()) : 0; }
- inline void setGetter(FunctionObject *g) { value = Primitive::fromManaged(reinterpret_cast<Managed *>(g)); }
- inline void setSetter(FunctionObject *s) { set = s ? Primitive::fromManaged(reinterpret_cast<Managed *>(s)) : Value::fromHeapObject(0); }
+ inline void setGetter(FunctionObject *g) { value = reinterpret_cast<Managed *>(g); }
+ inline void setSetter(FunctionObject *s) { set = (s ? reinterpret_cast<Managed *>(s) : 0); }
void copy(const Property *other, PropertyAttributes attrs) {
value = other->value;
@@ -85,8 +84,8 @@ struct Property {
explicit Property() { value = Encode::undefined(); set = Value::fromHeapObject(0); }
explicit Property(Value v) : value(v) { set = Value::fromHeapObject(0); }
Property(FunctionObject *getter, FunctionObject *setter) {
- value = Primitive::fromManaged(reinterpret_cast<Managed *>(getter));
- set = Primitive::fromManaged(reinterpret_cast<Managed *>(setter));
+ value = reinterpret_cast<Managed *>(getter);
+ set = reinterpret_cast<Managed *>(setter);
}
Property(Heap::FunctionObject *getter, Heap::FunctionObject *setter) {
value.m = reinterpret_cast<Heap::Base *>(getter);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 1e4718c208..e985c62228 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -55,6 +55,7 @@
#include <private/qv4objectproto_p.h>
#include <private/qv4jsonobject_p.h>
#include <private/qv4regexpobject_p.h>
+#include <private/qv4dateobject_p.h>
#include <private/qv4scopedvalue_p.h>
#include <private/qv4mm_p.h>
#include <private/qqmlscriptstring_p.h>
@@ -97,7 +98,7 @@ static QPair<QObject *, int> extractQtMethod(QV4::FunctionObject *function)
static QPair<QObject *, int> extractQtSignal(const Value &value)
{
if (value.isObject()) {
- QV4::ExecutionEngine *v4 = value.asObject()->engine();
+ QV4::ExecutionEngine *v4 = value.as<Object>()->engine();
QV4::Scope scope(v4);
QV4::ScopedFunctionObject function(scope, value);
if (function)
@@ -240,8 +241,8 @@ Heap::QObjectWrapper::QObjectWrapper(ExecutionEngine *engine, QObject *object)
void QObjectWrapper::initializeBindings(ExecutionEngine *engine)
{
- engine->functionPrototype.asObject()->defineDefaultProperty(QStringLiteral("connect"), method_connect);
- engine->functionPrototype.asObject()->defineDefaultProperty(QStringLiteral("disconnect"), method_disconnect);
+ engine->functionPrototype()->defineDefaultProperty(QStringLiteral("connect"), method_connect);
+ engine->functionPrototype()->defineDefaultProperty(QStringLiteral("disconnect"), method_disconnect);
}
QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const
@@ -260,7 +261,7 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlCont
}
ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String *n, QObjectWrapper::RevisionMode revisionMode,
- bool *hasProperty, bool includeImports)
+ bool *hasProperty, bool includeImports) const
{
if (QQmlData::wasDeleted(d()->object)) {
if (hasProperty)
@@ -346,8 +347,8 @@ ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx
QV4::ScopedString connect(scope, ctx->d()->engine->newIdentifier(QStringLiteral("connect")));
QV4::ScopedString disconnect(scope, ctx->d()->engine->newIdentifier(QStringLiteral("disconnect")));
- handler->put(connect, QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype.asObject()->get(connect)));
- handler->put(disconnect, QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype.asObject()->get(disconnect)));
+ handler->put(connect, QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype()->get(connect)));
+ handler->put(disconnect, QV4::ScopedValue(scope, ctx->d()->engine->functionPrototype()->get(disconnect)));
return handler.asReturnedValue();
} else {
@@ -476,14 +477,14 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
bindingFunction->initBindingLocation();
newBinding = new QQmlBinding(value, object, callingQmlContext);
- newBinding->setTarget(object, *property, callingQmlContext);
+ newBinding->setTarget(object, *property);
}
}
- QQmlAbstractBinding *oldBinding =
- QQmlPropertyPrivate::setBinding(object, property->coreIndex, -1, newBinding);
- if (oldBinding)
- oldBinding->destroy();
+ if (newBinding)
+ QQmlPropertyPrivate::setBinding(newBinding);
+ else
+ QQmlPropertyPrivate::removeBinding(object, property->encodedIndex(), QQmlPropertyPrivate::DestroyOldBinding);
if (!newBinding && property->isVarProperty()) {
// allow assignment of "special" values (null, undefined, function) to var properties
@@ -519,7 +520,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
error += QLatin1String(QMetaType::typeName(property->propType));
ctx->engine()->throwError(error);
return;
- } else if (value.asFunctionObject()) {
+ } else if (value.as<FunctionObject>()) {
// this is handled by the binding creation above
} else if (property->propType == QMetaType::Int && value.isNumber()) {
PROPERTY_STORE(int, value.asDouble());
@@ -673,7 +674,7 @@ bool QObjectWrapper::isEqualTo(Managed *a, Managed *b)
{
Q_ASSERT(a->as<QV4::QObjectWrapper>());
QV4::QObjectWrapper *qobjectWrapper = static_cast<QV4::QObjectWrapper *>(a);
- QV4::Object *o = b->asObject();
+ QV4::Object *o = b->as<Object>();
if (o) {
if (QV4::QmlTypeWrapper *qmlTypeWrapper = o->as<QV4::QmlTypeWrapper>())
return qmlTypeWrapper->toVariant().value<QObject*>() == qobjectWrapper->object();
@@ -689,9 +690,9 @@ ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object)
return (engine->memoryManager->alloc<QV4::QObjectWrapper>(engine, object))->asReturnedValue();
}
-QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProperty)
+QV4::ReturnedValue QObjectWrapper::get(const Managed *m, String *name, bool *hasProperty)
{
- QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
+ const QObjectWrapper *that = static_cast<const QObjectWrapper*>(m);
QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(that->engine());
return that->getQmlProperty(qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true);
}
@@ -816,7 +817,7 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
QV4::ScopedFunctionObject f(scope, This->function.value());
QV4::ScopedCallData callData(scope, argCount);
- callData->thisObject = This->thisObject.isUndefined() ? v4->globalObject()->asReturnedValue() : This->thisObject.value();
+ callData->thisObject = This->thisObject.isUndefined() ? v4->globalObject->asReturnedValue() : This->thisObject.value();
for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1];
if (type == qMetaTypeId<QVariant>()) {
@@ -1234,7 +1235,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType)
default:
return 10;
}
- } else if (actual.asDateObject()) {
+ } else if (actual.as<DateObject>()) {
switch (conversionType) {
case QMetaType::QDateTime:
return 0;
@@ -1252,7 +1253,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType)
default:
return 10;
}
- } else if (actual.asArrayObject()) {
+ } else if (actual.as<ArrayObject>()) {
switch (conversionType) {
case QMetaType::QJsonArray:
return 3;
@@ -1281,7 +1282,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType)
return 10;
}
}
- } else if (QV4::Object *obj = actual.asObject()) {
+ } else if (const Object *obj = actual.as<Object>()) {
if (obj->as<QV4::VariantObject>()) {
if (conversionType == qMetaTypeId<QVariant>())
return 0;
@@ -1611,9 +1612,9 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
type = callType;
} else if (callType == QMetaType::QObjectStar) {
qobjectPtr = 0;
- if (QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
+ if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
qobjectPtr = qobjectWrapper->object();
- else if (QV4::QmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QmlTypeWrapper>())
+ else if (const QV4::QmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QmlTypeWrapper>())
queryEngine = qmlTypeWrapper->isSingleton();
type = callType;
} else if (callType == qMetaTypeId<QVariant>()) {
@@ -1635,7 +1636,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
}
} else {
QObject *o = 0;
- if (QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
+ if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
o = qobjectWrapper->object();
qlistPtr->append(o);
}
@@ -1759,14 +1760,14 @@ ReturnedValue QObjectMethod::create(ExecutionContext *scope, QObject *object, in
return method.asReturnedValue();
}
-ReturnedValue QObjectMethod::create(ExecutionContext *scope, QQmlValueTypeWrapper *valueType, int index, const Value &qmlGlobal)
+ReturnedValue QObjectMethod::create(ExecutionContext *scope, const QQmlValueTypeWrapper *valueType, int index, const Value &qmlGlobal)
{
Scope valueScope(scope);
Scoped<QObjectMethod> method(valueScope, scope->d()->engine->memoryManager->alloc<QObjectMethod>(scope));
method->d()->propertyCache = valueType->d()->propertyCache;
method->d()->index = index;
method->d()->qmlGlobal = qmlGlobal;
- method->d()->valueTypeWrapper = valueType;
+ method->d()->valueTypeWrapper = *valueType;
return method.asReturnedValue();
}
@@ -1782,7 +1783,7 @@ const QMetaObject *Heap::QObjectMethod::metaObject()
return object->metaObject();
}
-QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx)
+QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx) const
{
QString result;
if (const QMetaObject *metaObject = d()->metaObject()) {
@@ -1808,7 +1809,7 @@ QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx)
return ctx->d()->engine->newString(result)->asReturnedValue();
}
-QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc)
+QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc) const
{
if (!d()->object)
return Encode::undefined();
@@ -1827,13 +1828,13 @@ QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, con
return Encode::undefined();
}
-ReturnedValue QObjectMethod::call(Managed *m, CallData *callData)
+ReturnedValue QObjectMethod::call(const Managed *m, CallData *callData)
{
- QObjectMethod *This = static_cast<QObjectMethod*>(m);
+ const QObjectMethod *This = static_cast<const QObjectMethod*>(m);
return This->callInternal(callData);
}
-ReturnedValue QObjectMethod::callInternal(CallData *callData)
+ReturnedValue QObjectMethod::callInternal(CallData *callData) const
{
Scope scope(engine());
ScopedContext context(scope, scope.engine->currentContext());
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 24e8b29e08..ac7aad3378 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -54,7 +54,7 @@
#include <private/qqmlpropertycache_p.h>
#include <private/qintrusivelist_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
QT_BEGIN_NAMESPACE
@@ -104,7 +104,7 @@ struct Q_QML_EXPORT QObjectWrapper : public Object
QObject *object() const { return d()->object.data(); }
- ReturnedValue getQmlProperty(QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false);
+ ReturnedValue getQmlProperty(QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false) const;
static ReturnedValue getQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0);
static bool setQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value);
@@ -128,7 +128,7 @@ private:
QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
- static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static PropertyAttributes query(const Managed *, String *name);
static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
@@ -149,17 +149,17 @@ struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject
enum { DestroyMethod = -1, ToStringMethod = -2 };
static ReturnedValue create(QV4::ExecutionContext *scope, QObject *object, int index, const Value &qmlGlobal = Primitive::undefinedValue());
- static ReturnedValue create(QV4::ExecutionContext *scope, QQmlValueTypeWrapper *valueType, int index, const Value &qmlGlobal = Primitive::undefinedValue());
+ static ReturnedValue create(QV4::ExecutionContext *scope, const QQmlValueTypeWrapper *valueType, int index, const Value &qmlGlobal = Primitive::undefinedValue());
int methodIndex() const { return d()->index; }
QObject *object() const { return d()->object.data(); }
- QV4::ReturnedValue method_toString(QV4::ExecutionContext *ctx);
- QV4::ReturnedValue method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc);
+ QV4::ReturnedValue method_toString(QV4::ExecutionContext *ctx) const;
+ QV4::ReturnedValue method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc) const;
- static ReturnedValue call(Managed *, CallData *callData);
+ static ReturnedValue call(const Managed *, CallData *callData);
- ReturnedValue callInternal(CallData *callData);
+ ReturnedValue callInternal(CallData *callData) const;
static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
};
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index 8e18a5fbdd..715df2d666 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -34,7 +34,7 @@
#include "qv4regexp_p.h"
#include "qv4engine_p.h"
#include "qv4scopedvalue_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
using namespace QV4;
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index f6e88e62b7..3274e030c4 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -37,7 +37,7 @@
#include "qv4objectproto_p.h"
#include "qv4regexp_p.h"
#include "qv4stringobject_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4scopedvalue_p.h"
#include <private/qqmljsengine_p.h>
@@ -75,7 +75,7 @@ Heap::RegExpObject::RegExpObject(InternalClass *ic, QV4::Object *prototype)
}
Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *value, bool global)
- : Heap::Object(engine->emptyClass, engine->regExpPrototype.asObject())
+ : Heap::Object(engine->emptyClass, engine->regExpPrototype())
, value(value->d())
, global(global)
{
@@ -88,7 +88,7 @@ Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *valu
// The conversion is not 100% exact since ECMA regexp and QRegExp
// have different semantics/flags, but we try to do our best.
Heap::RegExpObject::RegExpObject(QV4::ExecutionEngine *engine, const QRegExp &re)
- : Heap::Object(engine->emptyClass, engine->regExpPrototype.asObject())
+ : Heap::Object(engine->emptyClass, engine->regExpPrototype())
{
value = 0;
global = false;
@@ -231,14 +231,14 @@ Heap::RegExpCtor::RegExpCtor(QV4::ExecutionContext *scope)
void Heap::RegExpCtor::clearLastMatch()
{
lastMatch = Primitive::nullValue();
- lastInput = internalClass->engine->id_empty;
+ lastInput = internalClass->engine->id_empty->d();
lastMatchStart = 0;
lastMatchEnd = 0;
}
-ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
+ReturnedValue RegExpCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<Object *>(m)->engine());
+ Scope scope(static_cast<const Object *>(m)->engine());
ScopedContext ctx(scope, scope.engine->currentContext());
ScopedValue r(scope, callData->argument(0));
@@ -286,7 +286,7 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
return Encode(ctx->d()->engine->newRegExpObject(regexp, global));
}
-ReturnedValue RegExpCtor::call(Managed *that, CallData *callData)
+ReturnedValue RegExpCtor::call(const Managed *that, CallData *callData)
{
if (callData->argc > 0 && callData->args[0].as<RegExpObject>()) {
if (callData->argc == 1 || callData->args[1].isUndefined())
@@ -300,7 +300,7 @@ void RegExpCtor::markObjects(Heap::Base *that, ExecutionEngine *e)
{
RegExpCtor::Data *This = static_cast<RegExpCtor::Data *>(that);
This->lastMatch.mark(e);
- This->lastInput.mark(e);
+ This->lastInput->mark(e);
FunctionObject::markObjects(that, e);
}
@@ -363,7 +363,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
uint* matchOffsets = (uint*)alloca(r->value()->captureCount() * 2 * sizeof(uint));
const int result = Scoped<RegExp>(scope, r->value())->match(s, offset, matchOffsets);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor);
+ Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor());
regExpCtor->d()->clearLastMatch();
if (result == -1) {
@@ -372,7 +372,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
}
// fill in result data
- ScopedArrayObject array(scope, scope.engine->newArrayObject(scope.engine->regExpExecArrayClass, scope.engine->arrayPrototype.asObject()));
+ ScopedArrayObject array(scope, scope.engine->newArrayObject(scope.engine->regExpExecArrayClass, scope.engine->arrayPrototype()));
int len = r->value()->captureCount();
array->arrayReserve(len);
ScopedValue v(scope);
@@ -388,7 +388,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
RegExpCtor::Data *dd = regExpCtor->d();
dd->lastMatch = array;
- dd->lastInput = arg->stringValue();
+ dd->lastInput = arg->stringValue()->d();
dd->lastMatchStart = matchOffsets[0];
dd->lastMatchEnd = matchOffsets[1];
@@ -425,7 +425,7 @@ ReturnedValue RegExpPrototype::method_compile(CallContext *ctx)
ScopedCallData callData(scope, ctx->argc());
memcpy(callData->args, ctx->args(), ctx->argc()*sizeof(Value));
- Scoped<RegExpObject> re(scope, ctx->d()->engine->regExpCtor.asFunctionObject()->construct(callData));
+ Scoped<RegExpObject> re(scope, ctx->d()->engine->regExpCtor()->as<FunctionObject>()->construct(callData));
r->d()->value = re->value();
r->d()->global = re->global();
@@ -436,7 +436,7 @@ template <int index>
ReturnedValue RegExpPrototype::method_get_lastMatch_n(CallContext *ctx)
{
Scope scope(ctx);
- ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor.objectValue())->lastMatch());
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastMatch());
ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(index) : Encode::undefined());
if (result->isUndefined())
return ctx->d()->engine->newString()->asReturnedValue();
@@ -446,7 +446,7 @@ ReturnedValue RegExpPrototype::method_get_lastMatch_n(CallContext *ctx)
ReturnedValue RegExpPrototype::method_get_lastParen(CallContext *ctx)
{
Scope scope(ctx);
- ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor.objectValue())->lastMatch());
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastMatch());
ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined());
if (result->isUndefined())
return ctx->d()->engine->newString()->asReturnedValue();
@@ -455,13 +455,13 @@ ReturnedValue RegExpPrototype::method_get_lastParen(CallContext *ctx)
ReturnedValue RegExpPrototype::method_get_input(CallContext *ctx)
{
- return static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor.objectValue())->lastInput().asReturnedValue();
+ return static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastInput()->asReturnedValue();
}
ReturnedValue RegExpPrototype::method_get_leftContext(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor);
+ Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor());
QString lastInput = regExpCtor->lastInput()->toQString();
return ctx->d()->engine->newString(lastInput.left(regExpCtor->lastMatchStart()))->asReturnedValue();
}
@@ -469,7 +469,7 @@ ReturnedValue RegExpPrototype::method_get_leftContext(CallContext *ctx)
ReturnedValue RegExpPrototype::method_get_rightContext(CallContext *ctx)
{
Scope scope(ctx);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor);
+ Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor());
QString lastInput = regExpCtor->lastInput()->toQString();
return ctx->d()->engine->newString(lastInput.mid(regExpCtor->lastMatchEnd()))->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index f5f255faf5..29d20614de 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -61,14 +61,14 @@ struct RegExpObject : Object {
RegExpObject(QV4::ExecutionEngine *engine, QV4::RegExp *value, bool global);
RegExpObject(QV4::ExecutionEngine *engine, const QRegExp &re);
- RegExp *value;
+ Pointer<RegExp> value;
bool global;
};
struct RegExpCtor : FunctionObject {
RegExpCtor(QV4::ExecutionContext *scope);
Value lastMatch;
- StringValue lastInput;
+ Pointer<String> lastInput;
int lastMatchStart;
int lastMatchEnd;
void clearLastMatch();
@@ -117,12 +117,12 @@ struct RegExpCtor: FunctionObject
V4_OBJECT2(RegExpCtor, FunctionObject)
Value lastMatch() { return d()->lastMatch; }
- StringValue lastInput() { return d()->lastInput; }
+ Heap::String *lastInput() { return d()->lastInput; }
int lastMatchStart() { return d()->lastMatchStart; }
int lastMatchEnd() { return d()->lastMatchEnd; }
- static ReturnedValue construct(Managed *m, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
@@ -146,7 +146,7 @@ struct RegExpPrototype: RegExpObject
};
inline Heap::RegExpPrototype::RegExpPrototype(ExecutionEngine *e)
- : RegExpObject(e->emptyClass, e->objectPrototype.asObject())
+ : RegExpObject(e->emptyClass, e->objectPrototype())
{
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index c31de6a9f0..b04d404ae4 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -40,6 +40,7 @@
#include "qv4stringobject_p.h"
#include "qv4argumentsobject_p.h"
#include "qv4objectiterator_p.h"
+#include "qv4dateobject_p.h"
#include "qv4lookup_p.h"
#include "qv4function_p.h"
#include "private/qlocale_tools_p.h"
@@ -313,14 +314,14 @@ ReturnedValue Runtime::deleteName(ExecutionEngine *engine, int nameIndex)
QV4::ReturnedValue Runtime::instanceof(ExecutionEngine *engine, const Value &left, const Value &right)
{
Scope scope(engine);
- ScopedFunctionObject f(scope, right.asFunctionObject());
+ ScopedFunctionObject f(scope, right.as<FunctionObject>());
if (!f)
return engine->throwTypeError();
if (f->isBoundFunction())
f = static_cast<BoundFunction *>(f.getPointer())->target();
- ScopedObject v(scope, left.asObject());
+ ScopedObject v(scope, left.as<Object>());
if (!v)
return Encode(false);
@@ -380,10 +381,10 @@ Heap::String *RuntimeHelpers::stringFromNumber(ExecutionEngine *engine, double n
return engine->newString(qstr);
}
-ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
+ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeHint)
{
if (typeHint == PREFERREDTYPE_HINT) {
- if (object->asDateObject())
+ if (object->as<DateObject>())
typeHint = STRING_HINT;
else
typeHint = NUMBER_HINT;
@@ -401,10 +402,10 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
Scope scope(engine);
ScopedCallData callData(scope, 0);
- callData->thisObject = object;
+ callData->thisObject = *object;
ScopedValue conv(scope, object->get(*meth1));
- if (FunctionObject *o = conv->asFunctionObject()) {
+ if (FunctionObject *o = conv->as<FunctionObject>()) {
ScopedValue r(scope, o->call(callData));
if (r->isPrimitive())
return r->asReturnedValue();
@@ -414,7 +415,7 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
return Encode::undefined();
conv = object->get(*meth2);
- if (FunctionObject *o = conv->asFunctionObject()) {
+ if (FunctionObject *o = conv->as<FunctionObject>()) {
ScopedValue r(scope, o->call(callData));
if (r->isPrimitive())
return r->asReturnedValue();
@@ -575,7 +576,7 @@ ReturnedValue Runtime::getElement(ExecutionEngine *engine, const Value &object,
ScopedObject o(scope, object);
if (!o) {
if (idx < UINT_MAX) {
- if (String *str = object.asString()) {
+ if (const String *str = object.as<String>()) {
if (idx >= (uint)str->toQString().length()) {
return Encode::undefined();
}
@@ -909,7 +910,7 @@ ReturnedValue Runtime::callGlobalLookup(ExecutionEngine *engine, uint index, Cal
return engine->throwTypeError();
ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[l->nameIndex]);
- if (o->d() == scope.engine->evalFunction && name->equals(scope.engine->id_eval))
+ if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval))
return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData, true);
return o->call(callData);
@@ -931,7 +932,7 @@ ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, int nameI
if (base)
callData->thisObject = base;
- FunctionObject *o = func->asFunctionObject();
+ FunctionObject *o = func->as<FunctionObject>();
if (!o) {
QString objectAsString = QStringLiteral("[null]");
if (base)
@@ -940,7 +941,7 @@ ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, int nameI
return engine->throwTypeError(msg);
}
- if (o->d() == scope.engine->evalFunction && name->equals(scope.engine->id_eval)) {
+ if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval)) {
return static_cast<EvalFunction *>(o)->evalCall(callData, true);
}
@@ -1034,7 +1035,7 @@ ReturnedValue Runtime::constructActivationProperty(ExecutionEngine *engine, int
if (scope.engine->hasException)
return Encode::undefined();
- Object *f = func->asObject();
+ Object *f = func->as<Object>();
if (!f)
return engine->throwTypeError();
@@ -1043,7 +1044,7 @@ ReturnedValue Runtime::constructActivationProperty(ExecutionEngine *engine, int
ReturnedValue Runtime::constructValue(ExecutionEngine *engine, const Value &func, CallData *callData)
{
- Object *f = func.asObject();
+ const Object *f = func.as<Object>();
if (!f)
return engine->throwTypeError();
@@ -1100,7 +1101,7 @@ ReturnedValue Runtime::typeofValue(ExecutionEngine *engine, const Value &value)
case Value::Managed_Type:
if (value.isString())
res = engine->id_string;
- else if (value.objectValue()->asFunctionObject())
+ else if (value.objectValue()->as<FunctionObject>())
res = engine->id_function;
else
res = engine->id_object; // ### implementation-defined
@@ -1199,7 +1200,7 @@ ReturnedValue Runtime::objectLiteral(ExecutionEngine *engine, const QV4::Value *
{
Scope scope(engine);
QV4::InternalClass *klass = engine->currentContext()->compilationUnit->runtimeClasses[classId];
- ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype.asObject()));
+ ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype()));
{
bool needSparseArray = arrayGetterSetterCountAndFlags >> 30;
@@ -1425,7 +1426,7 @@ void Runtime::convertThisToObject(ExecutionEngine *engine)
if (t->isObject())
return;
if (t->isNullOrUndefined()) {
- *t = engine->globalObject()->asReturnedValue();
+ *t = engine->globalObject->asReturnedValue();
} else {
*t = t->toObject(engine)->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index f2f90bbc15..e8ebccc17b 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -34,8 +34,9 @@
#define QMLJS_RUNTIME_H
#include "qv4global_p.h"
-#include "qv4value_inl_p.h"
+#include "qv4value_p.h"
#include "qv4context_p.h"
+#include "qv4engine_p.h"
#include "qv4math_p.h"
#include <QtCore/qnumeric.h>
@@ -218,7 +219,7 @@ struct Q_QML_PRIVATE_EXPORT Runtime {
};
struct Q_QML_PRIVATE_EXPORT RuntimeHelpers {
- static ReturnedValue objectDefaultValue(Object *object, int typeHint);
+ static ReturnedValue objectDefaultValue(const Object *object, int typeHint);
static ReturnedValue toPrimitive(const Value &value, int typeHint);
static double stringToNumber(const QString &s);
@@ -243,7 +244,7 @@ struct Q_QML_PRIVATE_EXPORT RuntimeHelpers {
#ifndef V4_BOOTSTRAP
inline ReturnedValue RuntimeHelpers::toPrimitive(const Value &value, int typeHint)
{
- Object *o = value.asObject();
+ const Object *o = value.as<Object>();
if (!o)
return value.asReturnedValue();
return RuntimeHelpers::objectDefaultValue(o, typeHint);
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 908248f0f0..98ced91b05 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -85,10 +85,7 @@ struct Scope {
#ifndef QT_NO_DEBUG
size += nValues;
#endif
- Value *ptr = engine->jsStackTop;
- engine->jsStackTop = ptr + nValues;
- memset(ptr, 0, nValues*sizeof(Value));
- return ptr;
+ return engine->jsAlloca(nValues);
}
bool hasException() const {
@@ -202,7 +199,7 @@ struct Scoped
{
enum _Convert { Convert };
- inline void setPointer(Managed *p) {
+ inline void setPointer(const Managed *p) {
ptr->m = p ? p->m : 0;
#if QT_POINTER_SIZE == 4
ptr->tag = QV4::Value::Managed_Type;
@@ -225,7 +222,7 @@ struct Scoped
Scoped(const Scope &scope, const Value &v)
{
ptr = scope.engine->jsStackTop++;
- setPointer(value_cast<T>(v));
+ setPointer(v.as<T>());
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -235,7 +232,7 @@ struct Scoped
Value v;
v = o;
ptr = scope.engine->jsStackTop++;
- setPointer(value_cast<T>(v));
+ setPointer(v.as<T>());
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -243,7 +240,7 @@ struct Scoped
Scoped(const Scope &scope, const ScopedValue &v)
{
ptr = scope.engine->jsStackTop++;
- setPointer(value_cast<T>(*v.ptr));
+ setPointer(v.ptr->as<T>());
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -261,7 +258,7 @@ struct Scoped
Scoped(const Scope &scope, const Value *v)
{
ptr = scope.engine->jsStackTop++;
- setPointer(v ? value_cast<T>(*v) : 0);
+ setPointer(v ? v->as<T>() : 0);
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -287,7 +284,7 @@ struct Scoped
Scoped(const Scope &scope, const ReturnedValue &v)
{
ptr = scope.engine->jsStackTop++;
- setPointer(value_cast<T>(QV4::Value::fromReturnedValue(v)));
+ setPointer(QV4::Value::fromReturnedValue(v).as<T>());
#ifndef QT_NO_DEBUG
++scope.size;
#endif
@@ -302,9 +299,7 @@ struct Scoped
}
Scoped<T> &operator=(Heap::Base *o) {
- Value v;
- v = o;
- setPointer(value_cast<T>(v));
+ setPointer(Value::fromHeapObject(o).as<T>());
return *this;
}
Scoped<T> &operator=(typename T::Data *t) {
@@ -312,16 +307,16 @@ struct Scoped
return *this;
}
Scoped<T> &operator=(const Value &v) {
- setPointer(value_cast<T>(v));
+ setPointer(v.as<T>());
return *this;
}
Scoped<T> &operator=(Value *v) {
- setPointer(v ? value_cast<T>(*v) : 0);
+ setPointer(v ? v->as<T>() : 0);
return *this;
}
Scoped<T> &operator=(const ReturnedValue &v) {
- setPointer(value_cast<T>(QV4::Value::fromReturnedValue(v)));
+ setPointer(QV4::Value::fromReturnedValue(v).as<T>());
return *this;
}
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 4fde0e2445..bd5529294c 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -32,7 +32,7 @@
****************************************************************************/
#include "qv4script_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4functionobject_p.h"
#include "qv4function_p.h"
#include "qv4context_p.h"
@@ -122,13 +122,13 @@ Heap::QmlBindingWrapper::QmlBindingWrapper(QV4::ExecutionContext *scope, QV4::Ob
s.engine->popContext();
}
-ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *)
+ReturnedValue QmlBindingWrapper::call(const Managed *that, CallData *)
{
- ExecutionEngine *engine = static_cast<Object *>(that)->engine();
+ ExecutionEngine *engine = static_cast<const Object *>(that)->engine();
CHECK_STACK_LIMITS(engine);
Scope scope(engine);
- QmlBindingWrapper *This = static_cast<QmlBindingWrapper *>(that);
+ const QmlBindingWrapper *This = static_cast<const QmlBindingWrapper *>(that);
if (!This->function())
return QV4::Encode::undefined();
@@ -154,7 +154,7 @@ void QmlBindingWrapper::markObjects(Heap::Base *m, ExecutionEngine *e)
static ReturnedValue signalParameterGetter(QV4::CallContext *ctx, uint parameterIndex)
{
QV4::Scope scope(ctx);
- QV4::Scoped<CallContext> signalEmittingContext(scope, static_cast<Heap::CallContext *>(ctx->d()->parent));
+ QV4::Scoped<CallContext> signalEmittingContext(scope, ctx->d()->parent.cast<Heap::CallContext>());
Q_ASSERT(signalEmittingContext && signalEmittingContext->d()->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext);
return signalEmittingContext->argument(parameterIndex);
}
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index 05a9e45f45..998a2cff72 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -90,8 +90,8 @@ struct QmlBindingWrapper : Heap::FunctionObject {
QmlBindingWrapper(QV4::ExecutionContext *scope, Function *f, QV4::Object *qml);
// Constructor for QML functions and signal handlers, resulting binding wrapper is not callable!
QmlBindingWrapper(QV4::ExecutionContext *scope, QV4::Object *qml);
- Object *qml;
- CallContext *qmlContext;
+ Pointer<Object> qml;
+ Pointer<CallContext> qmlContext;
};
}
@@ -99,15 +99,13 @@ struct QmlBindingWrapper : Heap::FunctionObject {
struct Q_QML_EXPORT QmlBindingWrapper : FunctionObject {
V4_OBJECT2(QmlBindingWrapper, FunctionObject)
- static ReturnedValue call(Managed *that, CallData *);
+ static ReturnedValue call(const Managed *that, CallData *);
static void markObjects(Heap::Base *m, ExecutionEngine *e);
Heap::CallContext *context() const { return d()->qmlContext; }
static Heap::FunctionObject *createQmlCallableForFunction(QQmlContextData *qmlContext, QObject *scopeObject, QV4::Function *runtimeFunction,
const QList<QByteArray> &signalParameters = QList<QByteArray>(), QString *error = 0);
-
-private:
};
struct Q_QML_EXPORT Script {
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index f1f546bece..cd66f2942b 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -175,7 +175,7 @@ template <> QUrl convertValueToElement(const Value &value)
template <> QModelIndex convertValueToElement(const Value &value)
{
- const QQmlValueTypeWrapper *v = value_cast<QQmlValueTypeWrapper>(value);
+ const QQmlValueTypeWrapper *v = value.as<QQmlValueTypeWrapper>();
if (v)
return v->toVariant().toModelIndex();
return QModelIndex();
@@ -183,7 +183,7 @@ template <> QModelIndex convertValueToElement(const Value &value)
template <> QItemSelectionRange convertValueToElement(const Value &value)
{
- const QQmlValueTypeWrapper *v = value_cast<QQmlValueTypeWrapper>(value);
+ const QQmlValueTypeWrapper *v = value.as<QQmlValueTypeWrapper>();
if (v)
return v->toVariant().value<QItemSelectionRange>();
return QItemSelectionRange();
@@ -231,7 +231,7 @@ public:
defineAccessorProperty(QStringLiteral("length"), method_get_length, method_set_length);
}
- QV4::ReturnedValue containerGetIndexed(uint index, bool *hasProperty)
+ QV4::ReturnedValue containerGetIndexed(uint index, bool *hasProperty) const
{
/* Qt containers have int (rather than uint) allowable indexes. */
if (index > INT_MAX) {
@@ -400,7 +400,7 @@ public:
ScopedCallData callData(scope, 2);
callData->args[0] = convertElementToValue(this->m_ctx->d()->engine, lhs);
callData->args[1] = convertElementToValue(this->m_ctx->d()->engine, rhs);
- callData->thisObject = this->m_ctx->d()->engine->globalObject();
+ callData->thisObject = this->m_ctx->d()->engine->globalObject;
QV4::ScopedValue result(scope, compare->call(callData));
return result->toNumber() < 0;
}
@@ -419,7 +419,7 @@ public:
}
QV4::Scope scope(ctx);
- if (ctx->argc() == 1 && ctx->args()[0].asFunctionObject()) {
+ if (ctx->argc() == 1 && ctx->args()[0].as<FunctionObject>()) {
CompareFunctor cf(ctx, ctx->args()[0]);
std::sort(d()->container.begin(), d()->container.end(), cf);
} else {
@@ -526,8 +526,8 @@ public:
QMetaObject::metacall(d()->object, QMetaObject::WriteProperty, d()->propertyIndex, a);
}
- static QV4::ReturnedValue getIndexed(QV4::Managed *that, uint index, bool *hasProperty)
- { return static_cast<QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty); }
+ static QV4::ReturnedValue getIndexed(const QV4::Managed *that, uint index, bool *hasProperty)
+ { return static_cast<const QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty); }
static void putIndexed(Managed *that, uint index, const QV4::Value &value)
{ static_cast<QQmlSequence<Container> *>(that)->containerPutIndexed(index, value); }
static QV4::PropertyAttributes queryIndexed(const QV4::Managed *that, uint index)
@@ -544,7 +544,7 @@ public:
template <typename Container>
Heap::QQmlSequence<Container>::QQmlSequence(QV4::ExecutionEngine *engine, const Container &container)
- : Heap::Object(engine->emptyClass, engine->sequencePrototype.asObject())
+ : Heap::Object(engine->emptyClass, engine->sequencePrototype())
, container(container)
, propertyIndex(-1)
, isReference(false)
@@ -557,7 +557,7 @@ Heap::QQmlSequence<Container>::QQmlSequence(QV4::ExecutionEngine *engine, const
template <typename Container>
Heap::QQmlSequence<Container>::QQmlSequence(QV4::ExecutionEngine *engine, QObject *object, int propertyIndex)
- : Heap::Object(engine->emptyClass, engine->sequencePrototype.asObject())
+ : Heap::Object(engine->emptyClass, engine->sequencePrototype())
, object(object)
, propertyIndex(propertyIndex)
, isReference(true)
@@ -700,11 +700,11 @@ QVariant SequencePrototype::toVariant(const QV4::Value &array, int typeHint, boo
{
*succeeded = true;
- if (!array.asArrayObject()) {
+ if (!array.as<ArrayObject>()) {
*succeeded = false;
return QVariant();
}
- QV4::Scope scope(array.asObject()->engine());
+ QV4::Scope scope(array.as<Object>()->engine());
QV4::ScopedArrayObject a(scope, array);
FOREACH_QML_SEQUENCE_TYPE(SEQUENCE_TO_VARIANT) { /* else */ *succeeded = false; return QVariant(); }
@@ -717,7 +717,7 @@ QVariant SequencePrototype::toVariant(const QV4::Value &array, int typeHint, boo
return qMetaTypeId<SequenceType>(); \
} else
-int SequencePrototype::metaTypeForSequence(QV4::Object *object)
+int SequencePrototype::metaTypeForSequence(const QV4::Object *object)
{
FOREACH_QML_SEQUENCE_TYPE(MAP_META_TYPE)
/*else*/ {
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index 9949278a89..560c3c27ca 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -48,9 +48,10 @@
#include <QtCore/qglobal.h>
#include <QtCore/qvariant.h>
-#include "qv4value_inl_p.h"
+#include "qv4value_p.h"
#include "qv4object_p.h"
#include "qv4context_p.h"
+#include "qv4string_p.h"
QT_BEGIN_NAMESPACE
@@ -70,7 +71,7 @@ struct SequencePrototype : public QV4::Object
static bool isSequenceType(int sequenceTypeId);
static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
static ReturnedValue fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded);
- static int metaTypeForSequence(Object *object);
+ static int metaTypeForSequence(const Object *object);
static QVariant toVariant(Object *object);
static QVariant toVariant(const Value &array, int typeHint, bool *succeeded);
};
diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp
index e669924d4a..d98c1cc341 100644
--- a/src/qml/jsruntime/qv4serialize.cpp
+++ b/src/qml/jsruntime/qv4serialize.cpp
@@ -37,7 +37,7 @@
#include <private/qqmllistmodel_p.h>
#include <private/qqmllistmodelworkeragent_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4dateobject_p.h>
#include <private/qv4regexpobject_p.h>
#include <private/qv4sequenceobject_p.h>
@@ -168,11 +168,11 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
char *buffer = data.data() + offset;
memcpy(buffer, qstr.constData(), length*sizeof(QChar));
- } else if (v.asFunctionObject()) {
+ } else if (v.as<FunctionObject>()) {
// XXX TODO: Implement passing function objects between the main and
// worker scripts
push(data, valueheader(WorkerUndefined));
- } else if (QV4::ArrayObject *array = v.asArrayObject()) {
+ } else if (const QV4::ArrayObject *array = v.as<ArrayObject>()) {
uint length = array->getLength();
if (length > 0xFFFFFF) {
push(data, valueheader(WorkerUndefined));
@@ -195,11 +195,11 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
reserve(data, sizeof(quint32) + sizeof(double));
push(data, valueheader(WorkerNumber));
push(data, v.asDouble());
- } else if (QV4::DateObject *d = v.asDateObject()) {
+ } else if (const QV4::DateObject *d = v.as<DateObject>()) {
reserve(data, sizeof(quint32) + sizeof(double));
push(data, valueheader(WorkerDate));
- push(data, d->date().asDouble());
- } else if (RegExpObject *re = v.as<RegExpObject>()) {
+ push(data, d->date());
+ } else if (const RegExpObject *re = v.as<RegExpObject>()) {
quint32 flags = re->flags();
QString pattern = re->source();
int length = pattern.length() + 1;
@@ -218,7 +218,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
char *buffer = data.data() + offset;
memcpy(buffer, pattern.constData(), length*sizeof(QChar));
- } else if (QObjectWrapper *qobjectWrapper = v.as<QV4::QObjectWrapper>()) {
+ } else if (const QObjectWrapper *qobjectWrapper = v.as<QV4::QObjectWrapper>()) {
// XXX TODO: Generalize passing objects between the main thread and worker scripts so
// that others can trivially plug in their elements.
QQmlListModel *lm = qobject_cast<QQmlListModel *>(qobjectWrapper->object());
@@ -231,7 +231,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
}
// No other QObject's are allowed to be sent
push(data, valueheader(WorkerUndefined));
- } else if (Object *o = v.asObject()) {
+ } else if (const Object *o = v.as<Object>()) {
if (o->isListType()) {
// valid sequence. we generate a length (sequence length + 1 for the sequence type)
uint seqLength = ScopedValue(scope, o->get(engine->id_length))->toUInt32();
@@ -265,7 +265,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
s = properties->getIndexed(ii);
serialize(data, s, engine);
- QV4::String *str = s->asString();
+ QV4::String *str = s->as<String>();
val = o->get(str);
if (scope.hasException())
scope.engine->catchException();
@@ -356,7 +356,7 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
QVariant var = qVariantFromValue(ref);
QV4::ScopedValue v(scope, scope.engine->fromVariant(var));
QV4::ScopedString s(scope, engine->newString(QStringLiteral("__qml:hidden:ref")));
- rv->asObject()->defineReadonlyProperty(s, v);
+ rv->as<Object>()->defineReadonlyProperty(s, v);
agent->release();
agent->setEngine(engine);
diff --git a/src/qml/jsruntime/qv4serialize_p.h b/src/qml/jsruntime/qv4serialize_p.h
index 06eaffe4c4..d5d48edee7 100644
--- a/src/qml/jsruntime/qv4serialize_p.h
+++ b/src/qml/jsruntime/qv4serialize_p.h
@@ -46,7 +46,7 @@
//
#include <QtCore/qbytearray.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4sparsearray_p.h b/src/qml/jsruntime/qv4sparsearray_p.h
index 861c7dd28d..8496fc32e7 100644
--- a/src/qml/jsruntime/qv4sparsearray_p.h
+++ b/src/qml/jsruntime/qv4sparsearray_p.h
@@ -35,11 +35,7 @@
#define QV4SPARSEARRAY_H
#include "qv4global_p.h"
-#include <QtCore/qmap.h>
-#include "qv4value_inl_p.h"
-#include "qv4scopedvalue_p.h"
-#include "qv4property_p.h"
-#include <assert.h>
+#include <QtCore/qlist.h>
//#define Q_MAP_DEBUG
#ifdef Q_MAP_DEBUG
@@ -188,7 +184,7 @@ public:
typedef qptrdiff difference_type;
typedef int size_type;
-#ifndef QT_NO_DEBUG
+#ifdef Q_MAP_DEBUG
void dump() const;
#endif
};
@@ -261,7 +257,7 @@ inline void SparseArray::push_back(uint index, uint len)
n->value = index;
}
-#ifndef QT_NO_DEBUG
+#ifdef Q_MAP_DEBUG
inline void SparseArray::dump() const
{
const SparseArrayNode *it = begin();
@@ -344,4 +340,4 @@ inline SparseArrayNode *SparseArray::upperBound(uint akey)
QT_END_NAMESPACE
-#endif // QMAP_H
+#endif
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 20dd84420c..cf013121b1 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -32,7 +32,7 @@
****************************************************************************/
#include "qv4string_p.h"
-#include "qv4value_inl_p.h"
+#include "qv4value_p.h"
#ifndef V4_BOOTSTRAP
#include "qv4identifiertable_p.h"
#include "qv4runtime_p.h"
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 5a0c83b4b9..b133f68b20 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -184,6 +184,20 @@ public:
static uint toArrayIndex(const QString &str);
};
+template<>
+inline const String *Value::as() const {
+ return isManaged() && m && m->vtable->isString ? static_cast<const String *>(this) : 0;
+}
+
+#ifndef V4_BOOTSTRAP
+template<>
+inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
+{
+ return v.toString(e)->asReturnedValue();
+}
+#endif
+
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index e0b84f6da3..bbdc96f0f1 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -36,7 +36,7 @@
#include "qv4regexp_p.h"
#include "qv4regexpobject_p.h"
#include "qv4objectproto_p.h"
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#include "qv4scopedvalue_p.h"
#include "qv4alloca_p.h"
#include <QtCore/QDateTime>
@@ -80,7 +80,7 @@ Heap::StringObject::StringObject(InternalClass *ic, QV4::Object *prototype)
}
Heap::StringObject::StringObject(ExecutionEngine *engine, const Value &val)
- : Heap::Object(engine->emptyClass, engine->stringPrototype.asObject())
+ : Heap::Object(engine->emptyClass, engine->stringPrototype())
{
value = val;
Q_ASSERT(value.isString());
@@ -104,7 +104,7 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index)
{
ExecutionEngine *v4 = static_cast<StringObject *>(m)->engine();
Scope scope(v4);
- Scoped<StringObject> o(scope, m->asStringObject());
+ Scoped<StringObject> o(scope, m->as<StringObject>());
Q_ASSERT(!!o);
if (index < static_cast<uint>(o->d()->value.stringValue()->toQString().length())) {
@@ -158,9 +158,9 @@ Heap::StringCtor::StringCtor(QV4::ExecutionContext *scope)
{
}
-ReturnedValue StringCtor::construct(Managed *m, CallData *callData)
+ReturnedValue StringCtor::construct(const Managed *m, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<Object *>(m)->engine();
+ ExecutionEngine *v4 = static_cast<const Object *>(m)->engine();
Scope scope(v4);
ScopedValue value(scope);
if (callData->argc)
@@ -170,9 +170,9 @@ ReturnedValue StringCtor::construct(Managed *m, CallData *callData)
return Encode(v4->newStringObject(value));
}
-ReturnedValue StringCtor::call(Managed *m, CallData *callData)
+ReturnedValue StringCtor::call(const Managed *m, CallData *callData)
{
- ExecutionEngine *v4 = static_cast<Object *>(m)->engine();
+ ExecutionEngine *v4 = static_cast<const Object *>(m)->engine();
Scope scope(v4);
ScopedValue value(scope);
if (callData->argc)
@@ -220,7 +220,7 @@ static QString getThisString(ExecutionContext *ctx)
ScopedValue t(scope, ctx->thisObject());
if (t->isString())
return t->stringValue()->toQString();
- if (StringObject *thisString = t->asStringObject())
+ if (StringObject *thisString = t->as<StringObject>())
return thisString->d()->value.stringValue()->toQString();
if (t->isUndefined() || t->isNull()) {
scope.engine->throwTypeError();
@@ -234,7 +234,7 @@ ReturnedValue StringPrototype::method_toString(CallContext *context)
if (context->thisObject().isString())
return context->thisObject().asReturnedValue();
- StringObject *o = context->thisObject().asStringObject();
+ StringObject *o = context->thisObject().as<StringObject>();
if (!o)
return context->engine()->throwTypeError();
return o->d()->value.asReturnedValue();
@@ -368,7 +368,7 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
if (!rx) {
ScopedCallData callData(scope, 1);
callData->args[0] = regexp;
- rx = context->d()->engine->regExpCtor.asFunctionObject()->construct(callData);
+ rx = context->d()->engine->regExpCtor()->construct(callData);
}
if (!rx)
@@ -379,7 +379,7 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
// ### use the standard builtin function, not the one that might be redefined in the proto
ScopedString execString(scope, scope.engine->newString(QStringLiteral("exec")));
- ScopedFunctionObject exec(scope, scope.engine->regExpPrototype.asObject()->get(execString));
+ ScopedFunctionObject exec(scope, scope.engine->regExpPrototype()->get(execString));
ScopedCallData callData(scope, 1);
callData->thisObject = rx;
@@ -470,7 +470,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
{
Scope scope(ctx);
QString string;
- if (StringObject *thisString = ctx->thisObject().asStringObject())
+ if (StringObject *thisString = ctx->thisObject().as<StringObject>())
string = thisString->d()->value.stringValue()->toQString();
else
string = ctx->thisObject().toQString();
@@ -593,7 +593,7 @@ ReturnedValue StringPrototype::method_search(CallContext *ctx)
if (!regExp) {
ScopedCallData callData(scope, 1);
callData->args[0] = regExpValue;
- regExpValue = ctx->d()->engine->regExpCtor.asFunctionObject()->construct(callData);
+ regExpValue = ctx->d()->engine->regExpCtor()->construct(callData);
if (scope.engine->hasException)
return Encode::undefined();
regExp = regExpValue->as<RegExpObject>();
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index 459dc1322e..b0f2dd3e97 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -78,8 +78,8 @@ struct StringCtor: FunctionObject
{
V4_OBJECT2(StringCtor, FunctionObject)
- static ReturnedValue construct(Managed *m, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
struct StringPrototype: StringObject
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 429ec96f0b..d93b57e472 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -32,6 +32,7 @@
****************************************************************************/
#include "qv4typedarray_p.h"
#include "qv4arraybuffer_p.h"
+#include "qv4string_p.h"
#include <cmath>
@@ -201,10 +202,10 @@ Heap::TypedArrayCtor::TypedArrayCtor(QV4::ExecutionContext *scope, TypedArray::T
{
}
-ReturnedValue TypedArrayCtor::construct(Managed *m, CallData *callData)
+ReturnedValue TypedArrayCtor::construct(const Managed *m, CallData *callData)
{
- Scope scope(static_cast<Object *>(m)->engine());
- Scoped<TypedArrayCtor> that(scope, static_cast<TypedArrayCtor *>(m));
+ Scope scope(static_cast<const Object *>(m)->engine());
+ Scoped<TypedArrayCtor> that(scope, static_cast<const TypedArrayCtor *>(m));
if (!callData->argc || !callData->args[0].isObject()) {
// ECMA 6 22.2.1.1
@@ -329,13 +330,13 @@ ReturnedValue TypedArrayCtor::construct(Managed *m, CallData *callData)
return array.asReturnedValue();
}
-ReturnedValue TypedArrayCtor::call(Managed *that, CallData *callData)
+ReturnedValue TypedArrayCtor::call(const Managed *that, CallData *callData)
{
return construct(that, callData);
}
Heap::TypedArray::TypedArray(ExecutionEngine *e, Type t)
- : Heap::Object(e->emptyClass, e->typedArrayPrototype[t].asObject()),
+ : Heap::Object(e->emptyClass, e->typedArrayPrototype + t),
type(operations + t),
arrayType(t)
{
@@ -347,10 +348,10 @@ void TypedArray::markObjects(Heap::Base *that, ExecutionEngine *e)
Object::markObjects(that, e);
}
-ReturnedValue TypedArray::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue TypedArray::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
- Scope scope(static_cast<Object *>(m)->engine());
- Scoped<TypedArray> a(scope, static_cast<TypedArray *>(m));
+ Scope scope(static_cast<const Object *>(m)->engine());
+ Scoped<TypedArray> a(scope, static_cast<const TypedArray *>(m));
uint bytesPerElement = a->d()->type->bytesPerElement;
uint byteOffset = a->d()->byteOffset + index * bytesPerElement;
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index afd1bb97e7..8e1090dcd2 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -72,7 +72,7 @@ struct TypedArray : Object {
TypedArray(ExecutionEngine *e, Type t);
const TypedArrayOperations *type;
- ArrayBuffer *buffer;
+ Pointer<ArrayBuffer> buffer;
uint byteLength;
uint byteOffset;
Type arrayType;
@@ -113,7 +113,7 @@ struct Q_QML_PRIVATE_EXPORT TypedArray : Object
}
static void markObjects(Heap::Base *that, ExecutionEngine *e);
- static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
static void putIndexed(Managed *m, uint index, const Value &value);
};
@@ -121,8 +121,8 @@ struct TypedArrayCtor: FunctionObject
{
V4_OBJECT2(TypedArrayCtor, FunctionObject)
- static ReturnedValue construct(Managed *m, CallData *callData);
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue construct(const Managed *m, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
};
diff --git a/src/qml/qml/qqmlabstractexpression.cpp b/src/qml/jsruntime/qv4typedvalue_p.h
index c55c86952c..50b5a4db81 100644
--- a/src/qml/qml/qqmlabstractexpression.cpp
+++ b/src/qml/jsruntime/qv4typedvalue_p.h
@@ -30,64 +30,46 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef QV4TYPEDVALUE_H
+#define QV4TYPEDVALUE_H
-#include "qqmlabstractexpression_p.h"
+#include "qv4value_p.h"
QT_BEGIN_NAMESPACE
-QQmlAbstractExpression::QQmlAbstractExpression()
-: m_prevExpression(0), m_nextExpression(0)
-{
-}
+namespace QV4 {
-QQmlAbstractExpression::~QQmlAbstractExpression()
+template <typename T>
+struct TypedValue : public Value
{
- if (m_prevExpression) {
- *m_prevExpression = m_nextExpression;
- if (m_nextExpression)
- m_nextExpression->m_prevExpression = m_prevExpression;
+ template<typename X>
+ TypedValue &operator =(X *x) {
+ m = x;
+#if QT_POINTER_SIZE == 4
+ tag = Managed_Type;
+#endif
+ return *this;
}
+ TypedValue &operator =(T *t);
+ TypedValue &operator =(const Scoped<T> &v);
+// TypedValue &operator =(const ManagedRef<T> &v);
- if (m_context.isT2())
- m_context.asT2()->_s = 0;
-}
-
-QQmlContextData *QQmlAbstractExpression::context() const
-{
- if (m_context.isT1()) return m_context.asT1();
- else return m_context.asT2()->_c;
-}
+ TypedValue &operator =(const TypedValue<T> &t);
-void QQmlAbstractExpression::setContext(QQmlContextData *context)
-{
- if (m_prevExpression) {
- *m_prevExpression = m_nextExpression;
- if (m_nextExpression)
- m_nextExpression->m_prevExpression = m_prevExpression;
- m_prevExpression = 0;
- m_nextExpression = 0;
- }
+ bool operator!() const { return !managed(); }
- if (m_context.isT1()) m_context = context;
- else m_context.asT2()->_c = context;
+ operator T *() { return static_cast<T *>(managed()); }
+ T *operator->() { return static_cast<T *>(managed()); }
+ const T *operator->() const { return static_cast<T *>(managed()); }
+ T *getPointer() const { return static_cast<T *>(managed()); }
- if (context) {
- m_nextExpression = context->expressions;
- if (m_nextExpression)
- m_nextExpression->m_prevExpression = &m_nextExpression;
- m_prevExpression = &context->expressions;
- context->expressions = this;
- }
-}
+ void mark(ExecutionEngine *e) { if (managed()) managed()->mark(e); }
+};
+typedef TypedValue<String> StringValue;
-void QQmlAbstractExpression::refresh()
-{
-}
-bool QQmlAbstractExpression::isValid() const
-{
- return context() != 0;
-}
+} // namespace QV4
QT_END_NAMESPACE
+#endif
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index 68228f06bb..d659d02c3b 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -32,10 +32,11 @@
****************************************************************************/
#include <qv4engine_p.h>
#include <qv4runtime_p.h>
+#include <qv4string_p.h>
#ifndef V4_BOOTSTRAP
#include <qv4object_p.h>
#include <qv4objectproto_p.h>
-#include "qv4mm_p.h"
+#include <private/qv4mm_p.h>
#endif
#include <wtf/MathExtras.h>
@@ -68,6 +69,28 @@ int Value::toUInt16() const
return (unsigned short)number;
}
+bool Value::toBoolean() const
+{
+ switch (type()) {
+ case Value::Undefined_Type:
+ case Value::Null_Type:
+ return false;
+ case Value::Boolean_Type:
+ case Value::Integer_Type:
+ return (bool)int_32;
+ case Value::Managed_Type:
+#ifdef V4_BOOTSTRAP
+ Q_UNIMPLEMENTED();
+#else
+ if (isString())
+ return stringValue()->toQString().length() > 0;
+#endif
+ return true;
+ default: // double
+ return doubleValue() && !std::isnan(doubleValue());
+ }
+}
+
double Value::toInteger() const
{
if (integerCompatible())
@@ -87,10 +110,10 @@ double Value::toNumberImpl() const
#else
if (isString())
return RuntimeHelpers::stringToNumber(stringValue()->toQString());
- {
- Q_ASSERT(isObject());
- Scope scope(objectValue()->engine());
- ScopedValue prim(scope, RuntimeHelpers::toPrimitive(*this, NUMBER_HINT));
+ {
+ Q_ASSERT(isObject());
+ Scope scope(objectValue()->engine());
+ ScopedValue prim(scope, RuntimeHelpers::toPrimitive(*this, NUMBER_HINT));
if (scope.engine->hasException)
return 0;
return prim->toNumber();
@@ -281,4 +304,35 @@ Heap::Object *Value::toObject(ExecutionEngine *e) const
return RuntimeHelpers::convertToObject(e, *this);
}
+uint Value::asArrayLength(bool *ok) const
+{
+ *ok = true;
+ if (isInteger()) {
+ if (int_32 >= 0) {
+ return (uint)int_32;
+ } else {
+ *ok = false;
+ return UINT_MAX;
+ }
+ }
+ if (isNumber()) {
+ double d = doubleValue();
+ uint idx = (uint)d;
+ if (idx != d) {
+ *ok = false;
+ return UINT_MAX;
+ }
+ return idx;
+ }
+ if (isString())
+ return stringValue()->toUInt(ok);
+
+ uint idx = toUInt32();
+ double d = toNumber();
+ if (d != idx) {
+ *ok = false;
+ return UINT_MAX;
+ }
+ return idx;
+}
#endif // V4_BOOTSTRAP
diff --git a/src/qml/jsruntime/qv4value_inl_p.h b/src/qml/jsruntime/qv4value_inl_p.h
deleted file mode 100644
index 3a4c5c4822..0000000000
--- a/src/qml/jsruntime/qv4value_inl_p.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QV4VALUE_INL_H
-#define QV4VALUE_INL_H
-
-#include <cmath> // this HAS to come
-
-#include "qv4value_p.h"
-
-#include "qv4string_p.h"
-#include "qv4managed_p.h"
-#include "qv4engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-
-inline bool Value::isString() const
-{
- if (!isManaged())
- return false;
- return m && m->vtable->isString;
-}
-inline bool Value::isObject() const
-{
- if (!isManaged())
- return false;
- return m && m->vtable->isObject;
-}
-
-inline bool Value::isPrimitive() const
-{
- return !isObject();
-}
-
-inline String *Value::asString() const
-{
- if (isString())
- return stringValue();
- return 0;
-}
-
-inline void Value::mark(ExecutionEngine *e) const
-{
- if (!val)
- return;
- Managed *m = asManaged();
- if (m)
- m->mark(e);
-}
-
-inline Primitive Primitive::nullValue()
-{
- Primitive v;
-#if QT_POINTER_SIZE == 8
- v.val = quint64(_Null_Type) << Tag_Shift;
-#else
- v.tag = _Null_Type;
- v.int_32 = 0;
-#endif
- return v;
-}
-
-inline Primitive Primitive::fromBoolean(bool b)
-{
- Primitive v;
- v.tag = _Boolean_Type;
- v.int_32 = (bool)b;
- return v;
-}
-
-inline Primitive Primitive::fromDouble(double d)
-{
- Primitive v;
- v.setDouble(d);
- return v;
-}
-
-inline Primitive Primitive::fromInt32(int i)
-{
- Primitive v;
- v.tag = _Integer_Type;
- v.int_32 = i;
- return v;
-}
-
-inline Primitive Primitive::fromUInt32(uint i)
-{
- Primitive v;
- if (i < INT_MAX) {
- v.tag = _Integer_Type;
- v.int_32 = (int)i;
- } else {
- v.setDouble(i);
- }
- return v;
-}
-
-inline double Value::toNumber() const
-{
- if (isInteger())
- return int_32;
- if (isDouble())
- return doubleValue();
- return toNumberImpl();
-}
-
-inline int Value::toInt32() const
-{
- if (isInteger())
- return int_32;
- double d = isNumber() ? doubleValue() : toNumberImpl();
-
- const double D32 = 4294967296.0;
- const double D31 = D32 / 2.0;
-
- if ((d >= -D31 && d < D31))
- return static_cast<int>(d);
-
- return Primitive::toInt32(d);
-}
-
-inline unsigned int Value::toUInt32() const
-{
- return (unsigned int)toInt32();
-}
-
-
-inline bool Value::toBoolean() const
-{
- switch (type()) {
- case Value::Undefined_Type:
- case Value::Null_Type:
- return false;
- case Value::Boolean_Type:
- case Value::Integer_Type:
- return (bool)int_32;
- case Value::Managed_Type:
-#ifdef V4_BOOTSTRAP
- Q_UNIMPLEMENTED();
-#else
- if (isString())
- return stringValue()->toQString().length() > 0;
-#endif
- return true;
- default: // double
- return doubleValue() && !std::isnan(doubleValue());
- }
-}
-
-#ifndef V4_BOOTSTRAP
-inline uint Value::asArrayIndex() const
-{
-#if QT_POINTER_SIZE == 8
- if (!isNumber())
- return UINT_MAX;
- if (isInteger())
- return int_32 >= 0 ? (uint)int_32 : UINT_MAX;
-#else
- if (isInteger() && int_32 >= 0)
- return (uint)int_32;
- if (!isDouble())
- return UINT_MAX;
-#endif
- double d = doubleValue();
- uint idx = (uint)d;
- if (idx != d)
- return UINT_MAX;
- return idx;
-}
-
-inline uint Value::asArrayLength(bool *ok) const
-{
- *ok = true;
- if (isInteger()) {
- if (int_32 >= 0) {
- return (uint)int_32;
- } else {
- *ok = false;
- return UINT_MAX;
- }
- }
- if (isNumber()) {
- double d = doubleValue();
- uint idx = (uint)d;
- if (idx != d) {
- *ok = false;
- return UINT_MAX;
- }
- return idx;
- }
- if (isString())
- return stringValue()->toUInt(ok);
-
- uint idx = toUInt32();
- double d = toNumber();
- if (d != idx) {
- *ok = false;
- return UINT_MAX;
- }
- return idx;
-}
-
-inline Object *Value::asObject() const
-{
- return isObject() ? objectValue() : 0;
-}
-
-inline FunctionObject *Value::asFunctionObject() const
-{
- return isObject() ? managed()->asFunctionObject() : 0;
-}
-
-inline NumberObject *Value::asNumberObject() const
-{
- return isObject() ? managed()->asNumberObject() : 0;
-}
-
-inline StringObject *Value::asStringObject() const
-{
- return isObject() ? managed()->asStringObject() : 0;
-}
-
-inline DateObject *Value::asDateObject() const
-{
- return isObject() ? managed()->asDateObject() : 0;
-}
-
-inline ArrayObject *Value::asArrayObject() const
-{
- return isObject() ? managed()->asArrayObject() : 0;
-}
-
-inline ErrorObject *Value::asErrorObject() const
-{
- return isObject() ? managed()->asErrorObject() : 0;
-}
-
-template<typename T>
-inline T *Value::as() const { Managed *m = isObject() ? managed() : 0; return m ? m->as<T>() : 0; }
-
-#ifndef V4_BOOTSTRAP
-
-template<>
-inline String *value_cast(const Value &v) {
- return v.asString();
-}
-
-template<>
-inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
-{
- return v.toString(e)->asReturnedValue();
-}
-
-#endif
-
-#endif
-
-} // namespace QV4
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index cd1aef86d7..7454cbfff4 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -37,61 +37,18 @@
#include <QtCore/QString>
#include "qv4global_p.h"
+#include <private/qv4heap_p.h>
QT_BEGIN_NAMESPACE
namespace QV4 {
-typedef uint Bool;
-
namespace Heap {
-
-struct Q_QML_EXPORT Base {
- union {
- const ManagedVTable *vtable;
- quintptr mm_data;
- };
-
- inline ReturnedValue asReturnedValue() const;
- inline void mark(QV4::ExecutionEngine *engine);
-
- enum {
- MarkBit = 0x1,
- NotInUse = 0x2,
- PointerMask = ~0x3
- };
-
- ManagedVTable *gcGetVtable() const {
- return reinterpret_cast<ManagedVTable *>(mm_data & PointerMask);
- }
- inline bool isMarked() const {
- return mm_data & MarkBit;
- }
- inline void setMarkBit() {
- mm_data |= MarkBit;
- }
- inline void clearMarkBit() {
- mm_data &= ~MarkBit;
- }
-
- inline bool inUse() const {
- return !(mm_data & NotInUse);
- }
-
- Base *nextFree() {
- return reinterpret_cast<Base *>(mm_data & PointerMask);
- }
- void setNextFree(Base *m) {
- mm_data = (reinterpret_cast<quintptr>(m) | NotInUse);
- }
-
- void *operator new(size_t, Managed *m) { return m; }
- void *operator new(size_t, Heap::Base *m) { return m; }
- void operator delete(void *, Heap::Base *) {}
-};
-
+ struct Base;
}
+typedef uint Bool;
+
struct Q_QML_PRIVATE_EXPORT Value
{
/*
@@ -326,13 +283,11 @@ struct Q_QML_PRIVATE_EXPORT Value
return v;
}
- static inline Value fromManaged(Managed *m);
-
int toUInt16() const;
inline int toInt32() const;
inline unsigned int toUInt32() const;
- inline bool toBoolean() const;
+ bool toBoolean() const;
double toInteger() const;
inline double toNumber() const;
double toNumberImpl() const;
@@ -349,17 +304,28 @@ struct Q_QML_PRIVATE_EXPORT Value
return b;
}
- inline String *asString() const;
- inline Managed *asManaged() const;
- inline Object *asObject() const;
- inline FunctionObject *asFunctionObject() const;
- inline NumberObject *asNumberObject() const;
- inline StringObject *asStringObject() const;
- inline DateObject *asDateObject() const;
- inline ArrayObject *asArrayObject() const;
- inline ErrorObject *asErrorObject() const;
+ template <typename T>
+ const T *as() const {
+ if (!m || !isManaged())
+ return 0;
+
+ Q_ASSERT(m->vtable);
+#if !defined(QT_NO_QOBJECT_CHECK)
+ static_cast<const T *>(this)->qt_check_for_QMANAGED_macro(static_cast<const T *>(this));
+#endif
+ const VTable *vt = m->vtable;
+ while (vt) {
+ if (vt == T::staticVTable())
+ return static_cast<const T *>(this);
+ vt = vt->parent;
+ }
+ return 0;
+ }
+ template <typename T>
+ T *as() {
+ return const_cast<T *>(const_cast<const Value *>(this)->as<T>());
+ }
- template<typename T> inline T *as() const;
template<typename T> inline T *cast() {
return static_cast<T *>(managed());
}
@@ -368,7 +334,9 @@ struct Q_QML_PRIVATE_EXPORT Value
}
inline uint asArrayIndex() const;
- inline uint asArrayLength(bool *ok) const;
+#ifndef V4_BOOTSTRAP
+ uint asArrayLength(bool *ok) const;
+#endif
ReturnedValue asReturnedValue() const { return val; }
static Value fromReturnedValue(ReturnedValue val) { Value v; v.val = val; return v; }
@@ -376,12 +344,17 @@ struct Q_QML_PRIVATE_EXPORT Value
// Section 9.12
bool sameValue(Value other) const;
- inline void mark(ExecutionEngine *e) const;
+ inline void mark(ExecutionEngine *e);
Value &operator =(const ScopedValue &v);
Value &operator=(ReturnedValue v) { val = v; return *this; }
Value &operator=(Managed *m) {
- val = Value::fromManaged(m).val;
+ if (!m) {
+ tag = Undefined_Type;
+ uint_32 = 0;
+ } else {
+ val = reinterpret_cast<Value *>(m)->val;
+ }
return *this;
}
Value &operator=(Heap::Base *o) {
@@ -400,13 +373,64 @@ struct Q_QML_PRIVATE_EXPORT Value
}
};
-inline Managed *Value::asManaged() const
+inline bool Value::isString() const
+{
+ if (!isManaged())
+ return false;
+ return m && m->vtable->isString;
+}
+inline bool Value::isObject() const
+{
+ if (!isManaged())
+ return false;
+ return m && m->vtable->isObject;
+}
+
+inline bool Value::isPrimitive() const
+{
+ return !isObject();
+}
+
+inline double Value::toNumber() const
+{
+ if (isInteger())
+ return int_32;
+ if (isDouble())
+ return doubleValue();
+ return toNumberImpl();
+}
+
+
+#ifndef V4_BOOTSTRAP
+inline uint Value::asArrayIndex() const
+{
+#if QT_POINTER_SIZE == 8
+ if (!isNumber())
+ return UINT_MAX;
+ if (isInteger())
+ return int_32 >= 0 ? (uint)int_32 : UINT_MAX;
+#else
+ if (isInteger() && int_32 >= 0)
+ return (uint)int_32;
+ if (!isDouble())
+ return UINT_MAX;
+#endif
+ double d = doubleValue();
+ uint idx = (uint)d;
+ if (idx != d)
+ return UINT_MAX;
+ return idx;
+}
+#endif
+
+inline
+ReturnedValue Heap::Base::asReturnedValue() const
{
- if (isManaged())
- return managed();
- return 0;
+ return Value::fromHeapObject(const_cast<Heap::Base *>(this)).asReturnedValue();
}
+
+
struct Q_QML_PRIVATE_EXPORT Primitive : public Value
{
inline static Primitive emptyValue();
@@ -445,34 +469,52 @@ inline Primitive Primitive::emptyValue()
return v;
}
-template <typename T>
-struct TypedValue : public Value
+inline Primitive Primitive::nullValue()
{
- template<typename X>
- TypedValue &operator =(X *x) {
- m = x;
-#if QT_POINTER_SIZE == 4
- tag = Managed_Type;
+ Primitive v;
+#if QT_POINTER_SIZE == 8
+ v.val = quint64(_Null_Type) << Tag_Shift;
+#else
+ v.tag = _Null_Type;
+ v.int_32 = 0;
#endif
- return *this;
- }
- TypedValue &operator =(T *t);
- TypedValue &operator =(const Scoped<T> &v);
-// TypedValue &operator =(const ManagedRef<T> &v);
-
- TypedValue &operator =(const TypedValue<T> &t);
+ return v;
+}
- bool operator!() const { return !managed(); }
+inline Primitive Primitive::fromBoolean(bool b)
+{
+ Primitive v;
+ v.tag = _Boolean_Type;
+ v.int_32 = (bool)b;
+ return v;
+}
- operator T *() { return static_cast<T *>(managed()); }
- T *operator->() { return static_cast<T *>(managed()); }
- const T *operator->() const { return static_cast<T *>(managed()); }
- T *getPointer() const { return static_cast<T *>(managed()); }
+inline Primitive Primitive::fromDouble(double d)
+{
+ Primitive v;
+ v.setDouble(d);
+ return v;
+}
- void mark(ExecutionEngine *e) { if (managed()) managed()->mark(e); }
-};
-typedef TypedValue<String> StringValue;
+inline Primitive Primitive::fromInt32(int i)
+{
+ Primitive v;
+ v.tag = _Integer_Type;
+ v.int_32 = i;
+ return v;
+}
+inline Primitive Primitive::fromUInt32(uint i)
+{
+ Primitive v;
+ if (i < INT_MAX) {
+ v.tag = _Integer_Type;
+ v.int_32 = (int)i;
+ } else {
+ v.setDouble(i);
+ }
+ return v;
+}
struct Encode {
static ReturnedValue undefined() {
@@ -519,21 +561,29 @@ private:
Encode(void *);
};
-inline
-ReturnedValue Heap::Base::asReturnedValue() const
+template<typename T>
+ReturnedValue value_convert(ExecutionEngine *e, const Value &v);
+
+inline int Value::toInt32() const
{
- return Value::fromHeapObject(const_cast<Heap::Base *>(this)).asReturnedValue();
-}
+ if (isInteger())
+ return int_32;
+ double d = isNumber() ? doubleValue() : toNumberImpl();
+ const double D32 = 4294967296.0;
+ const double D31 = D32 / 2.0;
-template<typename T>
-T *value_cast(const Value &v)
+ if ((d >= -D31 && d < D31))
+ return static_cast<int>(d);
+
+ return Primitive::toInt32(d);
+}
+
+inline unsigned int Value::toUInt32() const
{
- return v.as<T>();
+ return (unsigned int)toInt32();
}
-template<typename T>
-ReturnedValue value_convert(ExecutionEngine *e, const Value &v);
}
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index 966f83acef..cd82159082 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -44,7 +44,7 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(VariantObject);
Heap::VariantObject::VariantObject(QV4::ExecutionEngine *engine, const QVariant &value)
- : Heap::Object(engine->emptyClass, engine->variantPrototype.asObject())
+ : Heap::Object(engine->emptyClass, engine->variantPrototype())
{
data = value;
if (isScarce())
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index 2b48412c4d..b19f12bb98 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -49,7 +49,7 @@
#include <QtQml/qqmllist.h>
#include <QtCore/qvariant.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index dda5848f0b..761e377f75 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -37,13 +37,14 @@
#include <QtCore/qjsondocument.h>
#include <QtCore/qjsonobject.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4debugging_p.h>
#include <private/qv4function_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4math_p.h>
#include <private/qv4scopedvalue_p.h>
#include <private/qv4lookup_p.h>
+#include <private/qv4string_p.h>
#include <iostream>
#include "qv4alloca_p.h"
@@ -858,7 +859,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code
engine->currentContext()->lineNumber = instr.lineNumber;
if (qt_v4IsDebugging)
qt_v4CheckForBreak(context, scopes, scopeDepth);
- MOTH_END_INSTR(Debug)
+ MOTH_END_INSTR(Line)
MOTH_BEGIN_INSTR(LoadThis)
VALUE(instr.result) = context->thisObject();
diff --git a/src/qml/memory/memory.pri b/src/qml/memory/memory.pri
new file mode 100644
index 0000000000..04b7566ccc
--- /dev/null
+++ b/src/qml/memory/memory.pri
@@ -0,0 +1,14 @@
+INCLUDEPATH += $$PWD
+INCLUDEPATH += $$OUT_PWD
+
+!qmldevtools_build {
+SOURCES += \
+ $$PWD/qv4mm.cpp \
+
+HEADERS += \
+ $$PWD/qv4mm_p.h
+
+}
+
+HEADERS += \
+ $$PWD/qv4heap_p.h
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
new file mode 100644
index 0000000000..606fd47cbb
--- /dev/null
+++ b/src/qml/memory/qv4heap_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4HEAP_P_H
+#define QV4HEAP_P_H
+
+#include <QtCore/QString>
+#include <private/qv4global_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+struct VTable
+{
+ const VTable * const parent;
+ uint isExecutionContext : 1;
+ uint isString : 1;
+ uint isObject : 1;
+ uint isFunctionObject : 1;
+ uint isErrorObject : 1;
+ uint isArrayData : 1;
+ uint unused : 18;
+ uint type : 8;
+ const char *className;
+ void (*destroy)(Heap::Base *);
+ void (*markObjects)(Heap::Base *, ExecutionEngine *e);
+ bool (*isEqualTo)(Managed *m, Managed *other);
+};
+
+namespace Heap {
+
+struct Q_QML_EXPORT Base {
+ union {
+ const VTable *vtable;
+ quintptr mm_data;
+ };
+
+ inline ReturnedValue asReturnedValue() const;
+ inline void mark(QV4::ExecutionEngine *engine);
+
+ enum {
+ MarkBit = 0x1,
+ NotInUse = 0x2,
+ PointerMask = ~0x3
+ };
+
+ VTable *gcGetVtable() const {
+ return reinterpret_cast<VTable *>(mm_data & PointerMask);
+ }
+ inline bool isMarked() const {
+ return mm_data & MarkBit;
+ }
+ inline void setMarkBit() {
+ mm_data |= MarkBit;
+ }
+ inline void clearMarkBit() {
+ mm_data &= ~MarkBit;
+ }
+
+ inline bool inUse() const {
+ return !(mm_data & NotInUse);
+ }
+
+ Base *nextFree() {
+ return reinterpret_cast<Base *>(mm_data & PointerMask);
+ }
+ void setNextFree(Base *m) {
+ mm_data = (reinterpret_cast<quintptr>(m) | NotInUse);
+ }
+
+ void *operator new(size_t, Managed *m) { return m; }
+ void *operator new(size_t, Heap::Base *m) { return m; }
+ void operator delete(void *, Heap::Base *) {}
+};
+
+template <typename T>
+struct Pointer {
+ Pointer() {}
+ Pointer(T *t) : ptr(t) {}
+
+ T *operator->() const { return ptr; }
+ operator T *() const { return ptr; }
+
+ Pointer &operator =(T *t) { ptr = t; return *this; }
+
+ template <typename Type>
+ Type *cast() { return static_cast<Type *>(ptr); }
+
+ T *ptr;
+};
+
+}
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index d5576b400a..7dbf12ff11 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -381,7 +381,7 @@ void MemoryManager::sweep(bool lastSweep)
{
if (m_weakValues) {
for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) {
- if (Managed *m = (*it).asManaged()) {
+ if (Managed *m = (*it).as<Managed>()) {
if (!m->markBit())
(*it) = Primitive::undefinedValue();
}
@@ -525,7 +525,7 @@ void MemoryManager::runGC()
size_t MemoryManager::getUsedMem() const
{
size_t usedMem = 0;
- for (QVector<PageAllocation>::const_iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i) {
+ for (QVector<PageAllocation>::const_iterator i = m_d->heapChunks.cbegin(), ei = m_d->heapChunks.cend(); i != ei; ++i) {
Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(i->base());
for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) {
Heap::Base *m = reinterpret_cast<Heap::Base *>(item);
@@ -607,7 +607,7 @@ void MemoryManager::collectFromJSStack() const
Value *v = m_d->engine->jsStackBase;
Value *top = m_d->engine->jsStackTop;
while (v < top) {
- Managed *m = v->asManaged();
+ Managed *m = v->as<Managed>();
if (m && m->inUse())
// Skip pointers to already freed objects, they are bogus as well
m->mark(m_d->engine);
diff --git a/src/qml/jsruntime/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index 00b41b796a..422809ba54 100644
--- a/src/qml/jsruntime/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -34,9 +34,9 @@
#ifndef QV4GC_H
#define QV4GC_H
-#include "qv4global_p.h"
-#include "qv4value_inl_p.h"
-#include "qv4scopedvalue_p.h"
+#include <private/qv4global_p.h>
+#include <private/qv4value_p.h>
+#include <private/qv4scopedvalue_p.h>
//#define DETAILED_MM_STATS
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index 6e06fb42ef..d75262bf0b 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -8,6 +8,9 @@ win32-msvc*:DEFINES *= _CRT_SECURE_NO_WARNINGS
win32:!wince*:!winrt:LIBS += -lshell32
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
+# Ensure this gcc optimization is switched off for mips platforms to avoid trouble with JIT.
+gcc:isEqual(QT_ARCH, "mips"): QMAKE_CXXFLAGS += -fno-reorder-blocks
+
MODULE_PLUGIN_TYPES = \
qmltooling
@@ -33,6 +36,7 @@ HEADERS += qtqmlglobal.h \
#modules
include(util/util.pri)
+include(memory/memory.pri)
include(parser/parser.pri)
include(compiler/compiler.pri)
include(jsapi/jsapi.pri)
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index e733bcec05..10ae9f0e52 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -35,7 +35,6 @@ SOURCES += \
$$PWD/qqmlimport.cpp \
$$PWD/qqmllist.cpp \
$$PWD/qqmllocale.cpp \
- $$PWD/qqmlabstractexpression.cpp \
$$PWD/qqmljavascriptexpression.cpp \
$$PWD/qqmlabstractbinding.cpp \
$$PWD/qqmlvaluetypeproxybinding.cpp \
@@ -107,7 +106,6 @@ HEADERS += \
$$PWD/qqmlscriptstring_p.h \
$$PWD/qqmllocale_p.h \
$$PWD/qqmlcomponentattached_p.h \
- $$PWD/qqmlabstractexpression_p.h \
$$PWD/qqmljavascriptexpression_p.h \
$$PWD/qqmlabstractbinding_p.h \
$$PWD/qqmlvaluetypeproxybinding_p.h \
diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp
index 40c8f451b4..04fbb16764 100644
--- a/src/qml/qml/qqmlabstractbinding.cpp
+++ b/src/qml/qml/qqmlabstractbinding.cpp
@@ -39,14 +39,6 @@
QT_BEGIN_NAMESPACE
-extern QQmlAbstractBinding::VTable QQmlBinding_vtable;
-extern QQmlAbstractBinding::VTable QQmlValueTypeProxyBinding_vtable;
-
-QQmlAbstractBinding::VTable *QQmlAbstractBinding::vTables[] = {
- &QQmlBinding_vtable,
- &QQmlValueTypeProxyBinding_vtable
-};
-
QQmlAbstractBinding::QQmlAbstractBinding(BindingType bt)
: m_nextBindingPtr(bt)
{
@@ -72,20 +64,20 @@ void QQmlAbstractBinding::addToObject()
Q_ASSERT(!nextBinding());
Q_ASSERT(isAddedToObject() == false);
- QObject *obj = object();
+ QObject *obj = targetObject();
Q_ASSERT(obj);
QQmlData *data = QQmlData::get(obj, true);
int coreIndex;
- if (QQmlPropertyData::decodeValueTypePropertyIndex(propertyIndex(), &coreIndex) != -1) {
+ if (QQmlPropertyData::decodeValueTypePropertyIndex(targetPropertyIndex(), &coreIndex) != -1) {
// Value type
// Find the value type proxy (if there is one)
QQmlValueTypeProxyBinding *proxy = 0;
if (data->hasBindingBit(coreIndex)) {
QQmlAbstractBinding *b = data->bindings;
- while (b && b->propertyIndex() != coreIndex)
+ while (b && b->targetPropertyIndex() != coreIndex)
b = b->nextBinding();
Q_ASSERT(b && b->bindingType() == QQmlAbstractBinding::ValueTypeProxy);
proxy = static_cast<QQmlValueTypeProxyBinding *>(b);
@@ -94,8 +86,8 @@ void QQmlAbstractBinding::addToObject()
if (!proxy) {
proxy = new QQmlValueTypeProxyBinding(obj, coreIndex);
- Q_ASSERT(proxy->propertyIndex() == coreIndex);
- Q_ASSERT(proxy->object() == obj);
+ Q_ASSERT(proxy->targetPropertyIndex() == coreIndex);
+ Q_ASSERT(proxy->targetObject() == obj);
proxy->addToObject();
}
@@ -118,59 +110,60 @@ Remove the binding from the object.
*/
void QQmlAbstractBinding::removeFromObject()
{
- if (isAddedToObject()) {
- QObject *obj = object();
- QQmlData *data = QQmlData::get(obj, false);
- Q_ASSERT(data);
-
- int coreIndex;
- if (QQmlPropertyData::decodeValueTypePropertyIndex(propertyIndex(), &coreIndex) != -1) {
-
- // Find the value type binding
- QQmlAbstractBinding *vtbinding = data->bindings;
- while (vtbinding->propertyIndex() != coreIndex) {
- vtbinding = vtbinding->nextBinding();
- Q_ASSERT(vtbinding);
- }
- Q_ASSERT(vtbinding->bindingType() == QQmlAbstractBinding::ValueTypeProxy);
-
- QQmlValueTypeProxyBinding *vtproxybinding =
- static_cast<QQmlValueTypeProxyBinding *>(vtbinding);
-
- QQmlAbstractBinding *binding = vtproxybinding->m_bindings;
- if (binding == this) {
- vtproxybinding->m_bindings = nextBinding();
- } else {
- while (binding->nextBinding() != this) {
- binding = binding->nextBinding();
- Q_ASSERT(binding);
- }
- binding->setNextBinding(nextBinding());
- }
+ if (!isAddedToObject())
+ return;
+
+ QObject *obj = targetObject();
+ QQmlData *data = QQmlData::get(obj, false);
+ Q_ASSERT(data);
- // Value type - we don't remove the proxy from the object. It will sit their happily
- // doing nothing until it is removed by a write, a binding change or it is reused
- // to hold more sub-bindings.
+ int coreIndex;
+ if (QQmlPropertyData::decodeValueTypePropertyIndex(targetPropertyIndex(), &coreIndex) != -1) {
+
+ // Find the value type binding
+ QQmlAbstractBinding *vtbinding = data->bindings;
+ while (vtbinding->targetPropertyIndex() != coreIndex) {
+ vtbinding = vtbinding->nextBinding();
+ Q_ASSERT(vtbinding);
+ }
+ Q_ASSERT(vtbinding->bindingType() == QQmlAbstractBinding::ValueTypeProxy);
+ QQmlValueTypeProxyBinding *vtproxybinding =
+ static_cast<QQmlValueTypeProxyBinding *>(vtbinding);
+
+ QQmlAbstractBinding *binding = vtproxybinding->m_bindings;
+ if (binding == this) {
+ vtproxybinding->m_bindings = nextBinding();
} else {
+ while (binding->nextBinding() != this) {
+ binding = binding->nextBinding();
+ Q_ASSERT(binding);
+ }
+ binding->setNextBinding(nextBinding());
+ }
- if (data->bindings == this) {
- data->bindings = nextBinding();
- } else {
- QQmlAbstractBinding *binding = data->bindings;
- while (binding->nextBinding() != this) {
- binding = binding->nextBinding();
- Q_ASSERT(binding);
- }
- binding->setNextBinding(nextBinding());
- }
+ // Value type - we don't remove the proxy from the object. It will sit their happily
+ // doing nothing until it is removed by a write, a binding change or it is reused
+ // to hold more sub-bindings.
+
+ } else {
- data->clearBindingBit(coreIndex);
+ if (data->bindings == this) {
+ data->bindings = nextBinding();
+ } else {
+ QQmlAbstractBinding *binding = data->bindings;
+ while (binding->nextBinding() != this) {
+ binding = binding->nextBinding();
+ Q_ASSERT(binding);
+ }
+ binding->setNextBinding(nextBinding());
}
- setNextBinding(0);
- setAddedToObject(false);
+ data->clearBindingBit(coreIndex);
}
+
+ setNextBinding(0);
+ setAddedToObject(false);
}
void QQmlAbstractBinding::printBindingLoopError(QQmlProperty &prop)
@@ -199,12 +192,7 @@ void QQmlAbstractBinding::clear()
}
}
-void QQmlAbstractBinding::default_retargetBinding(QQmlAbstractBinding *, QObject *, int)
-{
- qFatal("QQmlAbstractBinding::retargetBinding() called on illegal binding.");
-}
-
-QString QQmlAbstractBinding::default_expression(const QQmlAbstractBinding *)
+QString QQmlAbstractBinding::expression() const
{
return QLatin1String("<Unknown>");
}
diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h
index b5d8181ca5..d4cb4e0e9e 100644
--- a/src/qml/qml/qqmlabstractbinding_p.h
+++ b/src/qml/qml/qqmlabstractbinding_p.h
@@ -57,60 +57,29 @@ class QQmlObjectCreator;
class Q_QML_PRIVATE_EXPORT QQmlAbstractBinding
{
public:
- enum DestroyMode {
-
- // The binding should disconnect itself upon destroy
- DisconnectBinding,
-
- // The binding doesn't need to disconnect itself, but it can if it wants to.
- //
- // This is used in QQmlData::destroyed() - at the point at which the bindings are
- // destroyed, the notifiers are already disconnected, so no need to disconnect each
- // binding again.
- //
- // Bindings can use this flag to speed up destruction, especially for v4 bindings
- // disconnecting a single binding might be slow.
- KeepBindingConnected
- };
-
- struct VTable {
- void (*destroy)(QQmlAbstractBinding *, DestroyMode destroyMode);
- QString (*expression)(const QQmlAbstractBinding *);
- int (*propertyIndex)(const QQmlAbstractBinding *);
- QObject *(*object)(const QQmlAbstractBinding *);
- void (*setEnabled)(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags);
- void (*update)(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags);
- void (*retargetBinding)(QQmlAbstractBinding *, QObject *, int);
- };
-
typedef QWeakPointer<QQmlAbstractBinding> Pointer;
enum BindingType { Binding = 0, ValueTypeProxy = 1 };
inline BindingType bindingType() const;
- // Destroy the binding. Use this instead of calling delete.
- // Bindings are free to implement their own memory management, so the delete operator is
- // not necessarily safe. The default implementation clears the binding, removes it from
- // the object and calls delete.
- void destroy(DestroyMode destroyMode = DisconnectBinding)
- { vtable()->destroy(this, destroyMode); }
+ void destroy() {
+ removeFromObject();
+ clear();
+ delete this;
+ }
- QString expression() const { return vtable()->expression(this); }
+ virtual QString expression() const;
// Should return the encoded property index for the binding. Should return this value
// even if the binding is not enabled or added to an object.
// Encoding is: coreIndex | (valueTypeIndex << 16)
- int propertyIndex() const { return vtable()->propertyIndex(this); }
+ virtual int targetPropertyIndex() const = 0;
// Should return the object for the binding. Should return this object even if the
// binding is not enabled or added to the object.
- QObject *object() const { return vtable()->object(this); }
-
- void setEnabled(bool e) { setEnabled(e, QQmlPropertyPrivate::DontRemoveBinding); }
- void setEnabled(bool e, QQmlPropertyPrivate::WriteFlags f) { vtable()->setEnabled(this, e, f); }
+ virtual QObject *targetObject() const = 0;
- void update() { update(QQmlPropertyPrivate::DontRemoveBinding); }
- void update(QQmlPropertyPrivate::WriteFlags f) { vtable()->update(this, f); }
+ virtual void setEnabled(bool e, QQmlPropertyPrivate::WriteFlags f = QQmlPropertyPrivate::DontRemoveBinding) = 0;
void addToObject();
void removeFromObject();
@@ -118,33 +87,20 @@ public:
static inline Pointer getPointer(QQmlAbstractBinding *p);
static void printBindingLoopError(QQmlProperty &prop);
- // Default implementation for some VTable functions
- template<typename T>
- static void default_destroy(QQmlAbstractBinding *, DestroyMode);
- static QString default_expression(const QQmlAbstractBinding *);
- static void default_retargetBinding(QQmlAbstractBinding *, QObject *, int);
+ inline QQmlAbstractBinding *nextBinding() const;
protected:
QQmlAbstractBinding(BindingType);
- ~QQmlAbstractBinding();
+ virtual ~QQmlAbstractBinding();
void clear();
- // Called by QQmlPropertyPrivate to "move" a binding to a different property.
- // This is only used for alias properties. The default implementation qFatal()'s
- // to ensure that the method is never called for binding types that don't support it.
- void retargetBinding(QObject *o, int i) { vtable()->retargetBinding(this, o, i); }
-
private:
- Pointer weakPointer();
-
friend class QQmlData;
- friend class QQmlComponentPrivate;
friend class QQmlValueTypeProxyBinding;
- friend class QQmlPropertyPrivate;
- friend class QtSharedPointer::ExternalRefCount<QQmlAbstractBinding>;
- friend class QV4Bindings;
friend class QQmlObjectCreator;
+ Pointer weakPointer();
+
typedef QSharedPointer<QQmlAbstractBinding> SharedPointer;
// To save memory, we also store the rarely used weakPointer() instance in here
// We also use the flag bits:
@@ -154,7 +110,6 @@ private:
inline void setAddedToObject(bool v);
inline bool isAddedToObject() const;
- inline QQmlAbstractBinding *nextBinding() const;
inline void setNextBinding(QQmlAbstractBinding *);
// Pointer to the next binding in the linked list of bindings.
@@ -166,9 +121,6 @@ private:
// This saves a compiler-generated pointer to a compiler-generated vTable, and thus reduces
// the binding object size by sizeof(void*).
qintptr m_nextBindingPtr;
-
- static VTable *vTables[];
- inline const VTable *vtable() const { return vTables[bindingType()]; }
};
QQmlAbstractBinding::Pointer
@@ -202,18 +154,6 @@ QQmlAbstractBinding::BindingType QQmlAbstractBinding::bindingType() const
return (BindingType)(m_nextBindingPtr & 0x3);
}
-template<typename T>
-void QQmlAbstractBinding::default_destroy(QQmlAbstractBinding *This, DestroyMode mode)
-{
- // Assume the binding disconnects itself in the destructor, which for example QQmlBinding
- // does in the destructor of its base class, QQmlJavaScriptExpression
- Q_UNUSED(mode);
-
- This->removeFromObject();
- This->clear();
- delete static_cast<T *>(This);
-}
-
QT_END_NAMESPACE
#endif // QQMLABSTRACTBINDING_P_H
diff --git a/src/qml/qml/qqmlabstractexpression_p.h b/src/qml/qml/qqmlabstractexpression_p.h
deleted file mode 100644
index 82ba010434..0000000000
--- a/src/qml/qml/qqmlabstractexpression_p.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLABSTRACTEXPRESSION_P_H
-#define QQMLABSTRACTEXPRESSION_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qqmlcontext_p.h>
-#include <private/qfieldlist_p.h>
-#include <private/qflagpointer_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_QML_PRIVATE_EXPORT QQmlAbstractExpression
-{
-public:
- QQmlAbstractExpression();
- virtual ~QQmlAbstractExpression();
-
- bool isValid() const;
-
- QQmlContextData *context() const;
- void setContext(QQmlContextData *);
-
- virtual void refresh();
-
- class DeleteWatcher {
- public:
- inline DeleteWatcher(QQmlAbstractExpression *);
- inline ~DeleteWatcher();
- inline bool wasDeleted() const;
- private:
- friend class QQmlAbstractExpression;
- QQmlContextData *_c;
- QQmlAbstractExpression **_w;
- QQmlAbstractExpression *_s;
- };
-
-private:
- friend class QQmlContext;
- friend class QQmlContextData;
- friend class QQmlContextPrivate;
-
- QBiPointer<QQmlContextData, DeleteWatcher> m_context;
- QQmlAbstractExpression **m_prevExpression;
- QQmlAbstractExpression *m_nextExpression;
-};
-
-QQmlAbstractExpression::DeleteWatcher::DeleteWatcher(QQmlAbstractExpression *e)
-: _c(0), _w(0), _s(e)
-{
- if (e->m_context.isT1()) {
- _w = &_s;
- _c = e->m_context.asT1();
- e->m_context = this;
- } else {
- // Another watcher is already registered
- _w = &e->m_context.asT2()->_s;
- }
-}
-
-QQmlAbstractExpression::DeleteWatcher::~DeleteWatcher()
-{
- Q_ASSERT(*_w == 0 || (*_w == _s && _s->m_context.isT2()));
- if (*_w && _s->m_context.asT2() == this)
- _s->m_context = _c;
-}
-
-bool QQmlAbstractExpression::DeleteWatcher::wasDeleted() const
-{
- return *_w == 0;
-}
-
-QT_END_NAMESPACE
-
-#endif // QQMLABSTRACTEXPRESSION_P_H
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index f223d099e4..b9ca15af27 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -43,43 +43,30 @@
#include <private/qqmlscriptstring_p.h>
#include <private/qqmlcontextwrapper_p.h>
#include <private/qqmlbuiltinfunctions_p.h>
+#include <private/qqmlvmemetaobject_p.h>
#include <QVariant>
#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
-// Used in qqmlabstractbinding.cpp
-QQmlAbstractBinding::VTable QQmlBinding_vtable = {
- QQmlAbstractBinding::default_destroy<QQmlBinding>,
- QQmlBinding::expression,
- QQmlBinding::propertyIndex,
- QQmlBinding::object,
- QQmlBinding::setEnabled,
- QQmlBinding::update,
- QQmlBinding::retargetBinding
-};
-
QQmlBinding::Identifier QQmlBinding::Invalid = -1;
-static QQmlJavaScriptExpression::VTable QQmlBinding_jsvtable = {
- QQmlBinding::expressionIdentifier,
- QQmlBinding::expressionChanged
-};
-
QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContext *ctxt)
-: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding)
+ : QQmlJavaScriptExpression(),
+ QQmlAbstractBinding(Binding)
{
setNotifyOnValueChanged(true);
- QQmlAbstractExpression::setContext(QQmlContextData::get(ctxt));
+ QQmlJavaScriptExpression::setContext(QQmlContextData::get(ctxt));
setScopeObject(obj);
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::get(context()->engine)->v4engine();
- v4function.set(v4, qmlBinding(context(), obj, str, QString(), 0));
+ m_function.set(v4, qmlBinding(context(), obj, str, QString(), 0));
}
QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlContext *ctxt)
-: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding)
+ : QQmlJavaScriptExpression(),
+ QQmlAbstractBinding(Binding)
{
if (ctxt && !ctxt->isValid())
return;
@@ -100,51 +87,54 @@ QQmlBinding::QQmlBinding(const QQmlScriptString &script, QObject *obj, QQmlConte
}
setNotifyOnValueChanged(true);
- QQmlAbstractExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context));
+ QQmlJavaScriptExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context));
setScopeObject(obj ? obj : scriptPrivate->scope);
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::get(context()->engine)->v4engine();
if (runtimeFunction) {
- v4function.set(v4, QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxtdata, scopeObject(), runtimeFunction));
+ m_function.set(v4, QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxtdata, scopeObject(), runtimeFunction));
} else {
QString code = scriptPrivate->script;
- v4function.set(v4, qmlBinding(context(), scopeObject(), code, url, scriptPrivate->lineNumber));
+ m_function.set(v4, qmlBinding(context(), scopeObject(), code, url, scriptPrivate->lineNumber));
}
}
QQmlBinding::QQmlBinding(const QString &str, QObject *obj, QQmlContextData *ctxt)
-: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding)
+ : QQmlJavaScriptExpression(),
+ QQmlAbstractBinding(Binding)
{
setNotifyOnValueChanged(true);
- QQmlAbstractExpression::setContext(ctxt);
+ QQmlJavaScriptExpression::setContext(ctxt);
setScopeObject(obj);
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::get(context()->engine)->v4engine();
- v4function.set(v4, qmlBinding(ctxt, obj, str, QString(), 0));
+ m_function.set(v4, qmlBinding(ctxt, obj, str, QString(), 0));
}
QQmlBinding::QQmlBinding(const QString &str, QObject *obj,
QQmlContextData *ctxt,
const QString &url, quint16 lineNumber, quint16 columnNumber)
-: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding)
+ : QQmlJavaScriptExpression(),
+ QQmlAbstractBinding(Binding)
{
Q_UNUSED(columnNumber);
setNotifyOnValueChanged(true);
- QQmlAbstractExpression::setContext(ctxt);
+ QQmlJavaScriptExpression::setContext(ctxt);
setScopeObject(obj);
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::get(context()->engine)->v4engine();
- v4function.set(v4, qmlBinding(ctxt, obj, str, url, lineNumber));
+ m_function.set(v4, qmlBinding(ctxt, obj, str, url, lineNumber));
}
QQmlBinding::QQmlBinding(const QV4::Value &functionPtr, QObject *obj, QQmlContextData *ctxt)
-: QQmlJavaScriptExpression(&QQmlBinding_jsvtable), QQmlAbstractBinding(Binding)
+ : QQmlJavaScriptExpression(),
+ QQmlAbstractBinding(Binding)
{
setNotifyOnValueChanged(true);
- QQmlAbstractExpression::setContext(ctxt);
+ QQmlJavaScriptExpression::setContext(ctxt);
setScopeObject(obj);
- v4function.set(functionPtr.asObject()->engine(), functionPtr);
+ m_function.set(functionPtr.as<QV4::Object>()->engine(), functionPtr);
}
QQmlBinding::~QQmlBinding()
@@ -162,90 +152,88 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
return;
// Check that the target has not been deleted
- if (QQmlData::wasDeleted(object()))
+ if (QQmlData::wasDeleted(targetObject()))
return;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
QV4::Scope scope(ep->v4engine());
- QV4::ScopedFunctionObject f(scope, v4function.value());
+ QV4::ScopedFunctionObject f(scope, m_function.value());
Q_ASSERT(f);
- if (!updatingFlag()) {
- QQmlBindingProfiler prof(ep->profiler, f);
- setUpdatingFlag(true);
+ if (updatingFlag()) {
+ QQmlProperty p = QQmlPropertyPrivate::restore(targetObject(), m_core, 0);
+ QQmlAbstractBinding::printBindingLoopError(p);
+ return;
+ }
- QQmlAbstractExpression::DeleteWatcher watcher(this);
+ QQmlBindingProfiler prof(ep->profiler, f);
+ setUpdatingFlag(true);
- if (m_core.propType == qMetaTypeId<QQmlBinding *>()) {
+ QQmlJavaScriptExpression::DeleteWatcher watcher(this);
- int idx = m_core.coreIndex;
- Q_ASSERT(idx != -1);
+ if (m_core.propType == qMetaTypeId<QQmlBinding *>()) {
- QQmlBinding *t = this;
- int status = -1;
- void *a[] = { &t, 0, &status, &flags };
- QMetaObject::metacall(*m_coreObject, QMetaObject::WriteProperty, idx, a);
+ int idx = m_core.coreIndex;
+ Q_ASSERT(idx != -1);
- } else {
- ep->referenceScarceResources();
+ QQmlBinding *t = this;
+ int status = -1;
+ void *a[] = { &t, 0, &status, &flags };
+ QMetaObject::metacall(*m_coreObject, QMetaObject::WriteProperty, idx, a);
- bool isUndefined = false;
+ } else {
+ ep->referenceScarceResources();
- QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(context(), f, &isUndefined));
+ bool isUndefined = false;
- bool needsErrorLocationData = false;
- if (!watcher.wasDeleted() && !hasError())
- needsErrorLocationData = !QQmlPropertyPrivate::writeBinding(*m_coreObject, m_core, context(),
- this, result, isUndefined, flags);
+ QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined));
- if (!watcher.wasDeleted()) {
+ bool needsErrorLocationData = false;
+ if (!watcher.wasDeleted() && !hasError())
+ needsErrorLocationData = !QQmlPropertyPrivate::writeBinding(*m_coreObject, m_core, context(),
+ this, result, isUndefined, flags);
- if (needsErrorLocationData)
- delayedError()->setErrorLocation(f->sourceLocation());
+ if (!watcher.wasDeleted()) {
- if (hasError()) {
- if (!delayedError()->addError(ep)) ep->warning(this->error(context()->engine));
- } else {
- clearError();
- }
+ if (needsErrorLocationData)
+ delayedError()->setErrorLocation(f->sourceLocation());
+ if (hasError()) {
+ if (!delayedError()->addError(ep)) ep->warning(this->error(context()->engine));
+ } else {
+ clearError();
}
- ep->dereferenceScarceResources();
}
- if (!watcher.wasDeleted())
- setUpdatingFlag(false);
- } else {
- QQmlProperty p = property();
- QQmlAbstractBinding::printBindingLoopError(p);
+ ep->dereferenceScarceResources();
}
+
+ if (!watcher.wasDeleted())
+ setUpdatingFlag(false);
}
QVariant QQmlBinding::evaluate()
{
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
- QV4::Scope scope(ep->v4engine());
ep->referenceScarceResources();
bool isUndefined = false;
- QV4::ScopedValue f(scope, v4function.value());
- QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(context(), f, &isUndefined));
+ QV4::Scope scope(ep->v4engine());
+ QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined));
ep->dereferenceScarceResources();
return scope.engine->toVariant(result, qMetaTypeId<QList<QObject*> >());
}
-QString QQmlBinding::expressionIdentifier(QQmlJavaScriptExpression *e)
+QString QQmlBinding::expressionIdentifier()
{
- QQmlBinding *This = static_cast<QQmlBinding *>(e);
-
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(This->context()->engine);
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
QV4::Scope scope(ep->v4engine());
- QV4::ScopedValue f(scope, This->v4function.value());
- QV4::Function *function = f->asFunctionObject()->function();
+ QV4::ScopedValue f(scope, m_function.value());
+ QV4::Function *function = f->as<QV4::FunctionObject>()->function();
QString url = function->sourceFile();
quint16 lineNumber = function->compiledFunction->location.line;
@@ -254,10 +242,9 @@ QString QQmlBinding::expressionIdentifier(QQmlJavaScriptExpression *e)
return url + QLatin1Char(':') + QString::number(lineNumber) + QLatin1Char(':') + QString::number(columnNumber);
}
-void QQmlBinding::expressionChanged(QQmlJavaScriptExpression *e)
+void QQmlBinding::expressionChanged()
{
- QQmlBinding *This = static_cast<QQmlBinding *>(e);
- This->update();
+ update();
}
void QQmlBinding::refresh()
@@ -265,36 +252,6 @@ void QQmlBinding::refresh()
update();
}
-QString QQmlBinding::expression(const QQmlAbstractBinding *This)
-{
- return static_cast<const QQmlBinding *>(This)->expression();
-}
-
-int QQmlBinding::propertyIndex(const QQmlAbstractBinding *This)
-{
- return static_cast<const QQmlBinding *>(This)->propertyIndex();
-}
-
-QObject *QQmlBinding::object(const QQmlAbstractBinding *This)
-{
- return static_cast<const QQmlBinding *>(This)->object();
-}
-
-void QQmlBinding::setEnabled(QQmlAbstractBinding *This, bool e, QQmlPropertyPrivate::WriteFlags f)
-{
- static_cast<QQmlBinding *>(This)->setEnabled(e, f);
-}
-
-void QQmlBinding::update(QQmlAbstractBinding *This , QQmlPropertyPrivate::WriteFlags f)
-{
- static_cast<QQmlBinding *>(This)->update(f);
-}
-
-void QQmlBinding::retargetBinding(QQmlAbstractBinding *This, QObject *o, int i)
-{
- static_cast<QQmlBinding *>(This)->retargetBinding(o, i);
-}
-
void QQmlBinding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags)
{
setEnabledFlag(e);
@@ -307,44 +264,65 @@ void QQmlBinding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags)
QString QQmlBinding::expression() const
{
QV4::Scope scope(QQmlEnginePrivate::get(context()->engine)->v4engine());
- QV4::ScopedValue v(scope, v4function.value());
+ QV4::ScopedValue v(scope, m_function.value());
return v->toQStringNoThrow();
}
-QObject *QQmlBinding::object() const
+QObject *QQmlBinding::targetObject() const
{
- if (m_coreObject.hasValue()) return m_coreObject.constValue()->target;
- else return *m_coreObject;
+ return *m_coreObject;
}
-int QQmlBinding::propertyIndex() const
+int QQmlBinding::targetPropertyIndex() const
{
- if (m_coreObject.hasValue()) return m_coreObject.constValue()->targetProperty;
- else return m_core.encodedIndex();
-}
-
-void QQmlBinding::retargetBinding(QObject *t, int i)
-{
- m_coreObject.value().target = t;
- m_coreObject.value().targetProperty = i;
+ return m_core.encodedIndex();
}
void QQmlBinding::setTarget(const QQmlProperty &prop)
{
- setTarget(prop.object(), QQmlPropertyPrivate::get(prop)->core,
- QQmlPropertyPrivate::get(prop)->context);
+ setTarget(prop.object(), QQmlPropertyPrivate::get(prop)->core);
}
-void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, QQmlContextData *ctxt)
+void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core)
{
m_coreObject = object;
m_core = core;
- m_ctxt = ctxt;
-}
-QQmlProperty QQmlBinding::property() const
-{
- return QQmlPropertyPrivate::restore(object(), m_core, *m_ctxt);
+ while (m_core.isAlias()) {
+ int coreIndex = core.coreIndex;
+ int valueTypeIndex = core.getValueTypeCoreIndex();
+ QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
+
+ int aValueTypeIndex;
+ if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) {
+ m_core.coreIndex = -1;
+ m_coreObject = 0;
+ return;
+ }
+ if (valueTypeIndex == -1)
+ valueTypeIndex = aValueTypeIndex;
+
+ QQmlData *data = QQmlData::get(object, false);
+ if (!data || !data->propertyCache) {
+ m_core.coreIndex = -1;
+ m_coreObject = 0;
+ return;
+ }
+ QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex);
+ Q_ASSERT(propertyData);
+
+ m_coreObject = object;
+ m_core = *propertyData;
+ if (valueTypeIndex != -1) {
+ const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(m_core.propType);
+ Q_ASSERT(valueTypeMetaObject);
+ QMetaProperty vtProp = valueTypeMetaObject->property(valueTypeIndex);
+ m_core.setFlags(m_core.getFlags() | QQmlPropertyData::IsValueTypeVirtual);
+ m_core.valueTypeFlags = QQmlPropertyData::flagsForProperty(vtProp);
+ m_core.valueTypePropType = vtProp.userType();
+ m_core.valueTypeCoreIndex = valueTypeIndex;
+ }
+ }
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h
index 1e440b2e86..99c1699168 100644
--- a/src/qml/qml/qqmlbinding_p.h
+++ b/src/qml/qml/qqmlbinding_p.h
@@ -57,14 +57,12 @@
#include <private/qpointervaluepair_p.h>
#include <private/qqmlabstractbinding_p.h>
-#include <private/qqmlabstractexpression_p.h>
#include <private/qqmljavascriptexpression_p.h>
QT_BEGIN_NAMESPACE
class QQmlContext;
class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression,
- public QQmlAbstractExpression,
public QQmlAbstractBinding
{
public:
@@ -76,82 +74,60 @@ public:
QQmlBinding(const QV4::Value &, QObject *, QQmlContextData *);
void setTarget(const QQmlProperty &);
- void setTarget(QObject *, const QQmlPropertyData &, QQmlContextData *);
- QQmlProperty property() const;
+ void setTarget(QObject *, const QQmlPropertyData &);
void setNotifyOnValueChanged(bool);
- // Inherited from QQmlAbstractExpression
+ // Inherited from QQmlJavaScriptExpression
virtual void refresh();
- // "Inherited" from QQmlAbstractBinding
- static QString expression(const QQmlAbstractBinding *);
- static int propertyIndex(const QQmlAbstractBinding *);
- static QObject *object(const QQmlAbstractBinding *);
- static void setEnabled(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags);
- static void update(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags);
- static void retargetBinding(QQmlAbstractBinding *, QObject *, int);
-
- void setEnabled(bool, QQmlPropertyPrivate::WriteFlags flags);
- void update(QQmlPropertyPrivate::WriteFlags flags);
- void update() { update(QQmlPropertyPrivate::DontRemoveBinding); }
-
- QString expression() const;
- QObject *object() const;
- int propertyIndex() const;
- void retargetBinding(QObject *, int);
+ // Inherited from QQmlAbstractBinding
+ virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags flags = QQmlPropertyPrivate::DontRemoveBinding);
+ virtual QString expression() const;
+ virtual QObject *targetObject() const;
+ virtual int targetPropertyIndex() const;
+ void update(QQmlPropertyPrivate::WriteFlags flags = QQmlPropertyPrivate::DontRemoveBinding);
typedef int Identifier;
static Identifier Invalid;
QVariant evaluate();
- static QString expressionIdentifier(QQmlJavaScriptExpression *);
- static void expressionChanged(QQmlJavaScriptExpression *);
+ virtual QString expressionIdentifier();
+ virtual void expressionChanged();
protected:
friend class QQmlAbstractBinding;
~QQmlBinding();
private:
- QV4::PersistentValue v4function;
-
inline bool updatingFlag() const;
inline void setUpdatingFlag(bool);
inline bool enabledFlag() const;
inline void setEnabledFlag(bool);
- struct Retarget {
- QObject *target;
- int targetProperty;
- };
-
- QPointerValuePair<QObject, Retarget> m_coreObject;
+ QFlagPointer<QObject> m_coreObject;
QQmlPropertyData m_core;
- // We store some flag bits in the following flag pointers.
- // m_ctxt:flag1 - updatingFlag
- // m_ctxt:flag2 - enabledFlag
- QFlagPointer<QQmlContextData> m_ctxt;
};
bool QQmlBinding::updatingFlag() const
{
- return m_ctxt.flag();
+ return m_coreObject.flag();
}
void QQmlBinding::setUpdatingFlag(bool v)
{
- m_ctxt.setFlagValue(v);
+ m_coreObject.setFlagValue(v);
}
bool QQmlBinding::enabledFlag() const
{
- return m_ctxt.flag2();
+ return m_coreObject.flag2();
}
void QQmlBinding::setEnabledFlag(bool v)
{
- m_ctxt.setFlag2Value(v);
+ m_coreObject.setFlag2Value(v);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 766e657c59..77dccf6f04 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -47,7 +47,7 @@
#include <private/qqmlcompiler_p.h>
#include "qqmlinfo.h"
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <QtCore/qstringbuilder.h>
#include <QtCore/qdebug.h>
@@ -55,11 +55,6 @@
QT_BEGIN_NAMESPACE
-static QQmlJavaScriptExpression::VTable QQmlBoundSignalExpression_jsvtable = {
- QQmlBoundSignalExpression::expressionIdentifier,
- QQmlBoundSignalExpression::expressionChanged
-};
-
QQmlBoundSignalExpression::ExtraData::ExtraData(const QString &handlerName, const QString &parameterString,
const QString &expression, const QString &fileName,
quint16 line, quint16 column)
@@ -75,7 +70,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
const QString &fileName, quint16 line, quint16 column,
const QString &handlerName,
const QString &parameterString)
- : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable),
+ : QQmlJavaScriptExpression(),
m_index(index),
m_target(target),
m_extra(new ExtraData(handlerName, parameterString, expression, fileName, line, column))
@@ -87,12 +82,13 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
}
QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, const QV4::Value &function)
- : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable),
+ : QQmlJavaScriptExpression(),
m_index(index),
- m_function(function.asObject()->engine(), function),
m_target(target),
m_extra(0)
{
+ m_function.set(function.as<QV4::Object>()->engine(), function);
+
setExpressionFunctionValid(true);
setInvalidParameterName(false);
@@ -100,7 +96,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
}
QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction)
- : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable),
+ : QQmlJavaScriptExpression(),
m_index(index),
m_target(target),
m_extra(0)
@@ -137,14 +133,13 @@ QQmlBoundSignalExpression::~QQmlBoundSignalExpression()
delete m_extra.data();
}
-QString QQmlBoundSignalExpression::expressionIdentifier(QQmlJavaScriptExpression *e)
+QString QQmlBoundSignalExpression::expressionIdentifier()
{
- QQmlBoundSignalExpression *This = static_cast<QQmlBoundSignalExpression *>(e);
- QQmlSourceLocation loc = This->sourceLocation();
+ QQmlSourceLocation loc = sourceLocation();
return loc.sourceFile + QLatin1Char(':') + QString::number(loc.line);
}
-void QQmlBoundSignalExpression::expressionChanged(QQmlJavaScriptExpression *)
+void QQmlBoundSignalExpression::expressionChanged()
{
// bound signals do not notify on change.
}
@@ -254,7 +249,6 @@ void QQmlBoundSignalExpression::evaluate(void **a)
int *argsTypes = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, dummy, 0);
int argCount = argsTypes ? *argsTypes : 0;
- QV4::ScopedValue f(scope, m_function.value());
QV4::ScopedCallData callData(scope, argCount);
for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1];
@@ -278,7 +272,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
}
}
- QQmlJavaScriptExpression::evaluate(context(), f, callData, 0);
+ QQmlJavaScriptExpression::evaluate(callData, 0);
}
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index 8d677ea039..bc30b25d6a 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -47,7 +47,6 @@
#include <QtCore/qmetaobject.h>
-#include <private/qqmlabstractexpression_p.h>
#include <private/qqmljavascriptexpression_p.h>
#include <private/qqmlboundsignalexpressionpointer_p.h>
#include <private/qqmlnotifier_p.h>
@@ -58,7 +57,7 @@
QT_BEGIN_NAMESPACE
-class Q_QML_PRIVATE_EXPORT QQmlBoundSignalExpression : public QQmlAbstractExpression, public QQmlJavaScriptExpression, public QQmlRefCount
+class Q_QML_PRIVATE_EXPORT QQmlBoundSignalExpression : public QQmlJavaScriptExpression, public QQmlRefCount
{
public:
QQmlBoundSignalExpression(QObject *target, int index,
@@ -73,9 +72,9 @@ public:
QQmlBoundSignalExpression(QObject *target, int index,
QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction);
- // "inherited" from QQmlJavaScriptExpression.
- static QString expressionIdentifier(QQmlJavaScriptExpression *);
- static void expressionChanged(QQmlJavaScriptExpression *);
+ // inherited from QQmlJavaScriptExpression.
+ virtual QString expressionIdentifier();
+ virtual void expressionChanged();
// evaluation of a bound signal expression doesn't return any value
void evaluate(void **a);
@@ -99,8 +98,6 @@ private:
void setInvalidParameterName(bool v) { m_extra.setFlag2Value(v); }
int m_index;
- QV4::PersistentValue m_function;
-
QObject *m_target;
// only needed when !expressionFunctionValid()
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index a36b742085..8795d6d07a 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1216,7 +1216,7 @@ void QQmlComponent::createObject(QQmlV4Function *args)
if (args->length() >= 2) {
QV4::ScopedValue v(scope, (*args)[1]);
- if (!v->asObject() || v->asArrayObject()) {
+ if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) {
qmlInfo(this) << tr("createObject: value is not an object");
args->setReturnValue(QV4::Encode::null());
return;
@@ -1242,12 +1242,12 @@ void QQmlComponent::createObject(QQmlV4Function *args)
if (!valuemap->isUndefined()) {
QV4::ScopedObject qmlglobal(scope, args->qmlGlobal());
QV4::ScopedValue f(scope, QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlglobal));
- Q_ASSERT(f->asFunctionObject());
+ Q_ASSERT(f->as<QV4::FunctionObject>());
QV4::ScopedCallData callData(scope, 2);
- callData->thisObject = v4->globalObject();
+ callData->thisObject = v4->globalObject;
callData->args[0] = object;
callData->args[1] = valuemap;
- f->asFunctionObject()->call(callData);
+ f->as<QV4::FunctionObject>()->call(callData);
}
d->completeCreate();
@@ -1342,7 +1342,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
if (args->length() >= 2) {
QV4::ScopedValue v(scope, (*args)[1]);
if (v->isNull()) {
- } else if (!v->asObject() || v->asArrayObject()) {
+ } else if (!v->as<QV4::Object>() || v->as<QV4::ArrayObject>()) {
qmlInfo(this) << tr("createObject: value is not an object");
args->setReturnValue(QV4::Encode::null());
return;
@@ -1390,14 +1390,14 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu
QV4::Scope scope(v4engine);
QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, toCreate));
- Q_ASSERT(object->asObject());
+ Q_ASSERT(object->as<QV4::Object>());
if (!valuemap.isUndefined()) {
QV4::ScopedObject qmlGlobalObj(scope, qmlGlobal);
QV4::ScopedFunctionObject f(scope, QV4::Script::evaluate(v4engine,
QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobalObj));
QV4::ScopedCallData callData(scope, 2);
- callData->thisObject = v4engine->globalObject();
+ callData->thisObject = v4engine->globalObject;
callData->args[0] = object;
callData->args[1] = valuemap;
f->call(callData);
@@ -1492,9 +1492,9 @@ void QV4::QmlIncubatorObject::setInitialState(QObject *o)
QV4::ExecutionEngine *v4 = engine();
QV4::Scope scope(v4);
- QV4::ScopedFunctionObject f(scope, QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), d()->qmlGlobal.asObject()));
+ QV4::ScopedFunctionObject f(scope, QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), d()->qmlGlobal.as<Object>()));
QV4::ScopedCallData callData(scope, 2);
- callData->thisObject = v4->globalObject();
+ callData->thisObject = v4->globalObject;
callData->args[0] = QV4::QObjectWrapper::wrap(v4, o);
callData->args[1] = d()->valuemap;
f->call(callData);
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index f08f650913..052f371516 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -585,9 +585,9 @@ void QQmlContextData::clearContext()
{
emitDestruction();
- QQmlAbstractExpression *expression = expressions;
+ QQmlJavaScriptExpression *expression = expressions;
while (expression) {
- QQmlAbstractExpression *nextExpression = expression->m_nextExpression;
+ QQmlJavaScriptExpression *nextExpression = expression->m_nextExpression;
expression->m_prevExpression = 0;
expression->m_nextExpression = 0;
@@ -652,9 +652,9 @@ void QQmlContextData::setParent(QQmlContextData *p, bool parentTakesOwnership)
}
}
-void QQmlContextData::refreshExpressionsRecursive(QQmlAbstractExpression *expression)
+void QQmlContextData::refreshExpressionsRecursive(QQmlJavaScriptExpression *expression)
{
- QQmlAbstractExpression::DeleteWatcher w(expression);
+ QQmlJavaScriptExpression::DeleteWatcher w(expression);
if (expression->m_nextExpression)
refreshExpressionsRecursive(expression->m_nextExpression);
@@ -808,7 +808,7 @@ QV4::IdentifierHash<int> &QQmlContextData::propertyNames() const
{
if (propertyNameCache.isEmpty()) {
propertyNameCache = QV4::IdentifierHash<int>(QV8Engine::getV4(engine->handle()));
- for (QHash<int, int>::ConstIterator it = objectIndexToId.begin(), end = objectIndexToId.end();
+ for (QHash<int, int>::ConstIterator it = objectIndexToId.cbegin(), end = objectIndexToId.cend();
it != end; ++it) {
const QV4::CompiledData::Object *obj = typeCompilationUnit->data->objectAt(it.key());
const QString name = typeCompilationUnit->data->stringAt(obj->idIndex);
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index f5fd7d0a5c..95254d4baa 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -69,7 +69,7 @@ class QQmlExpression;
class QQmlEngine;
class QQmlExpression;
class QQmlExpressionPrivate;
-class QQmlAbstractExpression;
+class QQmlJavaScriptExpression;
class QQmlContextData;
class QQmlContextPrivate : public QObjectPrivate
@@ -171,7 +171,7 @@ public:
QQmlContextData **prevChild;
// Expressions that use this context
- QQmlAbstractExpression *expressions;
+ QQmlJavaScriptExpression *expressions;
// Doubly-linked list of objects that are owned by this context
QQmlData *contextObjects;
@@ -212,7 +212,7 @@ public:
private:
void refreshExpressionsRecursive(bool isGlobal);
- void refreshExpressionsRecursive(QQmlAbstractExpression *);
+ void refreshExpressionsRecursive(QQmlJavaScriptExpression *);
~QQmlContextData() {}
};
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index 5844eab54f..9b921b9fad 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -38,7 +38,7 @@
#include <private/qqmlcontext_p.h>
#include <private/qv4engine_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4objectproto_p.h>
#include <private/qv4mm_p.h>
#include <private/qv4function_p.h>
@@ -106,7 +106,7 @@ QQmlContextData *QmlContextWrapper::getContext(const Value &value)
if (!value.isObject())
return 0;
- QV4::ExecutionEngine *v4 = value.asObject()->engine();
+ QV4::ExecutionEngine *v4 = value.as<Object>()->engine();
Scope scope(v4);
QV4::Scoped<QmlContextWrapper> c(scope, value);
@@ -117,7 +117,7 @@ void QmlContextWrapper::takeContextOwnership(const Value &qmlglobal)
{
Q_ASSERT(qmlglobal.isObject());
- QV4::ExecutionEngine *v4 = qmlglobal.asObject()->engine();
+ QV4::ExecutionEngine *v4 = qmlglobal.as<Object>()->engine();
Scope scope(v4);
QV4::Scoped<QmlContextWrapper> c(scope, qmlglobal);
Q_ASSERT(c);
@@ -125,17 +125,17 @@ void QmlContextWrapper::takeContextOwnership(const Value &qmlglobal)
}
-ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasProperty)
{
Q_ASSERT(m->as<QmlContextWrapper>());
- QmlContextWrapper *resource = static_cast<QmlContextWrapper *>(m);
+ const QmlContextWrapper *resource = static_cast<const QmlContextWrapper *>(m);
QV4::ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
// In V8 the JS global object would come _before_ the QML global object,
// so simulate that here.
bool hasProp;
- QV4::ScopedValue result(scope, v4->globalObject()->get(name, &hasProp));
+ QV4::ScopedValue result(scope, v4->globalObject->get(name, &hasProp));
if (hasProp) {
if (hasProperty)
*hasProperty = hasProp;
@@ -431,10 +431,10 @@ Heap::QQmlIdObjectsArray::QQmlIdObjectsArray(ExecutionEngine *engine, QV4::QmlCo
{
}
-ReturnedValue QQmlIdObjectsArray::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue QQmlIdObjectsArray::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
- Scope scope(static_cast<QV4::QQmlIdObjectsArray*>(m)->engine());
- Scoped<QQmlIdObjectsArray> This(scope, static_cast<QV4::QQmlIdObjectsArray*>(m));
+ Scope scope(static_cast<const QV4::QQmlIdObjectsArray*>(m)->engine());
+ Scoped<QQmlIdObjectsArray> This(scope, static_cast<const QV4::QQmlIdObjectsArray*>(m));
Scoped<QmlContextWrapper> contextWrapper(scope, This->d()->contextWrapper);
QQmlContextData *context = contextWrapper->getContext();
if (!context) {
diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h
index 52d8677103..c569d09cd7 100644
--- a/src/qml/qml/qqmlcontextwrapper_p.h
+++ b/src/qml/qml/qqmlcontextwrapper_p.h
@@ -48,7 +48,7 @@
#include <QtCore/qglobal.h>
#include <private/qtqmlglobal_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4object_p.h>
#include <private/qqmlcontext_p.h>
#include <private/qv4functionobject_p.h>
@@ -81,7 +81,7 @@ struct QmlContextWrapper : Object {
struct QQmlIdObjectsArray : Object {
QQmlIdObjectsArray(QV4::ExecutionEngine *engine, QV4::QmlContextWrapper *contextWrapper);
- QmlContextWrapper *contextWrapper;
+ Pointer<QmlContextWrapper> contextWrapper;
};
}
@@ -103,7 +103,7 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
void setReadOnly(bool b) { d()->readOnly = b; }
- static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static void markObjects(Heap::Base *m, ExecutionEngine *engine);
@@ -118,7 +118,7 @@ struct QQmlIdObjectsArray : public Object
{
V4_OBJECT2(QQmlIdObjectsArray, Object)
- static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
static void markObjects(Heap::Base *that, ExecutionEngine *engine);
};
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index 04c42b638d..5cef128e7e 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -48,8 +48,9 @@
#include <private/qtqmlglobal_p.h>
#include <private/qobject_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4persistent_p.h>
+#include <qjsengine.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 8a7e4b84e7..fc5d672372 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -247,6 +247,10 @@ void QQmlEnginePrivate::activateDesignerMode()
The QQuickImageProvider::requestPixmap() method will be called for all image requests.
\value Texture The Image Provider provides QSGTextureProvider based images.
The QQuickImageProvider::requestTexture() method will be called for all image requests.
+ \value ImageResponse The Image provider provides QQuickTextureFactory based images.
+ Should only be used in QQuickAsyncImageProvider or its subclasses.
+ The QQuickAsyncImageProvider::requestImageResponse() method will be called for all image requests.
+ Since Qt 5.6
\omitvalue Invalid
*/
@@ -595,8 +599,8 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
QQmlEnginePrivate::~QQmlEnginePrivate()
{
- typedef QHash<QPair<QQmlType *, int>, QQmlPropertyCache *>::Iterator TypePropertyCacheIt;
- typedef QHash<int, QQmlCompiledData *>::Iterator CompositeTypesIt;
+ typedef QHash<QPair<QQmlType *, int>, QQmlPropertyCache *>::const_iterator TypePropertyCacheIt;
+ typedef QHash<int, QQmlCompiledData *>::const_iterator CompositeTypesIt;
if (inProgressCreations)
qWarning() << QQmlEngine::tr("There are still \"%1\" items in the process of being created at engine destruction.").arg(inProgressCreations);
@@ -615,9 +619,9 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
if (incubationController) incubationController->d = 0;
incubationController = 0;
- for (TypePropertyCacheIt iter = typePropertyCache.begin(), end = typePropertyCache.end(); iter != end; ++iter)
+ for (TypePropertyCacheIt iter = typePropertyCache.cbegin(), end = typePropertyCache.cend(); iter != end; ++iter)
(*iter)->release();
- for (CompositeTypesIt iter = m_compositeTypes.begin(), end = m_compositeTypes.end(); iter != end; ++iter) {
+ for (CompositeTypesIt iter = m_compositeTypes.cbegin(), end = m_compositeTypes.cend(); iter != end; ++iter) {
iter.value()->isRegisteredWithEngine = false;
// since unregisterInternalCompositeType() will not be called in this
@@ -812,10 +816,10 @@ void QQmlData::flushPendingBindingImpl(int coreIndex)
// Find the binding
QQmlAbstractBinding *b = bindings;
- while (b && *b->m_mePtr && b->propertyIndex() != coreIndex)
+ while (b && *b->m_mePtr && b->targetPropertyIndex() != coreIndex)
b = b->nextBinding();
- if (b && b->propertyIndex() == coreIndex) {
+ if (b && b->targetPropertyIndex() == coreIndex) {
b->clear();
b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor |
QQmlPropertyPrivate::DontRemoveBinding);
@@ -2243,8 +2247,8 @@ bool QQmlEnginePrivate::isList(int t) const
int QQmlEnginePrivate::listType(int t) const
{
Locker locker(this);
- QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
- if (iter != m_qmlLists.end())
+ QHash<int, int>::ConstIterator iter = m_qmlLists.constFind(t);
+ if (iter != m_qmlLists.cend())
return *iter;
else
return QQmlMetaType::listType(t);
@@ -2253,8 +2257,8 @@ int QQmlEnginePrivate::listType(int t) const
QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const
{
Locker locker(this);
- QHash<int, QQmlCompiledData *>::ConstIterator iter = m_compositeTypes.find(t);
- if (iter != m_compositeTypes.end()) {
+ QHash<int, QQmlCompiledData *>::ConstIterator iter = m_compositeTypes.constFind(t);
+ if (iter != m_compositeTypes.cend()) {
return QQmlMetaObject((*iter)->rootPropertyCache);
} else {
QQmlType *type = QQmlMetaType::qmlType(t);
@@ -2265,8 +2269,8 @@ QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const
QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const
{
Locker locker(this);
- QHash<int, QQmlCompiledData *>::ConstIterator iter = m_compositeTypes.find(t);
- if (iter != m_compositeTypes.end()) {
+ QHash<int, QQmlCompiledData *>::ConstIterator iter = m_compositeTypes.constFind(t);
+ if (iter != m_compositeTypes.cend()) {
return QQmlMetaObject((*iter)->rootPropertyCache);
} else {
QQmlType *type = QQmlMetaType::qmlType(t);
@@ -2277,8 +2281,8 @@ QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const
QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t)
{
Locker locker(this);
- QHash<int, QQmlCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
- if (iter != m_compositeTypes.end()) {
+ QHash<int, QQmlCompiledData*>::ConstIterator iter = m_compositeTypes.constFind(t);
+ if (iter != m_compositeTypes.cend()) {
return (*iter)->rootPropertyCache;
} else {
QQmlType *type = QQmlMetaType::qmlType(t);
@@ -2290,8 +2294,8 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t)
QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
{
Locker locker(this);
- QHash<int, QQmlCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
- if (iter != m_compositeTypes.end()) {
+ QHash<int, QQmlCompiledData*>::ConstIterator iter = m_compositeTypes.constFind(t);
+ if (iter != m_compositeTypes.cend()) {
return (*iter)->rootPropertyCache;
} else {
QQmlType *type = QQmlMetaType::qmlType(t);
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h
index df673c1fd5..61a884279d 100644
--- a/src/qml/qml/qqmlengine.h
+++ b/src/qml/qml/qqmlengine.h
@@ -52,7 +52,9 @@ public:
Image,
Pixmap,
Texture,
- Invalid
+ Invalid,
+ ImageResponse
+ // ### Qt6: reorder these, and give Invalid a fixed large value
};
enum Flag {
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index 35e0bc8c64..3813281044 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -45,13 +45,8 @@
QT_BEGIN_NAMESPACE
-static QQmlJavaScriptExpression::VTable QQmlExpressionPrivate_jsvtable = {
- QQmlExpressionPrivate::expressionIdentifier,
- QQmlExpressionPrivate::expressionChanged
-};
-
QQmlExpressionPrivate::QQmlExpressionPrivate()
-: QQmlJavaScriptExpression(&QQmlExpressionPrivate_jsvtable),
+: QQmlJavaScriptExpression(),
expressionFunctionValid(true),
line(0), column(0)
{
@@ -65,7 +60,7 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr, QOb
{
expression = expr;
- QQmlAbstractExpression::setContext(ctxt);
+ QQmlJavaScriptExpression::setContext(ctxt);
setScopeObject(me);
expressionFunctionValid = false;
}
@@ -74,9 +69,9 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, QV4::Function *runtimeFu
{
expressionFunctionValid = true;
QV4::ExecutionEngine *engine = QQmlEnginePrivate::getV4Engine(ctxt->engine);
- function.set(engine, QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxt, me, runtimeFunction));
+ m_function.set(engine, QV4::QmlBindingWrapper::createQmlCallableForFunction(ctxt, me, runtimeFunction));
- QQmlAbstractExpression::setContext(ctxt);
+ QQmlJavaScriptExpression::setContext(ctxt);
setScopeObject(me);
}
@@ -251,13 +246,11 @@ QV4::ReturnedValue QQmlExpressionPrivate::v4value(bool *isUndefined)
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::get(q->engine())->v4engine();
if (!expressionFunctionValid) {
- function.set(v4, qmlBinding(context(), scopeObject(), expression, url, line, &qmlscope));
+ m_function.set(v4, qmlBinding(context(), scopeObject(), expression, url, line, &qmlscope));
expressionFunctionValid = true;
}
- QV4::Scope scope(v4);
- QV4::ScopedValue f(scope, function.value());
- return evaluate(context(), f, isUndefined);
+ return evaluate(isUndefined);
}
QVariant QQmlExpressionPrivate::value(bool *isUndefined)
@@ -432,22 +425,15 @@ QQmlError QQmlExpression::error() const
calling QQmlExpression::evaluate()) before this signal will be emitted.
*/
-void QQmlExpressionPrivate::expressionChanged(QQmlJavaScriptExpression *e)
-{
- QQmlExpressionPrivate *This = static_cast<QQmlExpressionPrivate *>(e);
- This->expressionChanged();
-}
-
void QQmlExpressionPrivate::expressionChanged()
{
Q_Q(QQmlExpression);
emit q->valueChanged();
}
-QString QQmlExpressionPrivate::expressionIdentifier(QQmlJavaScriptExpression *e)
+QString QQmlExpressionPrivate::expressionIdentifier()
{
- QQmlExpressionPrivate *This = static_cast<QQmlExpressionPrivate *>(e);
- return QLatin1Char('"') + This->expression + QLatin1Char('"');
+ return QLatin1Char('"') + expression + QLatin1Char('"');
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h
index d8da387878..0419c9c11c 100644
--- a/src/qml/qml/qqmlexpression_p.h
+++ b/src/qml/qml/qqmlexpression_p.h
@@ -52,7 +52,6 @@
#include <private/qflagpointer_p.h>
#include <private/qdeletewatcher_p.h>
#include <private/qpointervaluepair_p.h>
-#include <private/qqmlabstractexpression_p.h>
#include <private/qqmljavascriptexpression_p.h>
QT_BEGIN_NAMESPACE
@@ -60,8 +59,7 @@ QT_BEGIN_NAMESPACE
class QQmlExpression;
class QString;
class QQmlExpressionPrivate : public QObjectPrivate,
- public QQmlJavaScriptExpression,
- public QQmlAbstractExpression
+ public QQmlJavaScriptExpression
{
Q_DECLARE_PUBLIC(QQmlExpression)
public:
@@ -82,15 +80,13 @@ public:
bool expressionFunctionValid:1;
- // "Inherited" from QQmlJavaScriptExpression
- static QString expressionIdentifier(QQmlJavaScriptExpression *);
- static void expressionChanged(QQmlJavaScriptExpression *);
+ // Inherited from QQmlJavaScriptExpression
+ virtual QString expressionIdentifier();
virtual void expressionChanged();
QString expression;
QV4::PersistentValue qmlscope;
- QV4::PersistentValue function;
QString url; // This is a QString for a reason. QUrls are slooooooow...
quint16 line;
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 02bd1c4b83..cc57d855c3 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -35,7 +35,7 @@
#include <private/qqmlexpression_p.h>
#include <private/qqmlcontextwrapper_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4script_p.h>
#include <private/qv4errorobject_p.h>
@@ -83,13 +83,22 @@ void QQmlDelayedError::catchJavaScriptException(QV4::ExecutionEngine *engine)
}
-QQmlJavaScriptExpression::QQmlJavaScriptExpression(VTable *v)
-: m_vtable(v)
+QQmlJavaScriptExpression::QQmlJavaScriptExpression()
+ : m_error(0),
+ m_context(0),
+ m_prevExpression(0),
+ m_nextExpression(0)
{
}
QQmlJavaScriptExpression::~QQmlJavaScriptExpression()
{
+ if (m_prevExpression) {
+ *m_prevExpression = m_nextExpression;
+ if (m_nextExpression)
+ m_nextExpression->m_prevExpression = m_prevExpression;
+ }
+
clearGuards();
if (m_scopeObject.isT2()) // notify DeleteWatcher of our deletion.
m_scopeObject.asT2()->_s = 0;
@@ -106,40 +115,62 @@ void QQmlJavaScriptExpression::resetNotifyOnValueChanged()
clearGuards();
}
-QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
- const QV4::Value &function, bool *isUndefined)
+void QQmlJavaScriptExpression::setContext(QQmlContextData *context)
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(context->engine);
+ if (m_prevExpression) {
+ *m_prevExpression = m_nextExpression;
+ if (m_nextExpression)
+ m_nextExpression->m_prevExpression = m_prevExpression;
+ m_prevExpression = 0;
+ m_nextExpression = 0;
+ }
+
+ m_context = context;
+
+ if (context) {
+ m_nextExpression = context->expressions;
+ if (m_nextExpression)
+ m_nextExpression->m_prevExpression = &m_nextExpression;
+ m_prevExpression = &context->expressions;
+ context->expressions = this;
+ }
+}
+
+void QQmlJavaScriptExpression::refresh()
+{
+}
+
+QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(bool *isUndefined)
+{
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_context->engine);
QV4::Scope scope(v4);
QV4::ScopedCallData callData(scope);
- return evaluate(context, function, callData, isUndefined);
+ return evaluate(callData, isUndefined);
}
-QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
- const QV4::Value &function,
- QV4::CallData *callData,
- bool *isUndefined)
+QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefined)
{
- Q_ASSERT(context && context->engine);
+ Q_ASSERT(m_context && m_context->engine);
- if (function.isUndefined()) {
+ QV4::Value *f = m_function.valueRef();
+ if (!f || f->isUndefined()) {
if (isUndefined)
*isUndefined = true;
return QV4::Encode::undefined();
}
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine);
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(m_context->engine);
// All code that follows must check with watcher before it accesses data members
// incase we have been deleted.
DeleteWatcher watcher(this);
Q_ASSERT(notifyOnValueChanged() || activeGuards.isEmpty());
- GuardCapture capture(context->engine, this, &watcher);
+ GuardCapture capture(m_context->engine, this, &watcher);
QQmlEnginePrivate::PropertyCapture *lastPropertyCapture = ep->propertyCapture;
- ep->propertyCapture = notifyOnValueChanged()?&capture:0;
+ ep->propertyCapture = notifyOnValueChanged() ? &capture : 0;
if (notifyOnValueChanged())
@@ -148,14 +179,14 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context,
QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
QV4::Scope scope(v4);
QV4::ScopedValue result(scope, QV4::Primitive::undefinedValue());
- callData->thisObject = v4->globalObject();
+ callData->thisObject = v4->globalObject;
if (scopeObject()) {
QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(v4, scopeObject()));
if (value->isObject())
callData->thisObject = value;
}
- result = function.asFunctionObject()->call(callData);
+ result = f->as<QV4::FunctionObject>()->call(callData);
if (scope.hasException()) {
if (watcher.wasDeleted())
scope.engine->catchException(); // ignore exception
@@ -223,7 +254,7 @@ void QQmlJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c,
if (!errorString) {
errorString = new QStringList;
QString preamble = QLatin1String("QQmlExpression: Expression ") +
- expression->m_vtable->expressionIdentifier(expression) +
+ expression->expressionIdentifier() +
QLatin1String(" depends on non-NOTIFYable properties:");
errorString->append(preamble);
}
@@ -258,25 +289,26 @@ void QQmlJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c,
void QQmlJavaScriptExpression::clearError()
{
- if (m_vtable.hasValue()) {
- m_vtable.value().clearError();
- m_vtable.value().removeError();
- }
+ if (m_error)
+ delete m_error;
+ m_error = 0;
}
QQmlError QQmlJavaScriptExpression::error(QQmlEngine *engine) const
{
Q_UNUSED(engine);
- if (m_vtable.hasValue())
- return m_vtable.constValue()->error();
+ if (m_error)
+ return m_error->error();
else
return QQmlError();
}
QQmlDelayedError *QQmlJavaScriptExpression::delayedError()
{
- return &m_vtable.value();
+ if (!m_error)
+ m_error = new QQmlDelayedError;
+ return m_error;
}
QV4::ReturnedValue
@@ -358,7 +390,7 @@ void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *e, void **)
QQmlJavaScriptExpression *expression =
static_cast<QQmlJavaScriptExpressionGuard *>(e)->expression;
- expression->m_vtable->expressionChanged(expression);
+ expression->expressionChanged();
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index 989d5a0b0d..f846b6570f 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -89,23 +89,17 @@ private:
QQmlDelayedError **prevError;
};
-class QQmlJavaScriptExpression
+class Q_QML_PRIVATE_EXPORT QQmlJavaScriptExpression
{
public:
- // Although this looks crazy, we implement our own "vtable" here, rather than relying on
- // C++ virtuals, to save memory. By doing it ourselves, we can overload the storage
- // location that is use for the vtable to also store the rarely used delayed error.
- // If we use C++ virtuals, we can't do this and it consts us an extra sizeof(void *) in
- // memory for every expression.
- struct VTable {
- QString (*expressionIdentifier)(QQmlJavaScriptExpression *);
- void (*expressionChanged)(QQmlJavaScriptExpression *);
- };
+ QQmlJavaScriptExpression();
+ virtual ~QQmlJavaScriptExpression();
- QQmlJavaScriptExpression(VTable *vtable);
+ virtual QString expressionIdentifier() = 0;
+ virtual void expressionChanged() = 0;
- QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function, bool *isUndefined);
- QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function, QV4::CallData *callData, bool *isUndefined);
+ QV4::ReturnedValue evaluate(bool *isUndefined);
+ QV4::ReturnedValue evaluate(QV4::CallData *callData, bool *isUndefined);
inline bool notifyOnValueChanged() const;
@@ -115,6 +109,13 @@ public:
inline QObject *scopeObject() const;
inline void setScopeObject(QObject *v);
+ bool isValid() const { return context() != 0; }
+
+ QQmlContextData *context() const { return m_context; }
+ void setContext(QQmlContextData *context);
+
+ virtual void refresh();
+
class DeleteWatcher {
public:
inline DeleteWatcher(QQmlJavaScriptExpression *);
@@ -143,10 +144,9 @@ public:
const QString &code,
const QString &filename, quint16 line,
QV4::PersistentValue *qmlscope = 0);
-protected:
- ~QQmlJavaScriptExpression();
private:
+ friend class QQmlContextData;
typedef QQmlJavaScriptExpressionGuard Guard;
friend void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **);
@@ -169,13 +169,20 @@ private:
QStringList *errorString;
};
- QPointerValuePair<VTable, QQmlDelayedError> m_vtable;
+ QQmlDelayedError *m_error;
// We store some flag bits in the following flag pointers.
// activeGuards:flag1 - notifyOnValueChanged
// activeGuards:flag2 - useSharedContext
QBiPointer<QObject, DeleteWatcher> m_scopeObject;
QForwardFieldList<Guard, &Guard::next> activeGuards;
+
+ QQmlContextData *m_context;
+ QQmlJavaScriptExpression **m_prevExpression;
+ QQmlJavaScriptExpression *m_nextExpression;
+
+protected:
+ QV4::PersistentValue m_function;
};
QQmlJavaScriptExpression::DeleteWatcher::DeleteWatcher(QQmlJavaScriptExpression *e)
@@ -222,12 +229,12 @@ void QQmlJavaScriptExpression::setScopeObject(QObject *v)
bool QQmlJavaScriptExpression::hasError() const
{
- return m_vtable.hasValue() && m_vtable.constValue()->isValid();
+ return m_error && m_error->isValid();
}
bool QQmlJavaScriptExpression::hasDelayedError() const
{
- return m_vtable.hasValue();
+ return m_error;
}
QQmlJavaScriptExpressionGuard::QQmlJavaScriptExpressionGuard(QQmlJavaScriptExpression *e)
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index bcb1e72f0b..32a5b36fbb 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -92,10 +92,10 @@ QVariant QmlListWrapper::toVariant() const
}
-ReturnedValue QmlListWrapper::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue QmlListWrapper::get(const Managed *m, String *name, bool *hasProperty)
{
Q_ASSERT(m->as<QmlListWrapper>());
- QmlListWrapper *w = static_cast<QmlListWrapper *>(m);
+ const QmlListWrapper *w = static_cast<const QmlListWrapper *>(m);
QV4::ExecutionEngine *v4 = w->engine();
if (name->equals(v4->id_length) && !w->d()->object.isNull()) {
@@ -110,12 +110,12 @@ ReturnedValue QmlListWrapper::get(Managed *m, String *name, bool *hasProperty)
return Object::get(m, name, hasProperty);
}
-ReturnedValue QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue QmlListWrapper::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
Q_UNUSED(hasProperty);
Q_ASSERT(m->as<QmlListWrapper>());
- QmlListWrapper *w = static_cast<QmlListWrapper *>(m);
+ const QmlListWrapper *w = static_cast<const QmlListWrapper *>(m);
QV4::ExecutionEngine *v4 = w->engine();
quint32 count = w->d()->property.count ? w->d()->property.count(&w->d()->property) : 0;
diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h
index 3590bcb1c9..7e305b9e43 100644
--- a/src/qml/qml/qqmllistwrapper_p.h
+++ b/src/qml/qml/qqmllistwrapper_p.h
@@ -50,7 +50,7 @@
#include <QtQml/qqmllist.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
@@ -81,8 +81,8 @@ struct Q_QML_EXPORT QmlListWrapper : Object
QVariant toVariant() const;
- static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
- static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static void advanceIterator(Managed *m, ObjectIterator *it, Heap::String **name, uint *index, Property *p, PropertyAttributes *attributes);
};
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 62b5b76ede..7f49798da6 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -65,13 +65,13 @@ static bool isLocaleObject(const QV4::Value &val)
void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine)
{
- engine->datePrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
- engine->datePrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleTimeString"), method_toLocaleTimeString);
- engine->datePrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleDateString"), method_toLocaleDateString);
- engine->dateCtor.objectValue()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
- engine->dateCtor.objectValue()->defineDefaultProperty(QStringLiteral("fromLocaleTimeString"), method_fromLocaleTimeString);
- engine->dateCtor.objectValue()->defineDefaultProperty(QStringLiteral("fromLocaleDateString"), method_fromLocaleDateString);
- engine->dateCtor.objectValue()->defineDefaultProperty(QStringLiteral("timeZoneUpdated"), method_timeZoneUpdated);
+ engine->datePrototype()->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
+ engine->datePrototype()->defineDefaultProperty(QStringLiteral("toLocaleTimeString"), method_toLocaleTimeString);
+ engine->datePrototype()->defineDefaultProperty(QStringLiteral("toLocaleDateString"), method_toLocaleDateString);
+ engine->dateCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
+ engine->dateCtor()->defineDefaultProperty(QStringLiteral("fromLocaleTimeString"), method_fromLocaleTimeString);
+ engine->dateCtor()->defineDefaultProperty(QStringLiteral("fromLocaleDateString"), method_fromLocaleDateString);
+ engine->dateCtor()->defineDefaultProperty(QStringLiteral("timeZoneUpdated"), method_timeZoneUpdated);
}
QV4::ReturnedValue QQmlDateExtension::method_toLocaleString(QV4::CallContext *ctx)
@@ -81,7 +81,7 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleString(QV4::CallContext *ct
QV4::Scope scope(ctx);
- QV4::DateObject *date = ctx->thisObject().asDateObject();
+ QV4::DateObject *date = ctx->thisObject().as<DateObject>();
if (!date)
return QV4::DatePrototype::method_toLocaleString(ctx);
@@ -125,7 +125,7 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleTimeString(QV4::CallContext
QV4::Scope scope(ctx);
- QV4::DateObject *date = ctx->thisObject().asDateObject();
+ QV4::DateObject *date = ctx->thisObject().as<DateObject>();
if (!date)
return QV4::DatePrototype::method_toLocaleTimeString(ctx);
@@ -170,7 +170,7 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleDateString(QV4::CallContext
QV4::Scope scope(ctx);
- QV4::DateObject *dateObj = ctx->thisObject().asDateObject();
+ QV4::DateObject *dateObj = ctx->thisObject().as<DateObject>();
if (!dateObj)
return QV4::DatePrototype::method_toLocaleDateString(ctx);
@@ -347,9 +347,9 @@ QV4::ReturnedValue QQmlDateExtension::method_timeZoneUpdated(QV4::CallContext *c
void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine)
{
- engine->numberPrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
- engine->numberPrototype.asObject()->defineDefaultProperty(QStringLiteral("toLocaleCurrencyString"), method_toLocaleCurrencyString);
- engine->numberCtor.objectValue()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
+ engine->numberPrototype()->defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
+ engine->numberPrototype()->defineDefaultProperty(QStringLiteral("toLocaleCurrencyString"), method_toLocaleCurrencyString);
+ engine->numberCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
}
QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(QV4::CallContext *ctx)
@@ -815,15 +815,15 @@ QV4::ReturnedValue QQmlLocale::wrap(ExecutionEngine *v4, const QLocale &locale)
void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine)
{
- engine->stringPrototype.asObject()->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare);
+ engine->stringPrototype()->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare);
}
QV4::ReturnedValue QQmlLocale::method_localeCompare(QV4::CallContext *ctx)
{
- if (ctx->argc() != 1 || (!ctx->args()[0].isString() && !ctx->args()[0].asStringObject()))
+ if (ctx->argc() != 1 || (!ctx->args()[0].isString() && !ctx->args()[0].as<StringObject>()))
return QV4::StringPrototype::method_localeCompare(ctx);
- if (!ctx->thisObject().isString() && !ctx->thisObject().asStringObject())
+ if (!ctx->thisObject().isString() && !ctx->thisObject().as<StringObject>())
return QV4::StringPrototype::method_localeCompare(ctx);
QString thisString = ctx->thisObject().toQStringNoThrow();
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index d4436482cf..d035544329 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -137,7 +137,7 @@ struct QQmlLocaleData : public QV4::Object
V4_NEEDS_DESTROY
static QLocale *getThisLocale(QV4::CallContext *ctx) {
- QV4::Object *o = ctx->thisObject().asObject();
+ QV4::Object *o = ctx->thisObject().as<Object>();
QQmlLocaleData *thisObject = o ? o->as<QQmlLocaleData>() : 0;
if (!thisObject) {
ctx->engine()->throwTypeError();
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 2f7834fa41..2947a03a4a 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -1437,8 +1437,8 @@ bool QQmlMetaType::isAnyModule(const QString &uri)
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- for (QQmlMetaTypeData::TypeModules::ConstIterator iter = data->uriToModule.begin();
- iter != data->uriToModule.end(); ++iter) {
+ for (QQmlMetaTypeData::TypeModules::ConstIterator iter = data->uriToModule.cbegin();
+ iter != data->uriToModule.cend(); ++iter) {
if ((*iter)->module() == uri)
return true;
}
@@ -1715,7 +1715,7 @@ QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStrin
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(name);
- while (it != data->nameToType.end() && it.key() == name) {
+ while (it != data->nameToType.cend() && it.key() == name) {
// XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty
if (version_major < 0 || module.isEmpty() || (*it)->availableInVersion(module, version_major,version_minor))
return (*it);
@@ -1749,7 +1749,7 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStri
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.constFind(metaObject);
- while (it != data->metaObjectToType.end() && it.key() == metaObject) {
+ while (it != data->metaObjectToType.cend() && it.key() == metaObject) {
QQmlType *t = *it;
if (version_major < 0 || module.isEmpty() || t->availableInVersion(module, version_major,version_minor))
return t;
@@ -1820,8 +1820,8 @@ QList<QString> QQmlMetaType::qmlTypeNames()
QQmlMetaTypeData *data = metaTypeData();
QList<QString> names;
- QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.begin();
- while (it != data->nameToType.end()) {
+ QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.cbegin();
+ while (it != data->nameToType.cend()) {
names += (*it)->qmlTypeName();
++it;
}
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 3c2f3690b9..38268528c9 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -62,14 +62,6 @@ struct ActiveOCRestorer
};
}
-static void removeBindingOnProperty(QObject *o, int index)
-{
- int coreIndex;
- int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex);
- QQmlAbstractBinding *binding = QQmlPropertyPrivate::setBinding(o, coreIndex, valueTypeIndex, 0);
- if (binding) binding->destroy();
-}
-
QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData, QQmlContextData *creationContext, void *activeVMEDataForRootContext)
: phase(Startup)
, compiledData(compiledData)
@@ -660,15 +652,12 @@ void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip)
// ### this is best done through type-compile-time binding skip lists.
if (_valueTypeProperty) {
- QQmlAbstractBinding *binding =
- QQmlPropertyPrivate::binding(_bindingTarget, _valueTypeProperty->coreIndex, -1);
+ QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(_bindingTarget, _valueTypeProperty->coreIndex);
if (binding && binding->bindingType() != QQmlAbstractBinding::ValueTypeProxy) {
- QQmlPropertyPrivate::setBinding(_bindingTarget, _valueTypeProperty->coreIndex, -1, 0);
- binding->destroy();
+ QQmlPropertyPrivate::removeBinding(_bindingTarget, _valueTypeProperty->coreIndex, QQmlPropertyPrivate::DestroyOldBinding);
} else if (binding) {
- QQmlValueTypeProxyBinding *proxy =
- static_cast<QQmlValueTypeProxyBinding *>(binding);
+ QQmlValueTypeProxyBinding *proxy = static_cast<QQmlValueTypeProxyBinding *>(binding);
if (qmlTypeForObject(_bindingTarget)) {
quint32 bindingSkipList = 0;
@@ -800,7 +789,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
if (_ddata->hasBindingBit(property->coreIndex) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression)
&& !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment)
&& !_valueTypeProperty)
- removeBindingOnProperty(_bindingTarget, property->coreIndex);
+ QQmlPropertyPrivate::removeBinding(_bindingTarget, property->coreIndex, QQmlPropertyPrivate::DestroyOldBinding);
if (binding->type == QV4::CompiledData::Binding::Type_Script) {
QV4::Function *runtimeFunction = compiledData->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
@@ -831,15 +820,10 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
sharedState->allCreatedBindings.push(qmlBinding);
qmlBinding->m_mePtr = &sharedState->allCreatedBindings.top();
- qmlBinding->setTarget(_bindingTarget, targetCorePropertyData, context);
+ qmlBinding->setTarget(_bindingTarget, targetCorePropertyData);
if (targetCorePropertyData.isAlias()) {
- QQmlAbstractBinding *old =
- QQmlPropertyPrivate::setBindingNoEnable(_bindingTarget,
- targetCorePropertyData.coreIndex,
- targetCorePropertyData.getValueTypeCoreIndex(),
- qmlBinding);
- if (old) { old->destroy(); }
+ QQmlPropertyPrivate::setBinding(qmlBinding, QQmlPropertyPrivate::DontEnable|QQmlPropertyPrivate::DestroyOldBinding);
} else {
qmlBinding->addToObject();
@@ -1124,7 +1108,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
QBitArray bindingsToSkip;
if (customParser) {
- QHash<int, QBitArray>::ConstIterator customParserBindings = compiledData->customParserBindings.find(index);
+ QHash<int, QBitArray>::ConstIterator customParserBindings = compiledData->customParserBindings.constFind(index);
if (customParserBindings != compiledData->customParserBindings.constEnd()) {
customParser->imports = compiledData->importCache;
@@ -1187,9 +1171,9 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
if (!b)
continue;
b->m_mePtr = 0;
- QQmlData *data = QQmlData::get(b->object());
+ QQmlData *data = QQmlData::get(b->targetObject());
Q_ASSERT(data);
- data->clearPendingBindingBit(b->propertyIndex());
+ data->clearPendingBindingBit(b->targetPropertyIndex());
b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor |
QQmlPropertyPrivate::DontRemoveBinding);
@@ -1299,7 +1283,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
QBitArray bindingSkipList = bindingsToSkip;
{
- QHash<int, QBitArray>::ConstIterator deferredBindings = compiledData->deferredBindingsPerObject.find(_compiledObjectIndex);
+ QHash<int, QBitArray>::ConstIterator deferredBindings = compiledData->deferredBindingsPerObject.constFind(_compiledObjectIndex);
if (deferredBindings != compiledData->deferredBindingsPerObject.constEnd()) {
if (bindingSkipList.isEmpty())
bindingSkipList.resize(deferredBindings->count());
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index fc24b15fd2..c6d2d44ee1 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -277,8 +277,8 @@ void QQmlOpenMetaObject::setValue(int id, const QVariant &value)
QVariant QQmlOpenMetaObject::value(const QByteArray &name) const
{
- QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name);
- if (iter == d->type->d->names.end())
+ QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.constFind(name);
+ if (iter == d->type->d->names.cend())
return QVariant();
return d->getData(*iter);
@@ -286,8 +286,8 @@ QVariant QQmlOpenMetaObject::value(const QByteArray &name) const
QVariant &QQmlOpenMetaObject::operator[](const QByteArray &name)
{
- QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name);
- Q_ASSERT(iter != d->type->d->names.end());
+ QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.constFind(name);
+ Q_ASSERT(iter != d->type->d->names.cend());
return d->getData(*iter);
}
@@ -299,10 +299,10 @@ QVariant &QQmlOpenMetaObject::operator[](int id)
bool QQmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val)
{
- QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name);
+ QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.constFind(name);
int id = -1;
- if (iter == d->type->d->names.end()) {
+ if (iter == d->type->d->names.cend()) {
id = createProperty(name.constData(), "") - d->type->d->propertyOffset;
} else {
id = *iter;
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index ae452b727e..54dfd3aa27 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -55,6 +55,7 @@
#include <private/qmetaobject_p.h>
#include <private/qqmlvaluetypewrapper_p.h>
#include <QtCore/qdebug.h>
+#include <cmath>
Q_DECLARE_METATYPE(QList<int>)
Q_DECLARE_METATYPE(QList<qreal>)
@@ -699,8 +700,7 @@ QQmlPropertyPrivate::binding(const QQmlProperty &that)
if (!that.d || !that.isProperty() || !that.d->object)
return 0;
- return binding(that.d->object, that.d->core.coreIndex,
- that.d->core.getValueTypeCoreIndex());
+ return binding(that.d->object, that.d->core.encodedIndex());
}
/*!
@@ -716,61 +716,97 @@ QQmlPropertyPrivate::binding(const QQmlProperty &that)
\a flags is passed through to the binding and is used for the initial update (when
the binding sets the initial value, it will use these flags for the write).
*/
-QQmlAbstractBinding *
-QQmlPropertyPrivate::setBinding(const QQmlProperty &that,
- QQmlAbstractBinding *newBinding,
- WriteFlags flags)
+void
+QQmlPropertyPrivate::setBinding(const QQmlProperty &that, QQmlAbstractBinding *newBinding)
{
+ if (!newBinding) {
+ removeBinding(that);
+ return;
+ }
+
if (!that.d || !that.isProperty() || !that.d->object) {
- if (newBinding)
- newBinding->destroy();
- return 0;
+ newBinding->destroy();
+ return;
}
+ setBinding(newBinding);
+}
- if (newBinding) {
- // In the case that the new binding is provided, we must target the property it
- // is associated with. If we don't do this, retargetBinding() can fail.
- QObject *object = newBinding->object();
- int pi = newBinding->propertyIndex();
+static QQmlAbstractBinding *removeOldBinding(QObject *object, int index, QQmlPropertyPrivate::BindingFlags flags)
+{
+ int coreIndex;
+ int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex);
- int core;
- int vt = QQmlPropertyData::decodeValueTypePropertyIndex(pi, &core);
+ QQmlData *data = QQmlData::get(object, false);
- return setBinding(object, core, vt, newBinding, flags);
- } else {
- return setBinding(that.d->object, that.d->core.coreIndex,
- that.d->core.getValueTypeCoreIndex(),
- newBinding, flags);
+ if (!data || !data->hasBindingBit(coreIndex))
+ return 0;
+
+ QQmlAbstractBinding *oldBinding = data->bindings;
+
+ while (oldBinding && oldBinding->targetPropertyIndex() != coreIndex)
+ oldBinding = oldBinding->nextBinding();
+
+ if (!oldBinding)
+ return 0;
+
+ if (valueTypeIndex != -1 && oldBinding->bindingType() == QQmlAbstractBinding::ValueTypeProxy)
+ oldBinding = static_cast<QQmlValueTypeProxyBinding *>(oldBinding)->binding(index);
+
+ if (!oldBinding)
+ return 0;
+
+ oldBinding->removeFromObject();
+ if (!(flags & QQmlPropertyPrivate::DontEnable))
+ oldBinding->setEnabled(false, 0);
+
+ if (flags & QQmlPropertyPrivate::DestroyOldBinding) {
+ oldBinding->destroy();
+ return 0;
}
+
+ return oldBinding;
+}
+
+QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(QQmlAbstractBinding *b, QQmlPropertyPrivate::BindingFlag flags)
+{
+ return removeBinding(b->targetObject(), b->targetPropertyIndex(), flags);
+}
+
+QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(QObject *o, int index, QQmlPropertyPrivate::BindingFlag flags)
+{
+ Q_ASSERT(o);
+
+ QObject *target;
+ int targetIndex;
+ findAliasTarget(o, index, &target, &targetIndex);
+ return removeOldBinding(target, targetIndex, flags);
+}
+
+QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(const QQmlProperty &that, BindingFlag flags)
+{
+ if (!that.d || !that.isProperty() || !that.d->object)
+ return 0;
+
+ return removeBinding(that.d->object, that.d->core.encodedIndex(), flags);
}
QQmlAbstractBinding *
-QQmlPropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex)
+QQmlPropertyPrivate::binding(QObject *object, int index)
{
QQmlData *data = QQmlData::get(object);
if (!data)
return 0;
- QQmlPropertyData *propertyData =
- data->propertyCache?data->propertyCache->property(coreIndex):0;
- if (propertyData && propertyData->isAlias()) {
- QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
-
- QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
- if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex) || aCoreIndex == -1)
- return 0;
+ findAliasTarget(object, index, &object, &index);
- // This will either be a value type sub-reference or an alias to a value-type sub-reference not both
- Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1);
- aValueTypeIndex = (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex;
- return binding(aObject, aCoreIndex, aValueTypeIndex);
- }
+ int coreIndex;
+ int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex);
if (!data->hasBindingBit(coreIndex))
return 0;
QQmlAbstractBinding *binding = data->bindings;
- while (binding && binding->propertyIndex() != coreIndex)
+ while (binding && binding->targetPropertyIndex() != coreIndex)
binding = binding->nextBinding();
if (binding && valueTypeIndex != -1) {
@@ -786,11 +822,11 @@ QQmlPropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex)
void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex,
QObject **targetObject, int *targetBindingIndex)
{
- int coreIndex;
- int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(bindingIndex, &coreIndex);
-
QQmlData *data = QQmlData::get(object, false);
if (data) {
+ int coreIndex;
+ int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(bindingIndex, &coreIndex);
+
QQmlPropertyData *propertyData =
data->propertyCache?data->propertyCache->property(coreIndex):0;
if (propertyData && propertyData->isAlias()) {
@@ -817,119 +853,30 @@ void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex,
*targetBindingIndex = bindingIndex;
}
-QQmlAbstractBinding *
-QQmlPropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex,
- QQmlAbstractBinding *newBinding, WriteFlags flags)
-{
- QQmlData *data = QQmlData::get(object, 0 != newBinding);
- QQmlAbstractBinding *binding = 0;
- if (data) {
- QQmlPropertyData *propertyData =
- data->propertyCache?data->propertyCache->property(coreIndex):0;
- if (propertyData && propertyData->isAlias()) {
- QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
-
- QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
- if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
- if (newBinding) newBinding->destroy();
- return 0;
- }
-
- // This will either be a value type sub-reference or an alias to a value-type sub-reference not both
- Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1);
- aValueTypeIndex = (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex;
- return setBinding(aObject, aCoreIndex, aValueTypeIndex, newBinding, flags);
- }
- }
-
- if (data && data->hasBindingBit(coreIndex)) {
- binding = data->bindings;
-
- while (binding && binding->propertyIndex() != coreIndex)
- binding = binding->nextBinding();
- }
-
- int index = coreIndex;
- if (valueTypeIndex != -1)
- index = QQmlPropertyData::encodeValueTypePropertyIndex(index, valueTypeIndex);
-
- if (binding && valueTypeIndex != -1 && binding->bindingType() == QQmlAbstractBinding::ValueTypeProxy)
- binding = static_cast<QQmlValueTypeProxyBinding *>(binding)->binding(index);
-
- if (binding) {
- binding->removeFromObject();
- binding->setEnabled(false, 0);
- }
-
- if (newBinding) {
- if (newBinding->propertyIndex() != index || newBinding->object() != object)
- newBinding->retargetBinding(object, index);
-
- Q_ASSERT(newBinding->propertyIndex() == index);
- Q_ASSERT(newBinding->object() == object);
-
- newBinding->addToObject();
- newBinding->setEnabled(true, flags);
- }
-
- return binding;
-}
-
-QQmlAbstractBinding *
-QQmlPropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valueTypeIndex,
- QQmlAbstractBinding *newBinding)
+void QQmlPropertyPrivate::setBinding(QQmlAbstractBinding *binding, BindingFlags flags, WriteFlags writeFlags)
{
- QQmlData *data = QQmlData::get(object, 0 != newBinding);
- QQmlAbstractBinding *binding = 0;
-
- if (data) {
- QQmlPropertyData *propertyData =
- data->propertyCache?data->propertyCache->property(coreIndex):0;
- if (propertyData && propertyData->isAlias()) {
- QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
+ Q_ASSERT(binding);
- QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
- if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
- if (newBinding) newBinding->destroy();
- return 0;
- }
+ QObject *object = binding->targetObject();
+ int index = binding->targetPropertyIndex();
- // This will either be a value type sub-reference or an alias to a value-type sub-reference not both
- Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1);
- aValueTypeIndex = (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex;
- return setBindingNoEnable(aObject, aCoreIndex, aValueTypeIndex, newBinding);
- }
- }
-
- if (data && data->hasBindingBit(coreIndex)) {
- binding = data->bindings;
-
- while (binding && binding->propertyIndex() != coreIndex)
- binding = binding->nextBinding();
+#ifndef QT_NO_DEBUG
+ int coreIndex;
+ QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex);
+ QQmlData *data = QQmlData::get(object, true);
+ if (data->propertyCache) {
+ QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex);
+ Q_ASSERT(propertyData && !propertyData->isAlias());
}
+#endif
- int index = coreIndex;
- if (valueTypeIndex != -1)
- index = QQmlPropertyData::encodeValueTypePropertyIndex(index, valueTypeIndex);
-
- if (binding && valueTypeIndex != -1 && binding->bindingType() == QQmlAbstractBinding::ValueTypeProxy)
- binding = static_cast<QQmlValueTypeProxyBinding *>(binding)->binding(index);
-
- if (binding)
- binding->removeFromObject();
-
- if (newBinding) {
- if (newBinding->propertyIndex() != index || newBinding->object() != object)
- newBinding->retargetBinding(object, index);
-
- Q_ASSERT(newBinding->propertyIndex() == index);
- Q_ASSERT(newBinding->object() == object);
+ removeOldBinding(object, index, flags);
- newBinding->addToObject();
- }
+ binding->addToObject();
+ if (!(flags & DontEnable))
+ binding->setEnabled(true, writeFlags);
- return binding;
}
/*!
@@ -1210,12 +1157,8 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object,
QQmlContextData *context, WriteFlags flags)
{
// Remove any existing bindings on this property
- if (!(flags & DontRemoveBinding) && object) {
- QQmlAbstractBinding *binding = setBinding(object, core.coreIndex,
- core.getValueTypeCoreIndex(),
- 0, flags);
- if (binding) binding->destroy();
- }
+ if (!(flags & DontRemoveBinding) && object)
+ removeBinding(object, core.encodedIndex(), DestroyOldBinding);
bool rv = false;
if (core.isValueTypeVirtual()) {
@@ -1255,7 +1198,7 @@ bool QQmlPropertyPrivate::write(QObject *object,
// Enum values come through the script engine as doubles
if (value.userType() == QVariant::Double) {
double integral;
- double fractional = modf(value.toDouble(), &integral);
+ double fractional = std::modf(value.toDouble(), &integral);
if (qFuzzyIsNull(fractional))
v.convert(QVariant::Int);
}
@@ -1551,7 +1494,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
if (expression->hasError()) {
return false;
} else if (isVarProperty) {
- QV4::FunctionObject *f = result.asFunctionObject();
+ const QV4::FunctionObject *f = result.as<QV4::FunctionObject>();
if (f && f->isBinding()) {
// we explicitly disallow this case to avoid confusion. Users can still store one
// in an array in a var property if they need to, but the common case is user error.
@@ -1569,7 +1512,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
} else if (isUndefined && type == qMetaTypeId<QVariant>()) {
writeValueProperty(object, core, QVariant(), context, flags);
} else if (type == qMetaTypeId<QJSValue>()) {
- QV4::FunctionObject *f = result.asFunctionObject();
+ const QV4::FunctionObject *f = result.as<QV4::FunctionObject>();
if (f && f->isBinding()) {
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
expression->delayedError()->setErrorObject(object);
@@ -1587,7 +1530,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
expression->delayedError()->setErrorDescription(errorStr);
expression->delayedError()->setErrorObject(object);
return false;
- } else if (QV4::FunctionObject *f = result.asFunctionObject()) {
+ } else if (const QV4::FunctionObject *f = result.as<QV4::FunctionObject>()) {
if (f->isBinding())
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
else
diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h
index 98e310ebce..7bbb600ade 100644
--- a/src/qml/qml/qqmlproperty_p.h
+++ b/src/qml/qml/qqmlproperty_p.h
@@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE
class QQmlContext;
class QQmlEnginePrivate;
class QQmlJavaScriptExpression;
+
class Q_QML_PRIVATE_EXPORT QQmlPropertyPrivate : public QQmlRefCount
{
public:
@@ -103,15 +104,19 @@ public:
QQmlContextData *, WriteFlags flags = 0);
static void findAliasTarget(QObject *, int, QObject **, int *);
- static QQmlAbstractBinding *setBinding(QObject *, int coreIndex,
- int valueTypeIndex /* -1 */,
- QQmlAbstractBinding *,
- WriteFlags flags = DontRemoveBinding);
- static QQmlAbstractBinding *setBindingNoEnable(QObject *, int coreIndex,
- int valueTypeIndex /* -1 */,
- QQmlAbstractBinding *);
- static QQmlAbstractBinding *binding(QObject *, int coreIndex,
- int valueTypeIndex /* -1 */);
+ enum BindingFlag {
+ None = 0,
+ DestroyOldBinding = 0x1,
+ DontEnable = 0x2
+ };
+ Q_DECLARE_FLAGS(BindingFlags, BindingFlag)
+
+ static void setBinding(QQmlAbstractBinding *binding, BindingFlags flags = None, WriteFlags writeFlags = DontRemoveBinding);
+
+ static QQmlAbstractBinding *removeBinding(const QQmlProperty &that, BindingFlag flag = None);
+ static QQmlAbstractBinding *removeBinding(QObject *o, int index, QQmlPropertyPrivate::BindingFlag flags = None);
+ static QQmlAbstractBinding *removeBinding(QQmlAbstractBinding *b, BindingFlag flag = None);
+ static QQmlAbstractBinding *binding(QObject *, int index);
static QQmlPropertyData saveValueType(const QQmlPropertyData &,
const QMetaObject *, int,
@@ -128,9 +133,7 @@ public:
// "Public" (to QML) methods
static QQmlAbstractBinding *binding(const QQmlProperty &that);
- static QQmlAbstractBinding *setBinding(const QQmlProperty &that,
- QQmlAbstractBinding *,
- WriteFlags flags = DontRemoveBinding);
+ static void setBinding(const QQmlProperty &that, QQmlAbstractBinding *);
static QQmlBoundSignalExpression *signalExpression(const QQmlProperty &that);
static QQmlBoundSignalExpressionPointer setSignalExpression(const QQmlProperty &that,
QQmlBoundSignalExpression *);
@@ -153,6 +156,7 @@ public:
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyPrivate::WriteFlags)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyPrivate::BindingFlags)
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index dd1f93ec00..168d038f9e 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -42,7 +42,7 @@
#include <private/qqmlaccessors_p.h>
#include <private/qmetaobjectbuilder_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <QtCore/qdebug.h>
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 6ed9ec0d36..4d8c6dd9a5 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -54,7 +54,7 @@
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qvector.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
QT_BEGIN_NAMESPACE
@@ -174,7 +174,6 @@ public:
int propType; // When !NotFullyResolved
const char *propTypeName; // When NotFullyResolved
};
- int coreIndex;
union {
// The notify index is in the range returned by QObjectPrivate::signalIndex().
// This is different from QMetaMethod::methodIndex().
@@ -208,6 +207,7 @@ public:
qintptr accessorData;
};
};
+ int coreIndex;
private:
friend class QQmlPropertyData;
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index d9ea273698..5be478fa65 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -60,7 +60,7 @@
#include <private/qflagpointer_p.h>
#include <private/qqmlirbuilder_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4script_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index d0658f2c3c..23cc12c895 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -125,7 +125,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, cons
const Import *i = static_cast<const Import *>(importNamespace);
Q_ASSERT(i->scriptIndex == -1);
- QMap<const Import *, QStringHash<Import> >::const_iterator it = m_namespacedImports.find(i);
+ QMap<const Import *, QStringHash<Import> >::const_iterator it = m_namespacedImports.constFind(i);
if (it != m_namespacedImports.constEnd()) {
Result r = query(*it, name);
if (r.isValid())
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 8a2118ef27..3d22b0b38f 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -124,14 +124,14 @@ ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, Q
}
-ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasProperty)
{
Q_ASSERT(m->as<QmlTypeWrapper>());
- QV4::ExecutionEngine *v4 = static_cast<QmlTypeWrapper *>(m)->engine();
+ QV4::ExecutionEngine *v4 = static_cast<const QmlTypeWrapper *>(m)->engine();
QV4::Scope scope(v4);
- Scoped<QmlTypeWrapper> w(scope, static_cast<QmlTypeWrapper *>(m));
+ Scoped<QmlTypeWrapper> w(scope, static_cast<const QmlTypeWrapper *>(m));
if (hasProperty)
*hasProperty = true;
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index 660d2836ff..14741a5bad 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -48,7 +48,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qpointer.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
@@ -94,7 +94,7 @@ struct Q_QML_EXPORT QmlTypeWrapper : Object
Heap::QmlTypeWrapper::TypeNameMode = Heap::QmlTypeWrapper::IncludeEnums);
- static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static PropertyAttributes query(const Managed *, String *name);
static bool isEqualTo(Managed *that, Managed *o);
diff --git a/src/qml/qml/qqmlvaluetypeproxybinding.cpp b/src/qml/qml/qqmlvaluetypeproxybinding.cpp
index cfc9b196d2..f0457d25e3 100644
--- a/src/qml/qml/qqmlvaluetypeproxybinding.cpp
+++ b/src/qml/qml/qqmlvaluetypeproxybinding.cpp
@@ -35,17 +35,6 @@
QT_BEGIN_NAMESPACE
-// Used in qqmlabstractbinding.cpp
-QQmlAbstractBinding::VTable QQmlValueTypeProxyBinding_vtable = {
- QQmlAbstractBinding::default_destroy<QQmlValueTypeProxyBinding>,
- QQmlAbstractBinding::default_expression,
- QQmlValueTypeProxyBinding::propertyIndex,
- QQmlValueTypeProxyBinding::object,
- QQmlValueTypeProxyBinding::setEnabled,
- QQmlValueTypeProxyBinding::update,
- QQmlAbstractBinding::default_retargetBinding
-};
-
QQmlValueTypeProxyBinding::QQmlValueTypeProxyBinding(QObject *o, int index)
: QQmlAbstractBinding(ValueTypeProxy), m_object(o), m_index(index), m_bindings(0)
{
@@ -64,51 +53,20 @@ QQmlValueTypeProxyBinding::~QQmlValueTypeProxyBinding()
}
}
-void QQmlValueTypeProxyBinding::setEnabled(QQmlAbstractBinding *_This,
- bool e, QQmlPropertyPrivate::WriteFlags flags)
+void QQmlValueTypeProxyBinding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags)
{
- QQmlValueTypeProxyBinding *This = static_cast<QQmlValueTypeProxyBinding *>(_This);
-
- if (e) {
- QQmlAbstractBinding *bindings = This->m_bindings;
- This->recursiveEnable(bindings, flags);
- } else {
- QQmlAbstractBinding *bindings = This->m_bindings;
- This->recursiveDisable(bindings);
+ QQmlAbstractBinding *b = m_bindings;
+ while (b) {
+ b->setEnabled(e, flags);
+ b = b->nextBinding();
}
}
-void QQmlValueTypeProxyBinding::recursiveEnable(QQmlAbstractBinding *b, QQmlPropertyPrivate::WriteFlags flags)
-{
- if (!b)
- return;
-
- recursiveEnable(b->nextBinding(), flags);
-
- if (b)
- b->setEnabled(true, flags);
-}
-
-void QQmlValueTypeProxyBinding::recursiveDisable(QQmlAbstractBinding *b)
-{
- if (!b)
- return;
-
- recursiveDisable(b->nextBinding());
-
- if (b)
- b->setEnabled(false, 0);
-}
-
-void QQmlValueTypeProxyBinding::update(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags)
-{
-}
-
QQmlAbstractBinding *QQmlValueTypeProxyBinding::binding(int propertyIndex)
{
QQmlAbstractBinding *binding = m_bindings;
- while (binding && binding->propertyIndex() != propertyIndex)
+ while (binding && binding->targetPropertyIndex() != propertyIndex)
binding = binding->nextBinding();
return binding;
@@ -123,7 +81,7 @@ void QQmlValueTypeProxyBinding::removeBindings(quint32 mask)
QQmlAbstractBinding *lastBinding = 0;
while (binding) {
- int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(binding->propertyIndex());
+ int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(binding->targetPropertyIndex());
if (valueTypeIndex != -1 && (mask & (1 << valueTypeIndex))) {
QQmlAbstractBinding *remove = binding;
binding = remove->nextBinding();
@@ -143,22 +101,12 @@ void QQmlValueTypeProxyBinding::removeBindings(quint32 mask)
}
}
-int QQmlValueTypeProxyBinding::propertyIndex(const QQmlAbstractBinding *This)
-{
- return static_cast<const QQmlValueTypeProxyBinding *>(This)->m_index;
-}
-
-QObject *QQmlValueTypeProxyBinding::object(const QQmlAbstractBinding *This)
-{
- return static_cast<const QQmlValueTypeProxyBinding *>(This)->m_object;
-}
-
-int QQmlValueTypeProxyBinding::propertyIndex() const
+int QQmlValueTypeProxyBinding::targetPropertyIndex() const
{
return m_index;
}
-QObject *QQmlValueTypeProxyBinding::object() const
+QObject *QQmlValueTypeProxyBinding::targetObject() const
{
return m_object;
}
diff --git a/src/qml/qml/qqmlvaluetypeproxybinding_p.h b/src/qml/qml/qqmlvaluetypeproxybinding_p.h
index 873fbb4af1..c73c944efd 100644
--- a/src/qml/qml/qqmlvaluetypeproxybinding_p.h
+++ b/src/qml/qml/qqmlvaluetypeproxybinding_p.h
@@ -54,26 +54,17 @@ class QQmlValueTypeProxyBinding : public QQmlAbstractBinding
public:
QQmlValueTypeProxyBinding(QObject *o, int coreIndex);
- int propertyIndex() const;
- QObject *object() const;
-
- QQmlAbstractBinding *binding(int propertyIndex);
-
+ QQmlAbstractBinding *binding(int targetPropertyIndex);
void removeBindings(quint32 mask);
- // "Inherited" from QQmlAbstractBinding
- static void setEnabled(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags);
- static void update(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags);
- static int propertyIndex(const QQmlAbstractBinding *);
- static QObject *object(const QQmlAbstractBinding *);
+ virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags);
+ virtual int targetPropertyIndex() const;
+ virtual QObject *targetObject() const;
protected:
~QQmlValueTypeProxyBinding();
private:
- void recursiveEnable(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags);
- void recursiveDisable(QQmlAbstractBinding *);
-
friend class QQmlAbstractBinding;
QObject *m_object;
int m_index;
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 67092438a7..b4d5faa4cf 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -292,7 +292,7 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx)
{
- Object *o = ctx->thisObject().asObject();
+ Object *o = ctx->thisObject().as<Object>();
if (!o)
return ctx->engine()->throwTypeError();
QQmlValueTypeWrapper *w = o->as<QQmlValueTypeWrapper>();
@@ -325,14 +325,14 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx)
return Encode(ctx->engine()->newString(result));
}
-ReturnedValue QQmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *hasProperty)
{
Q_ASSERT(m->as<QQmlValueTypeWrapper>());
- QQmlValueTypeWrapper *r = static_cast<QQmlValueTypeWrapper *>(m);
+ const QQmlValueTypeWrapper *r = static_cast<const QQmlValueTypeWrapper *>(m);
QV4::ExecutionEngine *v4 = r->engine();
// Note: readReferenceValue() can change the reference->type.
- if (QQmlValueTypeReference *reference = r->as<QQmlValueTypeReference>()) {
+ if (const QQmlValueTypeReference *reference = r->as<QQmlValueTypeReference>()) {
if (!reference->readReferenceValue())
return Primitive::undefinedValue().asReturnedValue();
}
@@ -408,45 +408,42 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
QMetaProperty property = metaObject->property(pd->coreIndex);
Q_ASSERT(property.isValid());
- QQmlBinding *newBinding = 0;
-
- QV4::ScopedFunctionObject f(scope, value);
- if (reference && f) {
- if (!f->isBinding()) {
- // assigning a JS function to a non-var-property is not allowed.
- QString error = QStringLiteral("Cannot assign JavaScript function to value-type property");
- ScopedString e(scope, v4->newString(error));
- v4->throwError(e);
- return;
- }
+ if (reference) {
+ QV4::ScopedFunctionObject f(scope, value);
+ if (f) {
+ if (!f->isBinding()) {
+ // assigning a JS function to a non-var-property is not allowed.
+ QString error = QStringLiteral("Cannot assign JavaScript function to value-type property");
+ ScopedString e(scope, v4->newString(error));
+ v4->throwError(e);
+ return;
+ }
- QQmlContextData *context = QmlContextWrapper::callingContext(v4);
+ QQmlContextData *context = QmlContextWrapper::callingContext(v4);
- QQmlPropertyData cacheData;
- cacheData.setFlags(QQmlPropertyData::IsWritable |
- QQmlPropertyData::IsValueTypeVirtual);
- cacheData.propType = writeBackPropertyType;
- cacheData.coreIndex = reference->d()->property;
- cacheData.valueTypeFlags = 0;
- cacheData.valueTypeCoreIndex = pd->coreIndex;
- cacheData.valueTypePropType = property.userType();
+ QQmlPropertyData cacheData;
+ cacheData.setFlags(QQmlPropertyData::IsWritable |
+ QQmlPropertyData::IsValueTypeVirtual);
+ cacheData.propType = writeBackPropertyType;
+ cacheData.coreIndex = reference->d()->property;
+ cacheData.valueTypeFlags = 0;
+ cacheData.valueTypeCoreIndex = pd->coreIndex;
+ cacheData.valueTypePropType = property.userType();
- QV4::Scoped<QQmlBindingFunction> bindingFunction(scope, (const Value &)f);
- bindingFunction->initBindingLocation();
+ QV4::Scoped<QQmlBindingFunction> bindingFunction(scope, (const Value &)f);
+ bindingFunction->initBindingLocation();
- newBinding = new QQmlBinding(value, reference->d()->object, context);
- newBinding->setTarget(reference->d()->object, cacheData, context);
- }
+ QQmlBinding *newBinding = new QQmlBinding(value, reference->d()->object, context);
+ newBinding->setTarget(reference->d()->object, cacheData);
+ QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::DestroyOldBinding);
+ return;
+ } else {
+ QQmlPropertyPrivate::removeBinding(reference->d()->object, QQmlPropertyData::encodeValueTypePropertyIndex(reference->d()->property, pd->coreIndex),
+ QQmlPropertyPrivate::DestroyOldBinding);
- if (reference) {
- QQmlAbstractBinding *oldBinding =
- QQmlPropertyPrivate::setBinding(reference->d()->object, reference->d()->property, pd->coreIndex, newBinding);
- if (oldBinding)
- oldBinding->destroy();
+ }
}
- if (newBinding)
- return;
QVariant v = v4->toVariant(value, property.userType());
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index cad48e661c..5f0edfb71d 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -48,7 +48,7 @@
#include <QtCore/qglobal.h>
#include <private/qtqmlglobal_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
@@ -89,7 +89,7 @@ public:
int typeId() const;
bool write(QObject *target, int propertyIndex) const;
- static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const Value &value);
static bool isEqualTo(Managed *m, Managed *other);
static PropertyAttributes query(const Managed *, String *name);
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 5b1be15869..15017a2572 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -874,10 +874,8 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
int flags = *reinterpret_cast<int*>(a[3]);
if (flags & QQmlPropertyPrivate::RemoveBindingOnAliasWrite) {
QQmlData *targetData = QQmlData::get(target);
- if (targetData && targetData->hasBindingBit(d->propertyIndex())) {
- QQmlAbstractBinding *binding = QQmlPropertyPrivate::setBinding(target, d->propertyIndex(), d->isValueTypeAlias()?d->valueTypeIndex():-1, 0);
- if (binding) binding->destroy();
- }
+ if (targetData && targetData->hasBindingBit(d->propertyIndex()))
+ QQmlPropertyPrivate::removeBinding(target, d->propertyIdx, QQmlPropertyPrivate::DestroyOldBinding);
}
}
@@ -1183,7 +1181,7 @@ void QQmlVMEMetaObject::setVmeMethod(int index, const QV4::Value &function)
v8methods = new QV4::PersistentValue[metaData->methodCount];
int methodIndex = index - methodOffset() - plainSignals;
- v8methods[methodIndex].set(function.asObject()->engine(), function);
+ v8methods[methodIndex].set(function.as<QV4::Object>()->engine(), function);
}
QV4::ReturnedValue QQmlVMEMetaObject::vmeProperty(int index)
@@ -1251,7 +1249,7 @@ void QQmlVMEMetaObject::mark(QV4::ExecutionEngine *e)
void QQmlVMEMetaObject::allocateVarPropertiesArray()
{
QQmlEngine *qml = qmlEngine(object);
- assert(qml);
+ Q_ASSERT(qml);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(qml->handle());
QV4::Scope scope(v4);
varProperties.set(scope.engine, v4->newArrayObject(metaData->varPropertyCount));
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index d0e2e34ff1..44809a26f0 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -63,7 +63,7 @@
#include <private/qv8engine_p.h>
#include <private/qflagpointer_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 2a3ede6a22..fd06ff4654 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -60,6 +60,7 @@
#include <private/qv4objectproto_p.h>
#include <private/qv4scopedvalue_p.h>
#include <private/qv4arraybuffer_p.h>
+#include <private/qv4jsonobject_p.h>
using namespace QV4;
@@ -222,8 +223,8 @@ public:
static ReturnedValue create(ExecutionEngine *, NodeImpl *, const QList<NodeImpl *> &);
// JS API
- static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
- static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
};
Heap::NamedNodeMap::NamedNodeMap(ExecutionEngine *engine, NodeImpl *data, const QList<NodeImpl *> &list)
@@ -244,8 +245,8 @@ public:
V4_NEEDS_DESTROY
// JS API
- static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
- static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
+ static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
// C++ API
static ReturnedValue create(ExecutionEngine *, NodeImpl *);
@@ -871,10 +872,10 @@ bool Node::isNull() const
return d()->d == 0;
}
-ReturnedValue NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue NamedNodeMap::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
Q_ASSERT(m->as<NamedNodeMap>());
- NamedNodeMap *r = static_cast<NamedNodeMap *>(m);
+ const NamedNodeMap *r = static_cast<const NamedNodeMap *>(m);
QV4::ExecutionEngine *v4 = r->engine();
if ((int)index < r->d()->list.count()) {
@@ -887,10 +888,10 @@ ReturnedValue NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty
return Encode::undefined();
}
-ReturnedValue NamedNodeMap::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue NamedNodeMap::get(const Managed *m, String *name, bool *hasProperty)
{
Q_ASSERT(m->as<NamedNodeMap>());
- NamedNodeMap *r = static_cast<NamedNodeMap *>(m);
+ const NamedNodeMap *r = static_cast<const NamedNodeMap *>(m);
QV4::ExecutionEngine *v4 = r->engine();
name->makeIdentifier(v4);
@@ -916,10 +917,10 @@ ReturnedValue NamedNodeMap::create(ExecutionEngine *v4, NodeImpl *data, const QL
return (v4->memoryManager->alloc<NamedNodeMap>(v4, data, list))->asReturnedValue();
}
-ReturnedValue NodeList::getIndexed(Managed *m, uint index, bool *hasProperty)
+ReturnedValue NodeList::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
Q_ASSERT(m->as<NodeList>());
- NodeList *r = static_cast<NodeList *>(m);
+ const NodeList *r = static_cast<const NodeList *>(m);
QV4::ExecutionEngine *v4 = r->engine();
if ((int)index < r->d()->d->children.count()) {
@@ -932,10 +933,10 @@ ReturnedValue NodeList::getIndexed(Managed *m, uint index, bool *hasProperty)
return Encode::undefined();
}
-ReturnedValue NodeList::get(Managed *m, String *name, bool *hasProperty)
+ReturnedValue NodeList::get(const Managed *m, String *name, bool *hasProperty)
{
Q_ASSERT(m->as<NodeList>());
- NodeList *r = static_cast<NodeList *>(m);
+ const NodeList *r = static_cast<const NodeList *>(m);
QV4::ExecutionEngine *v4 = r->engine();
name->makeIdentifier(v4);
@@ -1026,6 +1027,8 @@ public:
const QString & responseType() const;
void setResponseType(const QString &);
+
+ QV4::ReturnedValue jsonResponseBody(QV4::ExecutionEngine*);
private slots:
void readyRead();
void error(QNetworkReply::NetworkError);
@@ -1076,6 +1079,7 @@ private:
QNetworkAccessManager *networkAccessManager() { return m_nam; }
QString m_responseType;
+ QV4::PersistentValue m_parsedJson;
};
QQmlXMLHttpRequest::QQmlXMLHttpRequest(ExecutionEngine *engine, QNetworkAccessManager *manager)
@@ -1083,6 +1087,7 @@ QQmlXMLHttpRequest::QQmlXMLHttpRequest(ExecutionEngine *engine, QNetworkAccessMa
, m_state(Unsent), m_errorFlag(false), m_sendFlag(false)
, m_redirectCount(0), m_gotXml(false), m_textCodec(0), m_network(0), m_nam(manager)
, m_responseType()
+ , m_parsedJson()
{
}
@@ -1478,6 +1483,24 @@ void QQmlXMLHttpRequest::setResponseType(const QString &responseType)
m_responseType = responseType;
}
+QV4::ReturnedValue QQmlXMLHttpRequest::jsonResponseBody(QV4::ExecutionEngine* engine)
+{
+ if (m_parsedJson.isEmpty()) {
+ Scope scope(engine);
+
+ QJsonParseError error;
+ const QString& jtext = responseBody();
+ JsonParser parser(scope.engine, jtext.constData(), jtext.length());
+ ScopedValue jsonObject(scope, parser.parse(&error));
+ if (error.error != QJsonParseError::NoError)
+ return engine->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"));
+
+ m_parsedJson.set(scope.engine, jsonObject);
+ }
+
+ return m_parsedJson.value();
+}
+
#ifndef QT_NO_TEXTCODEC
QTextCodec* QQmlXMLHttpRequest::findTextCodec() const
@@ -1599,7 +1622,7 @@ struct QQmlXMLHttpRequestWrapper : Object {
struct QQmlXMLHttpRequestCtor : FunctionObject {
QQmlXMLHttpRequestCtor(ExecutionEngine *engine);
- Object *proto;
+ Pointer<Object> proto;
};
}
@@ -1625,9 +1648,9 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
c->proto->mark(e);
FunctionObject::markObjects(that, e);
}
- static ReturnedValue construct(Managed *that, QV4::CallData *)
+ static ReturnedValue construct(const Managed *that, QV4::CallData *)
{
- Scope scope(static_cast<QQmlXMLHttpRequestCtor *>(that)->engine());
+ Scope scope(static_cast<const QQmlXMLHttpRequestCtor *>(that)->engine());
Scoped<QQmlXMLHttpRequestCtor> ctor(scope, that->as<QQmlXMLHttpRequestCtor>());
if (!ctor)
return scope.engine->throwTypeError();
@@ -1639,7 +1662,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
return w.asReturnedValue();
}
- static ReturnedValue call(Managed *, QV4::CallData *) {
+ static ReturnedValue call(const Managed *, QV4::CallData *) {
return Primitive::undefinedValue().asReturnedValue();
}
@@ -1986,6 +2009,8 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(CallContext *ctx)
return QV4::Encode(scope.engine->newString(r->responseBody()));
} else if (responseType.compare(QLatin1String("arraybuffer"), Qt::CaseInsensitive) == 0) {
return QV4::Encode(scope.engine->newArrayBuffer(r->rawResponseBody()));
+ } else if (responseType.compare(QLatin1String("json"), Qt::CaseInsensitive) == 0) {
+ return r->jsonResponseBody(scope.engine);
} else {
return QV4::Encode(scope.engine->newString(QString()));
}
@@ -2033,7 +2058,7 @@ void *qt_add_qmlxmlhttprequest(ExecutionEngine *v4)
Scoped<QQmlXMLHttpRequestCtor> ctor(scope, v4->memoryManager->alloc<QQmlXMLHttpRequestCtor>(v4));
ScopedString s(scope, v4->newString(QStringLiteral("XMLHttpRequest")));
- v4->globalObject()->defineReadonlyProperty(s, ctor);
+ v4->globalObject->defineReadonlyProperty(s, ctor);
QQmlXMLHttpRequestData *data = new QQmlXMLHttpRequestData;
return data;
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index f53b9a0c7d..17dfeea168 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -51,6 +51,7 @@
#include <private/qv4include_p.h>
#include <private/qv4context_p.h>
#include <private/qv4stringobject_p.h>
+#include <private/qv4dateobject_p.h>
#include <private/qv4mm_p.h>
#include <private/qv4jsonobject_p.h>
#include <private/qv4objectproto_p.h>
@@ -669,7 +670,7 @@ ReturnedValue QtObject::method_formatTime(QV4::CallContext *ctx)
QVariant argVariant = ctx->engine()->toVariant(ctx->args()[0], -1);
QTime time;
- if (ctx->args()[0].asDateObject() || (argVariant.type() == QVariant::String))
+ if (ctx->args()[0].as<DateObject>() || (argVariant.type() == QVariant::String))
time = argVariant.toDateTime().time();
else // if (argVariant.type() == QVariant::Time), or invalid.
time = argVariant.toTime();
@@ -1178,7 +1179,7 @@ ReturnedValue QtObject::method_locale(CallContext *ctx)
return QQmlLocale::locale(ctx->engine(), code);
}
-Heap::QQmlBindingFunction::QQmlBindingFunction(QV4::FunctionObject *originalFunction)
+Heap::QQmlBindingFunction::QQmlBindingFunction(const QV4::FunctionObject *originalFunction)
: QV4::Heap::FunctionObject(originalFunction->scope(), originalFunction->name())
, originalFunction(originalFunction->d())
{
@@ -1191,10 +1192,10 @@ void QQmlBindingFunction::initBindingLocation()
d()->bindingLocation.line = frame.line;
}
-ReturnedValue QQmlBindingFunction::call(Managed *that, CallData *callData)
+ReturnedValue QQmlBindingFunction::call(const Managed *that, CallData *callData)
{
- Scope scope(static_cast<QQmlBindingFunction*>(that)->engine());
- ScopedFunctionObject function(scope, static_cast<QQmlBindingFunction*>(that)->d()->originalFunction);
+ Scope scope(static_cast<const QQmlBindingFunction*>(that)->engine());
+ ScopedFunctionObject function(scope, static_cast<const QQmlBindingFunction*>(that)->d()->originalFunction);
return function->call(callData);
}
@@ -1256,7 +1257,7 @@ ReturnedValue QtObject::method_binding(CallContext *ctx)
{
if (ctx->argc() != 1)
V4THROW_ERROR("binding() requires 1 argument");
- QV4::FunctionObject *f = ctx->args()[0].asFunctionObject();
+ const QV4::FunctionObject *f = ctx->args()[0].as<FunctionObject>();
if (!f)
V4THROW_TYPE("binding(): argument (binding expression) must be a function");
@@ -1267,7 +1268,7 @@ ReturnedValue QtObject::method_binding(CallContext *ctx)
ReturnedValue QtObject::method_get_platform(CallContext *ctx)
{
// ### inefficient. Should be just a value based getter
- Object *o = ctx->thisObject().asObject();
+ Object *o = ctx->thisObject().as<Object>();
if (!o)
return ctx->engine()->throwTypeError();
QtObject *qt = o->as<QtObject>();
@@ -1284,7 +1285,7 @@ ReturnedValue QtObject::method_get_platform(CallContext *ctx)
ReturnedValue QtObject::method_get_application(CallContext *ctx)
{
// ### inefficient. Should be just a value based getter
- Object *o = ctx->thisObject().asObject();
+ Object *o = ctx->thisObject().as<Object>();
if (!o)
return ctx->engine()->throwTypeError();
QtObject *qt = o->as<QtObject>();
@@ -1379,7 +1380,7 @@ static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *c
if (i != 0)
result.append(QLatin1Char(' '));
- if (ctx->args()[i].asArrayObject())
+ if (ctx->args()[i].as<ArrayObject>())
result.append(QStringLiteral("[") + ctx->args()[i].toQStringNoThrow() + QStringLiteral("]"));
else
result.append(ctx->args()[i].toQStringNoThrow());
@@ -1612,7 +1613,7 @@ void QV4::GlobalExtensions::init(QQmlEngine *qmlEngine, Object *globalObject)
globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt);
// string prototype extension
- v4->stringPrototype.asObject()->defineDefaultProperty(QStringLiteral("arg"), method_string_arg);
+ v4->stringPrototype()->defineDefaultProperty(QStringLiteral("arg"), method_string_arg);
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index b78375118b..bdd53fe601 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -68,8 +68,8 @@ struct ConsoleObject : Object {
};
struct QQmlBindingFunction : FunctionObject {
- QQmlBindingFunction(QV4::FunctionObject *originalFunction);
- FunctionObject *originalFunction;
+ QQmlBindingFunction(const QV4::FunctionObject *originalFunction);
+ Pointer<FunctionObject> originalFunction;
// Set when the binding is created later
QQmlSourceLocation bindingLocation;
};
@@ -166,7 +166,7 @@ struct QQmlBindingFunction : public QV4::FunctionObject
void initBindingLocation(); // from caller stack trace
- static ReturnedValue call(Managed *that, CallData *callData);
+ static ReturnedValue call(const Managed *that, CallData *callData);
static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
diff --git a/src/qml/qml/v8/qv4domerrors.cpp b/src/qml/qml/v8/qv4domerrors.cpp
index c318e2e550..1baaa113aa 100644
--- a/src/qml/qml/v8/qv4domerrors.cpp
+++ b/src/qml/qml/v8/qv4domerrors.cpp
@@ -59,7 +59,7 @@ void qt_add_domexceptions(ExecutionEngine *e)
domexception->defineReadonlyProperty(QStringLiteral("INVALID_ACCESS_ERR"), Primitive::fromInt32(DOMEXCEPTION_INVALID_ACCESS_ERR));
domexception->defineReadonlyProperty(QStringLiteral("VALIDATION_ERR"), Primitive::fromInt32(DOMEXCEPTION_VALIDATION_ERR));
domexception->defineReadonlyProperty(QStringLiteral("TYPE_MISMATCH_ERR"), Primitive::fromInt32(DOMEXCEPTION_TYPE_MISMATCH_ERR));
- e->globalObject()->defineDefaultProperty(QStringLiteral("DOMException"), domexception);
+ e->globalObject->defineDefaultProperty(QStringLiteral("DOMException"), domexception);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv4sqlerrors.cpp b/src/qml/qml/v8/qv4sqlerrors.cpp
index b7a5b71540..c61e57560d 100644
--- a/src/qml/qml/v8/qv4sqlerrors.cpp
+++ b/src/qml/qml/v8/qv4sqlerrors.cpp
@@ -51,7 +51,7 @@ void qt_add_sqlexceptions(QV4::ExecutionEngine *engine)
sqlexception->defineReadonlyProperty(QStringLiteral("SYNTAX_ERR"), Primitive::fromInt32(SQLEXCEPTION_SYNTAX_ERR));
sqlexception->defineReadonlyProperty(QStringLiteral("CONSTRAINT_ERR"), Primitive::fromInt32(SQLEXCEPTION_CONSTRAINT_ERR));
sqlexception->defineReadonlyProperty(QStringLiteral("TIMEOUT_ERR"), Primitive::fromInt32(SQLEXCEPTION_TIMEOUT_ERR));
- engine->globalObject()->defineDefaultProperty(QStringLiteral("SQLException"), sqlexception);
+ engine->globalObject->defineDefaultProperty(QStringLiteral("SQLException"), sqlexception);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index a7c63c9df1..be28b948f5 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -61,7 +61,7 @@
#include <QtCore/qdatastream.h>
#include <private/qsimd_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4dateobject_p.h>
#include <private/qv4objectiterator_p.h>
#include <private/qv4mm_p.h>
@@ -179,7 +179,7 @@ QQmlContextData *QV8Engine::callingContext()
void QV8Engine::initializeGlobal()
{
QV4::Scope scope(m_v4Engine);
- QV4::GlobalExtensions::init(m_engine, m_v4Engine->globalObject());
+ QV4::GlobalExtensions::init(m_engine, m_v4Engine->globalObject);
QQmlLocale::registerStringLocaleCompare(m_v4Engine);
QQmlDateExtension::registerExtension(m_v4Engine);
@@ -191,9 +191,9 @@ void QV8Engine::initializeGlobal()
qt_add_sqlexceptions(m_v4Engine);
{
- for (uint i = 0; i < m_v4Engine->globalObject()->internalClass()->size; ++i) {
- if (m_v4Engine->globalObject()->internalClass()->nameMap.at(i))
- m_illegalNames.insert(m_v4Engine->globalObject()->internalClass()->nameMap.at(i)->string);
+ for (uint i = 0; i < m_v4Engine->globalObject->internalClass()->size; ++i) {
+ if (m_v4Engine->globalObject->internalClass()->nameMap.at(i))
+ m_illegalNames.insert(m_v4Engine->globalObject->internalClass()->nameMap.at(i)->string);
}
}
@@ -229,7 +229,7 @@ void QV8Engine::freezeObject(const QV4::Value &value)
QV4::ScopedFunctionObject f(scope, m_freezeObject.value());
QV4::ScopedCallData callData(scope, 1);
callData->args[0] = value;
- callData->thisObject = m_v4Engine->globalObject();
+ callData->thisObject = m_v4Engine->globalObject;
f->call(callData);
}
@@ -266,9 +266,7 @@ void QV8Engine::setExtensionData(int index, Deletable *data)
void QV8Engine::initQmlGlobalObject()
{
initializeGlobal();
- QV4::Scope scope(m_v4Engine);
- QV4::ScopedValue v(scope, m_v4Engine->globalObject());
- freezeObject(v);
+ freezeObject(*m_v4Engine->globalObject);
}
void QV8Engine::setEngine(QQmlEngine *engine)
@@ -279,7 +277,7 @@ void QV8Engine::setEngine(QQmlEngine *engine)
QV4::ReturnedValue QV8Engine::global()
{
- return m_v4Engine->globalObject()->asReturnedValue();
+ return m_v4Engine->globalObject->asReturnedValue();
}
void QV8Engine::startTimer(const QString &timerName)
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index fb538772d1..94e7d2f140 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -60,7 +60,7 @@
#include <private/qqmlpropertycache_p.h>
#include <private/qv4qobjectwrapper_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4object_p.h>
#include <private/qv4identifier_p.h>
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index 7814fa6d56..43c583ca84 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -277,21 +277,17 @@ void QQmlBind::eval()
if (!d->when) {
//restore any previous binding
if (d->prevBind) {
- QQmlAbstractBinding *tmp = d->prevBind;
+ QQmlAbstractBinding *b = QQmlPropertyPrivate::binding(d->prop);
+ if (b != d->prevBind)
+ QQmlPropertyPrivate::setBinding(d->prevBind, QQmlPropertyPrivate::DestroyOldBinding);
d->prevBind = 0;
- tmp = QQmlPropertyPrivate::setBinding(d->prop, tmp);
- if (tmp) //should this ever be true?
- tmp->destroy();
}
return;
}
//save any set binding for restoration
- QQmlAbstractBinding *tmp;
- tmp = QQmlPropertyPrivate::setBinding(d->prop, 0);
- if (tmp && d->prevBind)
- tmp->destroy();
- else if (!d->prevBind)
+ QQmlAbstractBinding *tmp = QQmlPropertyPrivate::removeBinding(d->prop, (d->prevBind ? QQmlPropertyPrivate::DestroyOldBinding : QQmlPropertyPrivate::None));
+ if (tmp && !d->prevBind)
d->prevBind = tmp;
}
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 201fd4572c..d5fa2f4972 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -44,7 +44,7 @@
#include <private/qqmlincubator_p.h>
#include <private/qqmlcompiler_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <qv4objectiterator_p.h>
@@ -86,16 +86,11 @@ struct DelegateModelGroupFunction : QV4::FunctionObject
return scope->engine()->memoryManager->alloc<DelegateModelGroupFunction>(scope, flag, code);
}
- static QV4::ReturnedValue construct(QV4::Managed *m, QV4::CallData *)
+ static QV4::ReturnedValue call(const QV4::Managed *that, QV4::CallData *callData)
{
- return static_cast<DelegateModelGroupFunction *>(m)->engine()->throwTypeError();
- }
-
- static QV4::ReturnedValue call(QV4::Managed *that, QV4::CallData *callData)
- {
- QV4::ExecutionEngine *v4 = static_cast<DelegateModelGroupFunction *>(that)->engine();
+ QV4::ExecutionEngine *v4 = static_cast<const DelegateModelGroupFunction *>(that)->engine();
QV4::Scope scope(v4);
- QV4::Scoped<DelegateModelGroupFunction> f(scope, static_cast<DelegateModelGroupFunction *>(that));
+ QV4::Scoped<DelegateModelGroupFunction> f(scope, static_cast<const DelegateModelGroupFunction *>(that));
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject);
if (!o)
return v4->throwTypeError(QStringLiteral("Not a valid VisualData object"));
@@ -1637,7 +1632,7 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
if (!object.isObject())
return false;
- QV4::ExecutionEngine *v4 = object.asObject()->engine();
+ QV4::ExecutionEngine *v4 = object.as<QV4::Object>()->engine();
QV4::Scope scope(v4);
QV4::ScopedObject o(scope, object);
if (!o)
@@ -2511,7 +2506,7 @@ bool QQmlDelegateModelGroupPrivate::parseIndex(const QV4::Value &value, int *ind
if (!value.isObject())
return false;
- QV4::ExecutionEngine *v4 = value.asObject()->engine();
+ QV4::ExecutionEngine *v4 = value.as<QV4::Object>()->engine();
QV4::Scope scope(v4);
QV4::Scoped<QQmlDelegateModelItemObject> object(scope, value);
@@ -2579,9 +2574,9 @@ void QQmlDelegateModelGroup::insert(QQmlV4Function *args)
groups |= model->m_cacheMetaType->parseGroups(val);
}
- if (v->asArrayObject()) {
+ if (v->as<QV4::ArrayObject>()) {
return;
- } else if (v->asObject()) {
+ } else if (v->as<QV4::Object>()) {
model->insert(before, v, groups);
model->emitChanges();
}
@@ -2626,7 +2621,7 @@ void QQmlDelegateModelGroup::create(QQmlV4Function *args)
if (i < args->length() && index >= 0 && index <= model->m_compositor.count(group)) {
v = (*args)[i];
- if (v->asObject()) {
+ if (v->as<QV4::Object>()) {
int groups = 1 << d->group;
if (++i < args->length()) {
QV4::ScopedValue val(scope, (*args)[i]);
@@ -3286,12 +3281,12 @@ public:
quint32 count() const { return d()->changes.count(); }
const QQmlChangeSet::Change &at(int index) const { return d()->changes.at(index); }
- static QV4::ReturnedValue getIndexed(QV4::Managed *m, uint index, bool *hasProperty)
+ static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty)
{
Q_ASSERT(m->as<QQmlDelegateModelGroupChangeArray>());
- QV4::ExecutionEngine *v4 = static_cast<QQmlDelegateModelGroupChangeArray *>(m)->engine();
+ QV4::ExecutionEngine *v4 = static_cast<const QQmlDelegateModelGroupChangeArray *>(m)->engine();
QV4::Scope scope(v4);
- QV4::Scoped<QQmlDelegateModelGroupChangeArray> array(scope, static_cast<QQmlDelegateModelGroupChangeArray *>(m));
+ QV4::Scoped<QQmlDelegateModelGroupChangeArray> array(scope, static_cast<const QQmlDelegateModelGroupChangeArray *>(m));
if (index >= array->count()) {
if (hasProperty)
@@ -3311,10 +3306,10 @@ public:
return object.asReturnedValue();
}
- static QV4::ReturnedValue get(QV4::Managed *m, QV4::String *name, bool *hasProperty)
+ static QV4::ReturnedValue get(const QV4::Managed *m, QV4::String *name, bool *hasProperty)
{
Q_ASSERT(m->as<QQmlDelegateModelGroupChangeArray>());
- QQmlDelegateModelGroupChangeArray *array = static_cast<QQmlDelegateModelGroupChangeArray *>(m);
+ const QQmlDelegateModelGroupChangeArray *array = static_cast<const QQmlDelegateModelGroupChangeArray *>(m);
if (name->equals(array->engine()->id_length)) {
if (hasProperty)
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index ed97690adb..b376ce7fcb 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -421,13 +421,13 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles)
int roleIndex = -1;
// Add the value now
- if (QV4::String *s = propertyValue->asString()) {
+ if (const QV4::String *s = propertyValue->as<QV4::String>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String);
roleIndex = e->setStringProperty(r, s->toQString());
} else if (propertyValue->isNumber()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number);
roleIndex = e->setDoubleProperty(r, propertyValue->asDouble());
- } else if (QV4::ArrayObject *a = propertyValue->asArrayObject()) {
+ } else if (QV4::ArrayObject *a = propertyValue->as<QV4::ArrayObject>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
@@ -441,11 +441,11 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles)
} else if (propertyValue->isBoolean()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool);
roleIndex = e->setBoolProperty(r, propertyValue->booleanValue());
- } else if (QV4::DateObject *dd = propertyValue->asDateObject()) {
+ } else if (QV4::DateObject *dd = propertyValue->as<QV4::DateObject>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
QDateTime dt = dd->toQDateTime();
roleIndex = e->setDateTimeProperty(r, dt);
- } else if (QV4::Object *o = propertyValue->asObject()) {
+ } else if (QV4::Object *o = propertyValue->as<QV4::Object>()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
QObject *o = wrapper->object();
const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject);
@@ -502,7 +502,7 @@ void ListModel::set(int elementIndex, QV4::Object *object)
if (r.type == ListLayout::Role::Number) {
e->setDoublePropertyFast(r, propertyValue->asDouble());
}
- } else if (QV4::ArrayObject *a = propertyValue->asArrayObject()) {
+ } else if (QV4::ArrayObject *a = propertyValue->as<QV4::ArrayObject>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
if (r.type == ListLayout::Role::List) {
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
@@ -520,13 +520,13 @@ void ListModel::set(int elementIndex, QV4::Object *object)
if (r.type == ListLayout::Role::Bool) {
e->setBoolPropertyFast(r, propertyValue->booleanValue());
}
- } else if (QV4::DateObject *date = propertyValue->asDateObject()) {
+ } else if (QV4::DateObject *date = propertyValue->as<QV4::DateObject>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
if (r.type == ListLayout::Role::DateTime) {
QDateTime dt = date->toQDateTime();;
e->setDateTimePropertyFast(r, dt);
}
- } else if (QV4::Object *o = propertyValue->asObject()) {
+ } else if (QV4::Object *o = propertyValue->as<QV4::Object>()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
QObject *o = wrapper->object();
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject);
@@ -1169,7 +1169,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
roleIndex = setStringProperty(role, qstr);
} else if (d.isNumber()) {
roleIndex = setDoubleProperty(role, d.asDouble());
- } else if (d.asArrayObject()) {
+ } else if (d.as<QV4::ArrayObject>()) {
QV4::ScopedArrayObject a(scope, d);
if (role.type == ListLayout::Role::List) {
QV4::Scope scope(a->engine());
@@ -1187,7 +1187,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
}
} else if (d.isBoolean()) {
roleIndex = setBoolProperty(role, d.booleanValue());
- } else if (d.asDateObject()) {
+ } else if (d.as<QV4::DateObject>()) {
QV4::Scoped<QV4::DateObject> dd(scope, d);
QDateTime dt = dd->toQDateTime();
roleIndex = setDateTimeProperty(role, dt);
@@ -1330,8 +1330,8 @@ void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int>
QQmlListModel *subModel = QQmlListModel::createWithOwner(m_owner);
QVariantList subArray = value.toList();
- QVariantList::const_iterator subIt = subArray.begin();
- QVariantList::const_iterator subEnd = subArray.end();
+ QVariantList::const_iterator subIt = subArray.cbegin();
+ QVariantList::const_iterator subEnd = subArray.cend();
while (subIt != subEnd) {
const QVariantMap &subObject = subIt->toMap();
subModel->m_modelObjects.append(DynamicRoleModelNode::create(subObject, subModel));
@@ -1398,8 +1398,8 @@ void DynamicRoleModelNodeMetaObject::propertyWritten(int index)
QQmlListModel *subModel = QQmlListModel::createWithOwner(parentModel);
QVariantList subArray = v.toList();
- QVariantList::const_iterator subIt = subArray.begin();
- QVariantList::const_iterator subEnd = subArray.end();
+ QVariantList::const_iterator subIt = subArray.cbegin();
+ QVariantList::const_iterator subEnd = subArray.cend();
while (subIt != subEnd) {
const QVariantMap &subObject = subIt->toMap();
subModel->m_modelObjects.append(DynamicRoleModelNode::create(subObject, subModel));
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index c2c6e5ef5c..0aa5dc4ef6 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -54,7 +54,7 @@
#include <private/qv8engine_p.h>
#include <private/qv4serialize_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4script_p.h>
#include <private/qv4scopedvalue_p.h>
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index 356970eef0..e043d4e2ee 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -38,7 +38,7 @@
#include <private/qqmlproperty_p.h>
#include <private/qv8engine_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qmldevtools/qmldevtools.pro b/src/qmldevtools/qmldevtools.pro
index df1b750282..85f21ce6f6 100644
--- a/src/qmldevtools/qmldevtools.pro
+++ b/src/qmldevtools/qmldevtools.pro
@@ -19,3 +19,4 @@ include(../3rdparty/masm/masm-defs.pri)
include(../qml/parser/parser.pri)
include(../qml/jsruntime/jsruntime.pri)
include(../qml/compiler/compiler.pri)
+include(../qml/memory/memory.pri)
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp
index 3f91ce85a8..e405a53936 100644
--- a/src/qmltest/quicktestresult.cpp
+++ b/src/qmltest/quicktestresult.cpp
@@ -108,6 +108,14 @@ public Q_SLOTS:
pixel += x;
return QColor::fromRgba(*pixel);
}
+
+ bool equals(QuickTestImageObject *other) const
+ {
+ if (!other)
+ return m_image.isNull();
+
+ return m_image == other->m_image;
+ }
private:
QImage m_image;
};
@@ -478,8 +486,8 @@ void QuickTestResult::stringify(QQmlV4Function *args)
//Check for Object Type
if (value->isObject()
- && !value->asFunctionObject()
- && !value->asArrayObject()) {
+ && !value->as<QV4::FunctionObject>()
+ && !value->as<QV4::ArrayObject>()) {
QVariant v = scope.engine->toVariant(value, QMetaType::UnknownType);
if (v.isValid()) {
switch (v.type()) {
@@ -500,7 +508,7 @@ void QuickTestResult::stringify(QQmlV4Function *args)
if (result.isEmpty()) {
QString tmp = value->toQStringNoThrow();
- if (value->asArrayObject())
+ if (value->as<QV4::ArrayObject>())
result.append(QString::fromLatin1("[%1]").arg(tmp));
else
result.append(tmp);
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index cb694c499a..2068809b4e 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -46,7 +46,7 @@
#include <QtCore/QBuffer>
#include <QtCore/qdatetime.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4scopedvalue_p.h>
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 4aa3b1c8d0..85c45609b5 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -53,7 +53,7 @@
#include <private/qv4object_p.h>
#include <private/qquickwindow_p.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4objectproto_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -884,7 +884,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object
V4_OBJECT2(QQuickJSContext2DPixelData, QV4::Object)
V4_NEEDS_DESTROY
- static QV4::ReturnedValue getIndexed(QV4::Managed *m, uint index, bool *hasProperty);
+ static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty);
static void putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
static QV4::ReturnedValue proto_get_length(QV4::CallContext *ctx);
@@ -1379,7 +1379,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx
QV4::ScopedValue value(scope, ctx->argument(0));
- if (value->asObject()) {
+ if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
r->d()->context->state.fillStyle = color;
@@ -1488,7 +1488,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *c
QV4::ScopedValue value(scope, ctx->argument(0));
- if (value->asObject()) {
+ if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
r->d()->context->state.fillStyle = color;
@@ -1719,7 +1719,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
} else {
QImage patternTexture;
- if (QV4::Object *o = ctx->args()[0].asObject()) {
+ if (const QV4::Object *o = ctx->args()[0].as<Object>()) {
QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral("data")));
QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
if (!!pixelData) {
@@ -3089,12 +3089,12 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(QV4::CallContext
return QV4::Encode(r->d()->image.width() * r->d()->image.height() * 4);
}
-QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint index, bool *hasProperty)
+QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m, uint index, bool *hasProperty)
{
Q_ASSERT(m->as<QQuickJSContext2DPixelData>());
- QV4::ExecutionEngine *v4 = static_cast<QQuickJSContext2DPixelData *>(m)->engine();
+ QV4::ExecutionEngine *v4 = static_cast<const QQuickJSContext2DPixelData *>(m)->engine();
QV4::Scope scope(v4);
- QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<QQuickJSContext2DPixelData *>(m));
+ QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<const QQuickJSContext2DPixelData *>(m));
if (index < static_cast<quint32>(r->d()->image.width() * r->d()->image.height() * 4)) {
if (hasProperty)
@@ -3357,7 +3357,7 @@ QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(QV4::CallCo
qreal pos = ctx->args()[0].toNumber();
QColor color;
- if (ctx->args()[1].asObject()) {
+ if (ctx->args()[1].as<Object>()) {
color = scope.engine->toVariant(ctx->args()[1], qMetaTypeId<QColor>()).value<QColor>();
} else {
color = qt_color_from_string(ctx->args()[1]);
diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h
index 67d3a2e4fb..78fa26d791 100644
--- a/src/quick/items/context2d/qquickcontext2d_p.h
+++ b/src/quick/items/context2d/qquickcontext2d_p.h
@@ -48,7 +48,7 @@
#include <private/qv8engine_p.h>
#include <QtCore/QWaitCondition>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
//#define QQUICKCONTEXT2D_DEBUG //enable this for just DEBUG purpose!
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index 5b1aea5940..443d796c44 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -40,7 +40,7 @@
QT_BEGIN_NAMESPACE
class QQuickImagePrivate;
-class Q_AUTOTEST_EXPORT QQuickImage : public QQuickImageBase
+class Q_QUICK_PRIVATE_EXPORT QQuickImage : public QQuickImageBase
{
Q_OBJECT
Q_ENUMS(FillMode)
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 8b4723f340..6e50a9a77b 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -158,11 +158,6 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickPathView>(uri,major,minor,"PathView");
qmlRegisterUncreatableType<QQuickBasePositioner>(uri,major,minor,"Positioner",
QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
-#ifndef QT_NO_VALIDATOR
- qmlRegisterType<QQuickIntValidator>(uri,major,minor,"IntValidator");
- qmlRegisterType<QQuickDoubleValidator>(uri,major,minor,"DoubleValidator");
- qmlRegisterType<QRegExpValidator>(uri,major,minor,"RegExpValidator");
-#endif
qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle");
qmlRegisterType<QQuickRepeater>(uri,major,minor,"Repeater");
qmlRegisterType<QQuickRow>(uri,major,minor,"Row");
@@ -190,9 +185,6 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickCurve>();
qmlRegisterType<QQuickScaleGrid>();
qmlRegisterType<QQuickTextLine>();
-#ifndef QT_NO_VALIDATOR
- qmlRegisterType<QValidator>();
-#endif
qmlRegisterType<QQuickPen>();
qmlRegisterType<QQuickFlickableVisibleArea>();
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
@@ -268,6 +260,16 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickPinchArea, 1>(uri, 2, 5,"PinchArea");
qmlRegisterType<QQuickImage, 2>(uri, 2, 5,"Image");
+
+ qmlRegisterType<QQuickText, 6>(uri, 2, 6, "Text");
+ qmlRegisterType<QQuickTextEdit, 6>(uri, 2, 6, "TextEdit");
+ qmlRegisterType<QQuickTextInput, 6>(uri, 2, 6, "TextInput");
+ qmlRegisterUncreatableType<QQuickBasePositioner, 6>(uri, 2, 6, "Positioner",
+ QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
+ qmlRegisterType<QQuickColumn, 6>(uri, 2, 6, "Column");
+ qmlRegisterType<QQuickRow, 6>(uri, 2, 6, "Row");
+ qmlRegisterType<QQuickGrid, 6>(uri, 2, 6, "Grid");
+ qmlRegisterType<QQuickFlow, 6>(uri, 2, 6, "Flow");
}
static void initResources()
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 01ef1e65f7..20d7eba45a 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2421,7 +2421,7 @@ void QQuickItemViewPrivate::updateUnrequestedIndexes()
void QQuickItemViewPrivate::updateUnrequestedPositions()
{
- for (QHash<QQuickItem*,int>::const_iterator it = unrequestedItems.begin(), cend = unrequestedItems.end(); it != cend; ++it)
+ for (QHash<QQuickItem*,int>::const_iterator it = unrequestedItems.cbegin(), cend = unrequestedItems.cend(); it != cend; ++it)
repositionPackageItemAt(it.key(), it.value());
}
diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp
index 7fa6cdc161..6fa299bf03 100644
--- a/src/quick/items/qquickitemviewtransition.cpp
+++ b/src/quick/items/qquickitemviewtransition.cpp
@@ -34,6 +34,7 @@
#include "qquickitemviewtransition_p.h"
#include <QtQuick/qquickitem.h>
#include <QtQuick/private/qquicktransition_p.h>
+#include <QtQuick/private/qquicktransitionmanager_p_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index 170072a814..6f93697cc5 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -34,16 +34,20 @@
#ifndef QQUICKITEMVIEWTRANSITION_P_P_H
#define QQUICKITEMVIEWTRANSITION_P_P_H
-#include <private/qquicktransitionmanager_p_p.h>
+#include <QtQuick/private/qtquickglobal_p.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qpoint.h>
+#include <QtQml/qqml.h>
QT_BEGIN_NAMESPACE
class QQuickItem;
+class QQuickTransition;
class QQuickItemViewTransitionableItem;
class QQuickItemViewTransitionJob;
-class QQuickItemViewTransitionChangeListener
+class Q_QUICK_PRIVATE_EXPORT QQuickItemViewTransitionChangeListener
{
public:
QQuickItemViewTransitionChangeListener() {}
@@ -53,7 +57,7 @@ public:
};
-class QQuickItemViewTransitioner
+class Q_QUICK_PRIVATE_EXPORT QQuickItemViewTransitioner
{
public:
enum TransitionType {
@@ -113,7 +117,7 @@ private:
/*
An item that can be transitioned using QQuickViewTransitionJob.
*/
-class QQuickItemViewTransitionableItem
+class Q_QUICK_PRIVATE_EXPORT QQuickItemViewTransitionableItem
{
public:
QQuickItemViewTransitionableItem(QQuickItem *i);
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 3d28bf08c1..c1e3fbb4e0 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -942,7 +942,7 @@ QV4::ReturnedValue QQuickLoaderPrivate::extractInitialPropertyValues(QQmlV4Funct
QV4::ScopedValue valuemap(scope, QV4::Primitive::undefinedValue());
if (args->length() >= 2) {
QV4::ScopedValue v(scope, (*args)[1]);
- if (!v->isObject() || v->asArrayObject()) {
+ if (!v->isObject() || v->as<QV4::ArrayObject>()) {
*error = true;
qmlInfo(loader) << QQuickLoader::tr("setSource: value is not an object");
} else {
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index 621419d1a7..fb1263f0bd 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -50,7 +50,7 @@
#include "qquickitemchangelistener_p.h"
#include <qqmlincubator.h>
-#include <private/qv4value_inl_p.h>
+#include <private/qv4value_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickpainteditem_p.h b/src/quick/items/qquickpainteditem_p.h
index 3712e964f8..2759d9d683 100644
--- a/src/quick/items/qquickpainteditem_p.h
+++ b/src/quick/items/qquickpainteditem_p.h
@@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE
class QQuickPaintedItemTextureProvider;
class QSGPainterNode;
-class QQuickPaintedItemPrivate : public QQuickItemPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickPaintedItemPrivate : public QQuickItemPrivate
{
public:
QQuickPaintedItemPrivate();
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 58605f79dd..302532c3d1 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -98,7 +98,7 @@ QQuickPathViewPrivate::QQuickPathViewPrivate()
, inRefill(false)
, dragMargin(0), deceleration(100), maximumFlickVelocity(QML_FLICK_DEFAULTMAXVELOCITY)
, moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0)
- , firstIndex(-1), pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0)
+ , pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0)
, moveReason(Other), moveDirection(Shortest), attType(0), highlightComponent(0), highlightItem(0)
, moveHighlight(this, &QQuickPathViewPrivate::setHighlightPosition)
, highlightPosition(0)
@@ -447,7 +447,6 @@ void QQuickPathViewPrivate::regenerate()
if (!isValid())
return;
- firstIndex = -1;
updateMappedRange();
q->refill();
}
@@ -1473,7 +1472,7 @@ int QQuickPathView::indexAt(qreal x, qreal y) const
QQuickItem *item = d->items.at(idx);
QPointF p = item->mapFromItem(this, QPointF(x, y));
if (item->contains(p))
- return (d->firstIndex + idx) % d->modelCount;
+ return d->model->indexOf(item, 0);
}
return -1;
@@ -1896,12 +1895,12 @@ void QQuickPathView::refill()
int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount);
// first move existing items and remove items off path
- int idx = d->firstIndex;
- qCDebug(lcItemViewDelegateLifecycle) << "firstIndex" << idx << "currentIndex" << d->currentIndex << "offset" << d->offset;
+ qCDebug(lcItemViewDelegateLifecycle) << "currentIndex" << d->currentIndex << "offset" << d->offset;
QList<QQuickItem*>::iterator it = d->items.begin();
while (it != d->items.end()) {
- qreal pos = d->positionOfIndex(idx);
QQuickItem *item = *it;
+ int idx = d->model->indexOf(item, 0);
+ qreal pos = d->positionOfIndex(idx);
if (lcItemViewDelegateLifecycle().isDebugEnabled()) {
QQuickText *text = qmlobject_cast<QQuickText*>(item);
if (text)
@@ -1923,81 +1922,140 @@ void QQuickPathView::refill()
if (!d->isInBound(pos, d->mappedRange - d->mappedCache, 1.0 + d->mappedCache)) {
qCDebug(lcItemViewDelegateLifecycle) << "release" << idx << "@" << pos << ", !isInBound: lower" << (d->mappedRange - d->mappedCache) << "upper" << (1.0 + d->mappedCache);
d->releaseItem(item);
- if (it == d->items.begin()) {
- if (++d->firstIndex >= d->modelCount) {
- d->firstIndex = 0;
- }
- }
it = d->items.erase(it);
} else {
++it;
}
}
- ++idx;
- if (idx >= d->modelCount)
- idx = 0;
}
- if (!d->items.count())
- d->firstIndex = -1;
-
bool waiting = false;
if (d->modelCount) {
- // add items to beginning and end
+ // add items as needed
if (d->items.count() < count+d->cacheSize) {
- int idx = qRound(d->modelCount - d->offset) % d->modelCount;
+ int endIdx = 0;
+ qreal endPos;
+ int startIdx = 0;
qreal startPos = 0.0;
- if (d->haveHighlightRange && (d->highlightRangeMode != QQuickPathView::NoHighlightRange
- || d->snapMode != QQuickPathView::NoSnap))
- startPos = d->highlightRangeStart;
- if (d->firstIndex >= 0) {
- startPos = d->positionOfIndex(d->firstIndex);
- idx = (d->firstIndex + d->items.count()) % d->modelCount;
+ if (d->items.count()) {
+ //Find the beginning and end, items may not be in sorted order
+ endPos = -1.0;
+ startPos = 2.0;
+
+ for (int i = 0; i < d->items.count(); i++) {
+ int idx = d->model->indexOf(d->items[i], 0);
+ qreal curPos = d->positionOfIndex(idx);
+ if (curPos > endPos) {
+ endPos = curPos;
+ endIdx = idx;
+ }
+
+ if (curPos < startPos) {
+ startPos = curPos;
+ startIdx = idx;
+ }
+ }
+ } else {
+ if (d->haveHighlightRange
+ && (d->highlightRangeMode != QQuickPathView::NoHighlightRange
+ || d->snapMode != QQuickPathView::NoSnap))
+ startPos = d->highlightRangeStart;
+ // With no items, then "end" is just off the top so we populate via append
+ endIdx = (qRound(d->modelCount - d->offset) - 1) % d->modelCount;
+ endPos = d->positionOfIndex(endIdx);
}
- qreal pos = d->positionOfIndex(idx);
- while ((d->isInBound(pos, startPos, 1.0 + d->mappedCache) || !d->items.count()) && d->items.count() < count+d->cacheSize) {
- qCDebug(lcItemViewDelegateLifecycle) << "append" << idx << "@" << pos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
- QQuickItem *item = d->getItem(idx, idx+1, pos >= 1.0);
+ //Append
+ int idx = endIdx + 1;
+ if (idx >= d->modelCount)
+ idx = 0;
+ qreal nextPos = d->positionOfIndex(idx);
+ while ((d->isInBound(nextPos, endPos, 1.0 + d->mappedCache) || !d->items.count())
+ && d->items.count() < count+d->cacheSize) {
+ qCDebug(lcItemViewDelegateLifecycle) << "append" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
+ QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0);
if (!item) {
waiting = true;
break;
}
+ if (d->items.contains(item)) {
+ break; //Otherwise we'd "re-add" it, and get confused
+ }
if (d->currentIndex == idx) {
currentVisible = true;
- d->currentItemOffset = pos;
+ d->currentItemOffset = nextPos;
}
- if (d->items.count() == 0)
- d->firstIndex = idx;
d->items.append(item);
- d->updateItem(item, pos);
+ d->updateItem(item, nextPos);
+ endIdx = idx;
+ endPos = nextPos;
++idx;
if (idx >= d->modelCount)
idx = 0;
- pos = d->positionOfIndex(idx);
+ nextPos = d->positionOfIndex(idx);
}
- idx = d->firstIndex - 1;
+ //Prepend
+ idx = startIdx - 1;
if (idx < 0)
idx = d->modelCount - 1;
- pos = d->positionOfIndex(idx);
- while (!waiting && d->isInBound(pos, d->mappedRange - d->mappedCache, startPos) && d->items.count() < count+d->cacheSize) {
- qCDebug(lcItemViewDelegateLifecycle) << "prepend" << idx << "@" << pos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
- QQuickItem *item = d->getItem(idx, idx+1, pos >= 1.0);
+ nextPos = d->positionOfIndex(idx);
+ while (!waiting && d->isInBound(nextPos, d->mappedRange - d->mappedCache, startPos)
+ && d->items.count() < count+d->cacheSize) {
+ qCDebug(lcItemViewDelegateLifecycle) << "prepend" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
+ QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0);
if (!item) {
waiting = true;
break;
}
+ if (d->items.contains(item)) {
+ break; //Otherwise we'd "re-add" it, and get confused
+ }
if (d->currentIndex == idx) {
currentVisible = true;
- d->currentItemOffset = pos;
+ d->currentItemOffset = nextPos;
}
d->items.prepend(item);
- d->updateItem(item, pos);
- d->firstIndex = idx;
- idx = d->firstIndex - 1;
+ d->updateItem(item, nextPos);
+ startIdx = idx;
+ startPos = nextPos;
+ --idx;
if (idx < 0)
idx = d->modelCount - 1;
- pos = d->positionOfIndex(idx);
+ nextPos = d->positionOfIndex(idx);
+ }
+
+ // In rare cases, when jumping around with pathCount close to modelCount,
+ // new items appear in the middle. This more generic addition iteration handles this
+ // Since this is the rare case, we try append/prepend first and only do this if
+ // there are gaps still left to fill.
+ if (!waiting && d->items.count() < count+d->cacheSize) {
+ qCDebug(lcItemViewDelegateLifecycle) << "Checking for pathview middle inserts, items count was" << d->items.count();
+ idx = startIdx;
+ QQuickItem *lastItem = d->items[0];
+ while (idx != endIdx) {
+ //This gets the reference from the delegate model, and will not re-create
+ QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1.0);
+ if (!item) {
+ waiting = true;
+ break;
+ }
+ if (!d->items.contains(item)) { //We found a hole
+ nextPos = d->positionOfIndex(idx);
+ qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
+ if (d->currentIndex == idx) {
+ currentVisible = true;
+ d->currentItemOffset = nextPos;
+ }
+ int lastListIdx = d->items.indexOf(lastItem);
+ d->items.insert(lastListIdx + 1, item);
+ d->updateItem(item, nextPos);
+ }
+
+ lastItem = item;
+ ++idx;
+ if (idx >= d->modelCount)
+ idx = 0;
+ }
}
}
}
@@ -2128,7 +2186,6 @@ void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
d->offset = qmlMod(d->modelCount - d->currentIndex, d->modelCount);
changedOffset = true;
}
- d->firstIndex = -1;
d->updateMappedRange();
d->scheduleLayout();
}
@@ -2185,8 +2242,16 @@ void QQuickPathViewPrivate::createCurrentItem()
{
if (requestedIndex != -1)
return;
- int itemIndex = (currentIndex - firstIndex + modelCount) % modelCount;
- if (itemIndex < items.count()) {
+
+ bool inItems = false;
+ for (int i = 0; i < items.count(); i++) {
+ if (model->indexOf(items[i], 0) == currentIndex) {
+ inItems = true;
+ break;
+ }
+ }
+
+ if (inItems) {
if ((currentItem = getItem(currentIndex, currentIndex))) {
currentItem->setFocus(true);
if (QQuickPathViewAttached *att = attached(currentItem))
diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h
index 35ea8616a5..2a497881d4 100644
--- a/src/quick/items/qquickpathview_p_p.h
+++ b/src/quick/items/qquickpathview_p_p.h
@@ -155,7 +155,6 @@ public:
QQuickTimeLine tl;
QQuickTimeLineValueProxy<QQuickPathViewPrivate> moveOffset;
int flickDuration;
- int firstIndex;
int pathItems;
int requestedIndex;
int cacheSize;
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index 887d317069..c2eb7a9ac3 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -70,6 +70,10 @@ QQuickBasePositioner::PositionedItem::PositionedItem(QQuickItem *i)
, index(-1)
, isNew(false)
, isVisible(true)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
{
}
@@ -116,6 +120,14 @@ void QQuickBasePositioner::PositionedItem::startTransition(QQuickItemViewTransit
transitionableItem->startTransition(transitioner, index);
}
+void QQuickBasePositioner::PositionedItem::updatePadding(qreal lp, qreal tp, qreal rp, qreal bp)
+{
+ leftPadding = lp;
+ topPadding = tp;
+ rightPadding = rp;
+ bottomPadding = bp;
+}
+
QQuickBasePositioner::QQuickBasePositioner(PositionerType at, QQuickItem *parent)
: QQuickImplicitSizeItem(*(new QQuickBasePositionerPrivate), parent)
@@ -388,11 +400,8 @@ void QQuickBasePositioner::prePositioning()
void QQuickBasePositioner::positionItem(qreal x, qreal y, PositionedItem *target)
{
- Q_D(QQuickBasePositioner);
- if ( (target->itemX() != x || target->itemY() != y)
- && d->type == Both) {
+ if ( target->itemX() != x || target->itemY() != y )
target->moveTo(QPointF(x, y));
- }
}
void QQuickBasePositioner::positionItemX(qreal x, PositionedItem *target)
@@ -503,6 +512,163 @@ void QQuickBasePositioner::updateAttachedProperties(QQuickPositionerAttached *sp
}
}
+qreal QQuickBasePositioner::padding() const
+{
+ Q_D(const QQuickBasePositioner);
+ return d->padding;
+}
+
+void QQuickBasePositioner::setPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ if (qFuzzyCompare(d->padding, padding))
+ return;
+ d->padding = padding;
+ d->setPositioningDirty();
+ emit paddingChanged();
+ if (!d->explicitTopPadding)
+ emit topPaddingChanged();
+ if (!d->explicitLeftPadding)
+ emit leftPaddingChanged();
+ if (!d->explicitRightPadding)
+ emit rightPaddingChanged();
+ if (!d->explicitBottomPadding)
+ emit bottomPaddingChanged();
+}
+
+void QQuickBasePositioner::resetPadding()
+{
+ setPadding(0);
+}
+
+qreal QQuickBasePositioner::topPadding() const
+{
+ Q_D(const QQuickBasePositioner);
+ if (d->explicitTopPadding)
+ return d->topPadding;
+ return d->padding;
+}
+
+void QQuickBasePositioner::setTopPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ d->setTopPadding(padding);
+}
+
+void QQuickBasePositioner::resetTopPadding()
+{
+ Q_D(QQuickBasePositioner);
+ d->setTopPadding(0, true);
+}
+
+qreal QQuickBasePositioner::leftPadding() const
+{
+ Q_D(const QQuickBasePositioner);
+ if (d->explicitLeftPadding)
+ return d->leftPadding;
+ return d->padding;
+}
+
+void QQuickBasePositioner::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ d->setLeftPadding(padding);
+}
+
+void QQuickBasePositioner::resetLeftPadding()
+{
+ Q_D(QQuickBasePositioner);
+ d->setLeftPadding(0, true);
+}
+
+qreal QQuickBasePositioner::rightPadding() const
+{
+ Q_D(const QQuickBasePositioner);
+ if (d->explicitRightPadding)
+ return d->rightPadding;
+ return d->padding;
+}
+
+void QQuickBasePositioner::setRightPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ d->setRightPadding(padding);
+}
+
+void QQuickBasePositioner::resetRightPadding()
+{
+ Q_D(QQuickBasePositioner);
+ d->setRightPadding(0, true);
+}
+
+qreal QQuickBasePositioner::bottomPadding() const
+{
+ Q_D(const QQuickBasePositioner);
+ if (d->explicitBottomPadding)
+ return d->bottomPadding;
+ return d->padding;
+}
+
+void QQuickBasePositioner::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickBasePositioner);
+ d->setBottomPadding(padding);
+}
+
+void QQuickBasePositioner::resetBottomPadding()
+{
+ Q_D(QQuickBasePositioner);
+ d->setBottomPadding(0, true);
+}
+
+void QQuickBasePositionerPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickBasePositioner);
+ qreal tmp = q->topPadding();
+ topPadding = value;
+ explicitTopPadding = !reset;
+ if ((!reset && !qFuzzyCompare(tmp, value)) || (reset && !qFuzzyCompare(tmp, padding))) {
+ setPositioningDirty();
+ emit q->topPaddingChanged();
+ }
+}
+
+void QQuickBasePositionerPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickBasePositioner);
+ qreal tmp = q->leftPadding();
+ leftPadding = value;
+ explicitLeftPadding = !reset;
+ if ((!reset && !qFuzzyCompare(tmp, value)) || (reset && !qFuzzyCompare(tmp, padding))) {
+ setPositioningDirty();
+ emit q->leftPaddingChanged();
+ }
+}
+
+void QQuickBasePositionerPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickBasePositioner);
+ qreal tmp = q->rightPadding();
+ rightPadding = value;
+ explicitRightPadding = !reset;
+ if ((!reset && !qFuzzyCompare(tmp, value)) || (reset && !qFuzzyCompare(tmp, padding))) {
+ setPositioningDirty();
+ emit q->rightPaddingChanged();
+ }
+}
+
+void QQuickBasePositionerPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickBasePositioner);
+ qreal tmp = q->bottomPadding();
+ bottomPadding = value;
+ explicitBottomPadding = !reset;
+ if ((!reset && !qFuzzyCompare(tmp, value)) || (reset && !qFuzzyCompare(tmp, padding))) {
+ setPositioningDirty();
+ emit q->bottomPaddingChanged();
+ }
+}
+
/*!
\qmltype Positioner
\instantiates QQuickPositionerAttached
@@ -640,6 +806,16 @@ void QQuickPositionerAttached::setIsLastItem(bool isLastItem)
\sa Row, Grid, Flow, Positioner, ColumnLayout, {Qt Quick Examples - Positioners}
*/
/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Column::padding
+ \qmlproperty real QtQuick::Column::topPadding
+ \qmlproperty real QtQuick::Column::leftPadding
+ \qmlproperty real QtQuick::Column::bottomPadding
+ \qmlproperty real QtQuick::Column::rightPadding
+
+ These properties hold the padding around the content.
+*/
+/*!
\qmlproperty Transition QtQuick::Column::populate
This property holds the transition to be run for items that are part of
@@ -715,20 +891,23 @@ QQuickColumn::QQuickColumn(QQuickItem *parent)
void QQuickColumn::doPositioning(QSizeF *contentSize)
{
//Precondition: All items in the positioned list have a valid item pointer and should be positioned
- qreal voffset = 0;
+ qreal voffset = topPadding();
+ const qreal padding = leftPadding() + rightPadding();
+ contentSize->setWidth(qMax(contentSize->width(), padding));
for (int ii = 0; ii < positionedItems.count(); ++ii) {
PositionedItem &child = positionedItems[ii];
- positionItemY(voffset, &child);
- contentSize->setWidth(qMax(contentSize->width(), child.item->width()));
+ positionItem(child.itemX() + leftPadding() - child.leftPadding, voffset, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
+ contentSize->setWidth(qMax(contentSize->width(), child.item->width() + padding));
voffset += child.item->height();
voffset += spacing();
}
- if (voffset != 0)//If we positioned any items, undo the spacing from the last item
+ if (voffset - topPadding() != 0)//If we positioned any items, undo the spacing from the last item
voffset -= spacing();
- contentSize->setHeight(voffset);
+ contentSize->setHeight(voffset + bottomPadding());
}
void QQuickColumn::reportConflictingAnchors()
@@ -794,6 +973,16 @@ void QQuickColumn::reportConflictingAnchors()
\sa Column, Grid, Flow, Positioner, RowLayout, {Qt Quick Examples - Positioners}
*/
/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Row::padding
+ \qmlproperty real QtQuick::Row::topPadding
+ \qmlproperty real QtQuick::Row::leftPadding
+ \qmlproperty real QtQuick::Row::bottomPadding
+ \qmlproperty real QtQuick::Row::rightPadding
+
+ These properties hold the padding around the content.
+*/
+/*!
\qmlproperty Transition QtQuick::Row::populate
This property holds the transition to be run for items that are part of
@@ -940,27 +1129,34 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
{
//Precondition: All items in the positioned list have a valid item pointer and should be positioned
QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate* >(QQuickBasePositionerPrivate::get(this));
- qreal hoffset = 0;
+ qreal hoffset1 = leftPadding();
+ qreal hoffset2 = rightPadding();
+ if (!d->isLeftToRight())
+ qSwap(hoffset1, hoffset2);
+ qreal hoffset = hoffset1;
+ const qreal padding = topPadding() + bottomPadding();
+ contentSize->setHeight(qMax(contentSize->height(), padding));
QList<qreal> hoffsets;
for (int ii = 0; ii < positionedItems.count(); ++ii) {
PositionedItem &child = positionedItems[ii];
if (d->isLeftToRight()) {
- positionItemX(hoffset, &child);
+ positionItem(hoffset, child.itemY() + topPadding() - child.topPadding, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
} else {
hoffsets << hoffset;
}
- contentSize->setHeight(qMax(contentSize->height(), child.item->height()));
+ contentSize->setHeight(qMax(contentSize->height(), child.item->height() + padding));
hoffset += child.item->width();
hoffset += spacing();
}
- if (hoffset != 0)//If we positioned any items, undo the extra spacing from the last item
+ if (hoffset - hoffset1 != 0)//If we positioned any items, undo the extra spacing from the last item
hoffset -= spacing();
- contentSize->setWidth(hoffset);
+ contentSize->setWidth(hoffset + hoffset2);
if (d->isLeftToRight())
return;
@@ -976,7 +1172,8 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
for (int ii = 0; ii < positionedItems.count(); ++ii) {
PositionedItem &child = positionedItems[ii];
hoffset = end - hoffsets[acc++] - child.item->width();
- positionItemX(hoffset, &child);
+ positionItem(hoffset, child.itemY() + topPadding() - child.topPadding, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
}
}
@@ -1044,6 +1241,16 @@ void QQuickRow::reportConflictingAnchors()
\sa Flow, Row, Column, Positioner, GridLayout, {Qt Quick Examples - Positioners}
*/
/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Grid::padding
+ \qmlproperty real QtQuick::Grid::topPadding
+ \qmlproperty real QtQuick::Grid::leftPadding
+ \qmlproperty real QtQuick::Grid::bottomPadding
+ \qmlproperty real QtQuick::Grid::rightPadding
+
+ These properties hold the padding around the content.
+*/
+/*!
\qmlproperty Transition QtQuick::Grid::populate
This property holds the transition to be run for items that are part of
@@ -1423,8 +1630,11 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
c = (numVisible+(m_rows-1))/m_rows;
}
- if (r == 0 || c == 0)
- return; //Nothing to do
+ if (r == 0 || c == 0) {
+ contentSize->setHeight(topPadding() + bottomPadding());
+ contentSize->setWidth(leftPadding() + rightPadding());
+ return; //Nothing else to do
+ }
QList<qreal> maxColWidth;
QList<qreal> maxRowHeight;
@@ -1476,6 +1686,7 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
widthSum += columnSpacing;
widthSum += maxColWidth[j];
}
+ widthSum += leftPadding() + rightPadding();
qreal heightSum = 0;
for (int i = 0; i < maxRowHeight.size(); i++) {
@@ -1483,6 +1694,7 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
heightSum += rowSpacing;
heightSum += maxRowHeight[i];
}
+ heightSum += topPadding() + bottomPadding();
contentSize->setHeight(heightSum);
contentSize->setWidth(widthSum);
@@ -1493,10 +1705,10 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
else
end = widthSum;
- qreal xoffset = 0;
+ qreal xoffset = leftPadding();
if (!d->isLeftToRight())
- xoffset = end;
- qreal yoffset = 0;
+ xoffset = end - rightPadding();
+ qreal yoffset = topPadding();
int curRow =0;
int curCol =0;
for (int i = 0; i < positionedItems.count(); ++i) {
@@ -1518,6 +1730,7 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
alignYOffset += maxRowHeight[curRow] - child.item->height();
positionItem(childXOffset, alignYOffset, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
if (m_flow == LeftToRight) {
if (d->isLeftToRight())
@@ -1529,9 +1742,9 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
if (!curCol) {
yoffset += maxRowHeight[curRow]+rowSpacing;
if (d->isLeftToRight())
- xoffset = 0;
+ xoffset = leftPadding();
else
- xoffset = end;
+ xoffset = end - rightPadding();
curRow++;
if (curRow>=r)
break;
@@ -1545,7 +1758,7 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
xoffset += maxColWidth[curCol]+columnSpacing;
else
xoffset -= maxColWidth[curCol]+columnSpacing;
- yoffset = 0;
+ yoffset = topPadding();
curCol++;
if (curCol>=c)
break;
@@ -1603,6 +1816,16 @@ void QQuickGrid::reportConflictingAnchors()
\sa Column, Row, Grid, Positioner, {Qt Quick Examples - Positioners}
*/
/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Flow::padding
+ \qmlproperty real QtQuick::Flow::topPadding
+ \qmlproperty real QtQuick::Flow::leftPadding
+ \qmlproperty real QtQuick::Flow::bottomPadding
+ \qmlproperty real QtQuick::Flow::rightPadding
+
+ These properties hold the padding around the content.
+*/
+/*!
\qmlproperty Transition QtQuick::Flow::populate
This property holds the transition to be run for items that are part of
@@ -1786,23 +2009,30 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
//Precondition: All items in the positioned list have a valid item pointer and should be positioned
Q_D(QQuickFlow);
- qreal hoffset = 0;
- qreal voffset = 0;
+ qreal hoffset1 = leftPadding();
+ qreal hoffset2 = rightPadding();
+ if (!d->isLeftToRight())
+ qSwap(hoffset1, hoffset2);
+ qreal hoffset = hoffset1;
+ const qreal voffset1 = topPadding();
+ qreal voffset = voffset1;
qreal linemax = 0;
QList<qreal> hoffsets;
+ contentSize->setWidth(qMax(contentSize->width(), hoffset1 + hoffset2));
+ contentSize->setHeight(qMax(contentSize->height(), voffset + bottomPadding()));
for (int i = 0; i < positionedItems.count(); ++i) {
PositionedItem &child = positionedItems[i];
if (d->flow == LeftToRight) {
- if (widthValid() && hoffset && hoffset + child.item->width() > width()) {
- hoffset = 0;
+ if (widthValid() && hoffset != hoffset1 && hoffset + child.item->width() + hoffset2 > width()) {
+ hoffset = hoffset1;
voffset += linemax + spacing();
linemax = 0;
}
} else {
- if (heightValid() && voffset && voffset + child.item->height() > height()) {
- voffset = 0;
+ if (heightValid() && voffset != voffset1 && voffset + child.item->height() + bottomPadding() > height()) {
+ voffset = voffset1;
hoffset += linemax + spacing();
linemax = 0;
}
@@ -1810,13 +2040,16 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
if (d->isLeftToRight()) {
positionItem(hoffset, voffset, &child);
+ child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
} else {
hoffsets << hoffset;
positionItemY(voffset, &child);
+ child.topPadding = topPadding();
+ child.bottomPadding = bottomPadding();
}
- contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width()));
- contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height()));
+ contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width() + hoffset2));
+ contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height() + bottomPadding()));
if (d->flow == LeftToRight) {
hoffset += child.item->width();
@@ -1828,6 +2061,7 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
linemax = qMax(linemax, child.item->width());
}
}
+
if (d->isLeftToRight())
return;
@@ -1841,6 +2075,8 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
PositionedItem &child = positionedItems[i];
hoffset = end - hoffsets[acc++] - child.item->width();
positionItemX(hoffset, &child);
+ child.leftPadding = leftPadding();
+ child.rightPadding = rightPadding();
}
}
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index ea779695eb..6323405022 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -86,6 +86,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBasePositioner : public QQuickImplicitSizeIte
Q_PROPERTY(QQuickTransition *populate READ populate WRITE setPopulate NOTIFY populateChanged)
Q_PROPERTY(QQuickTransition *move READ move WRITE setMove NOTIFY moveChanged)
Q_PROPERTY(QQuickTransition *add READ add WRITE setAdd NOTIFY addChanged)
+
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
public:
enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 };
@@ -108,6 +114,26 @@ public:
void updateAttachedProperties(QQuickPositionerAttached *specificProperty = 0, QQuickItem *specificPropertyOwner = 0) const;
+ qreal padding() const;
+ void setPadding(qreal padding);
+ void resetPadding();
+
+ qreal topPadding() const;
+ void setTopPadding(qreal padding);
+ void resetTopPadding();
+
+ qreal leftPadding() const;
+ void setLeftPadding(qreal padding);
+ void resetLeftPadding();
+
+ qreal rightPadding() const;
+ void setRightPadding(qreal padding);
+ void resetRightPadding();
+
+ qreal bottomPadding() const;
+ void setBottomPadding(qreal padding);
+ void resetBottomPadding();
+
protected:
QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent);
void componentComplete() Q_DECL_OVERRIDE;
@@ -120,6 +146,11 @@ Q_SIGNALS:
void populateChanged();
void moveChanged();
void addChanged();
+ Q_REVISION(6) void paddingChanged();
+ Q_REVISION(6) void topPaddingChanged();
+ Q_REVISION(6) void leftPaddingChanged();
+ Q_REVISION(6) void rightPaddingChanged();
+ Q_REVISION(6) void bottomPaddingChanged();
protected Q_SLOTS:
void prePositioning();
@@ -144,11 +175,18 @@ protected:
bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds);
void startTransition(QQuickItemViewTransitioner *transitioner);
+ void updatePadding(qreal lp, qreal tp, qreal rp, qreal bp);
+
QQuickItem *item;
QQuickItemViewTransitionableItem *transitionableItem;
int index;
bool isNew;
bool isVisible;
+
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
};
QPODVector<PositionedItem,8> positionedItems;
diff --git a/src/quick/items/qquickpositioners_p_p.h b/src/quick/items/qquickpositioners_p_p.h
index 3a8fe20351..a58f79ac0a 100644
--- a/src/quick/items/qquickpositioners_p_p.h
+++ b/src/quick/items/qquickpositioners_p_p.h
@@ -69,6 +69,16 @@ public:
: spacing(0), type(QQuickBasePositioner::None)
, transitioner(0), positioningDirty(false)
, doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight)
+ , padding(0)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
+ , explicitTopPadding(false)
+ , explicitLeftPadding(false)
+ , explicitRightPadding(false)
+ , explicitBottomPadding(false)
+
{
}
@@ -98,6 +108,16 @@ public:
Qt::LayoutDirection layoutDirection;
+ qreal padding;
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
+ bool explicitTopPadding;
+ bool explicitLeftPadding;
+ bool explicitRightPadding;
+ bool explicitBottomPadding;
+
void mirrorChange() Q_DECL_OVERRIDE {
effectiveLayoutDirectionChange();
}
@@ -149,6 +169,11 @@ public:
virtual void effectiveLayoutDirectionChange()
{
}
+
+ void setTopPadding(qreal value, bool reset = false);
+ void setLeftPadding(qreal value, bool reset = false);
+ void setRightPadding(qreal value, bool reset = false);
+ void setBottomPadding(qreal value, bool reset = false);
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index 0168d73c8f..5333ad2f08 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -50,6 +50,7 @@ QQuickRepeaterPrivate::QQuickRepeaterPrivate()
, delegateValidated(false)
, itemCount(0)
{
+ setTransparentForPositioner(true);
}
QQuickRepeaterPrivate::~QQuickRepeaterPrivate()
@@ -397,9 +398,17 @@ void QQuickRepeaterPrivate::requestItems()
void QQuickRepeater::createdItem(int index, QObject *)
{
Q_D(QQuickRepeater);
+ QObject *object = d->model->object(index, false);
+ QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
+ emit itemAdded(index, item);
+}
+
+void QQuickRepeater::initItem(int index, QObject *object)
+{
+ Q_D(QQuickRepeater);
+ QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
+
if (!d->deletables.at(index)) {
- QObject *object = d->model->object(index, false);
- QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
if (!item) {
if (object) {
d->model->release(object);
@@ -425,17 +434,9 @@ void QQuickRepeater::createdItem(int index, QObject *)
}
item->stackBefore(after);
}
- emit itemAdded(index, item);
}
}
-void QQuickRepeater::initItem(int, QObject *object)
-{
- QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
- if (item)
- item->setParentItem(parentItem());
-}
-
void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
{
Q_D(QQuickRepeater);
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index 579919db27..3ea1c0ecf1 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -1024,48 +1024,48 @@ void QQuickAnchorChanges::execute(Reason reason)
//reset any anchors that have been specified as "undefined"
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::LeftAnchor) {
targetPrivate->anchors()->resetLeft();
- QQmlPropertyPrivate::setBinding(d->leftProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->leftProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::RightAnchor) {
targetPrivate->anchors()->resetRight();
- QQmlPropertyPrivate::setBinding(d->rightProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->rightProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::HCenterAnchor) {
targetPrivate->anchors()->resetHorizontalCenter();
- QQmlPropertyPrivate::setBinding(d->hCenterProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->hCenterProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::TopAnchor) {
targetPrivate->anchors()->resetTop();
- QQmlPropertyPrivate::setBinding(d->topProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->topProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BottomAnchor) {
targetPrivate->anchors()->resetBottom();
- QQmlPropertyPrivate::setBinding(d->bottomProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->bottomProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::VCenterAnchor) {
targetPrivate->anchors()->resetVerticalCenter();
- QQmlPropertyPrivate::setBinding(d->vCenterProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->vCenterProp);
}
if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BaselineAnchor) {
targetPrivate->anchors()->resetBaseline();
- QQmlPropertyPrivate::setBinding(d->baselineProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->baselineProp);
}
//set any anchors that have been specified
if (d->leftBinding)
- QQmlPropertyPrivate::setBinding(d->leftBinding->property(), d->leftBinding);
+ QQmlPropertyPrivate::setBinding(d->leftBinding);
if (d->rightBinding)
- QQmlPropertyPrivate::setBinding(d->rightBinding->property(), d->rightBinding);
+ QQmlPropertyPrivate::setBinding(d->rightBinding);
if (d->hCenterBinding)
- QQmlPropertyPrivate::setBinding(d->hCenterBinding->property(), d->hCenterBinding);
+ QQmlPropertyPrivate::setBinding(d->hCenterBinding);
if (d->topBinding)
- QQmlPropertyPrivate::setBinding(d->topBinding->property(), d->topBinding);
+ QQmlPropertyPrivate::setBinding(d->topBinding);
if (d->bottomBinding)
- QQmlPropertyPrivate::setBinding(d->bottomBinding->property(), d->bottomBinding);
+ QQmlPropertyPrivate::setBinding(d->bottomBinding);
if (d->vCenterBinding)
- QQmlPropertyPrivate::setBinding(d->vCenterBinding->property(), d->vCenterBinding);
+ QQmlPropertyPrivate::setBinding(d->vCenterBinding);
if (d->baselineBinding)
- QQmlPropertyPrivate::setBinding(d->baselineBinding->property(), d->baselineBinding);
+ QQmlPropertyPrivate::setBinding(d->baselineBinding);
}
bool QQuickAnchorChanges::isReversable()
@@ -1083,49 +1083,49 @@ void QQuickAnchorChanges::reverse(Reason reason)
//reset any anchors set by the state
if (d->leftBinding) {
targetPrivate->anchors()->resetLeft();
- QQmlPropertyPrivate::setBinding(d->leftBinding->property(), 0);
+ QQmlPropertyPrivate::removeBinding(d->leftBinding);
if (reason == ActualChange) {
d->leftBinding->destroy(); d->leftBinding = 0;
}
}
if (d->rightBinding) {
targetPrivate->anchors()->resetRight();
- QQmlPropertyPrivate::setBinding(d->rightBinding->property(), 0);
+ QQmlPropertyPrivate::removeBinding(d->rightBinding);
if (reason == ActualChange) {
d->rightBinding->destroy(); d->rightBinding = 0;
}
}
if (d->hCenterBinding) {
targetPrivate->anchors()->resetHorizontalCenter();
- QQmlPropertyPrivate::setBinding(d->hCenterBinding->property(), 0);
+ QQmlPropertyPrivate::removeBinding(d->hCenterBinding);
if (reason == ActualChange) {
d->hCenterBinding->destroy(); d->hCenterBinding = 0;
}
}
if (d->topBinding) {
targetPrivate->anchors()->resetTop();
- QQmlPropertyPrivate::setBinding(d->topBinding->property(), 0);
+ QQmlPropertyPrivate::removeBinding(d->topBinding);
if (reason == ActualChange) {
d->topBinding->destroy(); d->topBinding = 0;
}
}
if (d->bottomBinding) {
targetPrivate->anchors()->resetBottom();
- QQmlPropertyPrivate::setBinding(d->bottomBinding->property(), 0);
+ QQmlPropertyPrivate::removeBinding(d->bottomBinding);
if (reason == ActualChange) {
d->bottomBinding->destroy(); d->bottomBinding = 0;
}
}
if (d->vCenterBinding) {
targetPrivate->anchors()->resetVerticalCenter();
- QQmlPropertyPrivate::setBinding(d->vCenterBinding->property(), 0);
+ QQmlPropertyPrivate::removeBinding(d->vCenterBinding);
if (reason == ActualChange) {
d->vCenterBinding->destroy(); d->vCenterBinding = 0;
}
}
if (d->baselineBinding) {
targetPrivate->anchors()->resetBaseline();
- QQmlPropertyPrivate::setBinding(d->baselineBinding->property(), 0);
+ QQmlPropertyPrivate::removeBinding(d->baselineBinding);
if (reason == ActualChange) {
d->baselineBinding->destroy(); d->baselineBinding = 0;
}
@@ -1333,31 +1333,31 @@ void QQuickAnchorChanges::clearBindings()
d->anchorSet->d_func()->usedAnchors;
if (d->applyOrigLeft || (combined & QQuickAnchors::LeftAnchor)) {
targetPrivate->anchors()->resetLeft();
- QQmlPropertyPrivate::setBinding(d->leftProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->leftProp);
}
if (d->applyOrigRight || (combined & QQuickAnchors::RightAnchor)) {
targetPrivate->anchors()->resetRight();
- QQmlPropertyPrivate::setBinding(d->rightProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->rightProp);
}
if (d->applyOrigHCenter || (combined & QQuickAnchors::HCenterAnchor)) {
targetPrivate->anchors()->resetHorizontalCenter();
- QQmlPropertyPrivate::setBinding(d->hCenterProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->hCenterProp);
}
if (d->applyOrigTop || (combined & QQuickAnchors::TopAnchor)) {
targetPrivate->anchors()->resetTop();
- QQmlPropertyPrivate::setBinding(d->topProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->topProp);
}
if (d->applyOrigBottom || (combined & QQuickAnchors::BottomAnchor)) {
targetPrivate->anchors()->resetBottom();
- QQmlPropertyPrivate::setBinding(d->bottomProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->bottomProp);
}
if (d->applyOrigVCenter || (combined & QQuickAnchors::VCenterAnchor)) {
targetPrivate->anchors()->resetVerticalCenter();
- QQmlPropertyPrivate::setBinding(d->vCenterProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->vCenterProp);
}
if (d->applyOrigBaseline || (combined & QQuickAnchors::BaselineAnchor)) {
targetPrivate->anchors()->resetBaseline();
- QQmlPropertyPrivate::setBinding(d->baselineProp, 0);
+ QQmlPropertyPrivate::removeBinding(d->baselineProp);
}
}
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index dd4f57bfdb..799b1465ea 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE
const QChar QQuickTextPrivate::elideChar = QChar(0x2026);
QQuickTextPrivate::QQuickTextPrivate()
- : elideLayout(0), textLine(0), lineWidth(0)
+ : elideLayout(0), textLine(0), padding(0), lineWidth(0)
, color(0xFF000000), linkColor(0xFF0000FF), styleColor(0xFF000000)
, lineCount(1), multilengthEos(-1)
, elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop)
@@ -85,7 +85,15 @@ QQuickTextPrivate::QQuickTextPrivate()
}
QQuickTextPrivate::ExtraData::ExtraData()
- : lineHeight(1.0)
+ : topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
+ , explicitTopPadding(false)
+ , explicitLeftPadding(false)
+ , explicitRightPadding(false)
+ , explicitBottomPadding(false)
+ , lineHeight(1.0)
, doc(0)
, minimumPixelSize(12)
, minimumPointSize(12)
@@ -283,6 +291,74 @@ qreal QQuickTextPrivate::getImplicitHeight() const
return implicitHeight;
}
+qreal QQuickTextPrivate::availableWidth() const
+{
+ Q_Q(const QQuickText);
+ return q->width() - q->leftPadding() - q->rightPadding();
+}
+
+qreal QQuickTextPrivate::availableHeight() const
+{
+ Q_Q(const QQuickText);
+ return q->height() - q->topPadding() - q->bottomPadding();
+}
+
+void QQuickTextPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickText);
+ qreal oldPadding = q->topPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().topPadding = value;
+ extra.value().explicitTopPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ updateSize();
+ emit q->topPaddingChanged();
+ }
+}
+
+void QQuickTextPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickText);
+ qreal oldPadding = q->leftPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().leftPadding = value;
+ extra.value().explicitLeftPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ updateSize();
+ emit q->leftPaddingChanged();
+ }
+}
+
+void QQuickTextPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickText);
+ qreal oldPadding = q->rightPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().rightPadding = value;
+ extra.value().explicitRightPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ updateSize();
+ emit q->rightPaddingChanged();
+ }
+}
+
+void QQuickTextPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickText);
+ qreal oldPadding = q->bottomPadding();
+ if (!reset || extra.isAllocated()) {
+ extra.value().bottomPadding = value;
+ extra.value().explicitBottomPadding = !reset;
+ }
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ updateSize();
+ emit q->bottomPaddingChanged();
+ }
+}
+
/*!
\qmlproperty bool QtQuick::Text::antialiasing
@@ -409,7 +485,7 @@ void QQuickTextPrivate::updateBaseline(qreal baseline, qreal dy)
yoff = dy/2;
}
- q->setBaselineOffset(baseline + yoff);
+ q->setBaselineOffset(baseline + yoff + q->topPadding());
}
void QQuickTextPrivate::updateSize()
@@ -429,6 +505,9 @@ void QQuickTextPrivate::updateSize()
return;
}
+ qreal hPadding = q->leftPadding() + q->rightPadding();
+ qreal vPadding = q->topPadding() + q->bottomPadding();
+
if (text.isEmpty() && !isLineLaidOutConnected() && fontSizeMode() == QQuickText::FixedSize) {
// How much more expensive is it to just do a full layout on an empty string here?
// There may be subtle differences in the height and baseline calculations between
@@ -441,8 +520,8 @@ void QQuickTextPrivate::updateSize()
? lineHeight()
: fontHeight * lineHeight();
}
- updateBaseline(fm.ascent(), q->height() - fontHeight);
- q->setImplicitSize(0, fontHeight);
+ updateBaseline(fm.ascent(), q->height() - fontHeight - vPadding);
+ q->setImplicitSize(hPadding, fontHeight + vPadding);
layedOutTextRect = QRectF(0, 0, 0, fontHeight);
emit q->contentSizeChanged();
updateType = UpdatePaintNode;
@@ -463,7 +542,7 @@ void QQuickTextPrivate::updateSize()
layedOutTextRect = textRect;
size = textRect.size();
- updateBaseline(baseline, q->height() - size.height());
+ updateBaseline(baseline, q->height() - size.height() - vPadding);
} else {
widthExceeded = true; // always relayout rich text on width changes..
heightExceeded = false; // rich text layout isn't affected by height changes.
@@ -487,15 +566,15 @@ void QQuickTextPrivate::updateSize()
naturalWidth = extra->doc->idealWidth();
const bool wasInLayout = internalWidthUpdate;
internalWidthUpdate = true;
- q->setImplicitWidth(naturalWidth);
+ q->setImplicitWidth(naturalWidth + hPadding);
internalWidthUpdate = wasInLayout;
}
if (internalWidthUpdate)
return;
extra->doc->setPageSize(QSizeF());
- if (q->widthValid() && (wrapMode != QQuickText::NoWrap || extra->doc->idealWidth() < q->width()))
- extra->doc->setTextWidth(q->width());
+ if (q->widthValid() && (wrapMode != QQuickText::NoWrap || extra->doc->idealWidth() < availableWidth()))
+ extra->doc->setTextWidth(availableWidth());
else
extra->doc->setTextWidth(extra->doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
@@ -504,7 +583,7 @@ void QQuickTextPrivate::updateSize()
size = QSizeF(extra->doc->idealWidth(),dsize.height());
QFontMetricsF fm(font);
- updateBaseline(fm.ascent(), q->height() - size.height());
+ updateBaseline(fm.ascent(), q->height() - size.height() - vPadding);
//### need to confirm cost of always setting these for richText
internalWidthUpdate = true;
@@ -512,11 +591,11 @@ void QQuickTextPrivate::updateSize()
if (!q->widthValid())
iWidth = size.width();
if (iWidth > -1)
- q->setImplicitSize(iWidth, size.height());
+ q->setImplicitSize(iWidth + hPadding, size.height() + vPadding);
internalWidthUpdate = false;
if (iWidth == -1)
- q->setImplicitHeight(size.height());
+ q->setImplicitHeight(size.height() + vPadding);
}
if (layedOutTextRect.size() != previousSize)
@@ -622,7 +701,7 @@ void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height,
// use the text item's width by default if it has one and wrap is on or text must be aligned
if (q->widthValid() && (q->wrapMode() != QQuickText::NoWrap ||
q->effectiveHAlign() != QQuickText::AlignLeft))
- textLine->setWidth(q->width());
+ textLine->setWidth(availableWidth());
else
textLine->setWidth(INT_MAX);
if (lineHeight() != 1.0)
@@ -690,10 +769,11 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
&& (q->heightValid() || maximumLineCountValid);
if ((!requireImplicitSize || (implicitWidthValid && implicitHeightValid))
- && ((singlelineElide && q->width() <= 0.) || (multilineElide && q->heightValid() && q->height() <= 0.))) {
+ && ((singlelineElide && availableWidth() <= 0.)
+ || (multilineElide && q->heightValid() && availableHeight() <= 0.))) {
// we are elided and we have a zero width or height
- widthExceeded = q->widthValid() && q->width() <= 0.;
- heightExceeded = q->heightValid() && q->height() <= 0.;
+ widthExceeded = q->widthValid() && availableWidth() <= 0.;
+ heightExceeded = q->heightValid() && availableHeight() <= 0.;
if (!truncated) {
truncated = true;
@@ -729,7 +809,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
lineWidth = (q->widthValid() || implicitWidthValid) && q->width() > 0
? q->width()
: FLT_MAX;
- qreal maxHeight = q->heightValid() ? q->height() : FLT_MAX;
+ qreal maxHeight = q->heightValid() ? availableHeight() : FLT_MAX;
const bool customLayout = isLineLaidOutConnected();
const bool wasTruncated = truncated;
@@ -750,8 +830,8 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
int scaledFontSize = largeFont;
bool widthChanged = false;
- widthExceeded = q->width() <= 0 && (singlelineElide || canWrap || horizontalFit);
- heightExceeded = q->height() <= 0 && (multilineElide || verticalFit);
+ widthExceeded = availableWidth() <= 0 && (singlelineElide || canWrap || horizontalFit);
+ heightExceeded = availableHeight() <= 0 && (multilineElide || verticalFit);
QRectF br;
@@ -921,7 +1001,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
bool wasInLayout = internalWidthUpdate;
internalWidthUpdate = true;
- q->setImplicitSize(naturalWidth, naturalHeight);
+ q->setImplicitSize(naturalWidth + q->leftPadding() + q->rightPadding(), naturalHeight + q->topPadding() + q->bottomPadding());
internalWidthUpdate = wasInLayout;
// Update any variables that are dependent on the validity of the width or height.
@@ -938,8 +1018,11 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
const qreal oldWidth = lineWidth;
const qreal oldHeight = maxHeight;
- lineWidth = q->widthValid() && q->width() > 0 ? q->width() : naturalWidth;
- maxHeight = q->heightValid() ? q->height() : FLT_MAX;
+ const qreal availWidth = availableWidth();
+ const qreal availHeight = availableHeight();
+
+ lineWidth = q->widthValid() && availWidth > 0 ? availWidth : naturalWidth;
+ maxHeight = q->heightValid() ? availHeight : FLT_MAX;
// If the width of the item has changed and it's possible the result of wrapping,
// eliding, scaling has changed, or the text is not left aligned do another layout.
@@ -992,7 +1075,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
&& (q->heightValid() || (maximumLineCountValid && canWrap));
const qreal oldHeight = maxHeight;
- maxHeight = q->heightValid() ? q->height() : FLT_MAX;
+ maxHeight = q->heightValid() ? availableHeight() : FLT_MAX;
// If the height of the item has changed and it's possible the result of eliding,
// line count truncation or scaling has changed, do another layout.
if ((maxHeight < qMin(oldHeight, naturalHeight) || (heightExceeded && maxHeight > oldHeight))
@@ -2278,7 +2361,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
d->updateType = QQuickTextPrivate::UpdateNone;
- const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect.height() + d->lineHeightOffset(), height(), d->vAlign);
+ const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect.height() + d->lineHeightOffset(), d->availableHeight(), d->vAlign) + topPadding();
QQuickTextNode *node = 0;
if (!oldNode)
@@ -2295,11 +2378,11 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
const QColor linkColor = QColor::fromRgba(d->linkColor);
if (d->richText) {
- const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect.width(), width(), effectiveHAlign());
+ const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect.width(), d->availableWidth(), effectiveHAlign()) + leftPadding();
d->ensureDoc();
node->addTextDocument(QPointF(dx, dy), d->extra->doc, color, d->style, styleColor, linkColor);
} else if (d->layedOutTextRect.width() > 0) {
- const qreal dx = QQuickTextUtil::alignedX(d->lineWidth, width(), effectiveHAlign());
+ const qreal dx = QQuickTextUtil::alignedX(d->lineWidth, d->availableWidth(), effectiveHAlign()) + leftPadding();
int unelidedLineCount = d->lineCount;
if (d->elideLayout)
unelidedLineCount -= 1;
@@ -2584,14 +2667,15 @@ QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) const
{
Q_Q(const QQuickText);
QPointF translatedMousePos = mousePos;
- translatedMousePos.ry() -= QQuickTextUtil::alignedY(layedOutTextRect.height() + lineHeightOffset(), q->height(), vAlign);
+ translatedMousePos.rx() -= q->leftPadding();
+ translatedMousePos.ry() -= q->topPadding() + QQuickTextUtil::alignedY(layedOutTextRect.height() + lineHeightOffset(), availableHeight(), vAlign);
if (styledText) {
QString link = anchorAt(&layout, translatedMousePos);
if (link.isEmpty() && elideLayout)
link = anchorAt(elideLayout, translatedMousePos);
return link;
} else if (richText && extra.isAllocated() && extra->doc) {
- translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect.width(), q->width(), q->effectiveHAlign());
+ translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect.width(), availableWidth(), q->effectiveHAlign());
return extra->doc->documentLayout()->anchorAt(translatedMousePos);
}
return QString();
@@ -2809,4 +2893,124 @@ void QQuickText::invalidateFontCaches()
}
}
+/*!
+ \since 5.6
+ \qmlproperty real QtQuick::Text::padding
+ \qmlproperty real QtQuick::Text::topPadding
+ \qmlproperty real QtQuick::Text::leftPadding
+ \qmlproperty real QtQuick::Text::bottomPadding
+ \qmlproperty real QtQuick::Text::rightPadding
+
+ These properties hold the padding around the content. This space is reserved
+ in addition to the contentWidth and contentHeight.
+*/
+qreal QQuickText::padding() const
+{
+ Q_D(const QQuickText);
+ return d->padding;
+}
+
+void QQuickText::setPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ if (qFuzzyCompare(d->padding, padding))
+ return;
+ d->padding = padding;
+ d->updateSize();
+ emit paddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitTopPadding)
+ emit topPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitLeftPadding)
+ emit leftPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitRightPadding)
+ emit rightPaddingChanged();
+ if (!d->extra.isAllocated() || !d->extra->explicitBottomPadding)
+ emit bottomPaddingChanged();
+}
+
+void QQuickText::resetPadding()
+{
+ setPadding(0);
+}
+
+qreal QQuickText::topPadding() const
+{
+ Q_D(const QQuickText);
+ if (d->extra.isAllocated() && d->extra->explicitTopPadding)
+ return d->extra->topPadding;
+ return d->padding;
+}
+
+void QQuickText::setTopPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ d->setTopPadding(padding);
+}
+
+void QQuickText::resetTopPadding()
+{
+ Q_D(QQuickText);
+ d->setTopPadding(0, true);
+}
+
+qreal QQuickText::leftPadding() const
+{
+ Q_D(const QQuickText);
+ if (d->extra.isAllocated() && d->extra->explicitLeftPadding)
+ return d->extra->leftPadding;
+ return d->padding;
+}
+
+void QQuickText::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ d->setLeftPadding(padding);
+}
+
+void QQuickText::resetLeftPadding()
+{
+ Q_D(QQuickText);
+ d->setLeftPadding(0, true);
+}
+
+qreal QQuickText::rightPadding() const
+{
+ Q_D(const QQuickText);
+ if (d->extra.isAllocated() && d->extra->explicitRightPadding)
+ return d->extra->rightPadding;
+ return d->padding;
+}
+
+void QQuickText::setRightPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ d->setRightPadding(padding);
+}
+
+void QQuickText::resetRightPadding()
+{
+ Q_D(QQuickText);
+ d->setRightPadding(0, true);
+}
+
+qreal QQuickText::bottomPadding() const
+{
+ Q_D(const QQuickText);
+ if (d->extra.isAllocated() && d->extra->explicitBottomPadding)
+ return d->extra->bottomPadding;
+ return d->padding;
+}
+
+void QQuickText::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickText);
+ d->setBottomPadding(padding);
+}
+
+void QQuickText::resetBottomPadding()
+{
+ Q_D(QQuickText);
+ d->setBottomPadding(0, true);
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 283e3b510b..31a7205304 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -84,6 +84,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2)
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+
public:
QQuickText(QQuickItem *parent=0);
~QQuickText();
@@ -204,6 +210,26 @@ public:
Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
+ qreal padding() const;
+ void setPadding(qreal padding);
+ void resetPadding();
+
+ qreal topPadding() const;
+ void setTopPadding(qreal padding);
+ void resetTopPadding();
+
+ qreal leftPadding() const;
+ void setLeftPadding(qreal padding);
+ void resetLeftPadding();
+
+ qreal rightPadding() const;
+ void setRightPadding(qreal padding);
+ void resetRightPadding();
+
+ qreal bottomPadding() const;
+ void setBottomPadding(qreal padding);
+ void resetBottomPadding();
+
Q_SIGNALS:
void textChanged(const QString &text);
void linkActivated(const QString &link);
@@ -231,6 +257,11 @@ Q_SIGNALS:
void lineLaidOut(QQuickTextLine *line);
void baseUrlChanged();
void renderTypeChanged();
+ Q_REVISION(6) void paddingChanged();
+ Q_REVISION(6) void topPaddingChanged();
+ Q_REVISION(6) void leftPaddingChanged();
+ Q_REVISION(6) void rightPaddingChanged();
+ Q_REVISION(6) void bottomPaddingChanged();
protected:
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 9a6da3736e..6f954dd8c5 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -87,6 +87,14 @@ public:
struct ExtraData {
ExtraData();
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
+ bool explicitTopPadding;
+ bool explicitLeftPadding;
+ bool explicitRightPadding;
+ bool explicitBottomPadding;
qreal lineHeight;
QQuickTextDocumentWithImageResources *doc;
QString activeLink;
@@ -111,6 +119,7 @@ public:
QTextLayout *elideLayout;
QQuickTextLine *textLine;
+ qreal padding;
qreal lineWidth;
QRgb color;
@@ -159,6 +168,14 @@ public:
qreal getImplicitWidth() const Q_DECL_OVERRIDE;
qreal getImplicitHeight() const Q_DECL_OVERRIDE;
+ qreal availableWidth() const;
+ qreal availableHeight() const;
+
+ void setTopPadding(qreal value, bool reset = false);
+ void setLeftPadding(qreal value, bool reset = false);
+ void setRightPadding(qreal value, bool reset = false);
+ void setBottomPadding(qreal value, bool reset = false);
+
void ensureDoc();
QRectF setupTextLayout(qreal * const baseline);
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 8237ad10e4..0601932beb 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -699,6 +699,62 @@ Qt::InputMethodHints QQuickTextEditPrivate::effectiveInputMethodHints() const
}
#endif
+void QQuickTextEditPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextEdit);
+ qreal oldPadding = q->topPadding();
+ topPadding = value;
+ explicitTopPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ q->updateSize();
+ emit q->topPaddingChanged();
+ }
+}
+
+void QQuickTextEditPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextEdit);
+ qreal oldPadding = q->topPadding();
+ leftPadding = value;
+ explicitLeftPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ q->updateSize();
+ emit q->leftPaddingChanged();
+ if (q->isComponentComplete()) {
+ updateType = QQuickTextEditPrivate::UpdatePaintNode;
+ q->update();
+ }
+ }
+}
+
+void QQuickTextEditPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextEdit);
+ qreal oldPadding = q->topPadding();
+ rightPadding = value;
+ explicitRightPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ q->updateSize();
+ emit q->rightPaddingChanged();
+ if (q->isComponentComplete()) {
+ updateType = QQuickTextEditPrivate::UpdatePaintNode;
+ q->update();
+ }
+ }
+}
+
+void QQuickTextEditPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextEdit);
+ qreal oldPadding = q->topPadding();
+ bottomPadding = value;
+ explicitBottomPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ q->updateSize();
+ emit q->bottomPaddingChanged();
+ }
+}
+
QQuickTextEdit::VAlignment QQuickTextEdit::vAlign() const
{
Q_D(const QQuickTextEdit);
@@ -2106,7 +2162,7 @@ void QQuickTextEdit::markDirtyNodesForRange(int start, int end, int charDelta)
}
// mark the affected nodes as dirty
- while (it != d->textNodeMap.constEnd()) {
+ while (it != d->textNodeMap.end()) {
if ((*it)->startPos() <= end)
(*it)->setDirty();
else if (charDelta)
@@ -2232,7 +2288,7 @@ void QQuickTextEdit::updateSize()
return;
}
- qreal naturalWidth = d->implicitWidth;
+ qreal naturalWidth = d->implicitWidth - leftPadding() - rightPadding();
qreal newWidth = d->document->idealWidth();
// ### assumes that if the width is set, the text will fill to edges
@@ -2250,13 +2306,13 @@ void QQuickTextEdit::updateSize()
const bool wasInLayout = d->inLayout;
d->inLayout = true;
- setImplicitWidth(naturalWidth);
+ setImplicitWidth(naturalWidth + leftPadding() + rightPadding());
d->inLayout = wasInLayout;
if (d->inLayout) // probably the result of a binding loop, but by letting it
return; // get this far we'll get a warning to that effect.
}
if (d->document->textWidth() != width()) {
- d->document->setTextWidth(width());
+ d->document->setTextWidth(width() - leftPadding() - rightPadding());
newWidth = d->document->idealWidth();
}
//### need to confirm cost of always setting these
@@ -2271,12 +2327,12 @@ void QQuickTextEdit::updateSize()
// ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
if (!widthValid() && !d->requireImplicitWidth)
- setImplicitSize(newWidth, newHeight);
+ setImplicitSize(newWidth + leftPadding() + rightPadding(), newHeight + topPadding() + bottomPadding());
else
- setImplicitHeight(newHeight);
+ setImplicitHeight(newHeight + topPadding() + bottomPadding());
- d->xoff = qMax(qreal(0), QQuickTextUtil::alignedX(d->document->size().width(), width(), effectiveHAlign()));
- d->yoff = QQuickTextUtil::alignedY(d->document->size().height(), height(), d->vAlign);
+ d->xoff = leftPadding() + qMax(qreal(0), QQuickTextUtil::alignedX(d->document->size().width(), width() - leftPadding() - rightPadding(), effectiveHAlign()));
+ d->yoff = topPadding() + QQuickTextUtil::alignedY(d->document->size().height(), height() - topPadding() - bottomPadding(), d->vAlign);
setBaselineOffset(fm.ascent() + d->yoff + d->textMargin);
QSizeF size(newWidth, newHeight);
@@ -2423,10 +2479,13 @@ void QQuickTextEditPrivate::handleFocusEvent(QFocusEvent *event)
qGuiApp->inputMethod()->show();
q->connect(QGuiApplication::inputMethod(), SIGNAL(inputDirectionChanged(Qt::LayoutDirection)),
q, SLOT(q_updateAlignment()));
+#endif
} else {
+#ifndef QT_NO_IM
q->disconnect(QGuiApplication::inputMethod(), SIGNAL(inputDirectionChanged(Qt::LayoutDirection)),
q, SLOT(q_updateAlignment()));
#endif
+ emit q->editingFinished();
}
}
@@ -2595,6 +2654,15 @@ bool QQuickTextEditPrivate::isLinkHoveredConnected()
*/
/*!
+ \qmlsignal QtQuick::TextEdit::editingFinished()
+ \since 5.6
+
+ This signal is emitted when the text edit loses focus.
+
+ The corresponding handler is \c onEditingFinished.
+*/
+
+/*!
\qmlproperty string QtQuick::TextEdit::hoveredLink
\since 5.2
@@ -2687,7 +2755,131 @@ void QQuickTextEdit::append(const QString &text)
QString QQuickTextEdit::linkAt(qreal x, qreal y) const
{
Q_D(const QQuickTextEdit);
- return d->control->anchorAt(QPointF(x, y));
+ return d->control->anchorAt(QPointF(x + topPadding(), y + leftPadding()));
+}
+
+/*!
+ \since 5.6
+ \qmlproperty real QtQuick::TextEdit::padding
+ \qmlproperty real QtQuick::TextEdit::topPadding
+ \qmlproperty real QtQuick::TextEdit::leftPadding
+ \qmlproperty real QtQuick::TextEdit::bottomPadding
+ \qmlproperty real QtQuick::TextEdit::rightPadding
+
+ These properties hold the padding around the content. This space is reserved
+ in addition to the contentWidth and contentHeight.
+*/
+qreal QQuickTextEdit::padding() const
+{
+ Q_D(const QQuickTextEdit);
+ return d->padding;
+}
+
+void QQuickTextEdit::setPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ if (qFuzzyCompare(d->padding, padding))
+ return;
+ d->padding = padding;
+ updateSize();
+ if (isComponentComplete()) {
+ d->updateType = QQuickTextEditPrivate::UpdatePaintNode;
+ update();
+ }
+ emit paddingChanged();
+ if (!d->explicitTopPadding)
+ emit topPaddingChanged();
+ if (!d->explicitLeftPadding)
+ emit leftPaddingChanged();
+ if (!d->explicitRightPadding)
+ emit rightPaddingChanged();
+ if (!d->explicitBottomPadding)
+ emit bottomPaddingChanged();
+}
+
+void QQuickTextEdit::resetPadding()
+{
+ setPadding(0);
+}
+
+qreal QQuickTextEdit::topPadding() const
+{
+ Q_D(const QQuickTextEdit);
+ if (d->explicitTopPadding)
+ return d->topPadding;
+ return d->padding;
+}
+
+void QQuickTextEdit::setTopPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ d->setTopPadding(padding);
+}
+
+void QQuickTextEdit::resetTopPadding()
+{
+ Q_D(QQuickTextEdit);
+ d->setTopPadding(0, true);
+}
+
+qreal QQuickTextEdit::leftPadding() const
+{
+ Q_D(const QQuickTextEdit);
+ if (d->explicitLeftPadding)
+ return d->leftPadding;
+ return d->padding;
+}
+
+void QQuickTextEdit::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ d->setLeftPadding(padding);
+}
+
+void QQuickTextEdit::resetLeftPadding()
+{
+ Q_D(QQuickTextEdit);
+ d->setLeftPadding(0, true);
+}
+
+qreal QQuickTextEdit::rightPadding() const
+{
+ Q_D(const QQuickTextEdit);
+ if (d->explicitRightPadding)
+ return d->rightPadding;
+ return d->padding;
+}
+
+void QQuickTextEdit::setRightPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ d->setRightPadding(padding);
+}
+
+void QQuickTextEdit::resetRightPadding()
+{
+ Q_D(QQuickTextEdit);
+ d->setRightPadding(0, true);
+}
+
+qreal QQuickTextEdit::bottomPadding() const
+{
+ Q_D(const QQuickTextEdit);
+ if (d->explicitBottomPadding)
+ return d->bottomPadding;
+ return d->padding;
+}
+
+void QQuickTextEdit::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickTextEdit);
+ d->setBottomPadding(padding);
+}
+
+void QQuickTextEdit::resetBottomPadding()
+{
+ Q_D(QQuickTextEdit);
+ d->setBottomPadding(0, true);
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index bf6763f772..f1ccd72ca9 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -91,8 +91,13 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged)
Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl RESET resetBaseUrl NOTIFY baseUrlChanged)
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
- Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument FINAL REVISION 1)
+ Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument CONSTANT FINAL REVISION 1)
Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2)
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
public:
QQuickTextEdit(QQuickItem *parent=0);
@@ -247,6 +252,26 @@ public:
Q_REVISION(3) Q_INVOKABLE QString linkAt(qreal x, qreal y) const;
+ qreal padding() const;
+ void setPadding(qreal padding);
+ void resetPadding();
+
+ qreal topPadding() const;
+ void setTopPadding(qreal padding);
+ void resetTopPadding();
+
+ qreal leftPadding() const;
+ void setLeftPadding(qreal padding);
+ void resetLeftPadding();
+
+ qreal rightPadding() const;
+ void setRightPadding(qreal padding);
+ void resetRightPadding();
+
+ qreal bottomPadding() const;
+ void setBottomPadding(qreal padding);
+ void resetBottomPadding();
+
Q_SIGNALS:
void textChanged();
void contentSizeChanged();
@@ -283,6 +308,12 @@ Q_SIGNALS:
void baseUrlChanged();
void inputMethodHintsChanged();
void renderTypeChanged();
+ Q_REVISION(6) void editingFinished();
+ Q_REVISION(6) void paddingChanged();
+ Q_REVISION(6) void topPaddingChanged();
+ Q_REVISION(6) void leftPaddingChanged();
+ Q_REVISION(6) void rightPaddingChanged();
+ Q_REVISION(6) void bottomPaddingChanged();
public Q_SLOTS:
void selectAll();
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index 0cf0f46532..20c0d1ca9c 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -84,7 +84,9 @@ public:
QQuickTextEditPrivate()
: color(QRgb(0xFF000000)), selectionColor(QRgb(0xFF000080)), selectedTextColor(QRgb(0xFFFFFFFF))
- , textMargin(0.0), xoff(0), yoff(0), font(sourceFont), cursorComponent(0), cursorItem(0), document(0), control(0)
+ , textMargin(0.0), xoff(0), yoff(0), padding(0), topPadding(0), leftPadding(0), rightPadding(0), bottomPadding(0)
+ , explicitTopPadding(false), explicitLeftPadding(false), explicitRightPadding(false), explicitBottomPadding(false)
+ , font(sourceFont), cursorComponent(0), cursorItem(0), document(0), control(0)
, quickDocument(0), lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
, hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
, format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
@@ -131,6 +133,11 @@ public:
Qt::InputMethodHints effectiveInputMethodHints() const;
#endif
+ void setTopPadding(qreal value, bool reset = false);
+ void setLeftPadding(qreal value, bool reset = false);
+ void setRightPadding(qreal value, bool reset = false);
+ void setBottomPadding(qreal value, bool reset = false);
+
QColor color;
QColor selectionColor;
QColor selectedTextColor;
@@ -140,6 +147,15 @@ public:
qreal textMargin;
qreal xoff;
qreal yoff;
+ qreal padding;
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
+ bool explicitTopPadding;
+ bool explicitLeftPadding;
+ bool explicitRightPadding;
+ bool explicitBottomPadding;
QString text;
QUrl baseUrl;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index a4c61209f2..c5f3f3ffaf 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -786,8 +786,8 @@ QRectF QQuickTextInput::cursorRectangle() const
QTextLine l = d->m_textLayout.lineForTextPosition(c);
if (!l.isValid())
return QRectF();
- qreal x = l.cursorToX(c) - d->hscroll;
- qreal y = l.y() - d->vscroll;
+ qreal x = l.cursorToX(c) - d->hscroll + leftPadding();
+ qreal y = l.y() - d->vscroll + topPadding();
return QRectF(x, y, 1, l.height());
}
@@ -910,189 +910,6 @@ void QQuickTextInput::setAutoScroll(bool b)
emit autoScrollChanged(d->autoScroll);
}
-#ifndef QT_NO_VALIDATOR
-
-/*!
- \qmltype IntValidator
- \instantiates QIntValidator
- \inqmlmodule QtQuick
- \ingroup qtquick-text-utility
- \brief Defines a validator for integer values
-
- The IntValidator type provides a validator for integer values.
-
- If no \l locale is set IntValidator uses the \l {QLocale::setDefault()}{default locale} to
- interpret the number and will accept locale specific digits, group separators, and positive
- and negative signs. In addition, IntValidator is always guaranteed to accept a number
- formatted according to the "C" locale.
-*/
-
-
-QQuickIntValidator::QQuickIntValidator(QObject *parent)
- : QIntValidator(parent)
-{
-}
-
-/*!
- \qmlproperty string QtQuick::IntValidator::locale
-
- This property holds the name of the locale used to interpret the number.
-
- \sa {QtQml::Qt::locale()}{Qt.locale()}
-*/
-
-QString QQuickIntValidator::localeName() const
-{
- return locale().name();
-}
-
-void QQuickIntValidator::setLocaleName(const QString &name)
-{
- if (locale().name() != name) {
- setLocale(QLocale(name));
- emit localeNameChanged();
- }
-}
-
-void QQuickIntValidator::resetLocaleName()
-{
- QLocale defaultLocale;
- if (locale() != defaultLocale) {
- setLocale(defaultLocale);
- emit localeNameChanged();
- }
-}
-
-/*!
- \qmlproperty int QtQuick::IntValidator::top
-
- This property holds the validator's highest acceptable value.
- By default, this property's value is derived from the highest signed integer available (typically 2147483647).
-*/
-/*!
- \qmlproperty int QtQuick::IntValidator::bottom
-
- This property holds the validator's lowest acceptable value.
- By default, this property's value is derived from the lowest signed integer available (typically -2147483647).
-*/
-
-/*!
- \qmltype DoubleValidator
- \instantiates QDoubleValidator
- \inqmlmodule QtQuick
- \ingroup qtquick-text-utility
- \brief Defines a validator for non-integer numbers
-
- The DoubleValidator type provides a validator for non-integer numbers.
-
- Input is accepted if it contains a double that is within the valid range
- and is in the correct format.
-
- Input is accepected but invalid if it contains a double that is outside
- the range or is in the wrong format; e.g. with too many digits after the
- decimal point or is empty.
-
- Input is rejected if it is not a double.
-
- Note: If the valid range consists of just positive doubles (e.g. 0.0 to
- 100.0) and input is a negative double then it is rejected. If \l notation
- is set to DoubleValidator.StandardNotation, and the input contains more
- digits before the decimal point than a double in the valid range may have,
- it is also rejected. If \l notation is DoubleValidator.ScientificNotation,
- and the input is not in the valid range, it is accecpted but invalid. The
- value may yet become valid by changing the exponent.
-*/
-
-QQuickDoubleValidator::QQuickDoubleValidator(QObject *parent)
- : QDoubleValidator(parent)
-{
-}
-
-/*!
- \qmlproperty string QtQuick::DoubleValidator::locale
-
- This property holds the name of the locale used to interpret the number.
-
- \sa {QtQml::Qt::locale()}{Qt.locale()}
-*/
-
-QString QQuickDoubleValidator::localeName() const
-{
- return locale().name();
-}
-
-void QQuickDoubleValidator::setLocaleName(const QString &name)
-{
- if (locale().name() != name) {
- setLocale(QLocale(name));
- emit localeNameChanged();
- }
-}
-
-void QQuickDoubleValidator::resetLocaleName()
-{
- QLocale defaultLocale;
- if (locale() != defaultLocale) {
- setLocale(defaultLocale);
- emit localeNameChanged();
- }
-}
-
-#endif // QT_NO_VALIDATOR
-
-/*!
- \qmlproperty real QtQuick::DoubleValidator::top
-
- This property holds the validator's maximum acceptable value.
- By default, this property contains a value of infinity.
-*/
-/*!
- \qmlproperty real QtQuick::DoubleValidator::bottom
-
- This property holds the validator's minimum acceptable value.
- By default, this property contains a value of -infinity.
-*/
-/*!
- \qmlproperty int QtQuick::DoubleValidator::decimals
-
- This property holds the validator's maximum number of digits after the decimal point.
- By default, this property contains a value of 1000.
-*/
-/*!
- \qmlproperty enumeration QtQuick::DoubleValidator::notation
- This property holds the notation of how a string can describe a number.
-
- The possible values for this property are:
-
- \list
- \li DoubleValidator.StandardNotation
- \li DoubleValidator.ScientificNotation (default)
- \endlist
-
- If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part (e.g. 1.5E-2).
-*/
-
-/*!
- \qmltype RegExpValidator
- \instantiates QRegExpValidator
- \inqmlmodule QtQuick
- \ingroup qtquick-text-utility
- \brief Provides a string validator
-
- The RegExpValidator type provides a validator, which counts as valid any string which
- matches a specified regular expression.
-*/
-/*!
- \qmlproperty regExp QtQuick::RegExpValidator::regExp
-
- This property holds the regular expression used for validation.
-
- Note that this property should be a regular expression in JS syntax, e.g /a/ for the regular expression
- matching "a".
-
- By default, this property contains a regular expression with the pattern .* that matches any string.
-*/
-
/*!
\qmlproperty Validator QtQuick::TextInput::validator
@@ -1489,8 +1306,9 @@ void QQuickTextInput::positionAt(QQmlV4Function *args) const
int QQuickTextInputPrivate::positionAt(qreal x, qreal y, QTextLine::CursorPosition position) const
{
- x += hscroll;
- y += vscroll;
+ Q_Q(const QQuickTextInput);
+ x += hscroll - q->leftPadding();
+ y += vscroll - q->topPadding();
QTextLine line = m_textLayout.lineAt(0);
for (int i = 1; i < m_textLayout.lineCount(); ++i) {
QTextLine nextLine = m_textLayout.lineAt(i);
@@ -1748,7 +1566,7 @@ void QQuickTextInputPrivate::ensureVisible(int position, int preeditCursor, int
{
Q_Q(QQuickTextInput);
QTextLine textLine = m_textLayout.lineForTextPosition(position + preeditCursor);
- const qreal width = qMax<qreal>(0, q->width());
+ const qreal width = qMax<qreal>(0, q->width() - q->leftPadding() - q->rightPadding());
qreal cix = 0;
qreal widthUsed = 0;
if (textLine.isValid()) {
@@ -1811,7 +1629,7 @@ void QQuickTextInputPrivate::updateVerticalScroll()
#ifndef QT_NO_IM
const int preeditLength = m_textLayout.preeditAreaText().length();
#endif
- const qreal height = qMax<qreal>(0, q->height());
+ const qreal height = qMax<qreal>(0, q->height() - q->topPadding() - q->bottomPadding());
qreal heightUsed = contentSize.height();
qreal previousScroll = vscroll;
@@ -1920,13 +1738,13 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
node->deleteContent();
node->setMatrix(QMatrix4x4());
- QPointF offset(0, 0);
+ QPointF offset(leftPadding(), topPadding());
if (d->autoScroll && d->m_textLayout.lineCount() > 0) {
QFontMetricsF fm(d->font);
// the y offset is there to keep the baseline constant in case we have script changes in the text.
- offset = -QPointF(d->hscroll, d->vscroll + d->m_textLayout.lineAt(0).ascent() - fm.ascent());
+ offset += -QPointF(d->hscroll, d->vscroll + d->m_textLayout.lineAt(0).ascent() - fm.ascent());
} else {
- offset = -QPointF(d->hscroll, d->vscroll);
+ offset += -QPointF(d->hscroll, d->vscroll);
}
if (!d->m_textLayout.text().isEmpty()
@@ -2882,7 +2700,7 @@ qreal QQuickTextInputPrivate::getImplicitWidth() const
QTextLine line = layout.createLine();
line.setLineWidth(INT_MAX);
- d->implicitWidth = qCeil(line.naturalTextWidth());
+ d->implicitWidth = qCeil(line.naturalTextWidth()) + q->leftPadding() + q->rightPadding();
layout.endLayout();
}
@@ -2890,6 +2708,54 @@ qreal QQuickTextInputPrivate::getImplicitWidth() const
return implicitWidth;
}
+void QQuickTextInputPrivate::setTopPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextInput);
+ qreal oldPadding = q->topPadding();
+ topPadding = value;
+ explicitTopPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ updateLayout();
+ emit q->topPaddingChanged();
+ }
+}
+
+void QQuickTextInputPrivate::setLeftPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextInput);
+ qreal oldPadding = q->leftPadding();
+ leftPadding = value;
+ explicitLeftPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ updateLayout();
+ emit q->leftPaddingChanged();
+ }
+}
+
+void QQuickTextInputPrivate::setRightPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextInput);
+ qreal oldPadding = q->rightPadding();
+ rightPadding = value;
+ explicitRightPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ updateLayout();
+ emit q->rightPaddingChanged();
+ }
+}
+
+void QQuickTextInputPrivate::setBottomPadding(qreal value, bool reset)
+{
+ Q_Q(QQuickTextInput);
+ qreal oldPadding = q->bottomPadding();
+ bottomPadding = value;
+ explicitBottomPadding = !reset;
+ if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding))) {
+ updateLayout();
+ emit q->bottomPaddingChanged();
+ }
+}
+
void QQuickTextInputPrivate::updateLayout()
{
Q_Q(QQuickTextInput);
@@ -2915,12 +2781,12 @@ void QQuickTextInputPrivate::updateLayout()
line.setLineWidth(INT_MAX);
const bool wasInLayout = inLayout;
inLayout = true;
- q->setImplicitWidth(qCeil(line.naturalTextWidth()));
+ q->setImplicitWidth(qCeil(line.naturalTextWidth()) + q->leftPadding() + q->rightPadding());
inLayout = wasInLayout;
if (inLayout) // probably the result of a binding loop, but by letting it
return; // get this far we'll get a warning to that effect.
}
- qreal lineWidth = q->widthValid() ? q->width() : INT_MAX;
+ qreal lineWidth = q->widthValid() ? q->width() - q->leftPadding() - q->rightPadding() : INT_MAX;
qreal height = 0;
qreal width = 0;
do {
@@ -2947,9 +2813,9 @@ void QQuickTextInputPrivate::updateLayout()
q->update();
if (!requireImplicitWidth && !q->widthValid())
- q->setImplicitSize(width, height);
+ q->setImplicitSize(width + q->leftPadding() + q->rightPadding(), height + q->topPadding() + q->bottomPadding());
else
- q->setImplicitHeight(height);
+ q->setImplicitHeight(height + q->topPadding() + q->bottomPadding());
updateBaselineOffset();
@@ -2971,13 +2837,13 @@ void QQuickTextInputPrivate::updateBaselineOffset()
QFontMetricsF fm(font);
qreal yoff = 0;
if (q->heightValid()) {
- const qreal surplusHeight = q->height() - contentSize.height();
+ const qreal surplusHeight = q->height() - contentSize.height() - q->topPadding() - q->bottomPadding();
if (vAlign == QQuickTextInput::AlignBottom)
yoff = surplusHeight;
else if (vAlign == QQuickTextInput::AlignVCenter)
yoff = surplusHeight/2;
}
- q->setBaselineOffset(fm.ascent() + yoff);
+ q->setBaselineOffset(fm.ascent() + yoff + q->topPadding());
}
#ifndef QT_NO_CLIPBOARD
@@ -4273,6 +4139,21 @@ void QQuickTextInputPrivate::processKeyEvent(QKeyEvent* event)
return;
}
+ if (m_blinkPeriod > 0) {
+ if (m_blinkTimer)
+ q->killTimer(m_blinkTimer);
+
+ m_blinkTimer = q->startTimer(m_blinkPeriod / 2);
+
+ if (m_blinkStatus == 0) {
+ m_blinkStatus = 1;
+
+ updateType = UpdatePaintNode;
+ q->polish();
+ q->update();
+ }
+ }
+
if (m_echoMode == QQuickTextInput::PasswordEchoOnEdit
&& !m_passwordEchoEditing
&& !m_readOnly
@@ -4508,5 +4389,125 @@ void QQuickTextInput::ensureVisible(int position)
updateCursorRectangle(false);
}
+/*!
+ \since 5.6
+ \qmlproperty real QtQuick::TextInput::padding
+ \qmlproperty real QtQuick::TextInput::topPadding
+ \qmlproperty real QtQuick::TextInput::leftPadding
+ \qmlproperty real QtQuick::TextInput::bottomPadding
+ \qmlproperty real QtQuick::TextInput::rightPadding
+
+ These properties hold the padding around the content. This space is reserved
+ in addition to the contentWidth and contentHeight.
+*/
+qreal QQuickTextInput::padding() const
+{
+ Q_D(const QQuickTextInput);
+ return d->padding;
+}
+
+void QQuickTextInput::setPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ if (qFuzzyCompare(d->padding, padding))
+ return;
+ d->padding = padding;
+ d->updateLayout();
+ emit paddingChanged();
+ if (!d->explicitTopPadding)
+ emit topPaddingChanged();
+ if (!d->explicitLeftPadding)
+ emit leftPaddingChanged();
+ if (!d->explicitRightPadding)
+ emit rightPaddingChanged();
+ if (!d->explicitBottomPadding)
+ emit bottomPaddingChanged();
+}
+
+void QQuickTextInput::resetPadding()
+{
+ setPadding(0);
+}
+
+qreal QQuickTextInput::topPadding() const
+{
+ Q_D(const QQuickTextInput);
+ if (d->explicitTopPadding)
+ return d->topPadding;
+ return d->padding;
+}
+
+void QQuickTextInput::setTopPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ d->setTopPadding(padding);
+}
+
+void QQuickTextInput::resetTopPadding()
+{
+ Q_D(QQuickTextInput);
+ d->setTopPadding(0, true);
+}
+
+qreal QQuickTextInput::leftPadding() const
+{
+ Q_D(const QQuickTextInput);
+ if (d->explicitLeftPadding)
+ return d->leftPadding;
+ return d->padding;
+}
+
+void QQuickTextInput::setLeftPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ d->setLeftPadding(padding);
+}
+
+void QQuickTextInput::resetLeftPadding()
+{
+ Q_D(QQuickTextInput);
+ d->setLeftPadding(0, true);
+}
+
+qreal QQuickTextInput::rightPadding() const
+{
+ Q_D(const QQuickTextInput);
+ if (d->explicitRightPadding)
+ return d->rightPadding;
+ return d->padding;
+}
+
+void QQuickTextInput::setRightPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ d->setRightPadding(padding);
+}
+
+void QQuickTextInput::resetRightPadding()
+{
+ Q_D(QQuickTextInput);
+ d->setRightPadding(0, true);
+}
+
+qreal QQuickTextInput::bottomPadding() const
+{
+ Q_D(const QQuickTextInput);
+ if (d->explicitBottomPadding)
+ return d->bottomPadding;
+ return d->padding;
+}
+
+void QQuickTextInput::setBottomPadding(qreal padding)
+{
+ Q_D(QQuickTextInput);
+ d->setBottomPadding(padding);
+}
+
+void QQuickTextInput::resetBottomPadding()
+{
+ Q_D(QQuickTextInput);
+ d->setBottomPadding(0, true);
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index 3bcbe0fa25..333f55b35f 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -96,6 +96,12 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(qreal contentHeight READ contentHeight NOTIFY contentSizeChanged)
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
+ Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
+ Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
+ Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
+
public:
QQuickTextInput(QQuickItem * parent=0);
~QQuickTextInput();
@@ -260,6 +266,26 @@ public:
qreal contentWidth() const;
qreal contentHeight() const;
+ qreal padding() const;
+ void setPadding(qreal padding);
+ void resetPadding();
+
+ qreal topPadding() const;
+ void setTopPadding(qreal padding);
+ void resetTopPadding();
+
+ qreal leftPadding() const;
+ void setLeftPadding(qreal padding);
+ void resetLeftPadding();
+
+ qreal rightPadding() const;
+ void setRightPadding(qreal padding);
+ void resetRightPadding();
+
+ qreal bottomPadding() const;
+ void setBottomPadding(qreal padding);
+ void resetBottomPadding();
+
Q_SIGNALS:
void textChanged();
void cursorPositionChanged();
@@ -300,6 +326,11 @@ Q_SIGNALS:
void contentSizeChanged();
void inputMethodHintsChanged();
void renderTypeChanged();
+ Q_REVISION(6) void paddingChanged();
+ Q_REVISION(6) void topPaddingChanged();
+ Q_REVISION(6) void leftPaddingChanged();
+ Q_REVISION(6) void rightPaddingChanged();
+ Q_REVISION(6) void bottomPaddingChanged();
private:
void invalidateFontCaches();
@@ -360,46 +391,8 @@ private:
Q_DECLARE_PRIVATE(QQuickTextInput)
};
-#ifndef QT_NO_VALIDATOR
-class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator
-{
- Q_OBJECT
- Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
-public:
- QQuickIntValidator(QObject *parent = 0);
-
- QString localeName() const;
- void setLocaleName(const QString &name);
- void resetLocaleName();
-
-Q_SIGNALS:
- void localeNameChanged();
-};
-
-class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator
-{
- Q_OBJECT
- Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
-public:
- QQuickDoubleValidator(QObject *parent = 0);
-
- QString localeName() const;
- void setLocaleName(const QString &name);
- void resetLocaleName();
-
-Q_SIGNALS:
- void localeNameChanged();
-};
-#endif
-
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickTextInput)
-#ifndef QT_NO_VALIDATOR
-QML_DECLARE_TYPE(QValidator)
-QML_DECLARE_TYPE(QQuickIntValidator)
-QML_DECLARE_TYPE(QQuickDoubleValidator)
-QML_DECLARE_TYPE(QRegExpValidator)
-#endif
#endif // QQUICKTEXTINPUT_P_H
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 3038573bb3..25ee2e79ce 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -74,6 +74,15 @@ public:
QQuickTextInputPrivate()
: hscroll(0)
, vscroll(0)
+ , padding(0)
+ , topPadding(0)
+ , leftPadding(0)
+ , rightPadding(0)
+ , bottomPadding(0)
+ , explicitTopPadding(false)
+ , explicitLeftPadding(false)
+ , explicitRightPadding(false)
+ , explicitBottomPadding(false)
, cursorItem(0)
, textNode(0)
, m_maskData(0)
@@ -189,6 +198,16 @@ public:
qreal hscroll;
qreal vscroll;
+ qreal padding;
+ qreal topPadding;
+ qreal leftPadding;
+ qreal rightPadding;
+ qreal bottomPadding;
+ bool explicitTopPadding;
+ bool explicitLeftPadding;
+ bool explicitRightPadding;
+ bool explicitBottomPadding;
+
QTextLayout m_textLayout;
QString m_text;
QString m_inputMask;
@@ -420,6 +439,11 @@ public:
qreal getImplicitWidth() const Q_DECL_OVERRIDE;
+ void setTopPadding(qreal value, bool reset = false);
+ void setLeftPadding(qreal value, bool reset = false);
+ void setRightPadding(qreal value, bool reset = false);
+ void setBottomPadding(qreal value, bool reset = false);
+
private:
void removeSelectedText();
void internalSetText(const QString &txt, int pos = -1, bool edited = true);
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 5b5413a4ba..6582e3ad40 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -345,6 +345,9 @@ QQuickView::Status QQuickView::status() const
if (!d->component)
return QQuickView::Null;
+ if (d->component->status() == QQmlComponent::Ready && !d->root)
+ return QQuickView::Error;
+
return QQuickView::Status(d->component->status());
}
@@ -364,6 +367,10 @@ QList<QQmlError> QQuickView::errors() const
QQmlError error;
error.setDescription(QLatin1String("QQuickView: invalid qml engine."));
errs << error;
+ } else if (d->component->status() == QQmlComponent::Ready && !d->root) {
+ QQmlError error;
+ error.setDescription(QLatin1String("QQuickView: invalid root object."));
+ errs << error;
}
return errs;
@@ -501,14 +508,15 @@ void QQuickViewPrivate::setRootObject(QObject *obj)
if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) {
root = sgItem;
sgItem->setParentItem(q->QQuickWindow::contentItem());
+ } else if (qobject_cast<QWindow *>(obj)) {
+ qWarning() << "QQuickView does not support using windows as a root item." << endl
+ << endl
+ << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << endl;
} else {
qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl
<< endl
- << "If your example is using QML 2, (such as qmlscene) and the .qml file you" << endl
- << "loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur." << endl
- << endl
- << "To load files with 'import QtQuick 1.0' or 'import Qt 4.7', use the" << endl
- << "QDeclarativeView class in the Qt Quick 1 module." << endl;
+ << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << endl
+ << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << endl;
delete obj;
root = 0;
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 84b585e3b5..ee2556af64 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -3308,12 +3308,7 @@ QOpenGLFramebufferObject *QQuickWindow::renderTarget() const
QImage QQuickWindow::grabWindow()
{
Q_D(QQuickWindow);
- if (!isVisible()) {
-
- if (d->context->openglContext()) {
- qWarning("QQuickWindow::grabWindow: scene graph already in use");
- return QImage();
- }
+ if (!isVisible() && !d->context->openglContext()) {
if (!handle() || !size().isValid()) {
qWarning("QQuickWindow::grabWindow: window must be created and have a valid size");
@@ -4116,6 +4111,7 @@ void QQuickWindow::resetOpenGLState()
\value BeforeRenderingStage Before rendering.
\value AfterRenderingStage After rendering.
\value AfterSwapStage After the frame is swapped.
+ \value NoStage As soon as possible. This value was added in Qt 5.6.
\sa {Scene Graph and Rendering}
*/
@@ -4141,8 +4137,17 @@ void QQuickWindow::resetOpenGLState()
If the rendering is happening on a different thread, then the job
will happen on the rendering thread.
- \note This function does not trigger rendering; the job
- will be stored run until rendering is triggered elsewhere.
+ If \a stage is \l NoStage, \a job will be run at the earliest opportunity
+ whenever the render thread is not busy rendering a frame. If there is no
+ OpenGL context available or the window is not exposed at the time the job is
+ either posted or handled, it is deleted without executing the run() method.
+ If a non-threaded renderer is in use, the run() method of the job is executed
+ synchronously.
+ The OpenGL context is changed to the renderer context before executing a
+ \l NoStage job.
+
+ \note This function does not trigger rendering; the jobs targeting any other
+ stage than NoStage will be stored run until rendering is triggered elsewhere.
To force the job to run earlier, call QQuickWindow::update();
\sa beforeRendering(), afterRendering(), beforeSynchronizing(),
@@ -4154,16 +4159,22 @@ void QQuickWindow::scheduleRenderJob(QRunnable *job, RenderStage stage)
Q_D(QQuickWindow);
d->renderJobMutex.lock();
- if (stage == BeforeSynchronizingStage)
+ if (stage == BeforeSynchronizingStage) {
d->beforeSynchronizingJobs << job;
- else if (stage == AfterSynchronizingStage)
+ } else if (stage == AfterSynchronizingStage) {
d->afterSynchronizingJobs << job;
- else if (stage == BeforeRenderingStage)
+ } else if (stage == BeforeRenderingStage) {
d->beforeRenderingJobs << job;
- else if (stage == AfterRenderingStage)
+ } else if (stage == AfterRenderingStage) {
d->afterRenderingJobs << job;
- else if (stage == AfterSwapStage)
+ } else if (stage == AfterSwapStage) {
d->afterSwapJobs << job;
+ } else if (stage == NoStage) {
+ if (isExposed())
+ d->windowManager->postJob(this, job);
+ else
+ delete job;
+ }
d->renderJobMutex.unlock();
}
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index f7a1956120..1a1d44c3b4 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -77,7 +77,8 @@ public:
AfterSynchronizingStage,
BeforeRenderingStage,
AfterRenderingStage,
- AfterSwapStage
+ AfterSwapStage,
+ NoStage
};
Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption)
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 63938d50a9..81e72b7946 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -1081,6 +1081,9 @@ void Renderer::nodeWasRemoved(Node *node)
if (e) {
e->removed = true;
m_elementsToDelete.add(e);
+
+ if (m_renderNodeElements.isEmpty())
+ m_useDepthBuffer = context()->openglContext()->format().depthBufferSize() > 0;
}
}
@@ -2547,8 +2550,15 @@ void Renderer::render()
QSGNodeDumper::dump(rootNode());
}
- if (Q_UNLIKELY(debug_render() || debug_build())) {
+ QElapsedTimer timer;
+ quint64 timeRenderLists = 0;
+ quint64 timePrepareOpaque = 0;
+ quint64 timePrepareAlpha = 0;
+ quint64 timeSorting = 0;
+ quint64 timeUploadOpaque = 0;
+ quint64 timeUploadAlpha = 0;
+ if (Q_UNLIKELY(debug_render() || debug_build())) {
QByteArray type("rebuild:");
if (m_rebuild == 0)
type += " none";
@@ -2564,6 +2574,7 @@ void Renderer::render()
}
qDebug() << "Renderer::render()" << this << type;
+ timer.start();
}
if (m_vao)
@@ -2590,6 +2601,7 @@ void Renderer::render()
}
}
}
+ if (Q_UNLIKELY(debug_render())) timeRenderLists = timer.restart();
for (int i=0; i<m_opaqueBatches.size(); ++i)
m_opaqueBatches.at(i)->cleanupRemovedElements();
@@ -2602,7 +2614,9 @@ void Renderer::render()
if (m_rebuild & BuildBatches) {
prepareOpaqueBatches();
+ if (Q_UNLIKELY(debug_render())) timePrepareOpaque = timer.restart();
prepareAlphaBatches();
+ if (Q_UNLIKELY(debug_render())) timePrepareAlpha = timer.restart();
if (Q_UNLIKELY(debug_build())) {
qDebug() << "Opaque Batches:";
@@ -2622,8 +2636,11 @@ void Renderer::render()
}
}
}
+ } else {
+ if (Q_UNLIKELY(debug_render())) timePrepareOpaque = timePrepareAlpha = timer.restart();
}
+
deleteRemovedElements();
if (m_rebuild != 0) {
@@ -2639,6 +2656,8 @@ void Renderer::render()
m_zRange = 1.0 / (m_nextRenderOrder);
}
+ if (Q_UNLIKELY(debug_render())) timeSorting = timer.restart();
+
int largestVBO = 0;
#ifdef QSG_SEPARATE_INDEX_BUFFER
int largestIBO = 0;
@@ -2653,6 +2672,8 @@ void Renderer::render()
#endif
uploadBatch(b);
}
+ if (Q_UNLIKELY(debug_render())) timeUploadOpaque = timer.restart();
+
if (Q_UNLIKELY(debug_upload())) qDebug() << "Uploading Alpha Batches:";
for (int i=0; i<m_alphaBatches.size(); ++i) {
@@ -2663,6 +2684,7 @@ void Renderer::render()
largestIBO = qMax(b->ibo.size, largestIBO);
#endif
}
+ if (Q_UNLIKELY(debug_render())) timeUploadAlpha = timer.restart();
if (largestVBO * 2 < m_vertexUploadPool.size())
m_vertexUploadPool.resize(largestVBO * 2);
@@ -2673,6 +2695,15 @@ void Renderer::render()
renderBatches();
+ if (Q_UNLIKELY(debug_render())) {
+ qDebug(" -> times: build: %d, prepare(opaque/alpha): %d/%d, sorting: %d, upload(opaque/alpha): %d/%d, render: %d",
+ (int) timeRenderLists,
+ (int) timePrepareOpaque, (int) timePrepareAlpha,
+ (int) timeSorting,
+ (int) timeUploadOpaque, (int) timeUploadAlpha,
+ (int) timer.elapsed());
+ }
+
m_rebuild = 0;
m_renderOrderRebuildLower = -1;
m_renderOrderRebuildUpper = -1;
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index 102985f2c7..0c4b2f9af9 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -104,8 +104,11 @@ char const *const *QSGTextMaskShader::attributeNames() const
}
QSGTextMaskShader::QSGTextMaskShader(QFontEngine::GlyphFormat glyphFormat)
- : QSGMaterialShader(*new QSGMaterialShaderPrivate),
- m_glyphFormat(glyphFormat)
+ : QSGMaterialShader(*new QSGMaterialShaderPrivate)
+ , m_matrix_id(-1)
+ , m_color_id(-1)
+ , m_textureScale_id(-1)
+ , m_glyphFormat(glyphFormat)
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/textmask.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/textmask.frag"));
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
index 422e31ad96..6f4b85a5b9 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
@@ -80,6 +80,11 @@ QSGDistanceFieldTextMaterialShader::QSGDistanceFieldTextMaterialShader()
: QSGMaterialShader(),
m_fontScale(1.0)
, m_matrixScale(1.0)
+ , m_matrix_id(-1)
+ , m_textureScale_id(-1)
+ , m_alphaMin_id(-1)
+ , m_alphaMax_id(-1)
+ , m_color_id(-1)
, m_lastAlphaMin(-1)
, m_lastAlphaMax(-1)
{
@@ -260,6 +265,7 @@ protected:
DistanceFieldStyledTextMaterialShader::DistanceFieldStyledTextMaterialShader()
: QSGDistanceFieldTextMaterialShader()
+ , m_styleColor_id(-1)
{
}
@@ -330,6 +336,8 @@ protected:
DistanceFieldOutlineTextMaterialShader::DistanceFieldOutlineTextMaterialShader()
: DistanceFieldStyledTextMaterialShader()
+ , m_outlineAlphaMax0_id(-1)
+ , m_outlineAlphaMax1_id(-1)
{
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/distancefieldoutlinetext.frag"));
}
@@ -411,6 +419,7 @@ protected:
DistanceFieldShiftedStyleTextMaterialShader::DistanceFieldShiftedStyleTextMaterialShader()
: DistanceFieldStyledTextMaterialShader()
+ , m_shift_id(-1)
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/distancefieldshiftedtext.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/distancefieldshiftedtext.frag"));
@@ -489,6 +498,8 @@ private:
QSGHiQSubPixelDistanceFieldTextMaterialShader::QSGHiQSubPixelDistanceFieldTextMaterialShader()
: QSGDistanceFieldTextMaterialShader()
+ , m_fontScale_id(-1)
+ , m_vecDelta_id(-1)
{
setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/scenegraph/shaders/hiqsubpixeldistancefieldtext.vert"));
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/scenegraph/shaders/hiqsubpixeldistancefieldtext.frag"));
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index ec9c3c39f9..6c7fb89b6f 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -101,6 +101,22 @@ void QSGRenderLoop::cleanup()
s_instance = 0;
}
+/*!
+ * Non-threaded render loops immediately run the job if there is a context.
+ */
+void QSGRenderLoop::postJob(QQuickWindow *window, QRunnable *job)
+{
+ Q_ASSERT(window);
+ Q_ASSERT(job);
+
+ if (window->openglContext()) {
+ window->openglContext()->makeCurrent(window);
+ job->run();
+ }
+
+ delete job;
+}
+
class QSGGuiThreadRenderLoop : public QSGRenderLoop
{
Q_OBJECT
diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h
index 4293015b96..3336731fda 100644
--- a/src/quick/scenegraph/qsgrenderloop_p.h
+++ b/src/quick/scenegraph/qsgrenderloop_p.h
@@ -45,6 +45,7 @@ class QQuickWindow;
class QSGContext;
class QSGRenderContext;
class QAnimationDriver;
+class QRunnable;
class Q_QUICK_PRIVATE_EXPORT QSGRenderLoop : public QObject
{
@@ -72,6 +73,7 @@ public:
virtual QSGRenderContext *createRenderContext(QSGContext *) const = 0;
virtual void releaseResources(QQuickWindow *window) = 0;
+ virtual void postJob(QQuickWindow *window, QRunnable *job);
void addWindow(QQuickWindow *win) { m_windows.insert(win); }
void removeWindow(QQuickWindow *win) { m_windows.remove(win); }
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 56637387df..074e7633da 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -147,6 +147,9 @@ const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);
// called.
const QEvent::Type WM_Grab = QEvent::Type(QEvent::User + 5);
+// Passed by the window when there is a render job to run
+const QEvent::Type WM_PostJob = QEvent::Type(QEvent::User + 6);
+
template <typename T> T *windowFor(const QList<T> &list, QQuickWindow *window)
{
for (int i=0; i<list.size(); ++i) {
@@ -200,6 +203,14 @@ public:
QImage *image;
};
+class WMJobEvent : public WMWindowEvent
+{
+public:
+ WMJobEvent(QQuickWindow *c, QRunnable *postedJob)
+ : WMWindowEvent(c, WM_PostJob), job(postedJob) {}
+ ~WMJobEvent() { delete job; }
+ QRunnable *job;
+};
class QSGRenderThreadEventQueue : public QQueue<QEvent *>
{
@@ -345,7 +356,6 @@ bool QSGRenderThread::event(QEvent *e)
if (window) {
QQuickWindowPrivate::get(window)->fireAboutToStop();
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window removed";
- gl->doneCurrent();
window = 0;
}
waitCondition.wakeOne();
@@ -396,20 +406,21 @@ bool QSGRenderThread::event(QEvent *e)
case WM_Grab: {
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_Grab";
WMGrabEvent *ce = static_cast<WMGrabEvent *>(e);
- Q_ASSERT(ce->window == window);
+ Q_ASSERT(ce->window);
+ Q_ASSERT(ce->window == window || !window);
mutex.lock();
- if (window) {
- gl->makeCurrent(window);
+ if (ce->window) {
+ gl->makeCurrent(ce->window);
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync scene graph";
- QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
+ QQuickWindowPrivate *d = QQuickWindowPrivate::get(ce->window);
d->syncSceneGraph();
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering scene graph";
- QQuickWindowPrivate::get(window)->renderSceneGraph(windowSize);
+ QQuickWindowPrivate::get(ce->window)->renderSceneGraph(ce->window->size());
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- grabbing result";
- *ce->image = qt_gl_read_framebuffer(windowSize * window->effectiveDevicePixelRatio(), false, false);
+ *ce->image = qt_gl_read_framebuffer(windowSize * ce->window->effectiveDevicePixelRatio(), false, false);
}
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- waking gui to handle result";
waitCondition.wakeOne();
@@ -417,6 +428,20 @@ bool QSGRenderThread::event(QEvent *e)
return true;
}
+ case WM_PostJob: {
+ qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_PostJob";
+ WMJobEvent *ce = static_cast<WMJobEvent *>(e);
+ Q_ASSERT(ce->window == window);
+ if (window) {
+ gl->makeCurrent(window);
+ ce->job->run();
+ delete ce->job;
+ ce->job = 0;
+ qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- job done";
+ }
+ return true;
+ }
+
case WM_RequestRepaint:
qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_RequestPaint";
// When GUI posts this event, it is followed by a polishAndSync, so we mustn't
@@ -1239,6 +1264,18 @@ QImage QSGThreadedRenderLoop::grab(QQuickWindow *window)
return result;
}
+/*!
+ * Posts a new job event to the render thread.
+ * Returns true if posting succeeded.
+ */
+void QSGThreadedRenderLoop::postJob(QQuickWindow *window, QRunnable *job)
+{
+ Window *w = windowFor(m_windows, window);
+ if (w && w->thread && w->thread->window)
+ w->thread->postEvent(new WMJobEvent(window, job));
+ else
+ delete job;
+}
#include "qsgthreadedrenderloop.moc"
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
index d5ffbf10a3..67df9dcd31 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h
+++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h
@@ -71,6 +71,7 @@ public:
void releaseResources(QQuickWindow *window);
bool event(QEvent *);
+ void postJob(QQuickWindow *window, QRunnable *job);
bool interleaveIncubation() const;
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index 8b617e5e3f..016f41d436 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -126,9 +126,8 @@ void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState,
m_controller->startJob(this, m_job);
} else if (newState == Stopped) {
syncBackCurrentValues();
- if (m_internalState == State_Starting)
- m_internalState = State_Stopped;
- else if (m_controller) {
+ m_internalState = State_Stopped;
+ if (m_controller) {
m_controller->stopJob(this, m_job);
}
}
diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h
index 1cffae17db..34c106e89b 100644
--- a/src/quick/util/qquickanimatorjob_p.h
+++ b/src/quick/util/qquickanimatorjob_p.h
@@ -151,7 +151,6 @@ protected:
int m_duration;
- uint m_feedback : 1;
uint m_isTransform : 1;
uint m_isUniform : 1;
uint m_hasBeenRunning : 1;
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index a231209cd0..70fc3a0973 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -33,6 +33,9 @@
#include "qquickimageprovider.h"
+#include "qquickpixmapcache_p.h"
+#include <QtQuick/private/qsgcontext_p.h>
+
QT_BEGIN_NAMESPACE
class QQuickImageProviderPrivate
@@ -95,6 +98,23 @@ QImage QQuickTextureFactory::image() const
return QImage();
}
+/*!
+ Returns a QQuickTextureFactory holding given the image.
+
+ \since 5.6
+ */
+
+QQuickTextureFactory *QQuickTextureFactory::textureFactoryForImage(const QImage &image)
+{
+ if (image.isNull())
+ return 0;
+ QQuickTextureFactory *texture = QSGContext::createTextureFactoryFromImage(image);
+ if (texture)
+ return texture;
+ return new QQuickDefaultTextureFactory(image);
+}
+
+
/*!
\fn QSGTexture *QQuickTextureFactory::createTexture(QQuickWindow *window) const
@@ -118,6 +138,67 @@ QImage QQuickTextureFactory::image() const
/*!
+ \class QQuickImageResponse
+ \since 5.6
+ \brief The QQuickImageResponse class provides an interface for asynchronous image loading in QQuickAsyncImageProvider.
+ \inmodule QtQuick
+
+ The purpose of an image response is to provide a way for image provider jobs to be executed
+ in an asynchronous way.
+
+ Responses are deleted via \l deleteLater once the finished() signal has been emitted.
+ If you are using QRunnable as base for your QQuickImageResponse
+ ensure automatic deletion is disabled.
+
+ \sa QQuickImageProvider
+*/
+
+/*!
+ Constructs the image response
+*/
+QQuickImageResponse::QQuickImageResponse()
+{
+}
+
+/*!
+ Destructs the image response
+*/
+QQuickImageResponse::~QQuickImageResponse()
+{
+}
+
+/*!
+ Returns the error string for the job execution. An empty string means no error.
+*/
+QString QQuickImageResponse::errorString() const
+{
+ return QString();
+}
+
+/*!
+ This method is used to communicate that the response is no longer required by the engine.
+
+ It may be reimplemented to cancel a request in the provider side, however, it is not mandatory.
+*/
+void QQuickImageResponse::cancel()
+{
+}
+
+/*!
+ \fn void QQuickImageResponse::finished()
+
+ Signals that the job execution has finished (be it successfully, because an error happened or because it was cancelled).
+ */
+
+/*!
+ \fn QQuickTextureFactory *QQuickImageResponse::textureFactory() const
+
+ Returns the texture factory the job. You can use QQuickTextureFactory::textureFactoryForImage
+ if your provider works with QImage
+ */
+
+
+/*!
\class QQuickImageProvider
\since 5.0
\inmodule QtQuick
@@ -213,7 +294,7 @@ QImage QQuickTextureFactory::image() const
To force asynchronous image loading, even for image sources that do not
have the \c asynchronous property set to \c true, you may pass the
- \c QQuickImageProvider::ForceAsynchronousImageLoading flag to the image
+ \c QQmlImageProviderBase::ForceAsynchronousImageLoading flag to the image
provider constructor. This ensures that all image requests for the
provider are handled in a separate thread.
@@ -223,6 +304,12 @@ QImage QQuickTextureFactory::image() const
if \l {Image::}{asynchronous} is set to \c true, the value is ignored
and the image is loaded synchronously.
+ Asynchronous image loading for providers of type other than ImageResponse are
+ executed on a single thread per engine basis. That means that a slow image provider
+ will block the loading of any other request. To avoid that we suggest using QQuickAsyncImageProvider
+ and implement threading on the provider side via a \c QThreadPool or similar.
+ See the \l {imageresponseprovider}{Image Response Provider Example} for a complete implementation.
+
\section2 Image caching
@@ -365,5 +452,41 @@ QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSi
return 0;
}
+/*!
+ \class QQuickAsyncImageProvider
+ \since 5.6
+ \inmodule QtQuick
+ \brief The QQuickAsyncImageProvider class provides an interface for for asynchronous control of QML image requests.
+
+ \sa QQuickImageProvider
+*/
+QQuickAsyncImageProvider::QQuickAsyncImageProvider()
+ : QQuickImageProvider(ImageResponse, ForceAsynchronousImageLoading)
+ , d(0) // just as a placeholder in case we need it for the future
+{
+ Q_UNUSED(d);
+}
+
+QQuickAsyncImageProvider::~QQuickAsyncImageProvider()
+{
+}
+
+/*!
+ \fn QQuickImageResponse *QQuickAsyncImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize)
+
+ Implement this method to return the job that will provide the texture with \a id.
+
+ The \a id is the requested image source, with the "image:" scheme and
+ provider identifier removed. For example, if the image \l{Image::}{source}
+ was "image://myprovider/icons/home", the given \a id would be "icons/home".
+
+ The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
+ an Image item. If \a requestedSize is a valid size, the image
+ returned should be of that size.
+
+ \note this method may be called by multiple threads, so ensure the
+ implementation of this method is reentrant.
+*/
+
QT_END_NAMESPACE
diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h
index a2b510f606..cc03eb0fa0 100644
--- a/src/quick/util/qquickimageprovider.h
+++ b/src/quick/util/qquickimageprovider.h
@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
class QQuickImageProviderPrivate;
+class QQuickAsyncImageProviderPrivate;
class QSGTexture;
class QQuickWindow;
@@ -56,6 +57,25 @@ public:
virtual QSize textureSize() const = 0;
virtual int textureByteCount() const = 0;
virtual QImage image() const;
+
+ static QQuickTextureFactory *textureFactoryForImage(const QImage &image);
+};
+
+class Q_QUICK_EXPORT QQuickImageResponse : public QObject
+{
+Q_OBJECT
+public:
+ QQuickImageResponse();
+ virtual ~QQuickImageResponse();
+
+ virtual QQuickTextureFactory *textureFactory() const = 0;
+ virtual QString errorString() const;
+
+public Q_SLOTS:
+ virtual void cancel();
+
+Q_SIGNALS:
+ void finished();
};
class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase
@@ -81,6 +101,18 @@ private:
QQuickImageProviderPrivate *d;
};
+class Q_QUICK_EXPORT QQuickAsyncImageProvider : public QQuickImageProvider
+{
+public:
+ QQuickAsyncImageProvider();
+ virtual ~QQuickAsyncImageProvider();
+
+ virtual QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) = 0;
+
+private:
+ QQuickAsyncImageProviderPrivate *d;
+};
+
QT_END_NAMESPACE
#endif // QQUICKIMAGEPROVIDER_H
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index ddf2ae2393..f36d06d00d 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -44,7 +44,6 @@
#include <qpa/qplatformintegration.h>
#include <QtQuick/private/qsgtexture_p.h>
-#include <QtQuick/private/qsgcontext_p.h>
#include <QQuickWindow>
#include <QCoreApplication>
@@ -67,7 +66,7 @@
#include <private/qquickprofiler_p.h>
-#define IMAGEREQUEST_MAX_REQUEST_COUNT 8
+#define IMAGEREQUEST_MAX_NETWORK_REQUEST_COUNT 8
#define IMAGEREQUEST_MAX_REDIRECT_RECURSION 16
#define CACHE_EXPIRE_TIME 30
#define CACHE_REMOVAL_FRACTION 4
@@ -115,16 +114,6 @@ QSGTexture *QQuickDefaultTextureFactory::createTexture(QQuickWindow *window) con
return t;
}
-static QQuickTextureFactory *textureFactoryForImage(const QImage &image)
-{
- if (image.isNull())
- return 0;
- QQuickTextureFactory *texture = QSGContext::createTextureFactoryFromImage(image);
- if (texture)
- return texture;
- return new QQuickDefaultTextureFactory(image);
-}
-
class QQuickPixmapReader;
class QQuickPixmapData;
class QQuickPixmapReply : public QObject
@@ -181,6 +170,7 @@ public:
virtual bool event(QEvent *e);
private slots:
void networkRequestDone();
+ void asyncResponseFinished();
private:
QQuickPixmapReader *reader;
};
@@ -205,8 +195,9 @@ protected:
private:
friend class QQuickPixmapReaderThreadObject;
void processJobs();
- void processJob(QQuickPixmapReply *, const QUrl &, const QSize &, AutoTransform);
+ void processJob(QQuickPixmapReply *, const QUrl &, const QString &, AutoTransform, QQuickImageProvider::ImageType, QQuickImageProvider *);
void networkRequestDone(QNetworkReply *);
+ void asyncResponseFinished(QQuickImageResponse *);
QList<QQuickPixmapReply*> jobs;
QList<QQuickPixmapReply*> cancelled;
@@ -220,7 +211,8 @@ private:
QNetworkAccessManager *networkAccessManager();
QNetworkAccessManager *accessManager;
- QHash<QNetworkReply*,QQuickPixmapReply*> replies;
+ QHash<QNetworkReply*,QQuickPixmapReply*> networkJobs;
+ QHash<QQuickImageResponse*,QQuickPixmapReply*> asyncResponses;
static int replyDownloadProgress;
static int replyFinished;
@@ -439,8 +431,8 @@ QQuickPixmapReader::~QQuickPixmapReader()
delete reply;
}
jobs.clear();
- QList<QQuickPixmapReply*> activeJobs = replies.values();
- foreach (QQuickPixmapReply *reply, activeJobs) {
+ QList<QQuickPixmapReply*> activeJobs = networkJobs.values() + asyncResponses.values();
+ foreach (QQuickPixmapReply *reply, activeJobs ) {
if (reply->loading) {
cancelled.append(reply);
reply->data = 0;
@@ -455,7 +447,7 @@ QQuickPixmapReader::~QQuickPixmapReader()
void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
{
- QQuickPixmapReply *job = replies.take(reply);
+ QQuickPixmapReply *job = networkJobs.take(reply);
if (job) {
job->redirectCount++;
@@ -472,7 +464,7 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
QMetaObject::connect(reply, replyDownloadProgress, job, downloadProgress);
QMetaObject::connect(reply, replyFinished, threadObject, threadNetworkRequestDone);
- replies.insert(reply, job);
+ networkJobs.insert(reply, job);
return;
}
}
@@ -494,7 +486,7 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
// send completion event to the QQuickPixmapReply
mutex.lock();
if (!cancelled.contains(job))
- job->postReply(error, errorString, readSize, textureFactoryForImage(image));
+ job->postReply(error, errorString, readSize, QQuickTextureFactory::textureFactoryForImage(image));
mutex.unlock();
}
reply->deleteLater();
@@ -503,6 +495,32 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply)
threadObject->processJobs();
}
+void QQuickPixmapReader::asyncResponseFinished(QQuickImageResponse *response)
+{
+ QQuickPixmapReply *job = asyncResponses.take(response);
+
+ if (job) {
+ QQuickTextureFactory *t = 0;
+ QQuickPixmapReply::ReadError error = QQuickPixmapReply::NoError;
+ QString errorString;
+ QSize readSize;
+ if (!response->errorString().isEmpty()) {
+ error = QQuickPixmapReply::Loading;
+ errorString = response->errorString();
+ } else {
+ t = response->textureFactory();
+ }
+ mutex.lock();
+ if (!cancelled.contains(job))
+ job->postReply(error, errorString, t->textureSize(), t);
+ mutex.unlock();
+ }
+ response->deleteLater();
+
+ // kick off event loop again incase we have dropped below max request count
+ threadObject->processJobs();
+}
+
QQuickPixmapReaderThreadObject::QQuickPixmapReaderThreadObject(QQuickPixmapReader *i)
: reader(i)
{
@@ -529,6 +547,12 @@ void QQuickPixmapReaderThreadObject::networkRequestDone()
reader->networkRequestDone(reply);
}
+void QQuickPixmapReaderThreadObject::asyncResponseFinished()
+{
+ QQuickImageResponse *response = static_cast<QQuickImageResponse *>(sender());
+ reader->asyncResponseFinished(response);
+}
+
void QQuickPixmapReader::processJobs()
{
QMutexLocker locker(&mutex);
@@ -538,16 +562,22 @@ void QQuickPixmapReader::processJobs()
return; // Nothing else to do
// Clean cancelled jobs
- if (cancelled.count()) {
+ if (!cancelled.isEmpty()) {
for (int i = 0; i < cancelled.count(); ++i) {
QQuickPixmapReply *job = cancelled.at(i);
- QNetworkReply *reply = replies.key(job, 0);
+ QNetworkReply *reply = networkJobs.key(job, 0);
if (reply) {
- replies.remove(reply);
+ networkJobs.remove(reply);
if (reply->isRunning()) {
// cancel any jobs already started
reply->close();
}
+ } else {
+ QQuickImageResponse *asyncResponse = asyncResponses.key(job);
+ if (asyncResponse) {
+ asyncResponses.remove(asyncResponse);
+ asyncResponse->cancel();
+ }
}
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(job->url));
// deleteLater, since not owned by this thread
@@ -560,27 +590,34 @@ void QQuickPixmapReader::processJobs()
// Find a job we can use
bool usableJob = false;
for (int i = jobs.count() - 1; !usableJob && i >= 0; i--) {
- QQuickPixmapReply *runningJob = jobs[i];
- const QUrl url = runningJob->url;
+ QQuickPixmapReply *job = jobs[i];
+ const QUrl url = job->url;
+ QString localFile;
+ QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid;
+ QQuickImageProvider *provider = 0;
if (url.scheme() == QLatin1String("image")) {
+ provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url)));
+ if (provider)
+ imageType = provider->imageType();
+
usableJob = true;
} else {
- const QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
- usableJob = !localFile.isEmpty() || replies.count() < IMAGEREQUEST_MAX_REQUEST_COUNT;
+ localFile = QQmlFile::urlToLocalFileOrQrc(url);
+ usableJob = !localFile.isEmpty() || networkJobs.count() < IMAGEREQUEST_MAX_NETWORK_REQUEST_COUNT;
}
+
if (usableJob) {
jobs.removeAt(i);
- runningJob->loading = true;
+ job->loading = true;
PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url));
- QSize requestSize = runningJob->requestSize;
- AutoTransform autoTransform = runningJob->autoTransform;
+ AutoTransform autoTransform = job->autoTransform;
locker.unlock();
- processJob(runningJob, url, requestSize, autoTransform);
+ processJob(job, url, localFile, autoTransform, imageType, provider);
locker.relock();
}
}
@@ -591,79 +628,97 @@ void QQuickPixmapReader::processJobs()
}
}
-void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url,
- const QSize &requestSize, AutoTransform autoTransform)
+void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url, const QString &localFile,
+ AutoTransform autoTransform, QQuickImageProvider::ImageType imageType, QQuickImageProvider *provider)
{
// fetch
if (url.scheme() == QLatin1String("image")) {
// Use QQuickImageProvider
QSize readSize;
- QQuickImageProvider::ImageType imageType = QQuickImageProvider::Invalid;
- QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url)));
- if (provider)
- imageType = provider->imageType();
+ switch (imageType) {
+ case QQuickImageProvider::Invalid:
+ {
+ QString errorStr = QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString());
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(QQuickPixmapReply::Loading, errorStr, readSize, 0);
+ mutex.unlock();
+ break;
+ }
- if (imageType == QQuickImageProvider::Invalid) {
- QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::Loading;
- QString errorStr = QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString());
- QImage image;
- mutex.lock();
- if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image));
- mutex.unlock();
- } else if (imageType == QQuickImageProvider::Image) {
- QImage image = provider->requestImage(imageId(url), &readSize, requestSize);
- QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
- QString errorStr;
- if (image.isNull()) {
- errorCode = QQuickPixmapReply::Loading;
- errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+ case QQuickImageProvider::Image:
+ {
+ QImage image = provider->requestImage(imageId(url), &readSize, runningJob->requestSize);
+ QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
+ QString errorStr;
+ if (image.isNull()) {
+ errorCode = QQuickPixmapReply::Loading;
+ errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, QQuickTextureFactory::textureFactoryForImage(image));
+ mutex.unlock();
+ break;
}
- mutex.lock();
- if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image));
- mutex.unlock();
- } else if (imageType == QQuickImageProvider::Pixmap) {
- const QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize);
- QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
- QString errorStr;
- if (pixmap.isNull()) {
- errorCode = QQuickPixmapReply::Loading;
- errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+
+ case QQuickImageProvider::Pixmap:
+ {
+ const QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, runningJob->requestSize);
+ QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
+ QString errorStr;
+ if (pixmap.isNull()) {
+ errorCode = QQuickPixmapReply::Loading;
+ errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()));
+ mutex.unlock();
+ break;
}
- mutex.lock();
- if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(pixmap.toImage()));
- mutex.unlock();
- } else {
- QQuickTextureFactory *t = provider->requestTexture(imageId(url), &readSize, requestSize);
- QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
- QString errorStr;
- if (!t) {
- errorCode = QQuickPixmapReply::Loading;
- errorStr = QQuickPixmap::tr("Failed to get texture from provider: %1").arg(url.toString());
+
+ case QQuickImageProvider::Texture:
+ {
+ QQuickTextureFactory *t = provider->requestTexture(imageId(url), &readSize, runningJob->requestSize);
+ QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
+ QString errorStr;
+ if (!t) {
+ errorCode = QQuickPixmapReply::Loading;
+ errorStr = QQuickPixmap::tr("Failed to get texture from provider: %1").arg(url.toString());
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, t);
+ else
+ delete t;
+ mutex.unlock();
+ break;
}
- mutex.lock();
- if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, t);
- else
- delete t;
- mutex.unlock();
+ case QQuickImageProvider::ImageResponse:
+ {
+ QQuickAsyncImageProvider *asyncProvider = static_cast<QQuickAsyncImageProvider*>(provider);
+ QQuickImageResponse *response = asyncProvider->requestImageResponse(imageId(url), runningJob->requestSize);
+
+ QObject::connect(response, SIGNAL(finished()), threadObject, SLOT(asyncResponseFinished()));
+
+ asyncResponses.insert(response, runningJob);
+ break;
+ }
}
} else {
- QString lf = QQmlFile::urlToLocalFileOrQrc(url);
- if (!lf.isEmpty()) {
+ if (!localFile.isEmpty()) {
// Image is local - load/decode immediately
QImage image;
QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
QString errorStr;
- QFile f(lf);
+ QFile f(localFile);
QSize readSize;
if (f.open(QIODevice::ReadOnly)) {
- if (!readImage(url, &f, &image, &errorStr, &readSize, requestSize, autoTransform))
+ if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, autoTransform))
errorCode = QQuickPixmapReply::Loading;
} else {
errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
@@ -671,7 +726,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
}
mutex.lock();
if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image));
+ runningJob->postReply(errorCode, errorStr, readSize, QQuickTextureFactory::textureFactoryForImage(image));
mutex.unlock();
} else {
// Network resource
@@ -682,7 +737,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
QMetaObject::connect(reply, replyDownloadProgress, runningJob, downloadProgress);
QMetaObject::connect(reply, replyFinished, threadObject, threadNetworkRequestDone);
- replies.insert(reply, runningJob);
+ networkJobs.insert(reply, runningJob);
}
}
}
@@ -775,8 +830,6 @@ inline uint qHash(const QQuickPixmapKey &key)
return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.autoTransform * 0x5c5c5c5c);
}
-class QSGContext;
-
class QQuickPixmapStore : public QObject
{
Q_OBJECT
@@ -1084,7 +1137,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QImage image = provider->requestImage(imageId(url), &readSize, requestSize);
if (!image.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(image), readSize, requestSize, autoTransform, UsePluginDefault);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, UsePluginDefault);
}
}
case QQuickImageProvider::Pixmap:
@@ -1092,9 +1145,14 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize);
if (!pixmap.isNull()) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(pixmap.toImage()), readSize, requestSize, autoTransform, UsePluginDefault);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, autoTransform, UsePluginDefault);
}
}
+ case QQuickImageProvider::ImageResponse:
+ {
+ // Fall through, ImageResponse providers never get here
+ Q_ASSERT(imageType != QQuickImageProvider::ImageResponse && "Sync call to ImageResponse provider");
+ }
}
// provider has bad image type, or provider returned null image
@@ -1115,7 +1173,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
AutoTransform appliedTransform = autoTransform;
if (readImage(url, &f, &image, &errorString, &readSize, requestSize, appliedTransform)) {
*ok = true;
- return new QQuickPixmapData(declarativePixmap, url, textureFactoryForImage(image), readSize, requestSize, autoTransform, appliedTransform);
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, appliedTransform);
}
errorString = QQuickPixmap::tr("Invalid image data: %1").arg(url.toString());
@@ -1252,7 +1310,7 @@ void QQuickPixmap::setImage(const QImage &p)
clear();
if (!p.isNull())
- d = new QQuickPixmapData(this, textureFactoryForImage(p));
+ d = new QQuickPixmapData(this, QQuickTextureFactory::textureFactoryForImage(p));
}
void QQuickPixmap::setPixmap(const QQuickPixmap &other)
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index 6c333c6b13..707323f2e2 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -558,11 +558,7 @@ void QQuickPropertyChanges::changeValue(const QString &name, const QVariant &val
if (entry.name == name) {
expressionIterator.remove();
if (state() && state()->isStateActive()) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(d->property(name));
- if (oldBinding) {
- QQmlPropertyPrivate::setBinding(d->property(name), 0);
- oldBinding->destroy();
- }
+ QQmlPropertyPrivate::removeBinding(d->property(name), QQmlPropertyPrivate::DestroyOldBinding);
d->property(name).write(value);
}
@@ -624,15 +620,9 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString
if (entry.name == name) {
entry.expression = expression;
if (state() && state()->isStateActive()) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(d->property(name));
- if (oldBinding) {
- QQmlPropertyPrivate::setBinding(d->property(name), 0);
- oldBinding->destroy();
- }
-
QQmlBinding *newBinding = new QQmlBinding(expression, object(), qmlContext(this));
newBinding->setTarget(d->property(name));
- QQmlPropertyPrivate::setBinding(d->property(name), newBinding, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
+ QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
}
return;
}
@@ -651,7 +641,7 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString
QQmlBinding *newBinding = new QQmlBinding(expression, object(), qmlContext(this));
newBinding->setTarget(d->property(name));
- QQmlPropertyPrivate::setBinding(d->property(name), newBinding, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
+ QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
} else {
QQuickStateAction action;
action.restore = restoreEntryValues();
@@ -668,7 +658,7 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString
action.toValue = newBinding->evaluate();
newBinding->destroy();
} else {
- newBinding->setTarget(d->property(name));
+ newBinding->setTarget(action.property);
action.toBinding = QQmlAbstractBinding::getPointer(newBinding);
action.deletableToBinding = true;
@@ -677,7 +667,7 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString
if (oldBinding)
oldBinding->setEnabled(false, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
- QQmlPropertyPrivate::setBinding(action.property, newBinding, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
+ QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor);
}
}
}
diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp
index 98d7a76c7e..483167f52d 100644
--- a/src/quick/util/qquickstate.cpp
+++ b/src/quick/util/qquickstate.cpp
@@ -361,7 +361,7 @@ void QQuickState::cancel()
void QQuickStateAction::deleteFromBinding()
{
if (fromBinding) {
- QQmlPropertyPrivate::setBinding(property, 0);
+ QQmlPropertyPrivate::removeBinding(property);
fromBinding->destroy();
fromBinding = 0;
}
@@ -435,15 +435,11 @@ bool QQuickState::removeEntryFromRevertList(QObject *target, const QString &name
while (revertListIterator.hasNext()) {
QQuickSimpleAction &simpleAction = revertListIterator.next();
if (simpleAction.property().object() == target && simpleAction.property().name() == name) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(simpleAction.property());
- if (oldBinding) {
- QQmlPropertyPrivate::setBinding(simpleAction.property(), 0);
- oldBinding->destroy();
- }
+ QQmlPropertyPrivate::removeBinding(simpleAction.property(), QQmlPropertyPrivate::DestroyOldBinding);
simpleAction.property().write(simpleAction.value());
if (simpleAction.binding())
- QQmlPropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding());
+ QQmlPropertyPrivate::setBinding(simpleAction.binding());
revertListIterator.remove();
return true;
@@ -473,15 +469,11 @@ void QQuickState::removeAllEntriesFromRevertList(QObject *target)
while (revertListIterator.hasNext()) {
QQuickSimpleAction &simpleAction = revertListIterator.next();
if (simpleAction.property().object() == target) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(simpleAction.property());
- if (oldBinding) {
- QQmlPropertyPrivate::setBinding(simpleAction.property(), 0);
- oldBinding->destroy();
- }
+ QQmlPropertyPrivate::removeBinding(simpleAction.property(), QQmlPropertyPrivate::DestroyOldBinding);
simpleAction.property().write(simpleAction.value());
if (simpleAction.binding())
- QQmlPropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding());
+ QQmlPropertyPrivate::setBinding(simpleAction.binding());
revertListIterator.remove();
}
@@ -500,12 +492,8 @@ void QQuickState::addEntriesToRevertList(const QList<QQuickStateAction> &actionL
const QQuickStateAction &action = actionListIterator.next();
QQuickSimpleAction simpleAction(action);
action.property.write(action.toValue);
- if (!action.toBinding.isNull()) {
- QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(simpleAction.property());
- if (oldBinding)
- QQmlPropertyPrivate::setBinding(simpleAction.property(), 0);
- QQmlPropertyPrivate::setBinding(simpleAction.property(), action.toBinding.data(), QQmlPropertyPrivate::DontRemoveBinding);
- }
+ if (!action.toBinding.isNull())
+ QQmlPropertyPrivate::setBinding(action.toBinding.data());
simpleActionList.append(simpleAction);
}
@@ -663,10 +651,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
}
if (!found) {
QVariant cur = d->revertList.at(ii).property().read();
- QQmlAbstractBinding *delBinding =
- QQmlPropertyPrivate::setBinding(d->revertList.at(ii).property(), 0);
- if (delBinding)
- delBinding->destroy();
+ QQmlPropertyPrivate::removeBinding(d->revertList.at(ii).property(), QQmlPropertyPrivate::DestroyOldBinding);
QQuickStateAction a;
a.property = d->revertList.at(ii).property();
diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp
index 74754a0bfb..88fc03bba8 100644
--- a/src/quick/util/qquicktimeline.cpp
+++ b/src/quick/util/qquicktimeline.cpp
@@ -659,7 +659,7 @@ void QQuickTimeLine::complete()
*/
void QQuickTimeLine::clear()
{
- for (QQuickTimeLinePrivate::Ops::const_iterator iter = d->ops.begin(), cend = d->ops.end(); iter != cend; ++iter)
+ for (QQuickTimeLinePrivate::Ops::const_iterator iter = d->ops.cbegin(), cend = d->ops.cend(); iter != cend; ++iter)
iter.key()->_t = 0;
d->ops.clear();
d->length = 0;
diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp
index 832596d9a2..ac57ac20a4 100644
--- a/src/quick/util/qquicktransitionmanager.cpp
+++ b/src/quick/util/qquicktransitionmanager.cpp
@@ -102,7 +102,7 @@ void QQuickTransitionManagerPrivate::applyBindings()
{
foreach(const QQuickStateAction &action, bindingsList) {
if (!action.toBinding.isNull()) {
- QQmlPropertyPrivate::setBinding(action.property, action.toBinding.data());
+ QQmlPropertyPrivate::setBinding(action.toBinding.data());
} else if (action.event) {
if (action.reverseEvent)
action.event->reverse();
@@ -131,7 +131,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
if (action.toBinding)
d->bindingsList << action;
if (action.fromBinding)
- QQmlPropertyPrivate::setBinding(action.property, 0); // Disable current binding
+ QQmlPropertyPrivate::removeBinding(action.property); // Disable current binding
if (action.event && action.event->changesBindings()) { //### assume isReversable()?
d->bindingsList << action;
action.event->clearBindings();
@@ -156,7 +156,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
for (int ii = 0; ii < applyList.size(); ++ii) {
const QQuickStateAction &action = applyList.at(ii);
if (!action.toBinding.isNull()) {
- QQmlPropertyPrivate::setBinding(action.property, action.toBinding.data(), QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
+ QQmlPropertyPrivate::setBinding(action.toBinding.data(), QQmlPropertyPrivate::None, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
} else if (!action.event) {
QQmlPropertyPrivate::write(action.property, action.toValue, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
} else if (action.event->isReversable()) {
@@ -192,7 +192,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list,
}
if (action.toBinding)
- QQmlPropertyPrivate::setBinding(action.property, 0); // Make sure this is disabled during the transition
+ QQmlPropertyPrivate::removeBinding(action.property); // Make sure this is disabled during the transition
QQmlPropertyPrivate::write(action.property, action.fromValue, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
}
@@ -270,7 +270,7 @@ void QQuickTransitionManager::cancel()
for(int i = 0; i < d->bindingsList.count(); ++i) {
QQuickStateAction action = d->bindingsList[i];
if (!action.toBinding.isNull() && action.deletableToBinding) {
- QQmlPropertyPrivate::setBinding(action.property, 0);
+ QQmlPropertyPrivate::removeBinding(action.property);
action.toBinding.data()->destroy();
action.toBinding.clear();
action.deletableToBinding = false;
diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp
index 4d156a2d9a..4f6e49fa7a 100644
--- a/src/quick/util/qquickutilmodule.cpp
+++ b/src/quick/util/qquickutilmodule.cpp
@@ -49,6 +49,7 @@
#include "qquicktransition_p.h"
#include "qquickanimator_p.h"
#include "qquickshortcut_p.h"
+#include "qquickvalidator_p.h"
#include <qqmlinfo.h>
#include <private/qqmltypenotavailable_p.h>
#include <private/qquickanimationcontroller_p.h>
@@ -87,6 +88,13 @@ void QQuickUtilModule::defineModule()
qmlRegisterType<QQuickTransition>("QtQuick",2,0,"Transition");
qmlRegisterType<QQuickVector3dAnimation>("QtQuick",2,0,"Vector3dAnimation");
+#ifndef QT_NO_VALIDATOR
+ qmlRegisterType<QValidator>();
+ qmlRegisterType<QQuickIntValidator>("QtQuick",2,0,"IntValidator");
+ qmlRegisterType<QQuickDoubleValidator>("QtQuick",2,0,"DoubleValidator");
+ qmlRegisterType<QRegExpValidator>("QtQuick",2,0,"RegExpValidator");
+#endif
+
qmlRegisterUncreatableType<QQuickAnimator>("QtQuick", 2, 2, "Animator", QQuickAbstractAnimation::tr("Animator is an abstract class"));
qmlRegisterType<QQuickXAnimator>("QtQuick", 2, 2, "XAnimator");
qmlRegisterType<QQuickYAnimator>("QtQuick", 2, 2, "YAnimator");
diff --git a/src/quick/util/qquickvalidator.cpp b/src/quick/util/qquickvalidator.cpp
new file mode 100644
index 0000000000..3eebf5d77a
--- /dev/null
+++ b/src/quick/util/qquickvalidator.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickvalidator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_VALIDATOR
+
+/*!
+ \qmltype IntValidator
+ \instantiates QIntValidator
+ \inqmlmodule QtQuick
+ \ingroup qtquick-text-utility
+ \brief Defines a validator for integer values
+
+ The IntValidator type provides a validator for integer values.
+
+ If no \l locale is set IntValidator uses the \l {QLocale::setDefault()}{default locale} to
+ interpret the number and will accept locale specific digits, group separators, and positive
+ and negative signs. In addition, IntValidator is always guaranteed to accept a number
+ formatted according to the "C" locale.
+*/
+
+QQuickIntValidator::QQuickIntValidator(QObject *parent)
+ : QIntValidator(parent)
+{
+}
+
+/*!
+ \qmlproperty string QtQuick::IntValidator::locale
+
+ This property holds the name of the locale used to interpret the number.
+
+ \sa {QtQml::Qt::locale()}{Qt.locale()}
+*/
+
+QString QQuickIntValidator::localeName() const
+{
+ return locale().name();
+}
+
+void QQuickIntValidator::setLocaleName(const QString &name)
+{
+ if (locale().name() != name) {
+ setLocale(QLocale(name));
+ emit localeNameChanged();
+ }
+}
+
+void QQuickIntValidator::resetLocaleName()
+{
+ QLocale defaultLocale;
+ if (locale() != defaultLocale) {
+ setLocale(defaultLocale);
+ emit localeNameChanged();
+ }
+}
+
+/*!
+ \qmlproperty int QtQuick::IntValidator::top
+
+ This property holds the validator's highest acceptable value.
+ By default, this property's value is derived from the highest signed integer available (typically 2147483647).
+*/
+/*!
+ \qmlproperty int QtQuick::IntValidator::bottom
+
+ This property holds the validator's lowest acceptable value.
+ By default, this property's value is derived from the lowest signed integer available (typically -2147483647).
+*/
+
+/*!
+ \qmltype DoubleValidator
+ \instantiates QDoubleValidator
+ \inqmlmodule QtQuick
+ \ingroup qtquick-text-utility
+ \brief Defines a validator for non-integer numbers
+
+ The DoubleValidator type provides a validator for non-integer numbers.
+
+ Input is accepted if it contains a double that is within the valid range
+ and is in the correct format.
+
+ Input is accepected but invalid if it contains a double that is outside
+ the range or is in the wrong format; e.g. with too many digits after the
+ decimal point or is empty.
+
+ Input is rejected if it is not a double.
+
+ Note: If the valid range consists of just positive doubles (e.g. 0.0 to
+ 100.0) and input is a negative double then it is rejected. If \l notation
+ is set to DoubleValidator.StandardNotation, and the input contains more
+ digits before the decimal point than a double in the valid range may have,
+ it is also rejected. If \l notation is DoubleValidator.ScientificNotation,
+ and the input is not in the valid range, it is accecpted but invalid. The
+ value may yet become valid by changing the exponent.
+*/
+
+QQuickDoubleValidator::QQuickDoubleValidator(QObject *parent)
+ : QDoubleValidator(parent)
+{
+}
+
+/*!
+ \qmlproperty string QtQuick::DoubleValidator::locale
+
+ This property holds the name of the locale used to interpret the number.
+
+ \sa {QtQml::Qt::locale()}{Qt.locale()}
+*/
+
+QString QQuickDoubleValidator::localeName() const
+{
+ return locale().name();
+}
+
+void QQuickDoubleValidator::setLocaleName(const QString &name)
+{
+ if (locale().name() != name) {
+ setLocale(QLocale(name));
+ emit localeNameChanged();
+ }
+}
+
+void QQuickDoubleValidator::resetLocaleName()
+{
+ QLocale defaultLocale;
+ if (locale() != defaultLocale) {
+ setLocale(defaultLocale);
+ emit localeNameChanged();
+ }
+}
+
+/*!
+ \qmlproperty real QtQuick::DoubleValidator::top
+
+ This property holds the validator's maximum acceptable value.
+ By default, this property contains a value of infinity.
+*/
+/*!
+ \qmlproperty real QtQuick::DoubleValidator::bottom
+
+ This property holds the validator's minimum acceptable value.
+ By default, this property contains a value of -infinity.
+*/
+/*!
+ \qmlproperty int QtQuick::DoubleValidator::decimals
+
+ This property holds the validator's maximum number of digits after the decimal point.
+ By default, this property contains a value of 1000.
+*/
+/*!
+ \qmlproperty enumeration QtQuick::DoubleValidator::notation
+ This property holds the notation of how a string can describe a number.
+
+ The possible values for this property are:
+
+ \list
+ \li DoubleValidator.StandardNotation
+ \li DoubleValidator.ScientificNotation (default)
+ \endlist
+
+ If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part (e.g. 1.5E-2).
+*/
+
+/*!
+ \qmltype RegExpValidator
+ \instantiates QRegExpValidator
+ \inqmlmodule QtQuick
+ \ingroup qtquick-text-utility
+ \brief Provides a string validator
+
+ The RegExpValidator type provides a validator, which counts as valid any string which
+ matches a specified regular expression.
+*/
+/*!
+ \qmlproperty regExp QtQuick::RegExpValidator::regExp
+
+ This property holds the regular expression used for validation.
+
+ Note that this property should be a regular expression in JS syntax, e.g /a/ for the regular expression
+ matching "a".
+
+ By default, this property contains a regular expression with the pattern .* that matches any string.
+*/
+
+#endif // QT_NO_VALIDATOR
+
+QT_END_NAMESPACE
+
diff --git a/src/quick/util/qquickvalidator_p.h b/src/quick/util/qquickvalidator_p.h
new file mode 100644
index 0000000000..59d7884afc
--- /dev/null
+++ b/src/quick/util/qquickvalidator_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKVALIDATOR_P_H
+#define QQUICKVALIDATOR_P_H
+
+#include <QtGui/qvalidator.h>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_VALIDATOR
+class Q_AUTOTEST_EXPORT QQuickIntValidator : public QIntValidator
+{
+ Q_OBJECT
+ Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+public:
+ QQuickIntValidator(QObject *parent = 0);
+
+ QString localeName() const;
+ void setLocaleName(const QString &name);
+ void resetLocaleName();
+
+Q_SIGNALS:
+ void localeNameChanged();
+};
+
+class Q_AUTOTEST_EXPORT QQuickDoubleValidator : public QDoubleValidator
+{
+ Q_OBJECT
+ Q_PROPERTY(QString locale READ localeName WRITE setLocaleName RESET resetLocaleName NOTIFY localeNameChanged)
+public:
+ QQuickDoubleValidator(QObject *parent = 0);
+
+ QString localeName() const;
+ void setLocaleName(const QString &name);
+ void resetLocaleName();
+
+Q_SIGNALS:
+ void localeNameChanged();
+};
+#endif
+
+QT_END_NAMESPACE
+
+#ifndef QT_NO_VALIDATOR
+QML_DECLARE_TYPE(QValidator)
+QML_DECLARE_TYPE(QQuickIntValidator)
+QML_DECLARE_TYPE(QQuickDoubleValidator)
+QML_DECLARE_TYPE(QRegExpValidator)
+#endif
+
+#endif // QQUICKVALIDATOR_P_H
diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri
index 0e0df4e751..ffb31ae75e 100644
--- a/src/quick/util/util.pri
+++ b/src/quick/util/util.pri
@@ -29,7 +29,8 @@ SOURCES += \
$$PWD/qquickprofiler.cpp \
$$PWD/qquickfontmetrics.cpp \
$$PWD/qquicktextmetrics.cpp \
- $$PWD/qquickshortcut.cpp
+ $$PWD/qquickshortcut.cpp \
+ $$PWD/qquickvalidator.cpp
HEADERS += \
$$PWD/qquickapplication_p.h\
@@ -66,4 +67,5 @@ HEADERS += \
$$PWD/qquickprofiler_p.h \
$$PWD/qquickfontmetrics_p.h \
$$PWD/qquicktextmetrics_p.h \
- $$PWD/qquickshortcut_p.h
+ $$PWD/qquickshortcut_p.h \
+ $$PWD/qquickvalidator_p.h
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 608c5f93f5..1afea402fd 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -531,6 +531,9 @@ QQuickWidget::Status QQuickWidget::status() const
if (!d->component)
return QQuickWidget::Null;
+ if (d->component->status() == QQmlComponent::Ready && !d->root)
+ return QQuickWidget::Error;
+
return QQuickWidget::Status(d->component->status());
}
@@ -552,6 +555,10 @@ QList<QQmlError> QQuickWidget::errors() const
QQmlError error;
error.setDescription(QLatin1String("QQuickWidget: invalid qml engine."));
errs << error;
+ } else if (d->component->status() == QQmlComponent::Ready && !d->root) {
+ QQmlError error;
+ error.setDescription(QLatin1String("QQuickWidget: invalid root object."));
+ errs << error;
}
return errs;
@@ -871,14 +878,15 @@ void QQuickWidgetPrivate::setRootObject(QObject *obj)
if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) {
root = sgItem;
sgItem->setParentItem(offscreenWindow->contentItem());
+ } else if (qobject_cast<QWindow *>(obj)) {
+ qWarning() << "QQuickWidget does not support using windows as a root item." << endl
+ << endl
+ << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << endl;
} else {
qWarning() << "QQuickWidget only supports loading of root objects that derive from QQuickItem." << endl
<< endl
- << "If your example is using QML 2, (such as qmlscene) and the .qml file you" << endl
- << "loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur." << endl
- << endl
- << "To load files with 'import QtQuick 1.0' or 'import Qt 4.7', use the" << endl
- << "QDeclarativeView class in the Qt Quick 1 module." << endl;
+ << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << endl
+ << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << endl;
delete obj;
root = 0;
}