diff --git a/druntime.patch b/druntime.patch
index 7814ff6b..51b50e58 100644
--- a/druntime.patch
+++ b/druntime.patch
@@ -1,525 +1,525 @@
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/import/ldc/cstdarg.di ldc/druntime/import/ldc/cstdarg.di
---- v2.049/src/druntime/import/ldc/cstdarg.di 1970-01-01 03:00:00.000000000 +0300
-+++ ldc/druntime/import/ldc/cstdarg.di 2010-09-30 22:10:37.000000000 +0400
-@@ -0,0 +1,29 @@
-+/*
-+ * vararg support for extern(C) functions
-+ */
-+
-+module ldc.cstdarg;
-+
-+// Check for the right compiler
-+version(LDC)
-+{
-+ // OK
-+}
-+else
-+{
-+ static assert(false, "This module is only valid for LDC");
-+}
-+
-+alias void* va_list;
-+
-+pragma(va_start)
-+ void va_start(T)(va_list ap, ref T);
-+
-+pragma(va_arg)
-+ T va_arg(T)(va_list ap);
-+
-+pragma(va_end)
-+ void va_end(va_list args);
-+
-+pragma(va_copy)
-+ void va_copy(va_list dst, va_list src);
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/import/ldc/intrinsics.di ldc/druntime/import/ldc/intrinsics.di
---- v2.049/src/druntime/import/ldc/intrinsics.di 1970-01-01 03:00:00.000000000 +0300
-+++ ldc/druntime/import/ldc/intrinsics.di 2010-10-02 14:01:02.975890001 +0400
-@@ -0,0 +1,413 @@
-+/*
-+ * This module holds declarations to LLVM intrinsics.
-+ *
-+ * See the LLVM language reference for more information:
-+ *
-+ * - http://llvm.org/docs/LangRef.html#intrinsics
-+ *
-+ */
-+
-+module ldc.intrinsics;
-+
-+// Check for the right compiler
-+version(LDC)
-+{
-+ // OK
-+}
-+else
-+{
-+ static assert(false, "This module is only valid for LDC");
-+}
-+
-+//
-+// CODE GENERATOR INTRINSICS
-+//
-+
-+
-+// The 'llvm.returnaddress' intrinsic attempts to compute a target-specific
-+// value indicating the return address of the current function or one of its
-+// callers.
-+
-+pragma(intrinsic, "llvm.returnaddress")
-+ void* llvm_returnaddress(uint level);
-+
-+
-+// The 'llvm.frameaddress' intrinsic attempts to return the target-specific
-+// frame pointer value for the specified stack frame.
-+
-+pragma(intrinsic, "llvm.frameaddress")
-+ void* llvm_frameaddress(uint level);
-+
-+
-+// The 'llvm.stacksave' intrinsic is used to remember the current state of the
-+// function stack, for use with llvm.stackrestore. This is useful for
-+// implementing language features like scoped automatic variable sized arrays
-+// in C99.
-+
-+pragma(intrinsic, "llvm.stacksave")
-+ void* llvm_stacksave();
-+
-+
-+// The 'llvm.stackrestore' intrinsic is used to restore the state of the
-+// function stack to the state it was in when the corresponding llvm.stacksave
-+// intrinsic executed. This is useful for implementing language features like
-+// scoped automatic variable sized arrays in C99.
-+
-+pragma(intrinsic, "llvm.stackrestore")
-+ void llvm_stackrestore(void* ptr);
-+
-+
-+// The 'llvm.prefetch' intrinsic is a hint to the code generator to insert a
-+// prefetch instruction if supported; otherwise, it is a noop. Prefetches have
-+// no effect on the behavior of the program but can change its performance
-+// characteristics.
-+
-+pragma(intrinsic, "llvm.prefetch")
-+ void llvm_prefetch(void* ptr, uint rw, uint locality);
-+
-+
-+// The 'llvm.pcmarker' intrinsic is a method to export a Program Counter (PC)
-+// in a region of code to simulators and other tools. The method is target
-+// specific, but it is expected that the marker will use exported symbols to
-+// transmit the PC of the marker. The marker makes no guarantees that it will
-+// remain with any specific instruction after optimizations. It is possible
-+// that the presence of a marker will inhibit optimizations. The intended use
-+// is to be inserted after optimizations to allow correlations of simulation
-+// runs.
-+
-+pragma(intrinsic, "llvm.pcmarker")
-+ void llvm_pcmarker(uint id);
-+
-+
-+// The 'llvm.readcyclecounter' intrinsic provides access to the cycle counter
-+// register (or similar low latency, high accuracy clocks) on those targets that
-+// support it. On X86, it should map to RDTSC. On Alpha, it should map to RPCC.
-+// As the backing counters overflow quickly (on the order of 9 seconds on
-+// alpha), this should only be used for small timings.
-+
-+pragma(intrinsic, "llvm.readcyclecounter")
-+ ulong readcyclecounter();
-+
-+
-+
-+
-+//
-+// STANDARD C LIBRARY INTRINSICS
-+//
-+
-+
-+// The 'llvm.memcpy.*' intrinsics copy a block of memory from the source
-+// location to the destination location.
-+// 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);
-+
-+deprecated {
-+ alias llvm_memcpy!(uint) llvm_memcpy_i32;
-+ alias llvm_memcpy!(ulong) llvm_memcpy_i64;
-+}
-+
-+
-+// The 'llvm.memmove.*' intrinsics move a block of memory from the source
-+// location to the destination location. It is similar to the 'llvm.memcpy'
-+// intrinsic but allows the two memory locations to overlap.
-+// 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);
-+
-+deprecated {
-+ alias llvm_memmove!(uint) llvm_memmove_i32;
-+ alias llvm_memmove!(ulong) llvm_memmove_i64;
-+}
-+
-+
-+// The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte
-+// value.
-+// 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);
-+
-+deprecated {
-+ alias llvm_memset!(uint) llvm_memset_i32;
-+ alias llvm_memset!(ulong) llvm_memset_i64;
-+}
-+
-+
-+// The 'llvm.sqrt' intrinsics return the sqrt of the specified operand,
-+// returning the same value as the libm 'sqrt' functions would. Unlike sqrt in
-+// libm, however, llvm.sqrt has undefined behavior for negative numbers other
-+// than -0.0 (which allows for better optimization, because there is no need to
-+// worry about errno being set). llvm.sqrt(-0.0) is defined to return -0.0 like
-+// IEEE sqrt.
-+
-+pragma(intrinsic, "llvm.sqrt.f#")
-+ T llvm_sqrt(T)(T val);
-+
-+deprecated {
-+ alias llvm_sqrt!(float) llvm_sqrt_f32;
-+ alias llvm_sqrt!(double) llvm_sqrt_f64;
-+ alias llvm_sqrt!(real) llvm_sqrt_f80; // may not actually be .f80
-+}
-+
-+
-+// The 'llvm.sin.*' intrinsics return the sine of the operand.
-+
-+pragma(intrinsic, "llvm.sin.f#")
-+ T llvm_sin(T)(T val);
-+
-+deprecated {
-+ alias llvm_sin!(float) llvm_sin_f32;
-+ alias llvm_sin!(double) llvm_sin_f64;
-+ alias llvm_sin!(real) llvm_sin_f80; // may not actually be .f80
-+}
-+
-+
-+// The 'llvm.cos.*' intrinsics return the cosine of the operand.
-+
-+pragma(intrinsic, "llvm.cos.f#")
-+ T llvm_cos(T)(T val);
-+
-+deprecated {
-+ alias llvm_cos!(float) llvm_cos_f32;
-+ alias llvm_cos!(double) llvm_cos_f64;
-+ alias llvm_cos!(real) llvm_cos_f80; // may not actually be .f80
-+}
-+
-+
-+// The 'llvm.powi.*' intrinsics return the first operand raised to the specified
-+// (positive or negative) power. The order of evaluation of multiplications is
-+// not defined. When a vector of floating point type is used, the second
-+// argument remains a scalar integer value.
-+
-+pragma(intrinsic, "llvm.powi.f#")
-+ T llvm_powi(T)(T val, int power);
-+
-+deprecated {
-+ alias llvm_powi!(float) llvm_powi_f32;
-+ alias llvm_powi!(double) llvm_powi_f64;
-+ alias llvm_powi!(real) llvm_powi_f80; // may not actually be .f80
-+}
-+
-+
-+// The 'llvm.pow.*' intrinsics return the first operand raised to the specified
-+// (positive or negative) power.
-+
-+pragma(intrinsic, "llvm.pow.f#")
-+ T llvm_pow(T)(T val, T power);
-+
-+deprecated {
-+ alias llvm_pow!(float) llvm_pow_f32;
-+ alias llvm_pow!(double) llvm_pow_f64;
-+ alias llvm_pow!(real) llvm_pow_f80; // may not actually be .f80
-+}
-+
-+
-+//
-+// BIT MANIPULATION INTRINSICS
-+//
-+
-+// The 'llvm.bswap' family of intrinsics is used to byte swap integer values
-+// with an even number of bytes (positive multiple of 16 bits). These are
-+// useful for performing operations on data that is not in the target's native
-+// byte order.
-+
-+pragma(intrinsic, "llvm.bswap.i#.i#")
-+ T llvm_bswap(T)(T val);
-+
-+deprecated {
-+ alias llvm_bswap!(ushort) llvm_bswap_i16;
-+ alias llvm_bswap!(uint) llvm_bswap_i32;
-+ alias llvm_bswap!(ulong) llvm_bswap_i64;
-+}
-+
-+
-+// The 'llvm.ctpop' family of intrinsics counts the number of bits set in a
-+// value.
-+
-+pragma(intrinsic, "llvm.ctpop.i#")
-+ T llvm_ctpop(T)(T src);
-+
-+deprecated {
-+ alias llvm_ctpop!(ubyte) llvm_ctpop_i8;
-+ alias llvm_ctpop!(ushort) llvm_ctpop_i16;
-+ alias llvm_ctpop!(uint) llvm_ctpop_i32;
-+ alias llvm_ctpop!(ulong) llvm_ctpop_i64;
-+}
-+
-+
-+// The 'llvm.ctlz' family of intrinsic functions counts the number of leading
-+// zeros in a variable.
-+
-+pragma(intrinsic, "llvm.ctlz.i#")
-+ T llvm_ctlz(T)(T src);
-+
-+deprecated {
-+ alias llvm_ctlz!(ubyte) llvm_ctlz_i8;
-+ alias llvm_ctlz!(ushort) llvm_ctlz_i16;
-+ alias llvm_ctlz!(uint) llvm_ctlz_i32;
-+ alias llvm_ctlz!(ulong) llvm_ctlz_i64;
-+}
-+
-+
-+// The 'llvm.cttz' family of intrinsic functions counts the number of trailing
-+// zeros.
-+
-+pragma(intrinsic, "llvm.cttz.i#")
-+ T llvm_cttz(T)(T src);
-+
-+deprecated {
-+ alias llvm_cttz!(ubyte) llvm_cttz_i8;
-+ alias llvm_cttz!(ushort) llvm_cttz_i16;
-+ alias llvm_cttz!(uint) llvm_cttz_i32;
-+ alias llvm_cttz!(ulong) llvm_cttz_i64;
-+}
-+
-+
-+// The 'llvm.part.select' family of intrinsic functions selects a range of bits
-+// from an integer value and returns them in the same bit width as the original
-+// value.
-+
-+pragma(intrinsic, "llvm.part.select.i#")
-+ T llvm_part_select(T)(T val, uint loBit, uint hiBit);
-+
-+deprecated {
-+ alias llvm_part_select!(ubyte) llvm_part_select_i;
-+ alias llvm_part_select!(ushort) llvm_part_select_i;
-+ alias llvm_part_select!(uint) llvm_part_select_i;
-+ alias llvm_part_select!(ulong) llvm_part_select_i;
-+}
-+
-+
-+// The 'llvm.part.set' family of intrinsic functions replaces a range of bits
-+// in an integer value with another integer value. It returns the integer with
-+// the replaced bits.
-+
-+// TODO
-+// declare i17 @llvm.part.set.i17.i9 (i17 %val, i9 %repl, i32 %lo, i32 %hi)
-+// declare i29 @llvm.part.set.i29.i9 (i29 %val, i9 %repl, i32 %lo, i32 %hi)
-+
-+
-+
-+
-+//
-+// ATOMIC OPERATIONS AND SYNCHRONIZATION INTRINSICS
-+//
-+
-+// The llvm.memory.barrier intrinsic guarantees ordering between specific
-+// pairs of memory access types.
-+
-+pragma(intrinsic, "llvm.memory.barrier")
-+ void llvm_memory_barrier(bool ll, bool ls, bool sl, bool ss, bool device);
-+
-+// This loads a value in memory and compares it to a given value. If they are
-+// equal, it stores a new value into the memory.
-+
-+pragma(intrinsic, "llvm.atomic.cmp.swap.i#.p0i#")
-+ T llvm_atomic_cmp_swap(T)(shared T* ptr, T cmp, T val);
-+
-+// This intrinsic loads the value stored in memory at ptr and yields the value
-+// from memory. It then stores the value in val in the memory at ptr.
-+
-+pragma(intrinsic, "llvm.atomic.swap.i#.p0i#")
-+ T llvm_atomic_swap(T)(T* ptr, T val);
-+
-+// This intrinsic adds delta to the value stored in memory at ptr. It yields
-+// the original value at ptr.
-+
-+pragma(intrinsic, "llvm.atomic.load.add.i#.p0i#")
-+ T llvm_atomic_load_add(T)(shared const T* ptr, T val);
-+
-+// This intrinsic subtracts delta to the value stored in memory at ptr. It
-+// yields the original value at ptr.
-+
-+pragma(intrinsic, "llvm.atomic.load.sub.i#.p0i#")
-+ T llvm_atomic_load_sub(T)(T* ptr, T val);
-+
-+// These intrinsics bitwise the operation (and, nand, or, xor) delta to the
-+// value stored in memory at ptr. It yields the original value at ptr.
-+
-+pragma(intrinsic, "llvm.atomic.load.and.i#.p0i#")
-+ T llvm_atomic_load_and(T)(T* ptr, T val);
-+
-+pragma(intrinsic, "llvm.atomic.load.nand.i#.p0i#")
-+ T llvm_atomic_load_nand(T)(T* ptr, T val);
-+
-+pragma(intrinsic, "llvm.atomic.load.or.i#.p0i#")
-+ T llvm_atomic_load_or(T)(T* ptr, T val);
-+
-+pragma(intrinsic, "llvm.atomic.load.xor.i#.p0i#")
-+ T llvm_atomic_load_xor(T)(T* ptr, T val);
-+
-+// These intrinsics takes the signed or unsigned minimum or maximum of delta
-+// and the value stored in memory at ptr. It yields the original value at ptr.
-+
-+pragma(intrinsic, "llvm.atomic.load.max.i#.p0i#")
-+ T llvm_atomic_load_max(T)(T* ptr, T val);
-+
-+pragma(intrinsic, "llvm.atomic.load.min.i#.p0i#")
-+ T llvm_atomic_load_min(T)(T* ptr, T val);
-+
-+pragma(intrinsic, "llvm.atomic.load.umax.i#.p0i#")
-+ T llvm_atomic_load_umax(T)(T* ptr, T val);
-+
-+pragma(intrinsic, "llvm.atomic.load.umin.i#.p0i#")
-+ T llvm_atomic_load_umin(T)(T* ptr, T val);
-+
-+
-+//
-+// ARITHMETIC-WITH-OVERFLOW INTRINSICS
-+//
-+
-+struct OverflowRet(T) {
-+ static assert(is(T : int), T.stringof ~ " is not an integer type!");
-+ T result;
-+ bool overflow;
-+}
-+
-+// Signed and unsigned addition
-+pragma(intrinsic, "llvm.sadd.with.overflow.i#")
-+ OverflowRet!(T) llvm_sadd_with_overflow(T)(T lhs, T rhs);
-+
-+pragma(intrinsic, "llvm.uadd.with.overflow.i#")
-+ OverflowRet!(T) llvm_uadd_with_overflow(T)(T lhs, T rhs);
-+
-+
-+// Signed and unsigned subtraction
-+pragma(intrinsic, "llvm.ssub.with.overflow.i#")
-+ OverflowRet!(T) llvm_ssub_with_overflow(T)(T lhs, T rhs);
-+
-+pragma(intrinsic, "llvm.usub.with.overflow.i#")
-+ OverflowRet!(T) llvm_usub_with_overflow(T)(T lhs, T rhs);
-+
-+
-+// Signed and unsigned multiplication
-+pragma(intrinsic, "llvm.smul.with.overflow.i#")
-+ OverflowRet!(T) llvm_smul_with_overflow(T)(T lhs, T rhs);
-+
-+/* Note: LLVM documentations says:
-+ * Warning: 'llvm.umul.with.overflow' is badly broken.
-+ * It is actively being fixed, but it should not currently be used!
-+ *
-+ * See: http://llvm.org/docs/LangRef.html#int_umul_overflow
-+ */
-+//pragma(intrinsic, "llvm.umul.with.overflow.i#")
-+// OverflowRet!(T) llvm_umul_with_overflow(T)(T lhs, T rhs);
-+
-+
-+//
-+// GENERAL INTRINSICS
-+//
-+
-+
-+// This intrinsics is lowered to the target dependent trap instruction. If the
-+// target does not have a trap instruction, this intrinsic will be lowered to
-+// the call of the abort() function.
-+
-+pragma(intrinsic, "llvm.trap")
-+ void llvm_trap();
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/import/ldc/llvmasm.di ldc/druntime/import/ldc/llvmasm.di
---- v2.049/src/druntime/import/ldc/llvmasm.di 1970-01-01 03:00:00.000000000 +0300
-+++ ldc/druntime/import/ldc/llvmasm.di 2010-09-30 22:10:37.000000000 +0400
-@@ -0,0 +1,17 @@
-+module ldc.llvmasm;
-+
-+struct __asmtuple_t(T...)
-+{
-+ T v;
-+}
-+
-+pragma(llvm_inline_asm)
-+{
-+ void __asm( )(char[] asmcode, char[] constraints, ...);
-+ T __asm(T)(char[] asmcode, char[] constraints, ...);
-+
-+ template __asmtuple(T...)
-+ {
-+ __asmtuple_t!(T) __asmtuple(char[] asmcode, char[] constraints, ...);
-+ }
-+}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/import/ldc/vararg.d ldc/druntime/import/ldc/vararg.d
---- v2.049/src/druntime/import/ldc/vararg.d 1970-01-01 03:00:00.000000000 +0300
-+++ ldc/druntime/import/ldc/vararg.d 2010-09-30 22:10:37.000000000 +0400
-@@ -0,0 +1,43 @@
-+/*
-+ * This module holds the implementation of special vararg templates for D style var args.
-+ *
-+ * Provides the functions tango.core.Vararg expects to be present!
-+ */
-+
-+module ldc.Vararg;
-+
-+// Check for the right compiler
-+version(LDC)
-+{
-+ // OK
-+}
-+else
-+{
-+ static assert(false, "This module is only valid for LDC");
-+}
-+
-+alias void* va_list;
-+
-+void va_start(T) ( out va_list ap, inout T parmn )
-+{
-+ // not needed !
-+}
-+
-+T va_arg(T)(ref va_list vp)
-+{
-+ T* arg = cast(T*) vp;
-+ // ldc always aligns to size_t.sizeof in vararg lists
-+ vp = cast(va_list) ( cast(void*) vp + ( ( T.sizeof + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 ) ) );
-+ return *arg;
-+}
-+
-+void va_end( va_list ap )
-+{
-+ // not needed !
-+}
-+
-+void va_copy( out va_list dst, va_list src )
-+{
-+ // seems pretty useless !
-+ dst = src;
-+}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/import/object.di ldc/druntime/import/object.di
---- v2.049/src/druntime/import/object.di 2010-09-03 12:28:52.000000000 +0400
-+++ ldc/druntime/import/object.di 2010-10-05 12:47:24.873150000 +0400
-@@ -130,7 +130,7 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/import/ldc/cstdarg.di druntime/import/ldc/cstdarg.di
+--- druntime-old/import/ldc/cstdarg.di 1970-01-01 03:00:00.000000000 +0300
++++ druntime/import/ldc/cstdarg.di 2010-09-30 22:10:37.000000000 +0400
+@@ -0,0 +1,29 @@
++/*
++ * vararg support for extern(C) functions
++ */
++
++module ldc.cstdarg;
++
++// Check for the right compiler
++version(LDC)
++{
++ // OK
++}
++else
++{
++ static assert(false, "This module is only valid for LDC");
++}
++
++alias void* va_list;
++
++pragma(va_start)
++ void va_start(T)(va_list ap, ref T);
++
++pragma(va_arg)
++ T va_arg(T)(va_list ap);
++
++pragma(va_end)
++ void va_end(va_list args);
++
++pragma(va_copy)
++ void va_copy(va_list dst, va_list src);
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/import/ldc/intrinsics.di druntime/import/ldc/intrinsics.di
+--- druntime-old/import/ldc/intrinsics.di 1970-01-01 03:00:00.000000000 +0300
++++ druntime/import/ldc/intrinsics.di 2010-10-02 14:01:02.975890001 +0400
+@@ -0,0 +1,413 @@
++/*
++ * This module holds declarations to LLVM intrinsics.
++ *
++ * See the LLVM language reference for more information:
++ *
++ * - http://llvm.org/docs/LangRef.html#intrinsics
++ *
++ */
++
++module ldc.intrinsics;
++
++// Check for the right compiler
++version(LDC)
++{
++ // OK
++}
++else
++{
++ static assert(false, "This module is only valid for LDC");
++}
++
++//
++// CODE GENERATOR INTRINSICS
++//
++
++
++// The 'llvm.returnaddress' intrinsic attempts to compute a target-specific
++// value indicating the return address of the current function or one of its
++// callers.
++
++pragma(intrinsic, "llvm.returnaddress")
++ void* llvm_returnaddress(uint level);
++
++
++// The 'llvm.frameaddress' intrinsic attempts to return the target-specific
++// frame pointer value for the specified stack frame.
++
++pragma(intrinsic, "llvm.frameaddress")
++ void* llvm_frameaddress(uint level);
++
++
++// The 'llvm.stacksave' intrinsic is used to remember the current state of the
++// function stack, for use with llvm.stackrestore. This is useful for
++// implementing language features like scoped automatic variable sized arrays
++// in C99.
++
++pragma(intrinsic, "llvm.stacksave")
++ void* llvm_stacksave();
++
++
++// The 'llvm.stackrestore' intrinsic is used to restore the state of the
++// function stack to the state it was in when the corresponding llvm.stacksave
++// intrinsic executed. This is useful for implementing language features like
++// scoped automatic variable sized arrays in C99.
++
++pragma(intrinsic, "llvm.stackrestore")
++ void llvm_stackrestore(void* ptr);
++
++
++// The 'llvm.prefetch' intrinsic is a hint to the code generator to insert a
++// prefetch instruction if supported; otherwise, it is a noop. Prefetches have
++// no effect on the behavior of the program but can change its performance
++// characteristics.
++
++pragma(intrinsic, "llvm.prefetch")
++ void llvm_prefetch(void* ptr, uint rw, uint locality);
++
++
++// The 'llvm.pcmarker' intrinsic is a method to export a Program Counter (PC)
++// in a region of code to simulators and other tools. The method is target
++// specific, but it is expected that the marker will use exported symbols to
++// transmit the PC of the marker. The marker makes no guarantees that it will
++// remain with any specific instruction after optimizations. It is possible
++// that the presence of a marker will inhibit optimizations. The intended use
++// is to be inserted after optimizations to allow correlations of simulation
++// runs.
++
++pragma(intrinsic, "llvm.pcmarker")
++ void llvm_pcmarker(uint id);
++
++
++// The 'llvm.readcyclecounter' intrinsic provides access to the cycle counter
++// register (or similar low latency, high accuracy clocks) on those targets that
++// support it. On X86, it should map to RDTSC. On Alpha, it should map to RPCC.
++// As the backing counters overflow quickly (on the order of 9 seconds on
++// alpha), this should only be used for small timings.
++
++pragma(intrinsic, "llvm.readcyclecounter")
++ ulong readcyclecounter();
++
++
++
++
++//
++// STANDARD C LIBRARY INTRINSICS
++//
++
++
++// The 'llvm.memcpy.*' intrinsics copy a block of memory from the source
++// location to the destination location.
++// 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);
++
++deprecated {
++ alias llvm_memcpy!(uint) llvm_memcpy_i32;
++ alias llvm_memcpy!(ulong) llvm_memcpy_i64;
++}
++
++
++// The 'llvm.memmove.*' intrinsics move a block of memory from the source
++// location to the destination location. It is similar to the 'llvm.memcpy'
++// intrinsic but allows the two memory locations to overlap.
++// 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);
++
++deprecated {
++ alias llvm_memmove!(uint) llvm_memmove_i32;
++ alias llvm_memmove!(ulong) llvm_memmove_i64;
++}
++
++
++// The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte
++// value.
++// 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);
++
++deprecated {
++ alias llvm_memset!(uint) llvm_memset_i32;
++ alias llvm_memset!(ulong) llvm_memset_i64;
++}
++
++
++// The 'llvm.sqrt' intrinsics return the sqrt of the specified operand,
++// returning the same value as the libm 'sqrt' functions would. Unlike sqrt in
++// libm, however, llvm.sqrt has undefined behavior for negative numbers other
++// than -0.0 (which allows for better optimization, because there is no need to
++// worry about errno being set). llvm.sqrt(-0.0) is defined to return -0.0 like
++// IEEE sqrt.
++
++pragma(intrinsic, "llvm.sqrt.f#")
++ T llvm_sqrt(T)(T val);
++
++deprecated {
++ alias llvm_sqrt!(float) llvm_sqrt_f32;
++ alias llvm_sqrt!(double) llvm_sqrt_f64;
++ alias llvm_sqrt!(real) llvm_sqrt_f80; // may not actually be .f80
++}
++
++
++// The 'llvm.sin.*' intrinsics return the sine of the operand.
++
++pragma(intrinsic, "llvm.sin.f#")
++ T llvm_sin(T)(T val);
++
++deprecated {
++ alias llvm_sin!(float) llvm_sin_f32;
++ alias llvm_sin!(double) llvm_sin_f64;
++ alias llvm_sin!(real) llvm_sin_f80; // may not actually be .f80
++}
++
++
++// The 'llvm.cos.*' intrinsics return the cosine of the operand.
++
++pragma(intrinsic, "llvm.cos.f#")
++ T llvm_cos(T)(T val);
++
++deprecated {
++ alias llvm_cos!(float) llvm_cos_f32;
++ alias llvm_cos!(double) llvm_cos_f64;
++ alias llvm_cos!(real) llvm_cos_f80; // may not actually be .f80
++}
++
++
++// The 'llvm.powi.*' intrinsics return the first operand raised to the specified
++// (positive or negative) power. The order of evaluation of multiplications is
++// not defined. When a vector of floating point type is used, the second
++// argument remains a scalar integer value.
++
++pragma(intrinsic, "llvm.powi.f#")
++ T llvm_powi(T)(T val, int power);
++
++deprecated {
++ alias llvm_powi!(float) llvm_powi_f32;
++ alias llvm_powi!(double) llvm_powi_f64;
++ alias llvm_powi!(real) llvm_powi_f80; // may not actually be .f80
++}
++
++
++// The 'llvm.pow.*' intrinsics return the first operand raised to the specified
++// (positive or negative) power.
++
++pragma(intrinsic, "llvm.pow.f#")
++ T llvm_pow(T)(T val, T power);
++
++deprecated {
++ alias llvm_pow!(float) llvm_pow_f32;
++ alias llvm_pow!(double) llvm_pow_f64;
++ alias llvm_pow!(real) llvm_pow_f80; // may not actually be .f80
++}
++
++
++//
++// BIT MANIPULATION INTRINSICS
++//
++
++// The 'llvm.bswap' family of intrinsics is used to byte swap integer values
++// with an even number of bytes (positive multiple of 16 bits). These are
++// useful for performing operations on data that is not in the target's native
++// byte order.
++
++pragma(intrinsic, "llvm.bswap.i#.i#")
++ T llvm_bswap(T)(T val);
++
++deprecated {
++ alias llvm_bswap!(ushort) llvm_bswap_i16;
++ alias llvm_bswap!(uint) llvm_bswap_i32;
++ alias llvm_bswap!(ulong) llvm_bswap_i64;
++}
++
++
++// The 'llvm.ctpop' family of intrinsics counts the number of bits set in a
++// value.
++
++pragma(intrinsic, "llvm.ctpop.i#")
++ T llvm_ctpop(T)(T src);
++
++deprecated {
++ alias llvm_ctpop!(ubyte) llvm_ctpop_i8;
++ alias llvm_ctpop!(ushort) llvm_ctpop_i16;
++ alias llvm_ctpop!(uint) llvm_ctpop_i32;
++ alias llvm_ctpop!(ulong) llvm_ctpop_i64;
++}
++
++
++// The 'llvm.ctlz' family of intrinsic functions counts the number of leading
++// zeros in a variable.
++
++pragma(intrinsic, "llvm.ctlz.i#")
++ T llvm_ctlz(T)(T src);
++
++deprecated {
++ alias llvm_ctlz!(ubyte) llvm_ctlz_i8;
++ alias llvm_ctlz!(ushort) llvm_ctlz_i16;
++ alias llvm_ctlz!(uint) llvm_ctlz_i32;
++ alias llvm_ctlz!(ulong) llvm_ctlz_i64;
++}
++
++
++// The 'llvm.cttz' family of intrinsic functions counts the number of trailing
++// zeros.
++
++pragma(intrinsic, "llvm.cttz.i#")
++ T llvm_cttz(T)(T src);
++
++deprecated {
++ alias llvm_cttz!(ubyte) llvm_cttz_i8;
++ alias llvm_cttz!(ushort) llvm_cttz_i16;
++ alias llvm_cttz!(uint) llvm_cttz_i32;
++ alias llvm_cttz!(ulong) llvm_cttz_i64;
++}
++
++
++// The 'llvm.part.select' family of intrinsic functions selects a range of bits
++// from an integer value and returns them in the same bit width as the original
++// value.
++
++pragma(intrinsic, "llvm.part.select.i#")
++ T llvm_part_select(T)(T val, uint loBit, uint hiBit);
++
++deprecated {
++ alias llvm_part_select!(ubyte) llvm_part_select_i;
++ alias llvm_part_select!(ushort) llvm_part_select_i;
++ alias llvm_part_select!(uint) llvm_part_select_i;
++ alias llvm_part_select!(ulong) llvm_part_select_i;
++}
++
++
++// The 'llvm.part.set' family of intrinsic functions replaces a range of bits
++// in an integer value with another integer value. It returns the integer with
++// the replaced bits.
++
++// TODO
++// declare i17 @llvm.part.set.i17.i9 (i17 %val, i9 %repl, i32 %lo, i32 %hi)
++// declare i29 @llvm.part.set.i29.i9 (i29 %val, i9 %repl, i32 %lo, i32 %hi)
++
++
++
++
++//
++// ATOMIC OPERATIONS AND SYNCHRONIZATION INTRINSICS
++//
++
++// The llvm.memory.barrier intrinsic guarantees ordering between specific
++// pairs of memory access types.
++
++pragma(intrinsic, "llvm.memory.barrier")
++ void llvm_memory_barrier(bool ll, bool ls, bool sl, bool ss, bool device);
++
++// This loads a value in memory and compares it to a given value. If they are
++// equal, it stores a new value into the memory.
++
++pragma(intrinsic, "llvm.atomic.cmp.swap.i#.p0i#")
++ T llvm_atomic_cmp_swap(T)(shared T* ptr, T cmp, T val);
++
++// This intrinsic loads the value stored in memory at ptr and yields the value
++// from memory. It then stores the value in val in the memory at ptr.
++
++pragma(intrinsic, "llvm.atomic.swap.i#.p0i#")
++ T llvm_atomic_swap(T)(T* ptr, T val);
++
++// This intrinsic adds delta to the value stored in memory at ptr. It yields
++// the original value at ptr.
++
++pragma(intrinsic, "llvm.atomic.load.add.i#.p0i#")
++ T llvm_atomic_load_add(T)(shared const T* ptr, T val);
++
++// This intrinsic subtracts delta to the value stored in memory at ptr. It
++// yields the original value at ptr.
++
++pragma(intrinsic, "llvm.atomic.load.sub.i#.p0i#")
++ T llvm_atomic_load_sub(T)(T* ptr, T val);
++
++// These intrinsics bitwise the operation (and, nand, or, xor) delta to the
++// value stored in memory at ptr. It yields the original value at ptr.
++
++pragma(intrinsic, "llvm.atomic.load.and.i#.p0i#")
++ T llvm_atomic_load_and(T)(T* ptr, T val);
++
++pragma(intrinsic, "llvm.atomic.load.nand.i#.p0i#")
++ T llvm_atomic_load_nand(T)(T* ptr, T val);
++
++pragma(intrinsic, "llvm.atomic.load.or.i#.p0i#")
++ T llvm_atomic_load_or(T)(T* ptr, T val);
++
++pragma(intrinsic, "llvm.atomic.load.xor.i#.p0i#")
++ T llvm_atomic_load_xor(T)(T* ptr, T val);
++
++// These intrinsics takes the signed or unsigned minimum or maximum of delta
++// and the value stored in memory at ptr. It yields the original value at ptr.
++
++pragma(intrinsic, "llvm.atomic.load.max.i#.p0i#")
++ T llvm_atomic_load_max(T)(T* ptr, T val);
++
++pragma(intrinsic, "llvm.atomic.load.min.i#.p0i#")
++ T llvm_atomic_load_min(T)(T* ptr, T val);
++
++pragma(intrinsic, "llvm.atomic.load.umax.i#.p0i#")
++ T llvm_atomic_load_umax(T)(T* ptr, T val);
++
++pragma(intrinsic, "llvm.atomic.load.umin.i#.p0i#")
++ T llvm_atomic_load_umin(T)(T* ptr, T val);
++
++
++//
++// ARITHMETIC-WITH-OVERFLOW INTRINSICS
++//
++
++struct OverflowRet(T) {
++ static assert(is(T : int), T.stringof ~ " is not an integer type!");
++ T result;
++ bool overflow;
++}
++
++// Signed and unsigned addition
++pragma(intrinsic, "llvm.sadd.with.overflow.i#")
++ OverflowRet!(T) llvm_sadd_with_overflow(T)(T lhs, T rhs);
++
++pragma(intrinsic, "llvm.uadd.with.overflow.i#")
++ OverflowRet!(T) llvm_uadd_with_overflow(T)(T lhs, T rhs);
++
++
++// Signed and unsigned subtraction
++pragma(intrinsic, "llvm.ssub.with.overflow.i#")
++ OverflowRet!(T) llvm_ssub_with_overflow(T)(T lhs, T rhs);
++
++pragma(intrinsic, "llvm.usub.with.overflow.i#")
++ OverflowRet!(T) llvm_usub_with_overflow(T)(T lhs, T rhs);
++
++
++// Signed and unsigned multiplication
++pragma(intrinsic, "llvm.smul.with.overflow.i#")
++ OverflowRet!(T) llvm_smul_with_overflow(T)(T lhs, T rhs);
++
++/* Note: LLVM documentations says:
++ * Warning: 'llvm.umul.with.overflow' is badly broken.
++ * It is actively being fixed, but it should not currently be used!
++ *
++ * See: http://llvm.org/docs/LangRef.html#int_umul_overflow
++ */
++//pragma(intrinsic, "llvm.umul.with.overflow.i#")
++// OverflowRet!(T) llvm_umul_with_overflow(T)(T lhs, T rhs);
++
++
++//
++// GENERAL INTRINSICS
++//
++
++
++// This intrinsics is lowered to the target dependent trap instruction. If the
++// target does not have a trap instruction, this intrinsic will be lowered to
++// the call of the abort() function.
++
++pragma(intrinsic, "llvm.trap")
++ void llvm_trap();
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/import/ldc/llvmasm.di druntime/import/ldc/llvmasm.di
+--- druntime-old/import/ldc/llvmasm.di 1970-01-01 03:00:00.000000000 +0300
++++ druntime/import/ldc/llvmasm.di 2010-09-30 22:10:37.000000000 +0400
+@@ -0,0 +1,17 @@
++module ldc.llvmasm;
++
++struct __asmtuple_t(T...)
++{
++ T v;
++}
++
++pragma(llvm_inline_asm)
++{
++ void __asm( )(char[] asmcode, char[] constraints, ...);
++ T __asm(T)(char[] asmcode, char[] constraints, ...);
++
++ template __asmtuple(T...)
++ {
++ __asmtuple_t!(T) __asmtuple(char[] asmcode, char[] constraints, ...);
++ }
++}
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/import/ldc/vararg.d druntime/import/ldc/vararg.d
+--- druntime-old/import/ldc/vararg.d 1970-01-01 03:00:00.000000000 +0300
++++ druntime/import/ldc/vararg.d 2010-09-30 22:10:37.000000000 +0400
+@@ -0,0 +1,43 @@
++/*
++ * This module holds the implementation of special vararg templates for D style var args.
++ *
++ * Provides the functions tango.core.Vararg expects to be present!
++ */
++
++module ldc.Vararg;
++
++// Check for the right compiler
++version(LDC)
++{
++ // OK
++}
++else
++{
++ static assert(false, "This module is only valid for LDC");
++}
++
++alias void* va_list;
++
++void va_start(T) ( out va_list ap, inout T parmn )
++{
++ // not needed !
++}
++
++T va_arg(T)(ref va_list vp)
++{
++ T* arg = cast(T*) vp;
++ // ldc always aligns to size_t.sizeof in vararg lists
++ vp = cast(va_list) ( cast(void*) vp + ( ( T.sizeof + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 ) ) );
++ return *arg;
++}
++
++void va_end( va_list ap )
++{
++ // not needed !
++}
++
++void va_copy( out va_list dst, va_list src )
++{
++ // seems pretty useless !
++ dst = src;
++}
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/import/object.di druntime/import/object.di
+--- druntime-old/import/object.di 2010-09-03 12:28:52.000000000 +0400
++++ druntime/import/object.di 2010-10-05 12:47:24.873150000 +0400
+@@ -130,7 +130,7 @@
Interface[] interfaces;
TypeInfo_Class base;
void* destructor;
@@ -528,7 +528,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
uint m_flags;
// 1: // is IUnknown or is derived from IUnknown
// 2: // has no possible pointers into GC memory
-@@ -140,7 +140,7 @@
+@@ -140,7 +140,7 @@
// 32: // has typeinfo member
void* deallocator;
OffsetTypeInfo[] m_offTi;
@@ -537,7 +537,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
const(MemberInfo[]) function(string) xgetMembers;
static TypeInfo_Class find(in char[] classname);
-@@ -179,7 +179,7 @@
+@@ -179,7 +179,7 @@
class TypeInfo_Const : TypeInfo
{
@@ -546,7 +546,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
class TypeInfo_Invariant : TypeInfo_Const
-@@ -288,7 +288,6 @@
+@@ -288,7 +288,6 @@
interface TraceInfo
{
int opApply(scope int delegate(ref char[]));
@@ -554,10 +554,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
string msg;
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/import/std/intrinsic.di ldc/druntime/import/std/intrinsic.di
---- v2.049/src/druntime/import/std/intrinsic.di 2010-08-05 05:39:08.000000000 +0400
-+++ ldc/druntime/import/std/intrinsic.di 1970-01-01 03:00:00.000000000 +0300
-@@ -1,176 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/import/std/intrinsic.di druntime/import/std/intrinsic.di
+--- druntime-old/import/std/intrinsic.di 2010-08-05 05:39:08.000000000 +0400
++++ druntime/import/std/intrinsic.di 1970-01-01 03:00:00.000000000 +0300
+@@ -1,176 +0,0 @@
-/**
- * These functions are built-in intrinsics to the compiler.
- *
@@ -734,10 +734,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- * ditto
- */
-nothrow uint outpl( uint port_address, uint value );
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/core/atomic.d ldc/druntime/src/core/atomic.d
---- v2.049/src/druntime/src/core/atomic.d 2010-09-03 12:28:52.000000000 +0400
-+++ ldc/druntime/src/core/atomic.d 2010-10-05 15:55:10.893150001 +0400
-@@ -89,6 +89,117 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/core/atomic.d druntime/src/core/atomic.d
+--- druntime-old/src/core/atomic.d 2010-09-03 12:28:52.000000000 +0400
++++ druntime/src/core/atomic.d 2010-10-05 15:55:10.893150001 +0400
+@@ -89,6 +89,117 @@
return false;
}
}
@@ -855,7 +855,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
else version( AsmX86_32 )
{
T atomicOp(string op, T, V1)( ref shared T val, V1 mod )
-@@ -396,6 +507,12 @@
+@@ -396,6 +507,12 @@
}
}
}
@@ -868,10 +868,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
else version( AsmX86_64 )
{
T atomicOp(string op, T, V1)( ref shared T val, V1 mod )
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/gc/gc.d ldc/druntime/src/gc/gc.d
---- v2.049/src/druntime/src/gc/gc.d 2010-08-05 05:39:08.000000000 +0400
-+++ ldc/druntime/src/gc/gc.d 2010-10-04 16:54:06.837685001 +0400
-@@ -100,7 +100,7 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/gc/gc.d druntime/src/gc/gc.d
+--- druntime-old/src/gc/gc.d 2010-08-05 05:39:08.000000000 +0400
++++ druntime/src/gc/gc.d 2010-10-04 16:54:06.837685001 +0400
+@@ -100,7 +100,7 @@
version (GCCLASS)
{ void* p;
ClassInfo ci = GC.classinfo;
@@ -880,10 +880,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
p = malloc(ci.init.length);
(cast(byte*)p)[0 .. ci.init.length] = ci.init[];
_gc = cast(GC)p;
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/gc/gcbits.d ldc/druntime/src/gc/gcbits.d
---- v2.049/src/druntime/src/gc/gcbits.d 2010-08-08 04:10:24.000000000 +0400
-+++ ldc/druntime/src/gc/gcbits.d 2010-10-01 20:49:51.268892001 +0400
-@@ -26,6 +26,10 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/gc/gcbits.d druntime/src/gc/gcbits.d
+--- druntime-old/src/gc/gcbits.d 2010-08-08 04:10:24.000000000 +0400
++++ druntime/src/gc/gcbits.d 2010-10-01 20:49:51.268892001 +0400
+@@ -26,6 +26,10 @@
{
version = bitops;
}
@@ -894,10 +894,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
else version (GNU)
{
// use the unoptimized version
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/gc/gcx.d ldc/druntime/src/gc/gcx.d
---- v2.049/src/druntime/src/gc/gcx.d 2010-08-27 01:23:26.000000000 +0400
-+++ ldc/druntime/src/gc/gcx.d 2010-10-07 22:27:41.879253001 +0400
-@@ -1464,7 +1464,8 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/gc/gcx.d druntime/src/gc/gcx.d
+--- druntime-old/src/gc/gcx.d 2010-08-27 01:23:26.000000000 +0400
++++ druntime/src/gc/gcx.d 2010-10-07 22:27:41.879253001 +0400
+@@ -1464,7 +1464,8 @@
void initialize()
@@ -907,7 +907,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
(cast(byte*)&this)[0 .. Gcx.sizeof] = 0;
stackBottom = cast(char*)&dummy;
-@@ -2200,7 +2201,7 @@
+@@ -2200,7 +2201,7 @@
if ((cast(size_t)p & ~(PAGESIZE-1)) == pcache)
continue;
@@ -916,7 +916,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
if (pool)
{
size_t offset = cast(size_t)(p - pool.baseAddr);
-@@ -2270,80 +2271,129 @@
+@@ -2270,80 +2271,129 @@
__builtin_unwind_init();
sp = & sp;
}
@@ -1114,7 +1114,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
return result;
}
-@@ -2357,7 +2407,7 @@
+@@ -2357,7 +2407,7 @@
Pool* pool;
debug(COLLECT_PRINTF) printf("Gcx.fullcollect()\n");
@@ -1123,10 +1123,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
thread_suspendAll();
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/object_.d ldc/druntime/src/object_.d
---- v2.049/src/druntime/src/object_.d 2010-09-03 12:28:52.000000000 +0400
-+++ ldc/druntime/src/object_.d 2010-10-05 14:50:34.733150002 +0400
-@@ -1073,7 +1073,7 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/object_.d druntime/src/object_.d
+--- druntime-old/src/object_.d 2010-09-03 12:28:52.000000000 +0400
++++ druntime/src/object_.d 2010-10-05 14:50:34.733150002 +0400
+@@ -1073,7 +1073,7 @@
abstract class MemberInfo
{
@@ -1135,7 +1135,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
class MemberInfo_field : MemberInfo
-@@ -1663,7 +1663,6 @@
+@@ -1663,7 +1663,6 @@
{
int len = 0;
ModuleReference *mr;
@@ -1143,7 +1143,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
for (mr = _Dmodule_ref; mr; mr = mr.next)
len++;
_moduleinfo_array = new ModuleInfo*[len];
-@@ -1802,7 +1801,10 @@
+@@ -1802,7 +1801,10 @@
{
debug(PRINTF) printf("_moduleTlsCtor()\n");
@@ -1155,7 +1155,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
auto flags = cast(ubyte[])p[0 .. _moduleinfo_array.length];
flags[] = 0;
-@@ -2025,7 +2027,6 @@
+@@ -2025,7 +2027,6 @@
_d_monitor_create(h);
m = getMonitor(h);
}
@@ -1163,7 +1163,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
IMonitor i = m.impl;
if (i is null)
-@@ -2124,7 +2125,7 @@
+@@ -2124,7 +2125,7 @@
size_t _aaLen(void* p);
void* _aaGet(void** pp, TypeInfo keyti, size_t valuesize, ...);
void* _aaGetRvalue(void* p, TypeInfo keyti, size_t valuesize, ...);
@@ -1172,10 +1172,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
void _aaDel(void* p, TypeInfo keyti, ...);
void[] _aaValues(void* p, size_t keysize, size_t valuesize);
void[] _aaKeys(void* p, size_t keysize, size_t valuesize);
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/adi.d ldc/druntime/src/rt/adi.d
---- v2.049/src/druntime/src/rt/adi.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/adi.d 2010-10-07 14:32:52.911253001 +0400
-@@ -35,6 +35,14 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/adi.d druntime/src/rt/adi.d
+--- druntime-old/src/rt/adi.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/adi.d 2010-10-07 14:32:52.911253001 +0400
+@@ -35,6 +35,14 @@
extern (C) void gc_free( void* p );
}
@@ -1190,7 +1190,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
struct Array
{
-@@ -48,7 +56,7 @@
+@@ -48,7 +56,7 @@
* reversed.
*/
@@ -1199,7 +1199,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
if (a.length > 1)
{
-@@ -108,7 +116,7 @@
+@@ -108,7 +116,7 @@
hi = hi - 1 + (stridehi - stridelo);
}
}
@@ -1208,7 +1208,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
unittest
-@@ -143,7 +151,7 @@
+@@ -143,7 +151,7 @@
* reversed.
*/
@@ -1217,7 +1217,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
if (a.length > 1)
{
-@@ -201,7 +209,7 @@
+@@ -201,7 +209,7 @@
hi = hi - 1 + (stridehi - stridelo);
}
}
@@ -1226,7 +1226,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
unittest
-@@ -225,10 +233,10 @@
+@@ -225,10 +233,10 @@
* Support for array.reverse property.
*/
@@ -1239,7 +1239,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
body
{
-@@ -243,10 +251,10 @@
+@@ -243,10 +251,10 @@
tmp = buffer.ptr;
if (szelem > 16)
{
@@ -1253,7 +1253,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
for (; lo < hi; lo += szelem, hi -= szelem)
-@@ -267,7 +275,7 @@
+@@ -267,7 +275,7 @@
//gc_free(tmp);
}
}
@@ -1262,7 +1262,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
unittest
-@@ -311,7 +319,7 @@
+@@ -311,7 +319,7 @@
* Sort array of chars.
*/
@@ -1271,7 +1271,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
if (a.length > 1)
{
-@@ -326,14 +334,14 @@
+@@ -326,14 +334,14 @@
}
delete da;
}
@@ -1288,7 +1288,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
if (a.length > 1)
{
-@@ -348,7 +356,7 @@
+@@ -348,7 +356,7 @@
}
delete da;
}
@@ -1297,7 +1297,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
/***************************************
-@@ -358,7 +366,7 @@
+@@ -358,7 +366,7 @@
* 0 not equal
*/
@@ -1306,7 +1306,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
debug(adi) printf("_adEq(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
if (a1.length != a2.length)
-@@ -379,7 +387,7 @@
+@@ -379,7 +387,7 @@
return 1; // equal
}
@@ -1315,7 +1315,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
debug(adi) printf("_adEq2(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
if (a1.length != a2.length)
-@@ -405,7 +413,7 @@
+@@ -405,7 +413,7 @@
* Support for array compare test.
*/
@@ -1324,7 +1324,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
debug(adi) printf("adCmp()\n");
auto len = a1.length;
-@@ -435,7 +443,7 @@
+@@ -435,7 +443,7 @@
return (a1.length > a2.length) ? 1 : -1;
}
@@ -1333,7 +1333,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
debug(adi) printf("_adCmp2(a1.length = %d, a2.length = %d)\n", a1.length, a2.length);
return ti.compare(&a1, &a2);
-@@ -461,9 +469,9 @@
+@@ -461,9 +469,9 @@
* Support for array compare test.
*/
@@ -1345,7 +1345,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
asm
{ naked ;
-@@ -569,8 +577,8 @@
+@@ -569,8 +577,8 @@
ret ;
}
@@ -1356,169 +1356,169 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
int len;
int c;
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arrayInit.d ldc/druntime/src/rt/arrayInit.d
---- v2.049/src/druntime/src/rt/arrayInit.d 1970-01-01 03:00:00.000000000 +0300
-+++ ldc/druntime/src/rt/arrayInit.d 2010-10-03 20:41:52.223624001 +0400
-@@ -0,0 +1,155 @@
-+private import ldc.intrinsics;
-+
-+extern(C):
-+
-+int memcmp(void*,void*,size_t);
-+size_t strlen(char*);
-+
-+version(LLVM64)
-+alias llvm_memcpy_i64 llvm_memcpy;
-+else
-+alias llvm_memcpy_i32 llvm_memcpy;
-+
-+// per-element array init routines
-+
-+void _d_array_init_i16(ushort* a, size_t n, ushort v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_i32(uint* a, size_t n, uint v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_i64(ulong* a, size_t n, ulong v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_float(float* a, size_t n, float v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_double(double* a, size_t n, double v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_real(real* a, size_t n, real v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_cfloat(cfloat* a, size_t n, cfloat v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_cdouble(cdouble* a, size_t n, cdouble v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_creal(creal* a, size_t n, creal v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_pointer(void** a, size_t n, void* v)
-+{
-+ auto p = a;
-+ auto end = a+n;
-+ while (p !is end)
-+ *p++ = v;
-+}
-+
-+void _d_array_init_mem(void* a, size_t na, void* v, size_t nv)
-+{
-+ auto p = a;
-+ auto end = a + na*nv;
-+ while (p !is end) {
-+ llvm_memcpy(p,v,nv,0);
-+ p += nv;
-+ }
-+}
-+
-+/*
-+void _d_array_init(TypeInfo ti, void* a)
-+{
-+ auto initializer = ti.next.init();
-+ auto isize = initializer.length;
-+ auto q = initializer.ptr;
-+
-+ if (isize == 1)
-+ memset(p, *cast(ubyte*)q, size);
-+ else if (isize == int.sizeof)
-+ {
-+ int init = *cast(int*)q;
-+ size /= int.sizeof;
-+ for (size_t u = 0; u < size; u++)
-+ {
-+ (cast(int*)p)[u] = init;
-+ }
-+ }
-+ else
-+ {
-+ for (size_t u = 0; u < size; u += isize)
-+ {
-+ memcpy(p + u, q, isize);
-+ }
-+ }
-+}*/
-+
-+// for array cast
-+size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
-+{
-+ if (newelemsz == 1) {
-+ return len*elemsz;
-+ }
-+ else if ((len*elemsz) % newelemsz) {
-+ throw new Exception("Bad array cast");
-+ }
-+ return (len*elemsz)/newelemsz;
-+}
-+
-+// slice copy when assertions are enabled
-+void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen)
-+{
-+ assert(dst);
-+ assert(src);
-+ 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);
-+ else
-+ throw new Exception("overlapping array copy");
-+}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arrayassign.d ldc/druntime/src/rt/arrayassign.d
---- v2.049/src/druntime/src/rt/arrayassign.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/arrayassign.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,186 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arrayInit.d druntime/src/rt/arrayInit.d
+--- druntime-old/src/rt/arrayInit.d 1970-01-01 03:00:00.000000000 +0300
++++ druntime/src/rt/arrayInit.d 2010-10-03 20:41:52.223624001 +0400
+@@ -0,0 +1,155 @@
++private import ldc.intrinsics;
++
++extern(C):
++
++int memcmp(void*,void*,size_t);
++size_t strlen(char*);
++
++version(LLVM64)
++alias llvm_memcpy_i64 llvm_memcpy;
++else
++alias llvm_memcpy_i32 llvm_memcpy;
++
++// per-element array init routines
++
++void _d_array_init_i16(ushort* a, size_t n, ushort v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_i32(uint* a, size_t n, uint v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_i64(ulong* a, size_t n, ulong v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_float(float* a, size_t n, float v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_double(double* a, size_t n, double v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_real(real* a, size_t n, real v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_cfloat(cfloat* a, size_t n, cfloat v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_cdouble(cdouble* a, size_t n, cdouble v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_creal(creal* a, size_t n, creal v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_pointer(void** a, size_t n, void* v)
++{
++ auto p = a;
++ auto end = a+n;
++ while (p !is end)
++ *p++ = v;
++}
++
++void _d_array_init_mem(void* a, size_t na, void* v, size_t nv)
++{
++ auto p = a;
++ auto end = a + na*nv;
++ while (p !is end) {
++ llvm_memcpy(p,v,nv,0);
++ p += nv;
++ }
++}
++
++/*
++void _d_array_init(TypeInfo ti, void* a)
++{
++ auto initializer = ti.next.init();
++ auto isize = initializer.length;
++ auto q = initializer.ptr;
++
++ if (isize == 1)
++ memset(p, *cast(ubyte*)q, size);
++ else if (isize == int.sizeof)
++ {
++ int init = *cast(int*)q;
++ size /= int.sizeof;
++ for (size_t u = 0; u < size; u++)
++ {
++ (cast(int*)p)[u] = init;
++ }
++ }
++ else
++ {
++ for (size_t u = 0; u < size; u += isize)
++ {
++ memcpy(p + u, q, isize);
++ }
++ }
++}*/
++
++// for array cast
++size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
++{
++ if (newelemsz == 1) {
++ return len*elemsz;
++ }
++ else if ((len*elemsz) % newelemsz) {
++ throw new Exception("Bad array cast");
++ }
++ return (len*elemsz)/newelemsz;
++}
++
++// slice copy when assertions are enabled
++void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen)
++{
++ assert(dst);
++ assert(src);
++ 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);
++ else
++ throw new Exception("overlapping array copy");
++}
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arrayassign.d druntime/src/rt/arrayassign.d
+--- druntime-old/src/rt/arrayassign.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/arrayassign.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,186 +0,0 @@
-/**
- * Implementation of array assignment support routines.
- *
@@ -1705,10 +1705,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- }
- return pstart;
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arraybyte.d ldc/druntime/src/rt/arraybyte.d
---- v2.049/src/druntime/src/rt/arraybyte.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/arraybyte.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,1893 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arraybyte.d druntime/src/rt/arraybyte.d
+--- druntime-old/src/rt/arraybyte.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/arraybyte.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,1893 +0,0 @@
-/**
- * Contains SSE2 and MMX versions of certain operations for char, byte, and
- * ubyte ('a', 'g' and 'h' suffixes).
@@ -3602,10 +3602,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- }
- }
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arraycast.d ldc/druntime/src/rt/arraycast.d
---- v2.049/src/druntime/src/rt/arraycast.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/arraycast.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,94 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arraycast.d druntime/src/rt/arraycast.d
+--- druntime-old/src/rt/arraycast.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/arraycast.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,94 +0,0 @@
-/**
- * Implementation of array cast support routines.
- *
@@ -3700,10 +3700,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
-}
-
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arraycat.d ldc/druntime/src/rt/arraycat.d
---- v2.049/src/druntime/src/rt/arraycat.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/arraycat.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,42 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arraycat.d druntime/src/rt/arraycat.d
+--- druntime-old/src/rt/arraycat.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/arraycat.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,42 +0,0 @@
-/**
- * Implementation of array copy support routines.
- *
@@ -3746,10 +3746,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- }
- return to;
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arraydouble.d ldc/druntime/src/rt/arraydouble.d
---- v2.049/src/druntime/src/rt/arraydouble.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/arraydouble.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,1720 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arraydouble.d druntime/src/rt/arraydouble.d
+--- druntime-old/src/rt/arraydouble.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/arraydouble.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,1720 +0,0 @@
-/**
- * Contains SSE2 and MMX versions of certain operations for double.
- *
@@ -5470,10 +5470,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- }
- }
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arrayfloat.d ldc/druntime/src/rt/arrayfloat.d
---- v2.049/src/druntime/src/rt/arrayfloat.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/arrayfloat.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,1435 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arrayfloat.d druntime/src/rt/arrayfloat.d
+--- druntime-old/src/rt/arrayfloat.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/arrayfloat.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,1435 +0,0 @@
-/**
- * Contains SSE2 and MMX versions of certain operations for float.
- *
@@ -6909,10 +6909,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- }
- }
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arrayint.d ldc/druntime/src/rt/arrayint.d
---- v2.049/src/druntime/src/rt/arrayint.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/arrayint.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,2430 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arrayint.d druntime/src/rt/arrayint.d
+--- druntime-old/src/rt/arrayint.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/arrayint.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,2430 +0,0 @@
-/**
- * Contains MMX versions of certain operations for dchar, int, and uint ('w',
- * 'i' and 'k' suffixes).
@@ -9343,10 +9343,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- }
- }
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arrayreal.d ldc/druntime/src/rt/arrayreal.d
---- v2.049/src/druntime/src/rt/arrayreal.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/arrayreal.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,241 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arrayreal.d druntime/src/rt/arrayreal.d
+--- druntime-old/src/rt/arrayreal.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/arrayreal.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,241 +0,0 @@
-/**
- * Contains SSE2 and MMX versions of certain operations for real.
- *
@@ -9588,10 +9588,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- }
- }
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/arrayshort.d ldc/druntime/src/rt/arrayshort.d
---- v2.049/src/druntime/src/rt/arrayshort.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/arrayshort.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,2303 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/arrayshort.d druntime/src/rt/arrayshort.d
+--- druntime-old/src/rt/arrayshort.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/arrayshort.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,2303 +0,0 @@
-/**
- * Contains SSE2 and MMX versions of certain operations for wchar, short,
- * and ushort ('u', 's' and 't' suffixes).
@@ -11895,10 +11895,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- }
- }
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/deh.c ldc/druntime/src/rt/deh.c
---- v2.049/src/druntime/src/rt/deh.c 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/deh.c 1970-01-01 03:00:00.000000000 +0300
-@@ -1,734 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/deh.c druntime/src/rt/deh.c
+--- druntime-old/src/rt/deh.c 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/deh.c 1970-01-01 03:00:00.000000000 +0300
+@@ -1,734 +0,0 @@
-/**
- * Implementation of exception handling support routines for Windows.
- *
@@ -12633,10 +12633,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
-
-
-#endif
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/deh2.d ldc/druntime/src/rt/deh2.d
---- v2.049/src/druntime/src/rt/deh2.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/deh2.d 1970-01-01 03:00:00.000000000 +0300
-@@ -1,322 +0,0 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/deh2.d druntime/src/rt/deh2.d
+--- druntime-old/src/rt/deh2.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/deh2.d 1970-01-01 03:00:00.000000000 +0300
+@@ -1,322 +0,0 @@
-/**
- * Implementation of exception handling support routines for Posix.
- *
@@ -12959,442 +12959,442 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
- }
- }
-}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/eh.d ldc/druntime/src/rt/eh.d
---- v2.049/src/druntime/src/rt/eh.d 1970-01-01 03:00:00.000000000 +0300
-+++ ldc/druntime/src/rt/eh.d 2010-10-03 18:29:58.099624002 +0400
-@@ -0,0 +1,428 @@
-+/**
-+ * This module contains functions and structures required for
-+ * exception handling.
-+ */
-+module eh;
-+
-+private import core.stdc.stdio;
-+private import core.stdc.stdlib;
-+private import rt.util.console;
-+private import ldc.cstdarg;
-+
-+// debug = EH_personality;
-+// debug = EH_personality_verbose;
-+
-+// 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(X86_64) {
-+ version(linux) version=X86_UNWIND;
-+ version(darwin) version=X86_UNWIND;
-+ version(solaris) version=X86_UNWIND;
-+}
-+
-+//version = HP_LIBUNWIND;
-+
-+// D runtime functions
-+extern(C) {
-+ int _d_isbaseof(ClassInfo oc, ClassInfo c);
-+}
-+
-+// libunwind headers
-+extern(C)
-+{
-+ enum _Unwind_Reason_Code : int
-+ {
-+ NO_REASON = 0,
-+ FOREIGN_EXCEPTION_CAUGHT = 1,
-+ FATAL_PHASE2_ERROR = 2,
-+ FATAL_PHASE1_ERROR = 3,
-+ NORMAL_STOP = 4,
-+ END_OF_STACK = 5,
-+ HANDLER_FOUND = 6,
-+ INSTALL_CONTEXT = 7,
-+ CONTINUE_UNWIND = 8
-+ }
-+
-+ enum _Unwind_Action : int
-+ {
-+ SEARCH_PHASE = 1,
-+ CLEANUP_PHASE = 2,
-+ HANDLER_FRAME = 4,
-+ FORCE_UNWIND = 8
-+ }
-+
-+ alias void* _Unwind_Context_Ptr;
-+
-+ alias void function(_Unwind_Reason_Code, _Unwind_Exception*) _Unwind_Exception_Cleanup_Fn;
-+
-+ struct _Unwind_Exception
-+ {
-+ ulong exception_class;
-+ _Unwind_Exception_Cleanup_Fn exception_cleanup;
-+ ptrdiff_t private_1;
-+ ptrdiff_t private_2;
-+ }
-+
-+// interface to HP's libunwind from http://www.nongnu.org/libunwind/
-+version(HP_LIBUNWIND)
-+{
-+ 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);
-+ 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);
-+
-+ alias __libunwind_Unwind_Resume _Unwind_Resume;
-+ alias __libunwind_Unwind_RaiseException _Unwind_RaiseException;
-+ alias __libunwind_Unwind_GetLanguageSpecificData
-+ _Unwind_GetLanguageSpecificData;
-+ alias __libunwind_Unwind_GetIP _Unwind_GetIP;
-+ alias __libunwind_Unwind_SetIP _Unwind_SetIP;
-+ alias __libunwind_Unwind_SetGR _Unwind_SetGR;
-+ alias __libunwind_Unwind_GetRegionStart _Unwind_GetRegionStart;
-+}
-+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);
-+ 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);
-+}
-+else
-+{
-+ // runtime calls these directly
-+ void _Unwind_Resume(_Unwind_Exception*)
-+ {
-+ console("_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");
-+ return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
-+ }
-+}
-+
-+}
-+
-+// error and exit
-+extern(C) private void fatalerror(in char* format, ...)
-+{
-+ 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
-+private ubyte* get_uleb128(ubyte* addr, ref size_t res)
-+{
-+ res = 0;
-+ size_t bitsize = 0;
-+
-+ // read as long as high bit is set
-+ while(*addr & 0x80) {
-+ res |= (*addr & 0x7f) << bitsize;
-+ bitsize += 7;
-+ addr += 1;
-+ if(bitsize >= size_t.sizeof*8)
-+ fatalerror("tried to read uleb128 that exceeded size of size_t");
-+ }
-+ // read last
-+ if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize)
-+ fatalerror("Fatal error in EH code: tried to read uleb128 that exceeded size of size_t");
-+ res |= (*addr) << bitsize;
-+
-+ return addr + 1;
-+}
-+
-+private ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res)
-+{
-+ res = 0;
-+ size_t bitsize = 0;
-+
-+ // read as long as high bit is set
-+ while(*addr & 0x80) {
-+ res |= (*addr & 0x7f) << bitsize;
-+ bitsize += 7;
-+ addr += 1;
-+ if(bitsize >= size_t.sizeof*8)
-+ fatalerror("tried to read sleb128 that exceeded size of size_t");
-+ }
-+ // 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;
-+
-+ // take care of sign
-+ if(bitsize < size_t.sizeof*8 && ((*addr) & 0x40))
-+ res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1);
-+
-+ return addr + 1;
-+}
-+
-+
-+// exception struct used by the runtime.
-+// _d_throw allocates a new instance and passes the address of its
-+// _Unwind_Exception member to the unwind call. The personality
-+// routine is then able to get the whole struct by looking at the data
-+// surrounding the unwind info.
-+struct _d_exception
-+{
-+ Object exception_object;
-+ _Unwind_Exception unwind_info;
-+}
-+
-+// 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
-+char[8] _d_exception_class = "LLDCD1\0\0";
-+
-+
-+//
-+// x86 unwind specific implementation of personality function
-+// and helpers
-+//
-+version(X86_UNWIND)
-+{
-+
-+// 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_verbose) printf("entering personality function. context: %p\n", context);
-+ // check ver: the C++ Itanium ABI only allows ver == 1
-+ if(ver != 1)
-+ 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)
-+ 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 is null)
-+ return _Unwind_Reason_Code.CONTINUE_UNWIND;
-+
-+ /*
-+ find landing pad and action table index belonging to ip by walking
-+ the callsite_table
-+ */
-+ ubyte* callsite_walker = callsite_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;
-+
-+ // 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 action_offset;
-+
-+ while(true) {
-+ // if we've gone through the list and found nothing...
-+ if(callsite_walker >= action_table)
-+ 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);
-+
-+ debug(EH_personality_verbose) printf("ip=%llx %d %d %llx\n", ip, block_start_offset, 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)
-+ return _Unwind_Reason_Code.CONTINUE_UNWIND;
-+
-+ // if we've found our block, exit
-+ if(ip < region_start + block_start_offset + block_size)
-+ break;
-+ }
-+
-+ debug(EH_personality) printf("Found correct landing pad and actionOffset %d\n", 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);
-+
-+ // 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);
-+
-+ /*
-+ walk action table chain, comparing classinfos using _d_isbaseof
-+ */
-+ ubyte* action_walker = action_table + action_offset - 1;
-+
-+ ptrdiff_t ti_offset, next_action_offset;
-+ while(true) {
-+ 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))
-+ 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))
-+ fatalerror("Cleanup action must be last in chain");
-+ return _d_eh_install_finally_context(actions, 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);
-+
-+ // we've walked through all actions and found nothing...
-+ if(next_action_offset == 0)
-+ return _Unwind_Reason_Code.CONTINUE_UNWIND;
-+ else
-+ action_walker += next_action_offset;
-+ }
-+
-+ fatalerror("reached unreachable");
-+ return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
-+}
-+
-+// These are the register numbers for SetGR that
-+// llvm's eh.exception and eh.selector intrinsics
-+// will pick up.
-+// Hints for these can be found by looking at the
-+// EH_RETURN_DATA_REGNO macro in GCC, careful testing
-+// is required though.
-+version (X86_64)
-+{
-+ private int eh_exception_regno = 0;
-+ private int eh_selector_regno = 1;
-+} else {
-+ private int eh_exception_regno = 0;
-+ private int eh_selector_regno = 2;
-+}
-+
-+private _Unwind_Reason_Code _d_eh_install_catch_context(_Unwind_Action actions, ptrdiff_t switchval, ptrdiff_t landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
-+{
-+ debug(EH_personality) printf("Found catch clause!\n");
-+
-+ if(actions & _Unwind_Action.SEARCH_PHASE)
-+ return _Unwind_Reason_Code.HANDLER_FOUND;
-+
-+ else if(actions & _Unwind_Action.CLEANUP_PHASE)
-+ {
-+ debug(EH_personality) printf("Setting switch value to: %d!\n", switchval);
-+ _Unwind_SetGR(context, eh_exception_regno, cast(ptrdiff_t)cast(void*)(exception_struct.exception_object));
-+ _Unwind_SetGR(context, eh_selector_regno, cast(ptrdiff_t)switchval);
-+ _Unwind_SetIP(context, landing_pad);
-+ return _Unwind_Reason_Code.INSTALL_CONTEXT;
-+ }
-+
-+ fatalerror("reached unreachable");
-+ return _Unwind_Reason_Code.FATAL_PHASE2_ERROR;
-+}
-+
-+private _Unwind_Reason_Code _d_eh_install_finally_context(_Unwind_Action actions, ptrdiff_t landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
-+{
-+ // if we're merely in search phase, continue
-+ if(actions & _Unwind_Action.SEARCH_PHASE)
-+ return _Unwind_Reason_Code.CONTINUE_UNWIND;
-+
-+ debug(EH_personality) printf("Calling cleanup routine...\n");
-+
-+ _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)
-+{
-+ ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context);
-+ if (data is null)
-+ {
-+ //printf("language specific data was null\n");
-+ callsite = null;
-+ action = null;
-+ ci = null;
-+ return;
-+ }
-+
-+ //TODO: Do proper DWARF reading here
-+ if(*data++ != 0xff)
-+ fatalerror("DWARF header has unexpected format 1");
-+
-+ if(*data++ != 0x00)
-+ fatalerror("DWARF header has unexpected format 2");
-+ size_t cioffset;
-+ data = get_uleb128(data, cioffset);
-+ ci = cast(ClassInfo*)(data + cioffset);
-+
-+ if(*data++ != 0x03)
-+ fatalerror("DWARF header has unexpected format 3");
-+ size_t callsitelength;
-+ data = get_uleb128(data, callsitelength);
-+ action = data + callsitelength;
-+
-+ callsite = data;
-+}
-+
-+} // end of x86 Linux specific implementation
-+
-+
-+extern(C) void _d_throw_exception(Object 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");
-+ }
-+ abort();
-+}
-+
-+extern(C) void _d_eh_resume_unwind(_d_exception* exception_struct)
-+{
-+ _Unwind_Resume(&exception_struct.unwind_info);
-+}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/lifetime.d ldc/druntime/src/rt/lifetime.d
---- v2.049/src/druntime/src/rt/lifetime.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/lifetime.d 2010-10-07 22:03:51.471253002 +0400
-@@ -81,6 +81,28 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/eh.d druntime/src/rt/eh.d
+--- druntime-old/src/rt/eh.d 1970-01-01 03:00:00.000000000 +0300
++++ druntime/src/rt/eh.d 2010-10-03 18:29:58.099624002 +0400
+@@ -0,0 +1,428 @@
++/**
++ * This module contains functions and structures required for
++ * exception handling.
++ */
++module eh;
++
++private import core.stdc.stdio;
++private import core.stdc.stdlib;
++private import rt.util.console;
++private import ldc.cstdarg;
++
++// debug = EH_personality;
++// debug = EH_personality_verbose;
++
++// 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(X86_64) {
++ version(linux) version=X86_UNWIND;
++ version(darwin) version=X86_UNWIND;
++ version(solaris) version=X86_UNWIND;
++}
++
++//version = HP_LIBUNWIND;
++
++// D runtime functions
++extern(C) {
++ int _d_isbaseof(ClassInfo oc, ClassInfo c);
++}
++
++// libunwind headers
++extern(C)
++{
++ enum _Unwind_Reason_Code : int
++ {
++ NO_REASON = 0,
++ FOREIGN_EXCEPTION_CAUGHT = 1,
++ FATAL_PHASE2_ERROR = 2,
++ FATAL_PHASE1_ERROR = 3,
++ NORMAL_STOP = 4,
++ END_OF_STACK = 5,
++ HANDLER_FOUND = 6,
++ INSTALL_CONTEXT = 7,
++ CONTINUE_UNWIND = 8
++ }
++
++ enum _Unwind_Action : int
++ {
++ SEARCH_PHASE = 1,
++ CLEANUP_PHASE = 2,
++ HANDLER_FRAME = 4,
++ FORCE_UNWIND = 8
++ }
++
++ alias void* _Unwind_Context_Ptr;
++
++ alias void function(_Unwind_Reason_Code, _Unwind_Exception*) _Unwind_Exception_Cleanup_Fn;
++
++ struct _Unwind_Exception
++ {
++ ulong exception_class;
++ _Unwind_Exception_Cleanup_Fn exception_cleanup;
++ ptrdiff_t private_1;
++ ptrdiff_t private_2;
++ }
++
++// interface to HP's libunwind from http://www.nongnu.org/libunwind/
++version(HP_LIBUNWIND)
++{
++ 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);
++ 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);
++
++ alias __libunwind_Unwind_Resume _Unwind_Resume;
++ alias __libunwind_Unwind_RaiseException _Unwind_RaiseException;
++ alias __libunwind_Unwind_GetLanguageSpecificData
++ _Unwind_GetLanguageSpecificData;
++ alias __libunwind_Unwind_GetIP _Unwind_GetIP;
++ alias __libunwind_Unwind_SetIP _Unwind_SetIP;
++ alias __libunwind_Unwind_SetGR _Unwind_SetGR;
++ alias __libunwind_Unwind_GetRegionStart _Unwind_GetRegionStart;
++}
++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);
++ 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);
++}
++else
++{
++ // runtime calls these directly
++ void _Unwind_Resume(_Unwind_Exception*)
++ {
++ console("_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");
++ return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
++ }
++}
++
++}
++
++// error and exit
++extern(C) private void fatalerror(in char* format, ...)
++{
++ 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
++private ubyte* get_uleb128(ubyte* addr, ref size_t res)
++{
++ res = 0;
++ size_t bitsize = 0;
++
++ // read as long as high bit is set
++ while(*addr & 0x80) {
++ res |= (*addr & 0x7f) << bitsize;
++ bitsize += 7;
++ addr += 1;
++ if(bitsize >= size_t.sizeof*8)
++ fatalerror("tried to read uleb128 that exceeded size of size_t");
++ }
++ // read last
++ if(bitsize != 0 && *addr >= 1 << size_t.sizeof*8 - bitsize)
++ fatalerror("Fatal error in EH code: tried to read uleb128 that exceeded size of size_t");
++ res |= (*addr) << bitsize;
++
++ return addr + 1;
++}
++
++private ubyte* get_sleb128(ubyte* addr, ref ptrdiff_t res)
++{
++ res = 0;
++ size_t bitsize = 0;
++
++ // read as long as high bit is set
++ while(*addr & 0x80) {
++ res |= (*addr & 0x7f) << bitsize;
++ bitsize += 7;
++ addr += 1;
++ if(bitsize >= size_t.sizeof*8)
++ fatalerror("tried to read sleb128 that exceeded size of size_t");
++ }
++ // 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;
++
++ // take care of sign
++ if(bitsize < size_t.sizeof*8 && ((*addr) & 0x40))
++ res |= cast(ptrdiff_t)(-1) ^ ((1 << (bitsize+7)) - 1);
++
++ return addr + 1;
++}
++
++
++// exception struct used by the runtime.
++// _d_throw allocates a new instance and passes the address of its
++// _Unwind_Exception member to the unwind call. The personality
++// routine is then able to get the whole struct by looking at the data
++// surrounding the unwind info.
++struct _d_exception
++{
++ Object exception_object;
++ _Unwind_Exception unwind_info;
++}
++
++// 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
++char[8] _d_exception_class = "LLDCD1\0\0";
++
++
++//
++// x86 unwind specific implementation of personality function
++// and helpers
++//
++version(X86_UNWIND)
++{
++
++// 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_verbose) printf("entering personality function. context: %p\n", context);
++ // check ver: the C++ Itanium ABI only allows ver == 1
++ if(ver != 1)
++ 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)
++ 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 is null)
++ return _Unwind_Reason_Code.CONTINUE_UNWIND;
++
++ /*
++ find landing pad and action table index belonging to ip by walking
++ the callsite_table
++ */
++ ubyte* callsite_walker = callsite_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;
++
++ // 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 action_offset;
++
++ while(true) {
++ // if we've gone through the list and found nothing...
++ if(callsite_walker >= action_table)
++ 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);
++
++ debug(EH_personality_verbose) printf("ip=%llx %d %d %llx\n", ip, block_start_offset, 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)
++ return _Unwind_Reason_Code.CONTINUE_UNWIND;
++
++ // if we've found our block, exit
++ if(ip < region_start + block_start_offset + block_size)
++ break;
++ }
++
++ debug(EH_personality) printf("Found correct landing pad and actionOffset %d\n", 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);
++
++ // 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);
++
++ /*
++ walk action table chain, comparing classinfos using _d_isbaseof
++ */
++ ubyte* action_walker = action_table + action_offset - 1;
++
++ ptrdiff_t ti_offset, next_action_offset;
++ while(true) {
++ 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))
++ 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))
++ fatalerror("Cleanup action must be last in chain");
++ return _d_eh_install_finally_context(actions, 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);
++
++ // we've walked through all actions and found nothing...
++ if(next_action_offset == 0)
++ return _Unwind_Reason_Code.CONTINUE_UNWIND;
++ else
++ action_walker += next_action_offset;
++ }
++
++ fatalerror("reached unreachable");
++ return _Unwind_Reason_Code.FATAL_PHASE1_ERROR;
++}
++
++// These are the register numbers for SetGR that
++// llvm's eh.exception and eh.selector intrinsics
++// will pick up.
++// Hints for these can be found by looking at the
++// EH_RETURN_DATA_REGNO macro in GCC, careful testing
++// is required though.
++version (X86_64)
++{
++ private int eh_exception_regno = 0;
++ private int eh_selector_regno = 1;
++} else {
++ private int eh_exception_regno = 0;
++ private int eh_selector_regno = 2;
++}
++
++private _Unwind_Reason_Code _d_eh_install_catch_context(_Unwind_Action actions, ptrdiff_t switchval, ptrdiff_t landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
++{
++ debug(EH_personality) printf("Found catch clause!\n");
++
++ if(actions & _Unwind_Action.SEARCH_PHASE)
++ return _Unwind_Reason_Code.HANDLER_FOUND;
++
++ else if(actions & _Unwind_Action.CLEANUP_PHASE)
++ {
++ debug(EH_personality) printf("Setting switch value to: %d!\n", switchval);
++ _Unwind_SetGR(context, eh_exception_regno, cast(ptrdiff_t)cast(void*)(exception_struct.exception_object));
++ _Unwind_SetGR(context, eh_selector_regno, cast(ptrdiff_t)switchval);
++ _Unwind_SetIP(context, landing_pad);
++ return _Unwind_Reason_Code.INSTALL_CONTEXT;
++ }
++
++ fatalerror("reached unreachable");
++ return _Unwind_Reason_Code.FATAL_PHASE2_ERROR;
++}
++
++private _Unwind_Reason_Code _d_eh_install_finally_context(_Unwind_Action actions, ptrdiff_t landing_pad, _d_exception* exception_struct, _Unwind_Context_Ptr context)
++{
++ // if we're merely in search phase, continue
++ if(actions & _Unwind_Action.SEARCH_PHASE)
++ return _Unwind_Reason_Code.CONTINUE_UNWIND;
++
++ debug(EH_personality) printf("Calling cleanup routine...\n");
++
++ _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)
++{
++ ubyte* data = cast(ubyte*)_Unwind_GetLanguageSpecificData(context);
++ if (data is null)
++ {
++ //printf("language specific data was null\n");
++ callsite = null;
++ action = null;
++ ci = null;
++ return;
++ }
++
++ //TODO: Do proper DWARF reading here
++ if(*data++ != 0xff)
++ fatalerror("DWARF header has unexpected format 1");
++
++ if(*data++ != 0x00)
++ fatalerror("DWARF header has unexpected format 2");
++ size_t cioffset;
++ data = get_uleb128(data, cioffset);
++ ci = cast(ClassInfo*)(data + cioffset);
++
++ if(*data++ != 0x03)
++ fatalerror("DWARF header has unexpected format 3");
++ size_t callsitelength;
++ data = get_uleb128(data, callsitelength);
++ action = data + callsitelength;
++
++ callsite = data;
++}
++
++} // end of x86 Linux specific implementation
++
++
++extern(C) void _d_throw_exception(Object 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");
++ }
++ abort();
++}
++
++extern(C) void _d_eh_resume_unwind(_d_exception* exception_struct)
++{
++ _Unwind_Resume(&exception_struct.unwind_info);
++}
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/lifetime.d druntime/src/rt/lifetime.d
+--- druntime-old/src/rt/lifetime.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/lifetime.d 2010-10-08 14:55:56.581547002 +0400
+@@ -81,6 +81,28 @@
MAXSMALLSIZE = 256-SMALLPAD,
MAXMEDSIZE = (PAGESIZE / 2) - MEDPAD
}
@@ -13423,7 +13423,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
-@@ -92,6 +114,13 @@
+@@ -92,6 +114,13 @@
return gc_malloc(sz);
}
@@ -13437,577 +13437,206 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
/**
*
-@@ -665,6 +694,249 @@
- onOutOfMemoryError();
- }
-
-+version (LDC)
-+{
-+
-+/**
-+ * Allocate a new array of length elements.
-+ * ti is the type of the resulting array, or pointer to element.
-+ * The resulting array is initialized to 0
-+ */
-+extern (C) void* _d_newarrayT(TypeInfo ti, size_t length)
-+{
-+ void* p;
-+ auto size = ti.next.tsize(); // array element size
-+
-+ debug(PRINTF) printf("_d_newarrayT(length = %u, size = %d)\n", length, size);
-+ if (length == 0 || size == 0)
-+ return null;
-+
-+ size = length_adjust(size, length);
-+
-+ p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+ debug(PRINTF) printf(" p = %p\n", p);
-+ memset(p, 0, size);
-+
-+ return p;
-+}
-+
-+/**
-+ * As _d_newarrayT, but
-+ * for when the array has a non-zero initializer.
-+ */
-+extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length)
-+{
-+ void* result;
-+ auto size = ti.next.tsize(); // array element size
-+
-+ debug(PRINTF) printf("_d_newarrayiT(length = %d, size = %d)\n", length, size);
-+
-+ if (length == 0 || size == 0)
-+ result = null;
-+ else
-+ {
-+ auto initializer = ti.next.init();
-+ auto isize = initializer.length;
-+ auto q = initializer.ptr;
-+
-+ size = length_adjust(size, length);
-+
-+ auto p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+ debug(PRINTF) printf(" p = %p\n", p);
-+ if (isize == 1)
-+ memset(p, *cast(ubyte*)q, size);
-+ else if (isize == int.sizeof)
-+ {
-+ int init = *cast(int*)q;
-+ size /= int.sizeof;
-+ for (size_t u = 0; u < size; u++)
-+ {
-+ (cast(int*)p)[u] = init;
-+ }
-+ }
-+ else
-+ {
-+ for (size_t u = 0; u < size; u += isize)
-+ {
-+ memcpy(p + u, q, isize);
-+ }
-+ }
-+ result = p;
-+ }
-+ return result;
-+}
-+
-+/**
-+ * As _d_newarrayT, but without initialization
-+ */
-+extern (C) void* _d_newarrayvT(TypeInfo ti, size_t length)
-+{
-+ void* p;
-+ auto size = ti.next.tsize(); // array element size
-+
-+ debug(PRINTF) printf("_d_newarrayvT(length = %u, size = %d)\n", length, size);
-+ if (length == 0 || size == 0)
-+ return null;
-+
-+ size = length_adjust(size, length);
-+
-+ p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+ debug(PRINTF) printf(" p = %p\n", p);
-+ return p;
-+}
-+
-+/**
-+ * Allocate a new array of arrays of arrays of arrays ...
-+ * ti is the type of the resulting array.
-+ * ndims is the number of nested arrays.
-+ * dims it the array of dimensions, its size is ndims.
-+ * The resulting array is initialized to 0
-+ */
-+extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
-+{
-+ void* result;
-+
-+ debug(PRINTF) printf("_d_newarraymT(ndims = %d)\n", ndims);
-+ if (ndims == 0)
-+ result = null;
-+ else
-+ {
-+ static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
-+ {
-+ size_t dim = *pdim;
-+ void[] p;
-+
-+ debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
-+ if (ndims == 1)
-+ {
-+ auto r = _d_newarrayT(ti, dim);
-+ return r[0 .. dim];
-+ }
-+ else
-+ {
-+ p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
-+ for (int i = 0; i < dim; i++)
-+ {
-+ (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
-+ }
-+ }
-+ return p;
-+ }
-+
-+ result = foo(ti, dims, ndims).ptr;
-+ debug(PRINTF) printf("result = %p\n", result);
-+
-+ version (none)
-+ {
-+ for (int i = 0; i < ndims; i++)
-+ {
-+ printf("index %d: %d\n", i, *dims++);
-+ }
-+ }
-+ }
-+ return result;
-+}
-+
-+
-+/**
-+ * 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)
-+{
-+ void* result;
-+
-+ debug(PRINTF) printf("_d_newarraymiT(ndims = %d)\n", ndims);
-+ if (ndims == 0)
-+ result = null;
-+ else
-+ {
-+ static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
-+ {
-+ size_t dim = *pdim;
-+ void[] p;
-+
-+ if (ndims == 1)
-+ {
-+ auto r = _d_newarrayiT(ti, dim);
-+ p = r[0 .. dim];
-+ }
-+ else
-+ {
-+ p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
-+ for (int i = 0; i < dim; i++)
-+ {
-+ (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
-+ }
-+ }
-+ return p;
-+ }
-+
-+ result = foo(ti, dims, ndims).ptr;
-+ debug(PRINTF) printf("result = %p\n", result);
-+
-+ version (none)
-+ {
-+ for (int i = 0; i < ndims; i++)
-+ {
-+ printf("index %d: %d\n", i, *dims++);
-+ printf("init = %d\n", *dims++);
-+ }
-+ }
-+ }
-+ return result;
-+}
-+
-+/**
-+ * As _d_newarraymT, but without initialization
-+ */
-+extern (C) void* _d_newarraymvT(TypeInfo ti, int ndims, size_t* dims)
-+{
-+ void* result;
-+
-+ debug(PRINTF) printf("_d_newarraymvT(ndims = %d)\n", ndims);
-+ if (ndims == 0)
-+ result = null;
-+ else
-+ {
-+ static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
-+ {
-+ size_t dim = *pdim;
-+ void[] p;
-+
-+ debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
-+ if (ndims == 1)
-+ {
-+ auto r = _d_newarrayvT(ti, dim);
-+ return r[0 .. dim];
-+ }
-+ else
-+ {
-+ p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
-+ for (int i = 0; i < dim; i++)
-+ {
-+ (cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
-+ }
-+ }
-+ return p;
-+ }
-+
-+ result = foo(ti, dims, ndims).ptr;
-+ debug(PRINTF) printf("result = %p\n", result);
-+
-+ version (none)
-+ {
-+ for (int i = 0; i < ndims; i++)
-+ {
-+ printf("index %d: %d\n", i, *dims++);
-+ }
-+ }
-+ }
-+ return result;
-+}
-+
-+} else {
-+
- /**
- * Allocate a new array of length elements.
+@@ -670,7 +699,7 @@
* ti is the type of the resulting array, or pointer to element.
-@@ -884,6 +1156,7 @@
- return result;
+ * (For when the array is initialized to 0)
+ */
+-extern (C) ulong _d_newarrayT(TypeInfo ti, size_t length)
++extern (C) void[] _d_newarrayT(TypeInfo ti, size_t length)
+ {
+ ulong result;
+ auto size = ti.next.tsize(); // array element size
+@@ -702,7 +731,7 @@
+ __setArrayAllocLength(info, size, isshared);
+ result = cast(ulong)length + (cast(ulong)cast(size_t)arrstart << 32);
+ }
+- return result;
++ return *cast(void[]*)&result;
+
+ Loverflow:
+ onOutOfMemoryError();
+@@ -711,7 +740,7 @@
+ /**
+ * For when the array has a non-zero initializer.
+ */
+-extern (C) ulong _d_newarrayiT(TypeInfo ti, size_t length)
++extern (C) void[] _d_newarrayiT(TypeInfo ti, size_t length)
+ {
+ ulong result;
+ auto size = ti.next.tsize(); // array element size
+@@ -764,7 +793,7 @@
+ __setArrayAllocLength(info, size, isshared);
+ result = cast(ulong)length + (cast(ulong)cast(uint)arrstart << 32);
+ }
+- return result;
++ return *cast(void[]*)&result;
+
+ Loverflow:
+ onOutOfMemoryError();
+@@ -773,7 +802,7 @@
+ /**
+ *
+ */
+-extern (C) ulong _d_newarraymT(TypeInfo ti, int ndims, ...)
++extern (C) void[] _d_newarraymT(TypeInfo ti, int ndims, ...)
+ {
+ ulong result;
+
+@@ -823,14 +852,14 @@
+ }
+ va_end(q);
+ }
+- return result;
++ return *cast(void[]*)&result;
}
-+}
/**
*
-@@ -1042,6 +1315,175 @@
+ */
+-extern (C) ulong _d_newarraymiT(TypeInfo ti, int ndims, ...)
++extern (C) void[] _d_newarraymiT(TypeInfo ti, int ndims, ...)
+ {
+ ulong result;
+
+@@ -881,10 +910,9 @@
+ }
+ va_end(q);
}
+- return result;
++ return *cast(void[]*)&result;
}
-+version (LDC)
-+{
-+/**
-+ * Resize dynamic arrays with 0 initializers.
-+ */
-+extern (C) byte* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
-+in
-+{
-+ assert(ti);
-+// This assert on array consistency may fail with casts or in unions.
-+// This function still does something sensible even if plength && !pdata.
-+// assert(!plength || pdata);
-+}
-+body
-+{
-+ byte* newdata;
-+ size_t sizeelem = ti.next.tsize();
-+
-+ debug(PRINTF)
-+ {
-+ printf("_d_arraysetlengthT(sizeelem = %d, newlength = %d)\n", sizeelem, newlength);
-+ printf("\tp.data = %p, p.length = %d\n", pdata, plength);
-+ }
-+
-+ if (newlength)
-+ {
-+ size_t newsize = length_adjust(sizeelem, newlength);
-+
-+ debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
-+
-+ if (pdata)
-+ {
-+ newdata = pdata;
-+ if (newlength > plength)
-+ {
-+ size_t size = plength * sizeelem;
-+ auto info = gc_query(pdata);
-+
-+ if (info.size <= newsize || info.base != pdata)
-+ {
-+ if (info.size >= PAGESIZE && info.base == pdata)
-+ { // Try to extend in-place
-+ auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
-+ if (u)
-+ {
-+ goto L1;
-+ }
-+ }
-+ newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
-+ newdata[0 .. size] = pdata[0 .. size];
-+ }
-+ L1:
-+ newdata[size .. newsize] = 0;
-+ }
-+ }
-+ else
-+ {
-+ newdata = cast(byte *)gc_calloc(newsize + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+ }
-+ }
-+ else
-+ {
-+ newdata = pdata;
-+ }
-+
-+ return newdata;
-+}
-+
-+/**
-+ * Resize arrays for non-zero initializers.
-+ * p pointer to array lvalue to be updated
-+ * newlength new .length property of array
-+ * sizeelem size of each element of array
-+ * initsize size of initializer
-+ * ... initializer
-+ */
-+extern (C) byte* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
-+in
-+{
-+// This assert on array consistency may fail with casts or in unions.
-+// This function still does something sensible even if plength && !pdata.
-+// assert(!plength || pdata);
-+}
-+body
-+{
-+ byte* newdata;
-+ TypeInfo tinext = ti.next;
-+ size_t sizeelem = tinext.tsize();
-+ void[] initializer = tinext.init();
-+ size_t initsize = initializer.length;
-+
-+ assert(sizeelem);
-+ assert(initsize);
-+ assert(initsize <= sizeelem);
-+ assert((sizeelem / initsize) * initsize == sizeelem);
-+
-+ debug(PRINTF)
-+ {
-+ printf("_d_arraysetlengthiT(sizeelem = %d, newlength = %d, initsize = %d)\n", sizeelem, newlength, initsize);
-+ printf("\tp.data = %p, p.length = %d\n", pdata, plength);
-+ }
-+
-+ if (newlength)
-+ {
-+ size_t newsize = length_adjust(sizeelem, newlength);
-+ debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
-+
-+ size_t size = plength * sizeelem;
-+
-+ if (pdata)
-+ {
-+ newdata = pdata;
-+ if (newlength > plength)
-+ {
-+ auto info = gc_query(pdata);
-+
-+ if (info.size <= newsize || info.base != pdata)
-+ {
-+ if (info.size >= PAGESIZE && info.base == pdata)
-+ { // Try to extend in-place
-+ auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
-+ if (u)
-+ {
-+ goto L1;
-+ }
-+ }
-+ newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
-+ newdata[0 .. size] = pdata[0 .. size];
-+ L1: ;
-+ }
-+ }
-+ }
-+ else
-+ {
-+ newdata = cast(byte *)gc_malloc(newsize + 1, !(tinext.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+ }
-+
-+ auto q = initializer.ptr; // pointer to initializer
-+
-+ if (newsize > size)
-+ {
-+ if (initsize == 1)
-+ {
-+ debug(PRINTF) printf("newdata = %p, size = %d, newsize = %d, *q = %d\n", newdata, size, newsize, *cast(byte*)q);
-+ newdata[size .. newsize] = *(cast(byte*)q);
-+ }
-+ else
-+ {
-+ for (size_t u = size; u < newsize; u += initsize)
-+ {
-+ memcpy(newdata + u, q, initsize);
-+ }
-+ }
-+ }
-+ }
-+ else
-+ {
-+ newdata = pdata;
-+ }
-+
-+ return newdata;
-+
-+Loverflow:
-+ onOutOfMemoryError();
-+ return null;
-+}
-+
-+} else { // version (LDC)
-+
-
+-
+ /**
+ *
+ */
+@@ -1046,7 +1074,7 @@
/**
* Resize dynamic arrays with 0 initializers.
-@@ -1376,6 +1818,58 @@
+ */
+-extern (C) byte[] _d_arraysetlengthT(TypeInfo ti, size_t newlength, Array *p)
++extern (C) void[] _d_arraysetlengthT(TypeInfo ti, size_t newlength, Array *p)
+ in
+ {
+ assert(ti);
+@@ -1206,7 +1234,7 @@
+ * initsize size of initializer
+ * ... initializer
+ */
+-extern (C) byte[] _d_arraysetlengthiT(TypeInfo ti, size_t newlength, Array *p)
++extern (C) void[] _d_arraysetlengthiT(TypeInfo ti, size_t newlength, Array *p)
+ in
+ {
+ assert(!p.length || p.data);
+@@ -1376,12 +1404,11 @@
onOutOfMemoryError();
}
-+}
-+
+-
+ /**
+ * Append y[] to array pointed to by px
+ * size is size of each array element.
+ */
+-extern (C) long _d_arrayappendT(TypeInfo ti, Array *px, byte[] y)
++extern (C) void[] _d_arrayappendT(TypeInfo ti, Array *px, byte[] y)
+ {
+ // only optimize array append where ti is not a shared type
+ auto sizeelem = ti.next.tsize(); // array element size
+@@ -1468,10 +1495,9 @@
+ L1:
+ px.length = newlength;
+ memcpy(px.data + length * sizeelem, y.ptr, y.length * sizeelem);
+- return *cast(long*)px;
++ return *cast(void[]*)px;
+ }
+
+-
+ /**
+ *
+ */
+@@ -1552,21 +1578,36 @@
+ return newcap;
+ }
+
+version (LDC)
+{
+
+/**
+ * Appends a single element to an array.
+ */
-+extern (C) byte[] _d_arrayappendcT(TypeInfo ti, void* array, void* element)
++extern (C) void[] _d_arrayappendcT(TypeInfo ti, byte[] *x, byte *argp)
+{
-+ auto x = cast(byte[]*)array;
-+ auto sizeelem = ti.next.tsize(); // array element size
-+ auto info = gc_query(x.ptr);
-+ auto length = x.length;
-+ auto newlength = length + 1;
-+ auto newsize = newlength * sizeelem;
-+
-+ assert(info.size == 0 || length * sizeelem <= info.size);
-+
-+ debug(PRINTF) printf("_d_arrayappendcT(sizeelem = %d, ptr = %p, length = %d, cap = %d)\n", sizeelem, x.ptr, x.length, info.size);
-+
-+ if (info.size <= newsize || info.base != x.ptr)
-+ { byte* newdata;
-+
-+ if (info.size >= PAGESIZE && info.base == x.ptr)
-+ { // Try to extend in-place
-+ auto u = gc_extend(x.ptr, (newsize + 1) - info.size, (newsize + 1) - info.size);
-+ if (u)
-+ {
-+ goto L1;
-+ }
-+ }
-+ debug(PRINTF) printf("_d_arrayappendcT(length = %d, newlength = %d, cap = %d)\n", length, newlength, info.size);
-+ auto newcap = newCapacity(newlength, sizeelem);
-+ assert(newcap >= newlength * sizeelem);
-+ newdata = cast(byte *)gc_malloc(newcap + 1, info.attr);
-+ memcpy(newdata, x.ptr, length * sizeelem);
-+ (cast(void**)x)[1] = newdata;
-+ }
-+ L1:
-+ byte *argp = cast(byte *)element;
-+
-+ *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 _d_arrayappendT(ti, cast(Array*)x, argp[0..1]);
+}
+
-+} // version (LDC)
-+else
-+{
-
- /**
- * Append y[] to array pointed to by px
-@@ -1471,6 +1965,7 @@
- return *cast(long*)px;
- }
-
-+}
-
- /**
- *
-@@ -1552,6 +2047,11 @@
- return newcap;
- }
-
-+version (LDC)
-+{
+}
+else
+{
/**
*
-@@ -1641,6 +2141,8 @@
+ */
+-extern (C) long _d_arrayappendcT(TypeInfo ti, Array *x, ...)
++extern (C) void[] _d_arrayappendcT(TypeInfo ti, Array *x, ...)
+ {
+ byte *argp = cast(byte*)(&ti + 2);
+ return _d_arrayappendT(ti, x, argp[0..1]);
+ }
+
++}
+
+ /**
+ * Append dchar to char[]
+ */
+-extern (C) long _d_arrayappendcd(ref char[] x, dchar c)
++extern (C) void[] _d_arrayappendcd(ref char[] x, dchar c)
+ {
+ // c could encode into from 1 to 4 characters
+ char[4] buf = void;
+@@ -1612,7 +1653,7 @@
+ /**
+ * Append dchar to wchar[]
+ */
+-extern (C) long _d_arrayappendwd(ref wchar[] x, dchar c)
++extern (C) void[] _d_arrayappendwd(ref wchar[] x, dchar c)
+ {
+ // c could encode into from 1 to 2 w characters
+ wchar[2] buf = void;
+@@ -1641,7 +1682,6 @@
return _d_arrayappendT(typeid(shared wchar[]), cast(Array *)&x, appendthis);
}
-+}
-+
-
+-
/**
*
-@@ -1794,6 +2296,35 @@
+ */
+@@ -1794,11 +1834,10 @@
void* ptr;
}
-+version (LDC)
-+{
-+
-+/**
-+ *
-+ */
-+extern (C) void[] _adDupT(TypeInfo ti, void[] a)
-+out (result)
-+{
-+ auto sizeelem = ti.next.tsize(); // array element size
-+ assert(memcmp(result.ptr, a.ptr, a.length * sizeelem) == 0);
-+}
-+body
-+{
-+ void* ptr;
-+
-+ if (a.length)
-+ {
-+ auto sizeelem = ti.next.tsize(); // array element size
-+ auto size = a.length * sizeelem;
-+ ptr = gc_malloc(size, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
-+ memcpy(ptr, a.ptr, size);
-+ }
-+ return ptr[0 .. a.length];
-+}
-+
-+}
-+else
-+{
-
+-
/**
*
-@@ -1822,6 +2353,8 @@
- return *cast(long*)(&r);
+ */
+-extern (C) long _adDupT(TypeInfo ti, Array2 a)
++extern (C) void[] _adDupT(TypeInfo ti, void[] a)
+ out (result)
+ {
+ auto sizeelem = ti.next.tsize(); // array element size
+@@ -1819,7 +1858,7 @@
+ r.length = a.length;
+ memcpy(r.ptr, a.ptr, size);
+ }
+- return *cast(long*)(&r);
++ return *cast(void[]*)(&r);
}
-+}
-+
- unittest
- {
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/qsort.d ldc/druntime/src/rt/qsort.d
---- v2.049/src/druntime/src/rt/qsort.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/qsort.d 2010-10-07 13:59:06.815253002 +0400
-@@ -44,7 +44,7 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/qsort.d druntime/src/rt/qsort.d
+--- druntime-old/src/rt/qsort.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/qsort.d 2010-10-07 13:59:06.815253002 +0400
+@@ -44,7 +44,7 @@
structures. The default value is optimized for a high cost for compares. */
@@ -14016,7 +13645,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
{
byte* base;
byte*[40] stack; // stack
-@@ -124,7 +124,7 @@
+@@ -124,7 +124,7 @@
limit = sp[1];
}
else // else stack empty, all done
@@ -14025,10 +13654,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
assert(0);
}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/qsort2.d ldc/druntime/src/rt/qsort2.d
---- v2.049/src/druntime/src/rt/qsort2.d 2010-08-05 05:39:06.000000000 +0400
-+++ ldc/druntime/src/rt/qsort2.d 2010-10-07 14:01:41.359253001 +0400
-@@ -31,14 +31,14 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/qsort2.d druntime/src/rt/qsort2.d
+--- druntime-old/src/rt/qsort2.d 2010-08-05 05:39:06.000000000 +0400
++++ druntime/src/rt/qsort2.d 2010-10-07 14:01:41.359253001 +0400
+@@ -31,14 +31,14 @@
return tiglobal.compare(p1, p2);
}
@@ -14045,10 +13674,10 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
}
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/rt/trace.d ldc/druntime/src/rt/trace.d
---- v2.049/src/druntime/src/rt/trace.d 2010-08-07 09:46:06.000000000 +0400
-+++ ldc/druntime/src/rt/trace.d 2010-10-01 21:01:58.444892002 +0400
-@@ -855,7 +855,7 @@
+diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/rt/trace.d druntime/src/rt/trace.d
+--- druntime-old/src/rt/trace.d 2010-08-07 09:46:06.000000000 +0400
++++ druntime/src/rt/trace.d 2010-10-01 21:01:58.444892002 +0400
+@@ -855,7 +855,7 @@
version (OSX)
{ // 16 byte align stack
asm
@@ -14057,7 +13686,7 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
pushad ;
sub ESP,12 ;
}
-@@ -870,7 +870,7 @@
+@@ -870,7 +870,7 @@
else
{
asm
@@ -14066,219 +13695,219 @@ diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.
pushad ;
}
trace_epi();
-diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- v2.049/src/druntime/src/std/intrinsic.d ldc/druntime/src/std/intrinsic.d
---- v2.049/src/druntime/src/std/intrinsic.d 1970-01-01 03:00:00.000000000 +0300
-+++ ldc/druntime/src/std/intrinsic.d 2010-10-03 20:07:21.183624002 +0400
-@@ -0,0 +1,212 @@
-+/*
-+ * D phobos intrinsics for LDC
-+ *
-+ * From GDC ... public domain!
-+ */
-+module std.intrinsic;
-+
-+// Check for the right compiler
-+version(LDC)
-+{
-+ // OK
-+}
-+else
-+{
-+ static assert(false, "This module is only valid for LDC");
-+}
-+
-+/**
-+ * Scans the bits in v starting with bit 0, looking
-+ * for the first set bit.
-+ * Returns:
-+ * The bit number of the first bit set.
-+ * The return value is undefined if v is zero.
-+ */
-+nothrow int bsf(uint v)
-+{
-+ uint m = 1;
-+ uint i;
-+ for (i = 0; i < 32; i++,m<<=1) {
-+ if (v&m)
-+ return i;
-+ }
-+ return i; // supposed to be undefined
-+}
-+
-+/**
-+ * Scans the bits in v from the most significant bit
-+ * to the least significant bit, looking
-+ * for the first set bit.
-+ * Returns:
-+ * The bit number of the first bit set.
-+ * The return value is undefined if v is zero.
-+ * Example:
-+ * ---
-+ * import std.intrinsic;
-+ *
-+ * int main()
-+ * {
-+ * uint v;
-+ * int x;
-+ *
-+ * v = 0x21;
-+ * x = bsf(v);
-+ * printf("bsf(x%x) = %d\n", v, x);
-+ * x = bsr(v);
-+ * printf("bsr(x%x) = %d\n", v, x);
-+ * return 0;
-+ * }
-+ * ---
-+ * Output:
-+ * bsf(x21) = 0
-+ * bsr(x21) = 5
-+ */
-+nothrow int bsr(uint v)
-+{
-+ uint m = 0x80000000;
-+ uint i;
-+ for (i = 32; i ; i--,m>>>=1) {
-+ if (v&m)
-+ return i-1;
-+ }
-+ return i; // supposed to be undefined
-+}
-+
-+
-+/**
-+ * Tests the bit.
-+ */
-+nothrow int bt(uint *p, uint bitnum)
-+{
-+ return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ;
-+}
-+
-+
-+/**
-+ * Tests and complements the bit.
-+ */
-+nothrow int btc(uint *p, uint bitnum)
-+{
-+ uint * q = p + (bitnum / (uint.sizeof*8));
-+ uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
-+ int result = *q & mask;
-+ *q ^= mask;
-+ return result ? -1 : 0;
-+}
-+
-+
-+/**
-+ * Tests and resets (sets to 0) the bit.
-+ */
-+nothrow int btr(uint *p, uint bitnum)
-+{
-+ uint * q = p + (bitnum / (uint.sizeof*8));
-+ uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
-+ int result = *q & mask;
-+ *q &= ~mask;
-+ return result ? -1 : 0;
-+}
-+
-+
-+/**
-+ * Tests and sets the bit.
-+ * Params:
-+ * p = a non-NULL pointer to an array of uints.
-+ * index = a bit number, starting with bit 0 of p[0],
-+ * and progressing. It addresses bits like the expression:
-+---
-+p[index / (uint.sizeof*8)] & (1 << (index & ((uint.sizeof*8) - 1)))
-+---
-+ * Returns:
-+ * A non-zero value if the bit was set, and a zero
-+ * if it was clear.
-+ *
-+ * Example:
-+ * ---
-+import std.intrinsic;
-+
-+int main()
-+{
-+ uint array[2];
-+
-+ array[0] = 2;
-+ array[1] = 0x100;
-+
-+ printf("btc(array, 35) = %d\n", btc(array, 35));
-+ printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
-+
-+ printf("btc(array, 35) = %d\n", btc(array, 35));
-+ printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
-+
-+ printf("bts(array, 35) = %d\n", bts(array, 35));
-+ printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
-+
-+ printf("btr(array, 35) = %d\n", btr(array, 35));
-+ printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
-+
-+ printf("bt(array, 1) = %d\n", bt(array, 1));
-+ printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
-+
-+ return 0;
-+}
-+ * ---
-+ * Output:
-+
-+btc(array, 35) = 0 -+array = [0]:x2, [1]:x108 -+btc(array, 35) = -1 -+array = [0]:x2, [1]:x100 -+bts(array, 35) = 0 -+array = [0]:x2, [1]:x108 -+btr(array, 35) = -1 -+array = [0]:x2, [1]:x100 -+bt(array, 1) = -1 -+array = [0]:x2, [1]:x100 -+-+ */ -+nothrow int bts(uint *p, uint bitnum) -+{ -+ uint * q = p + (bitnum / (uint.sizeof*8)); -+ uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1)); -+ int result = *q & mask; -+ *q |= mask; -+ return result ? -1 : 0; -+} -+ -+/** -+ * Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes -+ * byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3 -+ * becomes byte 0. -+ */ -+pragma(intrinsic, "llvm.bswap.i32") -+ uint bswap(uint val); -+ -+/** -+ * Reads I/O port at port_address. -+ */ -+ubyte inp(uint p) { throw new Exception("inp intrinsic not yet implemented"); } -+ -+/** -+ * ditto -+ */ -+ushort inpw(uint p) { throw new Exception("inpw intrinsic not yet implemented"); } -+ -+/** -+ * ditto -+ */ -+uint inpl(uint p) { throw new Exception("inpl intrinsic not yet implemented"); } -+ -+/** -+ * ditto -+ */ -+ubyte outp(uint p, ubyte v) { throw new Exception("outp intrinsic not yet implemented"); } -+ -+/** -+ * ditto -+ */ -+ushort outpw(uint p, ushort v) { throw new Exception("outpw intrinsic not yet implemented"); } -+ -+/** -+ * ditto -+ */ -+uint outpl(uint p, uint v) { throw new Exception("outpl intrinsic not yet implemented"); } +diff -U 3 -H -d -r -N -x '*.mak' -x tk -x backend -x debug -x release -x '*_pch.h' -x Makefile -x '*.rej' -x '*~' -x '*.log' -x .svn -x '*pro.user' -x .directory -x cmake_install -x CMakeFiles -x .preprocessed.tmp -x 'Makefile.*' -x '*.orig' -- druntime-old/src/std/intrinsic.d druntime/src/std/intrinsic.d +--- druntime-old/src/std/intrinsic.d 1970-01-01 03:00:00.000000000 +0300 ++++ druntime/src/std/intrinsic.d 2010-10-03 20:07:21.183624002 +0400 +@@ -0,0 +1,212 @@ ++/* ++ * D phobos intrinsics for LDC ++ * ++ * From GDC ... public domain! ++ */ ++module std.intrinsic; ++ ++// Check for the right compiler ++version(LDC) ++{ ++ // OK ++} ++else ++{ ++ static assert(false, "This module is only valid for LDC"); ++} ++ ++/** ++ * Scans the bits in v starting with bit 0, looking ++ * for the first set bit. ++ * Returns: ++ * The bit number of the first bit set. ++ * The return value is undefined if v is zero. ++ */ ++nothrow int bsf(uint v) ++{ ++ uint m = 1; ++ uint i; ++ for (i = 0; i < 32; i++,m<<=1) { ++ if (v&m) ++ return i; ++ } ++ return i; // supposed to be undefined ++} ++ ++/** ++ * Scans the bits in v from the most significant bit ++ * to the least significant bit, looking ++ * for the first set bit. ++ * Returns: ++ * The bit number of the first bit set. ++ * The return value is undefined if v is zero. ++ * Example: ++ * --- ++ * import std.intrinsic; ++ * ++ * int main() ++ * { ++ * uint v; ++ * int x; ++ * ++ * v = 0x21; ++ * x = bsf(v); ++ * printf("bsf(x%x) = %d\n", v, x); ++ * x = bsr(v); ++ * printf("bsr(x%x) = %d\n", v, x); ++ * return 0; ++ * } ++ * --- ++ * Output: ++ * bsf(x21) = 0
++btc(array, 35) = 0 ++array = [0]:x2, [1]:x108 ++btc(array, 35) = -1 ++array = [0]:x2, [1]:x100 ++bts(array, 35) = 0 ++array = [0]:x2, [1]:x108 ++btr(array, 35) = -1 ++array = [0]:x2, [1]:x100 ++bt(array, 1) = -1 ++array = [0]:x2, [1]:x100 ++++ */ ++nothrow int bts(uint *p, uint bitnum) ++{ ++ uint * q = p + (bitnum / (uint.sizeof*8)); ++ uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1)); ++ int result = *q & mask; ++ *q |= mask; ++ return result ? -1 : 0; ++} ++ ++/** ++ * Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes ++ * byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3 ++ * becomes byte 0. ++ */ ++pragma(intrinsic, "llvm.bswap.i32") ++ uint bswap(uint val); ++ ++/** ++ * Reads I/O port at port_address. ++ */ ++ubyte inp(uint p) { throw new Exception("inp intrinsic not yet implemented"); } ++ ++/** ++ * ditto ++ */ ++ushort inpw(uint p) { throw new Exception("inpw intrinsic not yet implemented"); } ++ ++/** ++ * ditto ++ */ ++uint inpl(uint p) { throw new Exception("inpl intrinsic not yet implemented"); } ++ ++/** ++ * ditto ++ */ ++ubyte outp(uint p, ubyte v) { throw new Exception("outp intrinsic not yet implemented"); } ++ ++/** ++ * ditto ++ */ ++ushort outpw(uint p, ushort v) { throw new Exception("outpw intrinsic not yet implemented"); } ++ ++/** ++ * ditto ++ */ ++uint outpl(uint p, uint v) { throw new Exception("outpl intrinsic not yet implemented"); } diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 65d6523a..f0567092 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -214,15 +214,8 @@ void DtoSetArray(DValue* array, LLValue* dim, LLValue* ptr) Logger::println("SetArray"); LLValue *arr = array->getLVal(); assert(isaStruct(arr->getType()->getContainedType(0))); -#if 1 DtoStore(dim, DtoGEPi(arr,0,0)); DtoStore(ptr, DtoGEPi(arr,0,1)); -#else - DSliceValue *slice = DtoResizeDynArray(array->type, array, dim); - DtoMemCpy(DtoArrayPtr(array), ptr, dim); - DtoStore(dim, DtoGEPi(arr,0,0)); - DtoStore(slice->ptr, DtoGEPi(arr,0,1)); -#endif } ////////////////////////////////////////////////////////////////////////////////////////// @@ -424,6 +417,24 @@ static bool isInitialized(Type* et) { return true; } +////////////////////////////////////////////////////////////////////////////////////////// + +static DSliceValue *getSlice(Type *arrayType, LLValue *array) +{ + // Get ptr and length of the array + LLValue* newArrayLVal = DtoRawAlloca(array->getType(), 0, "newArray"); + DtoStore(array, newArrayLVal); + LLValue* arrayLen = DtoLoad(DtoGEPi(newArrayLVal,0,0)); + LLValue* newptr = DtoLoad(DtoGEPi(newArrayLVal,0,1)); + + // cast pointer to wanted type + const LLType* dstType = DtoType(arrayType)->getContainedType(1); + if (newptr->getType() != dstType) + newptr = DtoBitCast(newptr, dstType, ".gc_mem"); + + return new DSliceValue(arrayType, arrayLen, newptr); +} + ////////////////////////////////////////////////////////////////////////////////////////// DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit) { @@ -442,11 +453,24 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default if (defaultInit && !isInitialized(eltType)) defaultInit = false; bool zeroInit = eltType->isZeroInit(); + +#if DMDV2 + + const char* fnname = zeroInit ? "_d_newarrayT" : "_d_newarrayiT"; + LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, fnname); + + // call allocator + LLValue* newArray = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem").getInstruction(); + + return getSlice(arrayType, newArray); + +#else + const char* fnname = defaultInit ? (zeroInit ? "_d_newarrayT" : "_d_newarrayiT") : "_d_newarrayvT"; LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, fnname); // call allocator - LLValue* newptr = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem").getInstruction(); + LLValue* array = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem").getInstruction(); // cast to wanted type const LLType* dstType = DtoType(arrayType)->getContainedType(1); @@ -457,6 +481,9 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default Logger::cout() << "final ptr = " << *newptr << '\n'; return new DSliceValue(arrayType, arrayLen, newptr); + + +#endif } ////////////////////////////////////////////////////////////////////////////////////////// @@ -525,18 +552,29 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, LLValue* newdim) LLSmallVector