Fix busted iter/put code. Un-XFAIL foreach-box-drop.rs.

This commit is contained in:
Graydon Hoare 2011-04-23 14:17:44 -07:00
parent 2b298fa3e8
commit 912c1fc81c
2 changed files with 94 additions and 97 deletions

View File

@ -641,7 +641,7 @@ fn type_of_fn_full(@crate_ctxt cx,
atys +=
vec(T_fn_pair(cx.tn,
type_of_fn_full(cx, ast.proto_fn, none[TypeRef],
vec(rec(mode=ast.val, ty=output)),
vec(rec(mode=ast.alias, ty=output)),
ty.mk_nil(cx.tystore), 0u)));
}
@ -3553,17 +3553,15 @@ fn trans_for_each(@block_ctxt cx,
// pointer along with the foreach-body-fn pointer into a 'normal' fn pair
// and pass it in as a first class fn-arg to the iterator.
auto iter_body_llty = type_of_fn_full(lcx.ccx, ast.proto_fn,
none[TypeRef],
vec(rec(mode=ast.val, ty=decl_ty)),
ty.mk_nil(lcx.ccx.tystore), 0u);
auto iter_body_llty =
type_of_fn_full(lcx.ccx, ast.proto_fn,
none[TypeRef],
vec(rec(mode=ast.alias, ty=decl_ty)),
ty.mk_nil(lcx.ccx.tystore), 0u);
let ValueRef lliterbody = decl_internal_fastcall_fn(lcx.ccx.llmod,
s, iter_body_llty);
// FIXME: handle ty params properly.
let vec[ast.ty_param] ty_params = vec();
auto fcx = new_fn_ctxt(lcx, lliterbody);
auto bcx = new_top_block_ctxt(fcx);
auto lltop = bcx.llbb;
@ -3601,12 +3599,8 @@ fn trans_for_each(@block_ctxt cx,
i += 1u;
}
// Treat the loop variable as an upvar as well. We copy it to an alloca
// as usual.
auto lllvar = llvm.LLVMGetParam(fcx.llfn, 3u);
auto lllvarptr = alloca(bcx, val_ty(lllvar));
bcx.build.Store(lllvar, lllvarptr);
fcx.llupvars.insert(decl_id, lllvarptr);
// Add an upvar for the loop variable alias.
fcx.llupvars.insert(decl_id, llvm.LLVMGetParam(fcx.llfn, 3u));
auto r = trans_block(bcx, body);
@ -4570,6 +4564,68 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
}
}
fn trans_arg_expr(@block_ctxt cx,
ty.arg arg,
TypeRef lldestty0,
@ast.expr e) -> result {
auto val;
auto bcx = cx;
auto e_ty = ty.expr_ty(cx.fcx.lcx.ccx.tystore, e);
if (ty.type_is_structural(cx.fcx.lcx.ccx.tystore, e_ty)) {
auto re = trans_expr(bcx, e);
val = re.val;
bcx = re.bcx;
} else if (arg.mode == ast.alias) {
let lval_result lv;
if (ty.is_lval(e)) {
lv = trans_lval(bcx, e);
} else {
auto r = trans_expr(bcx, e);
if (type_is_immediate(cx.fcx.lcx.ccx, e_ty)) {
lv = lval_val(r.bcx, r.val);
} else {
lv = lval_mem(r.bcx, r.val);
}
}
bcx = lv.res.bcx;
if (lv.is_mem) {
val = lv.res.val;
} else {
// Non-mem but we're trying to alias; synthesize an
// alloca, spill to it and pass its address.
val = do_spill(lv.res.bcx, lv.res.val);
}
} else {
auto re = trans_expr(bcx, e);
val = re.val;
bcx = re.bcx;
}
if (ty.count_ty_params(cx.fcx.lcx.ccx.tystore, arg.ty) > 0u) {
auto lldestty = lldestty0;
if (arg.mode == ast.val) {
// FIXME: we'd prefer to use &&, but rustboot doesn't like it
if (ty.type_is_structural(cx.fcx.lcx.ccx.tystore, e_ty)) {
lldestty = T_ptr(lldestty);
}
}
val = bcx.build.PointerCast(val, lldestty);
}
if (arg.mode == ast.val) {
// FIXME: we'd prefer to use &&, but rustboot doesn't like it
if (ty.type_is_structural(cx.fcx.lcx.ccx.tystore, e_ty)) {
// Until here we've been treating structures by pointer;
// we are now passing it as an arg, so need to load it.
val = bcx.build.Load(val);
}
}
ret res(bcx, val);
}
// NB: must keep 4 fns in sync:
//
// - type_of_fn_full
@ -4660,68 +4716,9 @@ fn trans_args(@block_ctxt cx,
auto i = 0u;
for (@ast.expr e in es) {
auto mode = args.(i).mode;
auto val;
if (ty.type_is_structural(cx.fcx.lcx.ccx.tystore,
ty.expr_ty(cx.fcx.lcx.ccx.tystore, e))) {
auto re = trans_expr(bcx, e);
val = re.val;
bcx = re.bcx;
} else if (mode == ast.alias) {
let lval_result lv;
if (ty.is_lval(e)) {
lv = trans_lval(bcx, e);
} else {
auto r = trans_expr(bcx, e);
if (type_is_immediate(cx.fcx.lcx.ccx,
ty.expr_ty(cx.fcx.lcx.ccx.tystore,
e))) {
lv = lval_val(r.bcx, r.val);
} else {
lv = lval_mem(r.bcx, r.val);
}
}
bcx = lv.res.bcx;
if (lv.is_mem) {
val = lv.res.val;
} else {
// Non-mem but we're trying to alias; synthesize an
// alloca, spill to it and pass its address.
val = do_spill(lv.res.bcx, lv.res.val);
}
} else {
auto re = trans_expr(bcx, e);
val = re.val;
bcx = re.bcx;
}
if (ty.count_ty_params(cx.fcx.lcx.ccx.tystore, args.(i).ty) > 0u) {
auto lldestty = arg_tys.(i);
if (mode == ast.val) {
// FIXME: we'd prefer to use &&, but rustboot doesn't like it
if (ty.type_is_structural(cx.fcx.lcx.ccx.tystore,
ty.expr_ty(cx.fcx.lcx.ccx.tystore, e))) {
lldestty = T_ptr(lldestty);
}
}
val = bcx.build.PointerCast(val, lldestty);
}
if (mode == ast.val) {
// FIXME: we'd prefer to use &&, but rustboot doesn't like it
if (ty.type_is_structural(cx.fcx.lcx.ccx.tystore,
ty.expr_ty(cx.fcx.lcx.ccx.tystore, e))) {
// Until here we've been treating structures by pointer;
// we are now passing it as an arg, so need to load it.
val = bcx.build.Load(val);
}
}
llargs += vec(val);
auto r = trans_arg_expr(bcx, args.(i), arg_tys.(i), e);
bcx = r.bcx;
llargs += vec(r.val);
i += 1u;
}
@ -4797,15 +4794,23 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
bcx.build.FastCall(faddr, llargs);
auto retval = C_nil();
if (!ty.type_is_nil(cx.fcx.lcx.ccx.tystore, ret_ty)) {
retval = load_if_immediate(bcx, llretslot, ret_ty);
// Retval doesn't correspond to anything really tangible in the frame,
// but it's a ref all the same, so we put a note here to drop it when
// we're done in this scope.
find_scope_cx(cx).cleanups +=
vec(clean(bind drop_ty(_, retval, ret_ty)));
alt (lliterbody) {
case (none[ValueRef]) {
if (!ty.type_is_nil(cx.fcx.lcx.ccx.tystore, ret_ty)) {
retval = load_if_immediate(bcx, llretslot, ret_ty);
// Retval doesn't correspond to anything really tangible in
// the frame, but it's a ref all the same, so we put a note
// here to drop it when we're done in this scope.
find_scope_cx(cx).cleanups +=
vec(clean(bind drop_ty(_, retval, ret_ty)));
}
}
case (some[ValueRef](_)) {
// If there was an lliterbody, it means we were calling an
// iter, and we are *not* the party using its 'output' value,
// we should ignore llretslot.
}
}
ret res(bcx, retval);
}
@ -5296,18 +5301,12 @@ fn trans_put(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
alt (e) {
case (none[@ast.expr]) { }
case (some[@ast.expr](?x)) {
auto r = trans_expr(bcx, x);
auto llarg = r.val;
auto e_ty = ty.expr_ty(cx.fcx.lcx.ccx.tystore, x);
auto arg = rec(mode=ast.alias, ty=e_ty);
auto arg_tys = type_of_explicit_args(cx.fcx.lcx.ccx, vec(arg));
auto r = trans_arg_expr(bcx, arg, arg_tys.(0), x);
bcx = r.bcx;
if (ty.type_is_structural(cx.fcx.lcx.ccx.tystore,
ty.expr_ty(cx.fcx.lcx.ccx.tystore, x))) {
// Until here we've been treating structures by pointer; we
// are now passing it as an arg, so need to load it.
llarg = bcx.build.Load(llarg);
}
llargs += vec(llarg);
llargs += vec(r.val);
}
}

View File

@ -1,5 +1,3 @@
// xfail-stage0
obj ob[K](K k) {
iter foo() -> @tup(K) {
put @tup(k);