aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-07-04 16:07:50 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2017-07-05 09:05:55 +0000
commitcfb17c44cf3ae1268d066ba414759068059a7bbd (patch)
tree58efa2997a5ac52b7d1f11ec0c8de2754f02f03b /src
parent79ceef9f467d065c6e921892e9cc4ed46a0183cc (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')
-rw-r--r--src/qml/jsruntime/qv4context.cpp103
-rw-r--r--src/qml/jsruntime/qv4context_p.h16
-rw-r--r--src/qml/jsruntime/qv4engine.cpp6
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp2
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h10
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp10
-rw-r--r--src/qml/memory/qv4writebarrier_p.h2
-rw-r--r--src/qml/qml/qqmldelayedcallqueue.cpp4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp2
-rw-r--r--src/qml/types/qquickworkerscript.cpp2
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()) {