diff options
| author | Graydon Hoare <[email protected]> | 2011-01-07 16:26:30 -0800 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-01-07 16:26:30 -0800 |
| commit | 3b0e207109ba135e94264cef17bac989574ccb0b (patch) | |
| tree | 3a3f388b4b37bd34233ba3f721d42da08747e923 /src/comp/middle | |
| parent | Add sufficient import support to compile some simple single-crate programs. (diff) | |
| download | rust-3b0e207109ba135e94264cef17bac989574ccb0b.tar.xz rust-3b0e207109ba135e94264cef17bac989574ccb0b.zip | |
Drop closures. Un-XFAIL bind-interior.rs.
Diffstat (limited to 'src/comp/middle')
| -rw-r--r-- | src/comp/middle/trans.rs | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index f81c2bb4..50571879 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -298,7 +298,9 @@ fn T_closure_ptr(TypeRef lltarget_ty, } fn T_opaque_closure_ptr() -> TypeRef { - ret T_ptr(T_box(T_nil())); + ret T_closure_ptr(T_struct(vec(T_ptr(T_nil()), + T_ptr(T_nil()))), + T_nil()); } @@ -849,6 +851,50 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result { T_int(), C_int(0)); } + case (ty.ty_fn(_,_)) { + fn hit_zero(@block_ctxt cx, ValueRef v) -> result { + + // Call through the closure's own fields-drop glue first. + auto body = + cx.build.GEP(v, + vec(C_int(0), + C_int(abi.box_rc_field_body))); + + auto bindings = + cx.build.GEP(body, + vec(C_int(0), + C_int(abi.closure_elt_bindings))); + auto llrawptr = cx.build.BitCast(bindings, T_ptr(T_i8())); + + auto tydescptr = + cx.build.GEP(body, + vec(C_int(0), + C_int(abi.closure_elt_tydesc))); + auto tydesc = cx.build.Load(tydescptr); + auto llfnptr = + cx.build.GEP(tydesc, + vec(C_int(0), + C_int(abi.tydesc_field_drop_glue_off))); + auto llfn = cx.build.Load(llfnptr); + cx.build.FastCall(llfn, vec(cx.fcx.lltaskptr, llrawptr)); + + // Then free the body. + // FIXME: switch gc/non-gc on layer of the type. + ret trans_non_gc_free(cx, v); + } + auto box_cell = + cx.build.GEP(v, + vec(C_int(0), + C_int(abi.fn_field_box))); + + auto boxptr = cx.build.Load(box_cell); + + ret decr_refcnt_and_if_zero(cx, boxptr, + bind hit_zero(_, boxptr), + "free fn", + T_int(), C_int(0)); + } + case (_) { if (ty.type_is_structural(t)) { ret iter_structural_ty(cx, v, t, @@ -2145,13 +2191,11 @@ impure fn trans_bind(@block_ctxt cx, @ast.expr f, auto pair_code = bcx.build.GEP(pair_v, vec(C_int(0), C_int(abi.fn_field_code))); + + let @ty.t pair_ty = node_ann_type(cx.fcx.ccx, ann); let ValueRef llthunk = - trans_bind_thunk(cx.fcx.ccx, - node_ann_type(cx.fcx.ccx, ann), - ty.expr_ty(f), - args, - llclosure_ty, - bound_tys); + trans_bind_thunk(cx.fcx.ccx, pair_ty, ty.expr_ty(f), + args, llclosure_ty, bound_tys); bcx.build.Store(llthunk, pair_code); @@ -2163,6 +2207,9 @@ impure fn trans_bind(@block_ctxt cx, @ast.expr f, T_opaque_closure_ptr()), pair_box); + find_scope_cx(cx).cleanups += + clean(bind drop_slot(_, pair_v, pair_ty)); + ret res(bcx, pair_v); } } |