mirror of
https://github.com/golang/go
synced 2024-11-25 13:47:57 -07:00
various 6g cleanup:
* give genwrapper and genembedtramp the same signature. * move duint8, duint16, duint32, duint64, duintptr into gc. * tidy genwrapper. * bug involving struct field symbols in signature list. (hash-order dependent so hard to trigger) * new Type print format %#-T like %#T but omits names on function arguments. R=ken OCL=31237 CL=31237
This commit is contained in:
parent
74b546aefd
commit
2acbc37166
@ -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; d<nelem(dotlist); d++) {
|
||||
c = adddot1(e, t, d, nil);
|
||||
c = adddot1(e, rcvr, d, nil);
|
||||
if(c == 1)
|
||||
goto out;
|
||||
}
|
||||
fatal("genembedtramp %T.%s", t, b->name);
|
||||
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
|
||||
|
@ -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; d<nelem(dotlist); d++) {
|
||||
c = adddot1(e, t, d, nil);
|
||||
c = adddot1(e, rcvr, d, nil);
|
||||
if(c == 1)
|
||||
goto out;
|
||||
}
|
||||
fatal("genembedtramp %T.%s", t, b->name);
|
||||
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
|
||||
|
@ -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*);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user