Commit 1983121b authored by Russ Cox's avatar Russ Cox

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
parent 6cd74b03
...@@ -516,7 +516,6 @@ gentramp(Type *t, Sig *b) ...@@ -516,7 +516,6 @@ gentramp(Type *t, Sig *b)
int c, d, o; int c, d, o;
Prog *p; Prog *p;
Type *f; Type *f;
Sym *msym;
e = lookup(b->name); e = lookup(b->name);
for(d=0; d<nelem(dotlist); d++) { for(d=0; d<nelem(dotlist); d++) {
...@@ -596,292 +595,213 @@ out: ...@@ -596,292 +595,213 @@ out:
} }
void void
dumpsigt(void) dumpsigt(Type *t0, Sym *s)
{ {
Dcl *d, *x; Type *f, *t;
Type *t, *f; Sym *s1;
Sym *s1, *s; int o;
int et, o;
Sig *a, *b; Sig *a, *b;
Prog *p; Prog *p;
char *sp;
char buf[NSYMB]; char buf[NSYMB];
/* at.sym = s;
* 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;
// make unique t = t0;
if(at.sym->local != 1) if(isptr[t->etype] && t->type->sym != S) {
continue; t = t->type;
at.sym->local = 2; expandmeth(t->sym, t);
}
s = d->dsym; a = nil;
if(s == S) o = 0;
for(f=t->method; f!=T; f=f->down) {
if(f->type->etype != TFUNC)
continue; continue;
if(s->name[0] == '_') if(f->etype != TFIELD)
continue; fatal("dumpsignatures: not field");
if(strcmp(s->opackage, package) != 0) s1 = f->sym;
if(s1 == nil)
continue; continue;
expandmeth(s, t); b = mal(sizeof(*b));
b->link = a;
a = nil; a = b;
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;
a->name = s1->name; a->name = s1->name;
a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0); a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type, 0);
a->perm = o; a->perm = o;
a->sym = methodsym(f->sym, t); a->sym = methodsym(f->sym, t);
a->offset = f->embedded; // need trampoline a->offset = f->embedded; // need trampoline
o++; 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);
// first field of an type signature contains a = lsort(a, sigcmp);
// the element parameters and is not a real entry ot = 0;
ot = rnd(ot, maxround); // base structure
t = d->dtype; // sigi[0].name = ""
if(t->methptr & 2) ginsatoa(widthptr, stringo);
t = types[tptr];
// sigi[0].hash = elemalg // save type name for runtime error message.
gensatac(wi, algtype(t)); snprint(buf, sizeof buf, "%#T", t0);
datastring(buf, strlen(buf)+1);
// sigi[0].offset = width // first field of an type signature contains
gensatac(wi, t->width); // the element parameters and is not a real entry
if(t->methptr & 2)
t = types[tptr];
// skip the function // sigi[0].hash = elemalg
gensatac(widthptr, 0); gensatac(wi, algtype(t));
for(b=a; b!=nil; b=b->link) { // sigi[0].offset = width
ot = rnd(ot, maxround); // base structure gensatac(wi, t->width);
// sigx[++].name = "fieldname" // skip the function
ginsatoa(widthptr, stringo); gensatac(widthptr, 0);
// sigx[++].hash = hashcode for(b=a; b!=nil; b=b->link) {
gensatac(wi, b->hash); ot = rnd(ot, maxround); // base structure
// sigt[++].offset = of embeded struct // sigx[++].name = "fieldname"
gensatac(wi, 0); ginsatoa(widthptr, stringo);
// sigt[++].fun = &method // sigx[++].hash = hashcode
gensatad(b->sym); gensatac(wi, b->hash);
datastring(b->name, strlen(b->name)+1); // sigt[++].offset = of embeded struct
gensatac(wi, 0);
if(b->offset) // sigt[++].fun = &method
gentramp(d->dtype, b); gensatad(b->sym);
}
// nil field name at end datastring(b->name, strlen(b->name)+1);
ot = rnd(ot, maxround);
gensatac(widthptr, 0);
p = pc; if(b->offset)
gins(AGLOBL, N, N); gentramp(t0, b);
p->from = at;
p->to = ac;
p->to.offset = ot;
} }
if(stringo > 0) { // nil field name at end
p = pc; ot = rnd(ot, maxround);
gins(AGLOBL, N, N); gensatac(widthptr, 0);
p->from = ao;
p->to = ac;
p->to.offset = stringo;
}
// 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 void
dumpsigi(void) dumpsigi(Type *t, Sym *s)
{ {
Dcl *d, *x; Type *f;
Type *t, *f; Sym *s1;
Sym *s1, *s; int o;
int et, o;
Sig *a, *b; Sig *a, *b;
Prog *p; Prog *p;
char *sp; char *sp;
char buf[NSYMB]; char buf[NSYMB];
/* at.sym = s;
* 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; a = nil;
et = t->etype; o = 0;
if(et != TINTER) for(f=t->type; f!=T; f=f->down) {
if(f->type->etype != TFUNC)
continue; continue;
at.sym = signame(t, d->block); if(f->etype != TFIELD)
if(at.sym == S) fatal("dumpsignatures: not field");
continue;
// make unique s1 = f->sym;
if(at.sym->local != 1) if(s1 == nil)
continue; continue;
at.sym->local = 2; if(s1->name[0] == '_')
s = d->dsym;
if(s == S)
continue; continue;
if(s->name[0] == '_') b = mal(sizeof(*b));
continue; b->link = a;
a = b;
if(strcmp(s->opackage, package) != 0) a->name = s1->name;
continue; 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++;
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++;
}
a = lsort(a, sigcmp); a = lsort(a, sigcmp);
ot = 0; ot = 0;
ot = rnd(ot, maxround); // base structure ot = rnd(ot, maxround); // base structure
// sigi[0].name = "" // sigi[0].name = ""
ginsatoa(widthptr, stringo); ginsatoa(widthptr, stringo);
// save type name for runtime error message. // 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);
snprint(buf, sizeof buf, "%#T", t); datastring(buf, strlen(buf)+1);
datastring(buf, strlen(buf)+1);
// first field of an interface signature // first field of an interface signature
// contains the count and is not a real entry // contains the count and is not a real entry
// sigi[0].hash = 0 // sigi[0].hash = 0
gensatac(wi, 0); gensatac(wi, 0);
// sigi[0].offset = count // sigi[0].offset = count
o = 0; o = 0;
for(b=a; b!=nil; b=b->link) for(b=a; b!=nil; b=b->link)
o++; o++;
gensatac(wi, 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); //print(" %s\n", b->name);
ot = rnd(ot, maxround); // base structure 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 // sigx[++].name = "fieldname"
gensatac(wi, b->perm); ginsatoa(widthptr, stringo);
datastring(b->name, strlen(b->name)+1); // sigx[++].hash = hashcode
} gensatac(wi, b->hash);
// nil field name at end // sigi[++].perm = mapped offset of method
ot = rnd(ot, maxround); gensatac(wi, b->perm);
gensatac(widthptr, 0);
p = pc; datastring(b->name, strlen(b->name)+1);
gins(AGLOBL, N, N);
p->from = at;
p->to = ac;
p->to.offset = ot;
} }
if(stringo > 0) { // nil field name at end
p = pc; ot = rnd(ot, maxround);
gins(AGLOBL, N, N); gensatac(widthptr, 0);
p->from = ao;
p->to = ac; p = pc;
p->to.offset = stringo; gins(AGLOBL, N, N);
} p->from = at;
p->from.scale = DUPOK;
p->to = ac;
p->to.offset = ot;
} }
void void
dumpsignatures(void) dumpsignatures(void)
{ {
int et;
Dcl *d, *x; Dcl *d, *x;
Type *t; Type *t;
Sym *s; Sym *s, *s1;
Prog *p;
memset(&at, 0, sizeof(at)); memset(&at, 0, sizeof(at));
memset(&ao, 0, sizeof(ao)); memset(&ao, 0, sizeof(ao));
...@@ -923,19 +843,60 @@ dumpsignatures(void) ...@@ -923,19 +843,60 @@ dumpsignatures(void)
if(t == T) if(t == T)
continue; continue;
s = signame(t, 0); s = signame(t);
if(s == S) if(s == S)
continue; continue;
x = mal(sizeof(*d)); x = mal(sizeof(*d));
x->op = OTYPE; x->op = OTYPE;
x->dsym = d->dsym; if(t->etype == TINTER)
x->dtype = d->dtype; x->dtype = t;
else
x->dtype = ptrto(t);
x->forw = signatlist; x->forw = signatlist;
x->block = 0; x->block = 0;
signatlist = x; signatlist = x;
//print("SIG = %lS %lS %lT\n", d->dsym, s, t); //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 ...@@ -113,6 +113,7 @@ struct Sym
short become; short become;
short frame; short frame;
uchar subtype; uchar subtype;
uchar dupok;
ushort file; ushort file;
vlong value; vlong value;
int32 sig; int32 sig;
......
...@@ -972,6 +972,8 @@ loop: ...@@ -972,6 +972,8 @@ loop:
} }
if(p->to.offset > s->value) if(p->to.offset > s->value)
s->value = p->to.offset; s->value = p->to.offset;
if(p->from.scale & DUPOK)
s->dupok = 1;
goto loop; goto loop;
case ADYNT: case ADYNT:
...@@ -1017,6 +1019,12 @@ loop: ...@@ -1017,6 +1019,12 @@ loop:
case ADATA: case ADATA:
data: 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) if(edatap == P)
datap = p; datap = p;
else else
......
...@@ -125,6 +125,7 @@ struct Type ...@@ -125,6 +125,7 @@ struct Type
uchar methptr; // 1=direct 2=pointer uchar methptr; // 1=direct 2=pointer
uchar printed; uchar printed;
uchar embedded; // TFIELD embedded type uchar embedded; // TFIELD embedded type
uchar siggen;
// TFUNCT // TFUNCT
uchar thistuple; uchar thistuple;
...@@ -208,6 +209,7 @@ struct Sym ...@@ -208,6 +209,7 @@ struct Sym
uchar sym; // huffman encoding in object file uchar sym; // huffman encoding in object file
uchar local; // created in this file uchar local; // created in this file
uchar uniq; // imbedded field name first found uchar uniq; // imbedded field name first found
uchar siggen; // signature generated
char* opackage; // original package name char* opackage; // original package name
char* package; // package name char* package; // package name
...@@ -596,11 +598,10 @@ int isptrdarray(Type*); ...@@ -596,11 +598,10 @@ int isptrdarray(Type*);
int isinter(Type*); int isinter(Type*);
int isnilinter(Type*); int isnilinter(Type*);
int isddd(Type*); int isddd(Type*);
Sym* globalsig(Type*);
Type* ismethod(Type*); Type* ismethod(Type*);
Type* methtype(Type*); Type* methtype(Type*);
int needaddr(Type*); int needaddr(Type*);
Sym* signame(Type*, int); Sym* signame(Type*);
int bytearraysz(Type*); int bytearraysz(Type*);
int eqtype(Type*, Type*, int); int eqtype(Type*, Type*, int);
void argtype(Node*, Type*); void argtype(Node*, Type*);
......
...@@ -1606,134 +1606,53 @@ iscomposite(Type *t) ...@@ -1606,134 +1606,53 @@ iscomposite(Type *t)
} }
Sym* Sym*
globalsig(Type *t) signame(Type *t)
{ {
int et; Sym *ss;
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;
char *e; char *e;
Dcl *x; Dcl *x;
char buf[NSYMB]; char buf[NSYMB];
//print("signame %T\n", t);
if(t == T) if(t == T)
goto bad; 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"; e = "sigt";
if(t->etype == TINTER) if(t->etype == TINTER)
e = "sigi"; e = "sigi";
if(block == 0) // name is exported name, like *[]byte or *Struct or Interface
block = s->tblock; // (special symbols don't bother the linker).
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;
}
snprint(buf, sizeof(buf), "%#T", t); 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); ss = pkglookup(buf, e);
if(ss->oname == N) { if(ss->oname == N) {
ss->oname = newname(ss); ss->oname = newname(ss);
ss->oname->type = types[TUINT8]; ss->oname->type = types[TUINT8];
ss->oname->class = PEXTERN; 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; return ss;
bad: bad:
......
...@@ -919,10 +919,10 @@ loop: ...@@ -919,10 +919,10 @@ loop:
nnew = nod(ONEW, N, N); nnew = nod(ONEW, N, N);
nnew->type = nvar->type; nnew->type = nvar->type;
nnew = newcompat(nnew); nnew = newcompat(nnew);
nas = nod(OAS, nvar, nnew); nas = nod(OAS, nvar, nnew);
addtop = list(addtop, nas); addtop = list(addtop, nas);
nas = nod(OAS, nod(OIND, nvar, N), n->left); nas = nod(OAS, nod(OIND, nvar, N), n->left);
addtop = list(addtop, nas); addtop = list(addtop, nas);
...@@ -1761,7 +1761,7 @@ loop: ...@@ -1761,7 +1761,7 @@ loop:
return N; return N;
} }
more:
a = nod(OAS, nodarg(l, fp), r); a = nod(OAS, nodarg(l, fp), r);
a = convas(a); a = convas(a);
nn = list(a, nn); nn = list(a, nn);
...@@ -1786,6 +1786,8 @@ ascompat(Type *t1, Type *t2) ...@@ -1786,6 +1786,8 @@ ascompat(Type *t1, Type *t2)
// if(eqtype(t2, nilptr, 0)) // if(eqtype(t2, nilptr, 0))
// return 1; // return 1;
if(isnilinter(t1))
return 1;
if(isinter(t1)) { if(isinter(t1)) {
if(isinter(t2)) if(isinter(t2))
return 1; return 1;
...@@ -1793,6 +1795,8 @@ ascompat(Type *t1, Type *t2) ...@@ -1793,6 +1795,8 @@ ascompat(Type *t1, Type *t2)
return 1; return 1;
} }
if(isnilinter(t2))
return 1;
if(isinter(t2)) if(isinter(t2))
if(ismethod(t1)) if(ismethod(t1))
return 1; return 1;
...@@ -2649,13 +2653,13 @@ isandss(Type *lt, Node *r) ...@@ -2649,13 +2653,13 @@ isandss(Type *lt, Node *r)
return I2I; return I2I;
return Inone; return Inone;
} }
if(ismethod(rt) != T) if(isnilinter(lt) || ismethod(rt) != T)
return T2I; return T2I;
return Inone; return Inone;
} }
if(isinter(rt)) { if(isinter(rt)) {
if(ismethod(lt) != T) if(isnilinter(rt) || ismethod(lt) != T)
return I2T; return I2T;
return Inone; return Inone;
} }
...@@ -2682,7 +2686,7 @@ ifaceop(Type *tl, Node *n, int op) ...@@ -2682,7 +2686,7 @@ ifaceop(Type *tl, Node *n, int op)
a = n; // interface a = n; // interface
r = a; r = a;
s = signame(tl, 0); // sigi s = signame(tl); // sigi
if(s == S) if(s == S)
fatal("ifaceop: signame I2T"); fatal("ifaceop: signame I2T");
a = s->oname; a = s->oname;
...@@ -2701,14 +2705,14 @@ ifaceop(Type *tl, Node *n, int op) ...@@ -2701,14 +2705,14 @@ ifaceop(Type *tl, Node *n, int op)
a = n; // elem a = n; // elem
r = a; r = a;
s = signame(tr, 0); // sigt s = signame(tr); // sigt
if(s == S) if(s == S)
fatal("ifaceop: signame-1 T2I: %lT", tr); fatal("ifaceop: signame-1 T2I: %lT", tr);
a = s->oname; a = s->oname;
a = nod(OADDR, a, N); a = nod(OADDR, a, N);
r = list(a, r); r = list(a, r);
s = signame(tl, 0); // sigi s = signame(tl); // sigi
if(s == S) { if(s == S) {
fatal("ifaceop: signame-2 T2I: %lT", tl); fatal("ifaceop: signame-2 T2I: %lT", tl);
} }
...@@ -2728,7 +2732,7 @@ ifaceop(Type *tl, Node *n, int op) ...@@ -2728,7 +2732,7 @@ ifaceop(Type *tl, Node *n, int op)
a = n; // interface a = n; // interface
r = a; r = a;
s = signame(tl, 0); // sigi s = signame(tl); // sigi
if(s == S) if(s == S)
fatal("ifaceop: signame I2I"); fatal("ifaceop: signame I2I");
a = s->oname; a = s->oname;
......
...@@ -45,31 +45,7 @@ struct Map ...@@ -45,31 +45,7 @@ struct Map
static Map* hash[1009]; static Map* hash[1009];
#define END nil,0,0,nil Sigi sigi·empty[2] = { (byte*)"interface { }" };
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 };
static void static void
printsigi(Sigi *si) printsigi(Sigi *si)
...@@ -506,7 +482,7 @@ sys·unreflect(uint64 it, string type, Map *retim, void *retit) ...@@ -506,7 +482,7 @@ sys·unreflect(uint64 it, string type, Map *retim, void *retit)
retim = 0; retim = 0;
retit = 0; retit = 0;
} else { } else {
retim = hashmap(sigi·inter, findtype(type), 0); retim = hashmap(sigi·empty, findtype(type), 0);
retit = (void*)it; retit = (void*)it;
} }
FLUSH(&retim); FLUSH(&retim);
......
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