1: #ifndef lint
   2: static char *rcsid =
   3:    "$Header: fasl.c,v 1.10 85/03/24 11:03:34 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 mcnts[],mcntp,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:                  "mcnts",     (int) mcnts,  -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, *fstopen();   /* 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:         strncat(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)  mcnts) {
 473:                     *(int *)(code_core_org+reloc.r_address)
 474:                        += mcntp - offset(reloc);
 475:                 if(doprof){
 476:                  if (mcntp == (int) &mcnts[NMCOUNT-2])
 477:                 printf("Ran out of counters; increas NMCOUNT in fasl.c\n");
 478:                  if (mcntp < (int) &mcnts[NMCOUNT-1])
 479:                     mcntp += 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 = fstopen((char *) literal_core_org, lit_end - lit_org, "r");
 504: 
 505:     if(debug)printf("lit_org %d, charstrt  %d\n",lit_org, p->_base);
 506:     /* the first forms we wish to read are those literals in the
 507: 	 * literal table, that is those forms referenced by an offset
 508: 	 * from r8 in  compiled code
 509: 	 */
 510: 
 511:     /* to read in the forms correctly, we must set up the read table
 512: 	 */
 513:     currtab = Vreadtable->a.clb;
 514:     Vreadtable->a.clb = strtab;     /* standard read table */
 515:     curibase = ibase->a.clb;
 516:     ibase->a.clb = inewint(10);     /* read in decimal */
 517:     ouctolc = uctolc;   /* remember value of uctolc flag */
 518: 
 519:     PUSHDOWN(gcdis,tatom);          /* turn off gc */
 520: 
 521:     i = 1;
 522:     linktab = (lispval *)(lc_org +4);
 523:     while (linktab < (lispval *)lc_end)
 524:     {
 525:        np = svnp;
 526:        protect(P(p));
 527:        uctolc = FALSE;
 528:        handy = (lispval)Lread();
 529:        if (Vpurcopylits->a.clb != nil) {
 530:         handy = Ipurcopy(handy);
 531:        }
 532:        uctolc = ouctolc;
 533:        getc(p);         /* eat trailing blank */
 534:        if(debugmode != nil)
 535:        {   printf("form %d read: ",i++);
 536:            printr(handy,stdout);
 537:            putchar('\n');
 538:            fflush(stdout);
 539:        }
 540:        *linktab++ = handy;
 541:     }
 542: 
 543:     /* process the transfer table if one is used		*/
 544:     trsize = trans_size;
 545:     while(trsize--)
 546:     {
 547:         np = svnp;
 548:         protect(P(p));
 549:         uctolc = FALSE;
 550:         handy = Lread();        /* get function name */
 551:         uctolc = ouctolc;
 552:         getc(p);
 553:         tranloc->name = handy;
 554:         tranloc->fcn = qlinker; /* initially go to qlinker */
 555:         tranloc++;
 556:     }
 557: 
 558: 
 559: 
 560:     /* now process the binder table, which contains pointers to
 561: 	   functions to link in and forms to evaluate.
 562: 	*/
 563:     funcnt = 0;
 564: 
 565:     curbind = (struct bindage *) binder_core_org;
 566:     for( ; curbind->b_type != -1 ; curbind++)
 567:     {
 568:         np = svnp;
 569:         protect(P(p));
 570:         uctolc = FALSE;     /* inhibit uctolc conversion */
 571:         rdform = Lread();
 572:         /* debugging */
 573:         if(debugmode != nil) { printf("link form read: ");
 574:             printr(rdform,stdout);
 575:             printf("  ,type: %d\n",
 576:                  curbind->b_type);
 577:             fflush(stdout);
 578:               }
 579:         /* end debugging */
 580:         uctolc = ouctolc;       /* restore previous state */
 581:         getc(p);            /* eat trailing null */
 582:         protect(rdform);
 583:         if(curbind->b_type <= 2)    /* if function type */
 584:         {
 585:            handy = newfunct();
 586:            if (note_redef && (rdform->a.fnbnd != nil))
 587:            {
 588:            printr(rdform,stdout);
 589:            printf(" redefined\n");
 590:            }
 591:            rdform->a.fnbnd = handy;
 592:            handy->bcd.start = (lispval (*)())(code_core_org + funloc[funcnt++]);
 593:            handy->bcd.discipline =
 594:           (curbind->b_type == 0 ? lambda :
 595:                curbind->b_type == 1 ? nlambda :
 596:               macro);
 597:            if(domap) {
 598:                fprintf(map,"%s\n%x\n",rdform->a.pname,handy->bcd.start);
 599:            }
 600:         }
 601:         else {
 602:         Vreadtable->a.clb = currtab;
 603:         ibase->a.clb = curibase;
 604: 
 605:         /* debugging */
 606:         if(debugmode != nil) {
 607:             printf("Eval: ");
 608:             printr(rdform,stdout);
 609:             printf("\n");
 610:             fflush(stdout);
 611:         };
 612:         /* end debugging */
 613: 
 614:         eval(rdform);       /* otherwise eval it */
 615: 
 616:         if(uctolc) ouctolc = TRUE; /* if changed by eval, remember */
 617:         curibase = ibase->a.clb;
 618:         ibase->a.clb = inewint(10);
 619:         Vreadtable->a.clb = strtab;
 620:        }
 621:     };
 622: 
 623:     fclose(p);  /* give up file descriptor */
 624: 
 625:     POP;            /* restore state of gcdisable variable */
 626: 
 627:     Vreadtable->a.clb = currtab;
 628:     chkrtab(currtab);
 629:     ibase->a.clb = curibase;
 630: 
 631:     fclose(filp);
 632:     if(domap) fclose(map);
 633:     Freexs();
 634:     return(tatom);
 635: }
 636: 
 637: #if m_68k
 638: /* function used in qsort for 68k version only */
 639: compar(arg1,arg2)
 640: int *arg1,*arg2;
 641: {
 642:     if(*arg1 < *arg2) return (-1);
 643:         else if (*arg1 == *arg2) return (0);
 644:     else return(1);
 645: }
 646: #endif
 647: 
 648: /* gettran :: allocate a segment of transfer table of the given size	*/
 649: 
 650: struct trent *
 651: gettran(size)
 652: {
 653:     struct trtab *trp;
 654:     struct trent *retv;
 655:     int ousehole;
 656:     extern int usehole;
 657: 
 658:     if(size > TRENTS)
 659:       error("transfer table too large",FALSE);
 660: 
 661:     if(size > trleft)
 662:     {
 663:         /* allocate a new transfer table */
 664:         /* must not allocate in the hole or we cant modify it */
 665:         ousehole = usehole; /* remember old value */
 666:         usehole = FALSE;
 667:         trp = (struct trtab *)csegment(OTHER,sizeof(struct trtab),FALSE);
 668:         usehole = ousehole;
 669: 
 670:         trp->sentinal = 0;      /* make sure the sentinal is 0 */
 671:         trp->nxtt = trhead; /* link at beginning of table  */
 672:         trhead = trp;
 673:         trcur = &(trp->trentrs[0]); /* begin allocating here	*/
 674:         trleft = TRENTS;
 675:     }
 676: 
 677:     trleft = trleft - size;
 678:     retv = trcur;
 679:     trcur = trcur + size;
 680:     return(retv);
 681: }
 682: 
 683: /* clrtt :: clear transfer tables, or link them all up;
 684:  * this has two totally opposite functions:
 685:  * 1) all transfer tables are reset so that all function calls will go
 686:  * through qlinker
 687:  * 2) as many transfer tables are set up to point to bcd functions
 688:  *    as possible
 689:  */
 690: clrtt(flag)
 691: {
 692:     /*  flag = 0 :: set to qlinker
 693: 	 *  flag = 1 :: set to function bcd binding if possible
 694: 	 */
 695:     register struct trtab *temptt;
 696:     register struct trent *tement;
 697:     register lispval fnb;
 698: 
 699:     for (temptt = trhead; temptt != 0 ; temptt = temptt->nxtt)
 700:     {
 701:         for(tement = &temptt->trentrs[0] ; tement->fcn != 0 ; tement++)
 702:         {   if(flag == 0 || TYPE(fnb=tement->name->a.fnbnd) != BCD
 703:                  || TYPE(fnb->bcd.discipline) == STRNG)
 704:         tement->fcn =  qlinker;
 705:         else tement->fcn = fnb->bcd.start;
 706:         }
 707:     }
 708: }
 709: 
 710: /* chktt - builds a list of transfer table entries which don't yet have
 711:   a function associated with them, i.e if this transfer table entry
 712:   were used, an undefined function error would result
 713:  */
 714: lispval
 715: chktt()
 716: {
 717:     register struct trtab *temptt;
 718:     register struct trent *tement;
 719:     register lispval retlst,curv;
 720:     Savestack(4);
 721: 
 722:     retlst = newdot();      /* build list of undef functions */
 723:     protect(retlst);
 724:     for (temptt = trhead; temptt != 0 ; temptt = temptt->nxtt)
 725:     {
 726:             for(tement = &temptt->trentrs[0] ; tement->fcn != 0 ; tement++)
 727:         {
 728:            if(tement->name->a.fnbnd == nil)
 729:            {
 730:           curv= newdot();
 731:           curv->d.car = tement->name;
 732:           curv->d.cdr = retlst->d.cdr;
 733:           retlst->d.cdr = curv;
 734:         }
 735:          }
 736:      }
 737:      Restorestack();
 738:      return(retlst->d.cdr);
 739: }

Defined functions

Lfasl defined in line 176; never used
chktt defined in line 714; used 2 times
clrtt defined in line 690; used 4 times
compar defined in line 639; used 2 times
gettran defined in line 650; used 2 times

Defined variables

Symbtb defined in line 108; used 11 times
lispval defined in line 714; used 92 times
rcsid defined in line 2; never used
syml defined in line 144; used 9 times

Defined struct's

bindage defined in line 152; used 4 times
ssym defined in line 104; never used

Defined macros

MAXFNS defined in line 174; used 2 times
SYMMAX defined in line 142; used 5 times
offset defined in line 469; used 2 times
Last modified: 1985-08-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1740
Valid CSS Valid XHTML 1.0 Strict