Added support for array references.
Added support for array references.
1.1 --- a/jitcraft/Array.h Sat Jun 30 22:45:25 2012 -0700
1.2 +++ b/jitcraft/Array.h Sat Jun 30 23:40:17 2012 -0700
1.3 @@ -64,6 +64,7 @@
1.4 assert(index < nelements());
1.5 floatVec()[index] = f;
1.6 }
1.7 + inline void *slotPtr(size_t index);
1.8 Object *readObject(size_t index) {
1.9 assert(index < nelements());
1.10 return objVec()[index];
1.11 @@ -123,6 +124,15 @@
1.12 return reinterpret_cast<Object **>(vec());
1.13 }
1.14
1.15 +inline void *
1.16 +Array::slotPtr(size_t index)
1.17 +{
1.18 + assert(ArrayMap::cast(map())->type()->contained()->primitive() == PrimitiveType_Int32 ||
1.19 + ArrayMap::cast(map())->type()->contained()->primitive() == PrimitiveType_Float);
1.20 + assert(index < nelements());
1.21 + return reinterpret_cast<int *>(vec()) + index;
1.22 +}
1.23 +
1.24 }
1.25
1.26 #endif // _include_jitcraft_array_h_
2.1 --- a/jitcraft/BytecodeCompiler.cpp Sat Jun 30 22:45:25 2012 -0700
2.2 +++ b/jitcraft/BytecodeCompiler.cpp Sat Jun 30 23:40:17 2012 -0700
2.3 @@ -447,6 +447,12 @@
2.4 // Compute a reference to the name.
2.5 Variable *var = arg->toNameProxy()->binding()->toVariable();
2.6 __ newref(var);
2.7 + } else if (arg->isIndexExpression()) {
2.8 + IndexExpression *expr = arg->toIndexExpression();
2.9 + expr->left()->accept(this);
2.10 + expr->right()->accept(this);
2.11 + __ bounds_sta();
2.12 + __ arrayref_lifo();
2.13 } else {
2.14 // We don't know how to, or can't, build a direct reference to
2.15 // this type. Make an indirect one, by taking the top of the
3.1 --- a/jitcraft/BytecodeEmitter.h Sat Jun 30 22:45:25 2012 -0700
3.2 +++ b/jitcraft/BytecodeEmitter.h Sat Jun 30 23:40:17 2012 -0700
3.3 @@ -340,6 +340,9 @@
3.4 void slotref_lifo() {
3.5 singleByteOp(OP_SLOTREF_LIFO);
3.6 }
3.7 + void arrayref_lifo() {
3.8 + singleByteOp(OP_ARRAYREF_LIFO);
3.9 + }
3.10 void getref_i() {
3.11 singleByteOp(OP_GETREF_I);
3.12 }
4.1 --- a/jitcraft/Interpreter.cpp Sat Jun 30 22:45:25 2012 -0700
4.2 +++ b/jitcraft/Interpreter.cpp Sat Jun 30 23:40:17 2012 -0700
4.3 @@ -485,9 +485,21 @@
4.4 break;
4.5 }
4.6
4.7 +case OP_ARRAYREF_LIFO:
4.8 +{
4.9 + Reference *ref = Reference::NewArray(ZONE(), top.sp[-2].array, top.sp[-1].i32, Heap::Tenure_Stack);
4.10 + if (!ref) {
4.11 + assert(false);
4.12 + return false;
4.13 + }
4.14 + top.sp[-2].ref = ref;
4.15 + top.sp--;
4.16 + break;
4.17 +}
4.18 +
4.19 case OP_SLOTREF_LIFO:
4.20 {
4.21 - Reference *ref = Reference::NewStack(ZONE(), top.sp[-1], Heap::Tenure_Stack);
4.22 + Reference *ref = Reference::NewStack(ZONE(), top.sp[-1], Heap::Tenure_Stack);
4.23 if (!ref) {
4.24 assert(false);
4.25 return false;
5.1 --- a/jitcraft/Opcodes.cpp Sat Jun 30 22:45:25 2012 -0700
5.2 +++ b/jitcraft/Opcodes.cpp Sat Jun 30 23:40:17 2012 -0700
5.3 @@ -99,6 +99,7 @@
5.4 case OP_GETREF_F:
5.5 case OP_SETREF_F:
5.6 case OP_SLOTREF_LIFO:
5.7 + case OP_ARRAYREF_LIFO:
5.8 break;
5.9
5.10 case OP_STOP:
6.1 --- a/jitcraft/Opcodes.tbl Sat Jun 30 22:45:25 2012 -0700
6.2 +++ b/jitcraft/Opcodes.tbl Sat Jun 30 23:40:17 2012 -0700
6.3 @@ -139,7 +139,8 @@
6.4 OPDEF(OP_VARREF_LIFO, 44, "varref.lifo", 5, 0, 1)
6.5 OPDEF(OP_ARGREF_LIFO, 45, "argref.lifo", 5, 0, 1)
6.6 OPDEF(OP_SLOTREF_LIFO, 46, "slotref.lifo", 1, 1, 1)
6.7 -OPDEF(OP_GETREF_I, 47, "getref.i", 1, 1, 1)
6.8 -OPDEF(OP_SETREF_I, 48, "setref.i", 1, 2, 1)
6.9 -OPDEF(OP_GETREF_F, 49, "getref.f", 1, 1, 1)
6.10 -OPDEF(OP_SETREF_F, 50, "setref.f", 1, 2, 1)
6.11 +OPDEF(OP_ARRAYREF_LIFO, 47, "arrayref.lifo",1, 2, 1)
6.12 +OPDEF(OP_GETREF_I, 48, "getref.i", 1, 1, 1)
6.13 +OPDEF(OP_SETREF_I, 49, "setref.i", 1, 2, 1)
6.14 +OPDEF(OP_GETREF_F, 50, "getref.f", 1, 1, 1)
6.15 +OPDEF(OP_SETREF_F, 51, "setref.f", 1, 2, 1)
7.1 --- a/jitcraft/SemanticAnalysis.cpp Sat Jun 30 22:45:25 2012 -0700
7.2 +++ b/jitcraft/SemanticAnalysis.cpp Sat Jun 30 23:40:17 2012 -0700
7.3 @@ -395,6 +395,8 @@
7.4 assert(node->arguments()->size() == type->parameters()->length());
7.5
7.6 for (unsigned i = 0; i < node->arguments()->size(); i++) {
7.7 + // Note: we don't compute references unless the callee needs a
7.8 + // reference type.
7.9 Expression *expression = node->arguments()->at(i);
7.10 expression->accept(this);
7.11
7.12 @@ -402,6 +404,12 @@
7.13 if (!given)
7.14 return;
7.15
7.16 + // If it's an IndexExpression, we special case the ability to compute
7.17 + // a reference. Maybe we should compute actual Ref types for
7.18 + // IndexExpression?
7.19 + if (expression->isIndexExpression())
7.20 + given = given->contained();
7.21 +
7.22 Type *actual = Type::cast(type->parameters()->at(i));
7.23 assert(TypeCheckParameter(given, actual));
7.24
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/tests/ref-array.sp Sat Jun 30 23:40:17 2012 -0700
8.3 @@ -0,0 +1,13 @@
8.4 +f(&a)
8.5 +{
8.6 + for (new i = 0; i < 10; i = i + 1)
8.7 + a = a + i;
8.8 + return a;
8.9 +}
8.10 +
8.11 +main()
8.12 +{
8.13 + new array[4];
8.14 + f(array[3]);
8.15 + return array[3];
8.16 +}