@@ -374,16 +374,16 @@ fn C_struct(vec[ValueRef] elts) -> ValueRef {
374
374
}
375
375
376
376
fn C_tydesc ( TypeRef t) -> ValueRef {
377
- ret C_struct ( vec ( C_null ( T_opaque ( ) ) , // first_param
378
- llvm. LLVMSizeOf ( t) , // size
379
- llvm. LLVMAlignOf ( t) , // align
380
- C_null ( T_opaque ( ) ) , // copy_glue_off
381
- C_null ( T_opaque ( ) ) , // drop_glue_off
382
- C_null ( T_opaque ( ) ) , // free_glue_off
383
- C_null ( T_opaque ( ) ) , // sever_glue_off
384
- C_null ( T_opaque ( ) ) , // mark_glue_off
385
- C_null ( T_opaque ( ) ) , // obj_drop_glue_off
386
- C_null ( T_opaque ( ) ) ) ) ; // is_stateful
377
+ ret C_struct ( vec ( C_null ( T_ptr ( T_opaque ( ) ) ) , // first_param
378
+ llvm. LLVMSizeOf ( t) , // size
379
+ llvm. LLVMAlignOf ( t) , // align
380
+ C_null ( T_ptr ( T_opaque ( ) ) ) , // copy_glue_off
381
+ C_null ( T_ptr ( T_opaque ( ) ) ) , // drop_glue_off
382
+ C_null ( T_ptr ( T_opaque ( ) ) ) , // free_glue_off
383
+ C_null ( T_ptr ( T_opaque ( ) ) ) , // sever_glue_off
384
+ C_null ( T_ptr ( T_opaque ( ) ) ) , // mark_glue_off
385
+ C_null ( T_ptr ( T_opaque ( ) ) ) , // obj_drop_glue_off
386
+ C_null ( T_ptr ( T_opaque ( ) ) ) ) ) ; // is_stateful
387
387
}
388
388
389
389
fn decl_fn ( ModuleRef llmod, str name , uint cc, TypeRef llty) -> ValueRef {
@@ -450,6 +450,19 @@ fn trans_non_gc_free(@block_ctxt cx, ValueRef v) -> result {
450
450
C_int ( 0 ) ) ) ;
451
451
}
452
452
453
+ fn trans_malloc ( @block_ctxt cx , @typeck. ty t ) -> result {
454
+ auto ptr_ty = type_of ( cx. fcx . ccx , t) ;
455
+ auto body_ty = lib. llvm . llvm . LLVMGetElementType ( ptr_ty) ;
456
+ // FIXME: need a table to collect tydesc globals.
457
+ auto tydesc = C_int ( 0 ) ;
458
+ auto sz = cx. build . IntCast ( lib. llvm . llvm . LLVMSizeOf ( body_ty) , T_int ( ) ) ;
459
+ auto sub = trans_upcall ( cx, "upcall_malloc" , vec ( sz, tydesc) ) ;
460
+ sub. val = sub. bcx . build . IntToPtr ( sub. val , ptr_ty) ;
461
+ sub. bcx . cleanups += clean ( bind drop_ty ( _, sub. val , t) ) ;
462
+ ret sub;
463
+ }
464
+
465
+
453
466
fn incr_refcnt ( @block_ctxt cx , ValueRef box_ptr) -> result {
454
467
auto rc_ptr = cx. build . GEP ( box_ptr, vec ( C_int ( 0 ) ,
455
468
C_int ( abi. box_rc_field_refcnt ) ) ) ;
@@ -636,16 +649,21 @@ fn drop_ty(@block_ctxt cx,
636
649
T_int ( ) , C_int ( 0 ) ) ;
637
650
}
638
651
639
- case ( typeck. ty_box ( _ ) ) {
652
+ case ( typeck. ty_box ( ?body_ty ) ) {
640
653
fn hit_zero ( @block_ctxt cx , ValueRef v,
641
- @typeck. ty elt_ty ) -> result {
642
- auto res = drop_ty ( cx,
643
- cx. build . GEP ( v, vec ( C_int ( 0 ) ) ) ,
644
- elt_ty) ;
654
+ @typeck. ty body_ty ) -> result {
655
+ auto body = cx. build . GEP ( v,
656
+ vec ( C_int ( 0 ) ,
657
+ C_int ( abi. box_rc_field_body ) ) ) ;
658
+
659
+ auto res = drop_ty ( cx, body, body_ty) ;
645
660
// FIXME: switch gc/non-gc on stratum of the type.
646
661
ret trans_non_gc_free ( res. bcx , v) ;
647
662
}
648
- ret incr_refcnt ( cx, v) ;
663
+ ret decr_refcnt_and_if_zero ( cx, v,
664
+ bind hit_zero ( _, v, body_ty) ,
665
+ "free box" ,
666
+ T_int ( ) , C_int ( 0 ) ) ;
649
667
}
650
668
651
669
case ( _) {
@@ -778,7 +796,7 @@ impure fn trans_lit(@block_ctxt cx, &ast.lit lit) -> result {
778
796
C_int ( len) ) ) ;
779
797
sub. val = sub. bcx . build . IntToPtr ( sub. val ,
780
798
T_ptr ( T_str ( ) ) ) ;
781
- cx. cleanups += vec ( clean ( bind trans_drop_str ( _, sub. val ) ) ) ;
799
+ cx. cleanups += clean ( bind trans_drop_str ( _, sub. val ) ) ;
782
800
ret sub;
783
801
}
784
802
}
@@ -835,13 +853,19 @@ impure fn trans_unary(@block_ctxt cx, ast.unop op,
835
853
ret sub;
836
854
}
837
855
case ( ast. box ) {
838
- auto e_ty = node_type ( cx. fcx . ccx , a) ;
839
- auto box_ty = T_box ( e_ty) ;
840
- sub. val = cx. build . Malloc ( box_ty) ;
841
- auto rc = sub. bcx . build . GEP ( sub. val ,
856
+ auto e_ty = typeck. expr_ty ( e) ;
857
+ auto e_val = sub. val ;
858
+ sub = trans_malloc ( sub. bcx , node_ann_type ( sub. bcx . fcx . ccx , a) ) ;
859
+ auto box = sub. val ;
860
+ auto rc = sub. bcx . build . GEP ( box,
842
861
vec ( C_int ( 0 ) ,
843
862
C_int ( abi. box_rc_field_refcnt ) ) ) ;
844
- ret res ( sub. bcx , cx. build . Store ( C_int ( 1 ) , rc) ) ;
863
+ auto body = sub. bcx . build . GEP ( box,
864
+ vec ( C_int ( 0 ) ,
865
+ C_int ( abi. box_rc_field_body ) ) ) ;
866
+ sub. bcx . build . Store ( C_int ( 1 ) , rc) ;
867
+ sub = copy_ty ( sub. bcx , true , body, e_val, e_ty) ;
868
+ ret res( sub. bcx , box) ;
845
869
}
846
870
case ( _) {
847
871
cx. fcx . ccx . sess . unimpl ( "expr variant in trans_unary" ) ;
0 commit comments