aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-09-30 17:39:37 -0700
committerGraydon Hoare <[email protected]>2010-09-30 17:39:37 -0700
commit2e0d07540702ac6cabcc5670660c72f898d5cbd2 (patch)
treedf48c5f8070eb55f00db7c435e569782dee26d09
parentDrop slots on block exits even when blocks have no statements. Part way to fi... (diff)
downloadrust-2e0d07540702ac6cabcc5670660c72f898d5cbd2.tar.xz
rust-2e0d07540702ac6cabcc5670660c72f898d5cbd2.zip
Fix bug in bind thunks failing top drop unbound args; add test and adjust rustc to use bind again.
-rw-r--r--src/Makefile1
-rw-r--r--src/boot/me/trans.ml16
-rw-r--r--src/comp/middle/trans.rs9
-rw-r--r--src/rt/rust_builtin.cpp4
-rw-r--r--src/test/run-pass/drop-bind-thunk-args.rs8
5 files changed, 33 insertions, 5 deletions
diff --git a/src/Makefile b/src/Makefile
index c82331db..9ca5120d 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 d8be85bf..ce6f5d92 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 1828271f..1e82ee8f 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 8654e050..3a89cd5c 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 00000000..1198af40
--- /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