diff --git a/src/cmd/6g/gobj.c b/src/cmd/6g/gobj.c index e990d661df..02dffbe4c5 100644 --- a/src/cmd/6g/gobj.c +++ b/src/cmd/6g/gobj.c @@ -510,25 +510,7 @@ duintxx(Sym *s, int off, uint64 v, int wid) } int -duint32(Sym *s, int off, uint32 v) -{ - return duintxx(s, off, v, 4); -} - -int -duint16(Sym *s, int off, uint32 v) -{ - return duintxx(s, off, v, 2); -} - -int -duintptr(Sym *s, int off, uint32 v) -{ - return duintxx(s, off, v, 8); -} - -int -dsymptr(Sym *s, int off, Sym *x) +dsymptr(Sym *s, int off, Sym *x, int xoff) { Prog *p; @@ -543,48 +525,46 @@ dsymptr(Sym *s, int off, Sym *x) p->to.type = D_ADDR; p->to.index = D_EXTERN; p->to.sym = x; - p->to.offset = 0; + p->to.offset = xoff; off += widthptr; return off; } - void -genembedtramp(Type *t, Sig *b) +genembedtramp(Type *rcvr, Type *method, Sym *newnam) { Sym *e; - int c, d, o, loaded; + int c, d, o, mov, add, loaded; Prog *p; Type *f; - e = lookup(b->name); + if(debug['r']) + print("genembedtramp %T %T %S\n", rcvr, method, newnam); + + e = method->sym; for(d=0; dname); + fatal("genembedtramp %T.%S", rcvr, method->sym); out: -// print("genembedtramp %d\n", d); -// print(" t = %lT\n", t); -// print(" name = %s\n", b->name); -// print(" sym = %S\n", b->sym); -// print(" hash = 0x%ux\n", b->hash); - - newplist()->name = newname(b->sym); + newplist()->name = newname(newnam); //TEXT main·S_test2(SB),7,$0 p = pc; gins(ATEXT, N, N); p->from.type = D_EXTERN; - p->from.sym = b->sym; + p->from.sym = newnam; p->to.type = D_CONST; p->to.offset = 0; p->from.scale = 7; //print("1. %P\n", p); + mov = AMOVQ; + add = AADDQ; loaded = 0; o = 0; for(c=d-1; c>=0; c--) { @@ -596,16 +576,16 @@ out: loaded = 1; //MOVQ 8(SP), AX p = pc; - gins(AMOVQ, N, N); + gins(mov, N, N); p->from.type = D_INDIR+D_SP; - p->from.offset = 8; + p->from.offset = widthptr; p->to.type = D_AX; //print("2. %P\n", p); } //MOVQ o(AX), AX p = pc; - gins(AMOVQ, N, N); + gins(mov, N, N); p->from.type = D_INDIR+D_AX; p->from.offset = o; p->to.type = D_AX; @@ -615,14 +595,14 @@ out: if(o != 0) { //ADDQ $XX, AX p = pc; - gins(AADDQ, N, N); + gins(add, N, N); p->from.type = D_CONST; p->from.offset = o; if(loaded) p->to.type = D_AX; else { p->to.type = D_INDIR+D_SP; - p->to.offset = 8; + p->to.offset = widthptr; } //print("4. %P\n", p); } @@ -630,10 +610,10 @@ out: //MOVQ AX, 8(SP) if(loaded) { p = pc; - gins(AMOVQ, N, N); + gins(mov, N, N); p->from.type = D_AX; p->to.type = D_INDIR+D_SP; - p->to.offset = 8; + p->to.offset = widthptr; //print("5. %P\n", p); } else { // TODO(rsc): obviously this is unnecessary, @@ -651,7 +631,7 @@ out: p = pc; gins(AJMP, N, N); p->to.type = D_EXTERN; - p->to.sym = methodsym(lookup(b->name), ptrto(f->type)); + p->to.sym = methodsym(method->sym, ptrto(f->type)); //print("6. %P\n", p); pc->as = ARET; // overwrite AEND diff --git a/src/cmd/8g/gobj.c b/src/cmd/8g/gobj.c index c5f67cc4ab..1e20add3fe 100644 --- a/src/cmd/8g/gobj.c +++ b/src/cmd/8g/gobj.c @@ -508,25 +508,7 @@ duintxx(Sym *s, int off, uint64 v, int wid) } int -duint32(Sym *s, int off, uint32 v) -{ - return duintxx(s, off, v, 4); -} - -int -duint16(Sym *s, int off, uint32 v) -{ - return duintxx(s, off, v, 2); -} - -int -duintptr(Sym *s, int off, uint32 v) -{ - return duintxx(s, off, v, 4); -} - -int -dsymptr(Sym *s, int off, Sym *x) +dsymptr(Sym *s, int off, Sym *x, int xoff) { Prog *p; @@ -541,68 +523,65 @@ dsymptr(Sym *s, int off, Sym *x) p->to.type = D_ADDR; p->to.index = D_EXTERN; p->to.sym = x; - p->to.offset = 0; + p->to.offset = xoff; off += widthptr; return off; } - void -genembedtramp(Type *t, Sig *b) +genembedtramp(Type *rcvr, Type *method, Sym *newnam) { Sym *e; - int c, d, o; + int c, d, o, mov, add, loaded; Prog *p; Type *f; - e = lookup(b->name); + e = method->sym; for(d=0; dname); + fatal("genembedtramp %T.%S", rcvr, method->sym); out: - if(d == 0) - return; - -// print("genembedtramp %d\n", d); -// print(" t = %lT\n", t); -// print(" name = %s\n", b->name); -// print(" sym = %S\n", b->sym); -// print(" hash = 0x%ux\n", b->hash); - - newplist()->name = newname(b->sym); + newplist()->name = newname(newnam); //TEXT main·S_test2(SB),7,$0 p = pc; gins(ATEXT, N, N); p->from.type = D_EXTERN; - p->from.sym = b->sym; + p->from.sym = newnam; p->to.type = D_CONST; p->to.offset = 0; p->from.scale = 7; //print("1. %P\n", p); - //MOVL 4(SP), AX - p = pc; - gins(AMOVL, N, N); - p->from.type = D_INDIR+D_SP; - p->from.offset = widthptr; - p->to.type = D_AX; -//print("2. %P\n", p); + mov = AMOVL; + add = AADDL; + loaded = 0; o = 0; for(c=d-1; c>=0; c--) { f = dotlist[c].field; o += f->width; if(!isptr[f->type->etype]) continue; + if(!loaded) { + loaded = 1; + //MOVL 4(SP), AX + p = pc; + gins(mov, N, N); + p->from.type = D_INDIR+D_SP; + p->from.offset = widthptr; + p->to.type = D_AX; +//print("2. %P\n", p); + } + //MOVL o(AX), AX p = pc; - gins(AMOVL, N, N); + gins(mov, N, N); p->from.type = D_INDIR+D_AX; p->from.offset = o; p->to.type = D_AX; @@ -612,20 +591,34 @@ out: if(o != 0) { //ADDL $XX, AX p = pc; - gins(AADDL, N, N); + gins(add, N, N); p->from.type = D_CONST; p->from.offset = o; - p->to.type = D_AX; + if(loaded) + p->to.type = D_AX; + else { + p->to.type = D_INDIR+D_SP; + p->to.offset = widthptr; + } //print("4. %P\n", p); } //MOVL AX, 4(SP) - p = pc; - gins(AMOVL, N, N); - p->from.type = D_AX; - p->to.type = D_INDIR+D_SP; - p->to.offset = widthptr; + if(loaded) { + p = pc; + gins(mov, N, N); + p->from.type = D_AX; + p->to.type = D_INDIR+D_SP; + p->to.offset = widthptr; //print("5. %P\n", p); + } else { + // TODO(rsc): obviously this is unnecessary, + // but 6l has a bug, and it can't handle + // JMP instructions too close to the top of + // a new function. + p = pc; + gins(ANOP, N, N); + } f = dotlist[0].field; //JMP main·*Sub_test2(SB) @@ -634,7 +627,7 @@ out: p = pc; gins(AJMP, N, N); p->to.type = D_EXTERN; - p->to.sym = methodsym(lookup(b->name), ptrto(f->type)); + p->to.sym = methodsym(method->sym, ptrto(f->type)); //print("6. %P\n", p); pc->as = ARET; // overwrite AEND diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 3b521dd2dd..eb7e94ca54 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -171,7 +171,7 @@ struct Type // TARRAY int32 bound; // negative is dynamic array - + int32 maplineno; // first use of TFORW as map key }; #define T ((Type*)0) @@ -550,6 +550,7 @@ EXTERN Idir* idirs; EXTERN Type* types[NTYPE]; EXTERN uchar simtype[NTYPE]; EXTERN uchar isptr[NTYPE]; +EXTERN uchar isforw[NTYPE]; EXTERN uchar isint[NTYPE]; EXTERN uchar isfloat[NTYPE]; EXTERN uchar issigned[NTYPE]; @@ -606,6 +607,7 @@ EXTERN int32 nhunk; EXTERN int32 thunk; EXTERN int exporting; +EXTERN int noargnames; EXTERN int funcdepth; @@ -1081,11 +1083,15 @@ void zhist(Biobuf *b, int line, vlong offset); void zname(Biobuf *b, Sym *s, int t); void nopout(Prog*); 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 dgostringptr(Sym*, int off, char *str); +int dgostrlitptr(Sym*, int off, Strlit*); +int dsymptr(Sym *s, int off, Sym *x, int xoff); +int duint8(Sym *s, int off, uint8 v); +int duint16(Sym *s, int off, uint16 v); int duint32(Sym *s, int off, uint32 v); -int duintptr(Sym *s, int off, uint32 v); +int duint64(Sym *s, int off, uint64 v); +int duintptr(Sym *s, int off, uint64 v); int duintxx(Sym *s, int off, uint64 v, int wid); -void genembedtramp(Type*, Sig*); +void genembedtramp(Type*, Type*, Sym*); int gen_as_init(Node*, Node*); diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c index 64d1898963..e43a97383d 100644 --- a/src/cmd/gc/obj.c +++ b/src/cmd/gc/obj.c @@ -140,6 +140,36 @@ ieeedtod(uint64 *ieee, double native) *ieee = ((uint64)h << 32) | l; } +int +duint8(Sym *s, int off, uint8 v) +{ + return duintxx(s, off, v, 1); +} + +int +duint16(Sym *s, int off, uint16 v) +{ + return duintxx(s, off, v, 2); +} + +int +duint32(Sym *s, int off, uint32 v) +{ + return duintxx(s, off, v, 4); +} + +int +duint64(Sym *s, int off, uint64 v) +{ + return duintxx(s, off, v, 8); +} + +int +duintptr(Sym *s, int off, uint64 v) +{ + return duintxx(s, off, v, widthptr); +} + static int sigcmp(Sig *a, Sig *b) { @@ -239,7 +269,7 @@ dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s) // using genembedtramp if all that is necessary // is a pointer adjustment and a JMP. if(f->embedded && isptr[ifacet->etype] && !isifacemethod(f)) - genembedtramp(ifacet, a); + genembedtramp(ifacet, f, a->sym); else genwrapper(ifacet, f, a->sym); } @@ -275,7 +305,7 @@ dumpsigt(Type *progt, Type *ifacet, Type *rcvrt, Type *methodt, Sym *s) 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 + ot = dsymptr(s, ot, b->sym, 0); // &method } // nil field name at end diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 88180f59eb..e397284de0 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -1117,7 +1117,10 @@ Tpretty(Fmt *fp, Type *t) fmtprint(fp, "func"); fmtprint(fp, "("); for(t1=getinargx(t)->type; t1; t1=t1->down) { - fmtprint(fp, "%T", t1); + if(noargnames && t1->etype == TFIELD) + fmtprint(fp, "%T", t1->type); + else + fmtprint(fp, "%T", t1); if(t1->down) fmtprint(fp, ", "); } @@ -1135,7 +1138,10 @@ Tpretty(Fmt *fp, Type *t) t1 = getoutargx(t)->type; fmtprint(fp, " ("); for(; t1; t1=t1->down) { - fmtprint(fp, "%T", t1); + if(noargnames && t1->etype == TFIELD) + fmtprint(fp, "%T", t1->type); + else + fmtprint(fp, "%T", t1); if(t1->down) fmtprint(fp, ", "); } @@ -1195,7 +1201,11 @@ Tconv(Fmt *fp) { char buf[500], buf1[500]; Type *t, *t1; - int et, exp; + int r, et, sharp, minus; + + sharp = (fp->flags & FmtSharp); + minus = (fp->flags & FmtLeft); + fp->flags &= ~(FmtSharp|FmtLeft); t = va_arg(fp->args, Type*); if(t == T) @@ -1208,17 +1218,19 @@ Tconv(Fmt *fp) } if(!debug['t']) { - exp = (fp->flags & FmtSharp); - if(exp) + if(sharp) exporting++; - if(Tpretty(fp, t) >= 0) { + if(minus) + noargnames++; + r = Tpretty(fp, t); + if(sharp) + exporting--; + if(minus) + noargnames--; + if(r >= 0) { t->trecur--; - if(exp) - exporting--; return 0; } - if(exp) - exporting--; } et = t->etype; @@ -2061,7 +2073,7 @@ typehash(Type *at, int addsym, int d) case TFUNC: t = at->type; - // skip this argument + // skip this (receiver) argument if(t != T) t = t->down; for(; t!=T; t=t->down) @@ -2845,8 +2857,6 @@ expandmeth(Sym *s, Type *t) if(t == T) return; -//print("s=%S t=%lT\n", s, t); - // generate all reachable methods slist = nil; expand1(t, nelem(dotlist)-1, 0); @@ -2858,15 +2868,16 @@ expandmeth(Sym *s, Type *t) c = adddot1(sl->field->sym, t, d, &f); if(c == 0) continue; - if(c == 1 && f == sl->field) + if(c == 1) { sl->good = 1; + sl->field = f; + } break; } } for(sl=slist; sl!=nil; sl=sl->link) { if(sl->good) { -//print(" %lT\n", sl->field); // add it to the base type method list f = typ(TFIELD); *f = *sl->field; @@ -2928,26 +2939,25 @@ structargs(Type **tl, int mustname) * and calls the T.M method. * The resulting function is for use in method tables. * - * rcvrtype - U + * rcvr - U * method - M func (t T)(), a TFIELD type struct * newnam - the eventual mangled name of this function */ void -genwrapper(Type *rcvrtype, Type *method, Sym *newnam) +genwrapper(Type *rcvr, Type *method, Sym *newnam) { Node *this, *in, *out, *fn, *args, *call; Node *l; Iter savel; - if(debug['r']) { + if(debug['r']) print("genwrapper rcvrtype=%T method=%T newnam=%S\n", - rcvrtype, method, newnam); - } + rcvr, method, newnam); dclcontext = PEXTERN; markdcl(); - this = nametodcl(newname(lookup(".this")), rcvrtype); + this = nametodcl(newname(lookup(".this")), rcvr); in = structargs(getinarg(method->type), 1); out = structargs(getoutarg(method->type), 0);