From 8bc57fa85e6191117c8c27bf53f8e051e13783c3 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Fri, 21 Jan 2011 07:58:16 -0800 Subject: [PATCH] Tweak effect-checking rules in rustboot, remove/rewrite/re-auth impure cases in trans.rs --- src/boot/me/effect.ml | 89 ++++++----- src/comp/middle/trans.rs | 313 ++++++++++++++++++++------------------- src/comp/rustc.rc | 2 + 3 files changed, 221 insertions(+), 183 deletions(-) diff --git a/src/boot/me/effect.ml b/src/boot/me/effect.ml index 3d52f23a1d9..fc4d03b17d3 100644 --- a/src/boot/me/effect.ml +++ b/src/boot/me/effect.ml @@ -179,8 +179,7 @@ let effect_checking_visitor then Ast.EFF_pure else Stack.top auth_stack in - let next = lower_effect_of e curr in - Stack.push next auth_stack; + Stack.push e auth_stack; iflog cx begin fun _ -> @@ -189,40 +188,62 @@ let effect_checking_visitor "entering '%a', adjusting auth effect: '%a' -> '%a'" Ast.sprintf_name name Ast.sprintf_effect curr - Ast.sprintf_effect next + Ast.sprintf_effect e end end; + let report_mismatch declared_effect calculated_effect = + let name = Hashtbl.find cx.ctxt_all_item_names i.id in + err (Some i.id) + "%a claims effect '%a' but calculated effect is '%a'%s" + Ast.sprintf_name name + Ast.sprintf_effect declared_effect + Ast.sprintf_effect calculated_effect + begin + if Stack.is_empty auth_stack + then "" + else + Printf.sprintf " (auth effects are '%s')" + (stk_fold + auth_stack + (fun e s -> + if s = "" + then + Printf.sprintf "%a" + Ast.sprintf_effect e + else + Printf.sprintf "%s, %a" s + Ast.sprintf_effect e) "") + end + in begin match i.node.Ast.decl_item with Ast.MOD_ITEM_fn f when htab_search cx.ctxt_required_items i.id = None -> - let e = + let calculated_effect = match htab_search item_effect i.id with None -> Ast.EFF_pure | Some e -> e in - let fe = f.Ast.fn_aux.Ast.fn_effect in - let ae = - if Stack.is_empty auth_stack - then None - else Some (Stack.top auth_stack) - in - if e <> fe && (ae <> (Some e)) + let declared_effect = f.Ast.fn_aux.Ast.fn_effect in + if calculated_effect <> declared_effect then + (* Something's fishy in this case. If the calculated effect + * is equal to one auth'ed by an enclosing scope -- not just + * a lower one -- we accept this mismatch; otherwise we + * complain. + * + * FIXME: this choice of "what constitutes an error" in + * auth/effect mismatches is subjective and could do + * with some discussion. *) begin - let name = Hashtbl.find cx.ctxt_all_item_names i.id in - err (Some i.id) - "%a claims effect '%a' but calculated effect is '%a'%s" - Ast.sprintf_name name - Ast.sprintf_effect fe - Ast.sprintf_effect e - begin - match ae with - Some ae when ae <> fe -> - Printf.sprintf " (auth effect is '%a')" - Ast.sprintf_effect ae - | _ -> "" - end + match + stk_search auth_stack + (fun e -> + if e = calculated_effect then Some e else None) + with + Some _ -> () + | None -> + report_mismatch declared_effect calculated_effect end | _ -> () end; @@ -239,16 +260,16 @@ let effect_checking_visitor then Ast.EFF_pure else Stack.top auth_stack in - iflog cx - begin - fun _ -> - let name = Hashtbl.find cx.ctxt_all_item_names i.id in - log cx - "leaving '%a', restoring auth effect: '%a' -> '%a'" - Ast.sprintf_name name - Ast.sprintf_effect curr - Ast.sprintf_effect next - end + iflog cx + begin + fun _ -> + let name = Hashtbl.find cx.ctxt_all_item_names i.id in + log cx + "leaving '%a', restoring auth effect: '%a' -> '%a'" + Ast.sprintf_name name + Ast.sprintf_effect curr + Ast.sprintf_effect next + end in { inner with Walk.visit_mod_item_pre = visit_mod_item_pre; diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 1b895193a56..a7770b942e2 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1504,7 +1504,7 @@ fn copy_ty(@block_ctxt cx, fail; } -impure fn trans_lit(@block_ctxt cx, &ast.lit lit, &ast.ann ann) -> result { +fn trans_lit(@block_ctxt cx, &ast.lit lit, &ast.ann ann) -> result { alt (lit.node) { case (ast.lit_int(?i)) { ret res(cx, C_int(i)); @@ -1547,12 +1547,12 @@ impure fn trans_lit(@block_ctxt cx, &ast.lit lit, &ast.ann ann) -> result { auto sub = trans_upcall(cx, "upcall_new_str", vec(p2i(C_str(cx.fcx.ccx, s)), C_int(len))); - sub.val = sub.bcx.build.IntToPtr(sub.val, - T_ptr(T_str())); + auto val = sub.bcx.build.IntToPtr(sub.val, + T_ptr(T_str())); auto t = node_ann_type(cx.fcx.ccx, ann); find_scope_cx(cx).cleanups += - clean(bind drop_ty(_, sub.val, t)); - ret sub; + clean(bind drop_ty(_, val, t)); + ret res(sub.bcx, val); } } } @@ -1587,24 +1587,21 @@ fn node_type(@crate_ctxt cx, &ast.ann a) -> TypeRef { ret type_of(cx, node_ann_type(cx, a)); } -impure fn trans_unary(@block_ctxt cx, ast.unop op, - @ast.expr e, &ast.ann a) -> result { +fn trans_unary(@block_ctxt cx, ast.unop op, + @ast.expr e, &ast.ann a) -> result { auto sub = trans_expr(cx, e); alt (op) { case (ast.bitnot) { - sub.val = cx.build.Not(sub.val); - ret sub; + ret res(sub.bcx, cx.build.Not(sub.val)); } case (ast.not) { - sub.val = cx.build.Not(sub.val); - ret sub; + ret res(sub.bcx, cx.build.Not(sub.val)); } case (ast.neg) { // FIXME: switch by signedness. - sub.val = cx.build.Neg(sub.val); - ret sub; + ret res(sub.bcx, cx.build.Neg(sub.val)); } case (ast.box) { auto e_ty = ty.expr_ty(e); @@ -1622,15 +1619,15 @@ impure fn trans_unary(@block_ctxt cx, ast.unop op, ret res(sub.bcx, box); } case (ast.deref) { - sub.val = sub.bcx.build.GEP(sub.val, - vec(C_int(0), - C_int(abi.box_rc_field_body))); + auto val = sub.bcx.build.GEP(sub.val, + vec(C_int(0), + C_int(abi.box_rc_field_body))); auto e_ty = node_ann_type(sub.bcx.fcx.ccx, a); if (ty.type_is_scalar(e_ty) || ty.type_is_nil(e_ty)) { - sub.val = sub.bcx.build.Load(sub.val); + val = sub.bcx.build.Load(val); } - ret sub; + ret res(sub.bcx, val); } } fail; @@ -1672,8 +1669,8 @@ fn trans_eager_binop(@block_ctxt cx, ast.binop op, fail; } -impure fn trans_binary(@block_ctxt cx, ast.binop op, - @ast.expr a, @ast.expr b) -> result { +fn trans_binary(@block_ctxt cx, ast.binop op, + @ast.expr a, @ast.expr b) -> result { // First couple cases are lazy: @@ -1769,8 +1766,8 @@ fn join_results(@block_ctxt parent_cx, ret res(join_cx, phi); } -impure fn trans_if(@block_ctxt cx, @ast.expr cond, - &ast.block thn, &option.t[ast.block] els) -> result { +fn trans_if(@block_ctxt cx, @ast.expr cond, + &ast.block thn, &option.t[ast.block] els) -> result { auto cond_res = trans_expr(cx, cond); @@ -1796,8 +1793,8 @@ impure fn trans_if(@block_ctxt cx, @ast.expr cond, vec(then_res, else_res)); } -impure fn trans_while(@block_ctxt cx, @ast.expr cond, - &ast.block body) -> result { +fn trans_while(@block_ctxt cx, @ast.expr cond, + &ast.block body) -> result { auto cond_cx = new_scope_block_ctxt(cx, "while cond"); auto body_cx = new_scope_block_ctxt(cx, "while loop body"); @@ -1815,8 +1812,8 @@ impure fn trans_while(@block_ctxt cx, @ast.expr cond, ret res(next_cx, C_nil()); } -impure fn trans_do_while(@block_ctxt cx, &ast.block body, - @ast.expr cond) -> result { +fn trans_do_while(@block_ctxt cx, &ast.block body, + @ast.expr cond) -> result { auto body_cx = new_scope_block_ctxt(cx, "do-while loop body"); auto next_cx = new_sub_block_ctxt(cx, "next"); @@ -1850,8 +1847,8 @@ fn get_pat_union_ptr(@block_ctxt cx, vec[@ast.pat] subpats, ValueRef llval) ret cx.build.TruncOrBitCast(llblobptr, T_ptr(llunionty)); } -impure fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval, - @block_ctxt next_cx) -> result { +fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval, + @block_ctxt next_cx) -> result { alt (pat.node) { case (ast.pat_wild(_)) { ret res(cx, llval); } case (ast.pat_bind(_, _, _)) { ret res(cx, llval); } @@ -1903,8 +1900,8 @@ impure fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval, fail; } -impure fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval) - -> result { +fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval) + -> result { alt (pat.node) { case (ast.pat_wild(_)) { ret res(cx, llval); } case (ast.pat_bind(?id, ?def_id, ?ann)) { @@ -1941,8 +1938,8 @@ impure fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval) } } -impure fn trans_alt(@block_ctxt cx, @ast.expr expr, vec[ast.arm] arms) - -> result { +fn trans_alt(@block_ctxt cx, @ast.expr expr, vec[ast.arm] arms) + -> result { auto expr_res = trans_expr(cx, expr); auto last_cx = new_sub_block_ctxt(expr_res.bcx, "last"); @@ -2068,8 +2065,8 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt, fail; } -impure fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base, - &ast.ident field, &ast.ann ann) -> lval_result { +fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base, + &ast.ident field, &ast.ann ann) -> lval_result { auto lv = trans_lval(cx, base); auto r = lv.res; check (lv.is_mem); @@ -2102,8 +2099,8 @@ impure fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base, fail; } -impure fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base, - @ast.expr idx, &ast.ann ann) -> lval_result { +fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base, + @ast.expr idx, &ast.ann ann) -> lval_result { auto lv = trans_expr(cx, base); auto ix = trans_expr(lv.bcx, idx); @@ -2140,7 +2137,7 @@ impure fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base, // represented as an alloca or heap, hence needs a 'load' to be used as an // immediate). -impure fn trans_lval(@block_ctxt cx, @ast.expr e) -> lval_result { +fn trans_lval(@block_ctxt cx, @ast.expr e) -> lval_result { alt (e.node) { case (ast.expr_path(?p, ?dopt, ?ann)) { ret trans_path(cx, p, dopt, ann); @@ -2156,7 +2153,7 @@ impure fn trans_lval(@block_ctxt cx, @ast.expr e) -> lval_result { fail; } -impure fn trans_cast(@block_ctxt cx, @ast.expr e, &ast.ann ann) -> result { +fn trans_cast(@block_ctxt cx, @ast.expr e, &ast.ann ann) -> result { auto e_res = trans_expr(cx, e); auto llsrctype = val_ty(e_res.val); auto t = node_ann_type(cx.fcx.ccx, ann); @@ -2189,12 +2186,12 @@ impure fn trans_cast(@block_ctxt cx, @ast.expr e, &ast.ann ann) -> result { // NB: this must match type_of_fn_full and create_llargs_for_fn_args. -impure fn trans_args(@block_ctxt cx, - ValueRef llclosure, - option.t[ValueRef] llobj, - option.t[generic_info] gen, - &vec[@ast.expr] es, - @ty.t fn_ty) +fn trans_args(@block_ctxt cx, + ValueRef llclosure, + option.t[ValueRef] llobj, + option.t[generic_info] gen, + &vec[@ast.expr] es, + @ty.t fn_ty) -> tup(@block_ctxt, vec[ValueRef], option.t[ValueRef]) { let vec[ValueRef] vs = vec(cx.fcx.lltaskptr); let @block_ctxt bcx = cx; @@ -2236,13 +2233,15 @@ impure fn trans_args(@block_ctxt cx, for (@ast.expr e in es) { auto mode = args.(i).mode; - auto re; + auto val; if (ty.type_is_structural(ty.expr_ty(e))) { - re = trans_expr(bcx, e); + auto re = trans_expr(bcx, e); + val = re.val; + bcx = re.bcx; if (mode == ast.val) { // Until here we've been treating structures by pointer; // we are now passing it as an arg, so need to load it. - re.val = re.bcx.build.Load(re.val); + val = bcx.build.Load(val); } } else if (mode == ast.alias) { let lval_result lv; @@ -2252,42 +2251,42 @@ impure fn trans_args(@block_ctxt cx, auto r = trans_expr(bcx, e); lv = lval_val(r.bcx, r.val); } + bcx = lv.res.bcx; - if (!lv.is_mem) { + 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. auto llty = val_ty(lv.res.val); auto llptr = lv.res.bcx.build.Alloca(llty); lv.res.bcx.build.Store(lv.res.val, llptr); - re = res(lv.res.bcx, llptr); - } else { - re = lv.res; + val = llptr; } } else { - re = trans_expr(bcx, e); + auto re = trans_expr(bcx, e); + val = re.val; + bcx = re.bcx; } if (ty.type_has_dynamic_size(args.(i).ty)) { - re.val = re.bcx.build.PointerCast(re.val, - T_typaram_ptr()); + val = bcx.build.PointerCast(val, T_typaram_ptr()); } - vs += re.val; - bcx = re.bcx; - + vs += val; i += 1u; } ret tup(bcx, vs, llretslot_opt); } -impure fn trans_bind_thunk(@crate_ctxt cx, - @ty.t incoming_fty, - @ty.t outgoing_fty, - vec[option.t[@ast.expr]] args, - TypeRef llclosure_ty, - vec[@ty.t] bound_tys) -> ValueRef { +fn trans_bind_thunk(@crate_ctxt cx, + @ty.t incoming_fty, + @ty.t outgoing_fty, + vec[option.t[@ast.expr]] args, + TypeRef llclosure_ty, + vec[@ty.t] bound_tys) -> ValueRef { // Construct a thunk-call with signature incoming_fty, and that copies // args forward into a call to outgoing_fty. @@ -2371,9 +2370,9 @@ impure fn trans_bind_thunk(@crate_ctxt cx, ret llthunk; } -impure fn trans_bind(@block_ctxt cx, @ast.expr f, - vec[option.t[@ast.expr]] args, - &ast.ann ann) -> result { +fn trans_bind(@block_ctxt cx, @ast.expr f, + vec[option.t[@ast.expr]] args, + &ast.ann ann) -> result { auto f_res = trans_lval(cx, f); if (f_res.is_mem) { cx.fcx.ccx.sess.unimpl("re-binding existing function"); @@ -2483,8 +2482,8 @@ impure fn trans_bind(@block_ctxt cx, @ast.expr f, } } -impure fn trans_call(@block_ctxt cx, @ast.expr f, - vec[@ast.expr] args, &ast.ann ann) -> result { +fn trans_call(@block_ctxt cx, @ast.expr f, + vec[@ast.expr] args, &ast.ann ann) -> result { auto f_res = trans_lval(cx, f); auto faddr = f_res.res.val; auto llclosure = C_null(T_opaque_closure_ptr()); @@ -2551,8 +2550,8 @@ impure fn trans_call(@block_ctxt cx, @ast.expr f, ret res(bcx, retval); } -impure fn trans_tup(@block_ctxt cx, vec[ast.elt] elts, - &ast.ann ann) -> result { +fn trans_tup(@block_ctxt cx, vec[ast.elt] elts, + &ast.ann ann) -> result { auto t = node_ann_type(cx.fcx.ccx, ann); auto llty = type_of(cx.fcx.ccx, t); auto tup_val = cx.build.Alloca(llty); @@ -2569,8 +2568,8 @@ impure fn trans_tup(@block_ctxt cx, vec[ast.elt] elts, ret res(r.bcx, tup_val); } -impure fn trans_vec(@block_ctxt cx, vec[@ast.expr] args, - &ast.ann ann) -> result { +fn trans_vec(@block_ctxt cx, vec[@ast.expr] args, + &ast.ann ann) -> result { auto t = node_ann_type(cx.fcx.ccx, ann); auto unit_ty = t; alt (t.struct) { @@ -2610,8 +2609,8 @@ impure fn trans_vec(@block_ctxt cx, vec[@ast.expr] args, ret res(sub.bcx, vec_val); } -impure fn trans_rec(@block_ctxt cx, vec[ast.field] fields, - &ast.ann ann) -> result { +fn trans_rec(@block_ctxt cx, vec[ast.field] fields, + &ast.ann ann) -> result { auto t = node_ann_type(cx.fcx.ccx, ann); auto llty = type_of(cx.fcx.ccx, t); auto rec_val = cx.build.Alloca(llty); @@ -2631,7 +2630,7 @@ impure fn trans_rec(@block_ctxt cx, vec[ast.field] fields, -impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result { +fn trans_expr(@block_ctxt cx, @ast.expr e) -> result { alt (e.node) { case (ast.expr_lit(?lit, ?ann)) { ret trans_lit(cx, *lit, ann); @@ -2745,7 +2744,7 @@ fn load_scalar_or_boxed(@block_ctxt cx, } } -impure fn trans_log(@block_ctxt cx, @ast.expr e) -> result { +fn trans_log(@block_ctxt cx, @ast.expr e) -> result { auto sub = trans_expr(cx, e); auto e_ty = ty.expr_ty(e); @@ -2765,7 +2764,7 @@ impure fn trans_log(@block_ctxt cx, @ast.expr e) -> result { fail; } -impure fn trans_check_expr(@block_ctxt cx, @ast.expr e) -> result { +fn trans_check_expr(@block_ctxt cx, @ast.expr e) -> result { auto cond_res = trans_expr(cx, e); // FIXME: need pretty-printer. @@ -2785,23 +2784,27 @@ impure fn trans_check_expr(@block_ctxt cx, @ast.expr e) -> result { ret res(next_cx, C_nil()); } -impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result { - auto r = res(cx, C_nil()); +fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result { + auto bcx = cx; + auto val = C_nil(); + alt (e) { case (some[@ast.expr](?x)) { auto t = ty.expr_ty(x); - r = trans_expr(cx, x); + auto r = trans_expr(cx, x); + bcx = r.bcx; + val = r.val; // A return is an implicit copy into a newborn anonymous // 'return value' in the caller frame. - r.bcx = incr_all_refcnts(r.bcx, r.val, t).bcx; + bcx = incr_all_refcnts(bcx, val, t).bcx; if (ty.type_is_structural(t)) { // We usually treat structurals by-pointer; in particular, // trans_expr will have given us a structure pointer. But in // this case we're about to return. LLVM wants a first-class // value here (which makes sense; the frame is going away!) - r.val = r.bcx.build.Load(r.val); + val = r.bcx.build.Load(val); } } case (_) { /* fall through */ } @@ -2811,7 +2814,7 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result { let bool more_cleanups = true; auto cleanup_cx = cx; while (more_cleanups) { - r.bcx = trans_block_cleanups(r.bcx, cleanup_cx); + bcx = trans_block_cleanups(bcx, cleanup_cx); alt (cleanup_cx.parent) { case (parent_some(?b)) { cleanup_cx = b; @@ -2827,80 +2830,87 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result { auto t = ty.expr_ty(ex); if (ty.type_is_nil(t)) { - r.bcx.build.RetVoid(); - r.val = C_nil(); - ret r; // FIXME: early return needed due to typestate bug + bcx.build.RetVoid(); + val = C_nil(); + ret res(bcx, val); // FIXME: early return needed due to + // typestate bug } alt (cx.fcx.llretptr) { case (some[ValueRef](?llptr)) { // Generic return via tydesc + retptr. - r = copy_ty(r.bcx, true, llptr, r.val, t); - r.bcx.build.RetVoid(); + bcx = copy_ty(bcx, true, llptr, val, t).bcx; + bcx.build.RetVoid(); } case (none[ValueRef]) { - r.val = r.bcx.build.Ret(r.val); + val = bcx.build.Ret(val); } } - ret r; + ret res(bcx, val); } case (_) { /* fall through */ } } // FIXME: until LLVM has a unit type, we are moving around // C_nil values rather than their void type. - r.bcx.build.RetVoid(); - r.val = C_nil(); - ret r; + bcx.build.RetVoid(); + ret res(bcx, C_nil()); } -impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result { - auto sub = res(cx, C_nil()); +fn init_local(@block_ctxt cx, @ast.local local) -> result { + + // Make a note to drop this slot on the way out. + check (cx.fcx.lllocals.contains_key(local.id)); + auto llptr = cx.fcx.lllocals.get(local.id); + auto ty = node_ann_type(cx.fcx.ccx, local.ann); + auto bcx = cx; + + find_scope_cx(cx).cleanups += + clean(bind drop_slot(_, llptr, ty)); + + alt (local.init) { + case (some[@ast.expr](?e)) { + auto sub = trans_expr(bcx, e); + bcx = copy_ty(sub.bcx, true, llptr, sub.val, ty).bcx; + } + case (_) { + if (middle.ty.type_has_dynamic_size(ty)) { + auto llsz = size_of(cx, ty); + bcx = call_bzero(cx, llptr, llsz).bcx; + + } else { + auto llty = type_of(bcx.fcx.ccx, ty); + auto null = lib.llvm.llvm.LLVMConstNull(llty); + bcx.build.Store(null, llptr); + } + } + } + ret res(bcx, llptr); +} + +fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result { + auto bcx = cx; alt (s.node) { case (ast.stmt_log(?a)) { - sub.bcx = trans_log(cx, a).bcx; + bcx = trans_log(cx, a).bcx; } case (ast.stmt_check_expr(?a)) { - sub.bcx = trans_check_expr(cx, a).bcx; + bcx = trans_check_expr(cx, a).bcx; } case (ast.stmt_ret(?e)) { - sub.bcx = trans_ret(cx, e).bcx; + bcx = trans_ret(cx, e).bcx; } case (ast.stmt_expr(?e)) { - sub.bcx = trans_expr(cx, e).bcx; + bcx = trans_expr(cx, e).bcx; } case (ast.stmt_decl(?d)) { alt (d.node) { case (ast.decl_local(?local)) { - - // Make a note to drop this slot on the way out. - check (cx.fcx.lllocals.contains_key(local.id)); - auto llptr = cx.fcx.lllocals.get(local.id); - auto ty = node_ann_type(cx.fcx.ccx, local.ann); - find_scope_cx(cx).cleanups += - clean(bind drop_slot(_, llptr, ty)); - - alt (local.init) { - case (some[@ast.expr](?e)) { - sub = trans_expr(cx, e); - sub = copy_ty(sub.bcx, true, llptr, sub.val, ty); - } - case (_) { - if (middle.ty.type_has_dynamic_size(ty)) { - auto llsz = size_of(cx, ty); - sub = call_bzero(cx, llptr, llsz); - - } else { - auto llty = type_of(cx.fcx.ccx, ty); - auto null = lib.llvm.llvm.LLVMConstNull(llty); - sub = res(cx, cx.build.Store(null, llptr)); - } - } - } + bcx = init_local(bcx, local).bcx; } case (ast.decl_item(?i)) { trans_item(cx.fcx.ccx, *i); @@ -2911,7 +2921,7 @@ impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result { cx.fcx.ccx.sess.unimpl("stmt variant"); } } - ret sub; + ret res(bcx, C_nil()); } fn new_builder(BasicBlockRef llbb) -> builder { @@ -2990,19 +3000,24 @@ iter block_locals(&ast.block b) -> @ast.local { } } -impure fn trans_block(@block_ctxt cx, &ast.block b) -> result { +fn alloc_local(@block_ctxt cx, @ast.local local) -> result { + auto t = node_ann_type(cx.fcx.ccx, local.ann); + auto val = C_int(0); + if (ty.type_has_dynamic_size(t)) { + auto n = size_of(cx, t); + val = cx.build.ArrayAlloca(T_i8(), n); + } else { + val = cx.build.Alloca(type_of(cx.fcx.ccx, t)); + } + cx.fcx.lllocals.insert(local.id, val); + ret res(cx, val); +} + +fn trans_block(@block_ctxt cx, &ast.block b) -> result { auto bcx = cx; for each (@ast.local local in block_locals(b)) { - auto t = node_ann_type(cx.fcx.ccx, local.ann); - auto val = C_int(0); - if (ty.type_has_dynamic_size(t)) { - auto n = size_of(bcx, t); - val = bcx.build.ArrayAlloca(T_i8(), n); - } else { - val = bcx.build.Alloca(type_of(cx.fcx.ccx, t)); - } - cx.fcx.lllocals.insert(local.id, val); + bcx = alloc_local(bcx, local).bcx; } auto r = res(bcx, C_nil()); @@ -3102,10 +3117,10 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx, // allocas immediately upon entry; this permits us to GEP into structures we // were passed and whatnot. Apparently mem2reg will mop up. -impure fn copy_args_to_allocas(@block_ctxt cx, - option.t[TypeRef] ty_self, - vec[ast.arg] args, - vec[ty.arg] arg_tys) { +fn copy_args_to_allocas(@block_ctxt cx, + option.t[TypeRef] ty_self, + vec[ast.arg] args, + vec[ty.arg] arg_tys) { let uint arg_n = 0u; @@ -3203,9 +3218,9 @@ fn create_llobjfields_for_fields(@block_ctxt cx, ValueRef llself) { } } -impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid, - option.t[TypeRef] ty_self, - &vec[ast.ty_param] ty_params, &ast.ann ann) { +fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid, + option.t[TypeRef] ty_self, + &vec[ast.ty_param] ty_params, &ast.ann ann) { auto llfndecl = cx.item_ids.get(fid); cx.item_names.insert(cx.path, llfndecl); @@ -3234,9 +3249,9 @@ impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid, } } -impure fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty, - &ast._obj ob, - &vec[ast.ty_param] ty_params) -> ValueRef { +fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty, + &ast._obj ob, + &vec[ast.ty_param] ty_params) -> ValueRef { let vec[ValueRef] methods = vec(); fn meth_lteq(&@ast.method a, &@ast.method b) -> bool { @@ -3279,8 +3294,8 @@ impure fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty, ret gvar; } -impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid, - &vec[ast.ty_param] ty_params, &ast.ann ann) { +fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid, + &vec[ast.ty_param] ty_params, &ast.ann ann) { auto llctor_decl = cx.item_ids.get(oid); cx.item_names.insert(cx.path, llctor_decl); @@ -3442,7 +3457,7 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id, bcx.build.Ret(lltagval); } -impure fn trans_item(@crate_ctxt cx, &ast.item item) { +fn trans_item(@crate_ctxt cx, &ast.item item) { alt (item.node) { case (ast.item_fn(?name, ?f, ?tps, ?fid, ?ann)) { auto sub_cx = @rec(path=cx.path + "." + name with *cx); @@ -3469,7 +3484,7 @@ impure fn trans_item(@crate_ctxt cx, &ast.item item) { } } -impure fn trans_mod(@crate_ctxt cx, &ast._mod m) { +fn trans_mod(@crate_ctxt cx, &ast._mod m) { for (@ast.item item in m.items) { trans_item(cx, *item); } diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index 8f5414158f9..b439632cfbc 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -34,6 +34,8 @@ mod util { auth driver.rustc.main = impure; auth middle.trans = unsafe; +auth middle.trans.copy_args_to_allocas = impure; +auth middle.trans.trans_block = impure; auth lib.llvm = unsafe;