mirror of
https://github.com/golang/go
synced 2024-11-12 08:50:22 -07:00
6g interface changes:
* allow conversion between nil interface and any type. * mark signatures as DUPOK so that multiple .6 can contain sigt.*[]byte and only one gets used. R=ken OCL=18538 CL=18542
This commit is contained in:
parent
6cd74b03f3
commit
1983121bbb
407
src/cmd/6g/obj.c
407
src/cmd/6g/obj.c
@ -516,7 +516,6 @@ gentramp(Type *t, Sig *b)
|
||||
int c, d, o;
|
||||
Prog *p;
|
||||
Type *f;
|
||||
Sym *msym;
|
||||
|
||||
e = lookup(b->name);
|
||||
for(d=0; d<nelem(dotlist); d++) {
|
||||
@ -596,292 +595,213 @@ out:
|
||||
}
|
||||
|
||||
void
|
||||
dumpsigt(void)
|
||||
dumpsigt(Type *t0, Sym *s)
|
||||
{
|
||||
Dcl *d, *x;
|
||||
Type *t, *f;
|
||||
Sym *s1, *s;
|
||||
int et, o;
|
||||
Type *f, *t;
|
||||
Sym *s1;
|
||||
int o;
|
||||
Sig *a, *b;
|
||||
Prog *p;
|
||||
char *sp;
|
||||
char buf[NSYMB];
|
||||
|
||||
/*
|
||||
* put all the names into a linked
|
||||
* list so that it may be generated in sorted order.
|
||||
* the runtime will be linear rather than quadradic
|
||||
*/
|
||||
for(d=signatlist; d!=D; d=d->forw) {
|
||||
if(d->op != OTYPE)
|
||||
continue;
|
||||
t = d->dtype;
|
||||
et = t->etype;
|
||||
if(et == TINTER)
|
||||
continue;
|
||||
at.sym = signame(t, d->block);
|
||||
if(at.sym == S)
|
||||
at.sym = s;
|
||||
|
||||
t = t0;
|
||||
if(isptr[t->etype] && t->type->sym != S) {
|
||||
t = t->type;
|
||||
expandmeth(t->sym, t);
|
||||
}
|
||||
|
||||
a = nil;
|
||||
o = 0;
|
||||
for(f=t->method; f!=T; f=f->down) {
|
||||
if(f->type->etype != TFUNC)
|
||||
continue;
|
||||
|
||||
// make unique
|
||||
if(at.sym->local != 1)
|
||||
continue;
|
||||
at.sym->local = 2;
|
||||
if(f->etype != TFIELD)
|
||||
fatal("dumpsignatures: not field");
|
||||
|
||||
s = d->dsym;
|
||||
if(s == S)
|
||||
s1 = f->sym;
|
||||
if(s1 == nil)
|
||||
continue;
|
||||
|
||||
if(s->name[0] == '_')
|
||||
continue;
|
||||
b = mal(sizeof(*b));
|
||||
b->link = a;
|
||||
a = b;
|
||||
|
||||
if(strcmp(s->opackage, package) != 0)
|
||||
continue;
|
||||
a->name = s1->name;
|
||||
a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
|
||||
a->perm = o;
|
||||
a->sym = methodsym(f->sym, t);
|
||||
a->offset = f->embedded; // need trampoline
|
||||
|
||||
expandmeth(s, t);
|
||||
o++;
|
||||
}
|
||||
|
||||
a = nil;
|
||||
o = 0;
|
||||
for(f=t->method; f!=T; f=f->down) {
|
||||
if(f->type->etype != TFUNC)
|
||||
continue;
|
||||
a = lsort(a, sigcmp);
|
||||
ot = 0;
|
||||
ot = rnd(ot, maxround); // base structure
|
||||
|
||||
if(f->etype != TFIELD)
|
||||
fatal("dumpsignatures: not field");
|
||||
// sigi[0].name = ""
|
||||
ginsatoa(widthptr, stringo);
|
||||
|
||||
s1 = f->sym;
|
||||
if(s1 == nil)
|
||||
continue;
|
||||
// save type name for runtime error message.
|
||||
snprint(buf, sizeof buf, "%#T", t0);
|
||||
datastring(buf, strlen(buf)+1);
|
||||
|
||||
b = mal(sizeof(*b));
|
||||
b->link = a;
|
||||
a = b;
|
||||
// first field of an type signature contains
|
||||
// the element parameters and is not a real entry
|
||||
if(t->methptr & 2)
|
||||
t = types[tptr];
|
||||
|
||||
a->name = s1->name;
|
||||
a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
|
||||
a->perm = o;
|
||||
a->sym = methodsym(f->sym, t);
|
||||
a->offset = f->embedded; // need trampoline
|
||||
// sigi[0].hash = elemalg
|
||||
gensatac(wi, algtype(t));
|
||||
|
||||
o++;
|
||||
}
|
||||
// sigi[0].offset = width
|
||||
gensatac(wi, t->width);
|
||||
|
||||
a = lsort(a, sigcmp);
|
||||
ot = 0;
|
||||
// skip the function
|
||||
gensatac(widthptr, 0);
|
||||
|
||||
for(b=a; b!=nil; b=b->link) {
|
||||
ot = rnd(ot, maxround); // base structure
|
||||
|
||||
// sigi[0].name = ""
|
||||
// sigx[++].name = "fieldname"
|
||||
ginsatoa(widthptr, stringo);
|
||||
|
||||
// save type name for runtime error message.
|
||||
// TODO(rsc): the * is a botch but right more often than not.
|
||||
snprint(buf, sizeof buf, "*%#T", t);
|
||||
datastring(buf, strlen(buf)+1);
|
||||
// sigx[++].hash = hashcode
|
||||
gensatac(wi, b->hash);
|
||||
|
||||
// first field of an type signature contains
|
||||
// the element parameters and is not a real entry
|
||||
// sigt[++].offset = of embeded struct
|
||||
gensatac(wi, 0);
|
||||
|
||||
t = d->dtype;
|
||||
if(t->methptr & 2)
|
||||
t = types[tptr];
|
||||
// sigt[++].fun = &method
|
||||
gensatad(b->sym);
|
||||
|
||||
// sigi[0].hash = elemalg
|
||||
gensatac(wi, algtype(t));
|
||||
datastring(b->name, strlen(b->name)+1);
|
||||
|
||||
// sigi[0].offset = width
|
||||
gensatac(wi, t->width);
|
||||
|
||||
// skip the function
|
||||
gensatac(widthptr, 0);
|
||||
|
||||
for(b=a; b!=nil; b=b->link) {
|
||||
ot = rnd(ot, maxround); // base structure
|
||||
|
||||
// sigx[++].name = "fieldname"
|
||||
ginsatoa(widthptr, stringo);
|
||||
|
||||
// sigx[++].hash = hashcode
|
||||
gensatac(wi, b->hash);
|
||||
|
||||
// sigt[++].offset = of embeded struct
|
||||
gensatac(wi, 0);
|
||||
|
||||
// sigt[++].fun = &method
|
||||
gensatad(b->sym);
|
||||
|
||||
datastring(b->name, strlen(b->name)+1);
|
||||
|
||||
if(b->offset)
|
||||
gentramp(d->dtype, b);
|
||||
}
|
||||
|
||||
// nil field name at end
|
||||
ot = rnd(ot, maxround);
|
||||
gensatac(widthptr, 0);
|
||||
|
||||
p = pc;
|
||||
gins(AGLOBL, N, N);
|
||||
p->from = at;
|
||||
p->to = ac;
|
||||
p->to.offset = ot;
|
||||
if(b->offset)
|
||||
gentramp(t0, b);
|
||||
}
|
||||
|
||||
if(stringo > 0) {
|
||||
p = pc;
|
||||
gins(AGLOBL, N, N);
|
||||
p->from = ao;
|
||||
p->to = ac;
|
||||
p->to.offset = stringo;
|
||||
}
|
||||
// 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.
|
||||
p = pc;
|
||||
gins(AGLOBL, N, N);
|
||||
p->from = at;
|
||||
p->from.scale = DUPOK;
|
||||
p->to = ac;
|
||||
p->to.offset = ot;
|
||||
}
|
||||
|
||||
void
|
||||
dumpsigi(void)
|
||||
dumpsigi(Type *t, Sym *s)
|
||||
{
|
||||
Dcl *d, *x;
|
||||
Type *t, *f;
|
||||
Sym *s1, *s;
|
||||
int et, o;
|
||||
Type *f;
|
||||
Sym *s1;
|
||||
int o;
|
||||
Sig *a, *b;
|
||||
Prog *p;
|
||||
char *sp;
|
||||
char buf[NSYMB];
|
||||
|
||||
/*
|
||||
* put all the names into a linked
|
||||
* list so that it may be generated in sorted order.
|
||||
* the runtime will be linear rather than quadradic
|
||||
*/
|
||||
at.sym = s;
|
||||
|
||||
for(d=signatlist; d!=D; d=d->forw) {
|
||||
if(d->op != OTYPE)
|
||||
a = nil;
|
||||
o = 0;
|
||||
for(f=t->type; f!=T; f=f->down) {
|
||||
if(f->type->etype != TFUNC)
|
||||
continue;
|
||||
|
||||
t = d->dtype;
|
||||
et = t->etype;
|
||||
if(et != TINTER)
|
||||
if(f->etype != TFIELD)
|
||||
fatal("dumpsignatures: not field");
|
||||
|
||||
s1 = f->sym;
|
||||
if(s1 == nil)
|
||||
continue;
|
||||
if(s1->name[0] == '_')
|
||||
continue;
|
||||
|
||||
at.sym = signame(t, d->block);
|
||||
if(at.sym == S)
|
||||
continue;
|
||||
b = mal(sizeof(*b));
|
||||
b->link = a;
|
||||
a = b;
|
||||
|
||||
// make unique
|
||||
if(at.sym->local != 1)
|
||||
continue;
|
||||
at.sym->local = 2;
|
||||
a->name = s1->name;
|
||||
sp = strchr(s1->name, '_');
|
||||
if(sp != nil)
|
||||
a->name = sp+1;
|
||||
|
||||
s = d->dsym;
|
||||
if(s == S)
|
||||
continue;
|
||||
a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
|
||||
a->perm = o;
|
||||
a->sym = methodsym(f->sym, t);
|
||||
a->offset = 0;
|
||||
|
||||
if(s->name[0] == '_')
|
||||
continue;
|
||||
o++;
|
||||
}
|
||||
|
||||
if(strcmp(s->opackage, package) != 0)
|
||||
continue;
|
||||
a = lsort(a, sigcmp);
|
||||
ot = 0;
|
||||
ot = rnd(ot, maxround); // base structure
|
||||
|
||||
//print("sigi: %S\n", s);
|
||||
// sigi[0].name = ""
|
||||
ginsatoa(widthptr, stringo);
|
||||
|
||||
a = nil;
|
||||
o = 0;
|
||||
for(f=t->type; f!=T; f=f->down) {
|
||||
if(f->type->etype != TFUNC)
|
||||
continue;
|
||||
// save type name for runtime error message.
|
||||
snprint(buf, sizeof buf, "%#T", t);
|
||||
datastring(buf, strlen(buf)+1);
|
||||
|
||||
if(f->etype != TFIELD)
|
||||
fatal("dumpsignatures: not field");
|
||||
// first field of an interface signature
|
||||
// contains the count and is not a real entry
|
||||
|
||||
s1 = f->sym;
|
||||
if(s1 == nil)
|
||||
continue;
|
||||
if(s1->name[0] == '_')
|
||||
continue;
|
||||
// sigi[0].hash = 0
|
||||
gensatac(wi, 0);
|
||||
|
||||
b = mal(sizeof(*b));
|
||||
b->link = a;
|
||||
a = b;
|
||||
// sigi[0].offset = count
|
||||
o = 0;
|
||||
for(b=a; b!=nil; b=b->link)
|
||||
o++;
|
||||
gensatac(wi, o);
|
||||
|
||||
a->name = s1->name;
|
||||
sp = strchr(s1->name, '_');
|
||||
if(sp != nil)
|
||||
a->name = sp+1;
|
||||
|
||||
a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
|
||||
a->perm = o;
|
||||
a->sym = methodsym(f->sym, t);
|
||||
a->offset = 0;
|
||||
|
||||
o++;
|
||||
}
|
||||
|
||||
a = lsort(a, sigcmp);
|
||||
ot = 0;
|
||||
for(b=a; b!=nil; b=b->link) {
|
||||
//print(" %s\n", b->name);
|
||||
ot = rnd(ot, maxround); // base structure
|
||||
|
||||
// sigi[0].name = ""
|
||||
// sigx[++].name = "fieldname"
|
||||
ginsatoa(widthptr, stringo);
|
||||
|
||||
// save type name for runtime error message.
|
||||
// TODO(rsc): the * is a botch but right more often than not.
|
||||
snprint(buf, sizeof buf, "%#T", t);
|
||||
datastring(buf, strlen(buf)+1);
|
||||
// sigx[++].hash = hashcode
|
||||
gensatac(wi, b->hash);
|
||||
|
||||
// first field of an interface signature
|
||||
// contains the count and is not a real entry
|
||||
// sigi[++].perm = mapped offset of method
|
||||
gensatac(wi, b->perm);
|
||||
|
||||
// sigi[0].hash = 0
|
||||
gensatac(wi, 0);
|
||||
|
||||
// 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->to = ac;
|
||||
p->to.offset = ot;
|
||||
datastring(b->name, strlen(b->name)+1);
|
||||
}
|
||||
|
||||
if(stringo > 0) {
|
||||
p = pc;
|
||||
gins(AGLOBL, N, N);
|
||||
p->from = ao;
|
||||
p->to = ac;
|
||||
p->to.offset = stringo;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
void
|
||||
dumpsignatures(void)
|
||||
{
|
||||
int et;
|
||||
Dcl *d, *x;
|
||||
Type *t;
|
||||
Sym *s;
|
||||
Sym *s, *s1;
|
||||
Prog *p;
|
||||
|
||||
memset(&at, 0, sizeof(at));
|
||||
memset(&ao, 0, sizeof(ao));
|
||||
@ -923,19 +843,60 @@ dumpsignatures(void)
|
||||
if(t == T)
|
||||
continue;
|
||||
|
||||
s = signame(t, 0);
|
||||
s = signame(t);
|
||||
if(s == S)
|
||||
continue;
|
||||
|
||||
x = mal(sizeof(*d));
|
||||
x->op = OTYPE;
|
||||
x->dsym = d->dsym;
|
||||
x->dtype = d->dtype;
|
||||
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);
|
||||
}
|
||||
dumpsigi();
|
||||
dumpsigt();
|
||||
|
||||
// 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;
|
||||
|
||||
//print("dosig %T\n", t);
|
||||
// don't emit signatures for *NamedStruct or interface if
|
||||
// they were defined by other packages.
|
||||
// (optimization)
|
||||
s1 = S;
|
||||
if(isptr[et] && t->type != T)
|
||||
s1 = t->type->sym;
|
||||
else if(et == TINTER)
|
||||
s1 = t->sym;
|
||||
if(s1 != S && strcmp(s1->opackage, package) != 0)
|
||||
continue;
|
||||
|
||||
if(et == TINTER)
|
||||
dumpsigi(t, s);
|
||||
else
|
||||
dumpsigt(t, s);
|
||||
}
|
||||
|
||||
if(stringo > 0) {
|
||||
p = pc;
|
||||
gins(AGLOBL, N, N);
|
||||
p->from = ao;
|
||||
p->to = ac;
|
||||
p->to.offset = stringo;
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,7 @@ struct Sym
|
||||
short become;
|
||||
short frame;
|
||||
uchar subtype;
|
||||
uchar dupok;
|
||||
ushort file;
|
||||
vlong value;
|
||||
int32 sig;
|
||||
|
@ -972,6 +972,8 @@ loop:
|
||||
}
|
||||
if(p->to.offset > s->value)
|
||||
s->value = p->to.offset;
|
||||
if(p->from.scale & DUPOK)
|
||||
s->dupok = 1;
|
||||
goto loop;
|
||||
|
||||
case ADYNT:
|
||||
@ -1017,6 +1019,12 @@ loop:
|
||||
|
||||
case ADATA:
|
||||
data:
|
||||
// Assume that AGLOBL comes after ADATA.
|
||||
// If we've seen an AGLOBL that said this sym was DUPOK,
|
||||
// ignore any more ADATA we see, which must be
|
||||
// redefinitions.
|
||||
if(p->from.sym != S && p->from.sym->dupok)
|
||||
goto loop;
|
||||
if(edatap == P)
|
||||
datap = p;
|
||||
else
|
||||
|
@ -125,6 +125,7 @@ struct Type
|
||||
uchar methptr; // 1=direct 2=pointer
|
||||
uchar printed;
|
||||
uchar embedded; // TFIELD embedded type
|
||||
uchar siggen;
|
||||
|
||||
// TFUNCT
|
||||
uchar thistuple;
|
||||
@ -208,6 +209,7 @@ struct Sym
|
||||
uchar sym; // huffman encoding in object file
|
||||
uchar local; // created in this file
|
||||
uchar uniq; // imbedded field name first found
|
||||
uchar siggen; // signature generated
|
||||
|
||||
char* opackage; // original package name
|
||||
char* package; // package name
|
||||
@ -596,11 +598,10 @@ int isptrdarray(Type*);
|
||||
int isinter(Type*);
|
||||
int isnilinter(Type*);
|
||||
int isddd(Type*);
|
||||
Sym* globalsig(Type*);
|
||||
Type* ismethod(Type*);
|
||||
Type* methtype(Type*);
|
||||
int needaddr(Type*);
|
||||
Sym* signame(Type*, int);
|
||||
Sym* signame(Type*);
|
||||
int bytearraysz(Type*);
|
||||
int eqtype(Type*, Type*, int);
|
||||
void argtype(Node*, Type*);
|
||||
|
@ -1606,134 +1606,53 @@ iscomposite(Type *t)
|
||||
}
|
||||
|
||||
Sym*
|
||||
globalsig(Type *t)
|
||||
signame(Type *t)
|
||||
{
|
||||
int et;
|
||||
Sym *s;
|
||||
char buf[NSYMB];
|
||||
char *sigx;
|
||||
|
||||
if(t == T)
|
||||
return S;
|
||||
|
||||
et = t->etype;
|
||||
switch(et) {
|
||||
default:
|
||||
return S;
|
||||
|
||||
case TINTER:
|
||||
case TDDD:
|
||||
if(isnilinter(t)) {
|
||||
sigx = "sigi";
|
||||
strcpy(buf, "inter");
|
||||
goto out;
|
||||
}
|
||||
return S;
|
||||
|
||||
case TPTR32:
|
||||
case TPTR64:
|
||||
if(isptrto(t, TSTRING)) {
|
||||
et = TSTRING;
|
||||
break;
|
||||
}
|
||||
return S;
|
||||
|
||||
case TINT:
|
||||
case TINT8:
|
||||
case TINT16:
|
||||
case TINT32:
|
||||
case TINT64:
|
||||
|
||||
case TUINT:
|
||||
case TUINT8:
|
||||
case TUINT16:
|
||||
case TUINT32:
|
||||
case TUINT64:
|
||||
case TUINTPTR:
|
||||
|
||||
case TFLOAT:
|
||||
case TFLOAT32:
|
||||
case TFLOAT64:
|
||||
case TFLOAT80:
|
||||
|
||||
case TBOOL:
|
||||
break;
|
||||
}
|
||||
if(t->sym == S)
|
||||
return S;
|
||||
if(t->method != T)
|
||||
return S;
|
||||
if(strcmp(t->sym->name, types[et]->sym->name) != 0)
|
||||
return S;
|
||||
sigx = "sigt";
|
||||
snprint(buf, sizeof(buf), "%#T", t);
|
||||
|
||||
out:
|
||||
s = pkglookup(buf, sigx);
|
||||
if(s->oname == N) {
|
||||
s->oname = newname(s);
|
||||
s->oname->type = types[TUINT8];
|
||||
s->oname->class = PEXTERN;
|
||||
s->local = s->local;
|
||||
}
|
||||
//print("*** %lT %lS\n", t, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
Sym*
|
||||
signame(Type *t, int block)
|
||||
{
|
||||
Sym *s, *ss;
|
||||
Sym *ss;
|
||||
char *e;
|
||||
Dcl *x;
|
||||
char buf[NSYMB];
|
||||
|
||||
//print("signame %T\n", t);
|
||||
if(t == T)
|
||||
goto bad;
|
||||
|
||||
ss = globalsig(t);
|
||||
if(ss != S)
|
||||
return ss;
|
||||
|
||||
s = t->sym;
|
||||
if(s == S) {
|
||||
if(isptr[t->etype]) {
|
||||
t = t->type;
|
||||
if(t == T)
|
||||
goto bad;
|
||||
}
|
||||
s = t->sym;
|
||||
if(s == S)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
e = "sigt";
|
||||
if(t->etype == TINTER)
|
||||
e = "sigi";
|
||||
|
||||
if(block == 0)
|
||||
block = s->tblock;
|
||||
|
||||
if(block > 1) {
|
||||
// record internal type for signature generation
|
||||
x = mal(sizeof(*x));
|
||||
x->op = OTYPE;
|
||||
x->dsym = s;
|
||||
x->dtype = s->otype;
|
||||
x->forw = signatlist;
|
||||
x->block = block;
|
||||
signatlist = x;
|
||||
}
|
||||
// name is exported name, like *[]byte or *Struct or Interface
|
||||
// (special symbols don't bother the linker).
|
||||
snprint(buf, sizeof(buf), "%#T", t);
|
||||
|
||||
// special case: empty interface is named sigi.empty
|
||||
// so that it can be referred to by the runtime.
|
||||
if(strcmp(buf, "interface { }") == 0)
|
||||
strcpy(buf, "empty");
|
||||
|
||||
ss = pkglookup(buf, e);
|
||||
if(ss->oname == N) {
|
||||
ss->oname = newname(ss);
|
||||
ss->oname->type = types[TUINT8];
|
||||
ss->oname->class = PEXTERN;
|
||||
ss->local = s->local;
|
||||
//print("signame: %d %lS\n", ss->local, ss);
|
||||
}
|
||||
|
||||
if(!t->siggen) {
|
||||
//print("siggen %T\n", t);
|
||||
// special case: don't generate the empty interface
|
||||
if(strcmp(buf, "empty") == 0)
|
||||
goto out;
|
||||
|
||||
// record internal type for signature generation
|
||||
x = mal(sizeof(*x));
|
||||
x->op = OTYPE;
|
||||
x->dtype = t;
|
||||
x->forw = signatlist;
|
||||
t->siggen = 1;
|
||||
signatlist = x;
|
||||
}
|
||||
|
||||
out:
|
||||
return ss;
|
||||
|
||||
bad:
|
||||
|
@ -919,10 +919,10 @@ loop:
|
||||
nnew = nod(ONEW, N, N);
|
||||
nnew->type = nvar->type;
|
||||
nnew = newcompat(nnew);
|
||||
|
||||
|
||||
nas = nod(OAS, nvar, nnew);
|
||||
addtop = list(addtop, nas);
|
||||
|
||||
|
||||
nas = nod(OAS, nod(OIND, nvar, N), n->left);
|
||||
addtop = list(addtop, nas);
|
||||
|
||||
@ -1761,7 +1761,7 @@ loop:
|
||||
return N;
|
||||
}
|
||||
|
||||
more:
|
||||
|
||||
a = nod(OAS, nodarg(l, fp), r);
|
||||
a = convas(a);
|
||||
nn = list(a, nn);
|
||||
@ -1786,6 +1786,8 @@ ascompat(Type *t1, Type *t2)
|
||||
// if(eqtype(t2, nilptr, 0))
|
||||
// return 1;
|
||||
|
||||
if(isnilinter(t1))
|
||||
return 1;
|
||||
if(isinter(t1)) {
|
||||
if(isinter(t2))
|
||||
return 1;
|
||||
@ -1793,6 +1795,8 @@ ascompat(Type *t1, Type *t2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(isnilinter(t2))
|
||||
return 1;
|
||||
if(isinter(t2))
|
||||
if(ismethod(t1))
|
||||
return 1;
|
||||
@ -2649,13 +2653,13 @@ isandss(Type *lt, Node *r)
|
||||
return I2I;
|
||||
return Inone;
|
||||
}
|
||||
if(ismethod(rt) != T)
|
||||
if(isnilinter(lt) || ismethod(rt) != T)
|
||||
return T2I;
|
||||
return Inone;
|
||||
}
|
||||
|
||||
if(isinter(rt)) {
|
||||
if(ismethod(lt) != T)
|
||||
if(isnilinter(rt) || ismethod(lt) != T)
|
||||
return I2T;
|
||||
return Inone;
|
||||
}
|
||||
@ -2682,7 +2686,7 @@ ifaceop(Type *tl, Node *n, int op)
|
||||
a = n; // interface
|
||||
r = a;
|
||||
|
||||
s = signame(tl, 0); // sigi
|
||||
s = signame(tl); // sigi
|
||||
if(s == S)
|
||||
fatal("ifaceop: signame I2T");
|
||||
a = s->oname;
|
||||
@ -2701,14 +2705,14 @@ ifaceop(Type *tl, Node *n, int op)
|
||||
a = n; // elem
|
||||
r = a;
|
||||
|
||||
s = signame(tr, 0); // sigt
|
||||
s = signame(tr); // sigt
|
||||
if(s == S)
|
||||
fatal("ifaceop: signame-1 T2I: %lT", tr);
|
||||
a = s->oname;
|
||||
a = nod(OADDR, a, N);
|
||||
r = list(a, r);
|
||||
|
||||
s = signame(tl, 0); // sigi
|
||||
s = signame(tl); // sigi
|
||||
if(s == S) {
|
||||
fatal("ifaceop: signame-2 T2I: %lT", tl);
|
||||
}
|
||||
@ -2728,7 +2732,7 @@ ifaceop(Type *tl, Node *n, int op)
|
||||
a = n; // interface
|
||||
r = a;
|
||||
|
||||
s = signame(tl, 0); // sigi
|
||||
s = signame(tl); // sigi
|
||||
if(s == S)
|
||||
fatal("ifaceop: signame I2I");
|
||||
a = s->oname;
|
||||
|
@ -45,31 +45,7 @@ struct Map
|
||||
|
||||
static Map* hash[1009];
|
||||
|
||||
#define END nil,0,0,nil
|
||||
|
||||
Sigi sigi·inter[2] = { (byte*)"interface {}", 0, 0, nil, 0, 0 };
|
||||
|
||||
Sigt sigt·int8[2] = { (byte*)"int8", ASIMP, 1, nil, END };
|
||||
Sigt sigt·int16[2] = { (byte*)"int16", ASIMP, 2, nil, END };
|
||||
Sigt sigt·int32[2] = { (byte*)"int32", ASIMP, 4, nil, END };
|
||||
Sigt sigt·int64[2] = { (byte*)"int64", ASIMP, 8, nil, END };
|
||||
|
||||
Sigt sigt·uint8[2] = { (byte*)"uint8", ASIMP, 1, nil, END };
|
||||
Sigt sigt·uint16[2] = { (byte*)"uint16", ASIMP, 2, nil, END };
|
||||
Sigt sigt·uint32[2] = { (byte*)"uint32", ASIMP, 4, nil, END };
|
||||
Sigt sigt·uint64[2] = { (byte*)"uint64", ASIMP, 8, nil, END };
|
||||
|
||||
Sigt sigt·float32[2] = { (byte*)"float32", ASIMP, 4, nil, END };
|
||||
Sigt sigt·float64[2] = { (byte*)"float64", ASIMP, 8, nil, END };
|
||||
//Sigt sigt·float80[2] = { (byte*)"float80", ASIMP, 0, nil, END };
|
||||
|
||||
Sigt sigt·bool[2] = { (byte*)"bool", ASIMP, 1, nil, END };
|
||||
Sigt sigt·string[2] = { (byte*)"string", ASTRING, 8, nil, END };
|
||||
|
||||
Sigt sigt·int[2] = { (byte*)"int", ASIMP, 4, nil, END };
|
||||
Sigt sigt·uint[2] = { (byte*)"uint", ASIMP, 4, nil, END };
|
||||
Sigt sigt·uintptr[2] = { (byte*)"uintptr", ASIMP, 8, nil, END };
|
||||
Sigt sigt·float[2] = { (byte*)"float", ASIMP, 4, nil, END };
|
||||
Sigi sigi·empty[2] = { (byte*)"interface { }" };
|
||||
|
||||
static void
|
||||
printsigi(Sigi *si)
|
||||
@ -506,7 +482,7 @@ sys·unreflect(uint64 it, string type, Map *retim, void *retit)
|
||||
retim = 0;
|
||||
retit = 0;
|
||||
} else {
|
||||
retim = hashmap(sigi·inter, findtype(type), 0);
|
||||
retim = hashmap(sigi·empty, findtype(type), 0);
|
||||
retit = (void*)it;
|
||||
}
|
||||
FLUSH(&retim);
|
||||
|
Loading…
Reference in New Issue
Block a user