# HG changeset patch # User lindquist # Date 1196423812 -3600 # Node ID facc562f56743f9e77914f93d476169d9c94fd85 # Parent a2c2c3c1a73db8ed50fce294a1c4af6f09b2426f [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. diff -r a2c2c3c1a73d -r facc562f5674 dmd/mars.c --- 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; diff -r a2c2c3c1a73d -r facc562f5674 dmd/mtype.c --- 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)); diff -r a2c2c3c1a73d -r facc562f5674 gen/aa.cpp --- 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 args; + args.push_back(aaval); + args.push_back(keyti); + args.push_back(pkey); + + // call runtime + gIR->ir->CreateCall(func, args.begin(), args.end(),""); +} diff -r a2c2c3c1a73d -r facc562f5674 gen/aa.h --- 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 diff -r a2c2c3c1a73d -r facc562f5674 gen/arrays.cpp --- 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")); } diff -r a2c2c3c1a73d -r facc562f5674 gen/functions.cpp --- 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; } diff -r a2c2c3c1a73d -r facc562f5674 gen/toir.cpp --- 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; idata[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); diff -r a2c2c3c1a73d -r facc562f5674 llvmdc.kdevelop --- 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 @@ llvmdc . false - - + + @@ -156,7 +156,7 @@ .; - + set m_,_ theValue @@ -168,14 +168,16 @@ true Vertical - + + LLVM + executable /home/tomas/kdevprojects/llvmdc - - + + /home/tomas/kdevprojects/llvmdc false false @@ -398,13 +400,13 @@ make - + 0 - - - + + + default @@ -415,9 +417,9 @@ 0 0 false - - - + + + default @@ -432,11 +434,11 @@ - - - - - + + + + + true false false diff -r a2c2c3c1a73d -r facc562f5674 lphobos/internal/aaA.d --- 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; } +} - diff -r a2c2c3c1a73d -r facc562f5674 test/aa6.d --- /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); +}