diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-07-04 16:07:50 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2017-07-05 09:05:55 +0000 |
commit | cfb17c44cf3ae1268d066ba414759068059a7bbd (patch) | |
tree | 58efa2997a5ac52b7d1f11ec0c8de2754f02f03b /src/qml | |
parent | 79ceef9f467d065c6e921892e9cc4ed46a0183cc (diff) |
Simplify and unite handling of activation objects in Contexts
All ExecutionContexts (except for CatchContext) have or can have
some sort of activation object. Unify them in one pointer in
the ExecutionContext class, and unify it's handling where it's
actually the same.
Change-Id: I6750999ddbd5d1d74235ef4b34dcd7546c432541
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 103 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 16 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qmlcontext.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qmlcontext_p.h | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 10 | ||||
-rw-r--r-- | src/qml/memory/qv4writebarrier_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmldelayedcallqueue.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 2 | ||||
-rw-r--r-- | src/qml/types/qquickworkerscript.cpp | 2 |
10 files changed, 52 insertions, 105 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index ba72a9e43b..7c0a872a3b 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -132,8 +132,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) case Heap::ExecutionContext::Type_QmlContext: { // this is ugly, as it overrides the inner callcontext, but has to stay as long // as bindings still get their own callcontext - Heap::QmlContext *qml = static_cast<Heap::QmlContext *>(ctx->d()); - activation = qml->qml; + activation = ctx->d()->activation; break; } case Heap::ExecutionContext::Type_GlobalContext: { @@ -158,7 +157,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) void Heap::GlobalContext::init(ExecutionEngine *eng) { Heap::ExecutionContext::init(Heap::ExecutionContext::Type_GlobalContext); - global.set(eng, eng->globalObject->d()); + activation.set(eng, eng->globalObject->d()); } void Heap::CatchContext::init(ExecutionContext *outerContext, String *exceptionVarName, @@ -185,7 +184,7 @@ void Heap::WithContext::init(ExecutionContext *outerContext, Object *with) constantTable = outer->constantTable; compilationUnit = outer->compilationUnit; - withObject.set(internalClass->engine, with); + activation.set(internalClass->engine, with); } Identifier * const *SimpleCallContext::formals() const @@ -225,18 +224,6 @@ bool ExecutionContext::deleteProperty(String *name) return false; break; } - case Heap::ExecutionContext::Type_WithContext: { - ScopedObject withObject(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject); - if (withObject->hasProperty(name)) - return withObject->deleteProperty(name); - break; - } - case Heap::ExecutionContext::Type_GlobalContext: { - ScopedObject global(scope, static_cast<Heap::GlobalContext *>(ctx->d())->global); - if (global->hasProperty(name)) - return global->deleteProperty(name); - break; - } case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d()); uint index = c->v4Function->internalClass->find(id); @@ -245,11 +232,12 @@ bool ExecutionContext::deleteProperty(String *name) return false; Q_FALLTHROUGH(); } + case Heap::ExecutionContext::Type_WithContext: + case Heap::ExecutionContext::Type_GlobalContext: case Heap::ExecutionContext::Type_SimpleCallContext: { - Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d()); - ScopedObject qml(scope, c->activation); - if (qml && qml->hasProperty(name)) - return qml->deleteProperty(name); + ScopedObject object(scope, ctx->d()->activation); + if (object && object->hasProperty(name)) + return object->deleteProperty(name); break; } case Heap::ExecutionContext::Type_QmlContext: @@ -329,17 +317,14 @@ void ExecutionContext::setProperty(String *name, const Value &value) break; } case Heap::ExecutionContext::Type_WithContext: { - ScopedObject w(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject); + // the semantics are different from the setProperty calls of other activations + ScopedObject w(scope, static_cast<Heap::WithContext *>(ctx->d())->activation); if (w->hasProperty(name)) { w->put(name, value); return; } break; } - case Heap::ExecutionContext::Type_GlobalContext: { - activation = static_cast<Heap::GlobalContext *>(ctx->d())->global; - break; - } case Heap::ExecutionContext::Type_CallContext: case Heap::ExecutionContext::Type_SimpleCallContext: { Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d()); @@ -356,11 +341,13 @@ void ExecutionContext::setProperty(String *name, const Value &value) return; } } - activation = c->activation; - break; } + Q_FALLTHROUGH(); + case Heap::ExecutionContext::Type_GlobalContext: + activation = ctx->d()->activation; + break; case Heap::ExecutionContext::Type_QmlContext: { - activation = static_cast<Heap::QmlContext *>(ctx->d())->qml; + activation = ctx->d()->activation; activation->put(name, value); return; } @@ -401,23 +388,6 @@ ReturnedValue ExecutionContext::getProperty(String *name) return c->exceptionValue.asReturnedValue(); break; } - case Heap::ExecutionContext::Type_WithContext: { - ScopedObject w(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject); - bool hasProperty = false; - v = w->get(name, &hasProperty); - if (hasProperty) { - return v->asReturnedValue(); - } - break; - } - case Heap::ExecutionContext::Type_GlobalContext: { - ScopedObject global(scope, static_cast<Heap::GlobalContext *>(ctx->d())->global); - bool hasProperty = false; - v = global->get(name, &hasProperty); - if (hasProperty) - return v->asReturnedValue(); - break; - } case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d()); name->makeIdentifier(); @@ -436,9 +406,11 @@ ReturnedValue ExecutionContext::getProperty(String *name) } Q_FALLTHROUGH(); } + case Heap::ExecutionContext::Type_WithContext: + case Heap::ExecutionContext::Type_GlobalContext: + case Heap::ExecutionContext::Type_QmlContext: case Heap::ExecutionContext::Type_SimpleCallContext: { - Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d()); - ScopedObject activation(scope, c->activation); + ScopedObject activation(scope, ctx->d()->activation); if (activation) { bool hasProperty = false; v = activation->get(name, &hasProperty); @@ -447,14 +419,6 @@ ReturnedValue ExecutionContext::getProperty(String *name) } break; } - case Heap::ExecutionContext::Type_QmlContext: { - ScopedObject qml(scope, static_cast<Heap::QmlContext *>(ctx->d())->qml); - bool hasProperty = false; - v = qml->get(name, &hasProperty); - if (hasProperty) - return v->asReturnedValue(); - break; - } } } ScopedValue n(scope, name); @@ -480,24 +444,6 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) return c->exceptionValue.asReturnedValue(); break; } - case Heap::ExecutionContext::Type_WithContext: { - ScopedObject w(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject); - bool hasProperty = false; - v = w->get(name, &hasProperty); - if (hasProperty) { - base->setM(w->d()); - return v->asReturnedValue(); - } - break; - } - case Heap::ExecutionContext::Type_GlobalContext: { - ScopedObject global(scope, static_cast<Heap::GlobalContext *>(ctx->d())->global); - bool hasProperty = false; - v = global->get(name, &hasProperty); - if (hasProperty) - return v->asReturnedValue(); - break; - } case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d()); name->makeIdentifier(); @@ -515,9 +461,9 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) } Q_FALLTHROUGH(); } + case Heap::ExecutionContext::Type_GlobalContext: case Heap::ExecutionContext::Type_SimpleCallContext: { - Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d()); - ScopedObject activation(scope, c->activation); + ScopedObject activation(scope, ctx->d()->activation); if (activation) { bool hasProperty = false; v = activation->get(name, &hasProperty); @@ -526,12 +472,13 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) } break; } + case Heap::ExecutionContext::Type_WithContext: case Heap::ExecutionContext::Type_QmlContext: { - ScopedObject qml(scope, static_cast<Heap::QmlContext *>(ctx->d())->qml); + ScopedObject o(scope, ctx->d()->activation); bool hasProperty = false; - v = qml->get(name, &hasProperty); + v = o->get(name, &hasProperty); if (hasProperty) { - base->setM(qml->d()); + base->setM(o->d()); return v->asReturnedValue(); } break; diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 5cf134bc70..3ecdc594b6 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -110,6 +110,7 @@ struct QmlContext; Member(class, NoMark, Lookup *, lookups) \ Member(class, NoMark, const QV4::Value *, constantTable) \ Member(class, NoMark, CompiledData::CompilationUnitBase *, compilationUnit) \ + Member(class, Pointer, Object *, activation) \ Member(class, NoMark, int, lineNumber) // as member of non-pointer size this has to come last to preserve the ability to // translate offsetof of it between 64-bit and 32-bit. @@ -150,10 +151,10 @@ Q_STATIC_ASSERT(offsetof(ExecutionContextData, outer) == offsetof(ExecutionConte Q_STATIC_ASSERT(offsetof(ExecutionContextData, lookups) == offsetof(ExecutionContextData, outer) + QT_POINTER_SIZE); Q_STATIC_ASSERT(offsetof(ExecutionContextData, constantTable) == offsetof(ExecutionContextData, lookups) + QT_POINTER_SIZE); Q_STATIC_ASSERT(offsetof(ExecutionContextData, compilationUnit) == offsetof(ExecutionContextData, constantTable) + QT_POINTER_SIZE); -Q_STATIC_ASSERT(offsetof(ExecutionContextData, lineNumber) == offsetof(ExecutionContextData, compilationUnit) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(ExecutionContextData, activation) == offsetof(ExecutionContextData, compilationUnit) + QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(ExecutionContextData, lineNumber) == offsetof(ExecutionContextData, activation) + QT_POINTER_SIZE); #define SimpleCallContextMembers(class, Member) \ - Member(class, Pointer, Object *, activation) \ Member(class, NoMark, QV4::Function *, v4Function) DECLARE_HEAP_OBJECT(SimpleCallContext, ExecutionContext) { @@ -169,9 +170,8 @@ DECLARE_HEAP_OBJECT(SimpleCallContext, ExecutionContext) { }; V4_ASSERT_IS_TRIVIAL(SimpleCallContext) Q_STATIC_ASSERT(std::is_standard_layout<SimpleCallContextData>::value); -Q_STATIC_ASSERT(offsetof(SimpleCallContextData, activation) == 0); -Q_STATIC_ASSERT(offsetof(SimpleCallContextData, v4Function) == offsetof(SimpleCallContextData, activation) + QT_POINTER_SIZE); -Q_STATIC_ASSERT(sizeof(SimpleCallContextData) == 2 * QT_POINTER_SIZE); +Q_STATIC_ASSERT(offsetof(SimpleCallContextData, v4Function) == 0); +Q_STATIC_ASSERT(sizeof(SimpleCallContextData) == QT_POINTER_SIZE); Q_STATIC_ASSERT(sizeof(SimpleCallContext) == sizeof(ExecutionContext) + sizeof(SimpleCallContextData)); #if QT_POINTER_SIZE == 8 @@ -198,8 +198,7 @@ Q_STATIC_ASSERT(offsetof(CallContextData, function) == 0); // example it is not. Therefore we have a padding in place and always have a distance of 8 bytes. Q_STATIC_ASSERT(offsetof(CallContextData, locals) == offsetof(CallContextData, function) + 8); -#define GlobalContextMembers(class, Member) \ - Member(class, Pointer, Object *, global) +#define GlobalContextMembers(class, Member) DECLARE_HEAP_OBJECT(GlobalContext, ExecutionContext) { DECLARE_MARK_TABLE(GlobalContext); @@ -219,8 +218,7 @@ DECLARE_HEAP_OBJECT(CatchContext, ExecutionContext) { }; V4_ASSERT_IS_TRIVIAL(CatchContext) -#define WithContextMembers(class, Member) \ - Member(class, Pointer, Object *, withObject) +#define WithContextMembers(class, Member) DECLARE_HEAP_OBJECT(WithContext, ExecutionContext) { DECLARE_MARK_TABLE(WithContext); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 0ee7445477..d17af43ca4 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -398,7 +398,7 @@ ExecutionEngine::ExecutionEngine() // // set up the global object // - rootContext()->d()->global.set(scope.engine, globalObject->d()); + rootContext()->d()->activation.set(scope.engine, globalObject->d()); rootContext()->d()->callData->thisObject = globalObject; Q_ASSERT(globalObject->d()->vtable()); @@ -770,7 +770,7 @@ QObject *ExecutionEngine::qmlScopeObject() const if (!ctx) return 0; - return ctx->qml->scopeObject; + return ctx->qml()->scopeObject; } ReturnedValue ExecutionEngine::qmlSingletonWrapper(String *name) @@ -800,7 +800,7 @@ QQmlContextData *ExecutionEngine::callingQmlContext() const if (!ctx) return 0; - return ctx->qml->context->contextData(); + return ctx->qml()->context->contextData(); } QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index 61d785066f..13243e1575 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -305,7 +305,7 @@ void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QQmlContex constantTable = outer->constantTable; compilationUnit = outer->compilationUnit; - this->qml.set(internalClass->engine, qml->d()); + this->activation.set(internalClass->engine, qml->d()); } Heap::QmlContext *QmlContext::createWorkerContext(ExecutionContext *parent, const QUrl &source, Value *sendFunction) diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h index 2f1dbabaf2..9faf58d496 100644 --- a/src/qml/jsruntime/qv4qmlcontext_p.h +++ b/src/qml/jsruntime/qv4qmlcontext_p.h @@ -77,12 +77,12 @@ struct QQmlContextWrapper : Object { QQmlQPointer<QObject> scopeObject; }; -#define QmlContextMembers(class, Member) \ - Member(class, Pointer, QQmlContextWrapper *, qml) +#define QmlContextMembers(class, Member) DECLARE_HEAP_OBJECT(QmlContext, ExecutionContext) { DECLARE_MARK_TABLE(QmlContext); + QQmlContextWrapper *qml() { return static_cast<QQmlContextWrapper *>(activation.get()); } void init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml); }; @@ -114,14 +114,14 @@ struct Q_QML_EXPORT QmlContext : public ExecutionContext static Heap::QmlContext *create(QV4::ExecutionContext *parent, QQmlContextData *context, QObject *scopeObject); QObject *qmlScope() const { - return d()->qml->scopeObject; + return d()->qml()->scopeObject; } QQmlContextData *qmlContext() const { - return *d()->qml->context; + return *d()->qml()->context; } void takeContextOwnership() { - d()->qml->ownsContext = true; + d()->qml()->ownsContext = true; } }; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 4a61a7e37e..81ec903d18 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1455,20 +1455,20 @@ ReturnedValue Runtime::method_regexpLiteral(ExecutionEngine *engine, int id) ReturnedValue Runtime::method_getQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired) { const QmlContext &c = static_cast<const QmlContext &>(context); - return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->scopeObject, propertyIndex, captureRequired); + return QV4::QObjectWrapper::getProperty(engine, c.d()->qml()->scopeObject, propertyIndex, captureRequired); } ReturnedValue Runtime::method_getQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired) { const QmlContext &c = static_cast<const QmlContext &>(context); - return QV4::QObjectWrapper::getProperty(engine, (*c.d()->qml->context)->contextObject, propertyIndex, captureRequired); + return QV4::QObjectWrapper::getProperty(engine, (*c.d()->qml()->context)->contextObject, propertyIndex, captureRequired); } ReturnedValue Runtime::method_getQmlIdObject(ExecutionEngine *engine, const Value &c, uint index) { Scope scope(engine); const QmlContext &qmlContext = static_cast<const QmlContext &>(c); - QQmlContextData *context = *qmlContext.d()->qml->context; + QQmlContextData *context = *qmlContext.d()->qml()->context; if (!context || index >= (uint)context->idValueCount) return Encode::undefined(); @@ -1482,13 +1482,13 @@ ReturnedValue Runtime::method_getQmlIdObject(ExecutionEngine *engine, const Valu void Runtime::method_setQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value) { const QmlContext &c = static_cast<const QmlContext &>(context); - return QV4::QObjectWrapper::setProperty(engine, c.d()->qml->scopeObject, propertyIndex, value); + return QV4::QObjectWrapper::setProperty(engine, c.d()->qml()->scopeObject, propertyIndex, value); } void Runtime::method_setQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value) { const QmlContext &c = static_cast<const QmlContext &>(context); - return QV4::QObjectWrapper::setProperty(engine, (*c.d()->qml->context)->contextObject, propertyIndex, value); + return QV4::QObjectWrapper::setProperty(engine, (*c.d()->qml()->context)->contextObject, propertyIndex, value); } ReturnedValue Runtime::method_getQmlImportedScripts(NoThrowEngine *engine) diff --git a/src/qml/memory/qv4writebarrier_p.h b/src/qml/memory/qv4writebarrier_p.h index 3182fd2aa9..16aec08301 100644 --- a/src/qml/memory/qv4writebarrier_p.h +++ b/src/qml/memory/qv4writebarrier_p.h @@ -127,6 +127,8 @@ struct Pointer { WriteBarrier::write(e, base(), reinterpret_cast<Heap::Base **>(&ptr), reinterpret_cast<Heap::Base *>(newVal)); } + T get() { return ptr; } + template <typename Type> Type *cast() { return static_cast<Type *>(ptr); } diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp index 13e62ec696..0c82eadc97 100644 --- a/src/qml/qml/qqmldelayedcallqueue.cpp +++ b/src/qml/qml/qqmldelayedcallqueue.cpp @@ -158,8 +158,8 @@ void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction dfc.m_guarded = true; } else if (func->scope()->type == QV4::Heap::ExecutionContext::Type_QmlContext) { QV4::QmlContext::Data *g = static_cast<QV4::QmlContext::Data *>(func->scope()); - Q_ASSERT(g->qml->scopeObject); - dfc.m_objectGuard = QQmlGuard<QObject>(g->qml->scopeObject); + Q_ASSERT(g->qml()->scopeObject); + dfc.m_objectGuard = QQmlGuard<QObject>(g->qml()->scopeObject); dfc.m_guarded = true; } } diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 0feedc19cd..de19fe3cd7 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2869,7 +2869,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent ep->warning(error); } - QV4::ScopedValue retval(scope, qmlContext->d()->qml); + QV4::ScopedValue retval(scope, qmlContext->d()->qml()); if (shared) { m_value.set(scope.engine, retval); m_loaded = true; diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp index 6159355afc..6b7e3dee9f 100644 --- a/src/qml/types/qquickworkerscript.cpp +++ b/src/qml/types/qquickworkerscript.cpp @@ -365,7 +365,7 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d QV4::ScopedCallData callData(scope, 2); callData->thisObject = workerEngine->global(); - callData->args[0] = qmlContext->d()->qml; // ### + callData->args[0] = qmlContext->d()->qml(); // ### callData->args[1] = value; f->call(scope, callData); if (scope.hasException()) { |