diff options
| author | Brian Anderson <[email protected]> | 2011-03-16 21:49:15 -0400 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-03-22 08:04:38 -0700 |
| commit | 261d1e4c6178fec150915c9b97b2d4dd94b1ad95 (patch) | |
| tree | a9e3ddf2fc0d3131d1b6317222dd6fa406945af6 /src | |
| parent | Repair some fallout from pcwalton's last few build changes. (diff) | |
| download | rust-261d1e4c6178fec150915c9b97b2d4dd94b1ad95.tar.xz rust-261d1e4c6178fec150915c9b97b2d4dd94b1ad95.zip | |
Add codegen for ports and chans
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/trans.rs | 114 | ||||
| -rw-r--r-- | src/comp/middle/ty.rs | 6 |
2 files changed, 120 insertions, 0 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index d4cd3992..d4b4923e 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -339,6 +339,14 @@ fn T_box(TypeRef t) -> TypeRef { ret T_struct(vec(T_int(), t)); } +fn T_port(TypeRef t) -> TypeRef { + ret T_struct(vec(T_int())); // Refcount +} + +fn T_chan(TypeRef t) -> TypeRef { + ret T_struct(vec(T_int())); // Refcount +} + fn T_crate(type_names tn) -> TypeRef { auto s = "crate"; if (tn.name_has_type(s)) { @@ -623,6 +631,12 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef { case (ty.ty_vec(?mt)) { llty = T_ptr(T_vec(type_of_inner(cx, mt.ty, true))); } + case (ty.ty_port(?t)) { + llty = T_ptr(T_port(type_of_inner(cx, t, true))); + } + case (ty.ty_chan(?t)) { + llty = T_ptr(T_chan(type_of_inner(cx, t, true))); + } case (ty.ty_tup(?elts)) { let vec[TypeRef] tys = vec(); for (ty.mt elt in elts) { @@ -1609,6 +1623,28 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result { T_int(), C_int(0)); } + case (ty.ty_port(_)) { + fn hit_zero(@block_ctxt cx, ValueRef v) -> result { + ret trans_upcall(cx, "upcall_del_port", + vec(vp2i(cx, v))); + } + ret decr_refcnt_and_if_zero(cx, v, + bind hit_zero(_, v), + "free port", + T_int(), C_int(0)); + } + + case (ty.ty_chan(_)) { + fn hit_zero(@block_ctxt cx, ValueRef v) -> result { + ret trans_upcall(cx, "upcall_del_chan", + vec(vp2i(cx, v))); + } + ret decr_refcnt_and_if_zero(cx, v, + bind hit_zero(_, v), + "free chan", + T_int(), C_int(0)); + } + case (ty.ty_obj(_)) { fn hit_zero(@block_ctxt cx, ValueRef v) -> result { @@ -4496,6 +4532,22 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result { ret trans_be(cx, e); } + case (ast.expr_port(?ann)) { + ret trans_port(cx, ann); + } + + case (ast.expr_chan(?e, ?ann)) { + ret trans_chan(cx, e, ann); + } + + case (ast.expr_send(?lhs, ?rhs, ?ann)) { + ret trans_send(cx, lhs, rhs, ann); + } + + case (ast.expr_recv(?lhs, ?rhs, ?ann)) { + ret trans_recv(cx, lhs, rhs, ann); + } + // lval cases fall through to trans_lval and then // possibly load the result (if it's non-structural). @@ -4667,6 +4719,68 @@ fn trans_be(@block_ctxt cx, @ast.expr e) -> result { ret trans_ret(cx, some(e)); } +fn trans_port(@block_ctxt cx, ast.ann ann) -> result { + + auto t = node_ann_type(cx.fcx.ccx, ann); + auto unit_ty; + alt (t.struct) { + case (ty.ty_port(?t)) { + unit_ty = t; + } + case (_) { + cx.fcx.ccx.sess.bug("non-port type in trans_port"); + fail; + } + } + + auto llunit_ty = type_of(cx.fcx.ccx, unit_ty); + + auto bcx = cx; + auto unit_sz = size_of(bcx, unit_ty); + bcx = unit_sz.bcx; + auto sub = trans_upcall(bcx, "upcall_new_port", vec(unit_sz.val)); + bcx = sub.bcx; + auto llty = type_of(cx.fcx.ccx, t); + auto port_val = vi2p(bcx, sub.val, llty); + auto dropref = clean(bind drop_ty(_, port_val, t)); + find_scope_cx(bcx).cleanups += vec(dropref); + + ret res(bcx, port_val); +} + +fn trans_chan(@block_ctxt cx, @ast.expr e, ast.ann ann) -> result { + + auto bcx = cx; + auto prt = trans_expr(bcx, e); + bcx = prt.bcx; + + auto prt_ty = ty.expr_ty(e); + auto prt_llty = type_of(bcx.fcx.ccx, prt_ty); + auto prt_val = vp2i(bcx, prt.val); + auto sub = trans_upcall(bcx, "upcall_new_chan", vec(prt_val)); + bcx = sub.bcx; + + auto chan_ty = node_ann_type(bcx.fcx.ccx, ann); + auto chan_llty = type_of(bcx.fcx.ccx, chan_ty); + auto chan_val = vi2p(bcx, sub.val, chan_llty); + auto dropref = clean(bind drop_ty(_, chan_val, chan_ty)); + find_scope_cx(bcx).cleanups += vec(dropref); + + // TODO: Do I need to do anything with the port's refcount? + + ret res(bcx, chan_val); +} + +fn trans_send(@block_ctxt cx, @ast.expr lhs, @ast.expr rhs, + ast.ann ann) -> result { + fail; +} + +fn trans_recv(@block_ctxt cx, @ast.expr lhs, @ast.expr rhs, + ast.ann ann) -> result { + fail; +} + fn init_local(@block_ctxt cx, @ast.local local) -> result { // Make a note to drop this slot on the way out. diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 6eb3d8b5..72564078 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -411,6 +411,8 @@ fn type_is_boxed(@t ty) -> bool { case (ty_str) { ret true; } case (ty_vec(_)) { ret true; } case (ty_box(_)) { ret true; } + case (ty_port(_)) { ret true; } + case (ty_chan(_)) { ret true; } case (_) { ret false; } } fail; @@ -759,6 +761,10 @@ fn expr_ty(@ast.expr expr) -> @t { case (ast.expr_index(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_path(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_ext(_, _, _, _, ?ann)) { ret ann_to_type(ann); } + case (ast.expr_port(?ann)) { ret ann_to_type(ann); } + case (ast.expr_chan(_, ?ann)) { ret ann_to_type(ann); } + case (ast.expr_send(_, _, ?ann)) { ret ann_to_type(ann); } + case (ast.expr_recv(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_fail) { ret plain_ty(ty_nil); } case (ast.expr_log(_)) { ret plain_ty(ty_nil); } |