int EiC_analyseCode(code_t *C) { /* returns the index to the last visited instruction */ block_t *block = NULL; int nb = 0; int i,j,rtn; int *visit; visit = calloc(sizeof(*visit),nextinst(C)+1); block = realloc(block,(nb+1)*sizeof(*block)); block[nb++] = initblock(C,0,visit); for(i=0;i<nb;++i) { for(j=0;j<block[i].nb;++j) { if(!visit[block[i].branch[j]]) { block = realloc(block,(nb+1)*sizeof(*block)); block[nb++] = initblock(C,block[i].branch[j],visit); } else visit[block[i].branch[j]]++; } } rtn = 0; for(i=0;i<=nextinst(C);) if(visit[i]) rtn = i++; else if(i < nextinst(C) && instline(C,i)) { EiC_warningerror("Unreachable code at line %d",instline(C,i)); for(;i<nextinst(C) && !visit[i];i++) ; } else i++; EiC_peephole(C,visit); /******* for(i=0;i<nextinst(C);++i) if(!visit[i]) setopcode(C,i,empty); *******/ freeblock(block,nb); free(visit); return rtn; }
static block_t initblock(code_t *c, int leader, int *visit) { int i; block_t b; b.leader = leader; b.branch = NULL; b.nb = 0; b.ninst = 0; for(i=leader;i<nextinst(c);++i) { visit[i]++; b.ninst++; if(opcode(c,i) == eicreturn) break; else if(isgoto(c,i)) { /*printf("[%d:%d]\n",i,i+ivalcode(c,i));*/ addbranch(b.branch,b.nb,i+ivalcode(c,i)); if(opcode(c,i) != jmpu) { /*printf("[%d:%d]\n",i,i+1);*/ addbranch(b.branch,b.nb,i+1); } break; } else if(opcode(c,i) == jmptab) { struct {int n;val_t *loc;} *p; int j; p = pvalcode(c,i); addbranch(b.branch,b.nb,i + p->loc[0].ival); for(j =1;j<p->n;j+=2) addbranch(b.branch,b.nb,i + p->loc[j+1].ival); break; } } if(leader == nextinst(c)) visit[leader]++; return b; }
void EiC_peephole(code_t *C, int *visit) { int i, n,j; n = nextinst(C); for(i = 0; i < n; ++i) if(isgoto(C,i)) { j = i + ivalcode(C,i); if(j >= n) continue; if(opcode(C,j) == jmpu || opcode(C,i) == opcode(C,j)) { /*visit[i+ivalcode(C,i)]--;*/ ivalcode(C,i) += ivalcode(C,j); } } }
/* * This returns the correct package instance based on how many packages are * already installed. If there are none (npkgs == 0), it just returns the * package abbreviation. Otherwise, it interacts with the user (or reads the * admin file) to determine if we should overwrite an instance which is * already installed, or possibly install a new instance of this package */ char * getinst(int *updatingExisting, struct pkginfo *info, int npkgs, boolean_t a_preinstallCheck) { char *inst; char *sameinst; int i; int nsamearch; int samearch; /* entry debugging info */ same_pkg = 0; /* * If this is the first instance of the package, it's called the by * the package abbreviation. */ if (npkgs == 0) { return (pkgabrv); } /* * this package is already installed; determine how to handle the * new instance of the package to install */ if (ADM(instance, "newonly") || ADM(instance, "quit")) { /* * new instance is required, or quit if not new */ msgtext = MSG_NEWONLY; if (a_preinstallCheck == B_FALSE) { ptext(stderr, msgtext, pkgabrv); } else { (void) fprintf(stdout, "install-new-only=true\n"); (void) fprintf(stdout, "ckinstance=4\n"); } quit(4); } /* * package already installed and new instance not required * see if updating the same instance of the package */ samearch = nsamearch = 0; sameinst = NULL; for (i = 0; i < npkgs; i++) { if (strcmp(info[i].arch, pkgarch) == 0) { samearch = i; nsamearch++; if (strcmp(info[i].version, pkgvers) == 0) { sameinst = info[i].pkginst; } } } if (sameinst) { /* same instance of package */ if (a_preinstallCheck == B_FALSE) { ptext(stderr, MSG_SAME); } else { (void) fprintf(stdout, "install-same-instance=true\n"); (void) fprintf(stdout, "ckinstance=0\n"); } inst = sameinst; /* can't be overwriting a pre-svr4 package */ same_pkg++; (*updatingExisting)++; return (inst); } if (ADM(instance, "overwrite")) { /* not the same instance of the package */ if (npkgs == 1) { samearch = 0; /* use only package we know about */ } else if (nsamearch != 1) { /* * more than one instance of the same ARCH is already * installed on this machine */ msgtext = MSG_OVERWRITE; if (a_preinstallCheck == B_FALSE) { ptext(stderr, msgtext); } else { (void) fprintf(stdout, "install-ovewrite=true\n"); (void) fprintf(stdout, "ckinstance=4\n"); } quit(4); } inst = info[samearch].pkginst; if (info[samearch].status == PI_PRESVR4) { opresvr4++; /* overwriting a pre-svr4 package */ } (*updatingExisting)++; return (inst); } if (ADM(instance, "unique")) { if (maxinst <= npkgs) { /* too many instances */ msgtext = MSG_UNIQ1; if (a_preinstallCheck == B_FALSE) { ptext(stderr, msgtext, pkgabrv); } else { (void) fprintf(stdout, "install-too-many-instances=true\n"); (void) fprintf(stdout, "ckinstance=4\n"); } quit(4); } inst = nextinst(); return (inst); } if (a_preinstallCheck == B_FALSE) { if (echoGetFlag() == B_FALSE) { msgtext = MSG_NOINTERACT; ptext(stderr, msgtext); quit(5); } } else { (void) fprintf(stdout, "install-new-instance=true\n"); (void) fprintf(stdout, "ckinstance=1\n"); } inst = prompt(info, npkgs); if (strcmp(inst, "new") == 0) { inst = nextinst(); return (inst); } (*updatingExisting)++; /* see if this instance is presvr4 */ for (i = 0; i < npkgs; i++) { if (strcmp(inst, info[i].pkginst) == 0) { if (info[i].status == PI_PRESVR4) { opresvr4++; } break; } } return (inst); }