aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-01-21 07:58:16 -0800
committerGraydon Hoare <[email protected]>2011-01-21 07:59:56 -0800
commit8bc57fa85e6191117c8c27bf53f8e051e13783c3 (patch)
tree663f8d067457d0abe92e319e0b5c63a001fa1127 /src
parentM-x indent-region on trans.rs. (diff)
downloadrust-8bc57fa85e6191117c8c27bf53f8e051e13783c3.tar.xz
rust-8bc57fa85e6191117c8c27bf53f8e051e13783c3.zip
Tweak effect-checking rules in rustboot, remove/rewrite/re-auth impure cases in trans.rs
Diffstat (limited to 'src')
-rw-r--r--src/boot/me/effect.ml89
-rw-r--r--src/comp/middle/trans.rs313
-rw-r--r--src/comp/rustc.rc2
3 files changed, 221 insertions, 183 deletions
diff --git a/src/boot/me/effect.ml b/src/boot/me/effect.ml
index 3d52f23a..fc4d03b1 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 1b895193..a7770b94 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());
+}
+
+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);
}
-impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
- auto sub = res(cx, C_nil());
+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 8f541415..b439632c 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;