@@ -298,7 +298,9 @@ fn T_closure_ptr(TypeRef lltarget_ty,
298
298
}
299
299
300
300
fn T_opaque_closure_ptr ( ) -> TypeRef {
301
- ret T_ptr ( T_box ( T_nil ( ) ) ) ;
301
+ ret T_closure_ptr ( T_struct ( vec ( T_ptr ( T_nil ( ) ) ,
302
+ T_ptr ( T_nil ( ) ) ) ) ,
303
+ T_nil ( ) ) ;
302
304
}
303
305
304
306
@@ -849,6 +851,50 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
849
851
T_int ( ) , C_int ( 0 ) ) ;
850
852
}
851
853
854
+ case ( ty. ty_fn ( _, _) ) {
855
+ fn hit_zero ( @block_ctxt cx , ValueRef v) -> result {
856
+
857
+ // Call through the closure's own fields-drop glue first.
858
+ auto body =
859
+ cx. build . GEP ( v,
860
+ vec ( C_int ( 0 ) ,
861
+ C_int ( abi. box_rc_field_body ) ) ) ;
862
+
863
+ auto bindings =
864
+ cx. build . GEP ( body,
865
+ vec ( C_int ( 0 ) ,
866
+ C_int ( abi. closure_elt_bindings ) ) ) ;
867
+ auto llrawptr = cx. build . BitCast ( bindings, T_ptr ( T_i8 ( ) ) ) ;
868
+
869
+ auto tydescptr =
870
+ cx. build . GEP ( body,
871
+ vec ( C_int ( 0 ) ,
872
+ C_int ( abi. closure_elt_tydesc ) ) ) ;
873
+ auto tydesc = cx. build . Load ( tydescptr) ;
874
+ auto llfnptr =
875
+ cx. build . GEP ( tydesc,
876
+ vec ( C_int ( 0 ) ,
877
+ C_int ( abi. tydesc_field_drop_glue_off ) ) ) ;
878
+ auto llfn = cx. build . Load ( llfnptr) ;
879
+ cx. build . FastCall ( llfn, vec ( cx. fcx . lltaskptr , llrawptr) ) ;
880
+
881
+ // Then free the body.
882
+ // FIXME: switch gc/non-gc on layer of the type.
883
+ ret trans_non_gc_free ( cx, v) ;
884
+ }
885
+ auto box_cell =
886
+ cx. build . GEP ( v,
887
+ vec ( C_int ( 0 ) ,
888
+ C_int ( abi. fn_field_box ) ) ) ;
889
+
890
+ auto boxptr = cx. build . Load ( box_cell) ;
891
+
892
+ ret decr_refcnt_and_if_zero ( cx, boxptr,
893
+ bind hit_zero ( _, boxptr) ,
894
+ "free fn" ,
895
+ T_int ( ) , C_int ( 0 ) ) ;
896
+ }
897
+
852
898
case ( _) {
853
899
if ( ty. type_is_structural ( t) ) {
854
900
ret iter_structural_ty ( cx, v, t,
@@ -2145,13 +2191,11 @@ impure fn trans_bind(@block_ctxt cx, @ast.expr f,
2145
2191
auto pair_code = bcx. build. GEP ( pair_v,
2146
2192
vec( C_int ( 0 ) ,
2147
2193
C_int ( abi. fn_field_code) ) ) ;
2194
+
2195
+ let @ty. t pair_ty = node_ann_type( cx. fcx. ccx, ann) ;
2148
2196
let ValueRef llthunk =
2149
- trans_bind_thunk( cx. fcx. ccx,
2150
- node_ann_type( cx. fcx. ccx, ann) ,
2151
- ty. expr_ty( f) ,
2152
- args,
2153
- llclosure_ty,
2154
- bound_tys) ;
2197
+ trans_bind_thunk( cx. fcx. ccx, pair_ty, ty. expr_ty( f) ,
2198
+ args, llclosure_ty, bound_tys) ;
2155
2199
2156
2200
bcx. build. Store ( llthunk, pair_code) ;
2157
2201
@@ -2163,6 +2207,9 @@ impure fn trans_bind(@block_ctxt cx, @ast.expr f,
2163
2207
T_opaque_closure_ptr ( ) ) ,
2164
2208
pair_box) ;
2165
2209
2210
+ find_scope_cx( cx) . cleanups +=
2211
+ clean( bind drop_slot( _, pair_v, pair_ty) ) ;
2212
+
2166
2213
ret res( bcx, pair_v) ;
2167
2214
}
2168
2215
}
0 commit comments