diff --git a/tango-0.99.8.patch b/tango-0.99.8.patch deleted file mode 100644 index 8a90be2f..00000000 --- a/tango-0.99.8.patch +++ /dev/null @@ -1,121 +0,0 @@ -Index: object.di -=================================================================== ---- object.di (revision 4578) -+++ object.di (working copy) -@@ -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 -+ // 32: // has typeinfo - void* deallocator; - OffsetTypeInfo[] offTi; - void* defaultConstructor; -+ TypeInfo typeinfo; - - 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 4578) -+++ lib/common/tango/core/Thread.d (working copy) -@@ -295,7 +295,7 @@ - } - else version (X86_64) - { -- ulong rax,rbx,rcx,rdx,rbp,rsi,rdi,rsp,r10,r11,r12,r13,r14,r15; -+ ulong rax,rbx,rcx,rdx,rbp,rsi,rdi,rsp,r8,r9,r10,r11,r12,r13,r14,r15; - asm - { - movq rax[RBP], RAX ; -@@ -306,6 +306,8 @@ - movq rsi[RBP], RSI ; - movq rdi[RBP], RDI ; - movq rsp[RBP], RSP ; -+ movq r8[RBP], R8 ; -+ movq r9[RBP], R9 ; - movq r10[RBP], R10 ; - movq r11[RBP], R11 ; - movq r12[RBP], R12 ; -Index: lib/gc/basic/gcx.d -=================================================================== ---- lib/gc/basic/gcx.d (revision 4578) -+++ lib/gc/basic/gcx.d (working copy) -@@ -2198,7 +2198,7 @@ - } - else version (X86_64) - { -- ulong rax,rbx,rcx,rdx,rbp,rsi,rdi,rsp,r10,r11,r12,r13,r14,r15; -+ ulong rax,rbx,rcx,rdx,rbp,rsi,rdi,rsp,r8,r9,r10,r11,r12,r13,r14,r15; - asm - { - movq rax[RBP], RAX ; -@@ -2209,6 +2209,8 @@ - movq rsi[RBP], RSI ; - movq rdi[RBP], RDI ; - movq rsp[RBP], RSP ; -+ movq r8[RBP], R8 ; -+ movq r9[RBP], R9 ; - 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 4578) -+++ tango/net/Socket.d (working copy) -@@ -1545,10 +1545,10 @@ - - abstract class Address - { -- protected sockaddr* name(); -- protected int nameLen(); -- AddressFamily addressFamily(); -- char[] toString(); -+ abstract protected sockaddr* name(); -+ abstract protected int nameLen(); -+ abstract AddressFamily addressFamily(); -+ abstract char[] toString(); - - /*********************************************************************** - diff --git a/tango-0.99.9.patch b/tango-0.99.9.patch deleted file mode 100644 index 5bcc69de..00000000 --- a/tango-0.99.9.patch +++ /dev/null @@ -1,948 +0,0 @@ -Index: tango/core/rt/compiler/ldc/ldc/intrinsics.di -=================================================================== ---- tango/core/rt/compiler/ldc/ldc/intrinsics.di (revision 5576) -+++ tango/core/rt/compiler/ldc/ldc/intrinsics.di (working copy) -@@ -101,8 +101,16 @@ - // Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do - // not return a value, and takes an extra alignment argument. - --pragma(intrinsic, "llvm.memcpy.i#") -- void llvm_memcpy(T)(void* dst, void* src, T len, uint alignment); -+version(LDC_LLVMPre28) -+{ -+ pragma(intrinsic, "llvm.memcpy.i#") -+ void llvm_memcpy(T)(void* dst, void* src, T len, uint alignment); -+} -+else -+{ -+ pragma(intrinsic, "llvm.memcpy.p0i8.p0i8.i#") -+ void llvm_memcpy(T)(void* dst, void* src, T len, uint alignment, bool volatile_); -+} - - deprecated { - alias llvm_memcpy!(uint) llvm_memcpy_i32; -@@ -116,8 +124,16 @@ - // Note that, unlike the standard libc function, the llvm.memmove.* intrinsics - // do not return a value, and takes an extra alignment argument. - --pragma(intrinsic, "llvm.memmove.i#") -- void llvm_memmove(T)(void* dst, void* src, T len, uint alignment); -+version(LDC_LLVMPre28) -+{ -+ pragma(intrinsic, "llvm.memmove.i#") -+ void llvm_memmove(T)(void* dst, void* src, T len, uint alignment); -+} -+else -+{ -+ pragma(intrinsic, "llvm.memmove.p0i8.p0i8.i#") -+ void llvm_memmove(T)(void* dst, void* src, T len, uint alignment, bool volatile_); -+} - - deprecated { - alias llvm_memmove!(uint) llvm_memmove_i32; -@@ -130,8 +146,16 @@ - // Note that, unlike the standard libc function, the llvm.memset intrinsic does - // not return a value, and takes an extra alignment argument. - --pragma(intrinsic, "llvm.memset.i#") -- void llvm_memset(T)(void* dst, ubyte val, T len, uint alignment); -+version(LDC_LLVMPre28) -+{ -+ pragma(intrinsic, "llvm.memset.i#") -+ void llvm_memset(T)(void* dst, ubyte val, T len, uint alignment); -+} -+else -+{ -+ pragma(intrinsic, "llvm.memset.p0i8.i#") -+ void llvm_memset(T)(void* dst, ubyte val, T len, uint alignment, bool volatile_); -+} - - deprecated { - alias llvm_memset!(uint) llvm_memset_i32; -Index: tango/core/rt/compiler/ldc/rt/lifetime.d -=================================================================== ---- tango/core/rt/compiler/ldc/rt/lifetime.d (revision 5576) -+++ tango/core/rt/compiler/ldc/rt/lifetime.d (working copy) -@@ -241,7 +241,7 @@ - } - - /** -- * As _d_newarrayT, but -+ * As _d_newarrayT, but - * for when the array has a non-zero initializer. - */ - extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length) -@@ -359,7 +359,7 @@ - - - /** -- * As _d_newarraymT, but -+ * 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) -@@ -483,7 +483,7 @@ - // if (p) - // { - // This assert on array consistency may fail with casts or in unions. --// This function still does something sensible even if plength && !pdata. -+// This function still does something sensible even if plength && !pdata. - // assert(!plength || pdata); - - if (pdata) -@@ -505,9 +505,9 @@ - } - } - --/** -- * -- */ -+/** -+ * -+ */ - extern (C) void _d_callinterfacefinalizer(void *p) - { - if (p) -@@ -544,9 +544,9 @@ - - if (p) // not necessary if called from gc - { -- if (det) -- (cast(Object)p).dispose(); -- -+ if (det) -+ (cast(Object)p).dispose(); -+ - ClassInfo** pc = cast(ClassInfo**)p; - - if (*pc) -@@ -593,7 +593,7 @@ - { - assert(ti); - // This assert on array consistency may fail with casts or in unions. --// This function still does something sensible even if plength && !pdata. -+// This function still does something sensible even if plength && !pdata. - // assert(!plength || pdata); - } - body -@@ -651,7 +651,6 @@ - return newdata; - } - -- - /** - * Resize arrays for non-zero initializers. - * p pointer to array lvalue to be updated -@@ -664,7 +663,7 @@ - in - { - // This assert on array consistency may fail with casts or in unions. --// This function still does something sensible even if plength && !pdata. -+// This function still does something sensible even if plength && !pdata. - // assert(!plength || pdata); - } - body -@@ -786,6 +785,7 @@ - return *cast(long*)px; - } - -++/ - - /** - * -@@ -824,8 +824,8 @@ - const size_t b=0; // flatness factor, how fast the extra space decreases with array size - const size_t a=100; // allocate at most a% of the requested size as extra space (rounding will change this) - const size_t minBits=1; // minimum bit size -- - -+ - static size_t log2plusB(size_t c) - { - // could use the bsr bit op -@@ -847,12 +847,12 @@ - return newcap; - } - -- - /** -- * -+ * Appends a single element to an array. - */ --extern (C) byte[] _d_arrayappendcT(TypeInfo ti, ref byte[] x, ...) -+extern (C) byte[] _d_arrayappendcT(TypeInfo ti, void* array, void* element) - { -+ auto x = cast(byte[]*)array; - auto sizeelem = ti.next.tsize(); // array element size - auto info = gc_query(x.ptr); - auto length = x.length; -@@ -879,18 +879,19 @@ - assert(newcap >= newlength * sizeelem); - newdata = cast(byte *)gc_malloc(newcap + 1, info.attr); - memcpy(newdata, x.ptr, length * sizeelem); -- (cast(void**)(&x))[1] = newdata; -+ (cast(void**)x)[1] = newdata; - } - L1: -- byte *argp = cast(byte *)(&ti + 2); -+ byte *argp = cast(byte *)element; - -- *cast(size_t *)&x = newlength; -+ *cast(size_t *)x = newlength; - x.ptr[length * sizeelem .. newsize] = argp[0 .. sizeelem]; - assert((cast(size_t)x.ptr & 15) == 0); - assert(gc_sizeOf(x.ptr) > x.length * sizeelem); -- return x; -+ return *x; - } - -+/+ - - /** - * Append dchar to char[] -@@ -1128,7 +1129,6 @@ - return result; - } - -- - /** - * - */ -Index: tango/core/rt/compiler/ldc/rt/arrayInit.d -=================================================================== ---- tango/core/rt/compiler/ldc/rt/arrayInit.d (revision 5576) -+++ tango/core/rt/compiler/ldc/rt/arrayInit.d (working copy) -@@ -114,7 +114,10 @@ - auto p = a; - auto end = a + na*nv; - while (p !is end) { -- llvm_memcpy(p,v,nv,0); -+ version(LDC_LLVMPre28) -+ llvm_memcpy(p,v,nv,0); -+ else -+ llvm_memcpy(p,v,nv,1, false); - p += nv; - } - } -@@ -164,7 +167,12 @@ - if (dstlen != srclen) - throw new Exception("lengths don't match for array copy"); - else if (dst+dstlen <= src || src+srclen <= dst) -- llvm_memcpy(dst, src, dstlen, 0); -+ { -+ version(LDC_LLVMPre28) -+ llvm_memcpy(dst, src, dstlen, 0); -+ else -+ llvm_memcpy(dst, src, dstlen, 1, false); -+ } - else - throw new Exception("overlapping array copy"); - } -Index: tango/core/rt/compiler/ldc/rt/eh.d -=================================================================== ---- tango/core/rt/compiler/ldc/rt/eh.d (revision 5576) -+++ tango/core/rt/compiler/ldc/rt/eh.d (working copy) -@@ -1,38 +1,34 @@ - /** - * This module contains functions and structures required for -- * exception handling. -+ * dwarf exception handling with llvm - */ - module rt.eh; - --import ldc.cstdarg; --import rt.compiler.util.console; -+//debug = EH_personality; - --// debug = EH_personality; -- - // current EH implementation works on x86 - // if it has a working unwind runtime - version(X86) { - version(linux) version=X86_UNWIND; - version(darwin) version=X86_UNWIND; - version(solaris) version=X86_UNWIND; -- version(freebsd) version=X86_UNWIND; - } - version(X86_64) { - version(linux) version=X86_UNWIND; - version(darwin) version=X86_UNWIND; - version(solaris) version=X86_UNWIND; -- version(freebsd) version=X86_UNWIND; - } - - //version = HP_LIBUNWIND; - - private extern(C) void abort(); - private extern(C) int printf(char*, ...); --private extern(C) int vprintf(char*, va_list va); -+//private extern(C) int vprintf(char*, va_list va); - - // D runtime functions - extern(C) { -- int _d_isbaseof(ClassInfo oc, ClassInfo c); -+// int _d_isbaseof(ClassInfo oc, ClassInfo c); -+ Object _d_dynamic_cast(Object o, ClassInfo c); - } - - // libunwind headers -@@ -74,16 +70,19 @@ - // interface to HP's libunwind from http://www.nongnu.org/libunwind/ - version(HP_LIBUNWIND) - { -+ // Haven't checked whether and how it has _Unwind_Get{Text,Data}RelBase -+ pragma (msg, "HP_LIBUNWIND interface is out of date and untested"); -+ - void __libunwind_Unwind_Resume(_Unwind_Exception *); - _Unwind_Reason_Code __libunwind_Unwind_RaiseException(_Unwind_Exception *); - ptrdiff_t __libunwind_Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr - context); -- ptrdiff_t __libunwind_Unwind_GetIP(_Unwind_Context_Ptr context); -+ size_t __libunwind_Unwind_GetIP(_Unwind_Context_Ptr context); - ptrdiff_t __libunwind_Unwind_SetIP(_Unwind_Context_Ptr context, - ptrdiff_t new_value); - ptrdiff_t __libunwind_Unwind_SetGR(_Unwind_Context_Ptr context, int index, - ptrdiff_t new_value); -- ptrdiff_t __libunwind_Unwind_GetRegionStart(_Unwind_Context_Ptr context); -+ size_t __libunwind_Unwind_GetRegionStart(_Unwind_Context_Ptr context); - - alias __libunwind_Unwind_Resume _Unwind_Resume; - alias __libunwind_Unwind_RaiseException _Unwind_RaiseException; -@@ -94,27 +93,30 @@ - alias __libunwind_Unwind_SetGR _Unwind_SetGR; - alias __libunwind_Unwind_GetRegionStart _Unwind_GetRegionStart; - } --else version(X86_UNWIND) -+else version(X86_UNWIND) - { - void _Unwind_Resume(_Unwind_Exception*); - _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*); - ptrdiff_t _Unwind_GetLanguageSpecificData(_Unwind_Context_Ptr context); -- ptrdiff_t _Unwind_GetIP(_Unwind_Context_Ptr context); -+ size_t _Unwind_GetIP(_Unwind_Context_Ptr context); - ptrdiff_t _Unwind_SetIP(_Unwind_Context_Ptr context, ptrdiff_t new_value); - ptrdiff_t _Unwind_SetGR(_Unwind_Context_Ptr context, int index, - ptrdiff_t new_value); -- ptrdiff_t _Unwind_GetRegionStart(_Unwind_Context_Ptr context); -+ size_t _Unwind_GetRegionStart(_Unwind_Context_Ptr context); -+ -+ size_t _Unwind_GetTextRelBase(_Unwind_Context_Ptr); -+ size_t _Unwind_GetDataRelBase(_Unwind_Context_Ptr); - } - else - { - // runtime calls these directly - void _Unwind_Resume(_Unwind_Exception*) - { -- console("_Unwind_Resume is not implemented on this platform.\n"); -+ printf("_Unwind_Resume is not implemented on this platform.\n"); - } - _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception*) - { -- console("_Unwind_RaiseException is not implemented on this platform.\n"); -+ printf("_Unwind_RaiseException is not implemented on this platform.\n"); - return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; - } - } -@@ -122,14 +124,161 @@ - } - - // error and exit --extern(C) private void fatalerror(char[] format) -+extern(C) private void fatalerror(char* format, ...) - { -- printf("Fatal error in EH code: %.*s\n", format.length, format.ptr); -+// va_list args; -+// va_start(args, format); -+ printf("Fatal error in EH code: "); -+// vprintf(format, args); -+ printf("\n"); - abort(); - } - - --// helpers for reading certain DWARF data -+// DWARF EH encoding enum -+// See e.g. http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/dwarfext.html -+private enum : ubyte { -+ DW_EH_PE_omit = 0xff, // value is not present -+ -+ // value format -+ DW_EH_PE_absptr = 0x00, // literal pointer -+ DW_EH_PE_uleb128 = 0x01, -+ DW_EH_PE_udata2 = 0x02, // unsigned 2-byte -+ DW_EH_PE_udata4 = 0x03, -+ DW_EH_PE_udata8 = 0x04, -+ DW_EH_PE_sleb128 = 0x09, -+ DW_EH_PE_sdata2 = 0x0a, -+ DW_EH_PE_sdata4 = 0x0b, -+ DW_EH_PE_sdata8 = 0x0c, -+ -+ // value meaning -+ DW_EH_PE_pcrel = 0x10, // relative to program counter -+ DW_EH_PE_textrel = 0x20, // relative to .text -+ DW_EH_PE_datarel = 0x30, // relative to .got or .eh_frame_hdr -+ DW_EH_PE_funcrel = 0x40, // relative to beginning of function -+ DW_EH_PE_aligned = 0x50, // is an aligned void* -+ -+ // value is a pointer to the actual value -+ // this is a mask on top of one of the above -+ DW_EH_PE_indirect = 0x80 -+} -+ -+// Helpers for reading DWARF data -+ -+// Given an encoding and a context, return the base to which the encoding is -+// relative -+private size_t base_of_encoded(_Unwind_Context_Ptr context, ubyte encoding) -+{ -+ if (encoding == DW_EH_PE_omit) -+ return 0; -+ -+ switch (encoding & 0x70) // ignore DW_EH_PE_indirect -+ { -+ case DW_EH_PE_absptr, DW_EH_PE_pcrel, DW_EH_PE_aligned: -+ return 0; -+ -+ case DW_EH_PE_textrel: return _Unwind_GetTextRelBase(context); -+ case DW_EH_PE_datarel: return _Unwind_GetDataRelBase(context); -+ case DW_EH_PE_funcrel: return _Unwind_GetRegionStart(context); -+ -+ default: fatalerror("Unrecognized base for DWARF value"); -+ } -+} -+ -+// Only defined for fixed-size encodings -+private size_t size_of_encoded(ubyte encoding) -+{ -+ if (encoding == DW_EH_PE_omit) -+ return 0; -+ -+ switch (encoding & 0x07) // ignore leb128 -+ { -+ case DW_EH_PE_absptr: return (void*).sizeof; -+ case DW_EH_PE_udata2: return 2; -+ case DW_EH_PE_udata4: return 4; -+ case DW_EH_PE_udata8: return 8; -+ -+ default: fatalerror("Unrecognized fixed-size DWARF value encoding"); -+ } -+} -+ -+// Actual value readers below: read a value from the given ubyte* into the -+// output parameter and return the pointer incremented past the value. -+ -+// Like read_encoded_with_base but gets the base from the given context -+private ubyte* read_encoded(_Unwind_Context_Ptr context, ubyte encoding, ubyte* p, out size_t val) -+{ -+ return read_encoded_with_base(encoding, base_of_encoded(context, encoding), p, val); -+} -+ -+private ubyte* read_encoded_with_base(ubyte encoding, size_t base, ubyte* p, out size_t val) -+{ -+ if (encoding == DW_EH_PE_aligned) -+ { -+ auto a = cast(size_t)p; -+ a = (a + (void*).sizeof - 1) & -(void*).sizeof; -+ val = *cast(size_t*)a; -+ return cast(ubyte*)(a + (void*).sizeof); -+ } -+ -+ union U -+ { -+ size_t ptr; -+ ushort udata2; -+ uint udata4; -+ ulong udata8; -+ short sdata2; -+ int sdata4; -+ long sdata8; -+ } -+ -+ auto u = cast(U*)p; -+ -+ size_t result; -+ -+ switch (encoding & 0x0f) -+ { -+ case DW_EH_PE_absptr: -+ result = u.ptr; -+ p += (void*).sizeof; -+ break; -+ -+ case DW_EH_PE_uleb128: -+ { -+ p = get_uleb128(p, result); -+ break; -+ } -+ case DW_EH_PE_sleb128: -+ { -+ ptrdiff_t sleb128; -+ p = get_sleb128(p, sleb128); -+ result = cast(size_t)sleb128; -+ break; -+ } -+ -+ case DW_EH_PE_udata2: result = cast(size_t)u.udata2; p += 2; break; -+ case DW_EH_PE_udata4: result = cast(size_t)u.udata4; p += 4; break; -+ case DW_EH_PE_udata8: result = cast(size_t)u.udata8; p += 8; break; -+ case DW_EH_PE_sdata2: result = cast(size_t)u.sdata2; p += 2; break; -+ case DW_EH_PE_sdata4: result = cast(size_t)u.sdata4; p += 4; break; -+ case DW_EH_PE_sdata8: result = cast(size_t)u.sdata8; p += 8; break; -+ -+ default: fatalerror("Unrecognized DWARF value encoding format"); -+ } -+ if (result) -+ { -+ if ((encoding & 0x70) == DW_EH_PE_pcrel) -+ result += cast(size_t)u; -+ else -+ result += base; -+ -+ if (encoding & DW_EH_PE_indirect) -+ result = *cast(size_t*)result; -+ } -+ val = result; -+ return p; -+} -+ - private ubyte* get_uleb128(ubyte* addr, ref size_t res) - { - res = 0; -@@ -137,7 +286,7 @@ - - // read as long as high bit is set - while(*addr & 0x80) { -- res |= (*addr & 0x7f) << bitsize; -+ res |= (*addr & 0x7fU) << bitsize; - bitsize += 7; - addr += 1; - if(bitsize >= size_t.sizeof*8) -@@ -153,12 +302,12 @@ - - private ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res) - { -- res = 0; -+ size_t tres = 0; - size_t bitsize = 0; - - // read as long as high bit is set - while(*addr & 0x80) { -- res |= (*addr & 0x7f) << bitsize; -+ tres |= (*addr & 0x7fU) << bitsize; - bitsize += 7; - addr += 1; - if(bitsize >= size_t.sizeof*8) -@@ -167,12 +316,14 @@ - // read last - if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize) - fatalerror("tried to read sleb128 that exceeded size of size_t"); -- res |= (*addr) << bitsize; -+ tres |= (*addr) << bitsize; - - // take care of sign -- if(bitsize < size_t.sizeof*8 && ((*addr) & 0x40)) -- res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1); -+ if(bitsize < size_t.sizeof*8 && (*addr & 0x40U) != 0) -+ tres |= cast(size_t)(-1) ^ ((1 << (bitsize+7)) - 1); - -+ res = cast(ptrdiff_t)tres; -+ - return addr + 1; - } - -@@ -190,8 +341,7 @@ - - // the 8-byte string identifying the type of exception - // the first 4 are for vendor, the second 4 for language --//TODO: This may be the wrong way around --const char[8] _d_exception_class = "LLDCD1\0\0"; -+const char[8] _d_exception_class = "LDC_D_10"; - - - // -@@ -201,118 +351,174 @@ - version(X86_UNWIND) - { - -+// Various stuff we need -+struct Region -+{ -+ ubyte* callsite_table; -+ ubyte* action_table; -+ -+ // Note: classinfo_table points past the end of the table -+ ubyte* classinfo_table; -+ -+ size_t start; -+ size_t lpStart_base; // landing pad base -+ -+ ubyte ttypeEnc; -+ size_t ttype_base; // typeinfo base -+ -+ ubyte callSiteEnc; -+} -+ - // the personality routine gets called by the unwind handler and is responsible for - // reading the EH tables and deciding what to do - extern(C) _Unwind_Reason_Code _d_eh_personality(int ver, _Unwind_Action actions, ulong exception_class, _Unwind_Exception* exception_info, _Unwind_Context_Ptr context) - { -+ debug(EH_personality) printf("Entering personality routine, context=%p\n", context); - // check ver: the C++ Itanium ABI only allows ver == 1 - if(ver != 1) -+ { -+ debug(EH_personality) printf("eh version mismatch\n"); - return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; -+ } - - // check exceptionClass - //TODO: Treat foreign exceptions with more respect -- if((cast(char*)&exception_class)[0..8] != _d_exception_class) -+ auto wanted_ec = *cast(ulong*)_d_exception_class.ptr; -+ if(exception_class != wanted_ec) -+ { -+ debug(EH_personality) printf("exception class mismatch %p vs %p\n", exception_class, wanted_ec); - return _Unwind_Reason_Code.FATAL_PHASE1_ERROR; -+ } - - // find call site table, action table and classinfo table - // Note: callsite and action tables do not contain static-length - // data and will be parsed as needed -- // Note: classinfo_table points past the end of the table -- ubyte* callsite_table; -- ubyte* action_table; -- ClassInfo* classinfo_table; -- _d_getLanguageSpecificTables(context, callsite_table, action_table, classinfo_table); -- if (!callsite_table) -+ -+ Region region; -+ -+ _d_getLanguageSpecificTables(context, region); -+ -+ // workaround. this should not happen -+ if (!region.callsite_table) -+ { -+ debug(EH_personality) printf("callsite_table is null\n"); - return _Unwind_Reason_Code.CONTINUE_UNWIND; -+ } - -+ debug(EH_personality) printf("yay, checking\n"); -+ debug(EH_personality) printf("region.start = %p\n", region.start); -+ - /* - find landing pad and action table index belonging to ip by walking - the callsite_table - */ -- ubyte* callsite_walker = callsite_table; -+ ubyte* callsite_walker = region.callsite_table; -+ debug(EH_personality) printf("callsite table at: %p\n", region.callsite_table); -+ debug(EH_personality) printf("action table at: %p\n", region.action_table); -+ debug(EH_personality) printf("rtti table at %p\n", region.classinfo_table); - - // get the instruction pointer - // will be used to find the right entry in the callsite_table - // -1 because it will point past the last instruction -- ptrdiff_t ip = _Unwind_GetIP(context) - 1; -+ debug(EH_personality) printf("check1\n"); -+ size_t ip = _Unwind_GetIP(context) - 1; -+ debug(EH_personality) printf("check2\n"); - -- // address block_start is relative to -- ptrdiff_t region_start = _Unwind_GetRegionStart(context); -- - // table entries -- uint block_start_offset, block_size; -- ptrdiff_t landing_pad; -+ size_t landing_pad; - size_t action_offset; - - while(true) { - // if we've gone through the list and found nothing... -- if(callsite_walker >= action_table) -+ if(callsite_walker >= region.action_table) -+ { -+ debug(EH_personality) printf("found nothing\n"); - return _Unwind_Reason_Code.CONTINUE_UNWIND; -+ } - -- block_start_offset = *cast(uint*)callsite_walker; -- block_size = *(cast(uint*)callsite_walker + 1); -- landing_pad = *(cast(uint*)callsite_walker + 2); -- if(landing_pad) -- landing_pad += region_start; -- callsite_walker = get_uleb128(callsite_walker + 3*uint.sizeof, action_offset); -+ size_t block_start, block_size; - -- debug(EH_personality_verbose) printf("ip=%llx %d %d %llx\n", ip, block_start_offset, block_size, landing_pad); -+ callsite_walker = read_encoded(null, region.callSiteEnc, callsite_walker, block_start); -+ callsite_walker = read_encoded(null, region.callSiteEnc, callsite_walker, block_size); -+ callsite_walker = read_encoded(null, region.callSiteEnc, callsite_walker, landing_pad); -+ callsite_walker = get_uleb128(callsite_walker, action_offset); - -+ debug(EH_personality) printf("*block start offset = %p\n", block_start); -+ debug(EH_personality) printf(" block size = %p\n", block_size); -+ debug(EH_personality) printf(" landing pad = %p\n", landing_pad); -+ debug(EH_personality) printf(" ip=%p %p %p %p\n", ip, block_start, block_size, landing_pad); -+ - // since the list is sorted, as soon as we're past the ip - // there's no handler to be found -- if(ip < region_start + block_start_offset) -+ if(ip < region.start + block_start) -+ { -+ debug(EH_personality) printf("found nothing2\n"); - return _Unwind_Reason_Code.CONTINUE_UNWIND; -+ } - -+ if(landing_pad) -+ landing_pad += region.lpStart_base; -+ - // if we've found our block, exit -- if(ip < region_start + block_start_offset + block_size) -+ if(ip < region.start + block_start + block_size) - break; - } - -- debug(EH_personality) printf("Found correct landing pad and actionOffset %d\n", action_offset); -+ debug(EH_personality) printf("Found correct landing pad %p and actionOffset %p\n", landing_pad, action_offset); - - // now we need the exception's classinfo to find a handler - // the exception_info is actually a member of a larger _d_exception struct - // the runtime allocated. get that now -- _d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - _d_exception.unwind_info.offsetof); -+ _d_exception* exception_struct = cast(_d_exception*)(cast(ubyte*)exception_info - size_t.sizeof); //_d_exception.unwind_info.offsetof); - - // if there's no action offset and no landing pad, continue unwinding - if(!action_offset && !landing_pad) - return _Unwind_Reason_Code.CONTINUE_UNWIND; - - // if there's no action offset but a landing pad, this is a cleanup handler -- else if(!action_offset && landing_pad) -- return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context); -+ else if(!action_offset && landing_pad != 0) -+ { -+ debug(EH_personality) printf("installing finally context\n"); -+ return _d_eh_install_finally_context(actions, cast(ptrdiff_t)landing_pad, exception_struct, context); -+ } - - /* - walk action table chain, comparing classinfos using _d_isbaseof - */ -- ubyte* action_walker = action_table + action_offset - 1; -+ ubyte* action_walker = region.action_table + action_offset - 1; - -- ptrdiff_t ti_offset, next_action_offset; - while(true) { -+ ptrdiff_t ti_offset, next_action_offset; -+ - action_walker = get_sleb128(action_walker, ti_offset); - // it is intentional that we not modify action_walker here - // next_action_offset is from current action_walker position - get_sleb128(action_walker, next_action_offset); - - // negative are 'filters' which we don't use -- if(!(ti_offset >= 0)) -+ if(ti_offset < 0) - fatalerror("Filter actions are unsupported"); - - // zero means cleanup, which we require to be the last action - if(ti_offset == 0) { -- if(!(next_action_offset == 0)) -+ if(next_action_offset != 0) - fatalerror("Cleanup action must be last in chain"); -- return _d_eh_install_finally_context(actions, landing_pad, exception_struct, context); -+ return _d_eh_install_finally_context(actions, cast(ptrdiff_t)landing_pad, exception_struct, context); - } - - // get classinfo for action and check if the one in the - // exception structure is a base -- ClassInfo catch_ci = *(classinfo_table - ti_offset); -- debug(EH_personality) printf("Comparing catch %s to exception %s\n", catch_ci.name.ptr, exception_struct.exception_object.classinfo.name.ptr); -- if(_d_isbaseof(exception_struct.exception_object.classinfo, catch_ci)) -- return _d_eh_install_catch_context(actions, ti_offset, landing_pad, exception_struct, context); -+ size_t typeinfo; -+ auto filter = cast(size_t)ti_offset * size_of_encoded(region.ttypeEnc); -+ read_encoded_with_base(region.ttypeEnc, region.ttype_base, region.classinfo_table - filter, typeinfo); - -+ debug(EH_personality) -+ printf("classinfo at %zx (enc %zx (size %zx) base %zx ptr %zx)\n", typeinfo, region.ttypeEnc, size_of_encoded(region.ttypeEnc), region.ttype_base, region.classinfo_table - filter); -+ -+ auto catch_ci = *cast(ClassInfo*)&typeinfo; -+ if(_d_dynamic_cast(exception_struct.exception_object, catch_ci) !is null) -+ return _d_eh_install_catch_context(actions, ti_offset, cast(ptrdiff_t)landing_pad, exception_struct, context); -+ - // we've walked through all actions and found nothing... - if(next_action_offset == 0) - return _Unwind_Reason_Code.CONTINUE_UNWIND; -@@ -356,6 +562,7 @@ - } - - fatalerror("reached unreachable"); -+ - return _Unwind_Reason_Code.FATAL_PHASE2_ERROR; - } - -@@ -370,56 +577,78 @@ - _Unwind_SetGR(context, eh_exception_regno, cast(ptrdiff_t)exception_struct); - _Unwind_SetGR(context, eh_selector_regno, 0); - _Unwind_SetIP(context, landing_pad); -+ - return _Unwind_Reason_Code.INSTALL_CONTEXT; - } - --private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, ref ubyte* callsite, ref ubyte* action, ref ClassInfo* ci) -+private void _d_getLanguageSpecificTables(_Unwind_Context_Ptr context, out Region region) - { -- ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context); -+ auto data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context); -+ -+ // workaround. this should not be 0... - if (!data) - { -- callsite = null; -- action = null; -- ci = null; -- return; -+ //printf("language specific data is null\n"); -+ return; - } - -- //TODO: Do proper DWARF reading here -- if(*data++ != 0xff) -- fatalerror("DWARF header has unexpected format 1"); -+ region.start = _Unwind_GetRegionStart(context); - -- if(*data++ != 0x00) -- fatalerror("DWARF header has unexpected format 2"); -- size_t cioffset; -- data = get_uleb128(data, cioffset); -- ci = cast(ClassInfo*)(data + cioffset); -+ // Read the C++-style LSDA: this is implementation-defined by GCC but LLVM -+ // outputs the same kind of table - -- if(*data++ != 0x03) -- fatalerror("DWARF header has unexpected format 3"); -- size_t callsitelength; -- data = get_uleb128(data, callsitelength); -- action = data + callsitelength; -+ // Get @LPStart: landing pad offsets are relative to it -+ auto lpStartEnc = *data++; -+ if (lpStartEnc == DW_EH_PE_omit) -+ region.lpStart_base = region.start; -+ else -+ data = read_encoded(context, lpStartEnc, data, region.lpStart_base); - -- callsite = data; -+ // Get @TType: the offset to the handler and typeinfo -+ region.ttypeEnc = *data++; -+ if (region.ttypeEnc == DW_EH_PE_omit) -+ // Not sure about this one... -+ fatalerror("@TType must not be omitted from DWARF header"); -+ -+ size_t ciOffset; -+ data = get_uleb128(data, ciOffset); -+ region.classinfo_table = data + ciOffset; -+ -+ region.ttype_base = base_of_encoded(context, region.ttypeEnc); -+ -+ // Get encoding and length of the call site table, which precedes the action -+ // table. -+ region.callSiteEnc = *data++; -+ if (region.callSiteEnc == DW_EH_PE_omit) -+ fatalerror("Call site table encoding must not be omitted from DWARF header"); -+ -+ size_t callSiteLength; -+ region.callsite_table = get_uleb128(data, callSiteLength); -+ region.action_table = region.callsite_table + callSiteLength; - } - - } // end of x86 Linux specific implementation - -- --extern(C) void _d_throw_exception(Object e) -+// called to throw object -+extern(C) -+void _d_throw_exception(Object e) - { -+ //printf("throwing %p, rtti = %p\n", e, **cast(ClassRTTI***)e); - if (e !is null) - { - _d_exception* exc_struct = new _d_exception; - exc_struct.unwind_info.exception_class = *cast(ulong*)_d_exception_class.ptr; - exc_struct.exception_object = e; - _Unwind_Reason_Code ret = _Unwind_RaiseException(&exc_struct.unwind_info); -- console("_Unwind_RaiseException failed with reason code: ")(ret)("\n"); -+ printf("Error: returned %d from raise exception.\n", ret); -+ //console("_Unwind_RaiseException failed with reason code: ")(ret)("\n"); - } - abort(); - } - --extern(C) void _d_eh_resume_unwind(_d_exception* exception_struct) -+// called to resume unwinding -+extern(C) -+void _d_eh_resume_unwind(void* exception_struct) - { -- _Unwind_Resume(&exception_struct.unwind_info); -+ _Unwind_Resume(&(cast(_d_exception*)exception_struct).unwind_info); - } -Index: tango/core/vendor/ldc/intrinsics.di -=================================================================== ---- tango/core/vendor/ldc/intrinsics.di (revision 5576) -+++ tango/core/vendor/ldc/intrinsics.di (working copy) -@@ -101,8 +101,16 @@ - // Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do - // not return a value, and takes an extra alignment argument. - --pragma(intrinsic, "llvm.memcpy.i#") -- void llvm_memcpy(T)(void* dst, void* src, T len, uint alignment); -+version(LDC_LLVMPre28) -+{ -+ pragma(intrinsic, "llvm.memcpy.i#") -+ void llvm_memcpy(T)(void* dst, void* src, T len, uint alignment); -+} -+else -+{ -+ pragma(intrinsic, "llvm.memcpy.p0i8.p0i8.i#") -+ void llvm_memcpy(T)(void* dst, void* src, T len, uint alignment, bool volatile_); -+} - - deprecated { - alias llvm_memcpy!(uint) llvm_memcpy_i32; -@@ -116,8 +124,16 @@ - // Note that, unlike the standard libc function, the llvm.memmove.* intrinsics - // do not return a value, and takes an extra alignment argument. - --pragma(intrinsic, "llvm.memmove.i#") -- void llvm_memmove(T)(void* dst, void* src, T len, uint alignment); -+version(LDC_LLVMPre28) -+{ -+ pragma(intrinsic, "llvm.memmove.i#") -+ void llvm_memmove(T)(void* dst, void* src, T len, uint alignment); -+} -+else -+{ -+ pragma(intrinsic, "llvm.memmove.p0i8.p0i8.i#") -+ void llvm_memmove(T)(void* dst, void* src, T len, uint alignment, bool volatile_); -+} - - deprecated { - alias llvm_memmove!(uint) llvm_memmove_i32; -@@ -130,8 +146,16 @@ - // Note that, unlike the standard libc function, the llvm.memset intrinsic does - // not return a value, and takes an extra alignment argument. - --pragma(intrinsic, "llvm.memset.i#") -- void llvm_memset(T)(void* dst, ubyte val, T len, uint alignment); -+version(LDC_LLVMPre28) -+{ -+ pragma(intrinsic, "llvm.memset.i#") -+ void llvm_memset(T)(void* dst, ubyte val, T len, uint alignment); -+} -+else -+{ -+ pragma(intrinsic, "llvm.memset.p0i8.i#") -+ void llvm_memset(T)(void* dst, ubyte val, T len, uint alignment, bool volatile_); -+} - - deprecated { - alias llvm_memset!(uint) llvm_memset_i32;