int c, d, o;
Prog *p;
Type *f;
- Sym *msym;
e = lookup(b->name);
for(d=0; d<nelem(dotlist); d++) {
}
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));
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;
+ }
}
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)
retim = 0;
retit = 0;
} else {
- retim = hashmap(sigi·inter, findtype(type), 0);
+ retim = hashmap(sigi·empty, findtype(type), 0);
retit = (void*)it;
}
FLUSH(&retim);