@@ -339,6 +339,14 @@ fn T_box(TypeRef t) -> TypeRef {
339
339
ret T_struct ( vec ( T_int ( ) , t) ) ;
340
340
}
341
341
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
+
342
350
fn T_crate ( type_names tn) -> TypeRef {
343
351
auto s = "crate" ;
344
352
if ( tn. name_has_type ( s) ) {
@@ -623,6 +631,12 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
623
631
case ( ty. ty_vec ( ?mt) ) {
624
632
llty = T_ptr ( T_vec ( type_of_inner ( cx, mt. ty , true ) ) ) ;
625
633
}
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
+ }
626
640
case ( ty. ty_tup ( ?elts) ) {
627
641
let vec[ TypeRef ] tys = vec ( ) ;
628
642
for ( ty. mt elt in elts) {
@@ -1609,6 +1623,28 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
1609
1623
T_int ( ) , C_int ( 0 ) ) ;
1610
1624
}
1611
1625
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
+
1612
1648
case ( ty. ty_obj( _) ) {
1613
1649
fn hit_zero( @block_ctxt cx, ValueRef v) -> result {
1614
1650
@@ -4496,6 +4532,22 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
4496
4532
ret trans_be( cx, e) ;
4497
4533
}
4498
4534
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
+
4499
4551
// lval cases fall through to trans_lval and then
4500
4552
// possibly load the result (if it's non-structural).
4501
4553
@@ -4667,6 +4719,68 @@ fn trans_be(@block_ctxt cx, @ast.expr e) -> result {
4667
4719
ret trans_ret( cx, some( e) ) ;
4668
4720
}
4669
4721
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
+
4670
4784
fn init_local( @block_ctxt cx, @ast. local local) -> result {
4671
4785
4672
4786
// Make a note to drop this slot on the way out.
0 commit comments