]> Cypherpunks repositories - gostls13.git/commitdiff
move portable object routines (especially
authorRuss Cox <rsc@golang.org>
Tue, 31 Mar 2009 04:31:29 +0000 (21:31 -0700)
committerRuss Cox <rsc@golang.org>
Tue, 31 Mar 2009 04:31:29 +0000 (21:31 -0700)
signature generation) into gc.

R=ken
OCL=26933
CL=26933

src/cmd/6g/Makefile
src/cmd/6g/align.c
src/cmd/6g/gg.h
src/cmd/6g/gsubr.c
src/cmd/6g/obj.c
src/cmd/gc/Makefile
src/cmd/gc/go.h
src/cmd/gc/lex.c
src/cmd/gc/obj.c [new file with mode: 0644]
src/cmd/gc/subr.c

index 9a59858d7251cb4e132703e11f3d0ef78316eb4a..4d2b6ab97d8d14dd3f63020483c482d2fbe42cce 100644 (file)
@@ -15,11 +15,11 @@ HFILES=\
 
 OFILES=\
        list.$O\
+       obj.$O\
        align.$O\
        gen.$O\
        cgen.$O\
        gsubr.$O\
-       obj.$O\
        peep.$O\
        reg.$O\
        ../6l/enam.$O\
index 209ac324faeba621a01d3808ce166d0f44196f3a..fa7315057921fd207c65df904bc8f543caa22d68 100644 (file)
@@ -4,6 +4,10 @@
 
 #include "gg.h"
 
+int    thechar = '6';
+char*  thestring       = "amd64";
+
+
 /*
  * go declares several platform-specific type aliases:
  * int, uint, float, and uintptr
index af1e2c2ccca8eaea105163066afcb38458cfca2d..b3eddb3d359897629979f00f3c91a93ae483a072 100644 (file)
@@ -41,18 +41,6 @@ struct       Prog
        void*   reg;            // pointer to containing Reg struct
 };
 
-typedef        struct  Plist   Plist;
-struct Plist
-{
-       Node*   name;
-       Dcl*    locals;
-       Prog*   firstpc;
-       int     recur;
-       Plist*  link;
-};
-
-EXTERN Plist*  plist;
-EXTERN Plist*  plast;
 EXTERN Biobuf* bout;
 EXTERN int32   dynloc;
 EXTERN uchar   reg[D_NONE];
@@ -146,18 +134,5 @@ int        Rconv(Fmt*);
 int    Yconv(Fmt*);
 void   listinit(void);
 
-/*
- * obj
- */
-void   zname(Biobuf*, Sym*, int);
 void   zaddr(Biobuf*, Addr*, int);
-void   ieeedtod(Ieee*, double);
-void   dumpstrings(void);
-void   dumpsignatures(void);
-void   outhist(Biobuf*);
 
-/*
- * align
- */
-void   dowidth(Type*);
-uint32 rnd(uint32, uint32);
index ab4979a34b0e78172c37eea771a80a0a4b1a3e51..e47731309317c6d317936d131bf04d225ce97e35 100644 (file)
@@ -1938,10 +1938,39 @@ Prog*
 gjmp(Prog *to)
 {
        Prog *p;
-       
+
        p = gbranch(AJMP, T);
        if(to != P)
                patch(p, to);
        return p;
 }
 
+void
+ggloblnod(Node *nam, int32 width)
+{
+       Prog *p;
+
+       p = gins(AGLOBL, nam, N);
+       p->lineno = nam->lineno;
+       p->to.sym = S;
+       p->to.type = D_CONST;
+       p->to.offset = width;
+}
+
+void
+ggloblsym(Sym *s, int32 width, int dupok)
+{
+       Prog *p;
+
+       p = gins(AGLOBL, N, N);
+       p->from.type = D_EXTERN;
+       if(s == symstringo)
+               p->from.type = D_STATIC;
+       p->from.index = D_NONE;
+       p->from.sym = s;
+       p->to.type = D_CONST;
+       p->to.index = D_NONE;
+       p->to.offset = width;
+       if(dupok)
+               p->from.scale = DUPOK;
+}
index af375a1d455c9f1f6aadbffdfddf6d13076eee7a..26c2d929ce96fb297e7e1b597be570f9d47579a2 100644 (file)
 
 #include "gg.h"
 
-void
-dumpobj(void)
-{
-       Plist *pl;
-       Prog *p;
-       Dcl *d;
-       Sym *s;
-       Node *n;
-       struct { Sym *sym; short type; } h[NSYM];
-       int sf, st, t, sym;
-       Node n1;
-
-       // add nil plist w AEND
-       newplist();
-
-       bout = Bopen(outfile, OWRITE);
-       if(bout == nil)
-               fatal("cant open %s", outfile);
-
-       Bprint(bout, "amd64\n");
-       Bprint(bout, "  exports automatically generated from\n");
-       Bprint(bout, "  %s in package \"%s\"\n", curio.infile, package);
-       dumpexport();
-       Bprint(bout, "\n!\n");
-
-       outhist(bout);
-
-       // add globals
-       nodconst(&n1, types[TINT32], 0);
-       for(d=externdcl; d!=D; d=d->forw) {
-               if(d->op != ONAME)
-                       continue;
-
-               s = d->dsym;
-               if(s == S)
-                       fatal("external nil");
-               n = d->dnode;
-               if(n == N || n->type == T)
-                       fatal("external %S nil\n", s);
-
-               if(n->class == PFUNC)
-                       continue;
-
-               dowidth(n->type);
-               mpmovecfix(n1.val.u.xval, n->type->width);
-
-               p = pc;
-               gins(AGLOBL, s->oname, &n1);
-               p->lineno = s->oname->lineno;
-       }
-
-       dumpstrings();
-       dumpsignatures();
-
-       for(sym=0; sym<NSYM; sym++) {
-               h[sym].sym = S;
-               h[sym].type = 0;
-       }
-       sym = 1;
-
-       // fix up pc
-       pcloc = 0;
-       for(pl=plist; pl!=nil; pl=pl->link) {
-               for(p=pl->firstpc; p!=P; p=p->link) {
-                       p->loc = pcloc;
-                       pcloc++;
-               }
-       }
-
-       // put out functions
-       for(pl=plist; pl!=nil; pl=pl->link) {
-
-               if(debug['S']) {
-                       s = S;
-                       if(pl->name != N)
-                               s = pl->name->sym;
-                       print("\n--- prog list \"%S\" ---\n", s);
-                       for(p=pl->firstpc; p!=P; p=p->link)
-                               print("%P\n", p);
-               }
-
-               for(p=pl->firstpc; p!=P; p=p->link) {
-               jackpot:
-                       sf = 0;
-                       s = p->from.sym;
-                       while(s != S) {
-                               sf = s->sym;
-                               if(sf < 0 || sf >= NSYM)
-                                       sf = 0;
-                               t = p->from.type;
-                               if(t == D_ADDR)
-                                       t = p->from.index;
-                               if(h[sf].type == t)
-                               if(h[sf].sym == s)
-                                       break;
-                               s->sym = sym;
-                               zname(bout, s, t);
-                               h[sym].sym = s;
-                               h[sym].type = t;
-                               sf = sym;
-                               sym++;
-                               if(sym >= NSYM)
-                                       sym = 1;
-                               break;
-                       }
-                       st = 0;
-                       s = p->to.sym;
-                       while(s != S) {
-                               st = s->sym;
-                               if(st < 0 || st >= NSYM)
-                                       st = 0;
-                               t = p->to.type;
-                               if(t == D_ADDR)
-                                       t = p->to.index;
-                               if(h[st].type == t)
-                               if(h[st].sym == s)
-                                       break;
-                               s->sym = sym;
-                               zname(bout, s, t);
-                               h[sym].sym = s;
-                               h[sym].type = t;
-                               st = sym;
-                               sym++;
-                               if(sym >= NSYM)
-                                       sym = 1;
-                               if(st == sf)
-                                       goto jackpot;
-                               break;
-                       }
-                       Bputc(bout, p->as);
-                       Bputc(bout, p->as>>8);
-                       Bputc(bout, p->lineno);
-                       Bputc(bout, p->lineno>>8);
-                       Bputc(bout, p->lineno>>16);
-                       Bputc(bout, p->lineno>>24);
-                       zaddr(bout, &p->from, sf);
-                       zaddr(bout, &p->to, st);
-               }
-       }
-       Bterm(bout);
-}
-
-void
-Bputdot(Biobuf *b)
-{
-       // put out middle dot ยท
-       Bputc(b, 0xc2);
-       Bputc(b, 0xb7);
-}
-
 void
 zname(Biobuf *b, Sym *s, int t)
 {
@@ -198,13 +48,45 @@ zname(Biobuf *b, Sym *s, int t)
        Bputc(b, 0);
 }
 
+void
+zfile(Biobuf *b, char *p, int n)
+{
+       Bputc(b, ANAME);
+       Bputc(b, ANAME>>8);
+       Bputc(b, D_FILE);
+       Bputc(b, 1);
+       Bputc(b, '<');
+       Bwrite(b, p, n);
+       Bputc(b, 0);
+}
+
+void
+zhist(Biobuf *b, int line, vlong offset)
+{
+       Addr a;
+
+       Bputc(b, AHISTORY);
+       Bputc(b, AHISTORY>>8);
+       Bputc(b, line);
+       Bputc(b, line>>8);
+       Bputc(b, line>>16);
+       Bputc(b, line>>24);
+       zaddr(b, &zprog.from, 0);
+       a = zprog.to;
+       if(offset != 0) {
+               a.offset = offset;
+               a.type = D_CONST;
+       }
+       zaddr(b, &a, 0);
+}
+
 void
 zaddr(Biobuf *b, Addr *a, int s)
 {
        int32 l;
+       uint64 e;
        int i, t;
        char *n;
-       Ieee e;
 
        t = 0;
        if(a->index != D_NONE || a->scale != 0)
@@ -259,12 +141,12 @@ zaddr(Biobuf *b, Addr *a, int s)
                Bputc(b, s);
        if(t & T_FCONST) {
                ieeedtod(&e, a->dval);
-               l = e.l;
+               l = e;
                Bputc(b, l);
                Bputc(b, l>>8);
                Bputc(b, l>>16);
                Bputc(b, l>>24);
-               l = e.h;
+               l = e >> 32;
                Bputc(b, l);
                Bputc(b, l>>8);
                Bputc(b, l>>16);
@@ -284,95 +166,99 @@ zaddr(Biobuf *b, Addr *a, int s)
 }
 
 void
-outhist(Biobuf *b)
+dumpfuncs(void)
 {
-       Hist *h;
-       char *p, *q, *op;
-       Prog pg;
-       int n;
-
-       pg = zprog;
-       pg.as = AHISTORY;
-       for(h = hist; h != H; h = h->link) {
-               p = h->name;
-               op = 0;
-
-               if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') {
-                       op = p;
-                       p = pathname;
-               }
+       Plist *pl;
+       int sf, st, t, sym;
+       struct { Sym *sym; short type; } h[NSYM];
+       Sym *s;
+       Prog *p;
 
-               while(p) {
-                       q = utfrune(p, '/');
-                       if(q) {
-                               n = q-p;
-                               if(n == 0)
-                                       n = 1;          // leading "/"
-                               q++;
-                       } else {
-                               n = strlen(p);
-                               q = 0;
-                       }
-                       if(n) {
-                               Bputc(b, ANAME);
-                               Bputc(b, ANAME>>8);
-                               Bputc(b, D_FILE);
-                               Bputc(b, 1);
-                               Bputc(b, '<');
-                               Bwrite(b, p, n);
-                               Bputc(b, 0);
-                       }
-                       p = q;
-                       if(p == 0 && op) {
-                               p = op;
-                               op = 0;
-                       }
-               }
+       for(sym=0; sym<NSYM; sym++) {
+               h[sym].sym = S;
+               h[sym].type = 0;
+       }
+       sym = 1;
 
-               pg.lineno = h->line;
-               pg.to.type = zprog.to.type;
-               pg.to.offset = h->offset;
-               if(h->offset)
-                       pg.to.type = D_CONST;
-
-               Bputc(b, pg.as);
-               Bputc(b, pg.as>>8);
-               Bputc(b, pg.lineno);
-               Bputc(b, pg.lineno>>8);
-               Bputc(b, pg.lineno>>16);
-               Bputc(b, pg.lineno>>24);
-               zaddr(b, &pg.from, 0);
-               zaddr(b, &pg.to, 0);
+       // fix up pc
+       pcloc = 0;
+       for(pl=plist; pl!=nil; pl=pl->link) {
+               for(p=pl->firstpc; p!=P; p=p->link) {
+                       p->loc = pcloc;
+                       pcloc++;
+               }
        }
-}
 
-void
-ieeedtod(Ieee *ieee, double native)
-{
-       double fr, ho, f;
-       int exp;
+       // put out functions
+       for(pl=plist; pl!=nil; pl=pl->link) {
 
-       if(native < 0) {
-               ieeedtod(ieee, -native);
-               ieee->h |= 0x80000000L;
-               return;
-       }
-       if(native == 0) {
-               ieee->l = 0;
-               ieee->h = 0;
-               return;
+               if(debug['S']) {
+                       s = S;
+                       if(pl->name != N)
+                               s = pl->name->sym;
+                       print("\n--- prog list \"%S\" ---\n", s);
+                       for(p=pl->firstpc; p!=P; p=p->link)
+                               print("%P\n", p);
+               }
+
+               for(p=pl->firstpc; p!=P; p=p->link) {
+               jackpot:
+                       sf = 0;
+                       s = p->from.sym;
+                       while(s != S) {
+                               sf = s->sym;
+                               if(sf < 0 || sf >= NSYM)
+                                       sf = 0;
+                               t = p->from.type;
+                               if(t == D_ADDR)
+                                       t = p->from.index;
+                               if(h[sf].type == t)
+                               if(h[sf].sym == s)
+                                       break;
+                               s->sym = sym;
+                               zname(bout, s, t);
+                               h[sym].sym = s;
+                               h[sym].type = t;
+                               sf = sym;
+                               sym++;
+                               if(sym >= NSYM)
+                                       sym = 1;
+                               break;
+                       }
+                       st = 0;
+                       s = p->to.sym;
+                       while(s != S) {
+                               st = s->sym;
+                               if(st < 0 || st >= NSYM)
+                                       st = 0;
+                               t = p->to.type;
+                               if(t == D_ADDR)
+                                       t = p->to.index;
+                               if(h[st].type == t)
+                               if(h[st].sym == s)
+                                       break;
+                               s->sym = sym;
+                               zname(bout, s, t);
+                               h[sym].sym = s;
+                               h[sym].type = t;
+                               st = sym;
+                               sym++;
+                               if(sym >= NSYM)
+                                       sym = 1;
+                               if(st == sf)
+                                       goto jackpot;
+                               break;
+                       }
+                       Bputc(bout, p->as);
+                       Bputc(bout, p->as>>8);
+                       Bputc(bout, p->lineno);
+                       Bputc(bout, p->lineno>>8);
+                       Bputc(bout, p->lineno>>16);
+                       Bputc(bout, p->lineno>>24);
+                       zaddr(bout, &p->from, sf);
+                       zaddr(bout, &p->to, st);
+               }
        }
-       fr = frexp(native, &exp);
-       f = 2097152L;           /* shouldnt use fp constants here */
-       fr = modf(fr*f, &ho);
-       ieee->h = ho;
-       ieee->h &= 0xfffffL;
-       ieee->h |= (exp+1022L) << 20;
-       f = 65536L;
-       fr = modf(fr*f, &ho);
-       ieee->l = ho;
-       ieee->l <<= 16;
-       ieee->l |= (int32)(fr*f);
 }
 
 void
@@ -463,66 +349,91 @@ dumpstrings(void)
        }
 }
 
-static int
-sigcmp(Sig *a, Sig *b)
+int
+dstringptr(Sym *s, int off, char *str)
 {
-       return strcmp(a->name, b->name);
-}
+       Prog *p;
 
-static Addr    at, ao, ac, ad;
-static int     wi, ws, ot;
+       off = rnd(off, widthptr);
+       p = gins(ADATA, N, N);
+       p->from.type = D_EXTERN;
+       p->from.index = D_NONE;
+       p->from.sym = s;
+       p->from.offset = off;
+       p->from.scale = widthptr;
+       p->to.type = D_ADDR;
+       p->to.index = D_STATIC;
+       p->to.etype = TINT32;
+       p->to.sym = symstringo;
+       p->to.offset = stringo;
+       off += widthptr;
+
+       datastring(str, strlen(str)+1);
+       return off;
+}
 
-void
-ginsatoa(int fscale, int toffset)
+int
+duintxx(Sym *s, int off, uint64 v, int wid)
 {
        Prog *p;
 
-       p = pc;
-       ot = rnd(ot, fscale);
-
-       gins(ADATA, N, N);
-       p->from = at;
-       p->from.offset = ot;
-       p->from.scale = fscale;
-       p->to = ao;
-       p->to.offset = toffset;
-       ot += fscale;
+       off = rnd(off, wid);
+
+       p = gins(ADATA, N, N);
+       p->from.type = D_EXTERN;
+       p->from.index = D_NONE;
+       p->from.sym = s;
+       p->from.offset = off;
+       p->from.scale = wid;
+       p->to.type = D_CONST;
+       p->to.index = D_NONE;
+       p->to.offset = v;
+       off += wid;
+
+       return off;
 }
 
-void
-gensatac(int fscale, int toffset)
+int
+duint32(Sym *s, int off, uint32 v)
 {
-       Prog *p;
+       return duintxx(s, off, v, 4);
+}
 
-       p = pc;
-       ot = rnd(ot, fscale);
-
-       gins(ADATA, N, N);
-       p->from = at;
-       p->from.offset = ot;
-       p->from.scale = fscale;
-       p->to = ac;
-       p->to.offset = toffset;
-       ot += fscale;
+int
+duint16(Sym *s, int off, uint32 v)
+{
+       return duintxx(s, off, v, 2);
 }
 
-void
-gensatad(Sym *s)
+int
+duintptr(Sym *s, int off, uint32 v)
+{
+       return duintxx(s, off, v, 8);
+}
+
+int
+dsymptr(Sym *s, int off, Sym *x)
 {
        Prog *p;
 
-       p = pc;
-       ot = rnd(ot, widthptr);
+       off = rnd(off, widthptr);
 
-       gins(ADATA, N, N);
-       p->from = at;
-       p->from.offset = ot;
+       p = gins(ADATA, N, N);
+       p->from.type = D_EXTERN;
+       p->from.index = D_NONE;
+       p->from.sym = s;
+       p->from.offset = off;
        p->from.scale = widthptr;
-       p->to = ad;
-       p->to.sym = s;
-       ot += widthptr;
+       p->to.type = D_ADDR;
+       p->to.index = D_EXTERN;
+       p->to.sym = x;
+       p->to.offset = 0;
+       off += widthptr;
+
+       return off;
 }
 
+
 void
 genembedtramp(Type *t, Sig *b)
 {
@@ -615,405 +526,9 @@ out:
        pc->as = ARET;  // overwrite AEND
 }
 
-/*
- * Add DATA for signature s.
- *     progt - type in program
- *     ifacet - type stored in interface (==progt if small, ==ptrto(progt) if large)
- *     rcvrt - type used as method interface.  eqtype(ifacet, rcvrt) is always true,
- *             but ifacet might have a name that rcvrt does not.
- *     methodt - type with methods hanging off it (progt==*methodt sometimes)
- *
- * memory layout is Sigt struct from iface.c:
- *     struct  Sigt
- *     {
- *             byte*   name;                   // name of basic type
- *             Sigt*   link;                   // for linking into hash tables
- *             uint32  thash;                  // hash of type
- *             uint32  mhash;                  // hash of methods
- *             uint16  width;                  // width of base type in bytes
- *             uint16  alg;                    // algorithm
- *             uint32  pad;
- *             struct {
- *                     byte*   fname;
- *                     uint32  fhash;          // hash of type
- *                     uint32  offset;         // offset of substruct
- *                     void    (*fun)(void);
- *             } meth[1];                      // one or more - last name is nil
- *     };
- */
-
 void
-dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s)
+nopout(Prog *p)
 {
-       Type *f;
-       int o;
-       Sig *a, *b;
-       Prog *p;
-       char buf[NSYMB];
-       Type *this;
-       Iter savet;
-       Prog *oldlist;
-       Sym *method;
-       uint32 sighash;
-
-       at.sym = s;
-
-       a = nil;
-       o = 0;
-       oldlist = nil;
-       sighash = typehash(progt, 1, 0);
-       for(f=methodt->method; f!=T; f=f->down) {
-               if(f->type->etype != TFUNC)
-                       continue;
-
-               if(f->etype != TFIELD)
-                       fatal("dumpsignatures: not field");
-
-               method = f->sym;
-               if(method == nil)
-                       continue;
-
-               b = mal(sizeof(*b));
-               b->link = a;
-               a = b;
-
-               a->name = method->name;
-               a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0, 0);
-               if(!exportname(a->name))
-                       a->hash += PRIME10*stringhash(package);
-               a->perm = o;
-               a->sym = methodsym(method, rcvrt);
-
-               sighash = sighash*100003 + a->hash;
-
-               if(!a->sym->siggen) {
-                       a->sym->siggen = 1;
-                       // TODO(rsc): This test is still not quite right.
-
-                       this = structfirst(&savet, getthis(f->type))->type;
-                       if(isptr[this->etype] != isptr[ifacet->etype]) {
-                               if(oldlist == nil)
-                                       oldlist = pc;
-
-                               // indirect vs direct mismatch
-                               Sym *oldname, *newname;
-                               Type *oldthis, *newthis;
-
-                               newthis = ifacet;
-                               if(isptr[newthis->etype])
-                                       oldthis = ifacet->type;
-                               else
-                                       oldthis = ptrto(ifacet);
-                               newname = a->sym;
-                               oldname = methodsym(method, oldthis);
-                               genptrtramp(method, oldname, oldthis, f->type, newname, newthis);
-                       } else
-                       if(f->embedded) {
-                               // TODO(rsc): only works for pointer receivers
-                               if(oldlist == nil)
-                                       oldlist = pc;
-                               genembedtramp(ifacet, a);
-                       }
-               }
-               o++;
-       }
-
-       // restore data output
-       if(oldlist) {
-               // old list ended with AEND; change to ANOP
-               // so that the trampolines that follow can be found.
-               oldlist->as = ANOP;
-
-               // start new data list
-               newplist();
-       }
-
-       a = lsort(a, sigcmp);
-       ot = 0;
-       ot = rnd(ot, maxround); // base structure
-
-       // base of type signature contains parameters
-       ginsatoa(widthptr, stringo);            // name
-       ot = rnd(ot, widthptr)+widthptr;        // skip link
-       gensatac(wi, typehash(progt, 1, 0));    // thash
-       gensatac(wi, sighash);                  // mhash
-       gensatac(ws, progt->width);             // width
-       gensatac(ws, algtype(progt));           // algorithm
-
-       snprint(buf, sizeof buf, "%#T", progt);
-       datastring(buf, strlen(buf)+1);
-
-       for(b=a; b!=nil; b=b->link) {
-               ot = rnd(ot, maxround);         // base of substructure
-               ginsatoa(widthptr, stringo);    // field name
-               gensatac(wi, b->hash);          // hash
-               gensatac(wi, 0);                // offset
-               gensatad(b->sym);               // &method
-
-               datastring(b->name, strlen(b->name)+1);
-       }
-
-       // nil field name at end
-       ot = rnd(ot, maxround);
-       gensatac(widthptr, 0);
-
-       // set DUPOK to allow other .6s to contain
-       // the same signature.  only one will be chosen.
-       // should only happen for empty signatures
-       p = pc;
-       gins(AGLOBL, N, N);
-       p->from = at;
-       if(a == nil)
-               p->from.scale = DUPOK;
-       p->to = ac;
-       p->to.offset = ot;
-}
-
-/*
- * memory layout is Sigi struct from iface.c:
- *     struct  Sigi
- *     {
- *             byte*   name;
- *             uint32  hash;
- *             uint32  size;                   // number of methods
- *             struct {
- *                     byte*   fname;
- *                     uint32  fhash;
- *                     uint32  perm;           // location of fun in Sigt
- *             } meth[1];                      // [size+1] - last name is nil
- *     };
- */
-void
-dumpsigi(Type *t, Sym *s)
-{
-       Type *f;
-       Sym *s1;
-       int o;
-       Sig *a, *b;
-       Prog *p;
-       char buf[NSYMB];
-       uint32 sighash;
-
-       at.sym = s;
-
-       a = nil;
-       o = 0;
-       sighash = 0;
-       for(f=t->type; f!=T; f=f->down) {
-               if(f->type->etype != TFUNC)
-                       continue;
-
-               if(f->etype != TFIELD)
-                       fatal("dumpsignatures: not field");
-
-               s1 = f->sym;
-               if(s1 == nil)
-                       continue;
-
-               b = mal(sizeof(*b));
-               b->link = a;
-               a = b;
-
-               a->name = s1->name;
-               a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0, 0);
-               if(!exportname(a->name))
-                       a->hash += PRIME10*stringhash(package);
-               a->perm = o;
-               a->sym = methodsym(f->sym, t);
-               a->offset = 0;
-
-               sighash = sighash*100003 + a->hash;
-
-               o++;
-       }
-
-       a = lsort(a, sigcmp);
-       ot = 0;
-       ot = rnd(ot, maxround); // base structure
-
-       // sigi[0].name = ""
-       ginsatoa(widthptr, stringo);
-
-       // save type name for runtime error message.
-       snprint(buf, sizeof buf, "%#T", t);
-       datastring(buf, strlen(buf)+1);
-
-       // first field of an interface signature
-       // contains the count and is not a real entry
-
-       // sigi[0].hash = sighash
-       gensatac(wi, sighash);
-
-       // sigi[0].offset = count
-       o = 0;
-       for(b=a; b!=nil; b=b->link)
-               o++;
-       gensatac(wi, o);
-
-       for(b=a; b!=nil; b=b->link) {
-//print("      %s\n", b->name);
-               ot = rnd(ot, maxround); // base structure
-
-               // sigx[++].name = "fieldname"
-               ginsatoa(widthptr, stringo);
-
-               // sigx[++].hash = hashcode
-               gensatac(wi, b->hash);
-
-               // sigi[++].perm = mapped offset of method
-               gensatac(wi, b->perm);
-
-               datastring(b->name, strlen(b->name)+1);
-       }
-
-       // nil field name at end
-       ot = rnd(ot, maxround);
-       gensatac(widthptr, 0);
-
-       p = pc;
-       gins(AGLOBL, N, N);
-       p->from = at;
-       p->from.scale = DUPOK;
-       p->to = ac;
-       p->to.offset = ot;
+       p->as = ANOP;
 }
 
-void
-dumpsignatures(void)
-{
-       int et;
-       Dcl *d, *x;
-       Type *t, *progt, *methodt, *ifacet, *rcvrt;
-       Sym *s;
-       Prog *p;
-
-       memset(&at, 0, sizeof(at));
-       memset(&ao, 0, sizeof(ao));
-       memset(&ac, 0, sizeof(ac));
-       memset(&ad, 0, sizeof(ad));
-
-       wi = types[TINT32]->width;
-       ws = types[TINT16]->width;
-
-       // sig structure
-       at.type = D_EXTERN;
-       at.index = D_NONE;
-       at.sym = S;                     // fill in
-       at.offset = 0;                  // fill in
-
-       // $string
-       ao.type = D_ADDR;
-       ao.index = D_STATIC;
-       ao.etype = TINT32;
-       ao.sym = symstringo;
-       ao.offset = 0;                  // fill in
-
-       // constant
-       ac.type = D_CONST;
-       ac.index = D_NONE;
-       ac.offset = 0;                  // fill in
-
-       // $method
-       ad.type = D_ADDR;
-       ad.index = D_EXTERN;
-       ad.sym = S;                     // fill in
-       ad.offset = 0;
-
-       // copy externdcl list to signatlist
-       for(d=externdcl; d!=D; d=d->forw) {
-               if(d->op != OTYPE)
-                       continue;
-
-               t = d->dtype;
-               if(t == T)
-                       continue;
-
-               s = signame(t);
-               if(s == S)
-                       continue;
-
-               x = mal(sizeof(*d));
-               x->op = OTYPE;
-               if(t->etype == TINTER)
-                       x->dtype = t;
-               else
-                       x->dtype = ptrto(t);
-               x->forw = signatlist;
-               x->block = 0;
-               signatlist = x;
-//print("SIG = %lS %lS %lT\n", d->dsym, s, t);
-       }
-
-       // process signatlist
-       for(d=signatlist; d!=D; d=d->forw) {
-               if(d->op != OTYPE)
-                       continue;
-               t = d->dtype;
-               et = t->etype;
-               s = signame(t);
-               if(s == S)
-                       continue;
-
-               // only emit one
-               if(s->siggen)
-                       continue;
-               s->siggen = 1;
-
-               // interface is easy
-               if(et == TINTER || et == TDDD) {
-                       if(t->sym && !t->local)
-                               continue;
-                       dumpsigi(t, s);
-                       continue;
-               }
-
-               // non-interface is more complex
-               progt = t;
-               methodt = t;
-               ifacet = t;
-               rcvrt = t;
-
-               // if there's a pointer, methods are on base.
-               if(isptr[methodt->etype] && methodt->type->sym != S) {
-                       methodt = methodt->type;
-                       expandmeth(methodt->sym, methodt);
-
-                       // if methodt had a name, we don't want to see
-                       // it in the method names that go into the sigt.
-                       // e.g., if
-                       //      type item *rat
-                       // then item needs its own sigt distinct from *rat,
-                       // but it needs to have all of *rat's methods, using
-                       // the *rat (not item) in the method names.
-                       if(rcvrt->sym != S)
-                               rcvrt = ptrto(methodt);
-               }
-
-               // and if ifacet is too wide, the methods
-               // will see a pointer anyway.
-               if(ifacet->width > 8) {
-                       ifacet = ptrto(progt);
-                       rcvrt = ptrto(progt);
-               }
-
-               // don't emit non-trivial signatures for types defined outside this file.
-               // non-trivial signatures might also drag in generated trampolines,
-               // and ar can't handle duplicates of the trampolines.
-               // only pay attention to types with symbols, because
-               // the ... structs and maybe other internal structs
-               // don't get marked as local.
-               if(methodt->method && methodt->sym && !methodt->local)
-                       continue;
-
-//print("s=%S\n", s);
-               dumpsigt(progt, ifacet, rcvrt, methodt, s);
-       }
-
-       if(stringo > 0) {
-               p = pc;
-               gins(AGLOBL, N, N);
-               p->from = ao;
-               p->to = ac;
-               p->to.offset = stringo;
-       }
-}
index 2f79f31cbb855dabca106a69e004f1bd1fe97d3f..0fc15deaa89e8e59c3fc516fc5974108895a3d2a 100644 (file)
@@ -31,6 +31,7 @@ OFILES=\
        bits.$O\
        align.$O\
        gen.$O\
+       obj.$O\
 
 $(LIB): $(OFILES)
        ar rsc $(LIB) $(OFILES)
index 2654d48cc26f61db7158cd52d759b42d5aa0f271..62fd95a124799cdcffab55e15df528daba6cd376 100644 (file)
@@ -592,8 +592,8 @@ EXTERN      Node*   typeswvar;
 
 EXTERN char*   context;
 EXTERN char*   pkgcontext;
-EXTERN int     thechar;
-EXTERN char*   thestring;
+extern int     thechar;
+extern char*   thestring;
 EXTERN char*   hunk;
 EXTERN int32   nhunk;
 EXTERN int32   thunk;
@@ -979,6 +979,19 @@ struct     Label
 EXTERN Label*  labellist;
 EXTERN Label*  findlab(Sym*);
 
+typedef        struct  Plist   Plist;
+struct Plist
+{
+       Node*   name;
+       Dcl*    locals;
+       Prog*   firstpc;
+       int     recur;
+       Plist*  link;
+};
+
+EXTERN Plist*  plist;
+EXTERN Plist*  plast;
+
 EXTERN Prog*   continpc;
 EXTERN Prog*   breakpc;
 EXTERN Prog*   pc;
@@ -994,10 +1007,20 @@ Label*   findlab(Sym *s);
 void   gen(Node *n);
 void   newlab(int op, Sym *s);
 Node*  sysfunc(char *name);
+Plist* newplist(void);
 
+/*
+ *     obj.c
+ */
+void   Bputdot(Biobuf *b);
+void   dumpfuncs(void);
+void   dumpglobls(void);
+void   dumpobj(void);
+void   ieeedtod(uint64 *ieee, double native);
+void   outhist(Biobuf *b);
 
 /*
- *     gen.c/gsubr.c/obj.c
+ *     arch-specific gen.c/gsubr.c/obj.c
  */
 void   betypeinit(void);
 vlong  convvtox(vlong, int);
@@ -1021,3 +1044,21 @@ int      isfat(Type*);
 void   clearfat(Node *n);
 void   cgen(Node*, Node*);
 void   gused(Node*);
+void   dumpstrings(void);
+void   dumpsignatures(void);
+void   dumpfuncs(void);
+void   ggloblnod(Node *nam, int32 width);
+void   ggloblsym(Sym *s, int32 width, int dupok);
+void   zfile(Biobuf *b, char *p, int n);
+void   zhist(Biobuf *b, int line, vlong offset);
+void   zname(Biobuf *b, Sym *s, int t);
+void   dumpstrings(void);
+void   nopout(Prog*);
+void   datastring(char *s, int len);
+int    dstringptr(Sym *s, int off, char *str);
+int    dsymptr(Sym *s, int off, Sym *x);
+int    duint16(Sym *s, int off, uint32 v);
+int    duint32(Sym *s, int off, uint32 v);
+int    duintptr(Sym *s, int off, uint32 v);
+int    duintxx(Sym *s, int off, uint64 v, int wid);
+void   genembedtramp(Type*, Sig*);
index ab7ced37647fc13936ca40c5449ff9d9aadec576..c186058b4436a6a2bb142c0bca149c4bbdb91d53 100644 (file)
@@ -213,8 +213,6 @@ findpkg(String *name)
                goroot = getenv("GOROOT");
        }
 
-       // BOTCH need to get .6 from backend
-
        // try .a before .6.  important for building libraries:
        // if there is an array.6 in the array.a library,
        // want to find all of array.a, not just array.6.
@@ -222,7 +220,7 @@ findpkg(String *name)
                snprint(namebuf, sizeof(namebuf), "%s/%Z.a", p->dir, name);
                if(access(namebuf, 0) >= 0)
                        return 1;
-               snprint(namebuf, sizeof(namebuf), "%s/%Z.6", p->dir, name);
+               snprint(namebuf, sizeof(namebuf), "%s/%Z.%c", p->dir, name, thechar);
                if(access(namebuf, 0) >= 0)
                        return 1;
        }
@@ -230,14 +228,14 @@ findpkg(String *name)
        snprint(namebuf, sizeof(namebuf), "%Z.a", name);
        if(access(namebuf, 0) >= 0)
                return 1;
-       snprint(namebuf, sizeof(namebuf), "%Z.6", name);
+       snprint(namebuf, sizeof(namebuf), "%Z.%c", name, thechar);
        if(access(namebuf, 0) >= 0)
                return 1;
        if(goroot != nil) {
                snprint(namebuf, sizeof(namebuf), "%s/pkg/%Z.a", goroot, name);
                if(access(namebuf, 0) >= 0)
                        return 1;
-               snprint(namebuf, sizeof(namebuf), "%s/pkg/%Z.6", goroot, name);
+               snprint(namebuf, sizeof(namebuf), "%s/pkg/%Z.%c", goroot, name, thechar);
                if(access(namebuf, 0) >= 0)
                        return 1;
        }
@@ -1300,7 +1298,6 @@ mkpackage(char* pkg)
        lookup(package)->lexical = LPACK;
 
        if(outfile == nil) {
-               // BOTCH need to get .6 from backend
                p = strrchr(infile, '/');
                if(p == nil)
                        p = infile;
@@ -1310,7 +1307,6 @@ mkpackage(char* pkg)
                p = strrchr(namebuf, '.');
                if(p != nil)
                        *p = 0;
-               strncat(namebuf, ".6", sizeof(namebuf));
-               outfile = strdup(namebuf);
+               outfile = smprint("%s.%c", namebuf, thechar);
        }
 }
diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c
new file mode 100644 (file)
index 0000000..7c80ee2
--- /dev/null
@@ -0,0 +1,585 @@
+// 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.
+
+#include "go.h"
+
+/*
+ * architecture-independent object file output
+ */
+
+void
+dumpobj(void)
+{
+       bout = Bopen(outfile, OWRITE);
+       if(bout == nil)
+               fatal("cant open %s", outfile);
+
+       Bprint(bout, "%s\n", thestring);
+       Bprint(bout, "  exports automatically generated from\n");
+       Bprint(bout, "  %s in package \"%s\"\n", curio.infile, package);
+       dumpexport();
+       Bprint(bout, "\n!\n");
+
+       outhist(bout);
+
+       // add nil plist w AEND to catch
+       // auto-generated trampolines, data
+       newplist();
+
+       dumpglobls();
+       dumpstrings();
+       dumpsignatures();
+       dumpfuncs();
+
+       Bterm(bout);
+}
+
+void
+dumpglobls(void)
+{
+       Dcl *d;
+       Sym *s;
+       Node *n;
+
+       // add globals
+       for(d=externdcl; d!=D; d=d->forw) {
+               if(d->op != ONAME)
+                       continue;
+
+               s = d->dsym;
+               if(s == S)
+                       fatal("external nil");
+               n = d->dnode;
+               if(n == N || n->type == T)
+                       fatal("external %S nil\n", s);
+
+               if(n->class == PFUNC)
+                       continue;
+
+               dowidth(n->type);
+               ggloblnod(s->oname, n->type->width);
+       }
+}
+
+void
+Bputdot(Biobuf *b)
+{
+       // put out middle dot ยท
+       Bputc(b, 0xc2);
+       Bputc(b, 0xb7);
+}
+
+void
+outhist(Biobuf *b)
+{
+       Hist *h;
+       char *p, *q, *op;
+       int n;
+
+       for(h = hist; h != H; h = h->link) {
+               p = h->name;
+               op = 0;
+
+               if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') {
+                       op = p;
+                       p = pathname;
+               }
+
+               while(p) {
+                       q = utfrune(p, '/');
+                       if(q) {
+                               n = q-p;
+                               if(n == 0)
+                                       n = 1;          // leading "/"
+                               q++;
+                       } else {
+                               n = strlen(p);
+                               q = 0;
+                       }
+                       if(n)
+                               zfile(b, p, n);
+                       p = q;
+                       if(p == 0 && op) {
+                               p = op;
+                               op = 0;
+                       }
+               }
+
+               zhist(b, h->line, h->offset);
+       }
+}
+
+void
+ieeedtod(uint64 *ieee, double native)
+{
+       double fr, ho, f;
+       int exp;
+       uint32 h, l;
+
+       if(native < 0) {
+               ieeedtod(ieee, -native);
+               *ieee |= 1ULL<<63;
+               return;
+       }
+       if(native == 0) {
+               *ieee = 0;
+               return;
+       }
+       fr = frexp(native, &exp);
+       f = 2097152L;           /* shouldnt use fp constants here */
+       fr = modf(fr*f, &ho);
+       h = ho;
+       h &= 0xfffffL;
+       h |= (exp+1022L) << 20;
+       f = 65536L;
+       fr = modf(fr*f, &ho);
+       l = ho;
+       l <<= 16;
+       l |= (int32)(fr*f);
+       *ieee = ((uint64)h << 32) | l;
+}
+
+/*
+ * Add DATA for signature s.
+ *     progt - type in program
+ *     ifacet - type stored in interface (==progt if small, ==ptrto(progt) if large)
+ *     rcvrt - type used as method interface.  eqtype(ifacet, rcvrt) is always true,
+ *             but ifacet might have a name that rcvrt does not.
+ *     methodt - type with methods hanging off it (progt==*methodt sometimes)
+ *
+ * memory layout is Sigt struct from iface.c:
+ *     struct  Sigt
+ *     {
+ *             byte*   name;                   // name of basic type
+ *             Sigt*   link;                   // for linking into hash tables
+ *             uint32  thash;                  // hash of type
+ *             uint32  mhash;                  // hash of methods
+ *             uint16  width;                  // width of base type in bytes
+ *             uint16  alg;                    // algorithm
+ *             struct {
+ *                     byte*   fname;
+ *                     uint32  fhash;          // hash of type
+ *                     uint32  offset;         // offset of substruct
+ *                     void    (*fun)(void);
+ *             } meth[1];                      // one or more - last name is nil
+ *     };
+ */
+
+static int
+sigcmp(Sig *a, Sig *b)
+{
+       return strcmp(a->name, b->name);
+}
+
+void
+dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s)
+{
+       Type *f;
+       int o;
+       Sig *a, *b;
+       char buf[NSYMB];
+       Type *this;
+       Iter savet;
+       Prog *oldlist;
+       Sym *method;
+       uint32 sighash;
+       int ot;
+
+       a = nil;
+       o = 0;
+       oldlist = nil;
+       sighash = typehash(progt, 1, 0);
+       for(f=methodt->method; f!=T; f=f->down) {
+               if(f->type->etype != TFUNC)
+                       continue;
+
+               if(f->etype != TFIELD)
+                       fatal("dumpsignatures: not field");
+
+               method = f->sym;
+               if(method == nil)
+                       continue;
+
+               b = mal(sizeof(*b));
+               b->link = a;
+               a = b;
+
+               a->name = method->name;
+               a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0, 0);
+               if(!exportname(a->name))
+                       a->hash += PRIME10*stringhash(package);
+               a->perm = o;
+               a->sym = methodsym(method, rcvrt);
+
+               sighash = sighash*100003 + a->hash;
+
+               if(!a->sym->siggen) {
+                       a->sym->siggen = 1;
+                       // TODO(rsc): This test is still not quite right.
+
+                       this = structfirst(&savet, getthis(f->type))->type;
+                       if(isptr[this->etype] != isptr[ifacet->etype]) {
+                               if(oldlist == nil)
+                                       oldlist = pc;
+
+                               // indirect vs direct mismatch
+                               Sym *oldname, *newname;
+                               Type *oldthis, *newthis;
+
+                               newthis = ifacet;
+                               if(isptr[newthis->etype])
+                                       oldthis = ifacet->type;
+                               else
+                                       oldthis = ptrto(ifacet);
+                               newname = a->sym;
+                               oldname = methodsym(method, oldthis);
+                               genptrtramp(method, oldname, oldthis, f->type, newname, newthis);
+                       } else
+                       if(f->embedded) {
+                               // TODO(rsc): only works for pointer receivers
+                               if(oldlist == nil)
+                                       oldlist = pc;
+                               genembedtramp(ifacet, a);
+                       }
+               }
+               o++;
+       }
+
+       // restore data output
+       if(oldlist) {
+               // old list ended with AEND; change to ANOP
+               // so that the trampolines that follow can be found.
+               nopout(oldlist);
+
+               // start new data list
+               newplist();
+       }
+
+       a = lsort(a, sigcmp);
+       ot = 0;
+       ot = rnd(ot, maxround); // base structure
+
+       // base of type signature contains parameters
+       snprint(buf, sizeof buf, "%#T", progt);
+       ot = dstringptr(s, ot, buf);            // name
+       ot = duintptr(s, ot, 0);        // skip link
+       ot = duint32(s, ot, typehash(progt, 1, 0));     // thash
+       ot = duint32(s, ot, sighash);                   // mhash
+       ot = duint16(s, ot, progt->width);              // width
+       ot = duint16(s, ot, algtype(progt));            // algorithm
+
+       for(b=a; b!=nil; b=b->link) {
+               ot = rnd(ot, maxround);         // base of substructure
+               ot = dstringptr(s, ot, b->name);        // field name
+               ot = duint32(s, ot, b->hash);           // hash
+               ot = duint32(s, ot, 0);         // offset
+               ot = dsymptr(s, ot, b->sym);            // &method
+       }
+
+       // nil field name at end
+       ot = rnd(ot, maxround);
+       ot = duintptr(s, ot, 0);
+
+       // set DUPOK to allow other .6s to contain
+       // the same signature.  only one will be chosen.
+       // should only happen for empty signatures
+       ggloblsym(s, ot, a == nil);
+}
+
+/*
+ * memory layout is Sigi struct from iface.c:
+ *     struct  Sigi
+ *     {
+ *             byte*   name;
+ *             uint32  hash;
+ *             uint32  size;                   // number of methods
+ *             struct {
+ *                     byte*   fname;
+ *                     uint32  fhash;
+ *                     uint32  perm;           // location of fun in Sigt
+ *             } meth[1];                      // [size+1] - last name is nil
+ *     };
+ */
+void
+dumpsigi(Type *t, Sym *s)
+{
+       Type *f;
+       Sym *s1;
+       int o;
+       Sig *a, *b;
+       char buf[NSYMB];
+       uint32 sighash;
+       int ot;
+
+       a = nil;
+       o = 0;
+       sighash = 0;
+       for(f=t->type; f!=T; f=f->down) {
+               if(f->type->etype != TFUNC)
+                       continue;
+
+               if(f->etype != TFIELD)
+                       fatal("dumpsignatures: not field");
+
+               s1 = f->sym;
+               if(s1 == nil)
+                       continue;
+
+               b = mal(sizeof(*b));
+               b->link = a;
+               a = b;
+
+               a->name = s1->name;
+               a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0, 0);
+               if(!exportname(a->name))
+                       a->hash += PRIME10*stringhash(package);
+               a->perm = o;
+               a->sym = methodsym(f->sym, t);
+               a->offset = 0;
+
+               sighash = sighash*100003 + a->hash;
+
+               o++;
+       }
+
+       a = lsort(a, sigcmp);
+       ot = 0;
+       ot = rnd(ot, maxround); // base structure
+
+       // sigi[0].name = type name, for runtime error message
+       snprint(buf, sizeof buf, "%#T", t);
+       ot = dstringptr(s, ot, buf);
+
+       // first field of an interface signature
+       // contains the count and is not a real entry
+
+       // sigi[0].hash = sighash
+       ot = duint32(s, ot, sighash);
+
+       // sigi[0].offset = count
+       o = 0;
+       for(b=a; b!=nil; b=b->link)
+               o++;
+       ot = duint32(s, ot, o);
+
+       for(b=a; b!=nil; b=b->link) {
+//print("      %s\n", b->name);
+               ot = rnd(ot, maxround); // base structure
+
+               // sigx[++].name = "fieldname"
+               // sigx[++].hash = hashcode
+               // sigi[++].perm = mapped offset of method
+               ot = dstringptr(s, ot, b->name);
+               ot = duint32(s, ot, b->hash);
+               ot = duint32(s, ot, b->perm);
+       }
+
+       // nil field name at end
+       ot = rnd(ot, maxround);
+       ot = duintptr(s, ot, 0);
+
+       // TODO(rsc): DUPOK should not be necessary here,
+       // and I am a bit worried that it is.  If I turn it off,
+       // I get multiple definitions for sigi.dotdotdot.
+       ggloblsym(s, ot, 1);
+}
+
+void
+dumpsignatures(void)
+{
+       int et;
+       Dcl *d, *x;
+       Type *t, *progt, *methodt, *ifacet, *rcvrt;
+       Sym *s;
+
+       // copy externdcl list to signatlist
+       for(d=externdcl; d!=D; d=d->forw) {
+               if(d->op != OTYPE)
+                       continue;
+
+               t = d->dtype;
+               if(t == T)
+                       continue;
+
+               s = signame(t);
+               if(s == S)
+                       continue;
+
+               x = mal(sizeof(*d));
+               x->op = OTYPE;
+               if(t->etype == TINTER)
+                       x->dtype = t;
+               else
+                       x->dtype = ptrto(t);
+               x->forw = signatlist;
+               x->block = 0;
+               signatlist = x;
+//print("SIG = %lS %lS %lT\n", d->dsym, s, t);
+       }
+
+       // process signatlist
+       for(d=signatlist; d!=D; d=d->forw) {
+               if(d->op != OTYPE)
+                       continue;
+               t = d->dtype;
+               et = t->etype;
+               s = signame(t);
+               if(s == S)
+                       continue;
+
+               // only emit one
+               if(s->siggen)
+                       continue;
+               s->siggen = 1;
+
+               // interface is easy
+               if(et == TINTER || et == TDDD) {
+                       if(t->sym && !t->local)
+                               continue;
+                       dumpsigi(t, s);
+                       continue;
+               }
+
+               // non-interface is more complex
+               progt = t;
+               methodt = t;
+               ifacet = t;
+               rcvrt = t;
+
+               // if there's a pointer, methods are on base.
+               if(isptr[methodt->etype] && methodt->type->sym != S) {
+                       methodt = methodt->type;
+                       expandmeth(methodt->sym, methodt);
+
+                       // if methodt had a name, we don't want to see
+                       // it in the method names that go into the sigt.
+                       // e.g., if
+                       //      type item *rat
+                       // then item needs its own sigt distinct from *rat,
+                       // but it needs to have all of *rat's methods, using
+                       // the *rat (not item) in the method names.
+                       if(rcvrt->sym != S)
+                               rcvrt = ptrto(methodt);
+               }
+
+               // and if ifacet is too wide, the methods
+               // will see a pointer anyway.
+               if(ifacet->width > 8) {
+                       ifacet = ptrto(progt);
+                       rcvrt = ptrto(progt);
+               }
+
+               // don't emit non-trivial signatures for types defined outside this file.
+               // non-trivial signatures might also drag in generated trampolines,
+               // and ar can't handle duplicates of the trampolines.
+               // only pay attention to types with symbols, because
+               // the ... structs and maybe other internal structs
+               // don't get marked as local.
+               if(methodt->method && methodt->sym && !methodt->local)
+                       continue;
+
+//print("s=%S\n", s);
+               dumpsigt(progt, ifacet, rcvrt, methodt, s);
+       }
+
+       if(stringo > 0)
+               ggloblsym(symstringo, stringo, 0);
+}
+
+void
+stringpool(Node *n)
+{
+       Pool *p;
+       int w;
+
+       if(n->op != OLITERAL || n->val.ctype != CTSTR) {
+               if(n->val.ctype == CTNIL)
+                       return;
+               fatal("stringpool: not string %N", n);
+       }
+
+       p = mal(sizeof(*p));
+
+       p->sval = n->val.u.sval;
+       p->link = nil;
+
+       if(poolist == nil)
+               poolist = p;
+       else
+               poolast->link = p;
+       poolast = p;
+
+       w = types[TINT32]->width;
+       symstringo->offset += w;                // len
+       symstringo->offset += p->sval->len;     // str[len]
+       symstringo->offset = rnd(symstringo->offset, w);
+}
+
+Sig*
+lsort(Sig *l, int(*f)(Sig*, Sig*))
+{
+       Sig *l1, *l2, *le;
+
+       if(l == 0 || l->link == 0)
+               return l;
+
+       l1 = l;
+       l2 = l;
+       for(;;) {
+               l2 = l2->link;
+               if(l2 == 0)
+                       break;
+               l2 = l2->link;
+               if(l2 == 0)
+                       break;
+               l1 = l1->link;
+       }
+
+       l2 = l1->link;
+       l1->link = 0;
+       l1 = lsort(l, f);
+       l2 = lsort(l2, f);
+
+       /* set up lead element */
+       if((*f)(l1, l2) < 0) {
+               l = l1;
+               l1 = l1->link;
+       } else {
+               l = l2;
+               l2 = l2->link;
+       }
+       le = l;
+
+       for(;;) {
+               if(l1 == 0) {
+                       while(l2) {
+                               le->link = l2;
+                               le = l2;
+                               l2 = l2->link;
+                       }
+                       le->link = 0;
+                       break;
+               }
+               if(l2 == 0) {
+                       while(l1) {
+                               le->link = l1;
+                               le = l1;
+                               l1 = l1->link;
+                       }
+                       break;
+               }
+               if((*f)(l1, l2) < 0) {
+                       le->link = l1;
+                       le = l1;
+                       l1 = l1->link;
+               } else {
+                       le->link = l2;
+                       le = l2;
+                       l2 = l2->link;
+               }
+       }
+       le->link = 0;
+       return l;
+}
+
index 403f3dd285496aebd92e35c3641083fbba9ecbbf..d6414f7eb6a467da9c684cff4de5ff91f04dba8a 100644 (file)
@@ -2403,102 +2403,6 @@ tempname(Node *n, Type *t)
        n->xoffset = -stksize;
 }
 
-void
-stringpool(Node *n)
-{
-       Pool *p;
-       int w;
-
-       if(n->op != OLITERAL || n->val.ctype != CTSTR) {
-               if(n->val.ctype == CTNIL)
-                       return;
-               fatal("stringpool: not string %N", n);
-       }
-
-       p = mal(sizeof(*p));
-
-       p->sval = n->val.u.sval;
-       p->link = nil;
-
-       if(poolist == nil)
-               poolist = p;
-       else
-               poolast->link = p;
-       poolast = p;
-
-       w = types[TINT32]->width;
-       symstringo->offset += w;                // len
-       symstringo->offset += p->sval->len;     // str[len]
-       symstringo->offset = rnd(symstringo->offset, w);
-}
-
-Sig*
-lsort(Sig *l, int(*f)(Sig*, Sig*))
-{
-       Sig *l1, *l2, *le;
-
-       if(l == 0 || l->link == 0)
-               return l;
-
-       l1 = l;
-       l2 = l;
-       for(;;) {
-               l2 = l2->link;
-               if(l2 == 0)
-                       break;
-               l2 = l2->link;
-               if(l2 == 0)
-                       break;
-               l1 = l1->link;
-       }
-
-       l2 = l1->link;
-       l1->link = 0;
-       l1 = lsort(l, f);
-       l2 = lsort(l2, f);
-
-       /* set up lead element */
-       if((*f)(l1, l2) < 0) {
-               l = l1;
-               l1 = l1->link;
-       } else {
-               l = l2;
-               l2 = l2->link;
-       }
-       le = l;
-
-       for(;;) {
-               if(l1 == 0) {
-                       while(l2) {
-                               le->link = l2;
-                               le = l2;
-                               l2 = l2->link;
-                       }
-                       le->link = 0;
-                       break;
-               }
-               if(l2 == 0) {
-                       while(l1) {
-                               le->link = l1;
-                               le = l1;
-                               l1 = l1->link;
-                       }
-                       break;
-               }
-               if((*f)(l1, l2) < 0) {
-                       le->link = l1;
-                       le = l1;
-                       l1 = l1->link;
-               } else {
-                       le->link = l2;
-                       le = l2;
-                       l2 = l2->link;
-               }
-       }
-       le->link = 0;
-       return l;
-}
-
 void
 setmaxarg(Type *t)
 {