changeset 1455:89e38fbfef1f

Automated merge with http://hg.dsource.org/projects/ldc
author Robert Clipsham <robert@octarineparrot.com>
date Mon, 01 Jun 2009 19:02:20 +0100
parents 301a916eceef (diff) ff707c518ad7 (current diff)
children 7b218ec1044f
files dmd2/array.c dmd2/dchar.c dmd2/dchar.h dmd2/e2ir.c.nolink dmd2/gnuc.c dmd2/gnuc.h dmd2/link.c.nolink dmd2/lstring.c dmd2/lstring.h dmd2/man.c dmd2/port.h dmd2/root.c dmd2/root.h dmd2/stringtable.c dmd2/stringtable.h gen/classes.cpp
diffstat 44 files changed, 254 insertions(+), 241 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/func.c	Mon Jun 01 19:02:09 2009 +0100
+++ b/dmd/func.c	Mon Jun 01 19:02:20 2009 +0100
@@ -1266,12 +1266,17 @@
 		}
 		else
 		{   // Call invariant virtually
-		    ThisExp *v = new ThisExp(0);
-		    v->type = vthis->type;
-                    e = new AssertExp(loc, v, NULL);
+                    // LDC: unless this is a struct without invariant
+                    StructDeclaration* sd = ad->isStructDeclaration();
+                    if (!sd || sd->inv)
+                    {
+                        ThisExp *v = new ThisExp(0);
+                        v->type = vthis->type;
+                        e = new AssertExp(loc, v, NULL);
+                    }
 
                     // LDC: check for null this
-                    v = new ThisExp(0);
+                    ThisExp* v = new ThisExp(0);
                     v->type = vthis->type;
                     v->var = vthis;
 
--- a/dmd/lexer.c	Mon Jun 01 19:02:09 2009 +0100
+++ b/dmd/lexer.c	Mon Jun 01 19:02:20 2009 +0100
@@ -8,6 +8,10 @@
 // in artistic.txt, or the GNU General Public License in gnu.txt.
 // See the included readme.txt for details.
 
+#if __sun && __SVR4
+#define __C99FEATURES__ 1       // Needed on Solaris for NaN and more, LDC#313
+#endif
+
 #if IN_LLVM
 #include <cmath>
 #endif
--- a/gen/abi-x86-64.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/abi-x86-64.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -677,6 +677,13 @@
             }
         }
         
+        if (fty.arg_this) {
+            fty.arg_this->attrs |= llvm::Attribute::Nest;
+        }
+        if (fty.arg_nest) {
+            fty.arg_nest->attrs |= llvm::Attribute::Nest;
+        }
+        
         Logger::println("x86-64 D ABI: Transforming arguments");
         LOG_SCOPE;
         
--- a/gen/abi.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/abi.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -132,7 +132,7 @@
         assert(dv->isLVal());
         LLValue* mem = dv->getLVal();
         const LLType* t = LLIntegerType::get(dty->size()*8);
-        DtoLoad(DtoBitCast(mem, getPtrToType(t)));
+        return DtoLoad(DtoBitCast(mem, getPtrToType(t)));
     }
     const LLType* type(Type* t, const LLType*)
     {
@@ -196,8 +196,16 @@
                 Logger::println("Putting context ptr in register");
                 fty.arg_nest->attrs = llvm::Attribute::InReg;
             }
+            else if (IrFuncTyArg* sret = fty.arg_sret)
+            {
+                Logger::println("Putting sret ptr in register");
+                // sret and inreg are incompatible, but the ABI requires the
+                // sret parameter to be in EAX in this situation...
+                sret->attrs = (sret->attrs | llvm::Attribute::InReg)
+                                & ~llvm::Attribute::StructRet;
+            }
             // otherwise try to mark the last param inreg
-            else if (!fty.arg_sret && !fty.args.empty())
+            else if (!fty.args.empty())
             {
                 // The last parameter is passed in EAX rather than being pushed on the stack if the following conditions are met:
                 //   * It fits in EAX.
--- a/gen/arrays.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/arrays.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -894,7 +894,10 @@
 
     Type* totype = to->toBasetype();
     Type* fromtype = u->getType()->toBasetype();
-    assert(fromtype->ty == Tarray || fromtype->ty == Tsarray);
+    if (fromtype->ty != Tarray && fromtype->ty != Tsarray) {
+        error(loc, "can't cast %s to %s", u->getType()->toChars(), to->toChars());
+        fatal();
+    }
 
     LLValue* rval;
     LLValue* rval2;
--- a/gen/asm-x86-32.h	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/asm-x86-32.h	Mon Jun 01 19:02:20 2009 +0100
@@ -1528,9 +1528,8 @@
                                 }
 
                                 // osx needs an extra underscore
-                                if ( global.params.os == OSMacOSX )
-                                    insnTemplate << "_";
-
+                                if ( global.params.os == OSMacOSX || global.params.os == OSWindows )
+                                	insnTemplate << "_";
                                 // print out the mangle
                                 insnTemplate << vd->mangle();
                                 vd->nakedUse = true;
--- a/gen/classes.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/classes.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -514,7 +514,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl)
+LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl, char* name)
 {
     // sanity checks
     assert(fdecl->isVirtual());
@@ -533,7 +533,9 @@
     // load vtbl ptr
     funcval = DtoLoad(funcval);
     // index vtbl
-    funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toChars());
+    std::string vtblname = name;
+    vtblname.append("@vtbl");
+    funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, vtblname.c_str());
     // load funcptr
     funcval = DtoAlignedLoad(funcval);
 
@@ -542,6 +544,10 @@
 
     // cast to final funcptr type
     funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
+
+    // postpone naming until after casting to get the name in call instructions
+    funcval->setName(name);
+
     if (Logger::enabled())
         Logger::cout() << "funcval casted: " << *funcval << '\n';
 
--- a/gen/classes.h	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/classes.h	Mon Jun 01 19:02:20 2009 +0100
@@ -32,6 +32,6 @@
 
 LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* sd, VarDeclaration* vd);
 
-LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl);
+LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl, char* name);
 
 #endif
--- a/gen/complex.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/complex.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -410,7 +410,7 @@
 DValue* DtoCastComplex(Loc& loc, DValue* val, Type* _to)
 {
     Type* to = _to->toBasetype();
-    Type* vty = val->getType();
+    Type* vty = val->getType()->toBasetype();
     if (to->iscomplex()) {
         if (vty->size() == to->size())
             return val;
@@ -438,17 +438,25 @@
         DImValue* im = new DImValue(to, impart);
         return DtoCastFloat(loc, im, to);
     }
-    else if (to->isfloating()) {
+    else if (to->ty == Tbool) {
+        return new DImValue(_to, DtoComplexEquals(loc, TOKnotequal, val, DtoNullValue(vty)));
+    }
+    else if (to->isfloating() || to->isintegral()) {
         // FIXME: this loads both values, even when we only need one
         LLValue* v = val->getRVal();
         LLValue* repart = gIR->ir->CreateExtractValue(v, 0, ".re_part");
-        DImValue* re = new DImValue(to, repart);
+        Type *extractty;
+        if (vty->ty == Tcomplex32) {
+            extractty = Type::tfloat32;
+        } else if (vty->ty == Tcomplex64) {
+            extractty = Type::tfloat64;
+        } else if (vty->ty == Tcomplex80) {
+            extractty = Type::tfloat80;
+        }
+        DImValue* re = new DImValue(extractty, repart);
         return DtoCastFloat(loc, re, to);
     }
-    else if (to->ty == Tbool) {
-        return new DImValue(_to, DtoComplexEquals(loc, TOKnotequal, val, DtoNullValue(vty)));
-    }
     else
-    assert(0);
+        error(loc, "Don't know how to cast %s to %s", vty->toChars(), to->toChars());
 }
 
--- a/gen/main.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/main.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -369,7 +369,7 @@
     }
     else
     {
-        if (global.params.objname && files.dim > 1)
+        if (global.params.objname && files.dim > 1 && !singleObj)
         {
             error("multiple source files, but only one .obj name");
             fatal();
--- a/gen/passes/GarbageCollect2Stack.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/passes/GarbageCollect2Stack.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -30,6 +30,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/IRBuilder.h"
 #include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/CallGraph.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Target/TargetData.h"
@@ -43,24 +44,40 @@
 STATISTIC(NumToDynSize, "Number of calls promoted to dynamically-sized allocas");
 STATISTIC(NumDeleted, "Number of GC calls deleted because the return value was unused");
 
+
+namespace {
+    struct Analysis {
+        TargetData& TD;
+        const Module& M;
+        CallGraph* CG;
+        CallGraphNode* CGNode;
+        
+        const Type* getTypeFor(Value* typeinfo) const;
+    };
+}
+
 //===----------------------------------------------------------------------===//
 // Helper functions
 //===----------------------------------------------------------------------===//
 
-void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len) {
+void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len,
+                const Analysis& A) {
     Dst = B.CreateBitCast(Dst, PointerType::getUnqual(Type::Int8Ty));
     
     Module *M = B.GetInsertBlock()->getParent()->getParent();
     const Type* Tys[1];
     Tys[0] = Len->getType();
-    Value *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 1);
+    Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 1);
     Value *Align = ConstantInt::get(Type::Int32Ty, 1);
     
-    B.CreateCall4(MemSet, Dst, Val, Len, Align);
+    CallSite CS = B.CreateCall4(MemSet, Dst, Val, Len, Align);
+    if (A.CGNode)
+        A.CGNode->addCalledFunction(CS, A.CG->getOrInsertFunction(MemSet));
 }
 
-static void EmitMemZero(IRBuilder<>& B, Value* Dst, Value* Len) {
-    EmitMemSet(B, Dst, ConstantInt::get(Type::Int8Ty, 0), Len);
+static void EmitMemZero(IRBuilder<>& B, Value* Dst, Value* Len,
+                        const Analysis& A) {
+    EmitMemSet(B, Dst, ConstantInt::get(Type::Int8Ty, 0), Len, A);
 }
 
 
@@ -69,13 +86,6 @@
 //===----------------------------------------------------------------------===//
 
 namespace {
-    struct Analysis {
-        TargetData& TD;
-        const Module& M;
-        
-        const Type* getTypeFor(Value* typeinfo) const;
-    };
-    
     class FunctionInfo {
     protected:
         const Type* Ty;
@@ -174,7 +184,7 @@
                 // Use the original B to put initialization at the
                 // allocation site.
                 Value* Size = B.CreateMul(TypeSize, arrSize);
-                EmitMemZero(B, alloca, Size);
+                EmitMemZero(B, alloca, Size, A);
             }
             
             return alloca;
@@ -252,6 +262,7 @@
         
         bool doInitialization(Module &M) {
             this->M = &M;
+            return false;
         }
         
         bool runOnFunction(Function &F);
@@ -259,6 +270,7 @@
         virtual void getAnalysisUsage(AnalysisUsage &AU) const {
           AU.addRequired<TargetData>();
           AU.addRequired<LoopInfo>();
+          AU.addPreserved<CallGraph>();
         }
     };
     char GarbageCollect2Stack::ID = 0;
@@ -284,8 +296,9 @@
     KnownFunctions["_d_allocclass"] = &AllocClass;
 }
 
-static void RemoveCall(Instruction* Inst) {
-    if (InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) {
+static void RemoveCall(CallSite CS, const Analysis& A) {
+    if (CS.isInvoke()) {
+        InvokeInst* Invoke = cast<InvokeInst>(CS.getInstruction());
         // If this was an invoke instruction, we need to do some extra
         // work to preserve the control flow.
         
@@ -296,7 +309,9 @@
         BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent());
     }
     // Remove the runtime call.
-    Inst->eraseFromParent();
+    if (A.CGNode)
+        A.CGNode->removeCallEdgeFor(CS);
+    CS.getInstruction()->eraseFromParent();
 }
 
 /// runOnFunction - Top level algorithm.
@@ -306,8 +321,10 @@
     
     TargetData &TD = getAnalysis<TargetData>();
     const LoopInfo &LI = getAnalysis<LoopInfo>();
+    CallGraph* CG = getAnalysisIfAvailable<CallGraph>();
+    CallGraphNode* CGNode = CG ? (*CG)[&F] : NULL;
     
-    Analysis A = { TD, *M };
+    Analysis A = { TD, *M, CG, CGNode };
     
     BasicBlock& Entry = F.getEntryBlock();
     
@@ -351,7 +368,7 @@
             if (Inst->use_empty() && info->SafeToDelete) {
                 Changed = true;
                 NumDeleted++;
-                RemoveCall(Inst);
+                RemoveCall(CS, A);
                 continue;
             }
             
@@ -374,7 +391,7 @@
                 newVal = Builder.CreateBitCast(newVal, Inst->getType());
             Inst->replaceAllUsesWith(newVal);
             
-            RemoveCall(Inst);
+            RemoveCall(CS, A);
         }
     }
     
--- a/gen/rttibuilder.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/rttibuilder.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -76,7 +76,7 @@
 void RTTIBuilder::push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* mangle_sym)
 {
     std::string initname(mangle_sym->mangle());
-    initname.append(".rtti.void[].data");
+    initname.append(".rtti.voidarr.data");
 
     LLGlobalVariable* G = new llvm::GlobalVariable(
         CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname, gIR->module);
@@ -87,9 +87,14 @@
 
 void RTTIBuilder::push_array(llvm::Constant * CI, uint64_t dim, Type* valtype, Dsymbol * mangle_sym)
 {
-    std::string initname(mangle_sym?mangle_sym->mangle():".ldc");
+	std::string tmpStr(valtype->arrayOf()->toChars());
+	tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), '[' ), tmpStr.end() );
+	tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), ']' ), tmpStr.end() );
+	tmpStr.append("arr");
+
+	std::string initname(mangle_sym?mangle_sym->mangle():".ldc");
     initname.append(".rtti.");
-    initname.append(valtype->arrayOf()->toChars());
+    initname.append(tmpStr);
     initname.append(".data");
 
     LLGlobalVariable* G = new llvm::GlobalVariable(
--- a/gen/tocall.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/tocall.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -322,7 +322,8 @@
         // add attrs for hidden ptr
         Attr.Index = 1;
         Attr.Attrs = tf->fty.arg_sret->attrs;
-        assert((Attr.Attrs & llvm::Attribute::StructRet) && "Sret arg not sret?");
+        assert((Attr.Attrs & (llvm::Attribute::StructRet | llvm::Attribute::InReg))
+            && "Sret arg not sret or inreg?");
         attrs.push_back(Attr);
     }
 
--- a/gen/toir.cpp	Mon Jun 01 19:02:09 2009 +0100
+++ b/gen/toir.cpp	Mon Jun 01 19:02:20 2009 +0100
@@ -1134,22 +1134,8 @@
             assert(funcval);
         }
         else {
-            assert(fdecl->vtblIndex > 0);
-            assert(e1type->ty == Tclass);
-
-            LLValue* zero = DtoConstUint(0);
-            size_t vtblidx = fdecl->vtblIndex;
-            if (Logger::enabled())
-                Logger::cout() << "vthis: " << *vthis << '\n';
-            funcval = DtoGEP(vthis, zero, zero);
-            funcval = DtoLoad(funcval);
-            Logger::println("vtblidx = %lu", vtblidx);
-            funcval = DtoGEP(funcval, zero, DtoConstUint(vtblidx), toChars());
-            funcval = DtoLoad(funcval);
-
-            funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
-            if (Logger::enabled())
-                Logger::cout() << "funcval casted: " << *funcval << '\n';
+            DImValue vthis3(e1type, vthis);
+            funcval = DtoVirtualFunctionPointer(&vthis3, fdecl, toChars());
         }
 
         return new DFuncValue(fdecl, funcval, vthis2);
@@ -2031,7 +2017,7 @@
 
     LLValue* castfptr;
     if (func->isVirtual() && !func->isFinal())
-        castfptr = DtoVirtualFunctionPointer(u, func);
+        castfptr = DtoVirtualFunctionPointer(u, func, toChars());
     else if (func->isAbstract())
         assert(0 && "TODO delegate to abstract method");
     else if (func->toParent()->isInterfaceDeclaration())
--- a/runtime/internal/genobj.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/runtime/internal/genobj.d	Mon Jun 01 19:02:20 2009 +0100
@@ -152,8 +152,8 @@
     void*[]     vtbl;           /// virtual function pointer table
     Interface[] interfaces;     /// interfaces this class implements
     ClassInfo   base;           /// base class
-    void*       destructor;
-    void function(Object) classInvariant;
+    void*       destructor;     // Only use as delegate.funcptr!
+    void*       classInvariant; // Only use as delegate.funcptr!
     uint        flags;
     //  1:                      // IUnknown
     //  2:                      // has no possible pointers into GC memory
@@ -162,7 +162,7 @@
     // 32:                      // has typeinfo
     void*       deallocator;
     OffsetTypeInfo[] offTi;
-    void* defaultConstructor;   // default Constructor
+    void* defaultConstructor;   // default Constructor. Only use as delegate.funcptr!
     TypeInfo typeinfo;
 
     /**
@@ -198,8 +198,10 @@
 
         if (flags & 8 && defaultConstructor)
         {
-            auto ctor = cast(Object function(Object))defaultConstructor;
-            return ctor(o);
+            Object delegate() ctor;
+            ctor.ptr = cast(void*)o;
+            ctor.funcptr = cast(Object function())defaultConstructor;
+            return ctor();
         }
         return o;
     }
@@ -762,7 +764,10 @@
         assert(p);
         if (xtoHash)
         {   debug(PRINTF) printf("getHash() using xtoHash\n");
-            h = (*xtoHash)(p);
+            hash_t delegate() toHash;
+            toHash.ptr = p;
+            toHash.funcptr = xtoHash;
+            h = toHash();
         }
         else
         {
@@ -785,9 +790,12 @@
             c = 1;
         else if (!p1 || !p2)
             c = 0;
-        else if (xopEquals)
-            c = (*xopEquals)(p1, p2);
-        else
+        else if (xopEquals) {
+            int delegate(void*) opEquals;
+            opEquals.ptr = p1;
+            opEquals.funcptr = xopEquals;
+            c = opEquals(p2);
+        } else
             // BUG: relies on the GC not moving objects
             c = (memcmp(p1, p2, m_init.length) == 0);
         return c;
@@ -803,13 +811,12 @@
             if (p1)
             {   if (!p2)
                     c = 1;
-                else if (xopCmp)
-                    // the x86 D calling conv requires the this arg to be last here
-                    version(X86)
-                        c = (*xopCmp)(p2, p1);
-                    else
-                        c = (*xopCmp)(p1, p2);
-                else
+                else if (xopCmp) {
+                    int delegate(void*) opCmp;
+                    opCmp.ptr = p1;
+                    opCmp.funcptr = xopCmp;
+                    c = opCmp(p2);
+                } else
                     // BUG: relies on the GC not moving objects
                     c = memcmp(p1, p2, m_init.length);
             }
@@ -831,10 +838,11 @@
     char[] name;
     void[] m_init;      // initializer; never null
 
-    hash_t function(void*)    xtoHash;
-    int function(void*,void*) xopEquals;
-    int function(void*,void*) xopCmp;
-    char[] function(void*)    xtoString;
+    // These are ONLY for use as a delegate.funcptr!
+    hash_t function()   xtoHash;
+    int function(void*) xopEquals;
+    int function(void*) xopCmp;
+    char[] function()   xtoString;
 
     uint m_flags;
 }
--- a/runtime/internal/invariant.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/runtime/internal/invariant.d	Mon Jun 01 19:02:20 2009 +0100
@@ -18,7 +18,10 @@
     {
 	if (c.classInvariant)
 	{
-	    (*c.classInvariant)(o);
+	    void delegate() inv;
+	    inv.ptr = cast(void*) o;
+	    inv.funcptr = c.classInvariant;
+	    inv();
 	}
 	c = c.base;
     } while (c);
--- a/runtime/internal/lifetime.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/runtime/internal/lifetime.d	Mon Jun 01 19:02:20 2009 +0100
@@ -560,8 +560,10 @@
                         if (c.destructor)
                         {
                             debug(PRINTF) printf("calling dtor of %.*s\n", c.name.length, c.name.ptr);
-                            fp_t fp = cast(fp_t)c.destructor;
-                            (*fp)(cast(Object)p); // call destructor
+                            void delegate() dg;
+                            dg.ptr = p;
+                            dg.funcptr = cast(void function()) c.destructor;
+                            dg(); // call destructor
                         }
                         c = c.base;
                     } while (c);
--- a/tango-0.99.8.patch	Mon Jun 01 19:02:09 2009 +0100
+++ b/tango-0.99.8.patch	Mon Jun 01 19:02:20 2009 +0100
@@ -1,8 +1,15 @@
 Index: object.di
 ===================================================================
---- object.di	(revision 4655)
+--- object.di	(revision 4578)
 +++ object.di	(working copy)
-@@ -41,9 +41,11 @@
+@@ -35,15 +35,17 @@
+     Interface[] interfaces;
+     ClassInfo   base;
+     void*       destructor;
+-    void(*classInvariant)(Object);
++    void*       classInvariant;
+     uint        flags;
+     // 1:       // IUnknown
      // 2:       // has no possible pointers into GC memory
      // 4:       // has offTi[] member
      // 8:       // has constructors
@@ -14,9 +21,25 @@
  
      static ClassInfo find(char[] classname);
      Object create();
+@@ -127,10 +129,11 @@
+     char[] name;
+     void[] m_init;
+ 
+-    uint function(void*)      xtoHash;
+-    int function(void*,void*) xopEquals;
+-    int function(void*,void*) xopCmp;
+-    char[] function(void*)    xtoString;
++    // These are ONLY for use as a delegate.funcptr!
++    hash_t function()   xtoHash;
++    int function(void*) xopEquals;
++    int function(void*) xopCmp;
++    char[] function()   xtoString;
+ 
+     uint m_flags;
+ }
 Index: lib/common/tango/core/Thread.d
 ===================================================================
---- lib/common/tango/core/Thread.d	(revision 4655)
+--- lib/common/tango/core/Thread.d	(revision 4578)
 +++ lib/common/tango/core/Thread.d	(working copy)
 @@ -295,7 +295,7 @@
                  }
@@ -38,7 +61,7 @@
                          movq r12[RBP], R12        ;
 Index: lib/gc/basic/gcx.d
 ===================================================================
---- lib/gc/basic/gcx.d	(revision 4655)
+--- lib/gc/basic/gcx.d	(revision 4578)
 +++ lib/gc/basic/gcx.d	(working copy)
 @@ -2198,7 +2198,7 @@
              }
@@ -58,9 +81,28 @@
                      movq r10[RBP], R10      ;
                      movq r11[RBP], R11      ;
                      movq r12[RBP], R12      ;
+Index: tango/text/convert/Layout.d
+===================================================================
+--- tango/text/convert/Layout.d	(revision 4578)
++++ tango/text/convert/Layout.d	(working copy)
+@@ -660,8 +660,12 @@
+ 
+                        case TypeCode.STRUCT:
+                             auto s = cast(TypeInfo_Struct) type;
+-                            if (s.xtoString)
+-                                return Utf.fromString8 (s.xtoString(p), result);
++                            if (s.xtoString) {
++                                char[] delegate() toString;
++                                toString.ptr = p;
++                                toString.funcptr = cast(char[] function()) s.xtoString;
++                                return Utf.fromString8 (toString(), result);
++                            }
+                             goto default;
+ 
+                        case TypeCode.INTERFACE:
 Index: tango/net/Socket.d
 ===================================================================
---- tango/net/Socket.d	(revision 4655)
+--- tango/net/Socket.d	(revision 4578)
 +++ tango/net/Socket.d	(working copy)
 @@ -1545,10 +1545,10 @@
  
--- a/tests/mini/callingconv1.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/callingconv1.d	Mon Jun 01 19:02:20 2009 +0100
@@ -15,15 +15,32 @@
 
     version(D_InlineAsm_X86)
     {
-	asm
-    	{
-		mov EAX, [a];
-        	push EAX;
-        	mov EAX, [b];
-        	push EAX;
-        	call foo;
-        	fstp c;
-    	}
+	    version(Windows) 
+	    {
+    		asm
+    		{
+				movss XMM0, [a];
+				movss XMM1, [b];
+				movss [ESP], XMM1;
+				movss [ESP]+4, XMM0;		
+					call foo;
+				fstp [c]-4;
+				movss XMM0, [c]-4;
+				movss [c], XMM0;
+    		}
+		} else 
+		{
+		   
+			asm
+    		{
+				mov EAX, [a];
+        		push EAX;
+        		mov EAX, [b];
+        		push EAX;
+        		call foo;
+        		fstp c;
+    		}
+		}
     }
     else version(D_InlineAsm_X86_64)
     {
--- a/tests/mini/m.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/m.d	Mon Jun 01 19:02:20 2009 +0100
@@ -9,6 +9,9 @@
 version(darwin) {
     int* __error();
     alias __error __errno_location;
+} else version (Windows) {
+    int* strerror();
+    alias strerror __errno_location;
 } else {
     int* __errno_location();
 }
--- a/tests/mini/naked_asm5.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/naked_asm5.d	Mon Jun 01 19:02:20 2009 +0100
@@ -3,9 +3,17 @@
     version(X86)
     {
     const OP = (op == '+') ? "add" : "sub";
-    asm { naked; }
-    mixin("asm{"~OP~" EAX, [ESP+4];}");
-    asm { ret 4; }
+    version (Windows)
+    {
+    	asm { naked; }
+    	mixin("asm{push EBP;mov EBP,ESP;sub ESP,8;mov ECX,[EBP+8];"~OP~" EAX, ECX;add ESP,8;pop EBP;}");
+    	asm { ret; }
+	} else
+	{
+    	asm { naked; }
+    	mixin("asm{"~OP~" EAX, [ESP+4];}");
+    	asm { ret 4; }
+	}
     }
     else version(X86_64)
     {
--- a/tests/mini/norun_debug1.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug1.d	Mon Jun 01 19:02:20 2009 +0100
@@ -2,7 +2,7 @@
 
 void main()
 {
-    int* ptr;
+    int* ptr = cast(int*) 1;
 
     // all these should be inspectable
     int i = 1;
--- a/tests/mini/norun_debug10.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug10.d	Mon Jun 01 19:02:20 2009 +0100
@@ -16,6 +16,6 @@
 
 void func(Vec2 v2, ref Vec2 rv2, char[] str, out int i, ref float f)
 {
-    int* fail;
+    int* fail = cast(int*) 1;
     *fail = 0;
 }
--- a/tests/mini/norun_debug12.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug12.d	Mon Jun 01 19:02:20 2009 +0100
@@ -19,6 +19,6 @@
     scope c = new C;
     I i = c;
 
-    int* fail;
+    int* fail = cast(int*) 1;
     *fail = 0;
 }
--- a/tests/mini/norun_debug2.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug2.d	Mon Jun 01 19:02:20 2009 +0100
@@ -8,7 +8,7 @@
     while (iter < 25)
     {
         if (rand() % 20 == 10)
-            *cast(int*)null = 0;
+            *cast(int*)1 = 0;
         ++iter;
     }
     assert(0);
--- a/tests/mini/norun_debug3.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug3.d	Mon Jun 01 19:02:20 2009 +0100
@@ -5,6 +5,6 @@
     int i = 42;
     int* ip = &i;
 
-    int* fail;
+    int* fail = cast(int*) 1;
     *fail = 0;
 }
--- a/tests/mini/norun_debug4.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug4.d	Mon Jun 01 19:02:20 2009 +0100
@@ -6,6 +6,6 @@
     wchar wc = 'w';
     dchar dc = 'd';
 
-    int* fail;
+    int* fail = cast(int*) 1;
     *fail = 32;
 }
--- a/tests/mini/norun_debug5.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug5.d	Mon Jun 01 19:02:20 2009 +0100
@@ -10,6 +10,6 @@
 
 void func(int i, real r, real* p)
 {
-    int* fail;
+    int* fail = cast(int*) 1;
     *fail = 666;
 }
--- a/tests/mini/norun_debug6.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug6.d	Mon Jun 01 19:02:20 2009 +0100
@@ -4,6 +4,6 @@
 {
     char[] str = "hello world :)";
 
-    int* fail;
+    int* fail = cast(int*) 1;
     *fail = 32;
 }
--- a/tests/mini/norun_debug7.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug7.d	Mon Jun 01 19:02:20 2009 +0100
@@ -4,6 +4,6 @@
 
 void main()
 {
-    int* fail;
+    int* fail = cast(int*) 1;
     *fail = 0;
 }
--- a/tests/mini/norun_debug8.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug8.d	Mon Jun 01 19:02:20 2009 +0100
@@ -26,6 +26,6 @@
     foo.bar.y = 3.1415;
     foo.bar.foo = &foo;
 
-    int* fail;
+    int* fail = cast(int*) 1;
     *fail = 0;
 }
--- a/tests/mini/norun_debug9.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/norun_debug9.d	Mon Jun 01 19:02:20 2009 +0100
@@ -6,7 +6,7 @@
 
     void func()
     {
-        int* fail;
+        int* fail = cast(int*) 1;
         *fail = 0;
     }
 }
--- a/tests/mini/phobos/bug57.d	Mon Jun 01 19:02:09 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-import std.stdio;
-class Foo {}
-void func3()
-{
-    Foo[1] test=[new Foo];
-    writefln(test);
-}
-void main() {
-    func3();
-}
--- a/tests/mini/phobos/bug58.d	Mon Jun 01 19:02:09 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-module bug58;
-import std.stdio;
-void main()
-{
-    int[16] arr = [1,16,2,15,3,14,4,13,5,12,6,11,7,10,8,9];
-    writefln("arr = ",arr);
-    arr.sort;
-    writefln("arr.sort = ",arr);
-    assert(arr == [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
-}
--- a/tests/mini/phobos/bug66.d	Mon Jun 01 19:02:09 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-module bug66;
-import std.stdio;
-class Scene { string name() { return "Scene"; } }
-class Group : Scene { this () { } }
-void main() { writefln((new Group).name); }
--- a/tests/mini/phobos/bug71.d	Mon Jun 01 19:02:09 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-module bug71;
-
-void main()
-{
-    static TypeInfo skipCI(TypeInfo valti)
-    {
-      while (1)
-      {
-    if (valti.classinfo.name.length == 18 &&
-        valti.classinfo.name[9..18] == "Invariant")
-        valti = (cast(TypeInfo_Invariant)valti).next;
-    else if (valti.classinfo.name.length == 14 &&
-        valti.classinfo.name[9..14] == "Const")
-        valti = (cast(TypeInfo_Const)valti).next;
-    else
-        break;
-      }
-      return valti;
-    }
-}
\ No newline at end of file
--- a/tests/mini/phobos/bug79.d	Mon Jun 01 19:02:09 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-module bug79;
-import std.c.linux.linux;
-void main()
-{
-    timespec ts; 
-    ts.tv_nsec -= 1;
-    //auto t = ts.tv_nsec - 1;
-    //t -= 1;
-}
--- a/tests/mini/phobos/imports2.d	Mon Jun 01 19:02:09 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-module imports2;
-import std.stdio;
-
-void main() {
-    writefln("Hello world!"[]);
-}
--- a/tests/mini/phobos/stdiotest.d	Mon Jun 01 19:02:09 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-module stdiotest;
-
-import std.stdio;
-
-T typed(T)(T x)
-{
-    return x;
-}
-
-void main()
-{
-    /*char[] str = "hello";
-    writefln(str);
-
-    writefln("hello world");*/
-
-    char[] fmt = "%s";
-    writefln(2.0f);
-
-    /*{writefln(typed!(byte)(1));}
-    {writefln(typed!(short)(2));}
-    {writefln(typed!(int)(3));}
-    {writefln(typed!(long)(-4));}
-    {writefln(typed!(ulong)(5));}
-    {writefln("%f", typed!(float)(6));}
-    {writefln("%f", typed!(double)(7));}
-    {writefln("%f", typed!(real)(8));}*/
-}
--- a/tests/mini/phobos/stdiotest2.d	Mon Jun 01 19:02:09 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-module stdiotest2;
-import std.stdio;
-void main()
-{
-    int[4] v = [1,2,3,4];
-    {
-        writefln("%s", v);
-        {
-            int[] dv = v;
-            {writefln("%s", dv);}
-        }
-    }
-
-    {
-        writefln(v);
-        {
-            //int[] dv = v;
-            //{writefln(dv);}
-        }
-    }
-    //writefln(1,2,3,4.56,"hello",v);
-}
--- a/tests/mini/phobos/strings2.d	Mon Jun 01 19:02:09 2009 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-module strings2;
-
-import std.string;
-import std.stdio;
-
-void main()
-{
-    int i = 32;
-    auto str = format(i);
-    writefln(str);
-
-    long l = 123123;
-    str = format(l);
-    writefln(str);
-}
--- a/tests/mini/typeinfo10.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/typeinfo10.d	Mon Jun 01 19:02:20 2009 +0100
@@ -58,7 +58,10 @@
         assert(ti.compare(&v,&u) > 0);
         {
             auto tis = cast(TypeInfo_Struct)ti;
-            assert(tis.xtoString(&s) == s.toString());
+            char[] delegate() structToString;
+            structToString.ptr = &s;
+            structToString.funcptr = tis.xtoString;
+            assert(structToString() == s.toString());
         }
     }
 }
--- a/tests/mini/vararg6.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/mini/vararg6.d	Mon Jun 01 19:02:20 2009 +0100
@@ -1,5 +1,5 @@
 // tries to implement a fairly complete variadic print function
-module tangotests.vararg3;
+module tangotests.vararg6;
 
 extern(C) int printf(char*, ...);
 
@@ -179,7 +179,10 @@
     {
         if (sti.xtoString !is null)
         {
-            char[] str = sti.xtoString(arg);
+            char[] delegate() toString;
+            toString.ptr = arg;
+            toString.funcptr = sti.xtoString;
+            char[] str = toString();
             printf("%.*s", str.length, str.ptr);
         }
         else
--- a/tests/runminitest.d	Mon Jun 01 19:02:09 2009 +0100
+++ b/tests/runminitest.d	Mon Jun 01 19:02:20 2009 +0100
@@ -69,7 +69,7 @@
                 compilefailed ~= c.toString;
         }
         else if (cl == RUN || cl == NORUN) {
-            if (system(toStringz("obj/" ~ testname)) != 0) {
+            if (system(toStringz(Path.native("obj/" ~ testname))) != 0) {
                 if (cl == RUN)
                     runfailed ~= c.toString;
             }