diff options
author | Russ Cox <rsc@golang.org> | 2008-11-05 11:27:50 -0800 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2008-11-05 11:27:50 -0800 |
commit | f93e9122d55a438ef33e00d99f90d157e39c0e8a (patch) | |
tree | f3c233209ab5131760a45e54f4314388b4cfe1cc /src/cmd/6g/obj.c | |
parent | e5c26e215de8a476f735265abbe36a77e2501479 (diff) | |
download | golang-f93e9122d55a438ef33e00d99f90d157e39c0e8a.tar.gz |
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
Diffstat (limited to 'src/cmd/6g/obj.c')
-rw-r--r-- | src/cmd/6g/obj.c | 403 |
1 files changed, 182 insertions, 221 deletions
diff --git a/src/cmd/6g/obj.c b/src/cmd/6g/obj.c index 8b2a47c24..20763cf38 100644 --- a/src/cmd/6g/obj.c +++ b/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) - continue; + at.sym = s; - // make unique - if(at.sym->local != 1) - continue; - at.sym->local = 2; + t = t0; + if(isptr[t->etype] && t->type->sym != S) { + t = t->type; + expandmeth(t->sym, t); + } - s = d->dsym; - if(s == S) + a = nil; + o = 0; + for(f=t->method; f!=T; f=f->down) { + if(f->type->etype != TFUNC) continue; - if(s->name[0] == '_') - continue; + if(f->etype != TFIELD) + fatal("dumpsignatures: not field"); - if(strcmp(s->opackage, package) != 0) + s1 = f->sym; + if(s1 == nil) continue; - expandmeth(s, t); - - a = nil; - o = 0; - for(f=t->method; 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; + b = mal(sizeof(*b)); + b->link = a; + a = b; - 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 + 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 - 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. - // TODO(rsc): the * is a botch but right more often than not. - snprint(buf, sizeof buf, "*%#T", t); - datastring(buf, strlen(buf)+1); + o++; + } - // first field of an type signature contains - // the element parameters and is not a real entry + a = lsort(a, sigcmp); + ot = 0; + ot = rnd(ot, maxround); // base structure - t = d->dtype; - if(t->methptr & 2) - t = types[tptr]; + // sigi[0].name = "" + ginsatoa(widthptr, stringo); - // sigi[0].hash = elemalg - gensatac(wi, algtype(t)); + // save type name for runtime error message. + snprint(buf, sizeof buf, "%#T", t0); + datastring(buf, strlen(buf)+1); - // sigi[0].offset = width - gensatac(wi, t->width); + // first field of an type signature contains + // the element parameters and is not a real entry + if(t->methptr & 2) + t = types[tptr]; - // skip the function - gensatac(widthptr, 0); + // sigi[0].hash = elemalg + gensatac(wi, algtype(t)); - for(b=a; b!=nil; b=b->link) { - ot = rnd(ot, maxround); // base structure + // sigi[0].offset = width + gensatac(wi, t->width); - // sigx[++].name = "fieldname" - ginsatoa(widthptr, stringo); + // skip the function + gensatac(widthptr, 0); - // sigx[++].hash = hashcode - gensatac(wi, b->hash); + for(b=a; b!=nil; b=b->link) { + ot = rnd(ot, maxround); // base structure - // sigt[++].offset = of embeded struct - gensatac(wi, 0); + // sigx[++].name = "fieldname" + ginsatoa(widthptr, stringo); - // sigt[++].fun = &method - gensatad(b->sym); + // sigx[++].hash = hashcode + gensatac(wi, b->hash); - datastring(b->name, strlen(b->name)+1); + // sigt[++].offset = of embeded struct + gensatac(wi, 0); - if(b->offset) - gentramp(d->dtype, b); - } + // sigt[++].fun = &method + gensatad(b->sym); - // nil field name at end - ot = rnd(ot, maxround); - gensatac(widthptr, 0); + datastring(b->name, strlen(b->name)+1); - 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 - */ - - for(d=signatlist; d!=D; d=d->forw) { - if(d->op != OTYPE) - continue; + at.sym = s; - t = d->dtype; - et = t->etype; - if(et != TINTER) + a = nil; + o = 0; + for(f=t->type; f!=T; f=f->down) { + if(f->type->etype != TFUNC) continue; - at.sym = signame(t, d->block); - if(at.sym == S) - continue; + if(f->etype != TFIELD) + fatal("dumpsignatures: not field"); - // make unique - if(at.sym->local != 1) + s1 = f->sym; + if(s1 == nil) continue; - at.sym->local = 2; - - s = d->dsym; - if(s == S) + if(s1->name[0] == '_') 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; + sp = strchr(s1->name, '_'); + if(sp != nil) + a->name = sp+1; -//print("sigi: %S\n", s); + a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0); + a->perm = o; + a->sym = methodsym(f->sym, t); + a->offset = 0; - a = nil; - o = 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; - if(s1->name[0] == '_') - continue; - - b = mal(sizeof(*b)); - b->link = a; - a = b; - - 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++; - } + o++; + } - a = lsort(a, sigcmp); - ot = 0; - ot = rnd(ot, maxround); // base structure + a = lsort(a, sigcmp); + ot = 0; + ot = rnd(ot, maxround); // base structure - // sigi[0].name = "" - ginsatoa(widthptr, stringo); + // sigi[0].name = "" + 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); + // 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 + // first field of an interface signature + // contains the count and is not a real entry - // sigi[0].hash = 0 - gensatac(wi, 0); + // 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); + // 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) { + 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); + ot = rnd(ot, maxround); // base structure - // sigi[++].perm = mapped offset of method - gensatac(wi, b->perm); + // sigx[++].name = "fieldname" + ginsatoa(widthptr, stringo); - datastring(b->name, strlen(b->name)+1); - } + // sigx[++].hash = hashcode + gensatac(wi, b->hash); - // nil field name at end - ot = rnd(ot, maxround); - gensatac(widthptr, 0); + // sigi[++].perm = mapped offset of method + gensatac(wi, b->perm); - 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; + } } |