Mercurial > projects > ldc
diff druntime/src/compiler/dmd/arrayassign.d @ 759:d3eb054172f9
Added copy of druntime from DMD 2.020 modified for LDC.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 11 Nov 2008 01:52:37 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/druntime/src/compiler/dmd/arrayassign.d Tue Nov 11 01:52:37 2008 +0100 @@ -0,0 +1,180 @@ +/** + * Part of the D programming language runtime library. + * http://www.digitalmars.com + * Written by Walter Bright + * Placed in the Public Domain + */ +module rt.arrayassign; + +private +{ + import util.string; + import stdc.string; + import stdc.stdlib; + debug(PRINTF) import stdc.stdio; +} + +/** + * Does array assignment (not construction) from another + * array of the same element type. + * ti is the element type. + * Handles overlapping copies. + */ +extern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to) +{ + debug(PRINTF) printf("_d_arrayassign(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize()); + + if (to.length != from.length) + { + char[10] tmp = void; + string msg = "lengths don't match for array copy,"c; + msg ~= tmp.intToString(to.length) ~ " = " ~ tmp.intToString(from.length); + throw new Exception(msg); + } + + auto element_size = ti.tsize(); + + /* Need a temporary buffer tmp[] big enough to hold one element + */ + void[16] buf = void; + void[] tmp; + if (element_size > buf.sizeof) + tmp = alloca(element_size)[0 .. element_size]; + else + tmp = buf; + + + if (to.ptr <= from.ptr) + { + foreach (i; 0 .. to.length) + { + void* pto = to.ptr + i * element_size; + void* pfrom = from.ptr + i * element_size; + memcpy(tmp.ptr, pto, element_size); + memcpy(pto, pfrom, element_size); + ti.postblit(pto); + ti.destroy(tmp.ptr); + } + } + else + { + for (int i = to.length; i--; ) + { + void* pto = to.ptr + i * element_size; + void* pfrom = from.ptr + i * element_size; + memcpy(tmp.ptr, pto, element_size); + memcpy(pto, pfrom, element_size); + ti.postblit(pto); + ti.destroy(tmp.ptr); + } + } + return to; +} + +/** + * Does array initialization (not assignment) from another + * array of the same element type. + * ti is the element type. + */ +extern (C) void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to) +{ + debug(PRINTF) printf("_d_arrayctor(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize()); + + if (to.length != from.length) + { + char[10] tmp = void; + string msg = "lengths don't match for array initialization,"c; + msg ~= tmp.intToString(to.length) ~ " = " ~ tmp.intToString(from.length); + throw new Exception(msg); + } + + auto element_size = ti.tsize(); + + int i; + try + { + for (i = 0; i < to.length; i++) + { + // Copy construction is defined as bit copy followed by postblit. + memcpy(to.ptr + i * element_size, from.ptr + i * element_size, element_size); + ti.postblit(to.ptr + i * element_size); + } + } + catch (Object o) + { + /* Destroy, in reverse order, what we've constructed so far + */ + while (i--) + { + ti.destroy(to.ptr + i * element_size); + } + + throw o; + } + return to; +} + + +/** + * Do assignment to an array. + * p[0 .. count] = value; + */ +extern (C) void* _d_arraysetassign(void* p, void* value, int count, TypeInfo ti) +{ + void* pstart = p; + + auto element_size = ti.tsize(); + + //Need a temporary buffer tmp[] big enough to hold one element + void[16] buf = void; + void[] tmp; + if (element_size > buf.sizeof) + { + tmp = alloca(element_size)[0 .. element_size]; + } + else + tmp = buf; + + foreach (i; 0 .. count) + { + memcpy(tmp.ptr, p, element_size); + memcpy(p, value, element_size); + ti.postblit(p); + ti.destroy(tmp.ptr); + p += element_size; + } + return pstart; +} + +/** + * Do construction of an array. + * ti[count] p = value; + */ +extern (C) void* _d_arraysetctor(void* p, void* value, int count, TypeInfo ti) +{ + void* pstart = p; + auto element_size = ti.tsize(); + + try + { + foreach (i; 0 .. count) + { + // Copy construction is defined as bit copy followed by postblit. + memcpy(p, value, element_size); + ti.postblit(p); + p += element_size; + } + } + catch (Object o) + { + // Destroy, in reverse order, what we've constructed so far + while (p > pstart) + { + p -= element_size; + ti.destroy(p); + } + + throw o; + } + return pstart; +}