From e739486290c7ae1e7390a043e29c716a3e23dd03 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 5 Apr 2013 11:52:08 +0200 Subject: [PATCH] Introduce different context types These will be used to split up the context into more specialized subclasses. Change-Id: Ic346c1738ad6e9c4d78e2e6f51133c8ea781f59b Reviewed-by: Simon Hausmann --- src/v4/qv4context.cpp | 71 +++++++++++++++++++++++++--------------------- src/v4/qv4context.h | 21 ++++++++++---- src/v4/qv4globalobject.cpp | 2 +- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/v4/qv4context.cpp b/src/v4/qv4context.cpp index 88365f4..61f7557 100644 --- a/src/v4/qv4context.cpp +++ b/src/v4/qv4context.cpp @@ -98,7 +98,8 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) bool ExecutionContext::setMutableBinding(ExecutionContext *scope, String *name, const Value &value) { // ### throw if scope->strict is true, and it would change an immutable binding - if (function) { + if (type == CallContext) { + assert(function); for (unsigned int i = 0; i < function->varCount; ++i) if (function->varList[i]->isEqualTo(name)) { locals[i] = value; @@ -111,7 +112,7 @@ bool ExecutionContext::setMutableBinding(ExecutionContext *scope, String *name, } } - if (activation && (qmlObject || activation->__hasProperty__(scope, name))) { + if (activation && (type == QmlContext || activation->__hasProperty__(scope, name))) { activation->put(scope, name, value); return true; } @@ -124,7 +125,8 @@ Value ExecutionContext::getBindingValue(ExecutionContext *scope, String *name, b Q_UNUSED(strict); assert(function); - if (function) { + if (type == CallContext) { + assert(function); for (unsigned int i = 0; i < function->varCount; ++i) if (function->varList[i]->isEqualTo(name)) return locals[i]; @@ -175,6 +177,7 @@ unsigned int ExecutionContext::variableCount() const void ExecutionContext::init(ExecutionEngine *eng) { + type = GlobalContext; marked = false; engine = eng; outer = 0; @@ -190,13 +193,13 @@ void ExecutionContext::init(ExecutionEngine *eng) exceptionVarName = 0; exceptionValue = Value::undefinedValue(); strictMode = false; - qmlObject = false; activation = 0; withObject = 0; } void ExecutionContext::init(ExecutionContext *p, Object *with) { + type = WithContext; marked = false; engine = p->engine; outer = p; @@ -212,13 +215,13 @@ void ExecutionContext::init(ExecutionContext *p, Object *with) exceptionVarName = 0; exceptionValue = Value::undefinedValue(); strictMode = false; - qmlObject = false; activation = 0; withObject = with; } void ExecutionContext::initForCatch(ExecutionContext *p, String *exceptionVarName, const Value &exceptionValue) { + type = CatchContext; marked = false; engine = p->engine; outer = p; @@ -232,7 +235,6 @@ void ExecutionContext::initForCatch(ExecutionContext *p, String *exceptionVarNam this->exceptionVarName = exceptionVarName; this->exceptionValue = exceptionValue; strictMode = p->strictMode; - qmlObject = false; activation = 0; withObject = 0; } @@ -241,7 +243,7 @@ bool ExecutionContext::deleteProperty(String *name) { bool hasWith = false; for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) { - if (ctx->withObject) { + if (ctx->type == WithContext) { hasWith = true; if (ctx->withObject->__hasProperty__(this, name)) return ctx->withObject->deleteProperty(this, name); @@ -249,9 +251,10 @@ bool ExecutionContext::deleteProperty(String *name) if (ctx->activation && ctx->activation->__hasProperty__(this, name)) return ctx->activation->deleteProperty(this, name); } - if (ctx->exceptionVarName && ctx->exceptionVarName->isEqualTo(name)) + if (ctx->type == CatchContext && ctx->exceptionVarName->isEqualTo(name)) return false; - if (FunctionObject *f = ctx->function) { + if (ctx->type == CallContext) { + FunctionObject *f = ctx->function; if (f->needsActivation || hasWith) { for (unsigned int i = 0; i < f->varCount; ++i) if (f->varList[i]->isEqualTo(name)) @@ -299,20 +302,17 @@ void ExecutionContext::mark() void ExecutionContext::setProperty(String *name, const Value& value) { -// qDebug() << "=== SetProperty" << value.toString(this)->toQString(); for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) { - if (Object *w = ctx->withObject) { -// qDebug() << ctx << "hasWith"; + if (ctx->type == WithContext) { + Object *w = ctx->withObject; if (w->__hasProperty__(ctx, name)) { -// qDebug() << " withHasProp"; w->put(ctx, name, value); return; } - } else if (ctx->exceptionVarName && ctx->exceptionVarName->isEqualTo(name)) { + } else if (ctx->type == CatchContext && ctx->exceptionVarName->isEqualTo(name)) { ctx->exceptionValue = value; return; } else { -// qDebug() << ctx << "setting mutable binding"; if (ctx->setMutableBinding(this, name, value)) return; } @@ -331,27 +331,26 @@ Value ExecutionContext::getProperty(String *name) bool hasWith = false; bool hasCatchScope = false; -// qDebug() << "=== getProperty" << name->toQString(); for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) { - if (Object *w = ctx->withObject) { + if (ctx->type == WithContext) { + Object *w = ctx->withObject; hasWith = true; -// qDebug() << ctx << "hasWith"; bool hasProperty = false; Value v = w->get(ctx, name, &hasProperty); if (hasProperty) { -// qDebug() << " withHasProp"; return v; } continue; } - if (ctx->exceptionVarName) { + if (ctx->type == CatchContext) { hasCatchScope = true; if (ctx->exceptionVarName->isEqualTo(name)) return ctx->exceptionValue; } - if (FunctionObject *f = ctx->function) { + if (ctx->type == CallContext) { + FunctionObject *f = ctx->function; if (f->needsActivation || hasWith || hasCatchScope) { for (unsigned int i = 0; i < f->varCount; ++i) if (f->varList[i]->isEqualTo(name)) @@ -367,7 +366,8 @@ Value ExecutionContext::getProperty(String *name) if (hasProperty) return v; } - if (FunctionObject *f = ctx->function) { + if (ctx->type == CallContext) { + FunctionObject *f = ctx->function; if (f->function && f->function->isNamedExpression && name->isEqualTo(f->function->name)) return Value::fromObject(ctx->function); @@ -387,22 +387,25 @@ Value ExecutionContext::getPropertyNoThrow(String *name) bool hasWith = false; bool hasCatchScope = false; for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) { - if (Object *w = ctx->withObject) { + if (ctx->type == WithContext) { + Object *w = ctx->withObject; hasWith = true; bool hasProperty = false; Value v = w->get(ctx, name, &hasProperty); - if (hasProperty) + if (hasProperty) { return v; + } continue; } - if (ctx->exceptionVarName) { + if (ctx->type == CatchContext) { hasCatchScope = true; if (ctx->exceptionVarName->isEqualTo(name)) return ctx->exceptionValue; } - if (FunctionObject *f = ctx->function) { + if (ctx->type == CallContext) { + FunctionObject *f = ctx->function; if (f->needsActivation || hasWith || hasCatchScope) { for (unsigned int i = 0; i < f->varCount; ++i) if (f->varList[i]->isEqualTo(name)) @@ -418,7 +421,8 @@ Value ExecutionContext::getPropertyNoThrow(String *name) if (hasProperty) return v; } - if (FunctionObject *f = ctx->function) { + if (ctx->type == CallContext) { + FunctionObject *f = ctx->function; if (f->function && f->function->isNamedExpression && name->isEqualTo(f->function->name)) return Value::fromObject(ctx->function); @@ -438,7 +442,8 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base) bool hasWith = false; bool hasCatchScope = false; for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) { - if (Object *w = ctx->withObject) { + if (ctx->type == WithContext) { + Object *w = ctx->withObject; hasWith = true; bool hasProperty = false; Value v = w->get(ctx, name, &hasProperty); @@ -449,13 +454,14 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base) continue; } - if (ctx->exceptionVarName) { + if (ctx->type == CatchContext) { hasCatchScope = true; if (ctx->exceptionVarName->isEqualTo(name)) return ctx->exceptionValue; } - if (FunctionObject *f = ctx->function) { + if (ctx->type == CallContext) { + FunctionObject *f = ctx->function; if (f->needsActivation || hasWith || hasCatchScope) { for (unsigned int i = 0; i < f->varCount; ++i) if (f->varList[i]->isEqualTo(name)) @@ -471,7 +477,8 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base) if (hasProperty) return v; } - if (FunctionObject *f = ctx->function) { + if (ctx->type == CallContext) { + FunctionObject *f = ctx->function; if (f->function && f->function->isNamedExpression && name->isEqualTo(f->function->name)) return Value::fromObject(ctx->function); @@ -539,6 +546,7 @@ void ExecutionContext::throwURIError(Value msg) void ExecutionContext::initCallContext(ExecutionEngine *engine) { + type = CallContext; marked = false; this->engine = engine; outer = function->scope; @@ -553,7 +561,6 @@ void ExecutionContext::initCallContext(ExecutionEngine *engine) withObject = 0; strictMode = function->strictMode; - qmlObject = false; if (function->function) lookups = function->function->lookups; diff --git a/src/v4/qv4context.h b/src/v4/qv4context.h index 454cedb..0eec776 100644 --- a/src/v4/qv4context.h +++ b/src/v4/qv4context.h @@ -75,26 +75,37 @@ struct Q_V4_EXPORT DiagnosticMessage struct ExecutionContext { - ExecutionContext *next; // used in the GC + enum Type { + GlobalContext = 0x1, + SimpleCallContext = 0x2, + CallContext = 0x3, + CatchContext = 0x4, + WithContext = 0x5, + QmlContext = 0x6 + }; + ExecutionEngine *engine; ExecutionContext *outer; Value thisObject; + Value *arguments; + unsigned int argumentCount; + Type type; + + // ### remove me + Object *activation; FunctionObject *function; Lookup *lookups; - Value *arguments; - unsigned int argumentCount; Value *locals; + ExecutionContext *next; // used in the GC String *exceptionVarName; Value exceptionValue; bool strictMode; - bool qmlObject; // ## temporary until we do proper QML contexts bool marked; - Object *activation; Object *withObject; String * const *formals() const; diff --git a/src/v4/qv4globalobject.cpp b/src/v4/qv4globalobject.cpp index 1527798..7e03354 100644 --- a/src/v4/qv4globalobject.cpp +++ b/src/v4/qv4globalobject.cpp @@ -397,7 +397,7 @@ Value EvalFunction::evalCall(ExecutionContext *parentContext, Value /*thisObject ExecutionContext *k = ctx->engine->newCallContext(this, ctx->thisObject, 0, 0); if (qmlActivation) { k->activation = qmlActivation; - k->qmlObject = qmlActivation; + k->type = ExecutionContext::QmlContext; } ctx = k; } -- 2.7.4