--- gforth/engine/engine.c 1998/11/08 23:08:05 1.5 +++ gforth/engine/engine.c 1999/02/06 22:28:24 1.11 @@ -1,6 +1,6 @@ /* Gforth virtual machine (aka inner interpreter) - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc. This file is part of Gforth. @@ -45,6 +45,9 @@ #if defined(HAVE_LIBDL) || defined(HAVE_DLOPEN) /* what else? */ #include #endif +#if defined(_WIN32) +#include +#endif #ifdef hpux #include #endif @@ -77,6 +80,7 @@ int emitcounter; #endif #define NULLC '\0' +#ifdef HAS_FILE char *cstr(Char *from, UCell size, int clear) /* return a C-string corresponding to the Forth string ( FROM SIZE ). the C-string lives until the next call of cstr with CLEAR being true */ @@ -109,12 +113,6 @@ char *cstr(Char *from, UCell size, int c return b->buffer; } -#ifdef STANDALONE -char *tilde_cstr(Char *from, UCell size, int clear) -{ - return cstr(from, size, clear); -} -#else char *tilde_cstr(Char *from, UCell size, int clear) /* like cstr(), but perform tilde expansion on the string */ { @@ -156,7 +154,7 @@ char *tilde_cstr(Char *from, UCell size, return cstr(path,s1_len+s2_len,clear); } } -#endif +#endif #define NEWLINE '\n' @@ -164,6 +162,7 @@ char *tilde_cstr(Char *from, UCell size, #define rint(x) floor((x)+0.5) #endif +#ifdef HAS_FILE static char* fileattr[6]={"r","rb","r+","r+b","w","wb"}; #ifndef O_BINARY @@ -177,6 +176,7 @@ static int ufileattr[6]= { O_RDONLY|O_TEXT, O_RDONLY|O_BINARY, O_RDWR |O_TEXT, O_RDWR |O_BINARY, O_WRONLY|O_TEXT, O_WRONLY|O_BINARY }; +#endif /* if machine.h has not defined explicit registers, define them as implicit */ #ifndef IPREG @@ -219,19 +219,32 @@ static int ufileattr[6]= { #define DOCFA Xt cfa; GETCFA(cfa) #endif +#ifdef GFORTH_DEBUGGING +/* define some VM registers as global variables, so they survive exceptions; + global register variables are not up to the task (according to the + GNU C manual) */ +Xt *ip; +Cell *rp; +#endif + Label *engine(Xt *ip0, Cell *sp0, Cell *rp0, Float *fp0, Address lp0) /* executes code at ip, if ip!=NULL returns array of machine code labels (for use in a loader), if ip==NULL */ { - register Xt *ip IPREG = ip0; +#ifndef GFORTH_DEBUGGING + register Xt *ip IPREG; + register Cell *rp RPREG; +#endif register Cell *sp SPREG = sp0; - register Cell *rp RPREG = rp0; register Float *fp FPREG = fp0; register Address lp LPREG = lp0; #ifdef CFA_NEXT register Xt cfa CFAREG; #endif +#ifdef MORE_VARS + MORE_VARS +#endif register Address up UPREG = UP; IF_TOS(register Cell TOS TOSREG;) IF_FTOS(register Float FTOS FTOSREG;) @@ -250,7 +263,7 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * (Label)&&dodoes, /* the following entry is normally unused; it's there because its index indicates a does-handler */ - (Label)CPU_DEP1, + CPU_DEP1, #include "prim_lab.i" (Label)0 }; @@ -258,6 +271,8 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * CPU_DEP2 #endif + ip = ip0; + rp = rp0; #ifdef DEBUG fprintf(stderr,"ip=%x, sp=%x, rp=%x, fp=%x, lp=%x, up=%x\n", (unsigned)ip,(unsigned)sp,(unsigned)rp, @@ -270,27 +285,28 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * #define CODE_OFFSET (22*sizeof(Cell)) int i; Cell code_offset = offset_image? CODE_OFFSET : 0; - + symbols = (Label *)(malloc(MAX_SYMBOLS*sizeof(Cell)+CODE_OFFSET)+code_offset); for (i=0; i=MAX_SYMBOLS) { fprintf(stderr,"gforth-ditc: more than %d primitives\n",MAX_SYMBOLS); exit(1); - } - symbols[i] = &routines[i]; } -#endif /* defined(DOUBLY_INDIRECT) */ - return symbols; + symbols[i] = &routines[i]; } +#endif /* defined(DOUBLY_INDIRECT) */ + return symbols; +} IF_TOS(TOS = sp[0]); IF_FTOS(FTOS = fp[0]); - /* prep_terminal(); */ - NEXT_P0; +/* prep_terminal(); */ + SET_IP(ip); NEXT; + #ifdef CPU_DEP3 CPU_DEP3 #endif @@ -304,22 +320,17 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * #ifdef CISC_NEXT /* this is the simple version */ *--rp = (Cell)ip; - ip = (Xt *)PFA1(cfa); - NEXT_P0; + SET_IP((Xt *)PFA1(cfa)); NEXT; #else - /* this one is important, so we help the compiler optimizing - The following version may be better (for scheduling), but probably has - problems with code fields employing calls and delay slots - */ + /* this one is important, so we help the compiler optimizing */ { DEF_CA - Xt *current_ip = (Xt *)PFA1(cfa); - cfa = *current_ip; - NEXT1_P1; - *--rp = (Cell)ip; - ip = current_ip+1; - NEXT1_P2; + rp[-1] = (Cell)ip; + SET_IP((Xt *)PFA1(cfa)); + NEXT_P1; + rp--; + NEXT_P2; } #endif } @@ -387,7 +398,7 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * #ifdef DEBUG fprintf(stderr,"%08lx: field: %08lx\n",(Cell)ip,(Cell)PFA1(cfa)); #endif - TOS += *(Cell*)PFA1(cfa); + TOS += *(Cell*)PFA1(cfa); } NEXT_P0; NEXT; @@ -420,16 +431,15 @@ Label *engine(Xt *ip0, Cell *sp0, Cell * #endif *--rp = (Cell)ip; /* PFA1 might collide with DOES_CODE1 here, so we use PFA */ - ip = DOES_CODE1(cfa); #ifdef USE_TOS *sp-- = TOS; TOS = (Cell)PFA(cfa); #else *--sp = (Cell)PFA(cfa); #endif + SET_IP(DOES_CODE1(cfa)); /* fprintf(stderr,"TOS = %08lx, IP=%08lx\n", TOS, IP);*/ } - NEXT_P0; NEXT; #include "prim.i"