changeset 591:e6bcc4d9e5ff

Add _d_newarrayvT and _d_newarraymvT to create arrays without initialization. Adjust DtoNewDynArray to use DtoArrayInit for initialization of new arrays. Make Type::tvoid->defaultInit() not error.
author Christian Kamm <kamm incasoftware de>
date Sun, 14 Sep 2008 10:13:50 +0200
parents 1ecb43102d12
children 5fb7ed0ac580
files dmd/mtype.c gen/arrays.cpp gen/arrays.h gen/runtime.cpp gen/toir.cpp runtime/internal/lifetime.d
diffstat 6 files changed, 116 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/mtype.c	Fri Sep 12 13:11:32 2008 +0200
+++ b/dmd/mtype.c	Sun Sep 14 10:13:50 2008 +0200
@@ -1375,6 +1375,9 @@
 #endif
     switch (ty)
     {
+	case Tvoid:
+	    return new IntegerExp(loc, value, Type::tbool);
+
 	case Tchar:
 	    value = 0xFF;
 	    break;
--- a/gen/arrays.cpp	Fri Sep 12 13:11:32 2008 +0200
+++ b/gen/arrays.cpp	Sun Sep 14 10:13:50 2008 +0200
@@ -399,7 +399,7 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
-DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit)
+DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit)
 {
     Logger::println("DtoNewDynArray : %s", arrayType->toChars());
     LOG_SCOPE;
@@ -412,8 +412,7 @@
     LLValue* arrayLen = dim->getRVal();
 
     // get runtime function
-    bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
-    LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
+    LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newarrayvT");
 
     // call allocator
     LLValue* newptr = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem")->get();
@@ -425,18 +424,18 @@
 
     Logger::cout() << "final ptr = " << *newptr << '\n';
 
-#if 0
+    DSliceValue* ret = new DSliceValue(arrayType, arrayLen, newptr);
+
     if (defaultInit) {
-        DValue* e = dty->defaultInit()->toElem(gIR);
-        DtoArrayInit(newptr,dim,e->getRVal());
+        DValue* e = arrayType->nextOf()->defaultInit()->toElem(gIR);
+        DtoArrayInit(loc, ret, e);
     }
-#endif
 
-    return new DSliceValue(arrayType, arrayLen, newptr);
+    return ret;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
-DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims, bool defaultInit)
+DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit)
 {
     Logger::println("DtoNewMulDimDynArray : %s", arrayType->toChars());
     LOG_SCOPE;
@@ -474,6 +473,7 @@
     Logger::cout() << "final ptr = " << *newptr << '\n';
 
 #if 0
+    // using this would reinit all arrays beyond the first level to []
     if (defaultInit) {
         DValue* e = dty->defaultInit()->toElem(gIR);
         DtoArrayInit(newptr,dim,e->getRVal());
@@ -597,7 +597,7 @@
     res = gIR->ir->CreateAdd(len1,len2,"tmp");
 
     DValue* lenval = new DImValue(Type::tsize_t, res);
-    DSliceValue* slice = DtoNewDynArray(type, lenval, false);
+    DSliceValue* slice = DtoNewDynArray(exp1->loc, type, lenval, false);
     LLValue* mem = slice->ptr;
 
     src1 = DtoArrayPtr(e1);
@@ -637,7 +637,7 @@
         res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
 
         DValue* lenval = new DImValue(Type::tsize_t, res);
-        DSliceValue* slice = DtoNewDynArray(type, lenval, false);
+        DSliceValue* slice = DtoNewDynArray(exp1->loc, type, lenval, false);
         LLValue* mem = slice->ptr;
 
         DVarValue* memval = new DVarValue(e1->getType(), mem);
@@ -661,7 +661,7 @@
         res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
 
         DValue* lenval = new DImValue(Type::tsize_t, res);
-        DSliceValue* slice = DtoNewDynArray(type, lenval, false);
+        DSliceValue* slice = DtoNewDynArray(exp1->loc, type, lenval, false);
         LLValue* mem = slice->ptr;
 
         src1 = DtoArrayPtr(e1);
--- a/gen/arrays.h	Fri Sep 12 13:11:32 2008 +0200
+++ b/gen/arrays.h	Sun Sep 14 10:13:50 2008 +0200
@@ -19,8 +19,8 @@
 void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr);
 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* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit=true);
+DSliceValue* DtoNewMulDimDynArray(Loc& loc, 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	Fri Sep 12 13:11:32 2008 +0200
+++ b/gen/runtime.cpp	Sun Sep 14 10:13:50 2008 +0200
@@ -237,22 +237,27 @@
 
     // void* _d_newarrayT(TypeInfo ti, size_t length)
     // void* _d_newarrayiT(TypeInfo ti, size_t length)
+    // void* _d_newarrayvT(TypeInfo ti, size_t length)
     {
         std::string fname("_d_newarrayT");
         std::string fname2("_d_newarrayiT");
+        std::string fname3("_d_newarrayvT");
         std::vector<const LLType*> types;
         types.push_back(typeInfoTy);
         types.push_back(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);
+        llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M);
     }
 
     // void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims)
     // void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims)
+    // void* _d_newarraymvT(TypeInfo ti, size_t length, size_t* dims)
     {
         std::string fname("_d_newarraymT");
         std::string fname2("_d_newarraymiT");
+        std::string fname3("_d_newarraymvT");
         std::vector<const LLType*> types;
         types.push_back(typeInfoTy);
         types.push_back(sizeTy);
@@ -260,6 +265,7 @@
         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);
+        llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M);
     }
 
     // void* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
--- a/gen/toir.cpp	Fri Sep 12 13:11:32 2008 +0200
+++ b/gen/toir.cpp	Sun Sep 14 10:13:50 2008 +0200
@@ -1452,7 +1452,7 @@
         {
             DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
             // allocate & init
-            return DtoNewDynArray(newtype, sz, true);
+            return DtoNewDynArray(loc, newtype, sz, true);
         }
         else
         {
@@ -1460,7 +1460,7 @@
             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);
+            return DtoNewMulDimDynArray(loc, newtype, &dims[0], ndims, true);
         }
     }
     // new static array
--- a/runtime/internal/lifetime.d	Fri Sep 12 13:11:32 2008 +0200
+++ b/runtime/internal/lifetime.d	Sun Sep 14 10:13:50 2008 +0200
@@ -202,7 +202,7 @@
 /**
  * Allocate a new array of length elements.
  * ti is the type of the resulting array, or pointer to element.
- * (For when the array is initialized to 0)
+ * The resulting array is initialized to 0
  */
 extern (C) void* _d_newarrayT(TypeInfo ti, size_t length)
 {
@@ -236,7 +236,8 @@
 }
 
 /**
- * For when the array has a non-zero initializer.
+ * As _d_newarrayT, but 
+ * for when the array has a non-zero initializer.
  */
 extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length)
 {
@@ -294,7 +295,44 @@
 }
 
 /**
- *
+ * As _d_newarrayT, but without initialization
+ */
+extern (C) void* _d_newarrayvT(TypeInfo ti, size_t length)
+{
+    void* p;
+    auto size = ti.next.tsize();                // array element size
+
+    debug(PRINTF) printf("_d_newarrayvT(length = %u, size = %d)\n", length, size);
+    if (length == 0 || size == 0)
+        return null;
+
+    version (D_InlineAsm_X86)
+    {
+        asm
+        {
+            mov     EAX,size        ;
+            mul     EAX,length      ;
+            mov     size,EAX        ;
+            jc      Loverflow       ;
+        }
+    }
+    else
+        size *= length;
+    p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
+    debug(PRINTF) printf(" p = %p\n", p);
+    return p;
+
+Loverflow:
+    onOutOfMemoryError();
+    return null;
+}
+
+/**
+ * Allocate a new array of arrays of arrays of arrays ...
+ * ti is the type of the resulting array.
+ * ndims is the number of nested arrays.
+ * dims it the array of dimensions, its size is ndims.
+ * The resulting array is initialized to 0
  */
 extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
 {
@@ -343,7 +381,8 @@
 
 
 /**
- *
+ * As _d_newarraymT, but 
+ * for when the array has a non-zero initializer.
  */
 extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
 {
@@ -390,6 +429,54 @@
     return result;
 }
 
+/**
+ * As _d_newarraymT, but without initialization
+ */
+extern (C) void* _d_newarraymvT(TypeInfo ti, int ndims, size_t* dims)
+{
+    void* result;
+
+    debug(PRINTF) printf("_d_newarraymvT(ndims = %d)\n", ndims);
+    if (ndims == 0)
+        result = null;
+    else
+    {
+        static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
+        {
+            size_t dim = *pdim;
+            void[] p;
+
+            debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
+            if (ndims == 1)
+            {
+                auto r = _d_newarrayvT(ti, dim);
+                return r[0 .. dim];
+            }
+            else
+            {
+                p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
+                for (int i = 0; i < dim; i++)
+                {
+                    (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
+                }
+            }
+            return p;
+        }
+
+        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, *dims++);
+            }
+        }
+    }
+    return result;
+}
+
 /+
 
 /**