changeset 286:a3b7c19c866c trunk

[svn r307] Fixed: multidimensional new expressions now work. Eg.: auto ma = new int[][] (3,9);
author lindquist
date Sat, 21 Jun 2008 04:47:14 +0200
parents 297690b5d4a5
children 00eb2c967c3a
files gen/arrays.cpp gen/arrays.h gen/runtime.cpp gen/toir.cpp tango/lib/compiler/llvmdc/lifetime.d tangotests/marray1.d tangotests/marray2.d
diffstat 7 files changed, 127 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/gen/arrays.cpp	Sat Jun 21 03:14:49 2008 +0200
+++ b/gen/arrays.cpp	Sat Jun 21 04:47:14 2008 +0200
@@ -478,6 +478,48 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
+DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims, bool defaultInit)
+{
+    Logger::println("DtoNewMulDimDynArray : %s", arrayType->toChars());
+    LOG_SCOPE;
+
+    // typeinfo arg
+    LLValue* arrayTypeInfo = DtoTypeInfoOf(arrayType);
+
+    // get runtime function
+    bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
+    LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarraymT" : "_d_newarraymiT" );
+
+    // build dims
+    LLValue* dimsArg = new llvm::AllocaInst(DtoSize_t(), DtoConstUint(ndims), ".newdims", gIR->topallocapoint());
+    for (size_t i=0; i<ndims; ++i)
+    {
+        LLValue* dim = dims[i]->getRVal();
+        DtoStore(dim, DtoGEPi1(dimsArg, i));
+    }
+
+    // call allocator
+    LLConstant* arrayLen = DtoConstSize_t(ndims);
+    LLValue* newptr = gIR->ir->CreateCall3(fn, arrayTypeInfo, arrayLen, dimsArg, ".gc_mem");
+
+    // cast to wanted type
+    const LLType* dstType = DtoType(arrayType)->getContainedType(1);
+    if (newptr->getType() != dstType)
+        newptr = DtoBitCast(newptr, dstType, ".gc_mem");
+
+    Logger::cout() << "final ptr = " << *newptr << '\n';
+
+#if 0
+    if (defaultInit) {
+        DValue* e = dty->defaultInit()->toElem(gIR);
+        DtoArrayInit(newptr,dim,e->getRVal());
+    }
+#endif
+
+    return new DSliceValue(arrayType, arrayLen, newptr);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
 DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
 {
     Logger::println("DtoResizeDynArray : %s", arrayType->toChars());
--- a/gen/arrays.h	Sat Jun 21 03:14:49 2008 +0200
+++ b/gen/arrays.h	Sat Jun 21 04:47:14 2008 +0200
@@ -21,6 +21,7 @@
 void DtoSetArrayToNull(LLValue* v);
 
 DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit=true);
+DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
 DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
 
 DSliceValue* DtoCatAssignElement(DValue* arr, Expression* exp);
--- a/gen/runtime.cpp	Sat Jun 21 03:14:49 2008 +0200
+++ b/gen/runtime.cpp	Sat Jun 21 04:47:14 2008 +0200
@@ -266,6 +266,20 @@
         llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
     }
 
+    // void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims)
+    // void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims)
+    {
+        std::string fname("_d_newarraymT");
+        std::string fname2("_d_newarraymiT");
+        std::vector<const LLType*> types;
+        types.push_back(typeInfoTy);
+        types.push_back(sizeTy);
+        types.push_back(rt_ptr(sizeTy));
+        const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
+        llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
+        llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
+    }
+
     // void* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
     // void* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
     {
--- a/gen/toir.cpp	Sat Jun 21 03:14:49 2008 +0200
+++ b/gen/toir.cpp	Sat Jun 21 04:47:14 2008 +0200
@@ -1899,10 +1899,21 @@
         Logger::println("new dynamic array: %s", newtype->toChars());
         // get dim
         assert(arguments);
-        assert(arguments->dim == 1);
-        DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
-        // allocate & init
-        return DtoNewDynArray(newtype, sz, true);
+        assert(arguments->dim >= 1);
+        if (arguments->dim == 1)
+        {
+            DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
+            // allocate & init
+            return DtoNewDynArray(newtype, sz, true);
+        }
+        else
+        {
+            size_t ndims = arguments->dim;
+            std::vector<DValue*> dims(ndims);
+            for (size_t i=0; i<ndims; ++i)
+                dims[i] = ((Expression*)arguments->data[i])->toElem(p);
+            return DtoNewMulDimDynArray(newtype, &dims[0], ndims, true);
+        }
     }
     // new static array
     else if (ntype->ty == Tsarray)
--- a/tango/lib/compiler/llvmdc/lifetime.d	Sat Jun 21 03:14:49 2008 +0200
+++ b/tango/lib/compiler/llvmdc/lifetime.d	Sat Jun 21 04:47:14 2008 +0200
@@ -293,23 +293,19 @@
     return null;
 }
 
-/+
-
 /**
  *
  */
-extern (C) Array _d_newarraymT(TypeInfo ti, int ndims, ...)
+extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
 {
-    Array result;
+    void* result;
 
     debug(PRINTF) printf("_d_newarraymT(ndims = %d)\n", ndims);
     if (ndims == 0)
-        result = Array();
+        result = null;
     else
-    {   va_list q;
-        va_start!(int)(q, ndims);
-
-        void[] foo(TypeInfo ti, size_t* pdim, int ndims)
+    {
+        static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
         {
             size_t dim = *pdim;
             void[] p;
@@ -317,7 +313,8 @@
             debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
             if (ndims == 1)
             {
-                return _d_newarrayT(ti, dim);
+                auto r = _d_newarrayT(ti, dim);
+                return r[0 .. dim];
             }
             else
             {
@@ -330,19 +327,16 @@
             return p;
         }
 
-        size_t* pdim = cast(size_t *)q;
-        void[] arr = foo(ti, pdim, ndims);
-        result = Arra
-        debug(PRINTF) printf("result = %llx\n", result);
+        result = foo(ti, dims, ndims).ptr;
+        debug(PRINTF) printf("result = %p\n", result);
 
         version (none)
         {
             for (int i = 0; i < ndims; i++)
             {
-                printf("index %d: %d\n", i, va_arg!(int)(q));
+                printf("index %d: %d\n", i, *dims++);
             }
         }
-        va_end(q);
     }
     return result;
 }
@@ -351,19 +345,16 @@
 /**
  *
  */
-extern (C) Array _d_newarraymiT(TypeInfo ti, int ndims, ...)
+extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
 {
-    Array result;
+    void* result;
 
     debug(PRINTF) printf("_d_newarraymiT(ndims = %d)\n", ndims);
     if (ndims == 0)
-        result = 0;
+        result = null;
     else
     {
-        va_list q;
-        va_start!(int)(q, ndims);
-
-        void[] foo(TypeInfo ti, size_t* pdim, int ndims)
+        static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
         {
             size_t dim = *pdim;
             void[] p;
@@ -371,7 +362,7 @@
             if (ndims == 1)
             {
                 auto r = _d_newarrayiT(ti, dim);
-                p = *cast(void[]*)(&r);
+                p = r[0 .. dim];
             }
             else
             {
@@ -384,23 +375,23 @@
             return p;
         }
 
-        size_t* pdim = cast(size_t *)q;
-        result = cast(ulong)foo(ti, pdim, ndims);
-        debug(PRINTF) printf("result = %llx\n", result);
+        result = foo(ti, dims, ndims).ptr;
+        debug(PRINTF) printf("result = %p\n", result);
 
         version (none)
         {
             for (int i = 0; i < ndims; i++)
             {
-                printf("index %d: %d\n", i, va_arg!(int)(q));
-                printf("init = %d\n", va_arg!(int)(q));
+                printf("index %d: %d\n", i, *dims++);
+                printf("init = %d\n", *dims++);
             }
         }
-        va_end(q);
     }
     return result;
 }
 
+/+
+
 /**
  *
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tangotests/marray1.d	Sat Jun 21 04:47:14 2008 +0200
@@ -0,0 +1,19 @@
+module tangotest.marray1;
+
+void main()
+{
+    int[][] arr;
+    int[] a = [1,2];
+    int[] b = [6,7,8,9];
+    arr ~= a;
+    arr ~= b;
+    assert(a.length == 2);
+    assert(b.length == 4);
+    assert(arr.length == 2);
+    assert(arr[0][0] == 1);
+    assert(arr[0][1] == 2);
+    assert(arr[1][0] == 6);
+    assert(arr[1][1] == 7);
+    assert(arr[1][2] == 8);
+    assert(arr[1][3] == 9);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tangotests/marray2.d	Sat Jun 21 04:47:14 2008 +0200
@@ -0,0 +1,15 @@
+module tangotests.marray2;
+
+void main()
+{
+    int[][] ma = new int[][](2,4);
+    assert(ma.length == 2);
+    assert(ma[0].length == 4);
+    assert(ma[1].length == 4);
+    ma[0][3] = 32;
+    ma[1][2] = 123;
+    ma[0][0] = 55;
+    assert(ma[0][3] == 32);
+    assert(ma[1][2] == 123);
+    assert(ma[0][0] == 55);
+}