Annotation of 40BSD/cmd/lisp/nfasl.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.