@@ -7,19 +7,20 @@ import trans::{call_memmove, trans_shared_malloc, llsize_of, type_of_or_i8,
7
7
incr_ptr, INIT , copy_val, load_if_immediate, alloca, size_of,
8
8
llderivedtydescs_block_ctxt, lazily_emit_tydesc_glue,
9
9
get_tydesc, load_inbounds, move_val_if_temp, trans_lval,
10
- node_id_type, new_sub_block_ctxt, tps_normal, do_spill_noroot} ;
10
+ node_id_type, new_sub_block_ctxt, tps_normal, do_spill_noroot,
11
+ GEPi , alloc_ty} ;
11
12
import trans_build:: * ;
12
13
import trans_common:: * ;
13
14
14
- fn get_fill ( bcx : & @block_ctxt , vptr : ValueRef ) -> ValueRef {
15
- Load ( bcx, InBoundsGEP ( bcx, vptr , [ C_int ( 0 ) , C_uint ( abi:: vec_elt_fill) ] ) )
15
+ fn get_fill ( bcx : & @block_ctxt , vptrptr : ValueRef ) -> ValueRef {
16
+ Load ( bcx, GEPi ( bcx, Load ( bcx , vptrptr ) , [ 0 , abi:: vec_elt_fill as int ] ) )
16
17
}
17
- fn get_alloc ( bcx : & @block_ctxt , vptr : ValueRef ) -> ValueRef {
18
- Load ( bcx, InBoundsGEP ( bcx, vptr , [ C_int ( 0 ) , C_uint ( abi:: vec_elt_alloc) ] ) )
18
+ fn get_alloc ( bcx : & @block_ctxt , vptrptr : ValueRef ) -> ValueRef {
19
+ Load ( bcx, GEPi ( bcx, Load ( bcx , vptrptr ) , [ 0 , abi:: vec_elt_alloc as int ] ) )
19
20
}
20
- fn get_dataptr ( bcx : & @block_ctxt , vpt : ValueRef , unit_ty : TypeRef ) ->
21
+ fn get_dataptr ( bcx : & @block_ctxt , vptrptr : ValueRef , unit_ty : TypeRef ) ->
21
22
ValueRef {
22
- let ptr = InBoundsGEP ( bcx, vpt , [ C_int ( 0 ) , C_uint ( abi:: vec_elt_elems) ] ) ;
23
+ let ptr = GEPi ( bcx, Load ( bcx , vptrptr ) , [ 0 , abi:: vec_elt_elems as int ] ) ;
23
24
PointerCast ( bcx, ptr, T_ptr ( unit_ty) )
24
25
}
25
26
@@ -59,17 +60,22 @@ fn alloc(bcx: &@block_ctxt, vec_ty: &ty::t, elts: uint) -> alloc_result {
59
60
let alloc = if elts < 4 u { Mul ( bcx, C_int ( 4 ) , unit_sz) } else { fill } ;
60
61
let { bcx: bcx , val : vptr } = alloc_raw ( bcx, fill, alloc) ;
61
62
let vptr = PointerCast ( bcx, vptr, T_ptr ( llvecty) ) ;
62
- add_clean_temp ( bcx, vptr, vec_ty) ;
63
+
64
+ let r = alloc_ty ( bcx, vec_ty) ;
65
+ let vptrptr = r. val ; bcx = r. bcx ;
66
+
67
+ Store ( bcx, vptr, vptrptr) ;
68
+ add_clean_temp ( bcx, vptrptr, vec_ty) ;
63
69
ret { bcx : bcx,
64
- val : vptr ,
70
+ val : vptrptr ,
65
71
unit_ty : unit_ty,
66
72
llunitsz : unit_sz,
67
73
llunitty : llunitty} ;
68
74
}
69
75
70
76
fn duplicate ( bcx : & @block_ctxt , vptrptr : ValueRef ) -> @block_ctxt {
77
+ let fill = get_fill ( bcx, vptrptr) ;
71
78
let vptr = Load ( bcx, vptrptr) ;
72
- let fill = get_fill ( bcx, vptr) ;
73
79
let size = Add ( bcx, fill, llsize_of ( T_opaque_vec ( ) ) ) ;
74
80
let { bcx: bcx , val : newptr } =
75
81
trans_shared_malloc ( bcx, val_ty ( vptr) , size) ;
@@ -135,13 +141,13 @@ fn trans_str(bcx: &@block_ctxt, s: str) -> result {
135
141
}
136
142
137
143
fn trans_append ( cx : & @block_ctxt , vec_ty : ty:: t , lhsptr : ValueRef ,
138
- rhs : ValueRef ) -> result {
144
+ rhsptr : ValueRef ) -> result {
139
145
// Cast to opaque interior vector types if necessary.
140
146
let unit_ty = ty:: sequence_element_type ( bcx_tcx ( cx) , vec_ty) ;
141
147
let dynamic = ty:: type_has_dynamic_size ( bcx_tcx ( cx) , unit_ty) ;
142
148
if dynamic {
143
149
lhsptr = PointerCast ( cx, lhsptr, T_ptr ( T_ptr ( T_opaque_vec ( ) ) ) ) ;
144
- rhs = PointerCast ( cx, rhs , T_ptr ( T_opaque_vec ( ) ) ) ;
150
+ rhsptr = PointerCast ( cx, rhsptr , T_ptr ( T_ptr ( T_opaque_vec ( ) ) ) ) ;
145
151
}
146
152
let strings =
147
153
alt ty:: struct ( bcx_tcx ( cx) , vec_ty) {
@@ -152,26 +158,26 @@ fn trans_append(cx: &@block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
152
158
let { bcx: bcx , val : unit_sz } = size_of ( cx, unit_ty) ;
153
159
let llunitty = type_of_or_i8 ( cx, unit_ty) ;
154
160
161
+ let rhs = Load ( bcx, rhsptr) ;
155
162
let lhs = Load ( bcx, lhsptr) ;
156
163
let self_append = ICmp ( bcx, lib:: llvm:: LLVMIntEQ , lhs, rhs) ;
157
- let lfill = get_fill ( bcx, lhs ) ;
158
- let rfill = get_fill ( bcx, rhs ) ;
164
+ let lfill = get_fill ( bcx, lhsptr ) ;
165
+ let rfill = get_fill ( bcx, rhsptr ) ;
159
166
let new_fill = Add ( bcx, lfill, rfill) ;
160
167
if strings { new_fill = Sub ( bcx, new_fill, C_int ( 1 ) ) ; }
161
168
let opaque_lhs = PointerCast ( bcx, lhsptr, T_ptr ( T_ptr ( T_opaque_vec ( ) ) ) ) ;
162
169
Call ( bcx, bcx_ccx ( cx) . upcalls . vec_grow ,
163
170
[ cx. fcx . lltaskptr , opaque_lhs, new_fill] ) ;
164
171
// Was overwritten if we resized
165
- let lhs = Load ( bcx, lhsptr) ;
166
- let rhs = Select ( bcx, self_append, lhs, rhs) ;
172
+ rhsptr = Select ( bcx, self_append, lhsptr, rhsptr) ;
167
173
168
- let lhs_data = get_dataptr ( bcx, lhs , llunitty) ;
174
+ let lhs_data = get_dataptr ( bcx, lhsptr , llunitty) ;
169
175
let lhs_off = lfill;
170
176
if strings { lhs_off = Sub ( bcx, lhs_off, C_int ( 1 ) ) ; }
171
177
let write_ptr = pointer_add ( bcx, lhs_data, lhs_off) ;
172
178
let write_ptr_ptr = do_spill_noroot ( bcx, write_ptr) ;
173
179
let bcx =
174
- iter_vec_raw ( bcx, rhs , vec_ty, rfill,
180
+ iter_vec_raw ( bcx, rhsptr , vec_ty, rfill,
175
181
// We have to increment by the dynamically-computed size.
176
182
{ |& bcx, addr, _ty|
177
183
let write_ptr = Load ( bcx, write_ptr_ptr) ;
@@ -211,7 +217,8 @@ fn trans_append_literal(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
211
217
ret bcx;
212
218
}
213
219
214
- fn trans_add ( bcx : & @block_ctxt , vec_ty : ty:: t , lhs : ValueRef , rhs : ValueRef )
220
+ fn trans_add ( bcx : & @block_ctxt , vec_ty : ty:: t , lhsptr : ValueRef ,
221
+ rhsptr : ValueRef )
215
222
-> result {
216
223
let strings =
217
224
alt ty:: struct ( bcx_tcx ( bcx) , vec_ty) {
@@ -222,16 +229,18 @@ fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef, rhs: ValueRef)
222
229
let llunitty = type_of_or_i8 ( bcx, unit_ty) ;
223
230
let { bcx: bcx , val : llunitsz } = size_of ( bcx, unit_ty) ;
224
231
225
- let lhs_fill = get_fill ( bcx, lhs ) ;
232
+ let lhs_fill = get_fill ( bcx, lhsptr ) ;
226
233
if strings { lhs_fill = Sub ( bcx, lhs_fill, C_int ( 1 ) ) ; }
227
- let rhs_fill = get_fill ( bcx, rhs ) ;
234
+ let rhs_fill = get_fill ( bcx, rhsptr ) ;
228
235
let new_fill = Add ( bcx, lhs_fill, rhs_fill) ;
229
- let { bcx: bcx , val : new_vec } = alloc_raw ( bcx, new_fill, new_fill) ;
230
- let new_vec = PointerCast ( bcx, new_vec, T_ptr ( T_vec ( llunitty) ) ) ;
231
- add_clean_temp ( bcx, new_vec, vec_ty) ;
236
+ let { bcx: bcx , val : new_vec_ptr } = alloc_raw ( bcx, new_fill, new_fill) ;
237
+ new_vec_ptr = PointerCast ( bcx, new_vec_ptr, T_ptr ( T_vec ( llunitty) ) ) ;
238
+ let { bcx: bcx , val : new_vec_ptr_ptr } = alloc_ty ( bcx, vec_ty) ;
239
+ Store ( bcx, new_vec_ptr, new_vec_ptr_ptr) ;
240
+ add_clean_temp ( bcx, new_vec_ptr_ptr, vec_ty) ;
232
241
233
242
let write_ptr_ptr =
234
- do_spill_noroot ( bcx, get_dataptr ( bcx, new_vec , llunitty) ) ;
243
+ do_spill_noroot ( bcx, get_dataptr ( bcx, new_vec_ptr_ptr , llunitty) ) ;
235
244
let copy_fn =
236
245
bind fn ( bcx: & @block_ctxt, addr: ValueRef , _ty: ty:: t,
237
246
write_ptr_ptr: ValueRef , unit_ty: ty:: t, llunitsz: ValueRef )
@@ -247,22 +256,22 @@ fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef, rhs: ValueRef)
247
256
ret bcx;
248
257
} ( _, _, _, write_ptr_ptr, unit_ty, llunitsz) ;
249
258
250
- let bcx = iter_vec_raw ( bcx, lhs , vec_ty, lhs_fill, copy_fn) ;
251
- let bcx = iter_vec_raw ( bcx, rhs , vec_ty, rhs_fill, copy_fn) ;
252
- ret rslt( bcx, new_vec ) ;
259
+ let bcx = iter_vec_raw ( bcx, lhsptr , vec_ty, lhs_fill, copy_fn) ;
260
+ let bcx = iter_vec_raw ( bcx, rhsptr , vec_ty, rhs_fill, copy_fn) ;
261
+ ret rslt( bcx, new_vec_ptr_ptr ) ;
253
262
}
254
263
255
264
type val_and_ty_fn = fn ( & @block_ctxt , ValueRef , ty:: t ) -> result ;
256
265
257
266
type iter_vec_block = block ( & @block_ctxt , ValueRef , ty:: t ) -> @block_ctxt ;
258
267
259
- fn iter_vec_raw ( bcx : & @block_ctxt , vptr : ValueRef , vec_ty : ty:: t ,
268
+ fn iter_vec_raw ( bcx : & @block_ctxt , vptrptr : ValueRef , vec_ty : ty:: t ,
260
269
fill : ValueRef , f : & iter_vec_block ) -> @block_ctxt {
261
270
let unit_ty = ty:: sequence_element_type ( bcx_tcx ( bcx) , vec_ty) ;
262
271
let llunitty = type_of_or_i8 ( bcx, unit_ty) ;
263
272
let { bcx: bcx , val : unit_sz } = size_of ( bcx, unit_ty) ;
264
- let vptr = PointerCast ( bcx, vptr , T_ptr ( T_vec ( llunitty) ) ) ;
265
- let data_ptr = get_dataptr ( bcx, vptr , llunitty) ;
273
+ vptrptr = PointerCast ( bcx, vptrptr , T_ptr ( T_ptr ( T_vec ( llunitty) ) ) ) ;
274
+ let data_ptr = get_dataptr ( bcx, vptrptr , llunitty) ;
266
275
267
276
// Calculate the last pointer address we want to handle.
268
277
// TODO: Optimize this when the size of the unit type is statically
@@ -292,9 +301,8 @@ fn iter_vec_raw(bcx: &@block_ctxt, vptr: ValueRef, vec_ty: ty::t,
292
301
293
302
fn iter_vec ( bcx : & @block_ctxt , vptrptr : ValueRef , vec_ty : ty:: t ,
294
303
f : & iter_vec_block ) -> @block_ctxt {
295
- let vptr =
296
- Load ( bcx, PointerCast ( bcx, vptrptr, T_ptr ( T_ptr ( T_opaque_vec ( ) ) ) ) ) ;
297
- ret iter_vec_raw ( bcx, vptr, vec_ty, get_fill ( bcx, vptr) , f) ;
304
+ vptrptr = PointerCast ( bcx, vptrptr, T_ptr ( T_ptr ( T_opaque_vec ( ) ) ) ) ;
305
+ ret iter_vec_raw ( bcx, vptrptr, vec_ty, get_fill ( bcx, vptrptr) , f) ;
298
306
}
299
307
300
308
//
0 commit comments