Port the sequence (QList) wrapper away from v4classgen

This also gets rid of the QQmlSequenceBase base class.

Change-Id: I8cccc6c8924843ae37a4ee4ea95807f2b459d55b
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Simon Hausmann 2013-06-13 13:43:09 +02:00 committed by Lars Knoll
parent 50adb6318a
commit bc25d585de
4 changed files with 50 additions and 79 deletions

View File

@ -225,7 +225,7 @@ ExecutionEngine::ExecutionEngine(QQmlJS::EvalISelFactory *factory)
uRIErrorPrototype->init(this, uRIErrorCtor); uRIErrorPrototype->init(this, uRIErrorCtor);
variantPrototype->initClass(this); variantPrototype->initClass(this);
sequencePrototype->initClass(this); sequencePrototype->init(this);
// //
// set up the global object // set up the global object

View File

@ -159,12 +159,12 @@ template <> bool convertValueToElement(const QV4::Value &value)
} }
template <typename Container> template <typename Container>
class QQmlSequence : public QQmlSequenceBase class QQmlSequence : public QV4::Object
{ {
Q_MANAGED Q_MANAGED
public: public:
QQmlSequence(QV4::ExecutionEngine *engine, const Container &container) QQmlSequence(QV4::ExecutionEngine *engine, const Container &container)
: QQmlSequenceBase(engine) : QV4::Object(engine)
, m_container(container) , m_container(container)
, m_object(0) , m_object(0)
, m_propertyIndex(-1) , m_propertyIndex(-1)
@ -173,11 +173,11 @@ public:
type = Type_QmlSequence; type = Type_QmlSequence;
vtbl = &static_vtbl; vtbl = &static_vtbl;
prototype = engine->sequencePrototype; prototype = engine->sequencePrototype;
initClass(engine); init(engine);
} }
QQmlSequence(QV4::ExecutionEngine *engine, QObject *object, int propertyIndex) QQmlSequence(QV4::ExecutionEngine *engine, QObject *object, int propertyIndex)
: QQmlSequenceBase(engine) : QV4::Object(engine)
, m_object(object) , m_object(object)
, m_propertyIndex(propertyIndex) , m_propertyIndex(propertyIndex)
, m_isReference(true) , m_isReference(true)
@ -186,7 +186,12 @@ public:
vtbl = &static_vtbl; vtbl = &static_vtbl;
prototype = engine->sequencePrototype; prototype = engine->sequencePrototype;
loadReference(); 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) QV4::Value containerGetIndexed(QV4::ExecutionContext *ctx, uint index, bool *hasProperty)
@ -278,7 +283,7 @@ public:
if (m_isReference) { if (m_isReference) {
if (!m_object) if (!m_object)
return QQmlSequenceBase::advanceIterator(this, it, name, index, attrs); return QV4::Object::advanceIterator(this, it, name, index, attrs);
loadReference(); loadReference();
} }
@ -290,7 +295,7 @@ public:
it->tmpDynamicProperty.value = convertElementToValue(engine(), m_container.at(*index)); it->tmpDynamicProperty.value = convertElementToValue(engine(), m_container.at(*index));
return &it->tmpDynamicProperty; 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) bool containerDeleteIndexedProperty(QV4::ExecutionContext *ctx, uint index)
@ -382,56 +387,65 @@ public:
storeReference(); storeReference();
} }
QV4::Value lengthGetter(QV4::SimpleCallContext*) static QV4::Value method_get_length(QV4::SimpleCallContext *ctx)
{ {
if (m_isReference) { QQmlSequence<Container> *This = ctx->thisObject.as<QQmlSequence<Container> >();
if (!m_object) if (!This)
ctx->throwTypeError();
if (This->m_isReference) {
if (!This->m_object)
return QV4::Value::fromInt32(0); 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(); quint32 newLength = ctx->arguments[0].toUInt32();
/* Qt containers have int (rather than uint) allowable indexes. */ /* Qt containers have int (rather than uint) allowable indexes. */
if (newLength > INT_MAX) { if (newLength > INT_MAX) {
generateWarning(ctx, QLatin1String("Index out of range during length set")); 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 */ /* Read the sequence from the QObject property if we're a reference */
if (m_isReference) { if (This->m_isReference) {
if (!m_object) if (!This->m_object)
return; return QV4::Value::undefinedValue();
loadReference(); This->loadReference();
} }
/* Determine whether we need to modify the sequence */ /* Determine whether we need to modify the sequence */
qint32 newCount = static_cast<qint32>(newLength); qint32 newCount = static_cast<qint32>(newLength);
qint32 count = m_container.count(); qint32 count = This->m_container.count();
if (newCount == count) { if (newCount == count) {
return; return QV4::Value::undefinedValue();
} else if (newCount > count) { } else if (newCount > count) {
/* according to ECMA262r3 we need to insert */ /* according to ECMA262r3 we need to insert */
/* undefined values increasing length to newLength. */ /* undefined values increasing length to newLength. */
/* We cannot, so we insert default-values instead. */ /* We cannot, so we insert default-values instead. */
m_container.reserve(newCount); This->m_container.reserve(newCount);
while (newCount > count++) { while (newCount > count++) {
m_container.append(typename Container::value_type()); This->m_container.append(typename Container::value_type());
} }
} else { } else {
/* according to ECMA262r3 we need to remove */ /* according to ECMA262r3 we need to remove */
/* elements until the sequence is the required length. */ /* elements until the sequence is the required length. */
while (newCount < count) { while (newCount < count) {
count--; count--;
m_container.removeAt(count); This->m_container.removeAt(count);
} }
} }
/* write back if required. */ /* 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. */ /* write back. already checked that object is non-null, so skip that check here. */
storeReference(); This->storeReference();
} }
return QV4::Value::undefinedValue();
} }
QVariant toVariant() const QVariant toVariant() const
@ -517,6 +531,12 @@ SequencePrototype::SequencePrototype(ExecutionEngine *engine)
} }
#undef REGISTER_QML_SEQUENCE_METATYPE #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::Value SequencePrototype::method_sort(QV4::SimpleCallContext *ctx)
{ {
QV4::Object *o = ctx->thisObject.asObject(); QV4::Object *o = ctx->thisObject.asObject();
@ -537,38 +557,6 @@ QV4::Value SequencePrototype::method_sort(QV4::SimpleCallContext *ctx)
return ctx->thisObject; 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) \ #define IS_SEQUENCE(unused1, unused2, SequenceType, unused3) \
if (sequenceTypeId == qMetaTypeId<SequenceType>()) { \ if (sequenceTypeId == qMetaTypeId<SequenceType>()) { \
return true; \ return true; \
@ -660,6 +648,4 @@ int SequencePrototype::metaTypeForSequence(QV4::Object *object)
#undef MAP_META_TYPE #undef MAP_META_TYPE
#include "qv4sequenceobject_p_jsclass.cpp"
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -63,32 +63,18 @@ QT_BEGIN_NAMESPACE
namespace QV4 { namespace QV4 {
class QV4_JS_CLASS(QQmlSequenceBase) : public QV4::Object struct SequencePrototype : 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
{ {
SequencePrototype(QV4::ExecutionEngine *engine); SequencePrototype(QV4::ExecutionEngine *engine);
void initClass(QV4::ExecutionEngine *engine); void init(QV4::ExecutionEngine *engine);
static QV4::Value method_valueOf(QV4::SimpleCallContext *ctx) static QV4::Value method_valueOf(QV4::SimpleCallContext *ctx)
{ {
return QV4::Value::fromString(ctx->thisObject.toString(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 bool isSequenceType(int sequenceTypeId);
static QV4::Value newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded); static QV4::Value newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);

View File

@ -111,8 +111,7 @@ OTHER_FILES += \
$$PWD/v4classgen $$PWD/v4classgen
JS_CLASS_SOURCES += $$PWD/qv4dateobject_p.h \ JS_CLASS_SOURCES += $$PWD/qv4dateobject_p.h \
$$PWD/qv4variantobject_p.h \ $$PWD/qv4variantobject_p.h
$$PWD/qv4sequenceobject_p.h
js_class_bindings.output = ${QMAKE_FILE_BASE}_jsclass.cpp js_class_bindings.output = ${QMAKE_FILE_BASE}_jsclass.cpp
js_class_bindings.input = JS_CLASS_SOURCES js_class_bindings.input = JS_CLASS_SOURCES