# HG changeset patch # User David Anderson # Date 1341121525 25200 # Node ID 23627f8bc421c2b9106c87de78b80f3b133178f6 # Parent d8ed9b8f19ca6900c6a8c647394596cfb559ede8 Added support for arbitrary expression references. diff -r d8ed9b8f19ca -r 23627f8bc421 jitcraft/BytecodeCompiler.cpp --- a/jitcraft/BytecodeCompiler.cpp Sat Jun 30 22:34:48 2012 -0700 +++ b/jitcraft/BytecodeCompiler.cpp Sat Jun 30 22:45:25 2012 -0700 @@ -149,7 +149,6 @@ } } } - break; } @@ -179,14 +178,8 @@ Variable *var = proxy->binding()->toVariable(); // Make sure to bind the left-hand side first. - if (var->type()->isReference()) { - if (var->location() == Variable::STACK) { - __ getlocal(var->slot()); - } else { - assert(var->location() == Variable::PARAMETER); - __ getarg(var->slot()); - } - } + if (var->type()->isReference()) + __ get(var); node->expression()->accept(this); @@ -198,12 +191,7 @@ __ setref_i(); } } else { - if (var->location() == Variable::STACK) { - __ setlocal(var->slot()); - } else { - assert(var->location() == Variable::PARAMETER); - __ setarg(var->slot()); - } + __ set(var); } } else if (node->lvalue()->isIndexExpression()) { IndexExpression *index = node->lvalue()->toIndexExpression(); @@ -463,6 +451,7 @@ // We don't know how to, or can't, build a direct reference to // this type. Make an indirect one, by taking the top of the // stack and boxing it up. + arg->accept(this); __ slotref_lifo(); } } else { diff -r d8ed9b8f19ca -r 23627f8bc421 jitcraft/BytecodeEmitter.h --- a/jitcraft/BytecodeEmitter.h Sat Jun 30 22:34:48 2012 -0700 +++ b/jitcraft/BytecodeEmitter.h Sat Jun 30 22:45:25 2012 -0700 @@ -320,6 +320,23 @@ } writeUint32(var->slot()); } + void get(Variable *var) { + if (var->location() == Variable::STACK) { + getlocal(var->slot()); + } else { + assert(var->location() == Variable::PARAMETER); + getarg(var->slot()); + } + } + void set(Variable *var) { + assert(!var->type()->isReference()); + if (var->location() == Variable::STACK) { + setlocal(var->slot()); + } else { + assert(var->location() == Variable::PARAMETER); + setarg(var->slot()); + } + } void slotref_lifo() { singleByteOp(OP_SLOTREF_LIFO); } diff -r d8ed9b8f19ca -r 23627f8bc421 jitcraft/Interpreter.cpp --- a/jitcraft/Interpreter.cpp Sat Jun 30 22:34:48 2012 -0700 +++ b/jitcraft/Interpreter.cpp Sat Jun 30 22:45:25 2012 -0700 @@ -485,6 +485,17 @@ break; } +case OP_SLOTREF_LIFO: +{ + Reference *ref = Reference::NewStack(ZONE(), top.sp[-1], Heap::Tenure_Stack); + if (!ref) { + assert(false); + return false; + } + top.sp[-1].ref = ref; + break; +} + case OP_GETREF_I: { top.sp[-1].i32 = top.sp[-1].ref->getInt(); diff -r d8ed9b8f19ca -r 23627f8bc421 jitcraft/Opcodes.cpp --- a/jitcraft/Opcodes.cpp Sat Jun 30 22:34:48 2012 -0700 +++ b/jitcraft/Opcodes.cpp Sat Jun 30 22:45:25 2012 -0700 @@ -98,6 +98,7 @@ case OP_SETREF_I: case OP_GETREF_F: case OP_SETREF_F: + case OP_SLOTREF_LIFO: break; case OP_STOP: diff -r d8ed9b8f19ca -r 23627f8bc421 jitcraft/Scopes.cpp --- a/jitcraft/Scopes.cpp Sat Jun 30 22:34:48 2012 -0700 +++ b/jitcraft/Scopes.cpp Sat Jun 30 22:45:25 2012 -0700 @@ -217,8 +217,9 @@ // If the parent of this scope is the function scope, then this is the // function's block scope, and the lifo slot is part of the Frame instead. - assert(kind() != FUNCTION); - if (enclosing()->kind() == FUNCTION) + // Note we can get a function scope here if we're making a temporary in a + // function with no local variables. + if (kind() == FUNCTION || enclosing()->kind() == FUNCTION) return; lifoSlot_ = new (pool_) Variable(this, NULL); diff -r d8ed9b8f19ca -r 23627f8bc421 jitcraft/main.cpp --- a/jitcraft/main.cpp Sat Jun 30 22:34:48 2012 -0700 +++ b/jitcraft/main.cpp Sat Jun 30 22:45:25 2012 -0700 @@ -85,7 +85,7 @@ printf("\n ------------ \n\n"); - Code *main = module->getFunction(2); + Code *main = module->getFunction(1); Top top = ZONE()->stack().begin(); LocalTop localTop(top); diff -r d8ed9b8f19ca -r 23627f8bc421 tests/prototype/ref-expr.sp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/prototype/ref-expr.sp Sat Jun 30 22:45:25 2012 -0700 @@ -0,0 +1,11 @@ +f(&a) +{ + for (new i = 0; i < 10; i = i + 1) + a = a + i; + return a; +} + +main() +{ + return f(77); +}