]> Cypherpunks repositories - gostls13.git/commitdiff
more on arbitrary receiver types
authorKen Thompson <ken@golang.org>
Fri, 3 Oct 2008 03:51:10 +0000 (20:51 -0700)
committerKen Thompson <ken@golang.org>
Fri, 3 Oct 2008 03:51:10 +0000 (20:51 -0700)
this CL passes the tests, but should
be considered unstable

R=r
OCL=16390
CL=16390

src/cmd/6g/gg.h
src/cmd/6g/obj.c
src/cmd/gc/dcl.c
src/cmd/gc/go.h
src/cmd/gc/subr.c
src/cmd/gc/walk.c

index 5a45aca873e45ab65daf2f03902f22a375e8a98b..a6b9bcaf2220add8f180d8d93b8aa8cf607736c8 100644 (file)
@@ -58,7 +58,10 @@ struct Sig
        char*   name;
        Sym*    sym;
        uint32  hash;
+       int32   perm;
        int32   offset;
+       int32   width;
+       int32   elemalg;
        Sig*    link;
 };
 
index 5b16e716d0ffa21b619f27858c06c6735d7cd66a..a44ebdf362427061893746e4e2a243e965de1294 100644 (file)
@@ -580,10 +580,13 @@ dumpsignatures(void)
                                a->name = sp+1;
                        
                        a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
-                       a->offset = o;
+                       a->perm = o;
                        snprint(namebuf, sizeof(namebuf), "%s_%s",
                                at.sym->name+5, f->sym->name);
                        a->sym = lookup(namebuf);
+                       a->offset = 0;
+                       a->elemalg = 0;
+                       a->width = 0;
 
                        o++;
                }
@@ -660,7 +663,7 @@ dumpsignatures(void)
                        ot += wi;
 
                        if(et == TINTER) {
-                               // sigi[++].offset = offset of method
+                               // sigi[++].perm = mapped offset of method
                                ot = rnd(ot, wi);
                                p = pc;
                                gins(ADATA, N, N);
@@ -668,19 +671,43 @@ dumpsignatures(void)
                                p->from.offset = ot;
                                p->from.scale = wi;
                                p->to = ac;
-                               p->to.offset = b->offset;
+                               p->to.offset = b->perm;
                                ot += wi;
                        } else {
-                               // leave space for 3 ints
-                               // offset, algorithm and width
+                               // sigt[++].offset = of embeded struct
                                ot = rnd(ot, wi);
+                               p = pc;
+                               gins(ADATA, N, N);
+                               p->from = at;
+                               p->from.offset = ot;
+                               p->from.scale = wi;
+                               p->to = ac;
+                               p->to.offset = b->offset;
                                ot += wi;
+
+                               // sigt[++].width = type size
                                ot = rnd(ot, wi);
+                               p = pc;
+                               gins(ADATA, N, N);
+                               p->from = at;
+                               p->from.offset = ot;
+                               p->from.scale = wi;
+                               p->to = ac;
+                               p->to.offset = b->width;
                                ot += wi;
+
+                               // sigt[++].elemalg = type algorithm
                                ot = rnd(ot, wi);
+                               p = pc;
+                               gins(ADATA, N, N);
+                               p->from = at;
+                               p->from.offset = ot;
+                               p->from.scale = wi;
+                               p->to = ac;
+                               p->to.offset = b->elemalg;
                                ot += wi;
 
-                               // sigs[++].fun = &method
+                               // sigt[++].fun = &method
                                ot = rnd(ot, widthptr);
                                p = pc;
                                gins(ADATA, N, N);
index 5839d4abef36aeeae24dbbe92e2aa528dd5412ad..d6f1b144247cdd040d8703c7e998b010814de1fa 100644 (file)
@@ -250,7 +250,6 @@ addmethod(Node *n, Type *t, int local)
 {
        Type *f, *d, *pa;
        Sym *st, *sf;
-       int ptr;
 
        // get field sym
        if(n == N)
@@ -272,29 +271,11 @@ addmethod(Node *n, Type *t, int local)
        if(pa == T)
                goto bad;
 
-       switch(algtype(pa)) {
-       default:
-               goto bad;
-       case ASIMP:
-       case APTR:
-       case ASTRING:
-               break;
-       }
-
-       // optionally rip off ptr to type
-       ptr = 0;
-       if(isptr[pa->etype]) {
-               if(pa->sym == S || pa->sym->name[0] == '_') {
-                       ptr = 1;
-                       pa = pa->type;
-                       if(pa == T)
-                               goto bad;
-               }
-       }
-       if(pa->etype == TINTER)
-               yyerror("no methods on interfaces");
-
        // and finally the receiver sym
+       f = ismethod(pa);
+       if(f == T)
+               goto bad;
+       pa = f;
        st = pa->sym;
        if(st == S)
                goto bad;
@@ -306,11 +287,6 @@ addmethod(Node *n, Type *t, int local)
        n = nod(ODCLFIELD, newname(sf), N);
        n->type = t;
 
-       if(pa->method == T)
-               pa->methptr = ptr;
-       if(pa->methptr != ptr)
-               yyerror("combination of direct and ptr receivers of: %S", st);
-
        d = T;  // last found
        for(f=pa->method; f!=T; f=f->down) {
                if(f->etype != TFIELD)
@@ -331,7 +307,7 @@ addmethod(Node *n, Type *t, int local)
                stotype(n, &d->down);
 
        if(dflag())
-               print("method         %S of type %s%S\n", sf, (ptr? "*":""), st);
+               print("method         %S of type %T\n", sf, pa);
        return;
 
 bad:
@@ -450,8 +426,10 @@ funcargs(Type *ft)
                        all |= 2;
                t = structnext(&save);
        }
+
+       // this test is remarkedly similar to checkarglist
        if(all == 3)
-               yyerror("output parameters are all named or not named");
+               yyerror("cannot mix anonymous and named output arguments");
 
        ft->outnamed = 0;
        if(all == 1)
index d38c8cb38fb7638f1f06761c9711bf997cb6a1a6..28a2a626da1f18d08a6e1e7bc34096d2722f59d0 100644 (file)
@@ -571,7 +571,7 @@ int isptrto(Type*, int);
 int    isptrarray(Type*);
 int    isptrdarray(Type*);
 int    isinter(Type*);
-int    ismethod(Type*);
+Type*  ismethod(Type*);
 Sym*   signame(Type*);
 int    bytearraysz(Type*);
 int    eqtype(Type*, Type*, int);
index 4514f39140c0bf2e08e4bedf5309eb04e06aeaf8..d2c6a13ce61ac1f9f5a700a5472041883d6e8763 100644 (file)
@@ -1357,18 +1357,59 @@ isinter(Type *t)
        return 0;
 }
 
-int
+Type*
 ismethod(Type *t)
 {
-       // OLD WAY
-       if(isptrto(t, TSTRUCT))
-               return 1;
-       return 0;
+       int a;
+       Sym *s;
 
-       // NEW WAY - but doesnt work yet
-       if(t != T && t->method != T)
-               return 1;
-       return 0;
+       if(t == T)
+               return T;
+
+       a = algtype(t);
+
+       // direct receiver
+       s = t->sym;
+       if(s != S && s->name[0] != '_') {
+               if(t->methptr == 2)
+                       goto both;
+               t->methptr |= 1;
+               goto out;
+       }
+
+       // pointer receiver
+       if(!isptr[t->etype])
+               return T;
+
+       t = t->type;
+       if(t == T)
+               return T;
+
+       s = t->sym;
+       if(s != S && s->name[0] != '_') {
+               if(t->methptr == 1)
+                       goto both;
+               t->methptr |= 2;
+               goto out;
+       }
+
+       return T;
+
+both:
+       yyerror("type %T used as both direct and indirect method", t);
+       t->methptr = 3;
+
+out:
+       switch(a) {
+       default:
+               yyerror("type %T cannot be used as a method", t);
+       case ASIMP:
+       case APTR:
+       case ASTRING:
+               break;
+       }
+
+       return t;
 }
 
 Sym*
index cc06abc6e5f9f5c05dbabb782489d6afb98615ad..f3aafc4aad7f7702f3600c42a419db7e773dc6c0 100644 (file)
@@ -1598,9 +1598,12 @@ ascompat(Type *t1, Type *t2)
 //     if(eqtype(t2, nilptr, 0))
 //             return 1;
 
-       if(isinter(t1))
-               if(ismethod(t2) || isinter(t2))
+       if(isinter(t1)) {
+               if(isinter(t2))
                        return 1;
+               if(ismethod(t2))
+                       return 1;
+       }
 
        if(isinter(t2))
                if(ismethod(t1))
@@ -2445,15 +2448,20 @@ isandss(Type *lt, Node *r)
 
        rt = r->type;
        if(isinter(lt)) {
-               if(ismethod(rt))
+               if(isinter(rt)) {
+                       if(!eqtype(rt, lt, 0))
+                               return I2I;
+                       return Inone;
+               }
+               if(ismethod(rt) != T)
                        return T2I;
-               if(isinter(rt) && !eqtype(rt, lt, 0))
-                       return I2I;
+               return Inone;
        }
 
-       if(ismethod(lt)) {
-               if(isinter(rt))
+       if(isinter(rt)) {
+               if(ismethod(lt) != T)
                        return I2T;
+               return Inone;
        }
 
        return Inone;