Added support for arbitrary expression references.
Added support for arbitrary expression references.
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 +}