]> Cypherpunks repositories - gostls13.git/commitdiff
DOTDOTDOT
authorKen Thompson <ken@golang.org>
Sat, 1 Nov 2008 23:36:46 +0000 (16:36 -0700)
committerKen Thompson <ken@golang.org>
Sat, 1 Nov 2008 23:36:46 +0000 (16:36 -0700)
R=r
OCL=18317
CL=18317

src/cmd/6g/align.c
src/cmd/6g/gsubr.c
src/cmd/gc/go.h
src/cmd/gc/subr.c
src/cmd/gc/walk.c

index 64992ab6b9a2cb2ac6d0c977bed8eef50a19e8b8..28516df387887002586d4091420987405aa106f6 100644 (file)
@@ -119,6 +119,9 @@ dowidth(Type *t)
        case TFLOAT80:
                w = 10;
                break;
+       case TDDD:
+               w = 2*wptr;
+               break;
        case TINTER:            // implemented as 2 pointers
        case TFORWINTER:
                offmod(t);
index d8135e21e77f9cc52c6b2e8c6afa6596bb9d3443..3114eab27d7977b11396ce86003d4916cdbc9aa8 100644 (file)
@@ -1557,6 +1557,7 @@ isfat(Type *t)
        case TSTRUCT:
        case TARRAY:
        case TINTER:    // maybe remove later
+       case TDDD:      // maybe remove later
                return 1;
        }
        return 0;
index a0afb434dd148cc1c8ac920d5fed2a03c8adebbe..314333f741593a3e7a87e61defc77c598c1b5797 100644 (file)
@@ -597,6 +597,7 @@ int isptrarray(Type*);
 int    isptrdarray(Type*);
 int    isinter(Type*);
 int    isnilinter(Type*);
+int    isddd(Type*);
 Sym*   globalsig(Type*);
 Type*  ismethod(Type*);
 Type*  methtype(Type*);
index 09cba7d61bb22d7830732e8464854d9809ce2330..c0344a98993e075a8170753a4192376c0b0939e5 100644 (file)
@@ -818,6 +818,7 @@ etnames[] =
        [TBOOL]         = "BOOL",
        [TPTR32]        = "PTR32",
        [TPTR64]        = "PTR64",
+       [TDDD]          = "DDD",
        [TFUNC]         = "FUNC",
        [TARRAY]        = "ARRAY",
 //     [TDARRAY]       = "DARRAY",
@@ -1453,8 +1454,12 @@ isselect(Node *n)
 int
 isinter(Type *t)
 {
-       if(t != T && t->etype == TINTER)
-               return 1;
+       if(t != T) {
+               if(t->etype == TINTER)
+                       return 1;
+               if(t->etype == TDDD)
+                       return 1;
+       }
        return 0;
 }
 
@@ -1468,6 +1473,14 @@ isnilinter(Type *t)
        return 1;
 }
 
+int
+isddd(Type *t)
+{
+       if(t != T && t->etype == TDDD)
+               return 1;
+       return 0;
+}
+
 Type*
 ismethod(Type *t)
 {
@@ -1604,6 +1617,7 @@ globalsig(Type *t)
                return S;
 
        case TINTER:
+       case TDDD:
                if(isnilinter(t)) {
                        snprint(buf, sizeof(buf), "%s_%s", "sigi", "inter");
                        goto out;
@@ -1670,6 +1684,10 @@ signame(Type *t, int block)
        if(t == T)
                goto bad;
 
+       ss = globalsig(t);
+       if(ss != S)
+               return ss;
+
        s = t->sym;
        if(s == S) {
                if(isptr[t->etype]) {
@@ -1682,10 +1700,6 @@ signame(Type *t, int block)
                        goto bad;
        }
 
-       ss = globalsig(t);
-       if(ss != S)
-               return ss;
-
        e = "sigt";
        if(t->etype == TINTER)
                e = "sigi";
index 06f076d25076043dc2c7a3a13cea7f4ee84d97b9..f3bf6bdac030d31247a84d7507224f96ad60f8e1 100644 (file)
@@ -1555,10 +1555,7 @@ loop:
 
        a = nod(OAS, l, r);
        a = convas(a);
-       if(nn == N)
-               nn = a;
-       else
-               nn = list(a, nn);
+       nn = list(a, nn);
 
        l = listnext(&savel);
        r = listnext(&saver);
@@ -1595,10 +1592,7 @@ loop:
 
        a = nod(OAS, l, nodarg(r, fp));
        a = convas(a);
-       if(nn == N)
-               nn = a;
-       else
-               nn = list(a, nn);
+       nn = list(a, nn);
 
        l = listnext(&savel);
        r = structnext(&saver);
@@ -1606,6 +1600,109 @@ loop:
        goto loop;
 }
 
+/*
+ * make a tsig for the structure
+ * carrying the ... arguments
+ */
+Type*
+sigtype(Type *st)
+{
+       Dcl *x;
+       Sym *s;
+       Type *t;
+       static int sigdddgen;
+
+       dowidth(st);
+
+       sigdddgen++;
+       snprint(namebuf, sizeof(namebuf), "dsigddd_%d", sigdddgen);
+       s = lookup(namebuf);
+       t = newtype(s);
+       t = dodcltype(t);
+       updatetype(t, st);
+
+       // record internal type for signature generation
+       x = mal(sizeof(*x));
+       x->op = OTYPE;
+       x->dsym = s;
+       x->dtype = s->otype;
+       x->forw = signatlist;
+       x->block = block;
+       signatlist = x;
+
+       return s->otype;
+}
+
+/*
+ * package all the arguments that
+ * match a ... parameter into an
+ * automatic structure.
+ * then call the ... arg (interface)
+ * with a pointer to the structure
+ */
+Node*
+mkdotargs(Node *r, Iter *saver, Node *nn, Type *l, int fp)
+{
+       Type *t, *st, *ft;
+       Node *a, *n, *var;
+       Iter saven;
+
+       n = N;                  // list of assignments
+
+       st = typ(TSTRUCT);      // generated structure
+       ft = T;                 // last field
+       while(r != N) {
+               defaultlit(r);
+
+               // generate the next structure field
+               t = typ(TFIELD);
+               t->type = r->type;
+               if(ft == T)
+                       st->type = t;
+               else
+                       ft->down = t;
+               ft = t;
+
+               a = nod(OAS, N, r);
+               n = list(n, a);
+               r = listnext(saver);
+       }
+
+       // make a named type for the struct
+       st = sigtype(st);
+
+       // now we have the size, make the struct
+       var = nod(OXXX, N, N);
+       tempname(var, st);
+
+       // assign the fields to the struct
+       n = rev(n);
+       r = listfirst(&saven, &n);
+       t = st->type;
+       while(r != N) {
+               r->left = nod(OXXX, N, N);
+               *r->left = *var;
+               r->left->type = r->right->type;
+               r->left->xoffset += t->width;
+               nn = list(r, nn);
+               r = listnext(&saven);
+               t = t->down;
+       }
+
+       // last thing is to put assignment
+       // of a pointer to the structure to
+       // the DDD parameter
+
+       a = nod(OADDR, var, N);
+       a->type = ptrto(st);
+       a = nod(OAS, nodarg(l, fp), a);
+       a = convas(a);
+
+       nn = list(a, nn);
+
+       return nn;
+}
+
 Node*
 ascompatte(int op, Type **nl, Node **nr, int fp)
 {
@@ -1622,7 +1719,21 @@ ascompatte(int op, Type **nl, Node **nr, int fp)
        l = structfirst(&savel, nl);
        r = listfirst(&saver, nr);
        nn = N;
+
 loop:
+       if(l != T && isddd(l->type)) {
+               if(r != T && isddd(r->type)) {
+                       goto more;
+               }
+
+               nn = mkdotargs(r, &saver, nn, l, fp);
+
+               l = structnext(&savel);
+               if(l != T)
+                       yyerror("... must be last argument");
+               return rev(nn);
+       }
+
        if(l == T || r == N) {
                if(l != T || r != N)
                        yyerror("error in shape across %O", op);
@@ -1634,12 +1745,10 @@ loop:
                return N;
        }
 
+more:
        a = nod(OAS, nodarg(l, fp), r);
        a = convas(a);
-       if(nn == N)
-               nn = a;
-       else
-               nn = list(a, nn);
+       nn = list(a, nn);
 
        l = structnext(&savel);
        r = listnext(&saver);
@@ -2518,6 +2627,8 @@ isandss(Type *lt, Node *r)
        rt = r->type;
        if(isinter(lt)) {
                if(isinter(rt)) {
+                       if(isnilinter(lt) && isnilinter(rt))
+                               return Inone;
                        if(!eqtype(rt, lt, 0))
                                return I2I;
                        return Inone;
@@ -2649,6 +2760,9 @@ convas(Node *n)
        if(n->op != OAS)
                fatal("convas: not OAS %O", n->op);
 
+       lt = T;
+       rt = T;
+
        l = n->left;
        r = n->right;
        if(l == N || r == N)
@@ -2747,10 +2861,7 @@ colas(Node *nl, Node *nr)
                walktype(r, Erv);
                defaultlit(r);
                a = old2new(l, r->type);
-               if(n == N)
-                       n = a;
-               else
-                       n = list(n, a);
+               n = list(n, a);
 
                l = listnext(&savel);
                r = listnext(&saver);
@@ -2785,10 +2896,7 @@ multi:
                t = structfirst(&saver, getoutarg(t));
                while(l != N) {
                        a = old2new(l, t->type);
-                       if(n == N)
-                               n = a;
-                       else
-                               n = list(n, a);
+                       n = list(n, a);
                        l = listnext(&savel);
                        t = structnext(&saver);
                }
@@ -2877,16 +2985,12 @@ loop2:
        if(l == N) {
                r = rev(r);
                g = rev(g);
-               if(g != N)
-                       f = list(g, f);
+               f = list(g, f);
                r = list(f, r);
                return r;
        }
        if(l->ullman < UINF) {
-               if(r == N)
-                       r = l;
-               else
-                       r = list(l, r);
+               r = list(l, r);
                goto more;
        }
        if(f == N) {
@@ -2898,19 +3002,12 @@ loop2:
        a = nod(OXXX, N, N);
        tempname(a, l->right->type);
        a = nod(OAS, a, l->right);
-
-       if(g == N)
-               g = a;
-       else
-               g = list(a, g);
+       g = list(a, g);
 
        // put normal arg assignment on list
        // with fncall replaced by tempname
        l->right = a->left;
-       if(r == N)
-               r = l;
-       else
-               r = list(l, r);
+       r = list(l, r);
 
 more:
        l = listnext(&save);
@@ -3040,20 +3137,14 @@ reorder3(Node *n)
        q = N;
        l1 = listfirst(&save1, &n);
        while(l1 != N) {
-               if(q == N)
-                       q = l1;
-               else
-                       q = list(q, l1);
+               q = list(q, l1);
                l1 = listnext(&save1);
        }
 
        r = rev(r);
        l1 = listfirst(&save1, &r);
        while(l1 != N) {
-               if(q == N)
-                       q = l1;
-               else
-                       q = list(q, l1);
+               q = list(q, l1);
                l1 = listnext(&save1);
        }