comparison druntime/src/compiler/ldc/arrayassign.d @ 1458:e0b2d67cfe7c

Added druntime (this should be removed once it works).
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 02 Jun 2009 17:43:06 +0100
parents
children
comparison
equal deleted inserted replaced
1456:7b218ec1044f 1458:e0b2d67cfe7c
1 /**
2 * Implementation of array assignment support routines.
3 *
4 * Copyright: Copyright Digital Mars 2000 - 2009.
5 * License: <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>.
6 * Authors: Walter Bright
7 *
8 * Copyright Digital Mars 2000 - 2009.
9 * Distributed under the Boost Software License, Version 1.0.
10 * (See accompanying file LICENSE_1_0.txt or copy at
11 * http://www.boost.org/LICENSE_1_0.txt)
12 */
13 module rt.arrayassign;
14
15 private
16 {
17 import rt.util.string;
18 import core.stdc.string;
19 import core.stdc.stdlib;
20 debug(PRINTF) import core.stdc.stdio;
21 }
22
23 /**
24 * Does array assignment (not construction) from another
25 * array of the same element type.
26 * ti is the element type.
27 * Handles overlapping copies.
28 */
29 extern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to)
30 {
31 debug(PRINTF) printf("_d_arrayassign(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize());
32
33 if (to.length != from.length)
34 {
35 char[10] tmp = void;
36 string msg = "lengths don't match for array copy,"c;
37 msg ~= tmp.intToString(to.length) ~ " = " ~ tmp.intToString(from.length);
38 throw new Exception(msg);
39 }
40
41 auto element_size = ti.tsize();
42
43 /* Need a temporary buffer tmp[] big enough to hold one element
44 */
45 void[16] buf = void;
46 void[] tmp;
47 if (element_size > buf.sizeof)
48 tmp = alloca(element_size)[0 .. element_size];
49 else
50 tmp = buf;
51
52
53 if (to.ptr <= from.ptr)
54 {
55 foreach (i; 0 .. to.length)
56 {
57 void* pto = to.ptr + i * element_size;
58 void* pfrom = from.ptr + i * element_size;
59 memcpy(tmp.ptr, pto, element_size);
60 memcpy(pto, pfrom, element_size);
61 ti.postblit(pto);
62 ti.destroy(tmp.ptr);
63 }
64 }
65 else
66 {
67 for (int i = to.length; i--; )
68 {
69 void* pto = to.ptr + i * element_size;
70 void* pfrom = from.ptr + i * element_size;
71 memcpy(tmp.ptr, pto, element_size);
72 memcpy(pto, pfrom, element_size);
73 ti.postblit(pto);
74 ti.destroy(tmp.ptr);
75 }
76 }
77 return to;
78 }
79
80 /**
81 * Does array initialization (not assignment) from another
82 * array of the same element type.
83 * ti is the element type.
84 */
85 extern (C) void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to)
86 {
87 debug(PRINTF) printf("_d_arrayctor(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize());
88
89 if (to.length != from.length)
90 {
91 char[10] tmp = void;
92 string msg = "lengths don't match for array initialization,"c;
93 msg ~= tmp.intToString(to.length) ~ " = " ~ tmp.intToString(from.length);
94 throw new Exception(msg);
95 }
96
97 auto element_size = ti.tsize();
98
99 int i;
100 try
101 {
102 for (i = 0; i < to.length; i++)
103 {
104 // Copy construction is defined as bit copy followed by postblit.
105 memcpy(to.ptr + i * element_size, from.ptr + i * element_size, element_size);
106 ti.postblit(to.ptr + i * element_size);
107 }
108 }
109 catch (Object o)
110 {
111 /* Destroy, in reverse order, what we've constructed so far
112 */
113 while (i--)
114 {
115 ti.destroy(to.ptr + i * element_size);
116 }
117
118 throw o;
119 }
120 return to;
121 }
122
123
124 /**
125 * Do assignment to an array.
126 * p[0 .. count] = value;
127 */
128 extern (C) void* _d_arraysetassign(void* p, void* value, int count, TypeInfo ti)
129 {
130 void* pstart = p;
131
132 auto element_size = ti.tsize();
133
134 //Need a temporary buffer tmp[] big enough to hold one element
135 void[16] buf = void;
136 void[] tmp;
137 if (element_size > buf.sizeof)
138 {
139 tmp = alloca(element_size)[0 .. element_size];
140 }
141 else
142 tmp = buf;
143
144 foreach (i; 0 .. count)
145 {
146 memcpy(tmp.ptr, p, element_size);
147 memcpy(p, value, element_size);
148 ti.postblit(p);
149 ti.destroy(tmp.ptr);
150 p += element_size;
151 }
152 return pstart;
153 }
154
155 /**
156 * Do construction of an array.
157 * ti[count] p = value;
158 */
159 extern (C) void* _d_arraysetctor(void* p, void* value, int count, TypeInfo ti)
160 {
161 void* pstart = p;
162 auto element_size = ti.tsize();
163
164 try
165 {
166 foreach (i; 0 .. count)
167 {
168 // Copy construction is defined as bit copy followed by postblit.
169 memcpy(p, value, element_size);
170 ti.postblit(p);
171 p += element_size;
172 }
173 }
174 catch (Object o)
175 {
176 // Destroy, in reverse order, what we've constructed so far
177 while (p > pstart)
178 {
179 p -= element_size;
180 ti.destroy(p);
181 }
182
183 throw o;
184 }
185 return pstart;
186 }