@@ -27,6 +27,7 @@ use middle::ty;
2727use util:: common:: indenter;
2828use util:: ppaux:: ty_to_str;
2929
30+ use core:: option:: None ;
3031use core:: uint;
3132use core:: vec;
3233use syntax:: ast;
@@ -413,30 +414,57 @@ pub fn write_content(bcx: block,
413414 return bcx;
414415 }
415416
416- let tmpdatum = unpack_datum ! ( bcx, {
417+ // Some cleanup would be required in the case in which failure happens
418+ // during a copy. But given that copy constructors are not overridable,
419+ // this can only happen as a result of OOM. So we just skip out on the
420+ // cleanup since things would *probably* be broken at that point anyways.
421+
422+ let elem = unpack_datum ! ( bcx, {
417423 expr:: trans_to_datum( bcx, element)
418424 } ) ;
419425
420- let mut temp_cleanups = ~[ ] ;
426+ let next_bcx = sub_block ( bcx, ~"expr_repeat: while next") ;
427+ let loop_bcx = loop_scope_block ( bcx, next_bcx, None , ~"expr_repeat", None ) ;
428+ let cond_bcx = scope_block ( loop_bcx, None , ~"expr_repeat: loop cond") ;
429+ let set_bcx = scope_block ( loop_bcx, None , ~"expr_repeat: body: set") ;
430+ let inc_bcx = scope_block ( loop_bcx, None , ~"expr_repeat: body: inc") ;
431+ Br ( bcx, loop_bcx. llbb ) ;
421432
422- for uint:: range( 0 , count) |i| {
423- let lleltptr = GEPi ( bcx, lldest, [ i] ) ;
424- if i < count - 1 {
425- // Copy all but the last one in.
426- bcx = tmpdatum. copy_to ( bcx, INIT , lleltptr) ;
427- } else {
428- // Move the last one in.
429- bcx = tmpdatum. move_to ( bcx, INIT , lleltptr) ;
430- }
431- add_clean_temp_mem ( bcx, lleltptr, vt. unit_ty ) ;
432- temp_cleanups. push ( lleltptr) ;
433+ let loop_counter = {
434+ // i = 0
435+ let i = alloca ( loop_bcx, bcx. ccx ( ) . int_type ) ;
436+ Store ( loop_bcx, C_uint ( bcx. ccx ( ) , 0 ) , i) ;
437+
438+ Br ( loop_bcx, cond_bcx. llbb ) ;
439+ i
440+ } ;
441+
442+ { // i < count
443+ let lhs = Load ( cond_bcx, loop_counter) ;
444+ let rhs = C_uint ( bcx. ccx ( ) , count) ;
445+ let cond_val = ICmp ( cond_bcx, lib:: llvm:: IntULT , lhs, rhs) ;
446+
447+ CondBr ( cond_bcx, cond_val, set_bcx. llbb , next_bcx. llbb ) ;
433448 }
434449
435- for vec:: each( temp_cleanups) |cleanup| {
436- revoke_clean( bcx, * cleanup) ;
450+ { // v[i] = elem
451+ let i = Load ( set_bcx, loop_counter) ;
452+ let lleltptr = InBoundsGEP ( set_bcx, lldest, [ i] ) ;
453+ let set_bcx = elem. copy_to ( set_bcx, INIT , lleltptr) ;
454+
455+ Br ( set_bcx, inc_bcx. llbb ) ;
437456 }
438457
439- return bcx;
458+ { // i += 1
459+ let i = Load ( inc_bcx, loop_counter) ;
460+ let plusone = Add ( inc_bcx, i, C_uint ( bcx. ccx ( ) , 1 ) ) ;
461+ Store ( inc_bcx, plusone, loop_counter) ;
462+
463+ Br ( inc_bcx, cond_bcx. llbb ) ;
464+ }
465+
466+ return next_bcx;
467+
440468 }
441469 }
442470 }
0 commit comments