Added support for arbitrary expression references.
authorDavid Anderson <dvander@alliedmods.net>
Sat Jun 30 22:45:25 2012 -0700 (2012-06-30)
changeset 1623627f8bc421
parent 15 d8ed9b8f19ca
child 17 8aa89dd41e25
Added support for arbitrary expression references.
jitcraft/BytecodeCompiler.cpp
jitcraft/BytecodeEmitter.h
jitcraft/Interpreter.cpp
jitcraft/Opcodes.cpp
jitcraft/Scopes.cpp
jitcraft/main.cpp
tests/prototype/ref-expr.sp
     1.1 --- a/jitcraft/BytecodeCompiler.cpp	Sat Jun 30 22:34:48 2012 -0700
     1.2 +++ b/jitcraft/BytecodeCompiler.cpp	Sat Jun 30 22:45:25 2012 -0700
     1.3 @@ -149,7 +149,6 @@
     1.4                  }
     1.5              }
     1.6          }
     1.7 -
     1.8          break;
     1.9        }
    1.10  
    1.11 @@ -179,14 +178,8 @@
    1.12          Variable *var = proxy->binding()->toVariable();
    1.13  
    1.14          // Make sure to bind the left-hand side first.
    1.15 -        if (var->type()->isReference()) {
    1.16 -            if (var->location() == Variable::STACK) {
    1.17 -                __ getlocal(var->slot());
    1.18 -            } else {
    1.19 -                assert(var->location() == Variable::PARAMETER);
    1.20 -                __ getarg(var->slot());
    1.21 -            }
    1.22 -        }
    1.23 +        if (var->type()->isReference())
    1.24 +            __ get(var);
    1.25  
    1.26          node->expression()->accept(this);
    1.27  
    1.28 @@ -198,12 +191,7 @@
    1.29                  __ setref_i();
    1.30              }
    1.31          } else {
    1.32 -            if (var->location() == Variable::STACK) {
    1.33 -                __ setlocal(var->slot());
    1.34 -            } else {
    1.35 -                assert(var->location() == Variable::PARAMETER);
    1.36 -                __ setarg(var->slot());
    1.37 -            }
    1.38 +            __ set(var);
    1.39          }
    1.40      } else if (node->lvalue()->isIndexExpression()) {
    1.41          IndexExpression *index = node->lvalue()->toIndexExpression();
    1.42 @@ -463,6 +451,7 @@
    1.43                  // We don't know how to, or can't, build a direct reference to
    1.44                  // this type. Make an indirect one, by taking the top of the
    1.45                  // stack and boxing it up.
    1.46 +                arg->accept(this);
    1.47                  __ slotref_lifo();
    1.48              }
    1.49          } else {
     2.1 --- a/jitcraft/BytecodeEmitter.h	Sat Jun 30 22:34:48 2012 -0700
     2.2 +++ b/jitcraft/BytecodeEmitter.h	Sat Jun 30 22:45:25 2012 -0700
     2.3 @@ -320,6 +320,23 @@
     2.4          }
     2.5          writeUint32(var->slot());
     2.6      }
     2.7 +    void get(Variable *var) {
     2.8 +        if (var->location() == Variable::STACK) {
     2.9 +            getlocal(var->slot());
    2.10 +        } else {
    2.11 +            assert(var->location() == Variable::PARAMETER);
    2.12 +            getarg(var->slot());
    2.13 +        }
    2.14 +    }
    2.15 +    void set(Variable *var) {
    2.16 +        assert(!var->type()->isReference());
    2.17 +        if (var->location() == Variable::STACK) {
    2.18 +            setlocal(var->slot());
    2.19 +        } else {
    2.20 +            assert(var->location() == Variable::PARAMETER);
    2.21 +            setarg(var->slot());
    2.22 +        }
    2.23 +    }
    2.24      void slotref_lifo() {
    2.25          singleByteOp(OP_SLOTREF_LIFO);
    2.26      }
     3.1 --- a/jitcraft/Interpreter.cpp	Sat Jun 30 22:34:48 2012 -0700
     3.2 +++ b/jitcraft/Interpreter.cpp	Sat Jun 30 22:45:25 2012 -0700
     3.3 @@ -485,6 +485,17 @@
     3.4      break;
     3.5  }
     3.6  
     3.7 +case OP_SLOTREF_LIFO:
     3.8 +{
     3.9 +    Reference *ref = Reference::NewStack(ZONE(),  top.sp[-1], Heap::Tenure_Stack);
    3.10 +    if (!ref) {
    3.11 +        assert(false);
    3.12 +        return false;
    3.13 +    }
    3.14 +    top.sp[-1].ref = ref;
    3.15 +    break;
    3.16 +}
    3.17 +
    3.18  case OP_GETREF_I:
    3.19  {
    3.20      top.sp[-1].i32 = top.sp[-1].ref->getInt();
     4.1 --- a/jitcraft/Opcodes.cpp	Sat Jun 30 22:34:48 2012 -0700
     4.2 +++ b/jitcraft/Opcodes.cpp	Sat Jun 30 22:45:25 2012 -0700
     4.3 @@ -98,6 +98,7 @@
     4.4            case OP_SETREF_I:
     4.5            case OP_GETREF_F:
     4.6            case OP_SETREF_F:
     4.7 +          case OP_SLOTREF_LIFO:
     4.8              break;
     4.9  
    4.10            case OP_STOP:
     5.1 --- a/jitcraft/Scopes.cpp	Sat Jun 30 22:34:48 2012 -0700
     5.2 +++ b/jitcraft/Scopes.cpp	Sat Jun 30 22:45:25 2012 -0700
     5.3 @@ -217,8 +217,9 @@
     5.4  
     5.5      // If the parent of this scope is the function scope, then this is the
     5.6      // function's block scope, and the lifo slot is part of the Frame instead.
     5.7 -    assert(kind() != FUNCTION);
     5.8 -    if (enclosing()->kind() == FUNCTION)
     5.9 +    // Note we can get a function scope here if we're making a temporary in a
    5.10 +    // function with no local variables.
    5.11 +    if (kind() == FUNCTION || enclosing()->kind() == FUNCTION)
    5.12          return;
    5.13  
    5.14      lifoSlot_ = new (pool_) Variable(this, NULL);
     6.1 --- a/jitcraft/main.cpp	Sat Jun 30 22:34:48 2012 -0700
     6.2 +++ b/jitcraft/main.cpp	Sat Jun 30 22:45:25 2012 -0700
     6.3 @@ -85,7 +85,7 @@
     6.4  
     6.5      printf("\n ------------ \n\n");
     6.6  
     6.7 -    Code *main = module->getFunction(2);
     6.8 +    Code *main = module->getFunction(1);
     6.9  
    6.10      Top top = ZONE()->stack().begin();
    6.11      LocalTop localTop(top);
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tests/prototype/ref-expr.sp	Sat Jun 30 22:45:25 2012 -0700
     7.3 @@ -0,0 +1,11 @@
     7.4 +f(&a)
     7.5 +{
     7.6 +    for (new i = 0; i < 10; i = i + 1)
     7.7 +        a = a + i;
     7.8 +    return a;
     7.9 +}
    7.10 +
    7.11 +main()
    7.12 +{
    7.13 +    return f(77);
    7.14 +}