|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid = ! 3: "$Header: fasl.c,v 1.8 83/09/12 14:17:38 sklower Exp $"; ! 4: #endif ! 5: ! 6: /* -[Thu Jun 2 21:44:26 1983 by jkf]- ! 7: * fasl.c $Locker: $ ! 8: * compiled lisp loader ! 9: * ! 10: * (c) copyright 1982, Regents of the University of California ! 11: */ ! 12: ! 13: #include "global.h" ! 14: #include <sys/types.h> ! 15: #include "lispo.h" ! 16: #include "chkrtab.h" ! 17: #include "structs.h" ! 18: #include "frame.h" ! 19: ! 20: /* fasl - fast loader j.k.foderaro ! 21: * this loader is tuned for the lisp fast loading application ! 22: * any changes in the system loading procedure will require changes ! 23: * to this file ! 24: * ! 25: * The format of the object file we read as input: ! 26: * text segment: ! 27: * 1) program text - this comes first. ! 28: * 2) binder table - one word entries, see struct bindage ! 29: * begins with symbol: bind_org ! 30: * 3) litterals - exploded lisp objects. ! 31: * begins with symbol: lit_org ! 32: * ends with symbol: lit_end ! 33: * data segment: ! 34: * not used ! 35: * ! 36: * ! 37: * these segments are created permanently in memory: ! 38: * code segment - contains machine codes to evaluate lisp functions. ! 39: * linker segment - a list of pointers to lispvals. This allows the ! 40: * compiled code to reference constant lisp objects. ! 41: * The first word of the linker segment is a gc link ! 42: * pointer and does not point to a literal. The ! 43: * symbol binder is assumed to point to the second ! 44: * longword in this segment. The last word in the ! 45: * table is -1 as a sentinal to the gc marker. ! 46: * The number of real entries in the linker segment ! 47: * is given as the value of the linker_size symbol. ! 48: * Taking into account the 2 words required for the ! 49: * gc, there are 4*linker_size + 8 bytes in this segment. ! 50: * transfer segment - this is a transfer table block. It is used to ! 51: * allow compiled code to call other functions ! 52: * quickly. The number of entries in the transfer table is ! 53: * given as the value of the trans_size symbol. ! 54: * ! 55: * the following segments are set up in memory temporarily then flushed ! 56: * binder segment - a list of struct bindage entries. They describe ! 57: * what to do with the literals read from the literal ! 58: * table. The binder segment begins in the file ! 59: * following the bindorg symbol. ! 60: * literal segment - a list of characters which _Lread will read to ! 61: * create the lisp objects. The order of the literals ! 62: * is: ! 63: * linker literals - used to fill the linker segment. ! 64: * transfer table literals - used to fill the ! 65: * transfer segment ! 66: * binder literals - these include names of functions ! 67: * to bind interspersed with forms to evaluate. ! 68: * The meanings of the binder literals is given by ! 69: * the values in the binder segment. ! 70: * string segment - this is the string table from the file. We have ! 71: * to allocate space for it in core to speed up ! 72: * symbol referencing. ! 73: * ! 74: */ ! 75: ! 76: ! 77: /* external functions called or referenced */ ! 78: ! 79: lispval qcons(),qlinker(),qget(); ! 80: int _qf0(), _qf1(), _qf2(), _qf3(), _qf4(), _qfuncl(), svkludg(),qnewint(); ! 81: int qnewdoub(),qoneplus(),qoneminus(), wnaerr(); ! 82: lispval Lread(), Lcons(), Lminus(), Ladd1(), Lsub1(), Lplist(), Lputprop(); ! 83: lispval Lprint(), Lpatom(), Lconcat(), Lget(), Lmapc(), Lmapcan(); ! 84: lispval Llist(), Ladd(), Lgreaterp(), Lequal(), Ltimes(), Lsub(), Ipurcopy(); ! 85: lispval Lncons(), Ibindvars(), Iunbindvars(),error(); ! 86: int Inonlocalgo(); ! 87: lispval Istsrch(); ! 88: int mcount(), qpushframe(); ! 89: extern int mcounts[],mcountp,doprof; ! 90: ! 91: extern lispval *tynames[]; ! 92: extern struct frame *errp; ! 93: extern char _erthrow[]; ! 94: ! 95: extern int initflag; /* when TRUE, inhibits gc */ ! 96: ! 97: char *alloca(); /* stack space allocator */ ! 98: ! 99: /* mini symbol table, contains the only external symbols compiled code ! 100: is allowed to reference ! 101: */ ! 102: ! 103: ! 104: struct ssym { char *fnam; /* pointer to string containing name */ ! 105: int floc; /* address of symbol */ ! 106: int ord; /* ordinal number within cur sym tab */ ! 107: ! 108: } Symbtb[] ! 109: = { ! 110: "trantb", 0, -1, /* must be first */ ! 111: "linker", 0, -1, /* must be second */ ! 112: "mcount", (int) mcount, -1, ! 113: "mcounts", (int) mcounts, -1, ! 114: "_wnaerr", (int) wnaerr, -1, ! 115: "_qnewint", (int) qnewint, -1, ! 116: "_qnewdoub", (int) qnewdoub, -1, ! 117: "_qcons", (int) qcons, -1, ! 118: "_qoneplus", (int) qoneplus, -1, ! 119: "_qoneminus", (int) qoneminus, -1, ! 120: "_typetable", (int) typetable, -1, ! 121: "_tynames", (int) tynames, -1, ! 122: "_qget", (int) qget, -1, ! 123: "_errp", (int) &errp, -1, ! 124: "_Inonlocalgo", (int) Inonlocalgo, -1, ! 125: "__erthrow", (int) _erthrow, -1, ! 126: "_error", (int) error, -1, ! 127: "_qpushframe", (int) qpushframe, -1, ! 128: "_retval", (int)&retval, -1, ! 129: "_lispretval", (int)&lispretval,-1, ! 130: #ifndef NPINREG ! 131: "_np", (int) &np, -1, ! 132: "_lbot", (int) &lbot, -1, ! 133: #endif ! 134: #ifndef NILIS0 ! 135: "_nilatom", (int) &nilatom, -1, ! 136: #endif ! 137: "_bnp", (int) &bnp, -1, ! 138: "_Ibindvars", (int) Ibindvars, -1, ! 139: "_Iunbindvars", (int) Iunbindvars, -1 ! 140: }; ! 141: ! 142: #define SYMMAX ((sizeof Symbtb) / (sizeof (struct ssym))) ! 143: ! 144: struct nlist syml; /* to read a.out symb tab */ ! 145: extern int *bind_lists; /* gc binding lists */ ! 146: ! 147: /* bindage structure: ! 148: * the bindage structure describes the linkages of functions and name, ! 149: * and tells which functions should be evaluated. It is mainly used ! 150: * for the non-fasl'ing of files, we only use one of the fields in fasl ! 151: */ ! 152: struct bindage ! 153: { ! 154: int b_type; /* type code, as described below */ ! 155: }; ! 156: ! 157: /* the possible values of b_type ! 158: * -1 - this is the end of the bindage entries ! 159: * 0 - this is a lambda function ! 160: * 1 - this is a nlambda function ! 161: * 2 - this is a macro function ! 162: * 99 - evaluate the string ! 163: * ! 164: */ ! 165: ! 166: ! 167: extern struct trtab *trhead; /* head of list of transfer tables */ ! 168: extern struct trent *trcur; /* next entry to allocate */ ! 169: extern int trleft; /* # of entries left in this transfer table */ ! 170: ! 171: struct trent *gettran(); /* function to allocate entries */ ! 172: ! 173: /* maximum number of functions */ ! 174: #define MAXFNS 2000 ! 175: ! 176: lispval Lfasl() ! 177: { ! 178: extern int holend,usehole; ! 179: extern int uctolc; ! 180: extern char *curhbeg; ! 181: struct argent *svnp; ! 182: struct exec exblk; /* stores a.out header */ ! 183: FILE *filp, *p, *map; /* file pointer */ ! 184: int domap,note_redef; ! 185: lispval handy,debugmode; ! 186: struct relocation_info reloc; ! 187: struct trent *tranloc; ! 188: int trsize; ! 189: int i,j,times, *iptr; ! 190: int funloc[MAXFNS]; /* addresses of functions rel to txt org */ ! 191: int funcnt = 0; ! 192: ! 193: /* symbols whose values are taken from symbol table of .o file */ ! 194: int bind_org = 0; /* beginning of bind table */ ! 195: int lit_org = 0; /* beginning of literal table */ ! 196: int lit_end; /* end of literal table */ ! 197: int trans_size = 0; /* size in entries of transfer table */ ! 198: int linker_size; /* size in bytes of linker table ! 199: (not counting gc ptr) */ ! 200: ! 201: /* symbols which hold the locations of the segments in core and ! 202: * in the file ! 203: */ ! 204: char *code_core_org, /* beginning of code segment */ ! 205: *lc_org, /* beginning of linker segment */ ! 206: *lc_end, /* last word in linker segment */ ! 207: *literal_core_org, /* beginning of literal table */ ! 208: *binder_core_org, /* beginning of binder table */ ! 209: *string_core_org; ! 210: ! 211: int /*string_file_org, /* location of string table in file */ ! 212: string_size, /* number of chars in string table */ ! 213: segsiz; /* size of permanent incore segment */ ! 214: ! 215: char *symbol_name; ! 216: struct bindage *curbind; ! 217: lispval rdform, *linktab; ! 218: int ouctolc; ! 219: int debug = 0; ! 220: lispval currtab,curibase; ! 221: char ch,*filnm,*nfilnm; ! 222: char tempfilbf[100]; ! 223: char *strcat(); ! 224: long lseek(); ! 225: Keepxs(); ! 226: ! 227: ! 228: switch(np-lbot) { ! 229: case 0: ! 230: protect(nil); ! 231: case 1: ! 232: protect(nil); ! 233: case 2: ! 234: protect(nil); ! 235: case 3: ! 236: break; ! 237: default: ! 238: argerr("fasl"); ! 239: } ! 240: filnm = (char *) verify(lbot->val,"fasl: non atom arg"); ! 241: ! 242: ! 243: domap = FALSE; ! 244: /* debugging */ ! 245: debugmode = Istsrch(matom("debugging"))->d.cdr->d.cdr->d.cdr; ! 246: if (debugmode != nil) debug = 1; ! 247: /* end debugging */ ! 248: ! 249: ! 250: /* insure that the given file name ends in .o ! 251: if it doesnt, copy to a new buffer and add a .o ! 252: but Allow non .o file names (5mar80 jkf) ! 253: */ ! 254: tempfilbf[0] = '\0'; ! 255: nfilnm = filnm; /* same file name for now */ ! 256: if( (i = strlen(filnm)) < 2 || ! 257: strcmp(filnm+i-2,".o") != 0) ! 258: { ! 259: strcatn(tempfilbf,filnm,96); ! 260: strcat(tempfilbf,".o"); ! 261: nfilnm = tempfilbf; ! 262: } ! 263: ! 264: if ( (filp = fopen(nfilnm,"r")) == NULL) ! 265: if ((filnm == nfilnm) || ((filp = fopen(filnm,"r")) == NULL)) ! 266: errorh1(Vermisc,"Can't open file",nil,FALSE,9797,lbot->val); ! 267: ! 268: if ((handy = (lbot+1)->val) != nil ) ! 269: { ! 270: if((TYPE(handy) != ATOM ) || ! 271: (map = fopen(handy->a.pname, ! 272: (Istsrch(matom("appendmap"))->d.cdr->d.cdr->d.cdr == nil ! 273: ? "w" : "a"))) == NULL) ! 274: error("fasl: can't open map file",FALSE); ! 275: else ! 276: { domap = TRUE; ! 277: /* fprintf(map,"Map of file %s\n",lbot->val->a.pname); */ ! 278: } ! 279: } ! 280: ! 281: /* set the note redefinition flag */ ! 282: if((lbot+2)->val != nil) note_redef = TRUE; ! 283: else note_redef = FALSE; ! 284: ! 285: /* if nil don't print fasl message */ ! 286: if ( Vldprt->a.clb != nil ) { ! 287: printf("[fasl %s]",filnm); ! 288: fflush(stdout); ! 289: } ! 290: svnp = np; ! 291: ! 292: ! 293: ! 294: /* clear the ords in the symbol table */ ! 295: for(i=0 ; i < SYMMAX ; i++) Symbtb[i].ord = -1; ! 296: ! 297: if( read(fileno(filp),(char *)&exblk,sizeof(struct exec)) ! 298: != sizeof(struct exec)) ! 299: error("fasl: header read failed",FALSE); ! 300: ! 301: /* check that the magic number is valid */ ! 302: ! 303: if(exblk.a_magic != 0407) ! 304: errorh1(Vermisc,"fasl: file is not a lisp object file (bad magic number): ", ! 305: nil,FALSE,0,lbot->val); ! 306: ! 307: /* read in string table */ ! 308: lseek(fileno(filp),(long)(/*string_file_org =*/N_STROFF(exblk)),0); ! 309: if( read(fileno(filp), (char *)&string_size , 4) != 4) ! 310: error("fasl: string table read error, probably old fasl format", FALSE); ! 311: ! 312: lbot = np; /* set up base for later calls */ ! 313: /* allocate space for string table on the stack */ ! 314: string_core_org = alloca(string_size - 4); ! 315: ! 316: if( read(fileno(filp), string_core_org , string_size - 4) ! 317: != string_size -4) error("fasl: string table read error ",FALSE); ! 318: /* read in symbol table and set the ordinal values */ ! 319: ! 320: fseek(filp,(long) (N_SYMOFF(exblk)),0); ! 321: ! 322: times = exblk.a_syms/sizeof(struct nlist); ! 323: if(debug) printf(" %d symbols in symbol table\n",times); ! 324: ! 325: for(i=0; i < times ; i++) ! 326: { ! 327: if( fread((char *)&syml,sizeof(struct nlist),1,filp) != 1) ! 328: error("fasl: Symb tab read error",FALSE); ! 329: ! 330: symbol_name = syml.n_un.n_strx - 4 + string_core_org; ! 331: if(debug) printf("symbol %s\n read\n",symbol_name); ! 332: if (syml.n_type == N_EXT) ! 333: { ! 334: for(j=0; j< SYMMAX; j++) ! 335: { ! 336: if((Symbtb[j].ord < 0) ! 337: && strcmp(Symbtb[j].fnam,symbol_name)==0) ! 338: { Symbtb[j].ord = i; ! 339: if(debug)printf("symbol %s ord is %d\n",symbol_name,i); ! 340: break; ! 341: }; ! 342: ! 343: }; ! 344: ! 345: if( j>=SYMMAX ) printf("Unknown symbol %s\n",symbol_name); ! 346: } ! 347: else if (((ch = symbol_name[0]) == 's') ! 348: || (ch == 'L') ! 349: || (ch == '.') ) ; /* skip this */ ! 350: else if (symbol_name[0] == 'F') ! 351: { ! 352: if(funcnt >= MAXFNS) ! 353: error("fasl: too many function in file",FALSE); ! 354: funloc[funcnt++] = syml.n_value; /* seeing function */ ! 355: } ! 356: else if (!bind_org && (strcmp(symbol_name, "bind_org") == 0)) ! 357: bind_org = syml.n_value; ! 358: else if (strcmp(symbol_name, "lit_org") == 0) ! 359: lit_org = syml.n_value; ! 360: else if (strcmp(symbol_name, "lit_end") == 0) ! 361: lit_end = syml.n_value; ! 362: else if (strcmp(symbol_name, "trans_size") == 0) ! 363: trans_size = syml.n_value; ! 364: else if (strcmp(symbol_name, "linker_size") == 0) ! 365: linker_size = syml.n_value; ! 366: } ! 367: ! 368: #if m_68k ! 369: /* 68k only, on the vax the symbols appear in the correct order */ ! 370: { int compar(); ! 371: qsort(funloc,funcnt,sizeof(int),compar); ! 372: } ! 373: #endif ! 374: ! 375: if (debug) ! 376: printf("lit_org %x, lit_end %x, bind_org %x, linker_size %x\n", ! 377: lit_org, lit_end, bind_org, linker_size); ! 378: /* check to make sure we are working with the right format */ ! 379: if((lit_org == 0) || (lit_end == 0)) ! 380: errorh1(Vermisc,"File not in new fasl format",nil,FALSE,0,lbot->val); ! 381: ! 382: /*----------------*/ ! 383: ! 384: /* read in text segment up to beginning of binder table */ ! 385: ! 386: segsiz = bind_org + 4*linker_size + 8 + 3; /* size is core segment size ! 387: * plus linker table size ! 388: * plus 2 for gc list ! 389: * plus 3 to round up to word ! 390: */ ! 391: ! 392: lseek(fileno(filp),(long)sizeof(struct exec),0); ! 393: code_core_org = (char *) csegment(OTHER,segsiz,TRUE); ! 394: if(read(fileno(filp),code_core_org,bind_org) != bind_org) ! 395: error("Read error in text ",FALSE); ! 396: ! 397: if(debug) { ! 398: printf("Read %d bytes of text into 0x%x\n",bind_org,code_core_org); ! 399: printf(" incore segment size: %d (0x%x)\n",segsiz,segsiz); ! 400: } ! 401: ! 402: /* linker table is 2 entries (8 bytes) larger than the number of ! 403: * entries given by linker_size . There must be a gc word at ! 404: * the beginning and a -1 at the end ! 405: */ ! 406: lc_org = code_core_org + bind_org; ! 407: lc_end = lc_org + 4*linker_size + 4; ! 408: /* address of gc sentinal last */ ! 409: ! 410: if(debug)printf("lin_cor_org: %x, link_cor_end %x\n", ! 411: lc_org, ! 412: lc_end); ! 413: Symbtb[1].floc = (int) (lc_org + 4); ! 414: ! 415: /* set the linker table to all -1's so we can put in the gc table */ ! 416: for( iptr = (int *)(lc_org + 4 ); ! 417: iptr <= (int *)(lc_end); ! 418: iptr++) ! 419: *iptr = -1; ! 420: ! 421: ! 422: /* link our table into the gc tables */ ! 423: /* only do so if we will not purcopy these tables */ ! 424: if(Vpurcopylits->a.clb == nil) ! 425: { ! 426: *(int *)lc_org = (int)bind_lists; /* point to current */ ! 427: bind_lists = (int *) (lc_org + 4); /* point to first ! 428: item */ ! 429: } ! 430: ! 431: /* read the binder table and literals onto the stack */ ! 432: ! 433: binder_core_org = alloca(lit_end - bind_org); ! 434: read(fileno(filp),binder_core_org,lit_end-bind_org); ! 435: ! 436: literal_core_org = binder_core_org + lit_org - bind_org; ! 437: ! 438: /* check if there is a transfer table required for this ! 439: * file, and if so allocate one of the necessary size ! 440: */ ! 441: ! 442: if(trans_size > 0) ! 443: { ! 444: tranloc = gettran(trans_size); ! 445: Symbtb[0].floc = (int) tranloc; ! 446: } ! 447: ! 448: /* now relocate the necessary symbols in the text segment */ ! 449: ! 450: fseek(filp,(long)(sizeof(struct exec) + exblk.a_text + exblk.a_data),0); ! 451: times = (exblk.a_trsize)/sizeof(struct relocation_info); ! 452: ! 453: /* the only symbols we will relocate are references to ! 454: external symbols. They are recognized by ! 455: extern and pcrel set. ! 456: */ ! 457: ! 458: for( i=1; i<=times ; i++) ! 459: { ! 460: if( fread((char *)&reloc,sizeof(struct relocation_info),1,filp) != 1) ! 461: error("Bad text reloc read",FALSE); ! 462: if(reloc.r_extern) ! 463: { ! 464: for(j=0; j < SYMMAX; j++) ! 465: { ! 466: ! 467: if(Symbtb[j].ord == reloc.r_symbolnum) /* look for this sym */ ! 468: { ! 469: #define offset(p) (((p).r_pcrel) ? ((int) code_core_org): 0) ! 470: if(debug && FALSE) printf("Relocating %d (ord %d) at %x\n", ! 471: j, Symbtb[j].ord, reloc.r_address); ! 472: if (Symbtb[j].floc == (int) mcounts) { ! 473: *(int *)(code_core_org+reloc.r_address) ! 474: += mcountp - offset(reloc); ! 475: if(doprof){ ! 476: if (mcountp == (int) &mcounts[NMCOUNT-2]) ! 477: printf("Ran out of counters; increas NMCOUNT in fasl.c\n"); ! 478: if (mcountp < (int) &mcounts[NMCOUNT-1]) ! 479: mcountp += 4; ! 480: } ! 481: } else ! 482: *(int *)(code_core_org+reloc.r_address) ! 483: += Symbtb[j].floc - offset(reloc); ! 484: ! 485: break; ! 486: ! 487: } ! 488: }; ! 489: if( j >= SYMMAX) if(debug) printf("Couldnt find ord # %d\n", ! 490: reloc.r_symbolnum); ! 491: } ! 492: ! 493: } ! 494: ! 495: if ( Vldprt->a.clb != nil ) { ! 496: putchar('\n'); ! 497: fflush(stdout); ! 498: } ! 499: ! 500: /* set up a fake port so we can read from core */ ! 501: /* first find a free port */ ! 502: ! 503: p = stdin; ! 504: for( ; p->_flag & (_IOREAD|_IOWRT|_IORW) ; p++) ! 505: if( p >= _iob + _NFILE) ! 506: error(" No free file descriptor for fasl ",FALSE); ! 507: ! 508: p->_flag = _IOREAD | _IOSTRG; ! 509: p->_base = p->_ptr = (char *) literal_core_org; /* start at beginning of lit */ ! 510: p->_cnt = lit_end - lit_org; ! 511: ! 512: if(debug)printf("lit_org %d, charstrt %d\n",lit_org, p->_base); ! 513: /* the first forms we wish to read are those literals in the ! 514: * literal table, that is those forms referenced by an offset ! 515: * from r8 in compiled code ! 516: */ ! 517: ! 518: /* to read in the forms correctly, we must set up the read table ! 519: */ ! 520: currtab = Vreadtable->a.clb; ! 521: Vreadtable->a.clb = strtab; /* standard read table */ ! 522: curibase = ibase->a.clb; ! 523: ibase->a.clb = inewint(10); /* read in decimal */ ! 524: ouctolc = uctolc; /* remember value of uctolc flag */ ! 525: ! 526: PUSHDOWN(gcdis,tatom); /* turn off gc */ ! 527: ! 528: i = 1; ! 529: linktab = (lispval *)(lc_org +4); ! 530: while (linktab < (lispval *)lc_end) ! 531: { ! 532: np = svnp; ! 533: protect(P(p)); ! 534: uctolc = FALSE; ! 535: handy = (lispval)Lread(); ! 536: if (Vpurcopylits->a.clb != nil) { ! 537: handy = Ipurcopy(handy); ! 538: } ! 539: uctolc = ouctolc; ! 540: getc(p); /* eat trailing blank */ ! 541: if(debugmode != nil) ! 542: { printf("form %d read: ",i++); ! 543: printr(handy,stdout); ! 544: putchar('\n'); ! 545: fflush(stdout); ! 546: } ! 547: *linktab++ = handy; ! 548: } ! 549: ! 550: /* process the transfer table if one is used */ ! 551: trsize = trans_size; ! 552: while(trsize--) ! 553: { ! 554: np = svnp; ! 555: protect(P(p)); ! 556: uctolc = FALSE; ! 557: handy = Lread(); /* get function name */ ! 558: uctolc = ouctolc; ! 559: getc(p); ! 560: tranloc->name = handy; ! 561: tranloc->fcn = qlinker; /* initially go to qlinker */ ! 562: tranloc++; ! 563: } ! 564: ! 565: ! 566: ! 567: /* now process the binder table, which contains pointers to ! 568: functions to link in and forms to evaluate. ! 569: */ ! 570: funcnt = 0; ! 571: ! 572: curbind = (struct bindage *) binder_core_org; ! 573: for( ; curbind->b_type != -1 ; curbind++) ! 574: { ! 575: np = svnp; ! 576: protect(P(p)); ! 577: uctolc = FALSE; /* inhibit uctolc conversion */ ! 578: rdform = Lread(); ! 579: /* debugging */ ! 580: if(debugmode != nil) { printf("link form read: "); ! 581: printr(rdform,stdout); ! 582: printf(" ,type: %d\n", ! 583: curbind->b_type); ! 584: fflush(stdout); ! 585: } ! 586: /* end debugging */ ! 587: uctolc = ouctolc; /* restore previous state */ ! 588: getc(p); /* eat trailing null */ ! 589: protect(rdform); ! 590: if(curbind->b_type <= 2) /* if function type */ ! 591: { ! 592: handy = newfunct(); ! 593: if (note_redef && (rdform->a.fnbnd != nil)) ! 594: { ! 595: printr(rdform,stdout); ! 596: printf(" redefined\n"); ! 597: } ! 598: rdform->a.fnbnd = handy; ! 599: handy->bcd.start = (lispval (*)())(code_core_org + funloc[funcnt++]); ! 600: handy->bcd.discipline = ! 601: (curbind->b_type == 0 ? lambda : ! 602: curbind->b_type == 1 ? nlambda : ! 603: macro); ! 604: if(domap) { ! 605: fprintf(map,"%s\n%x\n",rdform->a.pname,handy->bcd.start); ! 606: } ! 607: } ! 608: else { ! 609: Vreadtable->a.clb = currtab; ! 610: ibase->a.clb = curibase; ! 611: ! 612: /* debugging */ ! 613: if(debugmode != nil) { ! 614: printf("Eval: "); ! 615: printr(rdform,stdout); ! 616: printf("\n"); ! 617: fflush(stdout); ! 618: }; ! 619: /* end debugging */ ! 620: ! 621: eval(rdform); /* otherwise eval it */ ! 622: ! 623: if(uctolc) ouctolc = TRUE; /* if changed by eval, remember */ ! 624: curibase = ibase->a.clb; ! 625: ibase->a.clb = inewint(10); ! 626: Vreadtable->a.clb = strtab; ! 627: } ! 628: }; ! 629: ! 630: p->_cnt = p->_file = p->_flag = 0; /* give up file descriptor */ ! 631: p->_ptr = p-> _base = (char *) 0; ! 632: ! 633: POP; /* restore state of gcdisable variable */ ! 634: ! 635: Vreadtable->a.clb = currtab; ! 636: chkrtab(currtab); ! 637: ibase->a.clb = curibase; ! 638: ! 639: fclose(filp); ! 640: if(domap) fclose(map); ! 641: Freexs(); ! 642: return(tatom); ! 643: } ! 644: ! 645: #if m_68k ! 646: /* function used in qsort for 68k version only */ ! 647: compar(arg1,arg2) ! 648: int *arg1,*arg2; ! 649: { ! 650: if(*arg1 < *arg2) return (-1); ! 651: else if (*arg1 == *arg2) return (0); ! 652: else return(1); ! 653: } ! 654: #endif ! 655: ! 656: /* gettran :: allocate a segment of transfer table of the given size */ ! 657: ! 658: struct trent * ! 659: gettran(size) ! 660: { ! 661: struct trtab *trp; ! 662: struct trent *retv; ! 663: int ousehole; ! 664: extern int usehole; ! 665: ! 666: if(size > TRENTS) ! 667: error("transfer table too large",FALSE); ! 668: ! 669: if(size > trleft) ! 670: { ! 671: /* allocate a new transfer table */ ! 672: /* must not allocate in the hole or we cant modify it */ ! 673: ousehole = usehole; /* remember old value */ ! 674: usehole = FALSE; ! 675: trp = (struct trtab *)csegment(OTHER,sizeof(struct trtab),FALSE); ! 676: usehole = ousehole; ! 677: ! 678: trp->sentinal = 0; /* make sure the sentinal is 0 */ ! 679: trp->nxtt = trhead; /* link at beginning of table */ ! 680: trhead = trp; ! 681: trcur = &(trp->trentrs[0]); /* begin allocating here */ ! 682: trleft = TRENTS; ! 683: } ! 684: ! 685: trleft = trleft - size; ! 686: retv = trcur; ! 687: trcur = trcur + size; ! 688: return(retv); ! 689: } ! 690: ! 691: /* clrtt :: clear transfer tables, or link them all up; ! 692: * this has two totally opposite functions: ! 693: * 1) all transfer tables are reset so that all function calls will go ! 694: * through qlinker ! 695: * 2) as many transfer tables are set up to point to bcd functions ! 696: * as possible ! 697: */ ! 698: clrtt(flag) ! 699: { ! 700: /* flag = 0 :: set to qlinker ! 701: * flag = 1 :: set to function bcd binding if possible ! 702: */ ! 703: register struct trtab *temptt; ! 704: register struct trent *tement; ! 705: register lispval fnb; ! 706: ! 707: for (temptt = trhead; temptt != 0 ; temptt = temptt->nxtt) ! 708: { ! 709: for(tement = &temptt->trentrs[0] ; tement->fcn != 0 ; tement++) ! 710: { if(flag == 0 || TYPE(fnb=tement->name->a.fnbnd) != BCD ! 711: || TYPE(fnb->bcd.discipline) == STRNG) ! 712: tement->fcn = qlinker; ! 713: else tement->fcn = fnb->bcd.start; ! 714: } ! 715: } ! 716: } ! 717: ! 718: /* chktt - builds a list of transfer table entries which don't yet have ! 719: a function associated with them, i.e if this transfer table entry ! 720: were used, an undefined function error would result ! 721: */ ! 722: lispval ! 723: chktt() ! 724: { ! 725: register struct trtab *temptt; ! 726: register struct trent *tement; ! 727: register lispval retlst,curv; ! 728: Savestack(4); ! 729: ! 730: retlst = newdot(); /* build list of undef functions */ ! 731: protect(retlst); ! 732: for (temptt = trhead; temptt != 0 ; temptt = temptt->nxtt) ! 733: { ! 734: for(tement = &temptt->trentrs[0] ; tement->fcn != 0 ; tement++) ! 735: { ! 736: if(tement->name->a.fnbnd == nil) ! 737: { ! 738: curv= newdot(); ! 739: curv->d.car = tement->name; ! 740: curv->d.cdr = retlst->d.cdr; ! 741: retlst->d.cdr = curv; ! 742: } ! 743: } ! 744: } ! 745: Restorestack(); ! 746: return(retlst->d.cdr); ! 747: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.