aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qdeclarativevmemetaobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/qdeclarativevmemetaobject.cpp')
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp1110
1 files changed, 0 insertions, 1110 deletions
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
deleted file mode 100644
index f7361eb2ce..0000000000
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ /dev/null
@@ -1,1110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdeclarativevmemetaobject_p.h"
-
-
-#include "qdeclarative.h"
-#include <private/qdeclarativerefcount_p.h>
-#include "qdeclarativeexpression.h"
-#include "qdeclarativeexpression_p.h"
-#include "qdeclarativecontext_p.h"
-#include "qdeclarativebinding_p.h"
-#include "qdeclarativepropertyvalueinterceptor_p.h"
-
-#include <private/qv8variantresource_p.h>
-
-Q_DECLARE_METATYPE(QJSValue);
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeVMEVariant
-{
-public:
- inline QDeclarativeVMEVariant();
- inline ~QDeclarativeVMEVariant();
-
- inline const void *dataPtr() const;
- inline void *dataPtr();
- inline int dataType() const;
-
- inline QObject *asQObject();
- inline const QVariant &asQVariant();
- inline int asInt();
- inline bool asBool();
- inline double asDouble();
- inline const QString &asQString();
- inline const QUrl &asQUrl();
- inline const QColor &asQColor();
- inline const QTime &asQTime();
- inline const QDate &asQDate();
- inline const QDateTime &asQDateTime();
- inline const QJSValue &asQJSValue();
-
- inline void setValue(QObject *);
- inline void setValue(const QVariant &);
- inline void setValue(int);
- inline void setValue(bool);
- inline void setValue(double);
- inline void setValue(const QString &);
- inline void setValue(const QUrl &);
- inline void setValue(const QColor &);
- inline void setValue(const QTime &);
- inline void setValue(const QDate &);
- inline void setValue(const QDateTime &);
- inline void setValue(const QJSValue &);
-private:
- int type;
- void *data[4]; // Large enough to hold all types
-
- inline void cleanup();
-};
-
-class QDeclarativeVMEMetaObjectEndpoint : public QDeclarativeNotifierEndpoint
-{
-public:
- QDeclarativeVMEMetaObjectEndpoint();
- static void vmecallback(QDeclarativeNotifierEndpoint *);
- void tryConnect();
-
- QFlagPointer<QDeclarativeVMEMetaObject> metaObject;
-};
-
-
-QDeclarativeVMEVariant::QDeclarativeVMEVariant()
-: type(QVariant::Invalid)
-{
-}
-
-QDeclarativeVMEVariant::~QDeclarativeVMEVariant()
-{
- cleanup();
-}
-
-void QDeclarativeVMEVariant::cleanup()
-{
- if (type == QVariant::Invalid) {
- } else if (type == QMetaType::Int ||
- type == QMetaType::Bool ||
- type == QMetaType::Double) {
- type = QVariant::Invalid;
- } else if (type == QMetaType::QObjectStar) {
- ((QDeclarativeGuard<QObject>*)dataPtr())->~QDeclarativeGuard<QObject>();
- type = QVariant::Invalid;
- } else if (type == QMetaType::QString) {
- ((QString *)dataPtr())->~QString();
- type = QVariant::Invalid;
- } else if (type == QMetaType::QUrl) {
- ((QUrl *)dataPtr())->~QUrl();
- type = QVariant::Invalid;
- } else if (type == QMetaType::QColor) {
- ((QColor *)dataPtr())->~QColor();
- type = QVariant::Invalid;
- } else if (type == QMetaType::QTime) {
- ((QTime *)dataPtr())->~QTime();
- type = QVariant::Invalid;
- } else if (type == QMetaType::QDate) {
- ((QDate *)dataPtr())->~QDate();
- type = QVariant::Invalid;
- } else if (type == QMetaType::QDateTime) {
- ((QDateTime *)dataPtr())->~QDateTime();
- type = QVariant::Invalid;
- } else if (type == qMetaTypeId<QVariant>()) {
- ((QVariant *)dataPtr())->~QVariant();
- type = QVariant::Invalid;
- } else if (type == qMetaTypeId<QJSValue>()) {
- ((QJSValue *)dataPtr())->~QJSValue();
- type = QVariant::Invalid;
- }
-
-}
-
-int QDeclarativeVMEVariant::dataType() const
-{
- return type;
-}
-
-const void *QDeclarativeVMEVariant::dataPtr() const
-{
- return &data;
-}
-
-void *QDeclarativeVMEVariant::dataPtr()
-{
- return &data;
-}
-
-QObject *QDeclarativeVMEVariant::asQObject()
-{
- if (type != QMetaType::QObjectStar)
- setValue((QObject *)0);
-
- return *(QDeclarativeGuard<QObject> *)(dataPtr());
-}
-
-const QVariant &QDeclarativeVMEVariant::asQVariant()
-{
- if (type != QMetaType::QVariant)
- setValue(QVariant());
-
- return *(QVariant *)(dataPtr());
-}
-
-int QDeclarativeVMEVariant::asInt()
-{
- if (type != QMetaType::Int)
- setValue(int(0));
-
- return *(int *)(dataPtr());
-}
-
-bool QDeclarativeVMEVariant::asBool()
-{
- if (type != QMetaType::Bool)
- setValue(bool(false));
-
- return *(bool *)(dataPtr());
-}
-
-double QDeclarativeVMEVariant::asDouble()
-{
- if (type != QMetaType::Double)
- setValue(double(0));
-
- return *(double *)(dataPtr());
-}
-
-const QString &QDeclarativeVMEVariant::asQString()
-{
- if (type != QMetaType::QString)
- setValue(QString());
-
- return *(QString *)(dataPtr());
-}
-
-const QUrl &QDeclarativeVMEVariant::asQUrl()
-{
- if (type != QMetaType::QUrl)
- setValue(QUrl());
-
- return *(QUrl *)(dataPtr());
-}
-
-const QColor &QDeclarativeVMEVariant::asQColor()
-{
- if (type != QMetaType::QColor)
- setValue(QColor());
-
- return *(QColor *)(dataPtr());
-}
-
-const QTime &QDeclarativeVMEVariant::asQTime()
-{
- if (type != QMetaType::QTime)
- setValue(QTime());
-
- return *(QTime *)(dataPtr());
-}
-
-const QDate &QDeclarativeVMEVariant::asQDate()
-{
- if (type != QMetaType::QDate)
- setValue(QDate());
-
- return *(QDate *)(dataPtr());
-}
-
-const QDateTime &QDeclarativeVMEVariant::asQDateTime()
-{
- if (type != QMetaType::QDateTime)
- setValue(QDateTime());
-
- return *(QDateTime *)(dataPtr());
-}
-
-const QJSValue &QDeclarativeVMEVariant::asQJSValue()
-{
- if (type != qMetaTypeId<QJSValue>())
- setValue(QJSValue());
-
- return *(QJSValue *)(dataPtr());
-}
-
-void QDeclarativeVMEVariant::setValue(QObject *v)
-{
- if (type != QMetaType::QObjectStar) {
- cleanup();
- type = QMetaType::QObjectStar;
- new (dataPtr()) QDeclarativeGuard<QObject>();
- }
- *(QDeclarativeGuard<QObject>*)(dataPtr()) = v;
-}
-
-void QDeclarativeVMEVariant::setValue(const QVariant &v)
-{
- if (type != qMetaTypeId<QVariant>()) {
- cleanup();
- type = qMetaTypeId<QVariant>();
- new (dataPtr()) QVariant(v);
- } else {
- *(QVariant *)(dataPtr()) = v;
- }
-}
-
-void QDeclarativeVMEVariant::setValue(int v)
-{
- if (type != QMetaType::Int) {
- cleanup();
- type = QMetaType::Int;
- }
- *(int *)(dataPtr()) = v;
-}
-
-void QDeclarativeVMEVariant::setValue(bool v)
-{
- if (type != QMetaType::Bool) {
- cleanup();
- type = QMetaType::Bool;
- }
- *(bool *)(dataPtr()) = v;
-}
-
-void QDeclarativeVMEVariant::setValue(double v)
-{
- if (type != QMetaType::Double) {
- cleanup();
- type = QMetaType::Double;
- }
- *(double *)(dataPtr()) = v;
-}
-
-void QDeclarativeVMEVariant::setValue(const QString &v)
-{
- if (type != QMetaType::QString) {
- cleanup();
- type = QMetaType::QString;
- new (dataPtr()) QString(v);
- } else {
- *(QString *)(dataPtr()) = v;
- }
-}
-
-void QDeclarativeVMEVariant::setValue(const QUrl &v)
-{
- if (type != QMetaType::QUrl) {
- cleanup();
- type = QMetaType::QUrl;
- new (dataPtr()) QUrl(v);
- } else {
- *(QUrl *)(dataPtr()) = v;
- }
-}
-
-void QDeclarativeVMEVariant::setValue(const QColor &v)
-{
- if (type != QMetaType::QColor) {
- cleanup();
- type = QMetaType::QColor;
- new (dataPtr()) QColor(v);
- } else {
- *(QColor *)(dataPtr()) = v;
- }
-}
-
-void QDeclarativeVMEVariant::setValue(const QTime &v)
-{
- if (type != QMetaType::QTime) {
- cleanup();
- type = QMetaType::QTime;
- new (dataPtr()) QTime(v);
- } else {
- *(QTime *)(dataPtr()) = v;
- }
-}
-
-void QDeclarativeVMEVariant::setValue(const QDate &v)
-{
- if (type != QMetaType::QDate) {
- cleanup();
- type = QMetaType::QDate;
- new (dataPtr()) QDate(v);
- } else {
- *(QDate *)(dataPtr()) = v;
- }
-}
-
-void QDeclarativeVMEVariant::setValue(const QDateTime &v)
-{
- if (type != QMetaType::QDateTime) {
- cleanup();
- type = QMetaType::QDateTime;
- new (dataPtr()) QDateTime(v);
- } else {
- *(QDateTime *)(dataPtr()) = v;
- }
-}
-
-void QDeclarativeVMEVariant::setValue(const QJSValue &v)
-{
- if (type != qMetaTypeId<QJSValue>()) {
- cleanup();
- type = qMetaTypeId<QJSValue>();
- new (dataPtr()) QJSValue(v);
- } else {
- *(QJSValue *)(dataPtr()) = v;
- }
-}
-
-QDeclarativeVMEMetaObjectEndpoint::QDeclarativeVMEMetaObjectEndpoint()
-{
- callback = &vmecallback;
-}
-
-void QDeclarativeVMEMetaObjectEndpoint::vmecallback(QDeclarativeNotifierEndpoint *e)
-{
- QDeclarativeVMEMetaObjectEndpoint *vmee = static_cast<QDeclarativeVMEMetaObjectEndpoint*>(e);
- vmee->tryConnect();
-}
-
-void QDeclarativeVMEMetaObjectEndpoint::tryConnect()
-{
- int aliasId = this - metaObject->aliasEndpoints;
-
- if (metaObject.flag()) {
- // This is actually notify
- int sigIdx = metaObject->methodOffset + aliasId + metaObject->metaData->propertyCount;
- QMetaObject::activate(metaObject->object, sigIdx, 0);
- } else {
- QDeclarativeVMEMetaData::AliasData *d = metaObject->metaData->aliasData() + aliasId;
- if (!d->isObjectAlias()) {
- QDeclarativeContextData *ctxt = metaObject->ctxt;
- QObject *target = ctxt->idValues[d->contextIdx].data();
- if (!target)
- return;
-
- QMetaProperty prop = target->metaObject()->property(d->propertyIndex());
- if (prop.hasNotifySignal())
- connect(target, prop.notifySignalIndex());
- }
-
- metaObject.setFlag();
- }
-}
-
-QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj,
- const QMetaObject *other,
- const QDeclarativeVMEMetaData *meta,
- QDeclarativeCompiledData *cdata)
-: QV8GCCallback::Node(GcPrologueCallback), object(obj), compiledData(cdata),
- ctxt(QDeclarativeData::get(obj, true)->outerContext), metaData(meta), data(0),
- aliasEndpoints(0), firstVarPropertyIndex(-1), varPropertiesInitialized(false),
- v8methods(0), parent(0)
-{
- compiledData->addref();
-
- *static_cast<QMetaObject *>(this) = *other;
- this->d.superdata = obj->metaObject();
-
- QObjectPrivate *op = QObjectPrivate::get(obj);
- if (op->metaObject)
- parent = static_cast<QAbstractDynamicMetaObject*>(op->metaObject);
- op->metaObject = this;
-
- propOffset = QAbstractDynamicMetaObject::propertyOffset();
- methodOffset = QAbstractDynamicMetaObject::methodOffset();
-
- data = new QDeclarativeVMEVariant[metaData->propertyCount - metaData->varPropertyCount];
-
- aConnected.resize(metaData->aliasCount);
- int list_type = qMetaTypeId<QDeclarativeListProperty<QObject> >();
-
- // ### Optimize
- for (int ii = 0; ii < metaData->propertyCount - metaData->varPropertyCount; ++ii) {
- int t = (metaData->propertyData() + ii)->propertyType;
- if (t == list_type) {
- listProperties.append(List(methodOffset + ii));
- data[ii].setValue(listProperties.count() - 1);
- }
- }
-
- firstVarPropertyIndex = metaData->propertyCount - metaData->varPropertyCount;
- if (metaData->varPropertyCount)
- QV8GCCallback::addGcCallbackNode(this);
-}
-
-QDeclarativeVMEMetaObject::~QDeclarativeVMEMetaObject()
-{
- compiledData->release();
- delete parent;
- delete [] data;
- delete [] aliasEndpoints;
-
- for (int ii = 0; v8methods && ii < metaData->methodCount; ++ii) {
- qPersistentDispose(v8methods[ii]);
- }
- delete [] v8methods;
-
- if (metaData->varPropertyCount)
- qPersistentDispose(varProperties); // if not weak, will not have been cleaned up by the callback.
-}
-
-int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
-{
- int id = _id;
- if(c == QMetaObject::WriteProperty) {
- int flags = *reinterpret_cast<int*>(a[3]);
- if (!(flags & QDeclarativePropertyPrivate::BypassInterceptor)
- && !aInterceptors.isEmpty()
- && aInterceptors.testBit(id)) {
- QPair<int, QDeclarativePropertyValueInterceptor*> pair = interceptors.value(id);
- int valueIndex = pair.first;
- QDeclarativePropertyValueInterceptor *vi = pair.second;
- int type = property(id).userType();
-
- if (type != QVariant::Invalid) {
- if (valueIndex != -1) {
- QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine):0;
- QDeclarativeValueType *valueType = 0;
- if (ep) valueType = ep->valueTypes[type];
- else valueType = QDeclarativeValueTypeFactory::valueType(type);
- Q_ASSERT(valueType);
-
- valueType->setValue(QVariant(type, a[0]));
- QMetaProperty valueProp = valueType->metaObject()->property(valueIndex);
- vi->write(valueProp.read(valueType));
-
- if (!ep) delete valueType;
- return -1;
- } else {
- vi->write(QVariant(type, a[0]));
- return -1;
- }
- }
- }
- }
- if (c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty) {
- if (id >= propOffset) {
- id -= propOffset;
-
- if (id < metaData->propertyCount) {
- int t = (metaData->propertyData() + id)->propertyType;
- bool needActivate = false;
-
- if (id >= firstVarPropertyIndex) {
- Q_ASSERT(t == QMetaType::QVariant);
- // the context can be null if accessing var properties from cpp after re-parenting an item.
- QDeclarativeEnginePrivate *ep = (ctxt == 0 || ctxt->engine == 0) ? 0 : QDeclarativeEnginePrivate::get(ctxt->engine);
- QV8Engine *v8e = (ep == 0) ? 0 : ep->v8engine();
- if (v8e) {
- v8::HandleScope handleScope;
- v8::Context::Scope contextScope(v8e->context());
- if (c == QMetaObject::ReadProperty) {
- *reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
- } else if (c == QMetaObject::WriteProperty) {
- writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
- }
- } else if (c == QMetaObject::ReadProperty) {
- // if the context was disposed, we just return an invalid variant from read.
- *reinterpret_cast<QVariant *>(a[0]) = QVariant();
- }
-
- } else {
-
- if (c == QMetaObject::ReadProperty) {
- switch(t) {
- case QVariant::Int:
- *reinterpret_cast<int *>(a[0]) = data[id].asInt();
- break;
- case QVariant::Bool:
- *reinterpret_cast<bool *>(a[0]) = data[id].asBool();
- break;
- case QVariant::Double:
- *reinterpret_cast<double *>(a[0]) = data[id].asDouble();
- break;
- case QVariant::String:
- *reinterpret_cast<QString *>(a[0]) = data[id].asQString();
- break;
- case QVariant::Url:
- *reinterpret_cast<QUrl *>(a[0]) = data[id].asQUrl();
- break;
- case QVariant::Color:
- *reinterpret_cast<QColor *>(a[0]) = data[id].asQColor();
- break;
- case QVariant::Date:
- *reinterpret_cast<QDate *>(a[0]) = data[id].asQDate();
- break;
- case QVariant::DateTime:
- *reinterpret_cast<QDateTime *>(a[0]) = data[id].asQDateTime();
- break;
- case QMetaType::QObjectStar:
- *reinterpret_cast<QObject **>(a[0]) = data[id].asQObject();
- break;
- case QMetaType::QVariant:
- *reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
- break;
- default:
- break;
- }
- if (t == qMetaTypeId<QDeclarativeListProperty<QObject> >()) {
- int listIndex = data[id].asInt();
- const List *list = &listProperties.at(listIndex);
- *reinterpret_cast<QDeclarativeListProperty<QObject> *>(a[0]) =
- QDeclarativeListProperty<QObject>(object, (void *)list,
- list_append, list_count, list_at,
- list_clear);
- }
-
- } else if (c == QMetaObject::WriteProperty) {
-
- switch(t) {
- case QVariant::Int:
- needActivate = *reinterpret_cast<int *>(a[0]) != data[id].asInt();
- data[id].setValue(*reinterpret_cast<int *>(a[0]));
- break;
- case QVariant::Bool:
- needActivate = *reinterpret_cast<bool *>(a[0]) != data[id].asBool();
- data[id].setValue(*reinterpret_cast<bool *>(a[0]));
- break;
- case QVariant::Double:
- needActivate = *reinterpret_cast<double *>(a[0]) != data[id].asDouble();
- data[id].setValue(*reinterpret_cast<double *>(a[0]));
- break;
- case QVariant::String:
- needActivate = *reinterpret_cast<QString *>(a[0]) != data[id].asQString();
- data[id].setValue(*reinterpret_cast<QString *>(a[0]));
- break;
- case QVariant::Url:
- needActivate = *reinterpret_cast<QUrl *>(a[0]) != data[id].asQUrl();
- data[id].setValue(*reinterpret_cast<QUrl *>(a[0]));
- break;
- case QVariant::Color:
- needActivate = *reinterpret_cast<QColor *>(a[0]) != data[id].asQColor();
- data[id].setValue(*reinterpret_cast<QColor *>(a[0]));
- break;
- case QVariant::Date:
- needActivate = *reinterpret_cast<QDate *>(a[0]) != data[id].asQDate();
- data[id].setValue(*reinterpret_cast<QDate *>(a[0]));
- break;
- case QVariant::DateTime:
- needActivate = *reinterpret_cast<QDateTime *>(a[0]) != data[id].asQDateTime();
- data[id].setValue(*reinterpret_cast<QDateTime *>(a[0]));
- break;
- case QMetaType::QObjectStar:
- needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject();
- data[id].setValue(*reinterpret_cast<QObject **>(a[0]));
- break;
- case QMetaType::QVariant:
- writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
- break;
- default:
- break;
- }
- }
-
- }
-
- if (c == QMetaObject::WriteProperty && needActivate) {
- activate(object, methodOffset + id, 0);
- }
-
- return -1;
- }
-
- id -= metaData->propertyCount;
-
- if (id < metaData->aliasCount) {
-
- QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + id;
-
- if (d->flags & QML_ALIAS_FLAG_PTR && c == QMetaObject::ReadProperty)
- *reinterpret_cast<void **>(a[0]) = 0;
-
- if (!ctxt) return -1;
-
- QDeclarativeContext *context = ctxt->asQDeclarativeContext();
- QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context);
-
- QObject *target = ctxtPriv->data->idValues[d->contextIdx].data();
- if (!target)
- return -1;
-
- connectAlias(id);
-
- if (d->isObjectAlias()) {
- *reinterpret_cast<QObject **>(a[0]) = target;
- return -1;
- }
-
- // Remove binding (if any) on write
- if(c == QMetaObject::WriteProperty) {
- int flags = *reinterpret_cast<int*>(a[3]);
- if (flags & QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite) {
- QDeclarativeData *targetData = QDeclarativeData::get(target);
- if (targetData && targetData->hasBindingBit(d->propertyIndex())) {
- QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::setBinding(target, d->propertyIndex(), d->isValueTypeAlias()?d->valueTypeIndex():-1, 0);
- if (binding) binding->destroy();
- }
- }
- }
-
- if (d->isValueTypeAlias()) {
- // Value type property
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);
-
- QDeclarativeValueType *valueType = ep->valueTypes[d->valueType()];
- Q_ASSERT(valueType);
-
- valueType->read(target, d->propertyIndex());
- int rv = QMetaObject::metacall(valueType, c, d->valueTypeIndex(), a);
-
- if (c == QMetaObject::WriteProperty)
- valueType->write(target, d->propertyIndex(), 0x00);
-
- return rv;
-
- } else {
- return QMetaObject::metacall(target, c, d->propertyIndex(), a);
- }
-
- }
- return -1;
-
- }
-
- } else if(c == QMetaObject::InvokeMetaMethod) {
-
- if (id >= methodOffset) {
-
- id -= methodOffset;
- int plainSignals = metaData->signalCount + metaData->propertyCount +
- metaData->aliasCount;
- if (id < plainSignals) {
- QMetaObject::activate(object, _id, a);
- return -1;
- }
-
- id -= plainSignals;
-
- if (id < metaData->methodCount) {
- if (!ctxt->engine)
- return -1; // We can't run the method
-
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);
- ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
-
- v8::Handle<v8::Function> function = method(id);
- if (function.IsEmpty()) {
- // The function was not compiled. There are some exceptional cases which the
- // expression rewriter does not rewrite properly (e.g., \r-terminated lines
- // are not rewritten correctly but this bug is deemed out-of-scope to fix for
- // performance reasons; see QTBUG-24064) and thus compilation will have failed.
- QDeclarativeError e;
- e.setDescription(QString(QLatin1String("Exception occurred during compilation of function: %1")).
- arg(QLatin1String(QMetaObject::method(_id).signature())));
- ep->warning(e);
- return -1; // The dynamic method with that id is not available.
- }
-
- QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + id;
-
- v8::HandleScope handle_scope;
- v8::Context::Scope scope(ep->v8engine()->context());
- v8::Handle<v8::Value> *args = 0;
-
- if (data->parameterCount) {
- args = new v8::Handle<v8::Value>[data->parameterCount];
- for (int ii = 0; ii < data->parameterCount; ++ii)
- args[ii] = ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1]);
- }
-
- v8::TryCatch try_catch;
-
- v8::Local<v8::Value> result = function->Call(ep->v8engine()->global(), data->parameterCount, args);
-
- QVariant rv;
- if (try_catch.HasCaught()) {
- QDeclarativeError error;
- QDeclarativeExpressionPrivate::exceptionToError(try_catch.Message(), error);
- if (error.isValid())
- ep->warning(error);
- if (a[0]) *(QVariant *)a[0] = QVariant();
- } else {
- if (a[0]) *(QVariant *)a[0] = ep->v8engine()->toVariant(result, 0);
- }
-
- ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
- return -1;
- }
- return -1;
- }
- }
-
- if (parent)
- return parent->metaCall(c, _id, a);
- else
- return object->qt_metacall(c, _id, a);
-}
-
-v8::Handle<v8::Function> QDeclarativeVMEMetaObject::method(int index)
-{
- if (!v8methods)
- v8methods = new v8::Persistent<v8::Function>[metaData->methodCount];
-
- if (v8methods[index].IsEmpty()) {
- QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + index;
-
- const char *body = ((const char*)metaData) + data->bodyOffset;
- int bodyLength = data->bodyLength;
-
- // XXX We should evaluate all methods in a single big script block to
- // improve the call time between dynamic methods defined on the same
- // object
- v8methods[index] = QDeclarativeExpressionPrivate::evalFunction(ctxt, object, body,
- bodyLength,
- ctxt->urlString,
- data->lineNumber);
- }
-
- return v8methods[index];
-}
-
-v8::Handle<v8::Value> QDeclarativeVMEMetaObject::readVarProperty(int id)
-{
- Q_ASSERT(id >= firstVarPropertyIndex);
-
- ensureVarPropertiesAllocated();
- return varProperties->Get(id - firstVarPropertyIndex);
-}
-
-QVariant QDeclarativeVMEMetaObject::readPropertyAsVariant(int id)
-{
- if (id >= firstVarPropertyIndex) {
- ensureVarPropertiesAllocated();
- return QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->toVariant(varProperties->Get(id - firstVarPropertyIndex), -1);
- } else {
- if (data[id].dataType() == QMetaType::QObjectStar) {
- return QVariant::fromValue(data[id].asQObject());
- } else {
- return data[id].asQVariant();
- }
- }
-}
-
-void QDeclarativeVMEMetaObject::writeVarProperty(int id, v8::Handle<v8::Value> value)
-{
- Q_ASSERT(id >= firstVarPropertyIndex);
- ensureVarPropertiesAllocated();
-
- // Importantly, if the current value is a scarce resource, we need to ensure that it
- // gets automatically released by the engine if no other references to it exist.
- v8::Local<v8::Value> oldv = varProperties->Get(id - firstVarPropertyIndex);
- if (oldv->IsObject()) {
- QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(oldv));
- if (r) {
- r->removeVmePropertyReference();
- }
- }
-
- // And, if the new value is a scarce resource, we need to ensure that it does not get
- // automatically released by the engine until no other references to it exist.
- if (value->IsObject()) {
- QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(value));
- if (r) {
- r->addVmePropertyReference();
- }
- }
-
- // Write the value and emit change signal as appropriate.
- varProperties->Set(id - firstVarPropertyIndex, value);
- activate(object, methodOffset + id, 0);
-}
-
-void QDeclarativeVMEMetaObject::writeProperty(int id, const QVariant &value)
-{
- if (id >= firstVarPropertyIndex) {
- ensureVarPropertiesAllocated();
-
- // Importantly, if the current value is a scarce resource, we need to ensure that it
- // gets automatically released by the engine if no other references to it exist.
- v8::Local<v8::Value> oldv = varProperties->Get(id - firstVarPropertyIndex);
- if (oldv->IsObject()) {
- QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(oldv));
- if (r) {
- r->removeVmePropertyReference();
- }
- }
-
- // And, if the new value is a scarce resource, we need to ensure that it does not get
- // automatically released by the engine until no other references to it exist.
- v8::Handle<v8::Value> newv = QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value);
- if (newv->IsObject()) {
- QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(newv));
- if (r) {
- r->addVmePropertyReference();
- }
- }
-
- // Write the value and emit change signal as appropriate.
- QVariant currentValue = readPropertyAsVariant(id);
- varProperties->Set(id - firstVarPropertyIndex, newv);
- if ((currentValue.userType() != value.userType() || currentValue != value))
- activate(object, methodOffset + id, 0);
- } else {
- bool needActivate = false;
- if (value.userType() == QMetaType::QObjectStar) {
- QObject *o = qvariant_cast<QObject *>(value);
- needActivate = (data[id].dataType() != QMetaType::QObjectStar || data[id].asQObject() != o);
- data[id].setValue(qvariant_cast<QObject *>(value));
- } else {
- needActivate = (data[id].dataType() != qMetaTypeId<QVariant>() ||
- data[id].asQVariant().userType() != value.userType() ||
- data[id].asQVariant() != value);
- data[id].setValue(value);
- }
-
- if (needActivate)
- activate(object, methodOffset + id, 0);
- }
-}
-
-void QDeclarativeVMEMetaObject::listChanged(int id)
-{
- activate(object, methodOffset + id, 0);
-}
-
-void QDeclarativeVMEMetaObject::list_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
-{
- List *list = static_cast<List *>(prop->data);
- list->append(o);
- QMetaObject::activate(prop->object, list->notifyIndex, 0);
-}
-
-int QDeclarativeVMEMetaObject::list_count(QDeclarativeListProperty<QObject> *prop)
-{
- return static_cast<List *>(prop->data)->count();
-}
-
-QObject *QDeclarativeVMEMetaObject::list_at(QDeclarativeListProperty<QObject> *prop, int index)
-{
- return static_cast<List *>(prop->data)->at(index);
-}
-
-void QDeclarativeVMEMetaObject::list_clear(QDeclarativeListProperty<QObject> *prop)
-{
- List *list = static_cast<List *>(prop->data);
- list->clear();
- QMetaObject::activate(prop->object, list->notifyIndex, 0);
-}
-
-void QDeclarativeVMEMetaObject::registerInterceptor(int index, int valueIndex, QDeclarativePropertyValueInterceptor *interceptor)
-{
- if (aInterceptors.isEmpty())
- aInterceptors.resize(propertyCount() + metaData->propertyCount);
- aInterceptors.setBit(index);
- interceptors.insert(index, qMakePair(valueIndex, interceptor));
-}
-
-int QDeclarativeVMEMetaObject::vmeMethodLineNumber(int index)
-{
- if (index < methodOffset) {
- Q_ASSERT(parent);
- return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeMethodLineNumber(index);
- }
-
- int plainSignals = metaData->signalCount + metaData->propertyCount + metaData->aliasCount;
- Q_ASSERT(index >= (methodOffset + plainSignals) && index < (methodOffset + plainSignals + metaData->methodCount));
-
- int rawIndex = index - methodOffset - plainSignals;
-
- QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + rawIndex;
- return data->lineNumber;
-}
-
-v8::Handle<v8::Function> QDeclarativeVMEMetaObject::vmeMethod(int index)
-{
- if (index < methodOffset) {
- Q_ASSERT(parent);
- return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeMethod(index);
- }
- int plainSignals = metaData->signalCount + metaData->propertyCount + metaData->aliasCount;
- Q_ASSERT(index >= (methodOffset + plainSignals) && index < (methodOffset + plainSignals + metaData->methodCount));
- return method(index - methodOffset - plainSignals);
-}
-
-// Used by debugger
-void QDeclarativeVMEMetaObject::setVmeMethod(int index, v8::Persistent<v8::Function> value)
-{
- if (index < methodOffset) {
- Q_ASSERT(parent);
- return static_cast<QDeclarativeVMEMetaObject *>(parent)->setVmeMethod(index, value);
- }
- int plainSignals = metaData->signalCount + metaData->propertyCount + metaData->aliasCount;
- Q_ASSERT(index >= (methodOffset + plainSignals) && index < (methodOffset + plainSignals + metaData->methodCount));
-
- if (!v8methods)
- v8methods = new v8::Persistent<v8::Function>[metaData->methodCount];
-
- int methodIndex = index - methodOffset - plainSignals;
- if (!v8methods[methodIndex].IsEmpty())
- qPersistentDispose(v8methods[methodIndex]);
- v8methods[methodIndex] = value;
-}
-
-v8::Handle<v8::Value> QDeclarativeVMEMetaObject::vmeProperty(int index)
-{
- if (index < propOffset) {
- Q_ASSERT(parent);
- return static_cast<QDeclarativeVMEMetaObject *>(parent)->vmeProperty(index);
- }
- return readVarProperty(index - propOffset);
-}
-
-void QDeclarativeVMEMetaObject::setVMEProperty(int index, v8::Handle<v8::Value> v)
-{
- if (index < propOffset) {
- Q_ASSERT(parent);
- static_cast<QDeclarativeVMEMetaObject *>(parent)->setVMEProperty(index, v);
- return;
- }
- return writeVarProperty(index - propOffset, v);
-}
-
-void QDeclarativeVMEMetaObject::ensureVarPropertiesAllocated()
-{
- if (!varPropertiesInitialized)
- allocateVarPropertiesArray();
-}
-
-// see also: QV8GCCallback::garbageCollectorPrologueCallback()
-void QDeclarativeVMEMetaObject::allocateVarPropertiesArray()
-{
- v8::HandleScope handleScope;
- v8::Context::Scope cs(QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->context());
- varProperties = qPersistentNew(v8::Array::New(metaData->varPropertyCount));
- varProperties.MakeWeak(static_cast<void*>(this), VarPropertiesWeakReferenceCallback);
- varPropertiesInitialized = true;
-}
-
-/*
- The "var" properties are stored in a v8::Array which will be strong persistent if the object has cpp-ownership
- and the root QObject in the parent chain does not have JS-ownership. In the weak persistent handle case,
- this callback will dispose the handle when the v8object which owns the lifetime of the var properties array
- is cleared as a result of all other handles to that v8object being released.
- See QV8GCCallback::garbageCollectorPrologueCallback() for more information.
- */
-void QDeclarativeVMEMetaObject::VarPropertiesWeakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter)
-{
- QDeclarativeVMEMetaObject *vmemo = static_cast<QDeclarativeVMEMetaObject*>(parameter);
- Q_ASSERT(vmemo);
- qPersistentDispose(object);
- vmemo->varProperties.Clear();
-}
-
-void QDeclarativeVMEMetaObject::GcPrologueCallback(QV8GCCallback::Node *node)
-{
- QDeclarativeVMEMetaObject *vmemo = static_cast<QDeclarativeVMEMetaObject*>(node);
- Q_ASSERT(vmemo);
- if (!vmemo->varPropertiesInitialized || vmemo->varProperties.IsEmpty() || !vmemo->ctxt || !vmemo->ctxt->engine)
- return;
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(vmemo->ctxt->engine);
- ep->v8engine()->addRelationshipForGC(vmemo->object, vmemo->varProperties);
-}
-
-bool QDeclarativeVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const
-{
- Q_ASSERT(index >= propOffset + metaData->propertyCount);
-
- *target = 0;
- *coreIndex = -1;
- *valueTypeIndex = -1;
-
- if (!ctxt)
- return false;
-
- QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + (index - propOffset - metaData->propertyCount);
- QDeclarativeContext *context = ctxt->asQDeclarativeContext();
- QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context);
-
- *target = ctxtPriv->data->idValues[d->contextIdx].data();
- if (!*target)
- return false;
-
- if (d->isObjectAlias()) {
- } else if (d->isValueTypeAlias()) {
- *coreIndex = d->propertyIndex();
- *valueTypeIndex = d->valueTypeIndex();
- } else {
- *coreIndex = d->propertyIndex();
- }
-
- return true;
-}
-
-void QDeclarativeVMEMetaObject::connectAlias(int aliasId)
-{
- if (!aConnected.testBit(aliasId)) {
-
- if (!aliasEndpoints)
- aliasEndpoints = new QDeclarativeVMEMetaObjectEndpoint[metaData->aliasCount];
-
- aConnected.setBit(aliasId);
-
- QDeclarativeVMEMetaData::AliasData *d = metaData->aliasData() + aliasId;
-
- QDeclarativeVMEMetaObjectEndpoint *endpoint = aliasEndpoints + aliasId;
- endpoint->metaObject = this;
-
- endpoint->connect(&ctxt->idValues[d->contextIdx].bindings);
-
- endpoint->tryConnect();
- }
-}
-
-void QDeclarativeVMEMetaObject::connectAliasSignal(int index)
-{
- int aliasId = (index - methodOffset) - metaData->propertyCount;
- if (aliasId < 0 || aliasId >= metaData->aliasCount)
- return;
-
- connectAlias(aliasId);
-}
-
-QT_END_NAMESPACE