changeset 127:facc562f5674 trunk

[svn r131] Fixed #11 All associative array properties now work as they should. Fixed problems with some cases of array.length and array.ptr. Fixed some problems with array properties. Fixed 'in' contracts.
author lindquist
date Fri, 30 Nov 2007 12:56:52 +0100
parents a2c2c3c1a73d
children e5fe8521bbfa
files dmd/mars.c dmd/mtype.c gen/aa.cpp gen/aa.h gen/arrays.cpp gen/functions.cpp gen/toir.cpp llvmdc.kdevelop lphobos/internal/aaA.d test/aa6.d
diffstat 10 files changed, 169 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/mars.c	Wed Nov 28 05:04:38 2007 +0100
+++ b/dmd/mars.c	Fri Nov 30 12:56:52 2007 +0100
@@ -259,11 +259,11 @@
     global.params.link = 1;
     global.params.useAssert = 0;
     global.params.useInvariants = 0;
-    global.params.useIn = 0;
+    global.params.useIn = 1;
     global.params.useOut = 0;
     global.params.useArrayBounds = 0;
     global.params.useSwitchError = 0;
-    global.params.useInline = 0;
+    global.params.useInline = 0; // this one messes things up to a point where codegen breaks
     global.params.obj = 1;
     global.params.Dversion = 2;
 
--- a/dmd/mtype.c	Wed Nov 28 05:04:38 2007 +0100
+++ b/dmd/mtype.c	Fri Nov 30 12:56:52 2007 +0100
@@ -1513,9 +1513,8 @@
 	static char *name[2] = { "_adReverseChar", "_adReverseWchar" };
 
 	nm = name[n->ty == Twchar];
-	fd = FuncDeclaration::genCfunc(Type::tindex, nm);
+	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
     fd->llvmRunTimeHack = true;
-    ((TypeFunction*)fd->type)->llvmRetInPtr = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -1532,9 +1531,8 @@
 	static char *name[2] = { "_adSortChar", "_adSortWchar" };
 
 	nm = name[n->ty == Twchar];
-	fd = FuncDeclaration::genCfunc(Type::tindex, nm);
+	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
     fd->llvmRunTimeHack = true;
-    ((TypeFunction*)fd->type)->llvmRetInPtr = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -1552,9 +1550,8 @@
 
 	assert(size);
 	dup = (ident == Id::dup);
-	fd = FuncDeclaration::genCfunc(Type::tindex, dup ? Id::adDup : Id::adReverse);
+	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), dup ? Id::adDup : Id::adReverse);
     fd->llvmRunTimeHack = true;
-    ((TypeFunction*)fd->type)->llvmRetInPtr = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -1572,10 +1569,9 @@
 	FuncDeclaration *fd;
 	Expressions *arguments;
 
-	fd = FuncDeclaration::genCfunc(tint32->arrayOf(),
+	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(),
 		(char*)(n->ty == Tbit ? "_adSortBit" : "_adSort"));
     fd->llvmRunTimeHack = true;
-    ((TypeFunction*)fd->type)->llvmRetInPtr = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -2277,6 +2273,7 @@
 	Expressions *arguments;
 
 	fd = FuncDeclaration::genCfunc(Type::tsize_t, Id::aaLen);
+    fd->llvmRunTimeHack = true;
 	ec = new VarExp(0, fd);
 	arguments = new Expressions();
 	arguments->push(e);
@@ -2291,7 +2288,8 @@
 	int size = key->size(e->loc);
 
 	assert(size);
-	fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaKeys);
+	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaKeys);
+    fd->llvmRunTimeHack = true;
 	ec = new VarExp(0, fd);
 	arguments = new Expressions();
 	arguments->push(e);
@@ -2305,12 +2303,13 @@
 	FuncDeclaration *fd;
 	Expressions *arguments;
 
-	fd = FuncDeclaration::genCfunc(Type::tindex, Id::aaValues);
+	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaValues);
+    fd->llvmRunTimeHack = true;
 	ec = new VarExp(0, fd);
 	arguments = new Expressions();
 	arguments->push(e);
 	size_t keysize = key->size(e->loc);
-	keysize = (keysize + 3) & ~3;	// BUG: 64 bit pointers?
+	keysize = (keysize + 4 - 1) & ~(4 - 1);
 	arguments->push(new IntegerExp(0, keysize, Type::tsize_t));
 	arguments->push(new IntegerExp(0, next->size(e->loc), Type::tsize_t));
 	e = new CallExp(e->loc, ec, arguments);
@@ -2322,7 +2321,8 @@
 	FuncDeclaration *fd;
 	Expressions *arguments;
 
-	fd = FuncDeclaration::genCfunc(Type::tint64, Id::aaRehash);
+	fd = FuncDeclaration::genCfunc(Type::tvoid->pointerTo(), Id::aaRehash);
+    fd->llvmRunTimeHack = true;
 	ec = new VarExp(0, fd);
 	arguments = new Expressions();
 	arguments->push(e->addressOf(sc));
--- a/gen/aa.cpp	Wed Nov 28 05:04:38 2007 +0100
+++ b/gen/aa.cpp	Fri Nov 30 12:56:52 2007 +0100
@@ -48,6 +48,20 @@
     return pkey;
 }
 
+// returns the keytype typeinfo
+static llvm::Value* to_keyti(DValue* key)
+{
+    // keyti param
+    Type* keytype = key->getType();
+    keytype->getTypeInfo(NULL);
+    TypeInfoDeclaration* tid = keytype->getTypeInfoDeclaration();
+    assert(tid);
+    DtoResolveDsymbol(Type::typeinfo);
+    DtoForceDeclareDsymbol(tid);
+    assert(tid->llvmValue);
+    return tid->llvmValue;
+}
+
 /////////////////////////////////////////////////////////////////////////////////////
 
 DValue* DtoAAIndex(Type* type, DValue* aa, DValue* key)
@@ -64,14 +78,7 @@
     aaval = DtoBitCast(aaval, funcTy->getParamType(0));
 
     // keyti param
-    Type* keytype = key->getType();
-    keytype->getTypeInfo(NULL);
-    TypeInfoDeclaration* tid = keytype->getTypeInfoDeclaration();
-    assert(tid);
-    DtoResolveDsymbol(Type::typeinfo);
-    DtoForceDeclareDsymbol(tid);
-    assert(tid->llvmValue);
-    llvm::Value* keyti = tid->llvmValue;
+    llvm::Value* keyti = to_keyti(key);
     keyti = DtoBitCast(keyti, funcTy->getParamType(1));
 
     // pkey param
@@ -89,7 +96,7 @@
     args.push_back(valsize);
 
     // call runtime
-    llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aaGet");
+    llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aa.index");
 
     // cast return value
     const llvm::Type* targettype = llvm::PointerType::get(DtoType(type));
@@ -119,14 +126,7 @@
     aaval = DtoBitCast(aaval, funcTy->getParamType(0));
 
     // keyti param
-    Type* keytype = key->getType();
-    keytype->getTypeInfo(NULL);
-    TypeInfoDeclaration* tid = keytype->getTypeInfoDeclaration();
-    assert(tid);
-    DtoResolveDsymbol(Type::typeinfo);
-    DtoForceDeclareDsymbol(tid);
-    assert(tid->llvmValue);
-    llvm::Value* keyti = tid->llvmValue;
+    llvm::Value* keyti = to_keyti(key);
     keyti = DtoBitCast(keyti, funcTy->getParamType(1));
 
     // pkey param
@@ -140,7 +140,7 @@
     args.push_back(pkey);
 
     // call runtime
-    llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aaIn");
+    llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "aa.in");
 
     // cast return value
     const llvm::Type* targettype = DtoType(type);
@@ -151,3 +151,38 @@
 }
 
 /////////////////////////////////////////////////////////////////////////////////////
+
+void DtoAARemove(DValue* aa, DValue* key)
+{
+    // call:
+    // extern(C) void _aaDel(AA aa, TypeInfo keyti, void* pkey)
+
+    // first get the runtime function
+    llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_aaDel");
+    const llvm::FunctionType* funcTy = func->getFunctionType();
+
+    Logger::cout() << "_aaDel = " << *func << '\n';
+
+    // aa param
+    llvm::Value* aaval = aa->getRVal();
+    Logger::cout() << "aaval: " << *aaval << '\n';
+    Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
+    aaval = DtoBitCast(aaval, funcTy->getParamType(0));
+
+    // keyti param
+    llvm::Value* keyti = to_keyti(key);
+    keyti = DtoBitCast(keyti, funcTy->getParamType(1));
+
+    // pkey param
+    llvm::Value* pkey = to_pkey(key);
+    pkey = DtoBitCast(pkey, funcTy->getParamType(2));
+
+    // build arg vector
+    std::vector<llvm::Value*> args;
+    args.push_back(aaval);
+    args.push_back(keyti);
+    args.push_back(pkey);
+
+    // call runtime
+    gIR->ir->CreateCall(func, args.begin(), args.end(),"");
+}
--- a/gen/aa.h	Wed Nov 28 05:04:38 2007 +0100
+++ b/gen/aa.h	Fri Nov 30 12:56:52 2007 +0100
@@ -3,5 +3,6 @@
 
 DValue* DtoAAIndex(Type* type, DValue* aa, DValue* key);
 DValue* DtoAAIn(Type* type, DValue* aa, DValue* key);
+void DtoAARemove(DValue* aa, DValue* key);
 
 #endif // LLVMDC_GEN_AA_H
--- a/gen/arrays.cpp	Wed Nov 28 05:04:38 2007 +0100
+++ b/gen/arrays.cpp	Fri Nov 30 12:56:52 2007 +0100
@@ -808,8 +808,10 @@
                 return s->len;
             }
             const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
-            assert(arrTy);
-            return DtoConstSize_t(arrTy->getNumElements());
+            if (arrTy)
+                return DtoConstSize_t(arrTy->getNumElements());
+            else
+                return DtoLoad(DtoGEPi(s->ptr, 0,0, "tmp"));
         }
         return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp"));
     }
@@ -831,9 +833,13 @@
     if (t->ty == Tarray) {
         if (DSliceValue* s = v->isSlice()) {
             if (s->len) return s->ptr;
+            const llvm::Type* t = s->ptr->getType()->getContainedType(0);
+            Logger::cout() << "ptr of full slice: " << *s->ptr << '\n';
             const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
-            assert(arrTy);
-            return DtoGEPi(s->ptr, 0,0, "tmp");
+            if (arrTy)
+                return DtoGEPi(s->ptr, 0,0, "tmp");
+            else
+                return DtoLoad(DtoGEPi(s->ptr, 0,1, "tmp"));
         }
         return DtoLoad(DtoGEPi(v->getRVal(), 0,1, "tmp"));
     }
--- a/gen/functions.cpp	Wed Nov 28 05:04:38 2007 +0100
+++ b/gen/functions.cpp	Fri Nov 30 12:56:52 2007 +0100
@@ -256,6 +256,8 @@
 
     if (fdecl->llvmRunTimeHack) {
         gIR->declareList.push_back(fdecl);
+        TypeFunction* tf = (TypeFunction*)fdecl->type;
+        tf->llvmRetInPtr = DtoIsPassedByRef(tf->next);
         return;
     }
 
--- a/gen/toir.cpp	Wed Nov 28 05:04:38 2007 +0100
+++ b/gen/toir.cpp	Fri Nov 30 12:56:52 2007 +0100
@@ -904,7 +904,7 @@
         Logger::cout() << "what are we calling? : " << *funcval << '\n';
     }
     assert(llfnty);
-    //Logger::cout() << "Function LLVM type: " << *llfnty << '\n';
+    Logger::cout() << "Function LLVM type: " << *llfnty << '\n';
 
     // argument handling
     llvm::FunctionType::param_iterator argiter = llfnty->param_begin();
@@ -2572,6 +2572,19 @@
     return DtoAAIn(type, aa, key);
 }
 
+DValue* RemoveExp::toElem(IRState* p)
+{
+    Logger::print("RemoveExp::toElem: %s\n", toChars());
+    LOG_SCOPE;
+
+    DValue* aa = e1->toElem(p);
+    DValue* key = e2->toElem(p);
+
+    DtoAARemove(aa, key);
+
+    return NULL; // does not produce anything useful
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 
 DValue* AssocArrayLiteralExp::toElem(IRState* p)
@@ -2583,6 +2596,20 @@
     assert(values);
     assert(keys->dim == values->dim);
 
+    Type* aatype = DtoDType(type);
+    Type* vtype = aatype->next;
+
+    DValue* aa;
+    if (p->topexp() && p->topexp()->e2 == this)
+    {
+        aa = p->topexp()->v;
+    }
+    else
+    {
+        llvm::Value* tmp = new llvm::AllocaInst(DtoType(type),"aaliteral",p->topallocapoint());
+        aa = new DVarValue(type, tmp, true);
+    }
+
     const size_t n = keys->dim;
     for (size_t i=0; i<n; ++i)
     {
@@ -2590,9 +2617,17 @@
         Expression* eval = (Expression*)values->data[i];
 
         Logger::println("(%u) aa[%s] = %s", i, ekey->toChars(), eval->toChars());
+
+        // index
+        DValue* key = ekey->toElem(p);
+        DValue* mem = DtoAAIndex(vtype, aa, key);
+
+        // store
+        DValue* val = eval->toElem(p);
+        DtoAssign(mem, val);
     }
 
-    assert(0);
+    return aa;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -2666,7 +2701,7 @@
 //STUB(CommaExp);
 //STUB(ArrayLengthExp);
 //STUB(HaltExp);
-STUB(RemoveExp);
+//STUB(RemoveExp);
 //STUB(ArrayLiteralExp);
 //STUB(AssocArrayLiteralExp);
 //STUB(StructLiteralExp);
--- a/llvmdc.kdevelop	Wed Nov 28 05:04:38 2007 +0100
+++ b/llvmdc.kdevelop	Fri Nov 30 12:56:52 2007 +0100
@@ -14,8 +14,8 @@
     <projectname>llvmdc</projectname>
     <projectdirectory>.</projectdirectory>
     <absoluteprojectpath>false</absoluteprojectpath>
-    <description></description>
-    <defaultencoding></defaultencoding>
+    <description/>
+    <defaultencoding/>
   </general>
   <kdevautoproject>
     <general/>
@@ -156,7 +156,7 @@
       <includePaths>.;</includePaths>
     </codecompletion>
     <creategettersetter>
-      <prefixGet></prefixGet>
+      <prefixGet/>
       <prefixSet>set</prefixSet>
       <prefixVariable>m_,_</prefixVariable>
       <parameterName>theValue</parameterName>
@@ -168,14 +168,16 @@
       <synchronize>true</synchronize>
       <orientation>Vertical</orientation>
     </splitheadersource>
-    <references/>
+    <references>
+      <pcs>LLVM</pcs>
+    </references>
   </kdevcppsupport>
   <kdevcustomproject>
     <run>
       <directoryradio>executable</directoryradio>
       <mainprogram>/home/tomas/kdevprojects/llvmdc</mainprogram>
-      <programargs></programargs>
-      <globaldebugarguments></globaldebugarguments>
+      <programargs/>
+      <globaldebugarguments/>
       <globalcwd>/home/tomas/kdevprojects/llvmdc</globalcwd>
       <useglobalprogram>false</useglobalprogram>
       <terminal>false</terminal>
@@ -398,13 +400,13 @@
     </blacklist>
     <build>
       <buildtool>make</buildtool>
-      <builddir></builddir>
+      <builddir/>
     </build>
     <other>
       <prio>0</prio>
-      <otherbin></otherbin>
-      <defaulttarget></defaulttarget>
-      <otheroptions></otheroptions>
+      <otherbin/>
+      <defaulttarget/>
+      <otheroptions/>
       <selectedenvironment>default</selectedenvironment>
       <environments>
         <default/>
@@ -415,9 +417,9 @@
       <numberofjobs>0</numberofjobs>
       <prio>0</prio>
       <dontact>false</dontact>
-      <makebin></makebin>
-      <defaulttarget></defaulttarget>
-      <makeoptions></makeoptions>
+      <makebin/>
+      <defaulttarget/>
+      <makeoptions/>
       <selectedenvironment>default</selectedenvironment>
       <environments>
         <default/>
@@ -432,11 +434,11 @@
   </cppsupportpart>
   <kdevdebugger>
     <general>
-      <gdbpath></gdbpath>
-      <dbgshell></dbgshell>
-      <configGdbScript></configGdbScript>
-      <runShellScript></runShellScript>
-      <runGdbScript></runGdbScript>
+      <gdbpath/>
+      <dbgshell/>
+      <configGdbScript/>
+      <runShellScript/>
+      <runGdbScript/>
       <breakonloadinglibs>true</breakonloadinglibs>
       <separatetty>false</separatetty>
       <floatingtoolbar>false</floatingtoolbar>
--- a/lphobos/internal/aaA.d	Wed Nov 28 05:04:38 2007 +0100
+++ b/lphobos/internal/aaA.d	Fri Nov 30 12:56:52 2007 +0100
@@ -98,8 +98,9 @@
 
 size_t aligntsize(size_t tsize)
 {
-    // Is pointer alignment on the x64 4 bytes or 8?
-    return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
+    // Is pointer alignment on the x86-64 4 bytes or 8?
+    //return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1);
+    return (tsize + 3) & (~3);
 }
 
 extern (C):
@@ -742,7 +743,8 @@
  * length pairs of key/value pairs.
  */
 
-extern (C)
+version(none) // not used, C variadics can't be implemented in LLVM on x86-64
+{
 BB* _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...)
 {
     auto valuesize = ti.next.tsize();		// value size
@@ -819,5 +821,5 @@
     }
     return result;
 }
+}
 
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/aa6.d	Fri Nov 30 12:56:52 2007 +0100
@@ -0,0 +1,25 @@
+module aa6;
+
+void main()
+{
+    int[int] aa;
+    aa = [1:1, 2:4, 3:9, 4:16];
+    printf("---\n");
+    foreach(int k, int v; aa)
+        printf("aa[%d] = %d\n", k, v);
+    aa.rehash;
+    printf("---\n");
+    foreach(int k, int v; aa)
+        printf("aa[%d] = %d\n", k, v);
+    size_t n = aa.length;
+    assert(n == 4);
+    int[] keys = aa.keys;
+    assert(keys[] == [1,2,3,4][]);
+    int[] vals = aa.values;
+    assert(vals[] == [1,4,9,16][]);
+    aa.remove(3);
+    printf("---\n");
+    foreach(int k, int v; aa)
+        printf("aa[%d] = %d\n", k, v);
+    assert(aa.length == 3);
+}