From e8746aeaecc4b1cfe312d8ed943ad74bd53f66e2 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 8 May 2014 14:35:30 +0200 Subject: Start implement new Object creation pattern Create objects through a static create() method that returns a pointer to the objects Data. This will later on simplify breaking the direct connection between Object and Object::Data. Change-Id: Id8daa3c766429bc36f432868e1957846147c96b6 Reviewed-by: Simon Hausmann --- src/imports/localstorage/plugin.cpp | 25 +++++++++------- src/particles/qquickv4particledata.cpp | 17 +++++------ src/qml/jsruntime/qv4managed.cpp | 15 ++++++++++ src/qml/jsruntime/qv4managed_p.h | 53 ++++++++++++++++++++-------------- src/qml/jsruntime/qv4memberdata_p.h | 10 +++++-- src/qml/jsruntime/qv4object.cpp | 10 +++++++ src/qml/jsruntime/qv4object_p.h | 6 ++++ src/qml/jsruntime/qv4scopedvalue_p.h | 16 ++++++++++ src/quick/items/qquickview.cpp | 9 +++--- src/quick/items/qquickview_p.h | 14 +++++---- src/quick/items/qquickwindowmodule.cpp | 2 +- 11 files changed, 121 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index 143c129dae..651b8d466f 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -104,6 +104,13 @@ class QQmlSqlDatabaseWrapper : public Object public: enum Type { Database, Query, Rows }; struct Data : Object::Data { + Data(ExecutionEngine *e) + : Object::Data(e) + { + setVTable(staticVTable()); + type = Database; + } + Type type; QSqlDatabase database; @@ -130,14 +137,10 @@ public: V4_OBJECT - QQmlSqlDatabaseWrapper(QV8Engine *e) - : Object(QV8Engine::getV4(e)) + static Data *create(QV8Engine *engine) { - setVTable(staticVTable()); - d()->type = Database; - d()->inTransaction = false; - d()->readonly = false; - d()->forwardOnly = false; + QV4::ExecutionEngine *e = QV8Engine::getV4(engine); + return new (e) Data(e); } ~QQmlSqlDatabaseWrapper() { @@ -325,7 +328,7 @@ static ReturnedValue qmlsqldatabase_executeSql(CallContext *ctx) } } if (query.exec()) { - QV4::Scoped rows(scope, new (scope.engine->memoryManager) QQmlSqlDatabaseWrapper(engine)); + QV4::Scoped rows(scope, QQmlSqlDatabaseWrapper::create(engine)); QV4::ScopedObject p(scope, databaseData(engine)->rowsProto.value()); rows->setPrototype(p.getPointer()); rows->d()->type = QQmlSqlDatabaseWrapper::Rows; @@ -402,7 +405,7 @@ static ReturnedValue qmlsqldatabase_changeVersion(CallContext *ctx) if (from_version != r->d()->version) V4THROW_SQL(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(r->d()->version)); - Scoped w(scope, new (scope.engine->memoryManager) QQmlSqlDatabaseWrapper(engine)); + Scoped w(scope, QQmlSqlDatabaseWrapper::create(engine)); ScopedObject p(scope, databaseData(engine)->queryProto.value()); w->setPrototype(p.getPointer()); w->d()->type = QQmlSqlDatabaseWrapper::Query; @@ -455,7 +458,7 @@ static ReturnedValue qmlsqldatabase_transaction_shared(CallContext *ctx, bool re QSqlDatabase db = r->d()->database; - Scoped w(scope, new (scope.engine->memoryManager) QQmlSqlDatabaseWrapper(engine)); + Scoped w(scope, QQmlSqlDatabaseWrapper::create(engine)); QV4::ScopedObject p(scope, databaseData(engine)->queryProto.value()); w->setPrototype(p.getPointer()); w->d()->type = QQmlSqlDatabaseWrapper::Query; @@ -733,7 +736,7 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args) database.open(); } - QV4::Scoped db(scope, new (scope.engine->memoryManager) QQmlSqlDatabaseWrapper(engine)); + QV4::Scoped db(scope, QQmlSqlDatabaseWrapper::create(engine)); QV4::ScopedObject p(scope, databaseData(engine)->databaseProto.value()); db->setPrototype(p.getPointer()); db->d()->database = database; diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp index 58e37ab64d..cfe99afafc 100644 --- a/src/particles/qquickv4particledata.cpp +++ b/src/particles/qquickv4particledata.cpp @@ -274,6 +274,12 @@ QT_BEGIN_NAMESPACE struct QV4ParticleData : public QV4::Object { struct Data : QV4::Object::Data { + Data(QV4::ExecutionEngine *engine, QQuickParticleData *datum) + : Object::Data(engine) + , datum(datum) + { + setVTable(QV4ParticleData::staticVTable()); + } QQuickParticleData* datum;//TODO: Guard needed? }; struct { @@ -281,15 +287,6 @@ struct QV4ParticleData : public QV4::Object } __data; V4_OBJECT - QV4ParticleData(QV4::ExecutionEngine *engine, QQuickParticleData *datum) - : Object(engine) - { - setVTable(staticVTable()); - d()->datum = datum; - } - - static void destroy(Managed *that) - { that->as()->~QV4ParticleData(); } }; DEFINE_OBJECT_VTABLE(QV4ParticleData); @@ -523,7 +520,7 @@ QQuickV4ParticleData::QQuickV4ParticleData(QV8Engine* engine, QQuickParticleData QV8ParticleDataDeletable *d = particleV8Data(engine); QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope scope(v4); - QV4::ScopedObject o(scope, new (v4->memoryManager) QV4ParticleData(v4, datum)); + QV4::ScopedObject o(scope, new (v4) QV4ParticleData::Data(v4, datum)); QV4::ScopedObject p(scope, d->proto.value()); o->setPrototype(p.getPointer()); m_v4Value = o; diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index 3b0bdd08e2..5613e65446 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -164,7 +164,22 @@ void Managed::setVTable(const ManagedVTable *vt) d()->internalClass = internalClass()->changeVTable(vt); } +void Managed::Data::setVTable(const ManagedVTable *vt) +{ + Q_ASSERT(internalClass); + internalClass = internalClass->changeVTable(vt); +} + + bool Managed::isEqualTo(Managed *, Managed *) { return false; } + + +void *Managed::Data::operator new(size_t size, ExecutionEngine *e) +{ + assert(e); + + return e->memoryManager->allocManaged(size); +} diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index c70b717b0f..729e835bb3 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -176,26 +176,41 @@ const QV4::ObjectVTable classname::static_vtbl = \ advanceIterator \ } +struct HeapObject { + +}; + struct Q_QML_PRIVATE_EXPORT Managed { - struct Data { + struct Data : HeapObject { + Data() {} + Data(InternalClass *internal) + : internalClass(internal) + , inUse(1) + , extensible(1) + { + // #### +// Q_ASSERT(internal && internal->vtable); + } InternalClass *internalClass; - union { - uint _data; - struct { - uchar markBit : 1; - uchar inUse : 1; - uchar extensible : 1; // used by Object - uchar _unused : 1; - uchar needsActivation : 1; // used by FunctionObject - uchar strictMode : 1; // used by FunctionObject - uchar bindingKeyFlag : 1; - uchar hasAccessorProperty : 1; - uchar _type; - mutable uchar subtype; - uchar _flags; - }; + struct { + uchar markBit : 1; + uchar inUse : 1; + uchar extensible : 1; // used by Object + uchar _unused : 1; + uchar needsActivation : 1; // used by FunctionObject + uchar strictMode : 1; // used by FunctionObject + uchar bindingKeyFlag : 1; + uchar hasAccessorProperty : 1; + uchar _type; + mutable uchar subtype; + uchar _flags; }; + + void setVTable(const ManagedVTable *vt); + + void *operator new(size_t size, ExecutionEngine *e); + void *operator new(size_t, Managed *m) { return m; } }; Data data; V4_MANAGED @@ -214,12 +229,8 @@ private: protected: Managed(InternalClass *internal) + : data(internal) { - Q_ASSERT(internal && internal->vtable); - d()->internalClass = internal; - d()->_data = 0; - d()->inUse = 1; - d()->extensible = 1; } public: diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h index 41e026077d..f5f2305745 100644 --- a/src/qml/jsruntime/qv4memberdata_p.h +++ b/src/qml/jsruntime/qv4memberdata_p.h @@ -51,11 +51,17 @@ namespace QV4 { struct MemberData : Managed { struct Data : Managed::Data { - uint size; + union { + uint size; + double _dummy; + }; Value data[1]; }; struct { - uint size; + union { + uint size; + double _dummy; + }; Value data[1]; } __data; diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index a9218cad35..9abfb252ce 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -70,6 +70,16 @@ using namespace QV4; DEFINE_OBJECT_VTABLE(Object); +Object::Data::Data(InternalClass *internalClass) + : Managed::Data(internalClass) +{ + if (internalClass->size) { + Scope scope(internalClass->engine); + ScopedObject o(scope, this); + o->memberData().ensureIndex(internalClass->engine, internalClass->size); + } +} + Object::Object(ExecutionEngine *engine) : Managed(engine->objectClass) { diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 19105b18d3..4ba27ccece 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -104,6 +104,12 @@ struct URIErrorPrototype; struct Q_QML_EXPORT Object: Managed { struct Data : Managed::Data { + Data(ExecutionEngine *engine) + : Managed::Data(engine->objectClass) + { + } + Data(InternalClass *internal = 0); + Members memberData; ArrayData *arrayData; }; diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index dfaa7e68bc..5a7852f49b 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -213,6 +213,16 @@ struct Scoped setPointer(value_cast(v)); #ifndef QT_NO_DEBUG ++scope.size; +#endif + } + Scoped(const Scope &scope, HeapObject *o) + { + Value v; + v.m = reinterpret_cast(o); + ptr = scope.engine->jsStackTop++; + setPointer(value_cast(v)); +#ifndef QT_NO_DEBUG + ++scope.size; #endif } Scoped(const Scope &scope, const ScopedValue &v) @@ -280,6 +290,12 @@ struct Scoped #endif } + Scoped &operator=(HeapObject *o) { + Value v; + v.m = reinterpret_cast(o); + setPointer(value_cast(v)); + return *this; + } Scoped &operator=(const Value &v) { setPointer(value_cast(v)); return *this; diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 1a5058f4ca..5e26cbeeb5 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -58,11 +58,10 @@ QT_BEGIN_NAMESPACE DEFINE_OBJECT_VTABLE(QQuickRootItemMarker); -QQuickRootItemMarker::QQuickRootItemMarker(QQmlEngine *engine, QQuickWindow *window) - : QV4::Object(QQmlEnginePrivate::getV4Engine(engine)) +QQuickRootItemMarker::Data *QQuickRootItemMarker::create(QQmlEngine *engine, QQuickWindow *window) { - d()->window = window; - setVTable(staticVTable()); + QV4::ExecutionEngine *e = QQmlEnginePrivate::getV4Engine(engine); + return new (e) Data(e, window); } void QQuickRootItemMarker::markObjects(QV4::Managed *that, QV4::ExecutionEngine *e) @@ -91,7 +90,7 @@ void QQuickViewPrivate::init(QQmlEngine* e) { QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine.data()); QV4::Scope scope(v4); - QV4::Scoped v(scope, new (v4->memoryManager) QQuickRootItemMarker(engine.data(), q)); + QV4::Scoped v(scope, QQuickRootItemMarker::create(engine.data(), q)); rootItemMarker = v; } diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h index e73d5aab9c..8b35500de9 100644 --- a/src/quick/items/qquickview_p.h +++ b/src/quick/items/qquickview_p.h @@ -105,6 +105,13 @@ public: struct QQuickRootItemMarker : public QV4::Object { struct Data : QV4::Object::Data { + Data(QV4::ExecutionEngine *engine, QQuickWindow *window) + : Object::Data(engine) + , window(window) + { + setVTable(staticVTable()); + } + QQuickWindow *window; }; struct { @@ -113,12 +120,7 @@ struct QQuickRootItemMarker : public QV4::Object V4_OBJECT - QQuickRootItemMarker(QQmlEngine *engine, QQuickWindow *window); - - static void destroy(Managed *that) - { - static_cast(that)->~QQuickRootItemMarker(); - } + static Data *create(QQmlEngine *engine, QQuickWindow *window); static void markObjects(Managed *that, QV4::ExecutionEngine *e); diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index 91388ea30f..51053ea801 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -102,7 +102,7 @@ protected: { QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(e); QV4::Scope scope(v4); - QV4::ScopedObject v(scope, new (v4->memoryManager) QQuickRootItemMarker(e, this)); + QV4::ScopedObject v(scope, QQuickRootItemMarker::create(e, this)); rootItemMarker = v; } } -- cgit v1.2.3