Port the sequence (QList) wrapper away from v4classgen
authorSimon Hausmann <simon.hausmann@digia.com>
Thu, 13 Jun 2013 11:43:09 +0000 (13:43 +0200)
committerLars Knoll <lars.knoll@digia.com>
Thu, 13 Jun 2013 12:16:16 +0000 (14:16 +0200)
This also gets rid of the QQmlSequenceBase base class.

Change-Id: I8cccc6c8924843ae37a4ee4ea95807f2b459d55b
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/v4/qv4engine.cpp
src/qml/qml/v4/qv4sequenceobject.cpp
src/qml/qml/v4/qv4sequenceobject_p.h
src/qml/qml/v4/v4.pri

index b659ced..20a65a8 100644 (file)
@@ -225,7 +225,7 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
     uRIErrorPrototype->init(this, uRIErrorCtor);
 
     variantPrototype->initClass(this);
-    sequencePrototype->initClass(this);
+    sequencePrototype->init(this);
 
     //
     // set up the global object
index be9bbfc..40f0c30 100644 (file)
@@ -159,12 +159,12 @@ template <> bool convertValueToElement(const QV4::Value &value)
 }
 
 template <typename Container>
-class QQmlSequence : public QQmlSequenceBase
+class QQmlSequence : public QV4::Object
 {
     Q_MANAGED
 public:
     QQmlSequence(QV4::ExecutionEngine *engine, const Container &container)
-        : QQmlSequenceBase(engine)
+        : QV4::Object(engine)
         , m_container(container)
         , m_object(0)
         , m_propertyIndex(-1)
@@ -173,11 +173,11 @@ public:
         type = Type_QmlSequence;
         vtbl = &static_vtbl;
         prototype = engine->sequencePrototype;
-        initClass(engine);
+        init(engine);
     }
 
     QQmlSequence(QV4::ExecutionEngine *engine, QObject *object, int propertyIndex)
-        : QQmlSequenceBase(engine)
+        : QV4::Object(engine)
         , m_object(object)
         , m_propertyIndex(propertyIndex)
         , m_isReference(true)
@@ -186,7 +186,12 @@ public:
         vtbl = &static_vtbl;
         prototype = engine->sequencePrototype;
         loadReference();
-        initClass(engine);
+        init(engine);
+    }
+
+    void init(ExecutionEngine *engine)
+    {
+        defineAccessorProperty(engine, QStringLiteral("length"), method_get_length, method_set_length);
     }
 
     QV4::Value containerGetIndexed(QV4::ExecutionContext *ctx, uint index, bool *hasProperty)
@@ -278,7 +283,7 @@ public:
 
         if (m_isReference) {
             if (!m_object)
-                return QQmlSequenceBase::advanceIterator(this, it, name, index, attrs);
+                return QV4::Object::advanceIterator(this, it, name, index, attrs);
             loadReference();
         }
 
@@ -290,7 +295,7 @@ public:
             it->tmpDynamicProperty.value = convertElementToValue(engine(), m_container.at(*index));
             return &it->tmpDynamicProperty;
         }
-        return QQmlSequenceBase::advanceIterator(this, it, name, index, attrs);
+        return QV4::Object::advanceIterator(this, it, name, index, attrs);
     }
 
     bool containerDeleteIndexedProperty(QV4::ExecutionContext *ctx, uint index)
@@ -382,56 +387,65 @@ public:
             storeReference();
     }
 
-    QV4::Value lengthGetter(QV4::SimpleCallContext*)
+    static QV4::Value method_get_length(QV4::SimpleCallContext *ctx)
     {
-        if (m_isReference) {
-            if (!m_object)
+        QQmlSequence<Container> *This = ctx->thisObject.as<QQmlSequence<Container> >();
+        if (!This)
+            ctx->throwTypeError();
+
+        if (This->m_isReference) {
+            if (!This->m_object)
                 return QV4::Value::fromInt32(0);
-            loadReference();
+            This->loadReference();
         }
-        return QV4::Value::fromInt32(m_container.count());
+        return QV4::Value::fromInt32(This->m_container.count());
     }
 
-    void lengthSetter(QV4::SimpleCallContext* ctx)
+    static QV4::Value method_set_length(QV4::SimpleCallContext* ctx)
     {
+        QQmlSequence<Container> *This = ctx->thisObject.as<QQmlSequence<Container> >();
+        if (!This)
+            ctx->throwTypeError();
+
         quint32 newLength = ctx->arguments[0].toUInt32();
         /* Qt containers have int (rather than uint) allowable indexes. */
         if (newLength > INT_MAX) {
             generateWarning(ctx, QLatin1String("Index out of range during length set"));
-            return;
+            return QV4::Value::undefinedValue();
         }
         /* Read the sequence from the QObject property if we're a reference */
-        if (m_isReference) {
-            if (!m_object)
-                return;
-            loadReference();
+        if (This->m_isReference) {
+            if (!This->m_object)
+                return QV4::Value::undefinedValue();
+            This->loadReference();
         }
         /* Determine whether we need to modify the sequence */
         qint32 newCount = static_cast<qint32>(newLength);
-        qint32 count = m_container.count();
+        qint32 count = This->m_container.count();
         if (newCount == count) {
-            return;
+            return QV4::Value::undefinedValue();
         } else if (newCount > count) {
             /* according to ECMA262r3 we need to insert */
             /* undefined values increasing length to newLength. */
             /* We cannot, so we insert default-values instead. */
-            m_container.reserve(newCount);
+            This->m_container.reserve(newCount);
             while (newCount > count++) {
-                m_container.append(typename Container::value_type());
+                This->m_container.append(typename Container::value_type());
             }
         } else {
             /* according to ECMA262r3 we need to remove */
             /* elements until the sequence is the required length. */
             while (newCount < count) {
                 count--;
-                m_container.removeAt(count);
+                This->m_container.removeAt(count);
             }
         }
         /* write back if required. */
-        if (m_isReference) {
+        if (This->m_isReference) {
             /* write back.  already checked that object is non-null, so skip that check here. */
-            storeReference();
+            This->storeReference();
         }
+        return QV4::Value::undefinedValue();
     }
 
     QVariant toVariant() const
@@ -517,6 +531,12 @@ SequencePrototype::SequencePrototype(ExecutionEngine *engine)
 }
 #undef REGISTER_QML_SEQUENCE_METATYPE
 
+void SequencePrototype::init(QV4::ExecutionEngine *engine)
+{
+    defineDefaultProperty(engine, QStringLiteral("sort"), method_sort, 1);
+    defineDefaultProperty(engine, QStringLiteral("valueOf"), method_valueOf, 0);
+}
+
 QV4::Value SequencePrototype::method_sort(QV4::SimpleCallContext *ctx)
 {
     QV4::Object *o = ctx->thisObject.asObject();
@@ -537,38 +557,6 @@ QV4::Value SequencePrototype::method_sort(QV4::SimpleCallContext *ctx)
     return ctx->thisObject;
 }
 
-QV4::Value QQmlSequenceBase::method_get_length(QV4::SimpleCallContext* ctx) QV4_ANNOTATE(attributes QV4::Attr_ReadOnly)
-{
-    QV4::Object *o = ctx->thisObject.asObject();
-    if (!o)
-        ctx->throwTypeError();
-#define CALL_LENGTH_GETTER(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue) \
-    if (QQml##SequenceElementTypeName##List *s = o->as<QQml##SequenceElementTypeName##List>()) { \
-        return s->lengthGetter(ctx); \
-    } else
-
-    FOREACH_QML_SEQUENCE_TYPE(CALL_LENGTH_GETTER)
-#undef CALL_LENGTH_GETTER
-
-    return QV4::Value::undefinedValue();
-}
-
-QV4::Value QQmlSequenceBase::method_set_length(QV4::SimpleCallContext* ctx)
-{
-    QV4::Object *o = ctx->thisObject.asObject();
-    if (!o)
-        ctx->throwTypeError();
-#define CALL_LENGTH_SETTER(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue) \
-    if (QQml##SequenceElementTypeName##List *s = o->as<QQml##SequenceElementTypeName##List>()) { \
-        s->lengthSetter(ctx); \
-    } else
-
-    FOREACH_QML_SEQUENCE_TYPE(CALL_LENGTH_SETTER)
-#undef CALL_LENGTH_SETTER
-
-    return QV4::Value::undefinedValue();
-}
-
 #define IS_SEQUENCE(unused1, unused2, SequenceType, unused3) \
     if (sequenceTypeId == qMetaTypeId<SequenceType>()) { \
         return true; \
@@ -660,6 +648,4 @@ int SequencePrototype::metaTypeForSequence(QV4::Object *object)
 
 #undef MAP_META_TYPE
 
-#include "qv4sequenceobject_p_jsclass.cpp"
-
 QT_END_NAMESPACE
index d2514c6..2cade45 100644 (file)
@@ -63,32 +63,18 @@ QT_BEGIN_NAMESPACE
 
 namespace QV4 {
 
-class QV4_JS_CLASS(QQmlSequenceBase) : public QV4::Object
-{
-public:
-    QQmlSequenceBase(QV4::ExecutionEngine *engine)
-        : QV4::Object(engine)
-    {}
-
-    void initClass(QV4::ExecutionEngine *engine);
-
-    static QV4::Value method_get_length(QV4::SimpleCallContext* ctx) QV4_ANNOTATE(attributes QV4::Attr_ReadOnly);
-
-    static QV4::Value method_set_length(QV4::SimpleCallContext* ctx);
-};
-
-struct QV4_JS_CLASS(SequencePrototype) : public QV4::Object
+struct SequencePrototype : public QV4::Object
 {
     SequencePrototype(QV4::ExecutionEngine *engine);
 
-    void initClass(QV4::ExecutionEngine *engine);
+    void init(QV4::ExecutionEngine *engine);
 
     static QV4::Value method_valueOf(QV4::SimpleCallContext *ctx)
     {
         return QV4::Value::fromString(ctx->thisObject.toString(ctx));
     }
 
-    static QV4::Value method_sort(QV4::SimpleCallContext *ctx) QV4_ARGC(1);
+    static QV4::Value method_sort(QV4::SimpleCallContext *ctx);
 
     static bool isSequenceType(int sequenceTypeId);
     static QV4::Value newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
index f613ae6..942c445 100644 (file)
@@ -111,8 +111,7 @@ OTHER_FILES += \
     $$PWD/v4classgen
 
 JS_CLASS_SOURCES += $$PWD/qv4dateobject_p.h \
-                    $$PWD/qv4variantobject_p.h \
-                    $$PWD/qv4sequenceobject_p.h
+                    $$PWD/qv4variantobject_p.h
 
 js_class_bindings.output = ${QMAKE_FILE_BASE}_jsclass.cpp
 js_class_bindings.input = JS_CLASS_SOURCES