Annotation of 40BSD/cmd/lisp/nfasl.c, revision 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.