| jmp_buf throw_jmp_buf; |
jmp_buf throw_jmp_buf; |
| #endif |
#endif |
| |
|
| #ifndef DEFAULTPATH |
#if defined(DIRECT_THREADED) |
| # define DEFAULTPATH "/usr/local/lib/gforth:." |
|
| #endif |
|
| |
|
| #ifdef DIRECT_THREADED |
|
| # define CA(n) (symbols[(n)]) |
# define CA(n) (symbols[(n)]) |
| #else |
#else |
| # define CA(n) ((Cell)(symbols+(n))) |
# define CA(n) ((Cell)(symbols+(n))) |
| static UCell rsize=0; |
static UCell rsize=0; |
| static UCell fsize=0; |
static UCell fsize=0; |
| static UCell lsize=0; |
static UCell lsize=0; |
| static int image_offset=0; |
int offset_image=0; |
| static int clear_dictionary=0; |
static int clear_dictionary=0; |
| static int debug=0; |
static int debug=0; |
| static size_t pagesize=0; |
static size_t pagesize=0; |
| switch(image[i]) |
switch(image[i]) |
| { |
{ |
| case CF_NIL : image[i]=0; break; |
case CF_NIL : image[i]=0; break; |
| |
#if !defined(DOUBLY_INDIRECT) |
| case CF(DOCOL) : |
case CF(DOCOL) : |
| case CF(DOVAR) : |
case CF(DOVAR) : |
| case CF(DOCON) : |
case CF(DOCON) : |
| case CF(DOUSER) : |
case CF(DOUSER) : |
| case CF(DODEFER) : |
case CF(DODEFER) : |
| case CF(DOFIELD) : MAKE_CF(image+i,symbols[CF(image[i])]); break; |
case CF(DOFIELD) : MAKE_CF(image+i,symbols[CF(image[i])]); break; |
| case CF(DODOES) : MAKE_DOES_CF(image+i,image[i+1]+((Cell)image)); |
|
| break; |
|
| case CF(DOESJUMP): MAKE_DOES_HANDLER(image+i); break; |
case CF(DOESJUMP): MAKE_DOES_HANDLER(image+i); break; |
| |
#endif /* !defined(DOUBLY_INDIRECT) */ |
| |
case CF(DODOES) : |
| |
MAKE_DOES_CF(image+i,image[i+1]+((Cell)image)); |
| |
break; |
| default : |
default : |
| /* printf("Code field generation image[%x]:=CA(%x)\n", |
/* printf("Code field generation image[%x]:=CA(%x)\n", |
| i, CF(image[i])); |
i, CF(image[i])); */ |
| */ image[i]=(Cell)CA(CF(image[i])); |
image[i]=(Cell)CA(CF(image[i])); |
| } |
} |
| else |
else |
| image[i]+=(Cell)image; |
image[i]+=(Cell)image; |
| static Address next_address=0; |
static Address next_address=0; |
| Address r; |
Address r; |
| |
|
| #if HAVE_MMAP && defined(MAP_ANON) |
#if HAVE_MMAP |
| |
#if defined(MAP_ANON) |
| if (debug) |
if (debug) |
| fprintf(stderr,"try mmap($%lx, $%lx, ...); ", (long)next_address, (long)size); |
fprintf(stderr,"try mmap($%lx, $%lx, ..., MAP_ANON, ...); ", (long)next_address, (long)size); |
| r=mmap(next_address, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); |
r=mmap(next_address, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); |
| |
#else /* !defined(MAP_ANON) */ |
| |
static int dev_zero=-1; |
| |
|
| |
if (dev_zero == -1) |
| |
dev_zero = open("/dev/zero", O_RDONLY); |
| |
if (dev_zero == -1) { |
| |
r = (Address)-1; |
| |
if (debug) |
| |
fprintf(stderr, "open(\"/dev/zero\"...) failed (%s), no mmap; ", |
| |
strerror(errno)); |
| |
} else { |
| |
if (debug) |
| |
fprintf(stderr,"try mmap($%lx, $%lx, ..., MAP_FILE, dev_zero, ...); ", (long)next_address, (long)size); |
| |
r=mmap(next_address, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, dev_zero, 0); |
| |
} |
| |
#endif /* !defined(MAP_ANON) */ |
| |
|
| if (r != (Address)-1) { |
if (r != (Address)-1) { |
| if (debug) |
if (debug) |
| fprintf(stderr, "success, address=$%lx\n", (long) r); |
fprintf(stderr, "success, address=$%lx\n", (long) r); |
| } |
} |
| if (debug) |
if (debug) |
| fprintf(stderr, "failed: %s\n", strerror(errno)); |
fprintf(stderr, "failed: %s\n", strerror(errno)); |
| #endif |
#endif /* HAVE_MMAP */ |
| /* use malloc as fallback, leave a little room (64B) for stack underflows */ |
/* use malloc as fallback, leave a little room (64B) for stack underflows */ |
| if ((r = malloc(size+64))==NULL) { |
if ((r = malloc(size+64))==NULL) { |
| perror(progname); |
perror(progname); |
| Char magic[9]; |
Char magic[9]; |
| Cell preamblesize=0; |
Cell preamblesize=0; |
| Label *symbols=engine(0,0,0,0,0); |
Label *symbols=engine(0,0,0,0,0); |
| UCell check_sum=checksum(symbols); |
Cell data_offset = offset_image ? 28*sizeof(Cell) : 0; |
| |
UCell check_sum; |
| static char* endianstring[]= { "big","little" }; |
static char* endianstring[]= { "big","little" }; |
| |
|
| |
#ifndef DOUBLY_INDIRECT |
| |
check_sum = checksum(symbols); |
| |
#else /* defined(DOUBLY_INDIRECT) */ |
| |
check_sum = (UCell)symbols; |
| |
#endif /* defined(DOUBLY_INDIRECT) */ |
| |
|
| do |
do |
| { |
{ |
| if(fread(magic,sizeof(Char),8,imagefile) < 8) { |
if(fread(magic,sizeof(Char),8,imagefile) < 8) { |
| #elif HAVE_SYSCONF && defined(_SC_PAGESIZE) |
#elif HAVE_SYSCONF && defined(_SC_PAGESIZE) |
| pagesize=sysconf(_SC_PAGESIZE); /* POSIX.4 */ |
pagesize=sysconf(_SC_PAGESIZE); /* POSIX.4 */ |
| #elif PAGESIZE |
#elif PAGESIZE |
| pagesize=PAGESIZE; /* in limits.h accoring to Gallmeister's POSIX.4 book */ |
pagesize=PAGESIZE; /* in limits.h according to Gallmeister's POSIX.4 book */ |
| #endif |
#endif |
| if (debug) |
if (debug) |
| fprintf(stderr,"pagesize=%d\n",pagesize); |
fprintf(stderr,"pagesize=%d\n",pagesize); |
| |
|
| image = my_alloc(preamblesize+dictsize+image_offset)+image_offset; |
image = my_alloc(preamblesize+dictsize+data_offset)+data_offset; |
| rewind(imagefile); /* fseek(imagefile,0L,SEEK_SET); */ |
rewind(imagefile); /* fseek(imagefile,0L,SEEK_SET); */ |
| if (clear_dictionary) |
if (clear_dictionary) |
| memset(image,0,dictsize); |
memset(image,0,dictsize); |
| } |
} |
| |
|
| UCell convsize(char *s, UCell elemsize) |
UCell convsize(char *s, UCell elemsize) |
| /* converts s of the format #+u (e.g. 25k) into the number of bytes. |
/* converts s of the format [0-9]+[bekM]? (e.g. 25k) into the number |
| the unit u can be one of bekM, where e stands for the element |
of bytes. the letter at the end indicates the unit, where e stands |
| size. default is e */ |
for the element size. default is e */ |
| { |
{ |
| char *endp; |
char *endp; |
| UCell n,m; |
UCell n,m; |
| {"path", required_argument, NULL, 'p'}, |
{"path", required_argument, NULL, 'p'}, |
| {"version", no_argument, NULL, 'v'}, |
{"version", no_argument, NULL, 'v'}, |
| {"help", no_argument, NULL, 'h'}, |
{"help", no_argument, NULL, 'h'}, |
| {"clear-dictionary", no_argument, NULL, 'c'}, |
/* put something != 0 into offset_image */ |
| /* put something != 0 into image_offset; it should be a |
{"offset-image", no_argument, &offset_image, 1}, |
| not-too-large max-aligned number */ |
{"clear-dictionary", no_argument, &clear_dictionary, 1}, |
| {"offset-image", no_argument, NULL, 'o'}, |
|
| {"debug", no_argument, &debug, 1}, |
{"debug", no_argument, &debug, 1}, |
| {0,0,0,0} |
{0,0,0,0} |
| /* no-init-file, no-rc? */ |
/* no-init-file, no-rc? */ |
| }; |
}; |
| |
|
| c = getopt_long(argc, argv, "+i:m:d:r:f:l:p:vhco", opts, &option_index); |
c = getopt_long(argc, argv, "+i:m:d:r:f:l:p:vh", opts, &option_index); |
| |
|
| if (c==EOF) |
if (c==EOF) |
| break; |
break; |
| break; |
break; |
| } |
} |
| switch (c) { |
switch (c) { |
| case 'c': clear_dictionary=1; break; |
|
| case 'o': image_offset=28*sizeof(Cell); break; |
|
| case 'i': imagename = optarg; break; |
case 'i': imagename = optarg; break; |
| case 'm': dictsize = convsize(optarg,sizeof(Cell)); break; |
case 'm': dictsize = convsize(optarg,sizeof(Cell)); break; |
| case 'd': dsize = convsize(optarg,sizeof(Cell)); break; |
case 'd': dsize = convsize(optarg,sizeof(Cell)); break; |
| -p PATH, --path=PATH Search path for finding image and sources\n\ |
-p PATH, --path=PATH Search path for finding image and sources\n\ |
| -r SIZE, --return-stack-size=SIZE Specify return stack size\n\ |
-r SIZE, --return-stack-size=SIZE Specify return stack size\n\ |
| -v, --version Print version and exit\n\ |
-v, --version Print version and exit\n\ |
| SIZE arguments consists of an integer followed by a unit. The unit can be\n\ |
SIZE arguments consist of an integer followed by a unit. The unit can be\n\ |
| `b' (bytes), `e' (elements), `k' (kilobytes), or `M' (Megabytes).\n\ |
`b' (bytes), `e' (elements), `k' (kilobytes), or `M' (Megabytes).\n\ |
| \n\ |
\n\ |
| Arguments of default image `gforth.fi':\n\ |
Arguments of default image `gforth.fi':\n\ |
| fullfilename[dirlen++]='/'; |
fullfilename[dirlen++]='/'; |
| strcpy(fullfilename+dirlen,imagename); |
strcpy(fullfilename+dirlen,imagename); |
| image_file=fopen(fullfilename,"rb"); |
image_file=fopen(fullfilename,"rb"); |
| |
if (image_file!=NULL && debug) |
| |
fprintf(stderr, "Opened image file: %s\n", fullfilename); |
| } |
} |
| path=pend+(*pend==PATHSEP); |
path=pend+(*pend==PATHSEP); |
| } while (image_file==NULL); |
} while (image_file==NULL); |