Move locals from ExecutionContext to CallContext
authorLars Knoll <lars.knoll@digia.com>
Fri, 5 Apr 2013 12:16:56 +0000 (14:16 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 5 Apr 2013 14:08:36 +0000 (16:08 +0200)
Change-Id: I3f6751fc7e0450a74339f1131b10b56a2ebe6a50
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/v4/debugging.cpp
src/v4/moth/qv4vme_moth.cpp
src/v4/qv4context.cpp
src/v4/qv4context.h
src/v4/qv4isel_masm.cpp

index 180958f..5760753 100644 (file)
@@ -72,8 +72,9 @@ VM::Value *FunctionState::argument(unsigned idx)
 
 VM::Value *FunctionState::local(unsigned idx)
 {
-    if (idx < _context->variableCount())
-        return _context->locals + idx;
+    VM::CallContext *c = _context->asCallContext();
+    if (c && idx < c->variableCount())
+        return c->locals + idx;
     return 0;
 }
 
index d5cbcd8..f4ac8f7 100644 (file)
@@ -151,10 +151,11 @@ static inline VM::Value *getValueRef(QQmlJS::VM::ExecutionContext *context,
     } else if (param.isLocal()) {
         VMSTATS(paramIsLocal);
         const unsigned index = param.index;
+        VM::CallContext *c = static_cast<VM::CallContext *>(context);
         Q_ASSERT(index >= 0);
         Q_ASSERT(index < context->variableCount());
-        Q_ASSERT(context->locals);
-        return context->locals + index;
+        Q_ASSERT(c->locals);
+        return c->locals + index;
     } else if (param.isTemp()) {
         VMSTATS(paramIsTemp);
         Q_ASSERT(param.index < stackSize);
@@ -166,10 +167,11 @@ static inline VM::Value *getValueRef(QQmlJS::VM::ExecutionContext *context,
         while (scope--)
             c = c->outer;
         const unsigned index = param.index;
+        VM::CallContext *cc = static_cast<VM::CallContext *>(c);
         Q_ASSERT(index >= 0);
-        Q_ASSERT(index < c->variableCount());
-        Q_ASSERT(c->locals);
-        return c->locals + index;
+        Q_ASSERT(index < cc->variableCount());
+        Q_ASSERT(cc->locals);
+        return cc->locals + index;
     } else {
         Q_UNIMPLEMENTED();
         return 0;
index 202acc8..274b2eb 100644 (file)
@@ -99,15 +99,16 @@ bool ExecutionContext::setMutableBinding(ExecutionContext *scope, String *name,
 {
     // ### throw if scope->strict is true, and it would change an immutable binding
     if (type == Type_CallContext) {
+        CallContext *c = static_cast<CallContext *>(this);
         assert(function);
-        for (unsigned int i = 0; i < function->varCount; ++i)
-            if (function->varList[i]->isEqualTo(name)) {
-                locals[i] = value;
+        for (unsigned int i = 0; i < c->function->varCount; ++i)
+            if (c->function->varList[i]->isEqualTo(name)) {
+                c->locals[i] = value;
                 return true;
             }
-        for (int i = (int)function->formalParameterCount - 1; i >= 0; --i)
-            if (function->formalParameterList[i]->isEqualTo(name)) {
-                arguments[i] = value;
+        for (int i = (int)c->function->formalParameterCount - 1; i >= 0; --i)
+            if (c->function->formalParameterList[i]->isEqualTo(name)) {
+                c->arguments[i] = value;
                 return true;
             }
     }
@@ -127,12 +128,13 @@ Value ExecutionContext::getBindingValue(ExecutionContext *scope, String *name, b
 
     if (type == Type_CallContext) {
         assert(function);
+        const CallContext *c = static_cast<const CallContext *>(this);
         for (unsigned int i = 0; i < function->varCount; ++i)
-            if (function->varList[i]->isEqualTo(name))
-                return locals[i];
-        for (int i = (int)function->formalParameterCount - 1; i >= 0; --i)
-            if (function->formalParameterList[i]->isEqualTo(name))
-                return arguments[i];
+            if (c->function->varList[i]->isEqualTo(name))
+                return c->locals[i];
+        for (int i = (int)c->function->formalParameterCount - 1; i >= 0; --i)
+            if (c->function->formalParameterList[i]->isEqualTo(name))
+                return c->arguments[i];
     }
 
     if (activation) {
@@ -190,7 +192,6 @@ void GlobalContext::init(ExecutionEngine *eng)
     argumentCount = 0;
     activation = 0;
     function = 0;
-    locals = 0;
 }
 
 void WithContext::init(ExecutionContext *p, Object *with)
@@ -210,7 +211,6 @@ void WithContext::init(ExecutionContext *p, Object *with)
     argumentCount = 0;
     activation = 0;
     function = 0;
-    locals = 0;
 }
 
 void CatchContext::init(ExecutionContext *p, String *exceptionVarName, const Value &exceptionValue)
@@ -231,7 +231,6 @@ void CatchContext::init(ExecutionContext *p, String *exceptionVarName, const Val
     argumentCount = 0;
     activation = 0;
     function = 0;
-    locals = 0;
 }
 
 void CallContext::initCallContext(ExecutionEngine *engine)
@@ -334,8 +333,13 @@ void ExecutionContext::mark()
         function->mark();
     for (unsigned arg = 0, lastArg = argumentCount; arg < lastArg; ++arg)
         arguments[arg].mark();
-    for (unsigned local = 0, lastLocal = variableCount(); local < lastLocal; ++local)
-        locals[local].mark();
+
+    if (type == Type_CallContext) {
+        VM::CallContext *c = static_cast<CallContext *>(this);
+        for (unsigned local = 0, lastLocal = c->variableCount(); local < lastLocal; ++local)
+            c->locals[local].mark();
+    }
+
     if (activation)
         activation->mark();
     if (type == Type_WithContext) {
@@ -401,14 +405,15 @@ Value ExecutionContext::getProperty(String *name)
         }
 
         if (ctx->type == Type_CallContext) {
-            FunctionObject *f = ctx->function;
+            VM::CallContext *c = static_cast<CallContext *>(ctx);
+            FunctionObject *f = c->function;
             if (f->needsActivation || hasWith || hasCatchScope) {
                 for (unsigned int i = 0; i < f->varCount; ++i)
                     if (f->varList[i]->isEqualTo(name))
-                        return ctx->locals[i];
+                        return c->locals[i];
                 for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
                     if (f->formalParameterList[i]->isEqualTo(name))
-                        return ctx->arguments[i];
+                        return c->arguments[i];
             }
         }
         if (ctx->activation) {
@@ -457,14 +462,15 @@ Value ExecutionContext::getPropertyNoThrow(String *name)
         }
 
         if (ctx->type == Type_CallContext) {
-            FunctionObject *f = ctx->function;
+            VM::CallContext *c = static_cast<CallContext *>(ctx);
+            FunctionObject *f = c->function;
             if (f->needsActivation || hasWith || hasCatchScope) {
                 for (unsigned int i = 0; i < f->varCount; ++i)
                     if (f->varList[i]->isEqualTo(name))
-                        return ctx->locals[i];
+                        return c->locals[i];
                 for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
                     if (f->formalParameterList[i]->isEqualTo(name))
-                        return ctx->arguments[i];
+                        return c->arguments[i];
             }
         }
         if (ctx->activation) {
@@ -514,14 +520,15 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base)
         }
 
         if (ctx->type == Type_CallContext) {
-            FunctionObject *f = ctx->function;
+            VM::CallContext *c = static_cast<CallContext *>(ctx);
+            FunctionObject *f = c->function;
             if (f->needsActivation || hasWith || hasCatchScope) {
                 for (unsigned int i = 0; i < f->varCount; ++i)
                     if (f->varList[i]->isEqualTo(name))
-                        return ctx->locals[i];
+                        return c->locals[i];
                 for (int i = (int)f->formalParameterCount - 1; i >= 0; --i)
                     if (f->formalParameterList[i]->isEqualTo(name))
-                        return ctx->arguments[i];
+                        return c->arguments[i];
             }
         }
         if (ctx->activation) {
index b97d8be..a1da174 100644 (file)
@@ -73,6 +73,8 @@ struct Q_V4_EXPORT DiagnosticMessage
     String *buildFullMessage(ExecutionContext *ctx) const;
 };
 
+struct CallContext;
+
 struct ExecutionContext
 {
     enum Type {
@@ -100,7 +102,6 @@ struct ExecutionContext
     unsigned int argumentCount;
     Object *activation;
     FunctionObject *function;
-    Value *locals;
 
     String * const *formals() const;
     unsigned int formalCount() const;
@@ -135,11 +136,15 @@ struct ExecutionContext
     bool needsOwnArguments() const;
 
     void mark();
+
+    inline CallContext *asCallContext();
 };
 
 struct CallContext : public ExecutionContext
 {
     void initCallContext(QQmlJS::VM::ExecutionEngine *engine);
+
+    Value *locals;
 };
 
 struct GlobalContext : public ExecutionContext
@@ -172,6 +177,11 @@ inline Value ExecutionContext::argument(unsigned int index)
     return Value::undefinedValue();
 }
 
+inline CallContext *ExecutionContext::asCallContext()
+{
+    return type == Type_CallContext ? static_cast<CallContext *>(this) : 0;
+}
+
 /* Function *f, int argc */
 #define requiredMemoryForExecutionContect(f, argc) \
     sizeof(CallContext) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount))
index 30f5b3f..2cb1031 100644 (file)
@@ -160,7 +160,7 @@ Assembler::Pointer Assembler::loadTempAddress(RegisterID reg, V4IR::Temp *t)
         loadPtr(Address(context, offsetof(ExecutionContext, arguments)), reg);
         offset = arg * sizeof(Value);
     } else if (t->index < f->locals.size()) {
-        loadPtr(Address(context, offsetof(ExecutionContext, locals)), reg);
+        loadPtr(Address(context, offsetof(CallContext, locals)), reg);
         offset = t->index * sizeof(Value);
     } else {
         assert(t->scope == 0);