Annotation of gforth/main.c, revision 1.8

1.1       anton       1: /*
1.8     ! pazsan      2:   $Id: main.c,v 1.7 1994/07/08 15:00:55 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.1       anton      17: 
1.7       anton      18: Xt *throw_ip;
                     19: 
                     20: 
1.2       pazsan     21: #ifndef DEFAULTBIN
                     22: #      define DEFAULTBIN ""
                     23: #endif
                     24: 
1.1       anton      25: #ifdef DIRECT_THREADED
1.2       pazsan     26: #      define CA(n)    (symbols[(n)])
1.1       anton      27: #else
1.2       pazsan     28: #      define CA(n)    ((int)(symbols+(n)))
1.1       anton      29: #endif
                     30: 
                     31: /* image file format:
                     32:  *   size of image with stacks without tags (in bytes)
                     33:  *   size of image without stacks and tags (in bytes)
1.5       pazsan     34:  *   size of data and FP stack (in bytes)
1.1       anton      35:  *   pointer to start of code
1.7       anton      36:  *   pointer into throw (for signal handling)
1.1       anton      37:  *   data (size in image[1])
                     38:  *   tags (1 bit/data cell)
                     39:  *
                     40:  * tag==1 mean that the corresponding word is an address;
                     41:  * If the word is >=0, the address is within the image;
                     42:  * addresses within the image are given relative to the start of the image.
                     43:  * If the word is =-1, the address is NIL,
1.2       pazsan     44:  * If the word is between -2 and -5, it's a CFA (:, Create, Constant, User)
                     45:  * If the word is -6, it's a DOES> CFA
                     46:  * If the word is -7, it's a DOES JUMP
                     47:  * If the word is <-7, it's a primitive
1.1       anton      48:  */
                     49: 
                     50: void relocate(int *image, char *bitstring, int size, Label symbols[])
                     51: {
1.5       pazsan     52:    int i=0, j, k, steps=(size/sizeof(Cell))/8;
                     53:    char bits;
                     54: /*   static char bits[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};*/
                     55:    
                     56:    for(k=0; k<=steps; k++)
                     57:      for(j=0, bits=bitstring[k]; j<8; j++, i++, bits<<=1)
                     58:        if(bits & 0x80)
                     59:          if(image[i]<0)
                     60:            switch(image[i])
                     61:              {
                     62:                case CF_NIL      : image[i]=0; break;
                     63:                case CF(DOCOL)   :
                     64:                case CF(DOVAR)   :
                     65:                case CF(DOCON)   :
                     66:                case CF(DOUSER)  : MAKE_CF(image+i,symbols[CF(image[i])]); break;
                     67:                case CF(DODOES)  : MAKE_DOES_CF(image+i,image[i+1]+((int)image));
                     68:                                   break;
                     69:                case CF(DOESJUMP): MAKE_DOES_HANDLER(image+i); break;
                     70:                default          : image[i]=(Cell)CA(CF(image[i]));
                     71:             }
                     72:          else
                     73:            image[i]+=(Cell)image;
1.2       pazsan     74: 
1.5       pazsan     75:    CACHE_FLUSH(image,size);
1.1       anton      76: }
                     77: 
                     78: int* loader(const char* filename)
                     79: {      int header[2];
                     80:        FILE *imagefile;
                     81:        int *image;
                     82: 
                     83:        if(!(int)(imagefile=fopen(filename,"rb")))
                     84:        {
                     85:                fprintf(stderr,"Can't open image file '%s'",filename);
                     86:                exit(1);
                     87:        }
                     88: 
                     89:        fread(header,1,2*sizeof(int),imagefile);
                     90: 
                     91:        image=malloc(header[0]+((header[0]-1)/sizeof(Cell))/8+1);
                     92: 
                     93:        memset(image,0,header[0]+((header[0]-1)/sizeof(Cell))/8+1);
                     94: 
                     95:        image[0]=header[0];
                     96:        image[1]=header[1];
                     97: 
                     98:        fread(image+2,1,header[1]-2*sizeof(Cell),imagefile);
                     99:        fread(((void *)image)+header[0],1,((header[1]-1)/sizeof(Cell))/8+1,
                    100:              imagefile);
                    101:        fclose(imagefile);
                    102: 
1.4       anton     103:        relocate(image,(char *)image+header[0],header[1],engine(0,0,0,0,0));
1.1       anton     104: 
                    105:        return(image);
                    106: }
                    107: 
                    108: int go_forth(int *image, int stack, Cell *entries)
                    109: {
                    110:        Cell* rp=(Cell*)((void *)image+image[0]);
                    111:        double* fp=(double*)((void *)rp-image[2]);
1.4       anton     112:        Address lp=(Address)((void *)fp-image[2]);
                    113:        Cell* sp=(Cell*)((void *)lp-image[2]);
1.1       anton     114:        Cell* ip=(Cell*)(image[3]);
1.8     ! pazsan    115:        int throw_code;
1.7       anton     116:        
                    117:        throw_ip = (Xt *)(image[4]);
1.1       anton     118:        for(;stack>0;stack--)
                    119:                *--sp=entries[stack-1];
                    120: 
                    121:        install_signal_handlers(); /* right place? */
1.8     ! pazsan    122: 
        !           123:        if ((throw_code=setjmp(throw_jmp_buf))) {
        !           124:                static Cell signal_data_stack[8];
        !           125:                static Cell signal_return_stack[8];
        !           126: 
        !           127:                signal_data_stack[7]=throw_code;
        !           128: 
        !           129:                return((int)engine(image[4],signal_data_stack+7,
        !           130:                                            signal_return_stack+8,0,0));
        !           131:        }
1.1       anton     132: 
1.4       anton     133:        return((int)engine(ip,sp,rp,fp,lp));
1.1       anton     134: }
                    135: 
                    136: int main(int argc, char **argv, char **env)
                    137: {
                    138:        char imagefile[256];
                    139:        Cell environ[3] = {(Cell)argc, (Cell)argv, (Cell)env};
                    140:        char* imagepath;
                    141: 
1.6       anton     142: #if defined(i386) && defined(ALIGNMENT_CHECK)
                    143:        /* turn on alignment checks on the 486.
                    144:         * on the 386 this should have no effect. */
                    145:        __asm__("pushfl; popl %eax; orl $0x40000, %eax; pushl %eax; popfl;");
                    146: #endif
1.1       anton     147:        if((int)(imagepath=getenv("FORTHBIN")))
                    148:        {
                    149:                strcpy(imagefile,imagepath);
                    150: 
                    151:                if(imagefile[strlen(imagefile)-1]!='/')
                    152:                        imagefile[strlen(imagefile)]='/';
                    153:        }
                    154:        else
1.2       pazsan    155:        {
                    156:                strcpy(imagefile,DEFAULTBIN);
                    157: 
                    158:                if(imagefile[0]!=0 && imagefile[strlen(imagefile)-1]!='/')
                    159:                        imagefile[strlen(imagefile)]='/';
                    160:        }
1.1       anton     161: 
                    162:        if(argc>1 && argv[1][0]=='@')
                    163:        {
                    164:                if(argv[1][1]=='/')
                    165:                        strcpy(imagefile,argv[1]+1);
                    166:                else
                    167:                        strcpy(imagefile+strlen(imagefile),argv[1]+1);
                    168: 
                    169:                environ[0]-=1;
                    170:                environ[1]+=sizeof(argv);
                    171:                argv[1]=argv[0];
                    172:        }
                    173:        else
                    174:                strcpy(imagefile+strlen(imagefile),"kernal.fi");
                    175: 
                    176:        exit(go_forth(loader(imagefile),3,environ));
                    177: }

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