From 89ac5618ac59905e878b7739b25ac6a8b7d3393a Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Sun, 28 Sep 2008 20:22:31 -0700 Subject: [PATCH] toward methods on any type R=r OCL=16068 CL=16068 --- src/cmd/6g/obj.c | 15 +++++++++++++-- src/cmd/gc/dcl.c | 11 ++++++++++- src/cmd/gc/go.h | 8 ++++++++ src/cmd/gc/go.y | 10 +++++++--- src/cmd/gc/subr.c | 22 ++++++++++++++++++++++ src/cmd/gc/walk.c | 22 ---------------------- src/runtime/iface.c | 23 ++++++++++++++++------- 7 files changed, 76 insertions(+), 35 deletions(-) diff --git a/src/cmd/6g/obj.c b/src/cmd/6g/obj.c index 969bd995ea..5b16e716d0 100644 --- a/src/cmd/6g/obj.c +++ b/src/cmd/6g/obj.c @@ -591,13 +591,15 @@ dumpsignatures(void) a = lsort(a, sigcmp); ot = 0; + // first field of an interface signature + // contains the count and is not a real entry if(et == TINTER) { o = 0; for(b=a; b!=nil; b=b->link) o++; // sigi[0].name = "" - ot = rnd(ot, maxround); + ot = rnd(ot, maxround); // array of structures p = pc; gins(ADATA, N, N); p->from = at; @@ -636,7 +638,7 @@ dumpsignatures(void) for(b=a; b!=nil; b=b->link) { // sigx[++].name = "fieldname" - ot = rnd(ot, maxround); + ot = rnd(ot, maxround); // array of structures p = pc; gins(ADATA, N, N); p->from = at; @@ -669,6 +671,15 @@ dumpsignatures(void) p->to.offset = b->offset; ot += wi; } else { + // leave space for 3 ints + // offset, algorithm and width + ot = rnd(ot, wi); + ot += wi; + ot = rnd(ot, wi); + ot += wi; + ot = rnd(ot, wi); + ot += wi; + // sigs[++].fun = &method ot = rnd(ot, widthptr); p = pc; diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 988cd25bdf..568f1e3df0 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -237,7 +237,7 @@ methodname(Node *n, Type *t) return newname(lookup(namebuf)); bad: - yyerror("illegal pointer: %T", t); + yyerror("illegal type: %T", t); return n; } @@ -272,6 +272,15 @@ addmethod(Node *n, Type *t, int local) if(pa == T) goto bad; + switch(algtype(pa)) { + default: + goto bad; + case ASIMP: + case APTR: + case ASTRING: + break; + } + // optionally rip off ptr to type ptr = 0; if(isptr[pa->etype]) { diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index d80f6e7751..45716c362b 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -34,6 +34,13 @@ enum PRIME7 = 10067, PRIME8 = 10079, PRIME9 = 10091, + + AUNK = 100, + // these values are known by runtime + ASIMP = 0, + ASTRING, + APTR, + AINTER, }; /* @@ -553,6 +560,7 @@ Node* nod(int, Node*, Node*); Node* list(Node*, Node*); Type* typ(int); Dcl* dcl(void); +int algtype(Type*); Node* rev(Node*); Node* unrev(Node*); void dodump(Node*, int); diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y index 4f46a1e1dc..69b7c76d0d 100644 --- a/src/cmd/gc/go.y +++ b/src/cmd/gc/go.y @@ -1258,9 +1258,13 @@ structdcl: } | new_name { - // must be a latype + // must be latype $$ = nod(ODCLFIELD, N, N); - $$->type = $1; + $$->type = $1->sym->otype; + if($1->sym->lexical != LATYPE) { + yyerror("unnamed structure field must be a type"); + $$->type = types[TINT32]; + }; } | LIMPORT structdcl { @@ -1691,7 +1695,7 @@ hidden_importfield: * to check whether the rest of the grammar is free of * reduce/reduce conflicts, comment this section out by * removing the slash on the next line. - */ + * lpack: LATYPE { diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 8859b3761c..20ba25344b 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -280,6 +280,28 @@ nod(int op, Node *nleft, Node *nright) return n; } +int +algtype(Type *t) +{ + int a; + + a = AUNK; + if(issimple[t->etype]) + a = ASIMP; // simple mem + else + if(isptrto(t, TSTRING)) + a = ASTRING; // string + else + if(isptr[t->etype]) + a = APTR; // pointer + else + if(isinter(t)) + a = AINTER; // interface +// else +// fatal("algtype: cant find type %T", t); + return a; +} + Node* list(Node *a, Node *b) { diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 417b011214..6029214c4e 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -1884,28 +1884,6 @@ bad: return T; } -static int -algtype(Type *t) -{ - int a; - - a = 100; - if(issimple[t->etype]) - a = 0; // simple mem - else - if(isptrto(t, TSTRING)) - a = 1; // string - else - if(isptr[t->etype]) - a = 2; // pointer - else - if(isinter(t)) - a = 3; // interface - else - fatal("algtype: cant find type %T", t); - return a; -} - Node* mapop(Node *n, int top) { diff --git a/src/runtime/iface.c b/src/runtime/iface.c index b8e980fc48..31d1ae1a33 100644 --- a/src/runtime/iface.c +++ b/src/runtime/iface.c @@ -14,6 +14,9 @@ struct Sigt { byte* name; uint32 hash; + uint32 offset; // offset of substruct + uint32 width; // width of type + uint32 elemalg; // algorithm of type void (*fun)(void); }; @@ -21,7 +24,7 @@ struct Sigi { byte* name; uint32 hash; - uint32 offset; + uint32 perm; // location of fun in Sigt }; struct Map @@ -44,7 +47,7 @@ printsigi(Sigi *si) sys·printpointer(si); prints("{"); - n = si[0].offset; + n = si[0].perm; // first entry has size for(i=1; ifun[0])); m->sigi = si; m->sigt = st; @@ -157,7 +166,7 @@ loop2: goto loop2; } - m->fun[si[ni].offset] = st[nt].fun; + m->fun[si[ni].perm] = st[nt].fun; ni++; goto loop1; } -- 2.48.1