@@ -91,7 +91,7 @@ fn type_of_fn(cx: @crate_ctxt, inputs: [ty::arg],
91
91
atys += [ out_ty] ;
92
92
93
93
// Arg 1: Environment
94
- atys += [ T_opaque_cbox_ptr ( cx) ] ;
94
+ atys += [ T_opaque_box_ptr ( cx) ] ;
95
95
96
96
// Args >2: ty params, if not acquired via capture...
97
97
for bounds in params {
@@ -193,7 +193,7 @@ fn type_of_inner(cx: @crate_ctxt, t: ty::t)
193
193
T_struct ( tys)
194
194
}
195
195
ty:: ty_opaque_closure_ptr ( _) {
196
- T_opaque_cbox_ptr ( cx)
196
+ T_opaque_box_ptr ( cx)
197
197
}
198
198
ty:: ty_constr ( subt, _) {
199
199
// FIXME: could be a constraint on ty_fn
@@ -764,54 +764,54 @@ fn trans_shared_malloc(cx: @block_ctxt, llptr_ty: TypeRef, llsize: ValueRef)
764
764
ret rslt( cx, PointerCast ( cx, rval, llptr_ty) ) ;
765
765
}
766
766
767
- // trans_malloc_boxed_raw: expects an unboxed type and returns a pointer to
768
- // enough space for something of that type, along with space for a reference
769
- // count; in other words, it allocates a box for something of that type.
770
- fn trans_malloc_boxed_raw ( cx : @block_ctxt , t : ty:: t ) -> result {
771
- let bcx = cx;
772
-
773
- // Synthesize a fake box type structurally so we have something
774
- // to measure the size of.
775
-
776
- // We synthesize two types here because we want both the type of the
777
- // pointer and the pointee. boxed_body is the type that we measure the
778
- // size of; box_ptr is the type that's converted to a TypeRef and used as
779
- // the pointer cast target in trans_raw_malloc.
767
+ // Returns a pointer to the body for the box. The box may be an opaque
768
+ // box. The result will be casted to the type of body_t, if it is statically
769
+ // known.
770
+ //
771
+ // The runtime equivalent is box_body() in "rust_internal.h".
772
+ fn opaque_box_body ( bcx : @block_ctxt ,
773
+ body_t : ty:: t ,
774
+ boxptr : ValueRef ) -> ValueRef {
775
+ let ccx = bcx_ccx ( bcx) ;
776
+ let boxptr = PointerCast ( bcx, boxptr, T_ptr ( T_box_header ( ccx) ) ) ;
777
+ let bodyptr = GEPi ( bcx, boxptr, [ 1 ] ) ;
778
+ if check type_has_static_size ( ccx, body_t) {
779
+ PointerCast ( bcx, bodyptr, T_ptr ( type_of ( ccx, body_t) ) )
780
+ } else {
781
+ PointerCast ( bcx, bodyptr, T_ptr ( T_i8 ( ) ) )
782
+ }
783
+ }
780
784
781
- // The mk_int here is the space being
782
- // reserved for the refcount.
783
- let boxed_body = ty:: mk_tup ( bcx_tcx ( bcx) , [ ty:: mk_int ( bcx_tcx ( cx) ) , t] ) ;
784
- let box_ptr = ty:: mk_imm_box ( bcx_tcx ( bcx) , t) ;
785
- let r = size_of ( cx, boxed_body) ;
786
- let llsz = r. val ; bcx = r. bcx ;
785
+ // trans_malloc_boxed_raw: expects an unboxed type and returns a pointer to
786
+ // enough space for a box of that type. This includes a rust_opaque_box
787
+ // header.
788
+ fn trans_malloc_boxed_raw ( bcx : @block_ctxt , t : ty:: t ,
789
+ & static_ti: option < @tydesc_info > ) -> result {
790
+ let bcx = bcx;
791
+ let ccx = bcx_ccx ( bcx) ;
787
792
788
793
// Grab the TypeRef type of box_ptr, because that's what trans_raw_malloc
789
794
// wants.
790
- // FIXME: Could avoid this check with a postcondition on mk_imm_box?
791
- // (requires Issue #586)
792
- let ccx = bcx_ccx ( bcx) ;
795
+ let box_ptr = ty:: mk_imm_box ( bcx_tcx ( bcx) , t) ;
793
796
check ( type_has_static_size ( ccx, box_ptr) ) ;
794
797
let llty = type_of ( ccx, box_ptr) ;
795
798
796
- let ti = none;
797
- let tydesc_result = get_tydesc ( bcx, t, true , ti) ;
798
- let lltydesc = tydesc_result. result . val ; bcx = tydesc_result. result . bcx ;
799
+ // Get the tydesc for the body:
800
+ let { bcx, val: lltydesc } = get_tydesc ( bcx, t, true , static_ti) . result ;
799
801
800
- let rval = Call ( cx , ccx . upcalls . malloc ,
801
- [ llsz , lltydesc] ) ;
802
- ret rslt( cx , PointerCast ( cx , rval, llty) ) ;
802
+ // Allocate space:
803
+ let rval = Call ( bcx , ccx . upcalls . malloc , [ lltydesc] ) ;
804
+ ret rslt( bcx , PointerCast ( bcx , rval, llty) ) ;
803
805
}
804
806
805
807
// trans_malloc_boxed: usefully wraps trans_malloc_box_raw; allocates a box,
806
808
// initializes the reference count to 1, and pulls out the body and rc
807
- fn trans_malloc_boxed ( cx : @block_ctxt , t : ty:: t ) ->
809
+ fn trans_malloc_boxed ( bcx : @block_ctxt , t : ty:: t ) ->
808
810
{ bcx : @block_ctxt , box : ValueRef , body : ValueRef } {
809
- let res = trans_malloc_boxed_raw ( cx, t) ;
810
- let box = res. val ;
811
- let rc = GEPi ( res. bcx , box, [ 0 , abi:: box_rc_field_refcnt] ) ;
812
- Store ( res. bcx , C_int ( bcx_ccx ( cx) , 1 ) , rc) ;
813
- let body = GEPi ( res. bcx , box, [ 0 , abi:: box_rc_field_body] ) ;
814
- ret { bcx : res. bcx , box : res. val , body : body} ;
811
+ let ti = none;
812
+ let { bcx, val: box } = trans_malloc_boxed_raw ( bcx, t, ti) ;
813
+ let body = GEPi ( bcx, box, [ 0 , abi:: box_field_body] ) ;
814
+ ret { bcx : bcx, box : box, body : body} ;
815
815
}
816
816
817
817
// Type descriptor and type glue stuff
@@ -1231,8 +1231,8 @@ fn make_take_glue(cx: @block_ctxt, v: ValueRef, t: ty::t) {
1231
1231
1232
1232
fn incr_refcnt_of_boxed ( cx : @block_ctxt , box_ptr : ValueRef ) -> @block_ctxt {
1233
1233
let ccx = bcx_ccx ( cx) ;
1234
- let rc_ptr =
1235
- GEPi ( cx, box_ptr, [ 0 , abi:: box_rc_field_refcnt ] ) ;
1234
+ maybe_validate_box ( cx , box_ptr ) ;
1235
+ let rc_ptr = GEPi ( cx, box_ptr, [ 0 , abi:: box_field_refcnt ] ) ;
1236
1236
let rc = Load ( cx, rc_ptr) ;
1237
1237
rc = Add ( cx, rc, C_int ( ccx, 1 ) ) ;
1238
1238
Store ( cx, rc, rc_ptr) ;
@@ -1243,7 +1243,7 @@ fn free_box(bcx: @block_ctxt, v: ValueRef, t: ty::t) -> @block_ctxt {
1243
1243
ret alt ty:: struct ( bcx_tcx ( bcx) , t) {
1244
1244
ty:: ty_box ( body_mt) {
1245
1245
let v = PointerCast ( bcx, v, type_of_1 ( bcx, t) ) ;
1246
- let body = GEPi ( bcx, v, [ 0 , abi:: box_rc_field_body ] ) ;
1246
+ let body = GEPi ( bcx, v, [ 0 , abi:: box_field_body ] ) ;
1247
1247
let bcx = drop_ty ( bcx, body, body_mt. ty ) ;
1248
1248
trans_free_if_not_gc ( bcx, v)
1249
1249
}
@@ -1274,7 +1274,7 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) {
1274
1274
let ccx = bcx_ccx ( bcx) ;
1275
1275
let llbox_ty = T_opaque_iface_ptr ( ccx) ;
1276
1276
let b = PointerCast ( bcx, v, llbox_ty) ;
1277
- let body = GEPi ( bcx, b, [ 0 , abi:: box_rc_field_body ] ) ;
1277
+ let body = GEPi ( bcx, b, [ 0 , abi:: box_field_body ] ) ;
1278
1278
let tydescptr = GEPi ( bcx, body, [ 0 , 0 ] ) ;
1279
1279
let tydesc = Load ( bcx, tydescptr) ;
1280
1280
let ti = none;
@@ -1375,18 +1375,31 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id,
1375
1375
ret next_cx;
1376
1376
}
1377
1377
1378
+ fn maybe_validate_box ( _cx : @block_ctxt , _box_ptr : ValueRef ) {
1379
+ // Uncomment this when debugging annoying use-after-free
1380
+ // bugs. But do not commit with this uncommented! Big performance hit.
1381
+
1382
+ // let cx = _cx, box_ptr = _box_ptr;
1383
+ // let ccx = bcx_ccx(cx);
1384
+ // warn_not_to_commit(ccx, "validate_box() is uncommented");
1385
+ // let raw_box_ptr = PointerCast(cx, box_ptr, T_ptr(T_i8()));
1386
+ // Call(cx, ccx.upcalls.validate_box, [raw_box_ptr]);
1387
+ }
1388
+
1378
1389
fn decr_refcnt_maybe_free ( cx : @block_ctxt , box_ptr : ValueRef , t : ty:: t )
1379
1390
-> @block_ctxt {
1380
1391
let ccx = bcx_ccx ( cx) ;
1392
+
1393
+ maybe_validate_box ( cx, box_ptr) ;
1394
+
1381
1395
let rc_adj_cx = new_sub_block_ctxt ( cx, "rc--" ) ;
1382
1396
let free_cx = new_sub_block_ctxt ( cx, "free" ) ;
1383
1397
let next_cx = new_sub_block_ctxt ( cx, "next" ) ;
1384
1398
let llbox_ty = T_opaque_iface_ptr ( ccx) ;
1385
1399
let box_ptr = PointerCast ( cx, box_ptr, llbox_ty) ;
1386
1400
let null_test = IsNull ( cx, box_ptr) ;
1387
1401
CondBr ( cx, null_test, next_cx. llbb , rc_adj_cx. llbb ) ;
1388
- let rc_ptr =
1389
- GEPi ( rc_adj_cx, box_ptr, [ 0 , abi:: box_rc_field_refcnt] ) ;
1402
+ let rc_ptr = GEPi ( rc_adj_cx, box_ptr, [ 0 , abi:: box_field_refcnt] ) ;
1390
1403
let rc = Load ( rc_adj_cx, rc_ptr) ;
1391
1404
rc = Sub ( rc_adj_cx, rc, C_int ( ccx, 1 ) ) ;
1392
1405
Store ( rc_adj_cx, rc, rc_ptr) ;
@@ -1397,7 +1410,6 @@ fn decr_refcnt_maybe_free(cx: @block_ctxt, box_ptr: ValueRef, t: ty::t)
1397
1410
ret next_cx;
1398
1411
}
1399
1412
1400
-
1401
1413
// Structural comparison: a rather involved form of glue.
1402
1414
fn maybe_name_value ( cx : @crate_ctxt , v : ValueRef , s : str ) {
1403
1415
if cx. sess . opts . save_temps {
@@ -2208,7 +2220,7 @@ fn autoderef(cx: @block_ctxt, v: ValueRef, t: ty::t) -> result_t {
2208
2220
while true {
2209
2221
alt ty:: struct ( ccx. tcx , t1) {
2210
2222
ty:: ty_box ( mt) {
2211
- let body = GEPi ( cx, v1, [ 0 , abi:: box_rc_field_body ] ) ;
2223
+ let body = GEPi ( cx, v1, [ 0 , abi:: box_field_body ] ) ;
2212
2224
t1 = mt. ty ;
2213
2225
2214
2226
// Since we're changing levels of box indirection, we may have
@@ -2514,7 +2526,7 @@ type lval_maybe_callee = {bcx: @block_ctxt,
2514
2526
generic : option < generic_info > } ;
2515
2527
2516
2528
fn null_env_ptr ( bcx : @block_ctxt ) -> ValueRef {
2517
- C_null ( T_opaque_cbox_ptr ( bcx_ccx ( bcx) ) )
2529
+ C_null ( T_opaque_box_ptr ( bcx_ccx ( bcx) ) )
2518
2530
}
2519
2531
2520
2532
fn lval_from_local_var ( bcx : @block_ctxt , r : local_var_result ) -> lval_result {
@@ -2790,7 +2802,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
2790
2802
let val =
2791
2803
alt ty:: struct ( ccx. tcx , t) {
2792
2804
ty:: ty_box ( _) {
2793
- GEPi ( sub. bcx , sub. val , [ 0 , abi:: box_rc_field_body ] )
2805
+ GEPi ( sub. bcx , sub. val , [ 0 , abi:: box_field_body ] )
2794
2806
}
2795
2807
ty:: ty_res ( _, _, _) {
2796
2808
GEPi ( sub. bcx , sub. val , [ 0 , 1 ] )
@@ -3160,7 +3172,7 @@ fn trans_call_inner(in_cx: @block_ctxt, fn_expr_ty: ty::t,
3160
3172
let llenv, dict_param = none;
3161
3173
alt f_res. env {
3162
3174
null_env {
3163
- llenv = llvm:: LLVMGetUndef ( T_opaque_cbox_ptr ( bcx_ccx ( cx) ) ) ;
3175
+ llenv = llvm:: LLVMGetUndef ( T_opaque_box_ptr ( bcx_ccx ( cx) ) ) ;
3164
3176
}
3165
3177
self_env ( e) { llenv = e; }
3166
3178
dict_env ( dict, e) { llenv = e; dict_param = some ( dict) ; }
@@ -3465,6 +3477,8 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
3465
3477
let tcx = bcx_tcx ( bcx) ;
3466
3478
debuginfo:: update_source_pos ( bcx, e. span ) ;
3467
3479
3480
+ #debug[ "trans_expr(%s,%?)" , expr_to_str ( e) , dest] ;
3481
+
3468
3482
if expr_is_lval ( bcx, e) {
3469
3483
ret lval_to_dps ( bcx, e, dest) ;
3470
3484
}
@@ -3998,6 +4012,8 @@ fn zero_alloca(cx: @block_ctxt, llptr: ValueRef, t: ty::t)
3998
4012
}
3999
4013
4000
4014
fn trans_stmt ( cx : @block_ctxt , s : ast:: stmt ) -> @block_ctxt {
4015
+ #debug[ "trans_expr(%s)" , stmt_to_str ( s) ] ;
4016
+
4001
4017
if ( !bcx_ccx ( cx) . sess . opts . no_asm_comments ) {
4002
4018
add_span_comment ( cx, s. span , stmt_to_str ( s) ) ;
4003
4019
}
@@ -5122,8 +5138,7 @@ fn fill_fn_pair(bcx: @block_ctxt, pair: ValueRef, llfn: ValueRef,
5122
5138
let code_cell = GEPi ( bcx, pair, [ 0 , abi:: fn_field_code] ) ;
5123
5139
Store ( bcx, llfn, code_cell) ;
5124
5140
let env_cell = GEPi ( bcx, pair, [ 0 , abi:: fn_field_box] ) ;
5125
- let llenvblobptr =
5126
- PointerCast ( bcx, llenvptr, T_opaque_cbox_ptr ( ccx) ) ;
5141
+ let llenvblobptr = PointerCast ( bcx, llenvptr, T_opaque_box_ptr ( ccx) ) ;
5127
5142
Store ( bcx, llenvblobptr, env_cell) ;
5128
5143
}
5129
5144
@@ -5591,7 +5606,8 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
5591
5606
shape_cx: shape:: mk_ctxt ( llmod) ,
5592
5607
gc_cx: gc:: mk_ctxt ( ) ,
5593
5608
crate_map: crate_map,
5594
- dbg_cx: dbg_cx} ;
5609
+ dbg_cx: dbg_cx,
5610
+ mutable do_not_commit_warning_issued: false } ;
5595
5611
let cx = new_local_ctxt ( ccx) ;
5596
5612
collect_items ( ccx, crate ) ;
5597
5613
trans_constants ( ccx, crate ) ;
0 commit comments