Commit 2acbc371 authored by Russ Cox's avatar Russ Cox

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
parent 74b546ae
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment