Skip to content

Commit 261d1e4

Browse files
brsongraydon
authored andcommitted
Add codegen for ports and chans
1 parent 7ac885e commit 261d1e4

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

src/comp/middle/trans.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,14 @@ fn T_box(TypeRef t) -> TypeRef {
339339
ret T_struct(vec(T_int(), t));
340340
}
341341

342+
fn T_port(TypeRef t) -> TypeRef {
343+
ret T_struct(vec(T_int())); // Refcount
344+
}
345+
346+
fn T_chan(TypeRef t) -> TypeRef {
347+
ret T_struct(vec(T_int())); // Refcount
348+
}
349+
342350
fn T_crate(type_names tn) -> TypeRef {
343351
auto s = "crate";
344352
if (tn.name_has_type(s)) {
@@ -623,6 +631,12 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
623631
case (ty.ty_vec(?mt)) {
624632
llty = T_ptr(T_vec(type_of_inner(cx, mt.ty, true)));
625633
}
634+
case (ty.ty_port(?t)) {
635+
llty = T_ptr(T_port(type_of_inner(cx, t, true)));
636+
}
637+
case (ty.ty_chan(?t)) {
638+
llty = T_ptr(T_chan(type_of_inner(cx, t, true)));
639+
}
626640
case (ty.ty_tup(?elts)) {
627641
let vec[TypeRef] tys = vec();
628642
for (ty.mt elt in elts) {
@@ -1609,6 +1623,28 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
16091623
T_int(), C_int(0));
16101624
}
16111625

1626+
case (ty.ty_port(_)) {
1627+
fn hit_zero(@block_ctxt cx, ValueRef v) -> result {
1628+
ret trans_upcall(cx, "upcall_del_port",
1629+
vec(vp2i(cx, v)));
1630+
}
1631+
ret decr_refcnt_and_if_zero(cx, v,
1632+
bind hit_zero(_, v),
1633+
"free port",
1634+
T_int(), C_int(0));
1635+
}
1636+
1637+
case (ty.ty_chan(_)) {
1638+
fn hit_zero(@block_ctxt cx, ValueRef v) -> result {
1639+
ret trans_upcall(cx, "upcall_del_chan",
1640+
vec(vp2i(cx, v)));
1641+
}
1642+
ret decr_refcnt_and_if_zero(cx, v,
1643+
bind hit_zero(_, v),
1644+
"free chan",
1645+
T_int(), C_int(0));
1646+
}
1647+
16121648
case (ty.ty_obj(_)) {
16131649
fn hit_zero(@block_ctxt cx, ValueRef v) -> result {
16141650

@@ -4496,6 +4532,22 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
44964532
ret trans_be(cx, e);
44974533
}
44984534

4535+
case (ast.expr_port(?ann)) {
4536+
ret trans_port(cx, ann);
4537+
}
4538+
4539+
case (ast.expr_chan(?e, ?ann)) {
4540+
ret trans_chan(cx, e, ann);
4541+
}
4542+
4543+
case (ast.expr_send(?lhs, ?rhs, ?ann)) {
4544+
ret trans_send(cx, lhs, rhs, ann);
4545+
}
4546+
4547+
case (ast.expr_recv(?lhs, ?rhs, ?ann)) {
4548+
ret trans_recv(cx, lhs, rhs, ann);
4549+
}
4550+
44994551
// lval cases fall through to trans_lval and then
45004552
// possibly load the result (if it's non-structural).
45014553

@@ -4667,6 +4719,68 @@ fn trans_be(@block_ctxt cx, @ast.expr e) -> result {
46674719
ret trans_ret(cx, some(e));
46684720
}
46694721

4722+
fn trans_port(@block_ctxt cx, ast.ann ann) -> result {
4723+
4724+
auto t = node_ann_type(cx.fcx.ccx, ann);
4725+
auto unit_ty;
4726+
alt (t.struct) {
4727+
case (ty.ty_port(?t)) {
4728+
unit_ty = t;
4729+
}
4730+
case (_) {
4731+
cx.fcx.ccx.sess.bug("non-port type in trans_port");
4732+
fail;
4733+
}
4734+
}
4735+
4736+
auto llunit_ty = type_of(cx.fcx.ccx, unit_ty);
4737+
4738+
auto bcx = cx;
4739+
auto unit_sz = size_of(bcx, unit_ty);
4740+
bcx = unit_sz.bcx;
4741+
auto sub = trans_upcall(bcx, "upcall_new_port", vec(unit_sz.val));
4742+
bcx = sub.bcx;
4743+
auto llty = type_of(cx.fcx.ccx, t);
4744+
auto port_val = vi2p(bcx, sub.val, llty);
4745+
auto dropref = clean(bind drop_ty(_, port_val, t));
4746+
find_scope_cx(bcx).cleanups += vec(dropref);
4747+
4748+
ret res(bcx, port_val);
4749+
}
4750+
4751+
fn trans_chan(@block_ctxt cx, @ast.expr e, ast.ann ann) -> result {
4752+
4753+
auto bcx = cx;
4754+
auto prt = trans_expr(bcx, e);
4755+
bcx = prt.bcx;
4756+
4757+
auto prt_ty = ty.expr_ty(e);
4758+
auto prt_llty = type_of(bcx.fcx.ccx, prt_ty);
4759+
auto prt_val = vp2i(bcx, prt.val);
4760+
auto sub = trans_upcall(bcx, "upcall_new_chan", vec(prt_val));
4761+
bcx = sub.bcx;
4762+
4763+
auto chan_ty = node_ann_type(bcx.fcx.ccx, ann);
4764+
auto chan_llty = type_of(bcx.fcx.ccx, chan_ty);
4765+
auto chan_val = vi2p(bcx, sub.val, chan_llty);
4766+
auto dropref = clean(bind drop_ty(_, chan_val, chan_ty));
4767+
find_scope_cx(bcx).cleanups += vec(dropref);
4768+
4769+
// TODO: Do I need to do anything with the port's refcount?
4770+
4771+
ret res(bcx, chan_val);
4772+
}
4773+
4774+
fn trans_send(@block_ctxt cx, @ast.expr lhs, @ast.expr rhs,
4775+
ast.ann ann) -> result {
4776+
fail;
4777+
}
4778+
4779+
fn trans_recv(@block_ctxt cx, @ast.expr lhs, @ast.expr rhs,
4780+
ast.ann ann) -> result {
4781+
fail;
4782+
}
4783+
46704784
fn init_local(@block_ctxt cx, @ast.local local) -> result {
46714785

46724786
// Make a note to drop this slot on the way out.

src/comp/middle/ty.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,8 @@ fn type_is_boxed(@t ty) -> bool {
411411
case (ty_str) { ret true; }
412412
case (ty_vec(_)) { ret true; }
413413
case (ty_box(_)) { ret true; }
414+
case (ty_port(_)) { ret true; }
415+
case (ty_chan(_)) { ret true; }
414416
case (_) { ret false; }
415417
}
416418
fail;
@@ -759,6 +761,10 @@ fn expr_ty(@ast.expr expr) -> @t {
759761
case (ast.expr_index(_, _, ?ann)) { ret ann_to_type(ann); }
760762
case (ast.expr_path(_, _, ?ann)) { ret ann_to_type(ann); }
761763
case (ast.expr_ext(_, _, _, _, ?ann)) { ret ann_to_type(ann); }
764+
case (ast.expr_port(?ann)) { ret ann_to_type(ann); }
765+
case (ast.expr_chan(_, ?ann)) { ret ann_to_type(ann); }
766+
case (ast.expr_send(_, _, ?ann)) { ret ann_to_type(ann); }
767+
case (ast.expr_recv(_, _, ?ann)) { ret ann_to_type(ann); }
762768

763769
case (ast.expr_fail) { ret plain_ty(ty_nil); }
764770
case (ast.expr_log(_)) { ret plain_ty(ty_nil); }

0 commit comments

Comments
 (0)