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:
parent
50adb6318a
commit
bc25d585de
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue