From 2e0d07540702ac6cabcc5670660c72f898d5cbd2 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 30 Sep 2010 17:39:37 -0700 Subject: [PATCH] Fix bug in bind thunks failing top drop unbound args; add test and adjust rustc to use bind again. --- src/Makefile | 1 + src/boot/me/trans.ml | 16 ++++++++++++++++ src/comp/middle/trans.rs | 9 ++++----- src/rt/rust_builtin.cpp | 4 ++++ src/test/run-pass/drop-bind-thunk-args.rs | 8 ++++++++ 5 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 src/test/run-pass/drop-bind-thunk-args.rs diff --git a/src/Makefile b/src/Makefile index c82331db8f2..9ca5120d5f7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -462,6 +462,7 @@ TEST_XFAILS_LLVM := $(TASK_XFAILS) \ deep.rs \ deref.rs \ destructor-ordering.rs \ + drop-bind-thunk-args.rs \ drop-on-empty-block-exit.rs \ export-non-interference.rs \ exterior.rs \ diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml index d8be85bfcc7..ce6f5d922f7 100644 --- a/src/boot/me/trans.ml +++ b/src/boot/me/trans.ml @@ -1640,12 +1640,28 @@ let trans_visitor get_element_ptr closure_target_cell Abi.fn_field_code in + let self_args_cell = + get_element_ptr all_self_args_cell Abi.calltup_elt_args + in + + let self_ty_params_cell = + get_element_ptr all_self_args_cell Abi.calltup_elt_ty_params + in + merge_bound_args self_args_rty callee_args_rty arg_slots arg_bound_flags; iflog (fun _ -> annotate "call through to closure target fn"); call_code (code_of_cell closure_target_code_cell); + + (* Drop the args we were passed. *) + Array.iteri + (fun i slot -> + let cell = get_element_ptr self_args_cell i in + drop_slot self_ty_params_cell cell slot) + unbound_slots; + trans_glue_frame_exit fix spill g diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 1828271fd30..1e82ee8fb06 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -51,7 +51,7 @@ state type fn_ctxt = rec(ValueRef llfn, type terminator = fn(@fn_ctxt cx, builder build); tag cleanup { - clean(fn(@block_ctxt cx, ValueRef v), ValueRef); + clean(fn(@block_ctxt cx)); } state type block_ctxt = rec(BasicBlockRef llbb, @@ -303,8 +303,7 @@ fn trans_lit(@block_ctxt cx, &ast.lit lit) -> ValueRef { vec(p2i(C_str(cx.fcx.tcx, s)), C_int(len))); v = cx.build.IntToPtr(v, T_ptr(T_str())); - auto f = drop_str; - cx.cleanups += vec(clean(f, v)); + cx.cleanups += vec(clean(bind drop_str(_, v))); ret v; } } @@ -496,8 +495,8 @@ fn trans_block(@fn_ctxt cx, &ast.block b, terminator term) { for (cleanup c in bcx.cleanups) { alt (c) { - case (clean(?cfn, ?v)) { - cfn(bcx, v); + case (clean(?cfn)) { + cfn(bcx); } } } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 8654e0507a8..3a89cd5c445 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -338,6 +338,10 @@ debug_fn(rust_task *task, type_desc *t, rust_fn *fn) debug_tydesc_helper(task, t); task->log(rust_log::STDLIB, " thunk at 0x%" PRIxPTR, fn->thunk); task->log(rust_log::STDLIB, " closure at 0x%" PRIxPTR, fn->closure); + if (fn->closure) { + task->log(rust_log::STDLIB, " refcount %" PRIdPTR, + fn->closure->ref_count); + } } extern "C" CDECL void * diff --git a/src/test/run-pass/drop-bind-thunk-args.rs b/src/test/run-pass/drop-bind-thunk-args.rs new file mode 100644 index 00000000000..1198af40cec --- /dev/null +++ b/src/test/run-pass/drop-bind-thunk-args.rs @@ -0,0 +1,8 @@ +fn f(@int x) { } + +fn main() { + auto x = @10; + auto ff = bind f(_); + ff(x); + ff(x); +} \ No newline at end of file