Clean up the DeclarativeEnvironment
authorLars Knoll <lars.knoll@digia.com>
Fri, 30 Nov 2012 08:48:46 +0000 (09:48 +0100)
committerErik Verbruggen <erik.verbruggen@digia.com>
Fri, 30 Nov 2012 11:30:14 +0000 (12:30 +0100)
Add a pointer to the FunctionObject in there, and remove the
duplication of the formal and local variable names.

Change-Id: Id8017b3e167228292b5d351e02b8927f0bfb41eb
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
debugging.cpp
moth/qv4vme_moth.cpp
qmljs_environment.cpp
qmljs_environment.h
qmljs_objects.cpp
qmljs_objects.h

index e55660e..a54c1a0 100644 (file)
@@ -58,10 +58,9 @@ VM::Value *FunctionState::argument(unsigned idx)
 
 VM::Value *FunctionState::local(unsigned idx)
 {
-    if (idx < _context->lexicalEnvironment->varCount)
+    if (idx < _context->lexicalEnvironment->variableCount())
         return _context->lexicalEnvironment->locals + idx;
-    else
-        return 0;
+    return 0;
 }
 
 Debugger::Debugger(VM::ExecutionEngine *engine)
index e71733d..ff42684 100644 (file)
@@ -80,13 +80,13 @@ static inline VM::Value *tempValue(QQmlJS::VM::ExecutionContext *context, QVecto
         Q_ASSERT(varEnv->arguments);
 
         return varEnv->arguments + arg;
-    } else if (index < (int) varEnv->varCount) {
+    } else if (index < (int) varEnv->variableCount()) {
         Q_ASSERT(index >= 0);
         Q_ASSERT(varEnv->locals);
 
         return varEnv->locals + index;
     } else {
-        int off = index - varEnv->varCount;
+        int off = index - varEnv->variableCount();
 
         Q_ASSERT(off >= 0);
         Q_ASSERT(off < stack.size());
@@ -231,21 +231,21 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
             }
         }
 #endif // DO_TRACE_INSTR
-        quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
+        quint32 argStart = instr.args - context->lexicalEnvironment->variableCount();
         TRACE(Call, "value index = %d, argStart = %d, argc = %d, result temp index = %d", instr.destIndex, argStart, instr.argc, instr.targetTempIndex);
         VM::Value *args = stack.data() + argStart;
         TEMP(instr.targetTempIndex) = __qmljs_call_value(context, VM::Value::undefinedValue(), TEMP(instr.destIndex), args, instr.argc);
     MOTH_END_INSTR(CallValue)
 
     MOTH_BEGIN_INSTR(CallProperty)
-        quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
+        quint32 argStart = instr.args - context->lexicalEnvironment->variableCount();
         VM::Value *args = stack.data() + argStart;
         VM::Value base = TEMP(instr.baseTemp);
         TEMP(instr.targetTempIndex) = __qmljs_call_property(context, base, instr.name, args, instr.argc);
     MOTH_END_INSTR(CallProperty)
 
     MOTH_BEGIN_INSTR(CallBuiltin)
-        quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
+        quint32 argStart = instr.args - context->lexicalEnvironment->variableCount();
         VM::Value *args = stack.data() + argStart;
         void *buf;
         switch (instr.builtin) {
@@ -325,20 +325,20 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
     MOTH_END_INSTR(CallBuiltinDeleteValue)
 
     MOTH_BEGIN_INSTR(CreateValue)
-        quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
+        quint32 argStart = instr.args - context->lexicalEnvironment->variableCount();
         VM::Value *args = stack.data() + argStart;
         TEMP(instr.targetTempIndex) = __qmljs_construct_value(context, TEMP(instr.func), args, instr.argc);
     MOTH_END_INSTR(CreateValue)
 
     MOTH_BEGIN_INSTR(CreateProperty)
-        quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
+        quint32 argStart = instr.args - context->lexicalEnvironment->variableCount();
         VM::Value *args = stack.data() + argStart;
         TEMP(instr.targetTempIndex) = __qmljs_construct_property(context, TEMP(instr.base), instr.name, args, instr.argc);
     MOTH_END_INSTR(CreateProperty)
 
     MOTH_BEGIN_INSTR(CreateActivationProperty)
         TRACE(inline, "property name = %s, argc = %d", instr.name->toQString().toUtf8().constData(), instr.argc);
-        quint32 argStart = instr.args - context->lexicalEnvironment->varCount;
+        quint32 argStart = instr.args - context->lexicalEnvironment->variableCount();
         VM::Value *args = stack.data() + argStart;
         TEMP(instr.targetTempIndex) = __qmljs_construct_activation_property(context, instr.name, args, instr.argc);
     MOTH_END_INSTR(CreateActivationProperty)
index a47698c..326ed93 100644 (file)
@@ -77,13 +77,10 @@ void DeclarativeEnvironment::init(ExecutionEngine *e)
 {
     engine = e;
     outer = 0;
+    function = 0;
     arguments = 0;
     argumentCount = 0;
     locals = 0;
-    formals = 0;
-    formalCount = 0;
-    vars = 0;
-    varCount = 0;
     activation = 0;
     withObject = 0;
     strictMode = false;
@@ -91,28 +88,25 @@ void DeclarativeEnvironment::init(ExecutionEngine *e)
 
 void DeclarativeEnvironment::init(FunctionObject *f, Value *args, uint argc)
 {
-    outer = f->scope;
+    function = f;
+    outer = function->scope;
     engine = outer->engine;
     strictMode = f->strictMode;
 
-    formals = f->formalParameterList;
-    formalCount = f->formalParameterCount;
     arguments = args;
     argumentCount = argc;
-    if (f->needsActivation || argc < formalCount){
-        arguments = new Value[qMax(argc, formalCount)];
+    if (function->needsActivation || argc < function->formalParameterCount){
+        arguments = new Value[qMax(argc, function->formalParameterCount)];
         if (argc)
             std::copy(args, args + argc, arguments);
-        if (argc < formalCount)
-            std::fill(arguments + argc, arguments + formalCount, Value::undefinedValue());
+        if (argc < function->formalParameterCount)
+            std::fill(arguments + argc, arguments + function->formalParameterCount, Value::undefinedValue());
     }
-    vars = f->varList;
-    varCount = f->varCount;
-    locals = varCount ? new Value[varCount] : 0;
-    if (varCount)
-        std::fill(locals, locals + varCount, Value::undefinedValue());
+    locals = function->varCount ? new Value[function->varCount] : 0;
+    if (function->varCount)
+        std::fill(locals, locals + function->varCount, Value::undefinedValue());
 
-    if (f->needsActivation)
+    if (function->needsActivation)
         activation = engine->newActivationObject(this);
     else
         activation = 0;
@@ -122,12 +116,15 @@ void DeclarativeEnvironment::init(FunctionObject *f, Value *args, uint argc)
 
 bool DeclarativeEnvironment::hasBinding(String *name) const
 {
-    for (unsigned int i = 0; i < varCount; ++i) {
-        if (__qmljs_string_equal(vars[i], name))
+    if (!function)
+        return false;
+
+    for (unsigned int i = 0; i < function->varCount; ++i) {
+        if (__qmljs_string_equal(function->varList[i], name))
             return true;
     }
-    for (unsigned int i = 0; i < formalCount; ++i) {
-        if (__qmljs_string_equal(formals[i], name))
+    for (unsigned int i = 0; i < function->formalParameterCount; ++i) {
+        if (__qmljs_string_equal(function->formalParameterList[i], name))
             return true;
     }
     return false;
@@ -152,16 +149,17 @@ void DeclarativeEnvironment::createMutableBinding(ExecutionContext *ctx, String
 void DeclarativeEnvironment::setMutableBinding(String *name, Value value, bool strict)
 {
     Q_UNUSED(strict);
+    assert(function);
 
     // ### throw if strict is true, and it would change an immutable binding
-    for (unsigned int i = 0; i < varCount; ++i) {
-        if (__qmljs_string_equal(vars[i], name)) {
+    for (unsigned int i = 0; i < variableCount(); ++i) {
+        if (__qmljs_string_equal(variables()[i], name)) {
             locals[i] = value;
             return;
         }
     }
-    for (unsigned int i = 0; i < formalCount; ++i) {
-        if (__qmljs_string_equal(formals[i], name)) {
+    for (unsigned int i = 0; i < formalCount(); ++i) {
+        if (__qmljs_string_equal(formals()[i], name)) {
             arguments[i] = value;
             return;
         }
@@ -172,13 +170,14 @@ void DeclarativeEnvironment::setMutableBinding(String *name, Value value, bool s
 Value DeclarativeEnvironment::getBindingValue(String *name, bool strict) const
 {
     Q_UNUSED(strict);
+    assert(function);
 
-    for (unsigned int i = 0; i < varCount; ++i) {
-        if (__qmljs_string_equal(vars[i], name))
+    for (unsigned int i = 0; i < variableCount(); ++i) {
+        if (__qmljs_string_equal(variables()[i], name))
             return locals[i];
     }
-    for (unsigned int i = 0; i < formalCount; ++i) {
-        if (__qmljs_string_equal(formals[i], name))
+    for (unsigned int i = 0; i < formalCount(); ++i) {
+        if (__qmljs_string_equal(formals()[i], name))
             return arguments[i];
     }
     assert(false);
@@ -211,6 +210,27 @@ void DeclarativeEnvironment::popWithObject()
     delete w;
 }
 
+String **DeclarativeEnvironment::formals() const
+{
+    return function ? function->formalParameterList : 0;
+}
+
+unsigned int DeclarativeEnvironment::formalCount() const
+{
+    return function ? function->formalParameterCount : 0;
+}
+
+String **DeclarativeEnvironment::variables() const
+{
+    return function ? function->varList : 0;
+}
+
+unsigned int DeclarativeEnvironment::variableCount() const
+{
+    return function ? function->varCount : 0;
+}
+
+
 void ExecutionContext::init(ExecutionEngine *eng)
 {
     engine = eng;
@@ -357,6 +377,5 @@ void ExecutionContext::wireUpPrototype(FunctionObject *f)
         thisObject.objectValue()->prototype = engine->objectPrototype;
 }
 
-
 } // namespace VM
 } // namespace QQmlJS
index 235d1bf..6caada9 100644 (file)
@@ -76,13 +76,15 @@ struct DeclarativeEnvironment
     ExecutionEngine *engine;
     DeclarativeEnvironment *outer;
 
+    FunctionObject *function;
+
     Value *arguments;
     unsigned int argumentCount;
     Value *locals;
-    String **formals;
-    unsigned int formalCount;
-    String **vars;
-    unsigned int varCount;
+    String **formals() const;
+    unsigned int formalCount() const;
+    String **variables() const;
+    unsigned int variableCount() const;
     bool strictMode;
 
     Object *activation;
index 9fa63fa..09e937d 100644 (file)
@@ -434,6 +434,10 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, IR::Function *function)
     : FunctionObject(scope)
     , function(function)
 {
+    // global function
+    if (!scope)
+        return;
+
     if (function->name)
         name = scope->engine->identifier(*function->name);
     needsActivation = function->needsActivation();
@@ -671,8 +675,8 @@ Value ScriptFunction::construct(VM::ExecutionContext *ctx)
 PropertyDescriptor *ActivationObject::__getPropertyDescriptor__(ExecutionContext *ctx, String *name, PropertyDescriptor *to_fill)
 {
     if (context) {
-        for (unsigned int i = 0; i < context->varCount; ++i) {
-            String *var = context->vars[i];
+        for (unsigned int i = 0; i < context->variableCount(); ++i) {
+            String *var = context->variables()[i];
             if (__qmljs_string_equal(var, name)) {
                 *to_fill = PropertyDescriptor::fromValue(context->locals[i]);
                 to_fill->writable = PropertyDescriptor::Set;
@@ -680,8 +684,8 @@ PropertyDescriptor *ActivationObject::__getPropertyDescriptor__(ExecutionContext
                 return to_fill;
             }
         }
-        for (unsigned int i = 0; i < context->formalCount; ++i) {
-            String *formal = context->formals[i];
+        for (unsigned int i = 0; i < context->formalCount(); ++i) {
+            String *formal = context->formals()[i];
             if (__qmljs_string_equal(formal, name)) {
                 *to_fill = PropertyDescriptor::fromValue(context->arguments[i]);
                 to_fill->writable = PropertyDescriptor::Set;
index f136304..a74f619 100644 (file)
@@ -500,7 +500,7 @@ struct FunctionObject: Object {
     bool strictMode;
 
     FunctionObject(ExecutionContext *scope)
-        : scope(scope->lexicalEnvironment)
+        : scope(scope ? scope->lexicalEnvironment : 0)
         , name(0)
         , formalParameterList(0)
         , formalParameterCount(0)