Annotation of gforth/main.c, revision 1.10

1.1       anton       1: /*
1.10    ! anton       2:   $Id: main.c,v 1.9 1994/08/25 15:25:30 anton Exp $
1.1       anton       3:   Copyright 1993 by the ANSI figForth Development Group
                      4: */
                      5: 
                      6: #include <ctype.h>
                      7: #include <stdio.h>
                      8: #include <string.h>
                      9: #include <math.h>
                     10: #include <sys/types.h>
                     11: #include <sys/stat.h>
                     12: #include <fcntl.h>
                     13: #include <assert.h>
                     14: #include <stdlib.h>
                     15: #include "forth.h"
1.5       pazsan     16: #include "io.h"
1.10    ! anton      17: #include "getopt.h"
1.1       anton      18: 
1.2       pazsan     19: #ifndef DEFAULTBIN
                     20: #      define DEFAULTBIN ""
                     21: #endif
                     22: 
1.10    ! anton      23: #ifndef DEFAULTPATH
        !            24: #      define DEFAULTPATH "/usr/local/lib/gforth:."
        !            25: #endif
        !            26: 
1.1       anton      27: #ifdef DIRECT_THREADED
1.2       pazsan     28: #      define CA(n)    (symbols[(n)])
1.1       anton      29: #else
1.2       pazsan     30: #      define CA(n)    ((int)(symbols+(n)))
1.1       anton      31: #endif
                     32: 
1.10    ! anton      33: #define maxaligned(n)  ((((Cell)n)+sizeof(Float)-1)&-sizeof(Float))
        !            34: 
        !            35: static int dictsize=0;
        !            36: static int dsize=0;
        !            37: static int rsize=0;
        !            38: static int fsize=0;
        !            39: static int lsize=0;
        !            40: char *progname;
        !            41: 
        !            42: 
1.1       anton      43: /* image file format:
                     44:  *   size of image with stacks without tags (in bytes)
                     45:  *   size of image without stacks and tags (in bytes)
1.5       pazsan     46:  *   size of data and FP stack (in bytes)
1.1       anton      47:  *   pointer to start of code
1.7       anton      48:  *   pointer into throw (for signal handling)
1.1       anton      49:  *   data (size in image[1])
                     50:  *   tags (1 bit/data cell)
                     51:  *
                     52:  * tag==1 mean that the corresponding word is an address;
                     53:  * If the word is >=0, the address is within the image;
                     54:  * addresses within the image are given relative to the start of the image.
                     55:  * If the word is =-1, the address is NIL,
1.2       pazsan     56:  * If the word is between -2 and -5, it's a CFA (:, Create, Constant, User)
                     57:  * If the word is -6, it's a DOES> CFA
                     58:  * If the word is -7, it's a DOES JUMP
                     59:  * If the word is <-7, it's a primitive
1.1       anton      60:  */
                     61: 
1.10    ! anton      62: void relocate(Cell *image, char *bitstring, int size, Label symbols[])
1.1       anton      63: {
1.5       pazsan     64:    int i=0, j, k, steps=(size/sizeof(Cell))/8;
                     65:    char bits;
                     66: /*   static char bits[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};*/
                     67:    
                     68:    for(k=0; k<=steps; k++)
                     69:      for(j=0, bits=bitstring[k]; j<8; j++, i++, bits<<=1)
                     70:        if(bits & 0x80)
                     71:          if(image[i]<0)
                     72:            switch(image[i])
                     73:              {
                     74:                case CF_NIL      : image[i]=0; break;
                     75:                case CF(DOCOL)   :
                     76:                case CF(DOVAR)   :
                     77:                case CF(DOCON)   :
1.9       anton      78:                case CF(DOUSER)  : 
                     79:                case CF(DODEFER)  : 
                     80:                  MAKE_CF(image+i,symbols[CF(image[i])]); break;
1.5       pazsan     81:                case CF(DODOES)  : MAKE_DOES_CF(image+i,image[i+1]+((int)image));
                     82:                                   break;
                     83:                case CF(DOESJUMP): MAKE_DOES_HANDLER(image+i); break;
                     84:                default          : image[i]=(Cell)CA(CF(image[i]));
                     85:             }
                     86:          else
                     87:            image[i]+=(Cell)image;
1.2       pazsan     88: 
1.5       pazsan     89:    CACHE_FLUSH(image,size);
1.1       anton      90: }
                     91: 
1.10    ! anton      92: Cell *loader(FILE *imagefile)
        !            93: {
        !            94:        Cell header[3];
        !            95:        Cell *image;
        !            96:        int wholesize;
        !            97:        int imagesize; /* everything needed by the image */
        !            98: 
        !            99:        fread(header,1,3*sizeof(Cell),imagefile);
        !           100:        if (dictsize==0)
        !           101:          dictsize = header[0];
        !           102:        if (dsize==0)
        !           103:          dsize=header[2];
        !           104:        if (rsize==0)
        !           105:          rsize=header[2];
        !           106:        if (fsize==0)
        !           107:          fsize=header[2];
        !           108:        if (lsize==0)
        !           109:          lsize=header[2];
        !           110:        dictsize=maxaligned(dictsize);
        !           111:        dsize=maxaligned(dsize);
        !           112:        rsize=maxaligned(rsize);
        !           113:        lsize=maxaligned(lsize);
        !           114:        fsize=maxaligned(fsize);
        !           115: 
        !           116:        wholesize = dictsize+dsize+rsize+fsize+lsize;
        !           117:        imagesize = header[1]+((header[1]-1)/sizeof(Cell))/8+1;
        !           118:        image=malloc(wholesize>imagesize?wholesize:imagesize);
        !           119:        memset(image,0,wholesize); /* why? - anton */
1.1       anton     120:        image[0]=header[0];
                    121:        image[1]=header[1];
1.10    ! anton     122:        image[2]=header[2];
1.1       anton     123: 
1.10    ! anton     124:        fread(image+3,1,header[1]-3*sizeof(Cell),imagefile);
        !           125:        fread(((void *)image)+header[1],1,((header[1]-1)/sizeof(Cell))/8+1,
1.1       anton     126:              imagefile);
                    127:        fclose(imagefile);
                    128: 
1.10    ! anton     129:        relocate(image,(char *)image+header[1],header[1],engine(0,0,0,0,0));
1.1       anton     130: 
                    131:        return(image);
                    132: }
                    133: 
1.10    ! anton     134: int go_forth(Cell *image, int stack, Cell *entries)
1.1       anton     135: {
1.10    ! anton     136:        Cell *sp=(Cell*)((void *)image+dictsize+dsize);
        !           137:        Address lp=(Address)((void *)sp+lsize);
        !           138:        Float *fp=(Float *)((void *)lp+fsize);
        !           139:        Cell *rp=(Cell*)((void *)fp+rsize);
        !           140:        Xt *ip=(Xt *)(image[3]);
1.8       pazsan    141:        int throw_code;
1.10    ! anton     142: 
1.1       anton     143:        for(;stack>0;stack--)
                    144:                *--sp=entries[stack-1];
                    145: 
                    146:        install_signal_handlers(); /* right place? */
1.8       pazsan    147: 
                    148:        if ((throw_code=setjmp(throw_jmp_buf))) {
                    149:                static Cell signal_data_stack[8];
                    150:                static Cell signal_return_stack[8];
                    151: 
                    152:                signal_data_stack[7]=throw_code;
                    153: 
1.10    ! anton     154:                return((int)engine((Xt *)image[4],signal_data_stack+7,
        !           155:                                                  signal_return_stack+8,0,0));
1.8       pazsan    156:        }
1.1       anton     157: 
1.4       anton     158:        return((int)engine(ip,sp,rp,fp,lp));
1.1       anton     159: }
                    160: 
1.10    ! anton     161: int convsize(char *s, int elemsize)
        !           162: /* converts s of the format #+u (e.g. 25k) into the number of bytes.
        !           163:    the unit u can be one of bekM, where e stands for the element
        !           164:    size. default is e */
        !           165: {
        !           166:   char *endp;
        !           167:   int n,m;
        !           168: 
        !           169:   m = elemsize;
        !           170:   n = strtoul(s,&endp,0);
        !           171:   if (endp!=NULL) {
        !           172:     if (strcmp(endp,"b")==0)
        !           173:       m=1;
        !           174:     else if (strcmp(endp,"k")==0)
        !           175:       m=1024;
        !           176:     else if (strcmp(endp,"M")==0)
        !           177:       m=1024*1024;
        !           178:     else if (strcmp(endp,"e")!=0) {
        !           179:       fprintf(stderr,"%s: cannot grok size specification %s\n", progname, s);
        !           180:       exit(1);
        !           181:     }
        !           182:   }
        !           183:   return n*m;
        !           184: }
        !           185: 
1.1       anton     186: int main(int argc, char **argv, char **env)
                    187: {
1.10    ! anton     188:        char *path, *path1;
        !           189:        char *imagename="gforth.fi";
        !           190:        FILE *image_file;
        !           191:        int c;
        !           192:          
1.6       anton     193: #if defined(i386) && defined(ALIGNMENT_CHECK)
                    194:        /* turn on alignment checks on the 486.
                    195:         * on the 386 this should have no effect. */
                    196:        __asm__("pushfl; popl %eax; orl $0x40000, %eax; pushl %eax; popfl;");
                    197: #endif
1.2       pazsan    198: 
1.10    ! anton     199:        progname = argv[0];
        !           200:        if ((path=getenv("GFORTHPATH"))==NULL)
        !           201:          path = strcpy(malloc(strlen(DEFAULTPATH)+1),DEFAULTPATH);
        !           202:        opterr=0;
        !           203:        while (1) {
        !           204:          int option_index=0;
        !           205:          static struct option opts[] = {
        !           206:            {"image-file", required_argument, NULL, 'i'},
        !           207:            {"dictionary-size", required_argument, NULL, 'm'},
        !           208:            {"data-stack-size", required_argument, NULL, 'd'},
        !           209:            {"return-stack-size", required_argument, NULL, 'r'},
        !           210:            {"fp-stack-size", required_argument, NULL, 'f'},
        !           211:            {"locals-stack-size", required_argument, NULL, 'l'},
        !           212:            {"path", required_argument, NULL, 'p'},
        !           213:            {0,0,0,0}
        !           214:            /* no-init-file, no-rc? */
        !           215:          };
        !           216: 
        !           217:          c = getopt_long(argc, argv, "+drfl", opts, &option_index);
        !           218:          if (c==EOF)
        !           219:            break;
        !           220:          if (c=='?') {
        !           221:            optind--;
        !           222:            break;
        !           223:          }
        !           224:          switch (c) {
        !           225:          case 'i': imagename = optarg; break;
        !           226:          case 'm': dictsize = convsize(optarg,sizeof(Cell)); break;
        !           227:          case 'd': dsize = convsize(optarg,sizeof(Cell)); break;
        !           228:          case 'r': rsize = convsize(optarg,sizeof(Cell)); break;
        !           229:          case 'f': fsize = convsize(optarg,sizeof(Float)); break;
        !           230:          case 'l': lsize = convsize(optarg,sizeof(Cell)); break;
        !           231:          case 'p': path = optarg; break;
        !           232:          }
1.2       pazsan    233:        }
1.10    ! anton     234:        path1=path;
        !           235:        do {
        !           236:          char *pend=strchr(path, ':');
        !           237:          if (pend==NULL)
        !           238:            pend=path+strlen(path);
        !           239:          if (strlen(path)==0) {
        !           240:            fprintf(stderr,"%s: cannot open image file %s in path %s for reading\n", progname, imagename, path1);
        !           241:            exit(1);
        !           242:          }
        !           243:          {
        !           244:            int dirlen=pend-path;
        !           245:            char fullfilename[dirlen+strlen(imagename)+2];
        !           246:            memcpy(fullfilename, path, dirlen);
        !           247:            if (fullfilename[dirlen-1]!='/')
        !           248:              fullfilename[dirlen++]='/';
        !           249:            strcpy(fullfilename+dirlen,imagename);
        !           250:            image_file=fopen(fullfilename,"rb");
        !           251:          }
        !           252:          path=pend+(*pend==':');
        !           253:        } while (image_file==NULL);
1.1       anton     254: 
                    255:        {
1.10    ! anton     256:          Cell environ[]= {(Cell)argc-(optind-1), (Cell)(argv+(optind-1)), (Cell)path1};
        !           257:          argv[optind-1] = progname;
        !           258: /*
        !           259:          for (i=0; i<environ[0]; i++)
        !           260:            printf("%s\n", ((char **)(environ[1]))[i]);
        !           261: */
        !           262:          exit(go_forth(loader(image_file),3, environ));
1.1       anton     263:        }
                    264: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>