]> Cypherpunks repositories - gostls13.git/commitdiff
len and cap on chans
authorRuss Cox <rsc@golang.org>
Thu, 20 Aug 2009 18:12:04 +0000 (11:12 -0700)
committerRuss Cox <rsc@golang.org>
Thu, 20 Aug 2009 18:12:04 +0000 (11:12 -0700)
R=ken
OCL=33599
CL=33599

doc/go_spec.html
src/cmd/6g/cgen.c
src/cmd/8g/cgen.c
src/cmd/gc/align.c
src/pkg/runtime/chan.c
test/chancap.go [new file with mode: 0644]

index 789232c6a00d3ec4947f85564702858e5324b3af..2190dca3fc819b51b45bf0caa2dabec0671d5965 100644 (file)
@@ -4345,10 +4345,6 @@ The following minimal alignment properties are guaranteed:
 <p>
 <font color=red>
 Implementation does not honor the restriction on goto statements and targets (no intervening declarations).
-<br/>
-cap() does not work on chans.
-<br/>
-len() does not work on chans.
 </font>
 </p>
 
index 97af9349bb5130b53b5af056fd60be7b241bbe9e..d36c0e15da2f8aec8d31b3f4ee876209e5a06615 100644 (file)
@@ -242,8 +242,8 @@ cgen(Node *n, Node *res)
                break;
 
        case OLEN:
-               if(istype(nl->type, TMAP)) {
-                       // map has len in the first 32-bit word.
+               if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) {
+                       // map and chan have len in the first 32-bit word.
                        // a zero pointer means zero length
                        regalloc(&n1, types[tptr], res);
                        cgen(nl, &n1);
@@ -279,6 +279,28 @@ cgen(Node *n, Node *res)
                break;
 
        case OCAP:
+               if(istype(nl->type, TCHAN)) {
+                       // chan has cap in the second 32-bit word.
+                       // a zero pointer means zero length
+                       regalloc(&n1, types[tptr], res);
+                       cgen(nl, &n1);
+
+                       nodconst(&n2, types[tptr], 0);
+                       gins(optoas(OCMP, types[tptr]), &n1, &n2);
+                       p1 = gbranch(optoas(OEQ, types[tptr]), T);
+
+                       n2 = n1;
+                       n2.op = OINDREG;
+                       n2.xoffset = 4;
+                       n2.type = types[TINT32];
+                       gmove(&n2, &n1);
+
+                       patch(p1, pc);
+
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       break;
+               }
                if(isslice(nl->type)) {
                        regalloc(&n1, types[tptr], res);
                        agen(nl, &n1);
index 25f700ae9f51511530b75311d376bc7e90ef01a3..db1986df9850a0e976ac0b19e2bbe514d0f89ea0 100644 (file)
@@ -237,7 +237,7 @@ cgen(Node *n, Node *res)
                break;
 
        case OLEN:
-               if(istype(nl->type, TMAP)) {
+               if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) {
                        // map has len in the first 32-bit word.
                        // a zero pointer means zero length
                        tempalloc(&n1, types[tptr]);
@@ -280,6 +280,28 @@ cgen(Node *n, Node *res)
                break;
 
        case OCAP:
+               if(istype(nl->type, TCHAN)) {
+                       // chan has cap in the second 32-bit word.
+                       // a zero pointer means zero length
+                       regalloc(&n1, types[tptr], res);
+                       cgen(nl, &n1);
+
+                       nodconst(&n2, types[tptr], 0);
+                       gins(optoas(OCMP, types[tptr]), &n1, &n2);
+                       p1 = gbranch(optoas(OEQ, types[tptr]), T);
+
+                       n2 = n1;
+                       n2.op = OINDREG;
+                       n2.xoffset = 4;
+                       n2.type = types[TINT32];
+                       gmove(&n2, &n1);
+
+                       patch(p1, pc);
+
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       break;
+               }
                if(isslice(nl->type)) {
                        igen(nl, &n1, res);
                        n1.op = OINDREG;
index 81ea9a7fe83ffbc1738a0b6d430eec2e8fb839cc..bd8b690471a60591d6da187d9c60df358864c07d 100644 (file)
@@ -303,11 +303,10 @@ typeinit(void)
        okforbool[TBOOL] = 1;
 
        okforcap[TARRAY] = 1;
-       //okforcap[TCHAN] = 1;
-       //okforcap[TMAP] = 1;
+       okforcap[TCHAN] = 1;
 
        okforlen[TARRAY] = 1;
-       //okforlen[TCHAN] = 1;
+       okforlen[TCHAN] = 1;
        okforlen[TMAP] = 1;
        okforlen[TSTRING] = 1;
 
index 64a52d48a935267190bb1b9b0cfbc7881c379058..c72ea1dff9e5ef4de52171d74cf488a743fe8b54 100644 (file)
@@ -39,10 +39,10 @@ struct      WaitQ
 
 struct Hchan
 {
+       uint32  qcount;                 // total data in the q
+       uint32  dataqsiz;               // size of the circular q
        uint16  elemsize;
        uint16  closed;                 // Wclosed Rclosed errorcount
-       uint32  dataqsiz;               // size of the circular q
-       uint32  qcount;                 // total data in the q
        Alg*    elemalg;                // interface for element type
        Link*   senddataq;              // pointer for sender
        Link*   recvdataq;              // pointer for receiver
diff --git a/test/chancap.go b/test/chancap.go
new file mode 100644 (file)
index 0000000..15256f7
--- /dev/null
@@ -0,0 +1,27 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+       c := make(chan int, 10);
+       if len(c) != 0 || cap(c) != 10 {
+               panicln("chan len/cap ", len(c), cap(c), " want 0 10");
+       }
+
+       for i := 0; i < 3; i++ {
+               c <- i;
+       }
+       if len(c) != 3 || cap(c) != 10 {
+               panicln("chan len/cap ", len(c), cap(c), " want 3 10");
+       }
+       
+       c = make(chan int);
+       if len(c) != 0 || cap(c) != 0 {
+               panicln("chan len/cap ", len(c), cap(c), " want 0 0");
+       }
+}
+