From bc25d585deaf4ade17ccc180bfe5d1b5fd8bd293 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 13 Jun 2013 13:43:09 +0200 Subject: [PATCH] Port the sequence (QList) wrapper away from v4classgen This also gets rid of the QQmlSequenceBase base class. Change-Id: I8cccc6c8924843ae37a4ee4ea95807f2b459d55b Reviewed-by: Lars Knoll --- src/qml/qml/v4/qv4engine.cpp | 2 +- src/qml/qml/v4/qv4sequenceobject.cpp | 104 +++++++++++++++-------------------- src/qml/qml/v4/qv4sequenceobject_p.h | 20 +------ src/qml/qml/v4/v4.pri | 3 +- 4 files changed, 50 insertions(+), 79 deletions(-) diff --git a/src/qml/qml/v4/qv4engine.cpp b/src/qml/qml/v4/qv4engine.cpp index b659ced..20a65a8 100644 --- a/src/qml/qml/v4/qv4engine.cpp +++ b/src/qml/qml/v4/qv4engine.cpp @@ -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 diff --git a/src/qml/qml/v4/qv4sequenceobject.cpp b/src/qml/qml/v4/qv4sequenceobject.cpp index be9bbfc..40f0c30 100644 --- a/src/qml/qml/v4/qv4sequenceobject.cpp +++ b/src/qml/qml/v4/qv4sequenceobject.cpp @@ -159,12 +159,12 @@ template <> bool convertValueToElement(const QV4::Value &value) } template -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 *This = ctx->thisObject.as >(); + 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 *This = ctx->thisObject.as >(); + 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(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()) { \ - 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()) { \ - 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()) { \ return true; \ @@ -660,6 +648,4 @@ int SequencePrototype::metaTypeForSequence(QV4::Object *object) #undef MAP_META_TYPE -#include "qv4sequenceobject_p_jsclass.cpp" - QT_END_NAMESPACE diff --git a/src/qml/qml/v4/qv4sequenceobject_p.h b/src/qml/qml/v4/qv4sequenceobject_p.h index d2514c6..2cade45 100644 --- a/src/qml/qml/v4/qv4sequenceobject_p.h +++ b/src/qml/qml/v4/qv4sequenceobject_p.h @@ -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); diff --git a/src/qml/qml/v4/v4.pri b/src/qml/qml/v4/v4.pri index f613ae6..942c445 100644 --- a/src/qml/qml/v4/v4.pri +++ b/src/qml/qml/v4/v4.pri @@ -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 -- 2.7.4