Added support for array references.
authorDavid Anderson <dvander@alliedmods.net>
Sat Jun 30 23:40:17 2012 -0700 (2012-06-30)
changeset 178aa89dd41e25
parent 16 23627f8bc421
child 18 ffd4ddec7b2e
Added support for array references.
jitcraft/Array.h
jitcraft/BytecodeCompiler.cpp
jitcraft/BytecodeEmitter.h
jitcraft/Interpreter.cpp
jitcraft/Opcodes.cpp
jitcraft/Opcodes.tbl
jitcraft/SemanticAnalysis.cpp
tests/ref-array.sp
     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 +}