From 26cd94ef47ffc969dc835e98b58eded14e669964 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 15 Mar 2010 15:58:35 +1000 Subject: Optimization: Reduce unnecessary QObject allocations --- src/declarative/qml/qdeclarativebinding.cpp | 19 +- src/declarative/qml/qdeclarativebinding_p.h | 5 +- .../qml/qdeclarativecompiledbindings.cpp | 68 +-- .../qml/qdeclarativecompiledbindings_p.h | 2 +- src/declarative/qml/qdeclarativecompileddata.cpp | 20 - src/declarative/qml/qdeclarativecompiler_p.h | 3 +- src/declarative/qml/qdeclarativecomponent.cpp | 61 +-- src/declarative/qml/qdeclarativecomponent.h | 1 - src/declarative/qml/qdeclarativecomponent_p.h | 10 +- src/declarative/qml/qdeclarativecontext.cpp | 504 +++++++++++---------- src/declarative/qml/qdeclarativecontext.h | 4 +- src/declarative/qml/qdeclarativecontext_p.h | 170 +++++-- .../qml/qdeclarativecontextscriptclass.cpp | 62 ++- .../qml/qdeclarativecontextscriptclass_p.h | 9 +- .../qml/qdeclarativedeclarativedata_p.h | 17 +- src/declarative/qml/qdeclarativeengine.cpp | 33 +- src/declarative/qml/qdeclarativeengine_p.h | 6 +- src/declarative/qml/qdeclarativeenginedebug.cpp | 35 +- src/declarative/qml/qdeclarativeexpression.cpp | 68 +-- src/declarative/qml/qdeclarativeexpression.h | 12 +- src/declarative/qml/qdeclarativeexpression_p.h | 15 +- src/declarative/qml/qdeclarativeinfo.cpp | 3 +- .../qml/qdeclarativeobjectscriptclass.cpp | 18 +- .../qml/qdeclarativeobjectscriptclass_p.h | 6 +- src/declarative/qml/qdeclarativeproperty.cpp | 12 +- src/declarative/qml/qdeclarativeproperty_p.h | 6 +- src/declarative/qml/qdeclarativevme.cpp | 80 +++- src/declarative/qml/qdeclarativevme_p.h | 10 +- src/declarative/qml/qdeclarativevmemetaobject.cpp | 25 +- src/declarative/qml/qdeclarativevmemetaobject_p.h | 3 +- .../util/qdeclarativepropertychanges.cpp | 3 +- 31 files changed, 740 insertions(+), 550 deletions(-) diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index bc78b5b..090bd5b 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -79,14 +79,25 @@ QDeclarativeBindingPrivate::QDeclarativeBindingPrivate() { } -QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, QDeclarativeContext *ctxt, const QString &url, int lineNumber, QObject *parent) +QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, + QDeclarativeContextData *ctxt, const QString &url, int lineNumber, + QObject *parent) : QDeclarativeExpression(ctxt, data, rc, obj, url, lineNumber, *new QDeclarativeBindingPrivate) { setParent(parent); setNotifyOnValueChanged(true); } -QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt, QObject *parent) +QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt, + QObject *parent) +: QDeclarativeExpression(QDeclarativeContextData::get(ctxt), str, obj, *new QDeclarativeBindingPrivate) +{ + setParent(parent); + setNotifyOnValueChanged(true); +} + +QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContextData *ctxt, + QObject *parent) : QDeclarativeExpression(ctxt, str, obj, *new QDeclarativeBindingPrivate) { setParent(parent); @@ -181,8 +192,8 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) } if (data->error.isValid()) { - QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine())? - QDeclarativeEnginePrivate::get(data->context()->engine()):0; + QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine)? + QDeclarativeEnginePrivate::get(data->context()->engine):0; if (!data->addError(p)) qWarning().nospace() << qPrintable(this->error().toString()); } else { diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index 21e3248..533b6d4 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -134,8 +134,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeBinding : public QDeclarativeExpression, Q_OBJECT public: QDeclarativeBinding(const QString &, QObject *, QDeclarativeContext *, QObject *parent=0); - QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContext *, const QString &, int, - QObject *parent); + QDeclarativeBinding(const QString &, QObject *, QDeclarativeContextData *, QObject *parent=0); + QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContextData *, + const QString &, int, QObject *parent); ~QDeclarativeBinding(); void setTarget(const QDeclarativeProperty &); diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index aa549a9..c8bff17 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -142,18 +142,18 @@ public: static int methodCount; void init(); - void run(int instr, QDeclarativeContextPrivate *context, + void run(int instr, QDeclarativeContextData *context, QDeclarativeDelayedError *error, QObject *scope, QObject *output); inline void unsubscribe(int subIndex); - inline void subscribeId(QDeclarativeContextPrivate *p, int idIndex, int subIndex); + inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex); inline void subscribe(QObject *o, int notifyIndex, int subIndex); QDeclarativePropertyCache::Data *findproperty(QObject *obj, - const QScriptDeclarativeClass::Identifier &name, - QDeclarativeEnginePrivate *enginePriv, - QDeclarativePropertyCache::Data &local); + const QScriptDeclarativeClass::Identifier &name, + QDeclarativeEnginePrivate *enginePriv, + QDeclarativePropertyCache::Data &local); bool findproperty(QObject *obj, Register *output, QDeclarativeEnginePrivate *enginePriv, @@ -162,7 +162,7 @@ public: bool isTerminal); void findgeneric(Register *output, // value output int subIdx, // Subscription index in config - QDeclarativeContextPrivate *context, // Context to search in + QDeclarativeContextData *context, // Context to search in const QScriptDeclarativeClass::Identifier &name, bool isTerminal); }; @@ -180,7 +180,7 @@ QDeclarativeCompiledBindingsPrivate::~QDeclarativeCompiledBindingsPrivate() int QDeclarativeCompiledBindingsPrivate::methodCount = -1; -QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContext *context) +QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context) : QObject(*(new QDeclarativeCompiledBindingsPrivate)) { Q_D(QDeclarativeCompiledBindings); @@ -279,17 +279,19 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) if (!binding->enabled) return; - QDeclarativeContext *context = q->QDeclarativeAbstractExpression::context(); + QDeclarativeContextData *context = q->QDeclarativeAbstractExpression::context(); if (!context) { qWarning("QDeclarativeCompiledBindings: Attempted to evaluate an expression in an invalid context"); return; } - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(context); + + if (!context->engine) + return; if (binding->updating) { QString name; if (binding->property & 0xFFFF0000) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(cp->engine); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; Q_ASSERT(vt); @@ -298,7 +300,7 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) name.append(QLatin1String(".")); name.append(QLatin1String(vt->metaObject()->property(binding->property >> 24).name())); } else { - name = binding->target->metaObject()->property(binding->property).name(); + name = QLatin1String(binding->target->metaObject()->property(binding->property).name()); } qmlInfo(binding->target) << QCoreApplication::translate("QDeclarativeCompiledBindings", "Binding loop detected for property \"%1\"").arg(name); return; @@ -306,19 +308,19 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding) binding->updating = true; if (binding->property & 0xFFFF0000) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(cp->engine); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; Q_ASSERT(vt); vt->read(binding->target, binding->property & 0xFFFF); QObject *target = vt; - run(binding->index, cp, binding, binding->scope, target); + run(binding->index, context, binding, binding->scope, target); vt->write(binding->target, binding->property & 0xFFFF, QDeclarativePropertyPrivate::DontRemoveBinding); } else { - run(binding->index, cp, binding, binding->scope, binding->target); + run(binding->index, context, binding, binding->scope, binding->target); } binding->updating = false; } @@ -630,13 +632,11 @@ struct QDeclarativeBindingCompilerPrivate void QDeclarativeCompiledBindingsPrivate::unsubscribe(int subIndex) { - Q_Q(QDeclarativeCompiledBindings); - QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex); sub->disconnect(); } -void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextPrivate *p, int idIndex, int subIndex) +void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex) { Q_Q(QDeclarativeCompiledBindings); @@ -710,7 +710,7 @@ inline static bool toBool(Register *reg, int type, bool *ok = 0) } } -inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextPrivate *context, bool *ok = 0) +inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *context, bool *ok = 0) { if (ok) *ok = true; @@ -828,7 +828,7 @@ bool QDeclarativeCompiledBindingsPrivate::findproperty(QObject *obj, Register *o void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, int subIdx, - QDeclarativeContextPrivate *context, + QDeclarativeContextData *context, const QScriptDeclarativeClass::Identifier &name, bool isTerminal) { @@ -841,14 +841,17 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, if (contextPropertyIndex != -1) { - if (subIdx != -1) - subscribe(QDeclarativeContextPrivate::get(context), contextPropertyIndex + context->notifyIndex, subIdx); - if (contextPropertyIndex < context->idValueCount) { output->setQObject(context->idValues[contextPropertyIndex]); output->settype(QMetaType::QObjectStar); + + if (subIdx != -1) + subscribeId(context, contextPropertyIndex, subIdx); + } else { - const QVariant &value = context->propertyValues.at(contextPropertyIndex); + QDeclarativeContextPrivate *cp = context->asQDeclarativeContextPrivate(); + const QVariant &value = cp->propertyValues.at(contextPropertyIndex); + if (isTerminal) { new (output->typeDataPtr()) QVariant(value); output->settype(qMetaTypeId()); @@ -859,6 +862,11 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, else { output->settype(QMetaType::QObjectStar); } return; } + + if (subIdx != -1) + subscribe(context->asQDeclarativeContext(), contextPropertyIndex + cp->notifyIndex, subIdx); + + } return; @@ -878,11 +886,7 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output, } - if (context->parent) { - context = QDeclarativeContextPrivate::get(context->parent); - } else { - context = 0; - } + context = context->parent; } output->setUndefined(); @@ -901,7 +905,7 @@ void QDeclarativeCompiledBindingsPrivate::init() } static void throwException(int id, QDeclarativeDelayedError *error, - Program *program, QDeclarativeContextPrivate *context, + Program *program, QDeclarativeContextData *context, const QString &description = QString()) { error->error.setUrl(context->url); @@ -1063,8 +1067,8 @@ static void dumpInstruction(const Instr *instr) } void QDeclarativeCompiledBindingsPrivate::run(int instrIndex, - QDeclarativeContextPrivate *context, QDeclarativeDelayedError *error, - QObject *scope, QObject *output) + QDeclarativeContextData *context, QDeclarativeDelayedError *error, + QObject *scope, QObject *output) { error->removeError(); @@ -1398,7 +1402,7 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex, // name is not present in the current context or it would have been // found during the static compile findgeneric(registers + instr->find.reg, instr->find.subscribeIndex, - QDeclarativeContextPrivate::get(context->parent), + context->parent, identifiers[instr->find.name].identifier, instr->common.type == Instr::FindGenericTerminal); break; diff --git a/src/declarative/qml/qdeclarativecompiledbindings_p.h b/src/declarative/qml/qdeclarativecompiledbindings_p.h index 2e24371..84a5df9 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings_p.h +++ b/src/declarative/qml/qdeclarativecompiledbindings_p.h @@ -95,7 +95,7 @@ class QDeclarativeCompiledBindingsPrivate; class QDeclarativeCompiledBindings : public QObject, public QDeclarativeAbstractExpression, public QDeclarativeRefCount { public: - QDeclarativeCompiledBindings(const char *program, QDeclarativeContext *context); + QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context); virtual ~QDeclarativeCompiledBindings(); QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property); diff --git a/src/declarative/qml/qdeclarativecompileddata.cpp b/src/declarative/qml/qdeclarativecompileddata.cpp index 30f9510..dfbf453 100644 --- a/src/declarative/qml/qdeclarativecompileddata.cpp +++ b/src/declarative/qml/qdeclarativecompileddata.cpp @@ -199,26 +199,6 @@ void QDeclarativeCompiledData::clear() cachedPrograms[ii] = 0; } - -QObject *QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContext *ctxt, const QBitField &bindings) const -{ - if (type) { - QObject *rv = 0; - void *memory = 0; - - type->create(&rv, &memory, sizeof(QDeclarativeDeclarativeData)); - QDeclarativeDeclarativeData *ddata = new (memory) QDeclarativeDeclarativeData; - ddata->ownMemory = false; - QObjectPrivate::get(rv)->declarativeData = ddata; - QDeclarativeEngine::setContextForObject(rv, ctxt); - - return rv; - } else { - Q_ASSERT(component); - return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings); - } -} - const QMetaObject *QDeclarativeCompiledData::TypeReference::metaObject() const { if (type) { diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index cca42e2..05b556e 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -72,6 +72,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QDeclarativeComponent; class QDeclarativeContext; +class QDeclarativeContextData; class QScriptProgram; class Q_AUTOTEST_EXPORT QDeclarativeCompiledData : public QDeclarativeRefCount, public QDeclarativeCleanup @@ -95,7 +96,7 @@ public: QDeclarativeComponent *component; QDeclarativeRefCount *ref; - QObject *createInstance(QDeclarativeContext *, const QBitField &) const; + QObject *createInstance(QDeclarativeContextData *, const QBitField &) const; const QMetaObject *metaObject() const; }; QList types; diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 07cdd6d..ffbd0fa 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -404,23 +404,12 @@ QDeclarativeContext *QDeclarativeComponent::creationContext() const { Q_D(const QDeclarativeComponent); if(d->creationContext) - return d->creationContext; + return d->creationContext->asQDeclarativeContext(); return qmlContext(this); } /*! - \internal - Sets the QDeclarativeContext the component was created in. This is only - desirable for components created in QML script. -*/ -void QDeclarativeComponent::setCreationContext(QDeclarativeContext* c) -{ - Q_D(QDeclarativeComponent); - d->creationContext = c; -} - -/*! Load the QDeclarativeComponent from the provided \a url. */ void QDeclarativeComponent::loadUrl(const QUrl &url) @@ -547,16 +536,11 @@ QObject *QDeclarativeComponent::create(QDeclarativeContext *context) return rv; } -QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context, - const QBitField &bindings) +QObject *QDeclarativeComponentPrivate::create(QDeclarativeContextData *context, + const QBitField &bindings) { if (!context) - context = engine->rootContext(); - - if (context->engine() != engine) { - qWarning("QDeclarativeComponent::create(): Must create component in context from the same QDeclarativeEngine"); - return 0; - } + context = QDeclarativeContextData::get(engine->rootContext()); QObject *rv = beginCreate(context, bindings); completeCreate(); @@ -589,7 +573,7 @@ QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context, QObject *QDeclarativeComponent::beginCreate(QDeclarativeContext *context) { Q_D(QDeclarativeComponent); - QObject *rv = d->beginCreate(context, QBitField()); + QObject *rv = d->beginCreate(context?QDeclarativeContextData::get(context):0, QBitField()); if (rv) { QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(rv); Q_ASSERT(ddata); @@ -599,7 +583,7 @@ QObject *QDeclarativeComponent::beginCreate(QDeclarativeContext *context) } QObject * -QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QBitField &bindings) +QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, const QBitField &bindings) { Q_Q(QDeclarativeComponent); if (!context) { @@ -607,7 +591,7 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QB return 0; } - if (context->engine() != engine) { + if (context->engine != engine) { qWarning("QDeclarativeComponent::beginCreate(): Must create component in context from the same QDeclarativeEngine"); return 0; } @@ -624,29 +608,26 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QB QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *contextPriv = - static_cast(QObjectPrivate::get(context)); - QDeclarativeContext *ctxt = new QDeclarativeContext(context, 0, true); - static_cast(ctxt->d_func())->url = cc->url; - static_cast(ctxt->d_func())->imports = cc->importCache; + QDeclarativeContextData *ctxt = new QDeclarativeContextData; + ctxt->isInternal = true; + ctxt->url = cc->url; + ctxt->imports = cc->importCache; cc->importCache->addref(); + ctxt->setParent(context); QObject *rv = begin(ctxt, ep, cc, start, count, &state, bindings); - if (rv) { - QDeclarative_setParent_noEvent(ctxt, rv); - } else { - delete ctxt; - } + if (!rv) ctxt->destroy(); + + if (rv && !context->isInternal && ep->isDebugging) + context->asQDeclarativeContextPrivate()->instances.append(rv); - if (rv && !contextPriv->isInternal && ep->isDebugging) - contextPriv->instances.append(rv); return rv; } -QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv, - QDeclarativeCompiledData *component, int start, int count, - ConstructionState *state, const QBitField &bindings) +QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, + QDeclarativeCompiledData *component, int start, int count, + ConstructionState *state, const QBitField &bindings) { bool isRoot = !enginePriv->inBeginCreate; enginePriv->inBeginCreate = true; @@ -676,8 +657,8 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContext *ctxt, QDeclar return rv; } -void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContext *, QDeclarativeEnginePrivate *enginePriv, - QObject *object, ConstructionState *state) +void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContextData *, QDeclarativeEnginePrivate *enginePriv, + QObject *object, ConstructionState *state) { bool isRoot = !enginePriv->inBeginCreate; enginePriv->inBeginCreate = true; diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h index aec0480..13a243e 100644 --- a/src/declarative/qml/qdeclarativecomponent.h +++ b/src/declarative/qml/qdeclarativecomponent.h @@ -104,7 +104,6 @@ public: void loadUrl(const QUrl &url); void setData(const QByteArray &, const QUrl &baseUrl); - void setCreationContext(QDeclarativeContext*); QDeclarativeContext *creationContext() const; static QDeclarativeComponentAttached *qmlAttachedProperties(QObject *); diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 3155813..649fce5 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -81,8 +81,8 @@ class QDeclarativeComponentPrivate : public QObjectPrivate public: QDeclarativeComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), engine(0), creationContext(0) {} - QObject *create(QDeclarativeContext *context, const QBitField &); - QObject *beginCreate(QDeclarativeContext *, const QBitField &); + QObject *create(QDeclarativeContextData *, const QBitField &); + QObject *beginCreate(QDeclarativeContextData *, const QBitField &); void completeCreate(); QDeclarativeCompositeTypeData *typeData; @@ -108,15 +108,15 @@ public: }; ConstructionState state; - static QObject *begin(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv, + static QObject *begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, QDeclarativeCompiledData *component, int start, int count, ConstructionState *state, const QBitField &bindings = QBitField()); - static void beginDeferred(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv, + static void beginDeferred(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv, QObject *object, ConstructionState *state); static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state); QDeclarativeEngine *engine; - QDeclarativeContext *creationContext; + QDeclarativeContextData *creationContext; void clear(); diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 06637d8..f1c961d 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -58,85 +58,13 @@ QT_BEGIN_NAMESPACE QDeclarativeContextPrivate::QDeclarativeContextPrivate() -: parent(0), engine(0), isInternal(false), propertyNames(0), - notifyIndex(-1), contextObject(0), imports(0), childContexts(0), - nextChild(0), prevChild(0), expressions(0), contextObjects(0), - idValues(0), idValueCount(0), optimizedBindings(0) +: data(0), notifyIndex(-1) { } -void QDeclarativeContextPrivate::addScript(const QDeclarativeParser::Object::ScriptBlock &script, - QObject *scopeObject) -{ - Q_Q(QDeclarativeContext); - - if (!engine) - return; - - QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); - QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); - - QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); - - scriptContext->pushScope(enginePriv->contextClass->newContext(q, scopeObject)); - scriptContext->pushScope(enginePriv->globalClass->globalObject()); - - QScriptValue scope = scriptEngine->newObject(); - scriptContext->setActivationObject(scope); - scriptContext->pushScope(scope); - - for (int ii = 0; ii < script.codes.count(); ++ii) { - scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii)); - - if (scriptEngine->hasUncaughtException()) { - QDeclarativeError error; - QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); - qWarning().nospace() << qPrintable(error.toString()); - } - } - - scriptEngine->popContext(); - - scripts.append(scope); -} - -void QDeclarativeContextPrivate::destroyed(ContextGuard *guard) -{ - Q_Q(QDeclarativeContext); - - // process of being deleted (which is *probably* why obj has been destroyed - // anyway), as we're about to get deleted which will invalidate all the - // expressions that could depend on us - QObject *parent = q->parent(); - if (parent && QObjectPrivate::get(parent)->wasDeleted) - return; - - guard->bindings.notify(); - - for (int ii = 0; ii < idValueCount; ++ii) { - if (&idValues[ii] == guard) { - QMetaObject::activate(q, ii + notifyIndex, 0); - return; - } - } -} - -void QDeclarativeContextPrivate::init() -{ - Q_Q(QDeclarativeContext); - - if (parent) { - QDeclarativeContextPrivate *ppriv = parent->d_func(); - nextChild = ppriv->childContexts; - if (nextChild) nextChild->d_func()->prevChild = &nextChild; - prevChild = &ppriv->childContexts; - ppriv->childContexts = q; - } -} - /*! \class QDeclarativeContext - \since 4.7 + \since 4.7 \brief The QDeclarativeContext class defines a context within a QML engine. \mainclass @@ -223,8 +151,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeEngine *e, bool) : QObject(*(new QDeclarativeContextPrivate)) { Q_D(QDeclarativeContext); - d->engine = e; - d->init(); + d->data = new QDeclarativeContextData(this); + + d->data->engine = e; } /*! @@ -235,10 +164,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeEngine *engine, QObject *pa : QObject(*(new QDeclarativeContextPrivate), parent) { Q_D(QDeclarativeContext); - QDeclarativeContext *parentContext = engine?engine->rootContext():0; - d->parent = parentContext; - d->engine = parentContext->engine(); - d->init(); + d->data = new QDeclarativeContextData(this); + + d->data->setParent(engine?QDeclarativeContextData::get(engine->rootContext()):0); } /*! @@ -249,22 +177,19 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QOb : QObject(*(new QDeclarativeContextPrivate), parent) { Q_D(QDeclarativeContext); - d->parent = parentContext; - d->engine = parentContext->engine(); - d->init(); + d->data = new QDeclarativeContextData(this); + + d->data->setParent(parentContext?QDeclarativeContextData::get(parentContext):0); } /*! \internal */ -QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QObject *parent, bool) -: QObject(*(new QDeclarativeContextPrivate), parent) +QDeclarativeContext::QDeclarativeContext(QDeclarativeContextData *data) +: QObject(*(new QDeclarativeContextPrivate), 0) { Q_D(QDeclarativeContext); - d->parent = parentContext; - d->engine = parentContext->engine(); - d->isInternal = true; - d->init(); + d->data = data; } /*! @@ -278,90 +203,8 @@ QDeclarativeContext::~QDeclarativeContext() { Q_D(QDeclarativeContext); - if (d->prevChild) { - *d->prevChild = d->nextChild; - if (d->nextChild) d->nextChild->d_func()->prevChild = d->prevChild; - d->nextChild = 0; - d->prevChild = 0; - } - - QDeclarativeContext *child = d->childContexts; - while (child) { - QDeclarativeContextPrivate *childpriv = child->d_func(); - childpriv->invalidateEngines(); - childpriv->parent = 0; - child = childpriv->nextChild; - childpriv->nextChild = 0; - childpriv->prevChild = 0; - } - d->childContexts = 0; - - QDeclarativeAbstractExpression *expression = d->expressions; - while (expression) { - QDeclarativeAbstractExpression *nextExpression = expression->m_nextExpression; - - expression->m_context = 0; - expression->m_prevExpression = 0; - expression->m_nextExpression = 0; - - expression = nextExpression; - } - - while (d->contextObjects) { - QDeclarativeDeclarativeData *co = d->contextObjects; - d->contextObjects = d->contextObjects->nextContextObject; - - co->context = 0; - co->outerContext = 0; - co->nextContextObject = 0; - co->prevContextObject = 0; - } - - if (d->propertyNames) - d->propertyNames->release(); - - if (d->imports) - d->imports->release(); - - if (d->optimizedBindings) - d->optimizedBindings->release(); - - delete [] d->idValues; -} - -void QDeclarativeContextPrivate::invalidateEngines() -{ - if (!engine) - return; - engine = 0; - - QDeclarativeContext *child = childContexts; - while (child) { - QDeclarativeContextPrivate *childpriv = child->d_func(); - childpriv->invalidateEngines(); - child = childpriv->nextChild; - } -} - -/* -Refreshes all expressions that could possibly depend on this context. -Refreshing flushes all context-tree dependent caches in the expressions, and should occur every -time the context tree *structure* (not values) changes. -*/ -void QDeclarativeContextPrivate::refreshExpressions() -{ - QDeclarativeContext *child = childContexts; - while (child) { - QDeclarativeContextPrivate *childpriv = child->d_func(); - childpriv->refreshExpressions(); - child = childpriv->nextChild; - } - - QDeclarativeAbstractExpression *expression = expressions; - while (expression) { - expression->refresh(); - expression = expression->m_nextExpression; - } + if (!d->data->isInternal) + d->data->destroy(); } /*! @@ -371,7 +214,7 @@ void QDeclarativeContextPrivate::refreshExpressions() QDeclarativeEngine *QDeclarativeContext::engine() const { Q_D(const QDeclarativeContext); - return d->engine; + return d->data->engine; } /*! @@ -381,7 +224,7 @@ QDeclarativeEngine *QDeclarativeContext::engine() const QDeclarativeContext *QDeclarativeContext::parentContext() const { Q_D(const QDeclarativeContext); - return d->parent; + return d->data->parent?d->data->parent->asQDeclarativeContext():0; } /*! @@ -390,7 +233,7 @@ QDeclarativeContext *QDeclarativeContext::parentContext() const QObject *QDeclarativeContext::contextObject() const { Q_D(const QDeclarativeContext); - return d->contextObject; + return d->data->contextObject; } /*! @@ -399,7 +242,7 @@ QObject *QDeclarativeContext::contextObject() const void QDeclarativeContext::setContextObject(QObject *object) { Q_D(QDeclarativeContext); - d->contextObject = object; + d->data->contextObject = object; } /*! @@ -411,50 +254,31 @@ void QDeclarativeContext::setContextProperty(const QString &name, const QVariant if (d->notifyIndex == -1) d->notifyIndex = this->metaObject()->methodCount(); - if (d->engine) { + QDeclarativeContextData *data = d->data; + + if (data->engine) { bool ok; - QObject *o = QDeclarativeEnginePrivate::get(d->engine)->toQObject(value, &ok); + QObject *o = QDeclarativeEnginePrivate::get(data->engine)->toQObject(value, &ok); if (ok) { setContextProperty(name, o); return; } } - if (!d->propertyNames) d->propertyNames = new QDeclarativeIntegerCache(d->engine); + if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine); - int idx = d->propertyNames->value(name); + int idx = data->propertyNames->value(name); if (idx == -1) { - d->propertyNames->add(name, d->idValueCount + d->propertyValues.count()); + data->propertyNames->add(name, data->idValueCount + d->propertyValues.count()); d->propertyValues.append(value); - d->refreshExpressions(); + data->refreshExpressions(); } else { d->propertyValues[idx] = value; QMetaObject::activate(this, idx + d->notifyIndex, 0); } } -void QDeclarativeContextPrivate::setIdProperty(int idx, QObject *obj) -{ - if (notifyIndex == -1) { - Q_Q(QDeclarativeContext); - notifyIndex = q->metaObject()->methodCount(); - } - - idValues[idx].priv = this; - idValues[idx] = obj; -} - -void QDeclarativeContextPrivate::setIdPropertyData(QDeclarativeIntegerCache *data) -{ - Q_ASSERT(!propertyNames); - propertyNames = data; - propertyNames->addref(); - - idValueCount = data->count(); - idValues = new ContextGuard[idValueCount]; -} - /*! Set the \a value of the \a name property on this context. @@ -466,14 +290,16 @@ void QDeclarativeContext::setContextProperty(const QString &name, QObject *value if (d->notifyIndex == -1) d->notifyIndex = this->metaObject()->methodCount(); - if (!d->propertyNames) d->propertyNames = new QDeclarativeIntegerCache(d->engine); - int idx = d->propertyNames->value(name); + QDeclarativeContextData *data = d->data; + + if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine); + int idx = data->propertyNames->value(name); if (idx == -1) { - d->propertyNames->add(name, d->idValueCount + d->propertyValues.count()); + data->propertyNames->add(name, data->idValueCount + d->propertyValues.count()); d->propertyValues.append(QVariant::fromValue(value)); - d->refreshExpressions(); + data->refreshExpressions(); } else { d->propertyValues[idx] = QVariant::fromValue(value); QMetaObject::activate(this, idx + d->notifyIndex, 0); @@ -489,15 +315,19 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const Q_D(const QDeclarativeContext); QVariant value; int idx = -1; - if (d->propertyNames) - idx = d->propertyNames->value(name); + + QDeclarativeContextData *data = d->data; + + if (data->propertyNames) + idx = data->propertyNames->value(name); if (idx == -1) { QByteArray utf8Name = name.toUtf8(); - if (d->contextObject) { - QObject *obj = d->contextObject; + if (data->contextObject) { + QObject *obj = data->contextObject; QDeclarativePropertyCache::Data local; - QDeclarativePropertyCache::Data *property = QDeclarativePropertyCache::property(d->engine, obj, name, local); + QDeclarativePropertyCache::Data *property = + QDeclarativePropertyCache::property(data->engine, obj, name, local); if (property) value = obj->metaObject()->property(property->coreIndex).read(obj); } @@ -505,7 +335,7 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const value = parentContext()->contextProperty(name); } else { if (idx >= d->propertyValues.count()) - value = QVariant::fromValue(d->idValues[idx - d->propertyValues.count()].data()); + value = QVariant::fromValue(data->idValues[idx - d->propertyValues.count()].data()); else value = d->propertyValues[idx]; } @@ -522,20 +352,26 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const QUrl QDeclarativeContext::resolvedUrl(const QUrl &src) { Q_D(QDeclarativeContext); - QDeclarativeContext *ctxt = this; + return d->data->resolvedUrl(src); +} + +QUrl QDeclarativeContextData::resolvedUrl(const QUrl &src) +{ + QDeclarativeContextData *ctxt = this; + if (src.isRelative() && !src.isEmpty()) { if (ctxt) { while(ctxt) { - if(ctxt->d_func()->url.isValid()) + if(ctxt->url.isValid()) break; else - ctxt = ctxt->parentContext(); + ctxt = ctxt->parent; } if (ctxt) - return ctxt->d_func()->url.resolved(src); - else if (d->engine) - return d->engine->baseUrl().resolved(src); + return ctxt->url.resolved(src); + else if (engine) + return engine->baseUrl().resolved(src); } return QUrl(); } else { @@ -543,6 +379,7 @@ QUrl QDeclarativeContext::resolvedUrl(const QUrl &src) } } + /*! Explicitly sets the url resolvedUrl() will use for relative references to \a baseUrl. @@ -553,7 +390,9 @@ QUrl QDeclarativeContext::resolvedUrl(const QUrl &src) */ void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl) { - d_func()->url = baseUrl; + Q_D(QDeclarativeContext); + + d->data->url = baseUrl; } /*! @@ -562,12 +401,13 @@ void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl) */ QUrl QDeclarativeContext::baseUrl() const { - const QDeclarativeContext* p = this; - while (p && p->d_func()->url.isEmpty()) { - p = p->parentContext(); - } - if (p) - return p->d_func()->url; + Q_D(const QDeclarativeContext); + const QDeclarativeContextData* data = d->data; + while (data && data->url.isEmpty()) + data = data->parent; + + if (data) + return data->url; else return QUrl(); } @@ -598,4 +438,214 @@ QObject *QDeclarativeContextPrivate::context_at(QDeclarativeListPropertydestroy(); + + if (prevChild) { + *prevChild = nextChild; + if (nextChild) nextChild->prevChild = prevChild; + nextChild = 0; + prevChild = 0; + } + + QDeclarativeContextData *child = childContexts; + while (child) { + QDeclarativeContextData *next = child->nextChild; + + child->invalidateEngines(); + child->parent = 0; + child->nextChild = 0; + child->prevChild = 0; + + child = next; + } + childContexts = 0; + + QDeclarativeAbstractExpression *expression = expressions; + while (expression) { + QDeclarativeAbstractExpression *nextExpression = expression->m_nextExpression; + + expression->m_context = 0; + expression->m_prevExpression = 0; + expression->m_nextExpression = 0; + + expression = nextExpression; + } + expressions = 0; + + while (contextObjects) { + QDeclarativeDeclarativeData *co = contextObjects; + contextObjects = contextObjects->nextContextObject; + + co->context = 0; + co->outerContext = 0; + co->nextContextObject = 0; + co->prevContextObject = 0; + } + + QDeclarativeGuardedContextData *contextGuard = contextGuards; + while (contextGuard) { + QDeclarativeGuardedContextData *next = contextGuard->m_next; + contextGuard->m_next = 0; + contextGuard->m_prev = 0; + contextGuard->m_contextData = 0; + contextGuard = next; + } + contextGuards = 0; + + if (propertyNames) + propertyNames->release(); + + if (imports) + imports->release(); + + if (optimizedBindings) + optimizedBindings->release(); + + delete [] idValues; + + if (isInternal) + delete publicContext; + + delete this; +} + +void QDeclarativeContextData::setParent(QDeclarativeContextData *p) +{ + if (p) { + parent = p; + engine = p->engine; + nextChild = p->childContexts; + if (nextChild) nextChild->prevChild = &nextChild; + prevChild = &p->childContexts; + p->childContexts = this; + } +} + +void QDeclarativeContextData::invalidateEngines() +{ + if (!engine) + return; + engine = 0; + + QDeclarativeContextData *child = childContexts; + while (child) { + child->invalidateEngines(); + child = child->nextChild; + } +} + +/* +Refreshes all expressions that could possibly depend on this context. Refreshing flushes all +context-tree dependent caches in the expressions, and should occur every time the context tree + *structure* (not values) changes. +*/ +void QDeclarativeContextData::refreshExpressions() +{ + QDeclarativeContextData *child = childContexts; + while (child) { + child->refreshExpressions(); + child = child->nextChild; + } + + QDeclarativeAbstractExpression *expression = expressions; + while (expression) { + expression->refresh(); + expression = expression->m_nextExpression; + } +} + +void QDeclarativeContextData::addObject(QObject *o) +{ + QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(o, true); + + Q_ASSERT(data->context == 0); + + data->context = this; + data->outerContext = this; + + data->nextContextObject = contextObjects; + if (data->nextContextObject) + data->nextContextObject->prevContextObject = &data->nextContextObject; + data->prevContextObject = &contextObjects; + contextObjects = data; +} + +void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::ScriptBlock &script, + QObject *scopeObject) +{ + if (!engine) + return; + + QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); + QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); + + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->contextClass->newContext(this, scopeObject)); + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + for (int ii = 0; ii < script.codes.count(); ++ii) { + scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii)); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + } + + scriptEngine->popContext(); + + scripts.append(scope); +} + +void QDeclarativeContextData::setIdProperty(int idx, QObject *obj) +{ + idValues[idx] = obj; +} + +void QDeclarativeContextData::setIdPropertyData(QDeclarativeIntegerCache *data) +{ + Q_ASSERT(!propertyNames); + propertyNames = data; + propertyNames->addref(); + + idValueCount = data->count(); + idValues = new ContextGuard[idValueCount]; +} + +QDeclarativeContext *QDeclarativeContextData::asQDeclarativeContext() +{ + if (!publicContext) + publicContext = new QDeclarativeContext(this); + return publicContext; +} + +QDeclarativeContextPrivate *QDeclarativeContextData::asQDeclarativeContextPrivate() +{ + return QDeclarativeContextPrivate::get(asQDeclarativeContext()); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h index 3ad9863..a349628 100644 --- a/src/declarative/qml/qdeclarativecontext.h +++ b/src/declarative/qml/qdeclarativecontext.h @@ -58,6 +58,7 @@ class QDeclarativeEngine; class QDeclarativeRefCount; class QDeclarativeContextPrivate; class QDeclarativeCompositeTypeData; +class QDeclarativeContextData; class Q_DECLARATIVE_EXPORT QDeclarativeContext : public QObject { @@ -96,7 +97,8 @@ private: friend class QDeclarativeComponentPrivate; friend class QDeclarativeScriptPrivate; friend class QDeclarativeBoundSignalProxy; - QDeclarativeContext(QDeclarativeContext *parent, QObject *objParent, bool); + friend class QDeclarativeContextData; + QDeclarativeContext(QDeclarativeContextData *); QDeclarativeContext(QDeclarativeEngine *, bool); }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index a1056b1..59b848f 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -56,10 +56,11 @@ #include "qdeclarativecontext.h" #include "qdeclarativedeclarativedata_p.h" -#include "qdeclarativeengine_p.h" #include "qdeclarativeintegercache_p.h" #include "qdeclarativetypenamecache_p.h" #include "qdeclarativenotifier_p.h" +#include "qdeclarativelist.h" +#include "qdeclarativeparser_p.h" #include #include @@ -78,6 +79,7 @@ class QDeclarativeExpressionPrivate; class QDeclarativeAbstractExpression; class QDeclarativeBinding_Id; class QDeclarativeCompiledBindings; +class QDeclarativeContextData; class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate { @@ -85,82 +87,178 @@ class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate public: QDeclarativeContextPrivate(); - QDeclarativeContext *parent; + QDeclarativeContextData *data; + + QList propertyValues; + int notifyIndex; + + static QDeclarativeContextPrivate *get(QDeclarativeContext *context) { + return static_cast(QObjectPrivate::get(context)); + } + static QDeclarativeContext *get(QDeclarativeContextPrivate *context) { + return static_cast(context->q_func()); + } + + // Only used for debugging + QList > instances; + + static int context_count(QDeclarativeListProperty *); + static QObject *context_at(QDeclarativeListProperty *, int); +}; + +class QDeclarativeGuardedContextData; +class QDeclarativeContextData +{ +public: + QDeclarativeContextData(); + QDeclarativeContextData(QDeclarativeContext *); + void destroy(); + + // My parent context and engine + QDeclarativeContextData *parent; QDeclarativeEngine *engine; + void setParent(QDeclarativeContextData *); + void invalidateEngines(); + void refreshExpressions(); + + void addObject(QObject *); + + QUrl resolvedUrl(const QUrl &); + + // My containing QDeclarativeContext. If isInternal is true this owns publicContext. + // If internal is false publicContext owns this. + QDeclarativeContext *asQDeclarativeContext(); + QDeclarativeContextPrivate *asQDeclarativeContextPrivate(); bool isInternal; + QDeclarativeContext *publicContext; + // Property name cache QDeclarativeIntegerCache *propertyNames; - QList propertyValues; - int notifyIndex; + // Context object QObject *contextObject; + // Any script blocks that exist on this context QList scripts; - void addScript(const QDeclarativeParser::Object::ScriptBlock &, QObject *); + void addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject); + // Context base url QUrl url; + // List of imports that apply to this context QDeclarativeTypeNameCache *imports; - void init(); - - void invalidateEngines(); - void refreshExpressions(); - - QDeclarativeContext *childContexts; + // My children + QDeclarativeContextData *childContexts; - QDeclarativeContext *nextChild; - QDeclarativeContext **prevChild; + // My peers in parent's childContexts list + QDeclarativeContextData *nextChild; + QDeclarativeContextData **prevChild; + // Expressions that use this context QDeclarativeAbstractExpression *expressions; + // Doubly-linked list of objects that are owned by this context QDeclarativeDeclarativeData *contextObjects; + // Doubly-linked list of context guards (XXX merge with contextObjects) + QDeclarativeGuardedContextData *contextGuards; + + // id guards struct ContextGuard : public QDeclarativeGuard { - inline ContextGuard(); - inline ContextGuard &operator=(QObject *obj); - inline virtual void objectDestroyed(QObject *); - - QDeclarativeContextPrivate *priv; + inline ContextGuard &operator=(QObject *obj) + { QDeclarativeGuard::operator=(obj); return *this; } + virtual void objectDestroyed(QObject *) { bindings.notify(); } QDeclarativeNotifier bindings; }; ContextGuard *idValues; int idValueCount; void setIdProperty(int, QObject *); void setIdPropertyData(QDeclarativeIntegerCache *); - void destroyed(ContextGuard *); - static QDeclarativeContextPrivate *get(QDeclarativeContext *context) { - return static_cast(QObjectPrivate::get(context)); - } - static QDeclarativeContext *get(QDeclarativeContextPrivate *context) { - return static_cast(context->q_func()); + // Optimized binding pointer + QDeclarativeCompiledBindings *optimizedBindings; + + // Linked contexts. this owns linkedContext. + QDeclarativeContextData *linkedContext; + + static QDeclarativeContextData *get(QDeclarativeContext *context) { + return QDeclarativeContextPrivate::get(context)->data; } - QDeclarativeCompiledBindings *optimizedBindings; +private: + ~QDeclarativeContextData() {} +}; - // Only used for debugging - QList > instances; +class QDeclarativeGuardedContextData +{ +public: + inline QDeclarativeGuardedContextData(); + inline QDeclarativeGuardedContextData(QDeclarativeContextData *); + inline ~QDeclarativeGuardedContextData(); - static int context_count(QDeclarativeListProperty *); - static QObject *context_at(QDeclarativeListProperty *, int); + inline void setContextData(QDeclarativeContextData *); + + inline QDeclarativeContextData *contextData(); + + inline operator QDeclarativeContextData*() const { return m_contextData; } + inline QDeclarativeContextData* operator->() const { return m_contextData; } + +private: + friend class QDeclarativeContextData; + + inline void clear(); + + QDeclarativeContextData *m_contextData; + QDeclarativeGuardedContextData *m_next; + QDeclarativeGuardedContextData **m_prev; }; -QDeclarativeContextPrivate::ContextGuard::ContextGuard() -: priv(0) +QDeclarativeGuardedContextData::QDeclarativeGuardedContextData() +: m_contextData(0), m_next(0), m_prev(0) +{ +} + +QDeclarativeGuardedContextData::QDeclarativeGuardedContextData(QDeclarativeContextData *data) +: m_contextData(0), m_next(0), m_prev(0) +{ + setContextData(data); +} + +QDeclarativeGuardedContextData::~QDeclarativeGuardedContextData() +{ + clear(); +} + +void QDeclarativeGuardedContextData::setContextData(QDeclarativeContextData *contextData) { + clear(); + + if (contextData) { + m_contextData = contextData; + m_next = contextData->contextGuards; + if (m_next) m_next->m_prev = &m_next; + m_prev = &contextData->contextGuards; + contextData->contextGuards = this; + } } -QDeclarativeContextPrivate::ContextGuard &QDeclarativeContextPrivate::ContextGuard::operator=(QObject *obj) +QDeclarativeContextData *QDeclarativeGuardedContextData::contextData() { - (QDeclarativeGuard&)*this = obj; return *this; + return m_contextData; } -void QDeclarativeContextPrivate::ContextGuard::objectDestroyed(QObject *) -{ - priv->destroyed(this); +void QDeclarativeGuardedContextData::clear() +{ + if (m_prev) { + *m_prev = m_next; + if (m_next) m_next->m_prev = m_prev; + m_contextData = 0; + m_next = 0; + m_prev = 0; + } } QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp index 0e5066e..847d632 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp +++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp @@ -51,17 +51,17 @@ QT_BEGIN_NAMESPACE struct ContextData : public QScriptDeclarativeClass::Object { ContextData() : overrideObject(0), isSharedContext(true) {} - ContextData(QDeclarativeContext *c, QObject *o) : context(c), scopeObject(o), overrideObject(0), isSharedContext(false) {} - QDeclarativeGuard context; + ContextData(QDeclarativeContextData *c, QObject *o) : context(c), scopeObject(o), overrideObject(0), isSharedContext(false) {} + QDeclarativeGuardedContextData context; QDeclarativeGuard scopeObject; QObject *overrideObject; bool isSharedContext; - QDeclarativeContext *getContext(QDeclarativeEngine *engine) { + QDeclarativeContextData *getContext(QDeclarativeEngine *engine) { if (isSharedContext) { return QDeclarativeEnginePrivate::get(engine)->sharedContext; } else { - return context.data(); + return context.contextData(); } } @@ -88,7 +88,7 @@ QDeclarativeContextScriptClass::~QDeclarativeContextScriptClass() { } -QScriptValue QDeclarativeContextScriptClass::newContext(QDeclarativeContext *context, QObject *scopeObject) +QScriptValue QDeclarativeContextScriptClass::newContext(QDeclarativeContextData *context, QObject *scopeObject) { QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -102,7 +102,7 @@ QScriptValue QDeclarativeContextScriptClass::newSharedContext() return newObject(scriptEngine, this, new ContextData()); } -QDeclarativeContext *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v) +QDeclarativeContextData *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v) { if (scriptClass(v) != this) return 0; @@ -133,7 +133,7 @@ QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier & lastData = 0; lastPropertyIndex = -1; - QDeclarativeContext *bindContext = ((ContextData *)object)->getContext(engine); + QDeclarativeContextData *bindContext = ((ContextData *)object)->getContext(engine); QObject *scopeObject = ((ContextData *)object)->getScope(engine); if (!bindContext) return 0; @@ -159,29 +159,28 @@ QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier & scopeObject = 0; // Only applies to the first context includeTypes = false; // Only applies to the first context if (rv) return rv; - bindContext = bindContext->parentContext(); + bindContext = bindContext->parent; } return 0; } QScriptClass::QueryFlags -QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, QObject *scopeObject, - const Identifier &name, - QScriptClass::QueryFlags flags, - bool includeTypes) +QDeclarativeContextScriptClass::queryProperty(QDeclarativeContextData *bindContext, QObject *scopeObject, + const Identifier &name, + QScriptClass::QueryFlags flags, + bool includeTypes) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); - lastPropertyIndex = cp->propertyNames?cp->propertyNames->value(name):-1; + lastPropertyIndex = bindContext->propertyNames?bindContext->propertyNames->value(name):-1; if (lastPropertyIndex != -1) { lastContext = bindContext; return QScriptClass::HandlesReadAccess; } - if (includeTypes && cp->imports) { - QDeclarativeTypeNameCache::Data *data = cp->imports->data(name); + if (includeTypes && bindContext->imports) { + QDeclarativeTypeNameCache::Data *data = bindContext->imports->data(name); if (data) { lastData = data; @@ -190,8 +189,8 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, } } - for (int ii = 0; ii < cp->scripts.count(); ++ii) { - lastFunction = QScriptDeclarativeClass::function(cp->scripts.at(ii), name); + for (int ii = 0; ii < bindContext->scripts.count(); ++ii) { + lastFunction = QScriptDeclarativeClass::function(bindContext->scripts.at(ii), name); if (lastFunction.isValid()) { lastContext = bindContext; return QScriptClass::HandlesReadAccess; @@ -209,13 +208,13 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, } } - if (cp->contextObject) { + if (bindContext->contextObject) { QScriptClass::QueryFlags rv = - ep->objectClass->queryProperty(cp->contextObject, name, flags, bindContext, + ep->objectClass->queryProperty(bindContext->contextObject, name, flags, bindContext, QDeclarativeObjectScriptClass::ImplicitObject | QDeclarativeObjectScriptClass::SkipAttachedProperties); if (rv) { - lastScopeObject = cp->contextObject; + lastScopeObject = bindContext->contextObject; lastContext = bindContext; return rv; } @@ -229,11 +228,10 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) { Q_UNUSED(object); - QDeclarativeContext *bindContext = lastContext; + QDeclarativeContextData *bindContext = lastContext; Q_ASSERT(bindContext); QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); if (lastScopeObject) { @@ -243,28 +241,29 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) } else if (lastData) { if (lastData->type) - return Value(scriptEngine, ep->typeNameClass->newObject(cp->contextObject, lastData->type)); + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->type)); else - return Value(scriptEngine, ep->typeNameClass->newObject(cp->contextObject, lastData->typeNamespace)); + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->typeNamespace)); } else if (lastPropertyIndex != -1) { QScriptValue rv; - if (lastPropertyIndex < cp->idValueCount) { - rv = ep->objectClass->newQObject(cp->idValues[lastPropertyIndex].data()); + if (lastPropertyIndex < bindContext->idValueCount) { + rv = ep->objectClass->newQObject(bindContext->idValues[lastPropertyIndex].data()); if (ep->captureProperties) - ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(&cp->idValues[lastPropertyIndex].bindings); + ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(&bindContext->idValues[lastPropertyIndex].bindings); } else { + QDeclarativeContextPrivate *cp = bindContext->asQDeclarativeContextPrivate(); const QVariant &value = cp->propertyValues.at(lastPropertyIndex); if (value.userType() == qMetaTypeId >()) { - rv = ep->listClass->newList(QDeclarativeListProperty(bindContext, (void*)lastPropertyIndex, 0, QDeclarativeContextPrivate::context_count, QDeclarativeContextPrivate::context_at), qMetaTypeId >()); + rv = ep->listClass->newList(QDeclarativeListProperty(bindContext->asQDeclarativeContext(), (void*)lastPropertyIndex, 0, QDeclarativeContextPrivate::context_count, QDeclarativeContextPrivate::context_at), qMetaTypeId >()); } else { rv = ep->scriptValueFromVariant(value); } if (ep->captureProperties) - ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext, -1, lastPropertyIndex + cp->notifyIndex); + ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext->asQDeclarativeContext(), -1, lastPropertyIndex + cp->notifyIndex); } @@ -283,11 +282,10 @@ void QDeclarativeContextScriptClass::setProperty(Object *object, const Identifie Q_UNUSED(object); Q_ASSERT(lastScopeObject); - QDeclarativeContext *bindContext = lastContext; + QDeclarativeContextData *bindContext = lastContext; Q_ASSERT(bindContext); QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext); ep->objectClass->setProperty(lastScopeObject, name, value, bindContext); } diff --git a/src/declarative/qml/qdeclarativecontextscriptclass_p.h b/src/declarative/qml/qdeclarativecontextscriptclass_p.h index 32c117c..93e4b20 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass_p.h +++ b/src/declarative/qml/qdeclarativecontextscriptclass_p.h @@ -60,16 +60,17 @@ QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QDeclarativeContext; +class QDeclarativeContextData; class QDeclarativeContextScriptClass : public QDeclarativeScriptClass { public: QDeclarativeContextScriptClass(QDeclarativeEngine *); ~QDeclarativeContextScriptClass(); - QScriptValue newContext(QDeclarativeContext *, QObject * = 0); + QScriptValue newContext(QDeclarativeContextData *, QObject * = 0); QScriptValue newSharedContext(); - QDeclarativeContext *contextFromValue(const QScriptValue &); + QDeclarativeContextData *contextFromValue(const QScriptValue &); QObject *setOverrideObject(QScriptValue &, QObject *); protected: @@ -79,7 +80,7 @@ protected: virtual void setProperty(Object *, const Identifier &name, const QScriptValue &); private: - QScriptClass::QueryFlags queryProperty(QDeclarativeContext *, QObject *scopeObject, + QScriptClass::QueryFlags queryProperty(QDeclarativeContextData *, QObject *scopeObject, const Identifier &, QScriptClass::QueryFlags flags, bool includeTypes); @@ -87,7 +88,7 @@ private: QDeclarativeEngine *engine; QObject *lastScopeObject; - QDeclarativeContext *lastContext; + QDeclarativeContextData *lastContext; QDeclarativeTypeNameCache::Data *lastData; int lastPropertyIndex; QScriptValue lastFunction; diff --git a/src/declarative/qml/qdeclarativedeclarativedata_p.h b/src/declarative/qml/qdeclarativedeclarativedata_p.h index f962986..d1d063a 100644 --- a/src/declarative/qml/qdeclarativedeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedeclarativedata_p.h @@ -63,13 +63,14 @@ class QDeclarativeCompiledData; class QDeclarativeAbstractBinding; class QDeclarativeContext; class QDeclarativePropertyCache; +class QDeclarativeContextData; class Q_AUTOTEST_EXPORT QDeclarativeDeclarativeData : public QDeclarativeData { public: - QDeclarativeDeclarativeData(QDeclarativeContext *ctxt = 0) - : ownMemory(true), indestructible(true), explicitIndestructibleSet(false), context(ctxt), - bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0), - outerContext(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), + QDeclarativeDeclarativeData() + : ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), + context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), + bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), attachedProperties(0), propertyCache(0), guards(0) {} virtual void destroyed(QObject *); @@ -80,11 +81,14 @@ public: } quint32 ownMemory:1; + quint32 ownContext:1; quint32 indestructible:1; quint32 explicitIndestructibleSet:1; - quint32 dummy:29; + quint32 dummy:28; + + QDeclarativeContextData *context; + QDeclarativeContextData *outerContext; - QDeclarativeContext *context; QDeclarativeAbstractBinding *bindings; // Linked list for QDeclarativeContext::contextObjects @@ -97,7 +101,6 @@ public: void clearBindingBit(int); void setBindingBit(QObject *obj, int); - QDeclarativeContext *outerContext; // Can't this be found from context? ushort lineNumber; ushort columnNumber; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 2a26626..e19e53f 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -189,7 +189,7 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url) { if (p) { - QDeclarativeContext *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context); + QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context); Q_ASSERT(ctxt); return ctxt->resolvedUrl(url); } @@ -635,9 +635,9 @@ QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object) if (!data) return 0; else if (data->outerContext) - return data->outerContext; + return data->outerContext->asQDeclarativeContext(); else - return data->context; + return 0; } /*! @@ -658,12 +658,8 @@ void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContex return; } - data->context = context; - data->nextContextObject = context->d_func()->contextObjects; - if (data->nextContextObject) - data->nextContextObject->prevContextObject = &data->nextContextObject; - data->prevContextObject = &context->d_func()->contextObjects; - context->d_func()->contextObjects = data; + QDeclarativeContextData *contextData = QDeclarativeContextData::get(context); + contextData->addObject(object); } /*! @@ -727,7 +723,7 @@ void qmlExecuteDeferred(QObject *object) if (data && data->deferredComponent) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine); QDeclarativeComponentPrivate::ConstructionState state; QDeclarativeComponentPrivate::beginDeferred(data->context, ep, object, &state); @@ -828,6 +824,9 @@ void QDeclarativeDeclarativeData::destroyed(QObject *object) g->objectDestroyed(object); } + if (ownContext) + context->destroy(); + if (ownMemory) delete this; else @@ -893,7 +892,7 @@ QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object, /*! Returns the QDeclarativeContext for the executing QScript \a ctxt. */ -QDeclarativeContext *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt) +QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt) { QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3); Q_ASSERT(scopeNode.isValid()); @@ -901,15 +900,15 @@ QDeclarativeContext *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt) return contextClass->contextFromValue(scopeNode); } -QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, - QScriptEngine *engine) +QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine) { QDeclarativeEnginePrivate *activeEnginePriv = static_cast(engine)->p; QDeclarativeEngine* activeEngine = activeEnginePriv->q_func(); - QDeclarativeContext* context = activeEnginePriv->getContext(ctxt); + QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); Q_ASSERT(context); + if(ctxt->argumentCount() != 1) { return engine->nullValue(); }else{ @@ -918,7 +917,7 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, return engine->nullValue(); QUrl url = QUrl(context->resolvedUrl(QUrl(arg))); QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine); - c->setCreationContext(context); + QDeclarativeComponentPrivate::get(c)->creationContext = context; QDeclarativeDeclarativeData::get(c, true)->setImplicitDestructible(); return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId()); } @@ -933,7 +932,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3) return engine->nullValue(); - QDeclarativeContext* context = activeEnginePriv->getContext(ctxt); + QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); Q_ASSERT(context); QString qml = ctxt->argument(0).toString(); @@ -971,7 +970,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS return engine->nullValue(); } - QObject *obj = component.create(context); + QObject *obj = component.create(context->asQDeclarativeContext()); if(component.isError()) { QList errors = component.errors(); diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index fb8c5e7..f1b7b0e 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -61,6 +61,7 @@ #include "qdeclarative.h" #include "qdeclarativevaluetype_p.h" #include "qdeclarativecontext.h" +#include "qdeclarativecontext_p.h" #include "qdeclarativeexpression.h" #include "qdeclarativeproperty_p.h" #include "qdeclarativepropertycache_p.h" @@ -162,7 +163,7 @@ public: struct ImportedNamespace; QDeclarativeContextScriptClass *contextClass; - QDeclarativeContext *sharedContext; + QDeclarativeContextData *sharedContext; QObject *sharedScope; QDeclarativeObjectScriptClass *objectClass; QDeclarativeValueTypeScriptClass *valueTypeClass; @@ -336,9 +337,10 @@ public: static QDeclarativeEngine *getEngine(QScriptEngine *e) { return static_cast(e)->p->q_func(); } static QDeclarativeEnginePrivate *get(QDeclarativeEngine *e) { return e->d_func(); } static QDeclarativeEnginePrivate *get(QDeclarativeContext *c) { return (c && c->engine()) ? QDeclarativeEnginePrivate::get(c->engine()) : 0; } + static QDeclarativeEnginePrivate *get(QDeclarativeContextData *c) { return (c && c->engine) ? QDeclarativeEnginePrivate::get(c->engine) : 0; } static QDeclarativeEnginePrivate *get(QScriptEngine *e) { return static_cast(e)->p; } static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); } - QDeclarativeContext *getContext(QScriptContext *); + QDeclarativeContextData *getContext(QScriptContext *); static void defineModule(); }; diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index 933683c..da73178 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -49,6 +49,7 @@ #include "qdeclarativebinding_p.h" #include "qdeclarativecontext_p.h" #include "qdeclarativewatcher_p.h" +#include "qdeclarativevaluetype_p.h" #include #include @@ -218,10 +219,9 @@ void QDeclarativeEngineDebugServer::buildObjectDump(QDataStream &message, message << fakeProperties[ii]; } -void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, - QDeclarativeContext *ctxt) +void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDeclarativeContext *ctxt) { - QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt); + QDeclarativeContextData *p = QDeclarativeContextData::get(ctxt); QString ctxtName = ctxt->objectName(); int ctxtId = QDeclarativeDebugService::idForObject(ctxt); @@ -230,35 +230,34 @@ void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, int count = 0; - QDeclarativeContext *child = p->childContexts; + QDeclarativeContextData *child = p->childContexts; while (child) { - QDeclarativeContextPrivate *p = QDeclarativeContextPrivate::get(child); - if (!p->isInternal) + if (!child->isInternal) ++count; - child = p->nextChild; + child = child->nextChild; } message << count; child = p->childContexts; while (child) { - QDeclarativeContextPrivate *p = QDeclarativeContextPrivate::get(child); - if (!p->isInternal) - buildObjectList(message, child); - child = p->nextChild; + if (!child->isInternal) + buildObjectList(message, child->asQDeclarativeContext()); + child = child->nextChild; } // Clean deleted objects - for (int ii = 0; ii < p->instances.count(); ++ii) { - if (!p->instances.at(ii)) { - p->instances.removeAt(ii); + QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(ctxt); + for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) { + if (!ctxtPriv->instances.at(ii)) { + ctxtPriv->instances.removeAt(ii); --ii; } } - message << p->instances.count(); - for (int ii = 0; ii < p->instances.count(); ++ii) { - message << objectData(p->instances.at(ii)); + message << ctxtPriv->instances.count(); + for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) { + message << objectData(ctxtPriv->instances.at(ii)); } } @@ -268,7 +267,7 @@ QDeclarativeEngineDebugServer::objectData(QObject *object) QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object); QDeclarativeObjectData rv; if (ddata) { - rv.url = ddata->outerContext->baseUrl(); + rv.url = ddata->outerContext->url; rv.lineNumber = ddata->lineNumber; rv.columnNumber = ddata->columnNumber; } else { diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index f3299ba..609eb39 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -98,8 +98,8 @@ QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() if (data) { data->q = 0; data->release(); data = 0; } } -void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, const QString &expr, - QObject *me) +void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr, + QObject *me) { data->expression = expr; @@ -107,8 +107,8 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, const QStrin data->me = me; } -void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, QDeclarativeRefCount *rc, - QObject *me, const QString &url, int lineNumber) +void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr, QDeclarativeRefCount *rc, + QObject *me, const QString &url, int lineNumber) { data->url = url; data->line = lineNumber; @@ -127,7 +127,7 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, bool isShared = progIdx & 0x80000000; progIdx &= 0x7FFFFFFF; - QDeclarativeEngine *engine = ctxt->engine(); + QDeclarativeEngine *engine = ctxt->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -167,10 +167,10 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, data->me = me; } -QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContext *context, QObject *object, +QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object, const QString &program, QScriptValue *contextObject) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine); if (contextObject) { *contextObject = ep->contextClass->newContext(context, object); @@ -184,10 +184,11 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex return rv; } -QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContext *context, QObject *object, - const QScriptProgram &program, QScriptValue *contextObject) +QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object, + const QScriptProgram &program, + QScriptValue *contextObject) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine); if (contextObject) { *contextObject = ep->contextClass->newContext(context, object); @@ -219,10 +220,10 @@ QDeclarativeExpression::QDeclarativeExpression() } /*! \internal */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, void *expr, - QDeclarativeRefCount *rc, QObject *me, - const QString &url, int lineNumber, - QDeclarativeExpressionPrivate &dd) +QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, void *expr, + QDeclarativeRefCount *rc, QObject *me, + const QString &url, int lineNumber, + QDeclarativeExpressionPrivate &dd) : QObject(dd, 0) { Q_D(QDeclarativeExpression); @@ -237,7 +238,18 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, void * the expression's execution. */ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const QString &expression, - QObject *scope) + QObject *scope) +: QObject(*new QDeclarativeExpressionPrivate, 0) +{ + Q_D(QDeclarativeExpression); + d->init(QDeclarativeContextData::get(ctxt), expression, scope); +} + +/*! + \internal +*/ +QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, const QString &expression, + QObject *scope) : QObject(*new QDeclarativeExpressionPrivate, 0) { Q_D(QDeclarativeExpression); @@ -245,8 +257,8 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const } /*! \internal */ -QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const QString &expression, - QObject *scope, QDeclarativeExpressionPrivate &dd) +QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, const QString &expression, + QObject *scope, QDeclarativeExpressionPrivate &dd) : QObject(dd, 0) { Q_D(QDeclarativeExpression); @@ -267,7 +279,7 @@ QDeclarativeExpression::~QDeclarativeExpression() QDeclarativeEngine *QDeclarativeExpression::engine() const { Q_D(const QDeclarativeExpression); - return d->data->context()?d->data->context()->engine():0; + return d->data->context()?d->data->context()->engine:0; } /*! @@ -277,7 +289,8 @@ QDeclarativeEngine *QDeclarativeExpression::engine() const QDeclarativeContext *QDeclarativeExpression::context() const { Q_D(const QDeclarativeExpression); - return d->data->context(); + QDeclarativeContextData *data = d->data->context(); + return data?data->asQDeclarativeContext():0; } /*! @@ -338,8 +351,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo #endif QDeclarativeExpressionData *data = this->data; - QDeclarativeContextPrivate *ctxtPriv = data->context()->d_func(); - QDeclarativeEngine *engine = data->context()->engine(); + QDeclarativeEngine *engine = data->context()->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); @@ -370,7 +382,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo data->expressionFunctionValid = true; } - QDeclarativeContext *oldSharedContext = 0; + QDeclarativeContextData *oldSharedContext = 0; QObject *oldSharedScope = 0; QObject *oldOverride = 0; if (data->isShared) { @@ -743,12 +755,12 @@ QDeclarativeAbstractExpression::~QDeclarativeAbstractExpression() } } -QDeclarativeContext *QDeclarativeAbstractExpression::context() const +QDeclarativeContextData *QDeclarativeAbstractExpression::context() const { return m_context; } -void QDeclarativeAbstractExpression::setContext(QDeclarativeContext *context) +void QDeclarativeAbstractExpression::setContext(QDeclarativeContextData *context) { if (m_prevExpression) { *m_prevExpression = m_nextExpression; @@ -761,13 +773,11 @@ void QDeclarativeAbstractExpression::setContext(QDeclarativeContext *context) m_context = context; if (m_context) { - QDeclarativeContextPrivate *cp = - static_cast(QObjectPrivate::get(m_context)); - m_nextExpression = cp->expressions; + m_nextExpression = m_context->expressions; if (m_nextExpression) m_nextExpression->m_prevExpression = &m_nextExpression; - m_prevExpression = &cp->expressions; - cp->expressions = this; + m_prevExpression = &context->expressions; + m_context->expressions = this; } } diff --git a/src/declarative/qml/qdeclarativeexpression.h b/src/declarative/qml/qdeclarativeexpression.h index 911d328..73a5793 100644 --- a/src/declarative/qml/qdeclarativeexpression.h +++ b/src/declarative/qml/qdeclarativeexpression.h @@ -58,6 +58,7 @@ class QDeclarativeRefCount; class QDeclarativeEngine; class QDeclarativeContext; class QDeclarativeExpressionPrivate; +class QDeclarativeContextData; class Q_DECLARATIVE_EXPORT QDeclarativeExpression : public QObject { Q_OBJECT @@ -91,18 +92,21 @@ Q_SIGNALS: void valueChanged(); protected: - QDeclarativeExpression(QDeclarativeContext *, const QString &, QObject *, - QDeclarativeExpressionPrivate &dd); - QDeclarativeExpression(QDeclarativeContext *, void *, QDeclarativeRefCount *rc, QObject *me, const QString &, - int, QDeclarativeExpressionPrivate &dd); + QDeclarativeExpression(QDeclarativeContextData *, const QString &, QObject *, + QDeclarativeExpressionPrivate &dd); + QDeclarativeExpression(QDeclarativeContextData *, void *, QDeclarativeRefCount *rc, + QObject *me, const QString &, int, QDeclarativeExpressionPrivate &dd); private Q_SLOTS: void __q_notify(); private: + QDeclarativeExpression(QDeclarativeContextData *, const QString &, QObject *); + Q_DECLARE_PRIVATE(QDeclarativeExpression) friend class QDeclarativeDebugger; friend class QDeclarativeContext; + friend class QDeclarativeVME; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index d170559..5adaa89 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -70,15 +70,16 @@ public: bool isValid() const; - QDeclarativeContext *context() const; - void setContext(QDeclarativeContext *); + QDeclarativeContextData *context() const; + void setContext(QDeclarativeContextData *); virtual void refresh(); private: friend class QDeclarativeContext; + friend class QDeclarativeContextData; friend class QDeclarativeContextPrivate; - QDeclarativeContext *m_context; + QDeclarativeContextData *m_context; QDeclarativeAbstractExpression **m_prevExpression; QDeclarativeAbstractExpression *m_nextExpression; }; @@ -143,8 +144,8 @@ public: QDeclarativeExpressionPrivate(QDeclarativeExpressionData *); ~QDeclarativeExpressionPrivate(); - void init(QDeclarativeContext *, const QString &, QObject *); - void init(QDeclarativeContext *, void *, QDeclarativeRefCount *, QObject *, const QString &, int); + void init(QDeclarativeContextData *, const QString &, QObject *); + void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int); QDeclarativeExpressionData *data; @@ -164,8 +165,8 @@ public: virtual void emitValueChanged(); static void exceptionToError(QScriptEngine *, QDeclarativeError &); - static QScriptValue evalInObjectScope(QDeclarativeContext *, QObject *, const QString &, QScriptValue * = 0); - static QScriptValue evalInObjectScope(QDeclarativeContext *, QObject *, const QScriptProgram &, QScriptValue * = 0); + static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QString &, QScriptValue * = 0); + static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &, QScriptValue * = 0); }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeinfo.cpp b/src/declarative/qml/qdeclarativeinfo.cpp index 7dc61fd..87a9254 100644 --- a/src/declarative/qml/qdeclarativeinfo.cpp +++ b/src/declarative/qml/qdeclarativeinfo.cpp @@ -43,6 +43,7 @@ #include "qdeclarativedeclarativedata_p.h" #include "qdeclarativecontext.h" +#include "qdeclarativecontext_p.h" #include "qdeclarativemetatype_p.h" #include @@ -103,7 +104,7 @@ QDeclarativeInfo::QDeclarativeInfo(const QObject *object) pos += QLatin1String(" ("); if (ddata) { if (ddata->outerContext) { - pos += ddata->outerContext->baseUrl().toString(); + pos += ddata->outerContext->url.toString(); pos += QLatin1Char(':'); pos += QString::number(ddata->lineNumber); pos += QLatin1Char(':'); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index 32a28fe..027166a 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -142,7 +142,7 @@ QDeclarativeObjectScriptClass::queryProperty(Object *object, const Identifier &n QScriptClass::QueryFlags QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, - QScriptClass::QueryFlags flags, QDeclarativeContext *evalContext, + QScriptClass::QueryFlags flags, QDeclarativeContextData *evalContext, QueryHints hints) { Q_UNUSED(flags); @@ -173,15 +173,11 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam } } - if (evalContext) { - QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(evalContext); - - if (cp->imports) { - QDeclarativeTypeNameCache::Data *data = cp->imports->data(name); - if (data) { - lastTNData = data; - return QScriptClass::HandlesReadAccess; - } + if (evalContext && evalContext->imports) { + QDeclarativeTypeNameCache::Data *data = evalContext->imports->data(name); + if (data) { + lastTNData = data; + return QScriptClass::HandlesReadAccess; } } } @@ -316,7 +312,7 @@ void QDeclarativeObjectScriptClass::setProperty(Object *object, void QDeclarativeObjectScriptClass::setProperty(QObject *obj, const Identifier &name, const QScriptValue &value, - QDeclarativeContext *evalContext) + QDeclarativeContextData *evalContext) { Q_UNUSED(name); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h index 1f7d1c9..396b782 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QScriptContext; class QScriptEngine; -class QDeclarativeContext; +class QDeclarativeContextData; #if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) class Q_AUTOTEST_EXPORT QDeclarativeObjectMethodScriptClass : public QScriptDeclarativeClass @@ -112,13 +112,13 @@ public: QScriptClass::QueryFlags queryProperty(QObject *, const Identifier &, QScriptClass::QueryFlags flags, - QDeclarativeContext *evalContext, + QDeclarativeContextData *evalContext, QueryHints hints = 0); ScriptValue property(QObject *, const Identifier &); void setProperty(QObject *, const Identifier &name, const QScriptValue &, - QDeclarativeContext *evalContext = 0); + QDeclarativeContextData *evalContext = 0); virtual QStringList propertyNames(Object *); virtual bool compare(Object *, Object *); diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index c55c22f..caa1acf 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -124,7 +124,7 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeContext *ct : d(new QDeclarativePropertyPrivate) { d->q = this; - d->context = ctxt; + d->context = ctxt?QDeclarativeContextData::get(ctxt):0; d->engine = ctxt?ctxt->engine():0; d->initDefault(obj); } @@ -177,7 +177,7 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QD : d(new QDeclarativePropertyPrivate) { d->q = this; - d->context = ctxt; + d->context = ctxt?QDeclarativeContextData::get(ctxt):0; d->engine = ctxt?ctxt->engine():0; d->initProperty(obj, name); if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; } @@ -204,7 +204,7 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name { if (!obj) return; - QDeclarativeTypeNameCache *typeNameCache = context?QDeclarativeContextPrivate::get(context)->imports:0; + QDeclarativeTypeNameCache *typeNameCache = context?context->imports:0; QStringList path = name.split(QLatin1Char('.')); if (path.isEmpty()) return; @@ -924,7 +924,7 @@ bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, Writ } bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePropertyCache::Data &property, - const QVariant &value, QDeclarativeContext *context, + const QVariant &value, QDeclarativeContextData *context, WriteFlags flags) { int coreIdx = property.coreIndex; @@ -1305,7 +1305,7 @@ QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObje } QDeclarativeProperty -QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContext *ctxt) +QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContextData *ctxt) { QDeclarativeProperty prop; @@ -1314,7 +1314,7 @@ QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QD prop.d->object = object; prop.d->context = ctxt; - prop.d->engine = ctxt?ctxt->engine():0; + prop.d->engine = ctxt->engine; const SerializedData *sd = (const SerializedData *)data.constData(); if (sd->isValueType) { diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h index 26b85b8..1bbee64 100644 --- a/src/declarative/qml/qdeclarativeproperty_p.h +++ b/src/declarative/qml/qdeclarativeproperty_p.h @@ -82,7 +82,7 @@ public: valueType(other.valueType) {} QDeclarativeProperty *q; - QDeclarativeContext *context; + QDeclarativeContextData *context; QDeclarativeEngine *engine; QDeclarativeGuard object; @@ -109,7 +109,7 @@ public: static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags); static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &, - QDeclarativeContext *, WriteFlags flags = 0); + QDeclarativeContextData *, WriteFlags flags = 0); static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex, int valueTypeIndex /* -1 */, QDeclarativeAbstractBinding *, WriteFlags flags = DontRemoveBinding); @@ -117,7 +117,7 @@ public: static QByteArray saveValueType(const QMetaObject *, int, const QMetaObject *, int); static QByteArray saveProperty(const QMetaObject *, int); - static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContext *); + static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContextData *); static bool equal(const QMetaObject *, const QMetaObject *); static bool canConvert(const QMetaObject *from, const QMetaObject *to); diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 05553fd..b3c07f5 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -100,9 +100,8 @@ struct ListInstance QDeclarativeListProperty qListProperty; }; -QObject *QDeclarativeVME::run(QDeclarativeContext *ctxt, QDeclarativeCompiledData *comp, - int start, int count, - const QBitField &bindingSkipList) +QObject *QDeclarativeVME::run(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, + int start, int count, const QBitField &bindingSkipList) { QDeclarativeVMEStack stack; @@ -119,7 +118,7 @@ void QDeclarativeVME::runDeferred(QObject *object) if (!data || !data->context || !data->deferredComponent) return; - QDeclarativeContext *ctxt = data->context; + QDeclarativeContextData *ctxt = data->context; QDeclarativeCompiledData *comp = data->deferredComponent; int start = data->deferredIdx + 1; int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount; @@ -129,7 +128,8 @@ void QDeclarativeVME::runDeferred(QObject *object) run(stack, ctxt, comp, start, count, QBitField()); } -QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarativeContext *ctxt, +QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, + QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, int start, int count, const QBitField &bindingSkipList) @@ -152,8 +152,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QDeclarativeVMEStack qliststack; vmeErrors.clear(); - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine()); - QDeclarativeContextPrivate *cp = (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); int status = -1; //for dbus QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor; @@ -169,9 +168,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati if (instr.init.parserStatusSize) parserStatus = QDeclarativeEnginePrivate::SimpleList(instr.init.parserStatusSize); if (instr.init.contextCache != -1) - cp->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache)); + ctxt->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache)); if (instr.init.compiledBinding != -1) - cp->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt); + ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt); } break; @@ -188,6 +187,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QObject *o = types.at(instr.create.type).createInstance(ctxt, bindings); + if (!o) { if(types.at(instr.create.type).component) vmeErrors << types.at(instr.create.type).component->errors(); @@ -197,6 +197,24 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(o); Q_ASSERT(ddata); + + if (stack.isEmpty()) { + if (ddata->context) { + Q_ASSERT(ddata->context != ctxt); + Q_ASSERT(ddata->outerContext); + Q_ASSERT(ddata->outerContext != ctxt); + QDeclarativeContextData *c = ddata->context; + while (c->linkedContext) c = c->linkedContext; + c->linkedContext = ctxt; + } else { + ctxt->addObject(o); + } + + ddata->ownContext = true; + } else if (!ddata->context) { + ctxt->addObject(o); + } + ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; @@ -229,25 +247,30 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati case QDeclarativeInstruction::SetId: { QObject *target = stack.top(); - cp->setIdProperty(instr.setId.index, target); + ctxt->setIdProperty(instr.setId.index, target); } break; case QDeclarativeInstruction::SetDefault: { - QObject *target = stack.top(); - ctxt->setContextObject(target); + ctxt->contextObject = stack.top(); } break; case QDeclarativeInstruction::CreateComponent: { - QObject *qcomp = new QDeclarativeComponent(ctxt->engine(), comp, ii + 1, instr.createComponent.count, stack.isEmpty() ? 0 : stack.top()); + QObject *qcomp = new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, + stack.isEmpty() ? 0 : stack.top()); - QDeclarativeEngine::setContextForObject(qcomp, ctxt); - QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp); + QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp, true); Q_ASSERT(ddata); + + ctxt->addObject(qcomp); + + if (stack.isEmpty()) + ddata->ownContext = true; + ddata->setImplicitDestructible(); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; @@ -555,7 +578,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati case QDeclarativeInstruction::StoreScript: { QObject *target = stack.top(); - cp->addScript(scripts.at(instr.storeScript.value), target); + ctxt->addScript(scripts.at(instr.storeScript.value), target); } break; @@ -564,7 +587,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati QObject *target = stack.top(); QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope); QDeclarativeScriptString ss; - ss.setContext(ctxt); + ss.setContext(ctxt->asQDeclarativeContext()); ss.setScopeObject(scope); ss.setScript(primitives.at(instr.storeScriptString.value)); @@ -620,7 +643,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, QDeclarati break; QDeclarativeAbstractBinding *binding = - cp->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property); + ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property); bindValues.append(binding); binding->m_mePtr = &bindValues.values[bindValues.count - 1]; binding->addToObject(target); @@ -848,4 +871,25 @@ QList QDeclarativeVME::errors() const return vmeErrors; } +QObject * +QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData *ctxt, + const QBitField &bindings) const +{ + if (type) { + QObject *rv = 0; + void *memory = 0; + + type->create(&rv, &memory, sizeof(QDeclarativeDeclarativeData)); + QDeclarativeDeclarativeData *ddata = new (memory) QDeclarativeDeclarativeData; + ddata->ownMemory = false; + QObjectPrivate::get(rv)->declarativeData = ddata; + + return rv; + } else { + Q_ASSERT(component); + return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings); + } +} + + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h index bcd3ac9..3f8aa15 100644 --- a/src/declarative/qml/qdeclarativevme_p.h +++ b/src/declarative/qml/qdeclarativevme_p.h @@ -65,7 +65,7 @@ class QObject; class QDeclarativeInstruction; class QDeclarativeCompiledData; class QDeclarativeCompiledData; -class QDeclarativeContext; +class QDeclarativeContextData; template class QDeclarativeVMEStack { @@ -100,7 +100,7 @@ class QDeclarativeVME public: QDeclarativeVME(); - QObject *run(QDeclarativeContext *, QDeclarativeCompiledData *, + QObject *run(QDeclarativeContextData *, QDeclarativeCompiledData *, int start = -1, int count = -1, const QBitField & = QBitField()); void runDeferred(QObject *); @@ -109,8 +109,10 @@ public: QList errors() const; private: - QObject *run(QDeclarativeVMEStack &, QDeclarativeContext *, QDeclarativeCompiledData *, - int start, int count, const QBitField &); + QObject *run(QDeclarativeVMEStack &, + QDeclarativeContextData *, QDeclarativeCompiledData *, + int start, int count, + const QBitField &); QList vmeErrors; }; diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index d67c834..f9c99ee 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -55,11 +55,11 @@ QT_BEGIN_NAMESPACE QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj, - const QMetaObject *other, - const QDeclarativeVMEMetaData *meta, - QDeclarativeCompiledData *cdata) -: object(obj), compiledData(cdata), ctxt(qmlContext(obj)), metaData(meta), methods(0), - parent(0) + const QMetaObject *other, + const QDeclarativeVMEMetaData *meta, + QDeclarativeCompiledData *cdata) +: object(obj), compiledData(cdata), ctxt(QDeclarativeDeclarativeData::get(obj)->outerContext), + metaData(meta), methods(0), parent(0) { compiledData->addref(); @@ -115,7 +115,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) if (type != QVariant::Invalid) { if (valueIndex != -1) { - QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine()):0; + QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine):0; QDeclarativeValueType *valueType = 0; if (ep) valueType = ep->valueTypes[type]; else valueType = QDeclarativeValueTypeFactory::valueType(type); @@ -214,16 +214,17 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) *reinterpret_cast(a[0]) = 0; if (!ctxt) return -1; - QDeclarativeContextPrivate *ctxtPriv = - (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt); - QObject *target = ctxtPriv->idValues[d->contextIdx].data(); + QDeclarativeContext *context = ctxt->asQDeclarativeContext(); + QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context); + + QObject *target = ctxtPriv->data->idValues[d->contextIdx].data(); if (!target) return -1; if (c == QMetaObject::ReadProperty && !aConnected.testBit(id)) { int sigIdx = methodOffset + id + metaData->propertyCount; - QMetaObject::connect(ctxt, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); + QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx); if (d->propertyIdx != -1) { QMetaProperty prop = @@ -262,10 +263,10 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) id -= plainSignals; if (id < metaData->methodCount) { - if (!ctxt->engine()) + if (!ctxt->engine) return -1; // We can't run the method - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine()); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine); QScriptValue function = method(id); diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h index 37c0b7a..e11f6fa 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject_p.h +++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h @@ -63,6 +63,7 @@ #include "qdeclarativeguard_p.h" #include "qdeclarativecompiler_p.h" +#include "qdeclarativecontext_p.h" QT_BEGIN_NAMESPACE @@ -121,7 +122,7 @@ protected: private: QObject *object; QDeclarativeCompiledData *compiledData; - QDeclarativeGuard ctxt; + QDeclarativeGuardedContextData ctxt; const QDeclarativeVMEMetaData *metaData; int propOffset; diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index 9c2b1e6..8865e04 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -439,7 +439,8 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions() if (d->isExplicit) { a.toValue = d->expressions.at(ii).second->value(); } else { - QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->expressions.at(ii).second->expression(), object(), qmlContext(this)); + QDeclarativeBinding *newBinding = + new QDeclarativeBinding(d->expressions.at(ii).second->expression(), object(), qmlContext(this)); newBinding->setTarget(prop); a.toBinding = newBinding; a.deletableToBinding = true; -- cgit v0.12