| #if defined(HAVE_LIBDL) || defined(HAVE_DLOPEN) /* what else? */ |
#if defined(HAVE_LIBDL) || defined(HAVE_DLOPEN) /* what else? */ |
| #include <dlfcn.h> |
#include <dlfcn.h> |
| #endif |
#endif |
| |
#if defined(_WIN32) |
| |
#include <windows.h> |
| |
#endif |
| #ifdef hpux |
#ifdef hpux |
| #include <dl.h> |
#include <dl.h> |
| #endif |
#endif |
| #endif |
#endif |
| #define NULLC '\0' |
#define NULLC '\0' |
| |
|
| |
#ifdef HAS_FILE |
| char *cstr(Char *from, UCell size, int clear) |
char *cstr(Char *from, UCell size, int clear) |
| /* return a C-string corresponding to the Forth string ( FROM SIZE ). |
/* 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 */ |
the C-string lives until the next call of cstr with CLEAR being true */ |
| return b->buffer; |
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) |
char *tilde_cstr(Char *from, UCell size, int clear) |
| /* like cstr(), but perform tilde expansion on the string */ |
/* like cstr(), but perform tilde expansion on the string */ |
| { |
{ |
| #define rint(x) floor((x)+0.5) |
#define rint(x) floor((x)+0.5) |
| #endif |
#endif |
| |
|
| |
#ifdef HAS_FILE |
| static char* fileattr[6]={"r","rb","r+","r+b","w","wb"}; |
static char* fileattr[6]={"r","rb","r+","r+b","w","wb"}; |
| |
|
| #ifndef O_BINARY |
#ifndef O_BINARY |
| O_RDONLY|O_TEXT, O_RDONLY|O_BINARY, |
O_RDONLY|O_TEXT, O_RDONLY|O_BINARY, |
| O_RDWR |O_TEXT, O_RDWR |O_BINARY, |
O_RDWR |O_TEXT, O_RDWR |O_BINARY, |
| O_WRONLY|O_TEXT, O_WRONLY|O_BINARY }; |
O_WRONLY|O_TEXT, O_WRONLY|O_BINARY }; |
| |
#endif |
| |
|
| /* if machine.h has not defined explicit registers, define them as implicit */ |
/* if machine.h has not defined explicit registers, define them as implicit */ |
| #ifndef IPREG |
#ifndef IPREG |
| #define DOCFA Xt cfa; GETCFA(cfa) |
#define DOCFA Xt cfa; GETCFA(cfa) |
| #endif |
#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) |
Label *engine(Xt *ip0, Cell *sp0, Cell *rp0, Float *fp0, Address lp0) |
| /* executes code at ip, if ip!=NULL |
/* executes code at ip, if ip!=NULL |
| returns array of machine code labels (for use in a loader), 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 *sp SPREG = sp0; |
| register Cell *rp RPREG = rp0; |
|
| register Float *fp FPREG = fp0; |
register Float *fp FPREG = fp0; |
| register Address lp LPREG = lp0; |
register Address lp LPREG = lp0; |
| #ifdef CFA_NEXT |
#ifdef CFA_NEXT |
| register Xt cfa CFAREG; |
register Xt cfa CFAREG; |
| #endif |
#endif |
| |
#ifdef MORE_VARS |
| |
MORE_VARS |
| |
#endif |
| register Address up UPREG = UP; |
register Address up UPREG = UP; |
| IF_TOS(register Cell TOS TOSREG;) |
IF_TOS(register Cell TOS TOSREG;) |
| IF_FTOS(register Float FTOS FTOSREG;) |
IF_FTOS(register Float FTOS FTOSREG;) |
| (Label)&&dodoes, |
(Label)&&dodoes, |
| /* the following entry is normally unused; |
/* the following entry is normally unused; |
| it's there because its index indicates a does-handler */ |
it's there because its index indicates a does-handler */ |
| (Label)CPU_DEP1, |
CPU_DEP1, |
| #include "prim_lab.i" |
#include "prim_lab.i" |
| (Label)0 |
(Label)0 |
| }; |
}; |
| CPU_DEP2 |
CPU_DEP2 |
| #endif |
#endif |
| |
|
| |
ip = ip0; |
| |
rp = rp0; |
| #ifdef DEBUG |
#ifdef DEBUG |
| fprintf(stderr,"ip=%x, sp=%x, rp=%x, fp=%x, lp=%x, up=%x\n", |
fprintf(stderr,"ip=%x, sp=%x, rp=%x, fp=%x, lp=%x, up=%x\n", |
| (unsigned)ip,(unsigned)sp,(unsigned)rp, |
(unsigned)ip,(unsigned)sp,(unsigned)rp, |
| |
|
| symbols = (Label *)(malloc(MAX_SYMBOLS*sizeof(Cell)+CODE_OFFSET)+code_offset); |
symbols = (Label *)(malloc(MAX_SYMBOLS*sizeof(Cell)+CODE_OFFSET)+code_offset); |
| for (i=0; i<DOESJUMP+1; i++) |
for (i=0; i<DOESJUMP+1; i++) |
| symbols[i] = routines[i]; |
symbols[i] = (Label)routines[i]; |
| for (; routines[i]!=0; i++) { |
for (; routines[i]!=0; i++) { |
| if (i>=MAX_SYMBOLS) { |
if (i>=MAX_SYMBOLS) { |
| fprintf(stderr,"gforth-ditc: more than %d primitives\n",MAX_SYMBOLS); |
fprintf(stderr,"gforth-ditc: more than %d primitives\n",MAX_SYMBOLS); |
| IF_TOS(TOS = sp[0]); |
IF_TOS(TOS = sp[0]); |
| IF_FTOS(FTOS = fp[0]); |
IF_FTOS(FTOS = fp[0]); |
| /* prep_terminal(); */ |
/* prep_terminal(); */ |
| NEXT_P0; |
SET_IP(ip); |
| NEXT; |
NEXT; |
| |
|
| |
|
| #ifdef CPU_DEP3 |
#ifdef CPU_DEP3 |
| CPU_DEP3 |
CPU_DEP3 |
| #endif |
#endif |
| #ifdef CISC_NEXT |
#ifdef CISC_NEXT |
| /* this is the simple version */ |
/* this is the simple version */ |
| *--rp = (Cell)ip; |
*--rp = (Cell)ip; |
| ip = (Xt *)PFA1(cfa); |
SET_IP((Xt *)PFA1(cfa)); |
| NEXT_P0; |
|
| NEXT; |
NEXT; |
| #else |
#else |
| /* this one is important, so we help the compiler optimizing |
/* 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 |
|
| */ |
|
| { |
{ |
| DEF_CA |
DEF_CA |
| Xt *current_ip = (Xt *)PFA1(cfa); |
rp[-1] = (Cell)ip; |
| cfa = *current_ip; |
SET_IP((Xt *)PFA1(cfa)); |
| NEXT1_P1; |
NEXT_P1; |
| *--rp = (Cell)ip; |
rp--; |
| ip = current_ip+1; |
NEXT_P2; |
| NEXT1_P2; |
|
| } |
} |
| #endif |
#endif |
| } |
} |
| #endif |
#endif |
| *--rp = (Cell)ip; |
*--rp = (Cell)ip; |
| /* PFA1 might collide with DOES_CODE1 here, so we use PFA */ |
/* PFA1 might collide with DOES_CODE1 here, so we use PFA */ |
| ip = DOES_CODE1(cfa); |
|
| #ifdef USE_TOS |
#ifdef USE_TOS |
| *sp-- = TOS; |
*sp-- = TOS; |
| TOS = (Cell)PFA(cfa); |
TOS = (Cell)PFA(cfa); |
| #else |
#else |
| *--sp = (Cell)PFA(cfa); |
*--sp = (Cell)PFA(cfa); |
| #endif |
#endif |
| |
SET_IP(DOES_CODE1(cfa)); |
| /* fprintf(stderr,"TOS = %08lx, IP=%08lx\n", TOS, IP);*/ |
/* fprintf(stderr,"TOS = %08lx, IP=%08lx\n", TOS, IP);*/ |
| } |
} |
| NEXT_P0; |
|
| NEXT; |
NEXT; |
| |
|
| #include "prim.i" |
#include "prim.i" |