void genp9(Node *file, char *out) { Htab *globls, *strtab; Node *n, **blob; Func **fn; size_t nfn, nblob; size_t i; FILE *fd; /* ensure that all physical registers have a loc created before any * other locs, so that locmap[Physreg] maps to the Loc for the physreg * in question */ for (i = 0; i < Nreg; i++) locphysreg(i); fn = NULL; nfn = 0; blob = NULL; nblob = 0; globls = mkht(varhash, vareq); initconsts(globls); /* We need to define all global variables before use */ fillglobls(file->file.globls, globls); pushstab(file->file.globls); for (i = 0; i < file->file.nstmts; i++) { n = file->file.stmts[i]; switch (n->type) { case Nuse: /* nothing to do */ case Nimpl: break; case Ndecl: simpglobl(n, globls, &fn, &nfn, &blob, &nblob); break; default: die("Bad node %s in toplevel", nodestr[n->type]); break; } } popstab(); fd = fopen(out, "w"); if (!fd) die("Couldn't open fd %s", out); strtab = mkht(strlithash, strliteq); for (i = 0; i < nblob; i++) genblob(fd, blob[i], globls, strtab); for (i = 0; i < nfn; i++) genfunc(fd, fn[i], globls, strtab); for (i = 0; i < ntypes; i++) if (types[i]->isreflect && !types[i]->isimport) gentype(fd, types[i]); fprintf(fd, "\n"); genstrings(fd, strtab); fclose(fd); }
static void simpblk(Simp *s, Node *n) { size_t i; pushstab(n->block.scope); for (i = 0; i < n->block.nstmts; i++) { n->block.stmts[i] = fold(n->block.stmts[i], 0); simp(s, n->block.stmts[i]); } popstab(); }
/* Usefile format: * U<pkgname> * T<pickled-type> * R<picled-trait> * I<pickled-impl> * D<picled-decl> * G<pickled-decl><pickled-initializer> */ int loaduse(char *path, FILE *f, Stab *st, Vis vis) { intptr_t tid; size_t i; int v; char *pkg; Node *dcl, *impl, *init; Stab *s; Type *ty; Trait *tr; char *lib; int c; pushstab(file->file.globls); if (!tydedup) tydedup = mkht(tyhash, tyeq); if (fgetc(f) != 'U') return 0; v = rdint(f); if (v != Abiversion) { fprintf(stderr, "%s: abi version %d, expected %d\n", path, v, Abiversion); return 0; } pkg = rdstr(f); /* if the package names match up, or the usefile has no declared * package, then we simply add to the current stab. Otherwise, * we add a new stab under the current one */ if (st->name) { if (pkg && !strcmp(pkg, st->name)) { s = st; } else { s = findstab(st, pkg); } } else { if (pkg) { s = findstab(st, pkg); } else { s = st; } } if (!streq(st->name, pkg)) vis = Visintern; if (!s) { printf("could not find matching package for merge: %s in %s\n", st->name, path); exit(1); } tidmap = mkht(ptrhash, ptreq); trmap = mkht(ptrhash, ptreq); if (!initmap) initmap = mkht(namehash, nameeq); /* builtin traits */ for (i = 0; i < Ntraits; i++) htput(trmap, itop(i), traittab[i]); while ((c = fgetc(f)) != EOF) { switch(c) { case 'L': lib = rdstr(f); for (i = 0; i < file->file.nlibdeps; i++) if (!strcmp(file->file.libdeps[i], lib)) /* break out of both loop and switch */ goto foundlib; lappend(&file->file.libdeps, &file->file.nlibdeps, lib); foundlib: break; case 'X': lib = rdstr(f); for (i = 0; i < file->file.nextlibs; i++) if (!strcmp(file->file.extlibs[i], lib)) /* break out of both loop and switch */ goto foundextlib; lappend(&file->file.extlibs, &file->file.nextlibs, lib); foundextlib: break; case 'F': lappend(&file->file.files, &file->file.nfiles, rdstr(f)); break; case 'G': case 'D': dcl = rdsym(f, NULL); dcl->decl.vis = vis; dcl->decl.isglobl = 1; putdcl(s, dcl); break; case 'S': init = unpickle(f); if (!hthas(initmap, init)) { htput(initmap, init, init); lappend(&file->file.init, &file->file.ninit, init); } break; case 'R': tr = traitunpickle(f); tr->vis = vis; puttrait(s, tr->name, tr); for (i = 0; i < tr->nfuncs; i++) putdcl(s, tr->funcs[i]); break; case 'T': tid = rdint(f); ty = tyunpickle(f); if(!ty->ishidden) ty->vis = vis; htput(tidmap, itop(tid), ty); /* fix up types */ if (ty->type == Tyname || ty->type == Tygeneric) { if (ty->issynth) break; if (!streq(s->name, ty->name->name.ns)) ty->ishidden = 1; if (!gettype(s, ty->name) && !ty->ishidden) puttype(s, ty->name, ty); } else if (ty->type == Tyunion) { for (i = 0; i < ty->nmemb; i++) if (!getucon(s, ty->udecls[i]->name) && !ty->udecls[i]->synth) putucon(s, ty->udecls[i]); } break; case 'I': impl = unpickle(f); putimpl(s, impl); /* specialized declarations always go into the global stab */ for (i = 0; i < impl->impl.ndecls; i++) putdcl(file->file.globls, impl->impl.decls[i]); break; case EOF: break; } } fixtypemappings(s); fixtraitmappings(s); htfree(tidmap); popstab(); return 1; }
/* Unpickles a node from a file. Minimal checking * is done. Specifically, no checks are done for * sane arities, a bad file can crash the compiler */ static Node *unpickle(FILE *fd) { size_t i; Ntype type; Node *n; type = rdbyte(fd); if (type == Nnone) return NULL; n = mknode(Zloc, type); n->loc.line = rdint(fd); n->loc.file = file->file.nfiles - 1; switch (n->type) { case Nfile: lappend(&n->file.files, &n->file.nfiles, rdstr(fd)); n->file.nuses = rdint(fd); n->file.uses = zalloc(sizeof(Node*)*n->file.nuses); for (i = 0; i < n->file.nuses; i++) n->file.uses[i] = unpickle(fd); n->file.nstmts = rdint(fd); n->file.stmts = zalloc(sizeof(Node*)*n->file.nstmts); for (i = 0; i < n->file.nstmts; i++) n->file.stmts[i] = unpickle(fd); n->file.globls = rdstab(fd, 0); break; case Nexpr: n->expr.op = rdbyte(fd); rdtype(fd, &n->expr.type); n->expr.isconst = rdbool(fd); n->expr.idx = unpickle(fd); n->expr.nargs = rdint(fd); n->expr.args = zalloc(sizeof(Node *)*n->expr.nargs); for (i = 0; i < n->expr.nargs; i++) n->expr.args[i] = unpickle(fd); break; case Nname: if (rdbool(fd)) n->name.ns = rdstr(fd); n->name.name = rdstr(fd); break; case Nuse: n->use.islocal = rdbool(fd); n->use.name = rdstr(fd); break; case Nlit: n->lit.littype = rdbyte(fd); rdtype(fd, &n->lit.type); n->lit.nelt = rdint(fd); switch (n->lit.littype) { case Lchr: n->lit.chrval = rdint(fd); break; case Lint: n->lit.intval = rdint(fd); break; case Lflt: n->lit.fltval = rdflt(fd); break; case Lstr: rdlenstr(fd, &n->lit.strval); break; case Llbl: n->lit.lblval = rdstr(fd); break; case Lbool: n->lit.boolval = rdbool(fd); break; case Lfunc: n->lit.fnval = unpickle(fd); break; } break; case Nloopstmt: n->loopstmt.init = unpickle(fd); n->loopstmt.cond = unpickle(fd); n->loopstmt.step = unpickle(fd); n->loopstmt.body = unpickle(fd); break; case Niterstmt: n->iterstmt.elt = unpickle(fd); n->iterstmt.seq = unpickle(fd); n->iterstmt.body = unpickle(fd); break; case Nmatchstmt: n->matchstmt.val = unpickle(fd); n->matchstmt.nmatches = rdint(fd); n->matchstmt.matches = zalloc(sizeof(Node *)*n->matchstmt.nmatches); for (i = 0; i < n->matchstmt.nmatches; i++) n->matchstmt.matches[i] = unpickle(fd); break; case Nmatch: n->match.pat = unpickle(fd); n->match.block = unpickle(fd); break; case Nifstmt: n->ifstmt.cond = unpickle(fd); n->ifstmt.iftrue = unpickle(fd); n->ifstmt.iffalse = unpickle(fd); break; case Nblock: n->block.scope = rdstab(fd, 0); n->block.nstmts = rdint(fd); n->block.stmts = zalloc(sizeof(Node *)*n->block.nstmts); n->block.scope->super = curstab(); pushstab(n->func.scope->super); for (i = 0; i < n->block.nstmts; i++) n->block.stmts[i] = unpickle(fd); popstab(); break; case Ndecl: n->decl.did = ndecls; /* unique within file */ /* sym */ n->decl.name = unpickle(fd); rdtype(fd, &n->decl.type); /* symflags */ n->decl.isconst = rdbool(fd); n->decl.isgeneric = rdbool(fd); n->decl.isextern = rdbool(fd); n->decl.isnoret = rdbool(fd); n->decl.ispkglocal = rdbool(fd); /* init */ n->decl.init = unpickle(fd); lappend(&decls, &ndecls, n); break; case Nfunc: rdtype(fd, &n->func.type); n->func.scope = rdstab(fd, 1); n->func.nargs = rdint(fd); n->func.args = zalloc(sizeof(Node *)*n->func.nargs); n->func.scope->super = curstab(); pushstab(n->func.scope->super); for (i = 0; i < n->func.nargs; i++) n->func.args[i] = unpickle(fd); n->func.body = unpickle(fd); popstab(); break; case Nimpl: n->impl.traitname = unpickle(fd); i = rdint(fd); rdtrait(fd, &n->impl.trait, NULL); rdtype(fd, &n->impl.type); n->impl.ndecls = rdint(fd); n->impl.decls = zalloc(sizeof(Node *)*n->impl.ndecls); for (i = 0; i < n->impl.ndecls; i++) n->impl.decls[i] = rdsym(fd, n->impl.trait); break; case Nnone: die("Nnone should not be seen as node type!"); break; } return n; }