1
0
mirror of https://github.com/golang/go synced 2024-09-25 13:20:13 -06:00

6l: generate gotypesigs on demand.

add sys.unreflect, which uses gotypesigs.

R=r
DELTA=170  (152 added, 12 deleted, 6 changed)
OCL=18396
CL=18404
This commit is contained in:
Russ Cox 2008-11-03 16:03:12 -08:00
parent bcd6403cc9
commit 47caf6424c
7 changed files with 158 additions and 18 deletions

View File

@ -7,6 +7,7 @@
// accumulate all type information from .6 files. // accumulate all type information from .6 files.
// check for inconsistencies. // check for inconsistencies.
// define gotypestrings variable if needed. // define gotypestrings variable if needed.
// define gotypesigs variable if needed.
// TODO: // TODO:
// include type info for non-exported types. // include type info for non-exported types.
@ -301,6 +302,16 @@ importcmp(const void *va, const void *vb)
return strcmp(a->name, b->name); return strcmp(a->name, b->name);
} }
static int
symcmp(const void *va, const void *vb)
{
Sym *a, *b;
a = *(Sym**)va;
b = *(Sym**)vb;
return strcmp(a->name, b->name);
}
// if there is an undefined reference to gotypestrings, // if there is an undefined reference to gotypestrings,
// create it. c declaration is // create it. c declaration is
// extern char gotypestrings[]; // extern char gotypestrings[];
@ -309,7 +320,7 @@ importcmp(const void *va, const void *vb)
void void
definetypestrings(void) definetypestrings(void)
{ {
int i, j, len, n; int i, j, len, n, w;
char *p; char *p;
Import **all, *x; Import **all, *x;
Fmt f; Fmt f;
@ -376,27 +387,79 @@ definetypestrings(void)
// (had to add D_SBIG even to do that; the compiler // (had to add D_SBIG even to do that; the compiler
// would have generated 8-byte chunks.) // would have generated 8-byte chunks.)
for(i=0; i<n; i+=100) { for(i=0; i<n; i+=100) {
prog = mal(sizeof *prog); w = 100;
prog->as = ADATA; if(w > n - i)
prog->width = 100; w = n - i;
if(prog->width > n - i) prog = newdata(s, i, w, D_EXTERN);
prog->width = n - i;
prog->from.scale = prog->width;
prog->from.type = D_EXTERN;
prog->from.sym = s;
prog->from.offset = i;
prog->to.type = D_SBIG; prog->to.type = D_SBIG;
prog->to.sbig = p + i; prog->to.sbig = p + i;
if(edatap == P)
datap = prog;
else
edatap->link = prog;
edatap = prog;
prog->link = P;
} }
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f typestrings %d\n", cputime(), n); Bprint(&bso, "%5.2f typestrings %d\n", cputime(), n);
} }
// if there is an undefined reference to gotypesigs, create it.
// c declaration is
// extern Sigt *gotypesigs[];
// extern int ngotypesigs;
// used by sys.unreflect runtime.
void
definetypesigs(void)
{
int i, j, n;
Sym **all, *s, *x;
Prog *prog;
if(debug['g'])
return;
if(debug['v'])
Bprint(&bso, "%5.2f definetypesigs\n", cputime());
s = lookup("gotypesigs", 0);
if(s->type == 0)
return;
if(s->type != SXREF) {
diag("gotypesigs already defined");
return;
}
s->type = SDATA;
// make a list of all the sigt symbols.
n = 0;
for(i=0; i<NHASH; i++)
for(x = hash[i]; x; x=x->link)
if(memcmp(x->name, "sigt·", 6) == 0)
n++;
all = mal(n*sizeof all[0]);
j = 0;
for(i=0; i<NHASH; i++)
for(x = hash[i]; x; x=x->link)
if(memcmp(x->name, "sigt·", 6) == 0)
all[j++] = x;
// sort them by name
qsort(all, n, sizeof all[0], symcmp);
// emit array as sequence of references.
enum { PtrSize = 8 };
for(i=0; i<n; i++) {
prog = newdata(s, PtrSize*i, PtrSize, D_EXTERN);
prog->to.type = D_ADDR;
prog->to.index = D_EXTERN;
prog->to.sym = all[i];
}
s->value = PtrSize*n;
// emit count
s = lookup("ngotypesigs", 0);
s->type = SDATA;
s->value = sizeof(int32);
prog = newdata(s, 0, sizeof(int32), D_EXTERN);
prog->to.offset = n;
if(debug['v'])
Bprint(&bso, "%5.2f typestrings %d\n", cputime(), n);
}

View File

@ -380,6 +380,7 @@ Prog* copyp(Prog*);
double cputime(void); double cputime(void);
void datblk(int32, int32); void datblk(int32, int32);
void definetypestrings(void); void definetypestrings(void);
void definetypesigs(void);
void diag(char*, ...); void diag(char*, ...);
void dodata(void); void dodata(void);
void doinit(void); void doinit(void);
@ -409,6 +410,7 @@ void lputl(int32);
void main(int, char*[]); void main(int, char*[]);
void mkfwd(void); void mkfwd(void);
void* mysbrk(uint32); void* mysbrk(uint32);
Prog* newdata(Sym*, int, int, int);
void nuxiinit(void); void nuxiinit(void);
void objfile(char*); void objfile(char*);
int opsize(Prog*); int opsize(Prog*);

View File

@ -369,6 +369,7 @@ main(int argc, char *argv[])
objfile(a); objfile(a);
} }
definetypestrings(); definetypestrings();
definetypesigs();
firstp = firstp->link; firstp = firstp->link;
if(firstp == P) if(firstp == P)

View File

@ -926,7 +926,7 @@ ckoff(Sym *s, int32 v)
diag("relocation offset %ld for %s out of range", v, s->name); diag("relocation offset %ld for %s out of range", v, s->name);
} }
static Prog* Prog*
newdata(Sym *s, int o, int w, int t) newdata(Sym *s, int o, int w, int t)
{ {
Prog *p; Prog *p;

View File

@ -33,6 +33,7 @@ export func ifaceI2T(sigt *byte, iface any) (ret any);
export func ifaceI2I(sigi *byte, iface any) (ret any); export func ifaceI2I(sigi *byte, iface any) (ret any);
export func ifaceeq(i1 any, i2 any) (ret bool); export func ifaceeq(i1 any, i2 any) (ret bool);
export func reflect(i interface { }) (uint64, string); export func reflect(i interface { }) (uint64, string);
export func unreflect(uint64, string) (ret interface { });
export func argc() int; export func argc() int;
export func envc() int; export func envc() int;

View File

@ -25,6 +25,7 @@ char *sysimport =
"export func sys.ifaceI2I (sigi *uint8, iface any) (ret any)\n" "export func sys.ifaceI2I (sigi *uint8, iface any) (ret any)\n"
"export func sys.ifaceeq (i1 any, i2 any) (ret bool)\n" "export func sys.ifaceeq (i1 any, i2 any) (ret bool)\n"
"export func sys.reflect (i interface { }) (? uint64, ? string)\n" "export func sys.reflect (i interface { }) (? uint64, ? string)\n"
"export func sys.unreflect (? uint64, ? string) (ret interface { })\n"
"export func sys.argc () (? int)\n" "export func sys.argc () (? int)\n"
"export func sys.envc () (? int)\n" "export func sys.envc () (? int)\n"
"export func sys.argv (? int) (? string)\n" "export func sys.argv (? int) (? string)\n"

View File

@ -378,3 +378,75 @@ sys·reflect(Map *im, void *it, uint64 retit, string rettype)
FLUSH(&retit); FLUSH(&retit);
FLUSH(&rettype); FLUSH(&rettype);
} }
extern Sigt *gotypesigs[];
extern int32 ngotypesigs;
static Sigt*
fakesigt(string type)
{
// TODO(rsc): Cache these by type string.
Sigt *sigt;
// Must be pointer in order for alg, width to be right.
if(type == nil || type->len == 0 || type->str[0] != '*') {
// TODO(rsc): What to do here?
prints("bad unreflect type: ");
sys·printstring(type);
prints("\n");
throw("unreflect");
}
sigt = mal(2*sizeof sigt[0]);
sigt[0].name = mal(type->len + 1);
mcpy(sigt[0].name, type->str, type->len);
sigt[0].hash = ASIMP; // alg
sigt[0].offset = sizeof(void*); // width
return sigt;
}
static int32
cmpstringchars(string a, uint8 *b)
{
int32 i;
for(i=0;; i++) {
if(i == a->len) {
if(b[i] == 0)
return 0;
return -1;
}
if(b[i] == 0)
return 1;
if(a->str[i] != b[i]) {
if((uint8)a->str[i] < (uint8)b[i])
return -1;
return 1;
}
}
}
static Sigt*
findtype(string type)
{
int32 i;
for(i=0; i<ngotypesigs; i++)
if(cmpstringchars(type, gotypesigs[i]->name) == 0)
return gotypesigs[i];
return fakesigt(type);
}
void
sys·unreflect(uint64 it, string type, Map *retim, void *retit)
{
if(cmpstring(type, emptystring) == 0) {
retim = 0;
retit = 0;
} else {
retim = hashmap(sigi·inter, findtype(type), 0);
retit = (void*)it;
}
FLUSH(&retim);
FLUSH(&retit);
}