diff gen/toir.cpp @ 203:e881c9b1c738 trunk

[svn r219] Fixed: the tango/lib/gc/basic garbage collector now compiles and links into an executable (change in tango/lib/llvmdc-posix.mak), closes #5 . Changed: removed the crappy realloc based dynamic memory runtime and started moving over to DMD style runtime support, part of moving to real GC. Fixed: dynamic arrays now use GC runtime for allocating memory. Fixed: new expression now use GC for allocating memory. Changed: revamped the dynamic array support routines related to dynamic memory. Fixed: assertions no longer create exsessive allocas. Changed: misc. minor cleanups.
author lindquist
date Tue, 13 May 2008 14:42:09 +0200
parents 8f9191180c7a
children 9d44ec83acd1
line wrap: on
line diff
--- a/gen/toir.cpp	Mon May 12 23:49:07 2008 +0200
+++ b/gen/toir.cpp	Tue May 13 14:42:09 2008 +0200
@@ -572,10 +572,15 @@
     DImValue* im = r->isIm();
     if (!im || !im->inPlace()) {
         Logger::println("assignment not inplace");
-        if (l->isArrayLen())
-            DtoResizeDynArray(l->getLVal(), r->getRVal());
+        if (DArrayLenValue* al = l->isArrayLen())
+        {
+            DSliceValue* slice = DtoResizeDynArray(l->getType(), l, r);
+            DtoAssign(l, slice);
+        }
         else
+        {
             DtoAssign(l, r);
+        }
     }
 
     if (l->isSlice() || l->isComplex())
@@ -1932,10 +1937,54 @@
 
     Type* ntype = DtoDType(newtype);
 
+    // new class
     if (ntype->ty == Tclass) {
         Logger::println("new class");
         return DtoNewClass((TypeClass*)ntype, this);
     }
+    // new dynamic array
+    else if (ntype->ty == Tarray)
+    {
+        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);
+    }
+    // new static array
+    else if (ntype->ty == Tsarray)
+    {
+        assert(0);
+    }
+    // new struct
+    else if (ntype->ty == Tstruct)
+    {
+        // allocate
+        llvm::Value* mem = DtoNew(newtype);
+        // init
+        TypeStruct* ts = (TypeStruct*)ntype;
+        if (ts->isZeroInit()) {
+            DtoStructZeroInit(mem);
+        }
+        else {
+            assert(ts->sym);
+            DtoStructCopy(mem,ts->sym->ir.irStruct->init);
+        }
+        return new DImValue(type, mem, false);
+    }
+    // new basic type
+    else
+    {
+        // allocate
+        llvm::Value* mem = DtoNew(newtype);
+        // BUG: default initialize
+        // return
+        return new DImValue(type, mem, false);
+    }
+
+    /*
 
     const llvm::Type* t = DtoType(ntype);
 
@@ -1969,8 +2018,17 @@
             assert(0 && "num args to 'new' != 1");
         }
     }
+    // simple new of a single non-class, non-array value
     else {
-        emem = new llvm::MallocInst(t,"tmp",p->scopebb());
+        // get runtime function
+        llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT");
+        // get type info
+        llvm::Constant* ti = DtoTypeInfoOf(newtype);
+        assert(isaPointer(ti));
+        // call runtime
+        llvm::SmallVector<llvm::Value*,1> arg;
+        arg.push_back(ti);
+        emem = p->ir->CreateCall(fn, arg.begin(), arg.end(), ".gc_mem");
     }
 
     if (ntype->ty == Tstruct) {
@@ -1985,6 +2043,8 @@
     }
 
     return new DImValue(type, emem, inplace);
+    */
+    assert(0);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -2053,10 +2113,11 @@
     LOG_SCOPE;
 
     DValue* u = e1->toElem(p);
+    Logger::println("e1 = %s", e1->type->toChars());
 
     if (p->topexp() && p->topexp()->e1 == this)
     {
-        return new DArrayLenValue(type, u->getLVal());
+        return new DArrayLenValue(e1->type, u->getLVal());
     }
     else
     {
@@ -2488,6 +2549,19 @@
 
     bool arrNarr = DtoDType(e1->type) == DtoDType(e2->type);
 
+    // array ~ array
+    if (arrNarr)
+    {
+        return DtoCatArrays(type, e1, e2);
+    }
+    // array ~ element
+    // element ~ array
+    else
+    {
+        return DtoCatArrayElement(type, e1, e2);
+    }
+
+    /*
     IRExp* ex = p->topexp();
     if (ex && ex->e2 == this) {
         assert(ex->v);
@@ -2502,11 +2576,13 @@
         const llvm::Type* arrty = DtoType(t);
         llvm::Value* dst = new llvm::AllocaInst(arrty, "tmpmem", p->topallocapoint());
         if (arrNarr)
+            DtoCatAr
             DtoCatArrays(dst,e1,e2);
         else
             DtoCatArrayElement(dst,e1,e2);
         return new DVarValue(type, dst, true);
     }
+    */
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -2523,15 +2599,17 @@
     Type* e2type = DtoDType(e2->type);
 
     if (e2type == elemtype) {
-        DtoCatAssignElement(l->getLVal(),e2);
+        DSliceValue* slice = DtoCatAssignElement(l,e2);
+        DtoAssign(l, slice);
     }
     else if (e1type == e2type) {
-        DtoCatAssignArray(l->getLVal(),e2);
+        DSliceValue* slice = DtoCatAssignArray(l,e2);
+        DtoAssign(l, slice);
     }
     else
         assert(0 && "only one element at a time right now");
 
-    return 0;
+    return l;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////