| void ** clist; |
void ** clist; |
| void * ritem; |
void * ritem; |
| |
|
| void gforth_callback(ffi_cif * cif, void * resp, void ** args, Xt * ip) |
void gforth_callback(ffi_cif * cif, void * resp, void ** args, void * ip) |
| { |
{ |
| Cell *rp = gforth_RP; |
Cell *rp = gforth_RP; |
| Cell *sp = gforth_SP; |
Cell *sp = gforth_SP; |
| clist = args; |
clist = args; |
| ritem = resp; |
ritem = resp; |
| |
|
| engine(ip, sp, rp, fp, lp); |
engine((Xt *)ip, sp, rp, fp, lp); |
| |
|
| /* restore global variables */ |
/* restore global variables */ |
| gforth_RP = rp; |
gforth_RP = rp; |
| return result; |
return result; |
| } |
} |
| |
|
| void gforth_relocate(Cell *image, const unsigned char *bitstring, |
void gforth_relocate(Cell *image, const Char *bitstring, |
| int size, Cell base, Label symbols[]) |
UCell size, Cell base, Label symbols[]) |
| { |
{ |
| int i=0, j, k, steps=(((size-1)/sizeof(Cell))/RELINFOBITS)+1; |
int i=0, j, k, steps=(((size-1)/sizeof(Cell))/RELINFOBITS)+1; |
| Cell token; |
Cell token; |
| ((ImageHeader*)(image))->base = (Address) image; |
((ImageHeader*)(image))->base = (Address) image; |
| } |
} |
| |
|
| |
#ifndef DOUBLY_INDIRECT |
| static UCell checksum(Label symbols[]) |
static UCell checksum(Label symbols[]) |
| { |
{ |
| UCell r=PRIM_VERSION; |
UCell r=PRIM_VERSION; |
| #endif |
#endif |
| return r; |
return r; |
| } |
} |
| |
#endif |
| |
|
| static Address verbose_malloc(Cell size) |
static Address verbose_malloc(Cell size) |
| { |
{ |
| Label goto_start; |
Label goto_start; |
| Cell goto_len; |
Cell goto_len; |
| |
|
| |
#ifndef NO_DYNAMIC |
| static int compare_labels(const void *pa, const void *pb) |
static int compare_labels(const void *pa, const void *pb) |
| { |
{ |
| Label a = *(Label *)pa; |
Label a = *(Label *)pa; |
| Label b = *(Label *)pb; |
Label b = *(Label *)pb; |
| return a-b; |
return a-b; |
| } |
} |
| |
#endif |
| |
|
| static Label bsearch_next(Label key, Label *a, UCell n) |
static Label bsearch_next(Label key, Label *a, UCell n) |
| /* a is sorted; return the label >=key that is the closest in a; |
/* a is sorted; return the label >=key that is the closest in a; |
| flush_to_here(); |
flush_to_here(); |
| } |
} |
| |
|
| |
#if !(defined(DOUBLY_INDIRECT) || defined(INDIRECT_THREADED)) |
| #ifdef NO_IP |
#ifdef NO_IP |
| static Cell compile_prim_dyn(PrimNum p, Cell *tcp) |
static Cell compile_prim_dyn(PrimNum p, Cell *tcp) |
| /* compile prim #p dynamically (mod flags etc.) and return start |
/* compile prim #p dynamically (mod flags etc.) and return start |
| #endif /* !defined(NO_DYNAMIC) */ |
#endif /* !defined(NO_DYNAMIC) */ |
| } |
} |
| #endif /* !defined(NO_IP) */ |
#endif /* !defined(NO_IP) */ |
| |
#endif |
| |
|
| #ifndef NO_DYNAMIC |
#ifndef NO_DYNAMIC |
| static int cost_codesize(int prim) |
static int cost_codesize(int prim) |
| long lb_applicable_base_rules = 0; |
long lb_applicable_base_rules = 0; |
| long lb_applicable_chain_rules = 0; |
long lb_applicable_chain_rules = 0; |
| |
|
| |
#if !(defined(DOUBLY_INDIRECT) || defined(INDIRECT_THREADED)) |
| static void init_waypoints(struct waypoint ws[]) |
static void init_waypoints(struct waypoint ws[]) |
| { |
{ |
| int k; |
int k; |
| transitions(s); |
transitions(s); |
| return s; |
return s; |
| } |
} |
| |
#endif |
| |
|
| #define TPA_SIZE 16384 |
#define TPA_SIZE 16384 |
| |
|
| struct tpa_state *state_infront; /* note: brack-to-front labeling */ |
struct tpa_state *state_infront; /* note: brack-to-front labeling */ |
| } *tpa_table[TPA_SIZE]; |
} *tpa_table[TPA_SIZE]; |
| |
|
| |
#if !(defined(DOUBLY_INDIRECT) || defined(INDIRECT_THREADED)) |
| static Cell hash_tpa(PrimNum p, struct tpa_state *t) |
static Cell hash_tpa(PrimNum p, struct tpa_state *t) |
| { |
{ |
| UCell it = (UCell )t; |
UCell it = (UCell )t; |
| return (memcmp(t1->inst, t2->inst, maxstates*sizeof(struct waypoint)) == 0 && |
return (memcmp(t1->inst, t2->inst, maxstates*sizeof(struct waypoint)) == 0 && |
| memcmp(t1->trans,t2->trans,maxstates*sizeof(struct waypoint)) == 0); |
memcmp(t1->trans,t2->trans,maxstates*sizeof(struct waypoint)) == 0); |
| } |
} |
| |
#endif |
| |
|
| struct tpa_state_entry { |
struct tpa_state_entry { |
| struct tpa_state_entry *next; |
struct tpa_state_entry *next; |
| return (r+(r>>14)+(r>>22)) & (TPA_SIZE-1); |
return (r+(r>>14)+(r>>22)) & (TPA_SIZE-1); |
| } |
} |
| |
|
| |
#if !(defined(DOUBLY_INDIRECT) || defined(INDIRECT_THREADED)) |
| static struct tpa_state *lookup_tpa_state(struct tpa_state *t) |
static struct tpa_state *lookup_tpa_state(struct tpa_state *t) |
| { |
{ |
| Cell hash = hash_tpa_state(t); |
Cell hash = hash_tpa_state(t); |
| } |
} |
| assert(nextstate==CANONICAL_STATE); |
assert(nextstate==CANONICAL_STATE); |
| } |
} |
| |
#endif |
| |
|
| /* compile *start, possibly rewriting it into a static and/or dynamic |
/* compile *start, possibly rewriting it into a static and/or dynamic |
| superinstruction */ |
superinstruction */ |
| memset(imp+header.image_size, 0, dictsize-header.image_size); |
memset(imp+header.image_size, 0, dictsize-header.image_size); |
| if(header.base==0 || header.base == (Address)0x100) { |
if(header.base==0 || header.base == (Address)0x100) { |
| Cell reloc_size=((header.image_size-1)/sizeof(Cell))/8+1; |
Cell reloc_size=((header.image_size-1)/sizeof(Cell))/8+1; |
| char reloc_bits[reloc_size]; |
Char reloc_bits[reloc_size]; |
| fseek(imagefile, preamblesize+header.image_size, SEEK_SET); |
fseek(imagefile, preamblesize+header.image_size, SEEK_SET); |
| fread(reloc_bits, 1, reloc_size, imagefile); |
fread(reloc_bits, 1, reloc_size, imagefile); |
| gforth_relocate((Cell *)imp, reloc_bits, header.image_size, (Cell)header.base, vm_prims); |
gforth_relocate((Cell *)imp, reloc_bits, header.image_size, (Cell)header.base, vm_prims); |
| static FILE *openimage(char *fullfilename) |
static FILE *openimage(char *fullfilename) |
| { |
{ |
| FILE *image_file; |
FILE *image_file; |
| char * expfilename = tilde_cstr(fullfilename, strlen(fullfilename), 1); |
char * expfilename = tilde_cstr((Char *)fullfilename, strlen(fullfilename), 1); |
| |
|
| image_file=fopen(expfilename,"rb"); |
image_file=fopen(expfilename,"rb"); |
| if (image_file!=NULL && debug) |
if (image_file!=NULL && debug) |
| static FILE *checkimage(char *path, int len, char *imagename) |
static FILE *checkimage(char *path, int len, char *imagename) |
| { |
{ |
| int dirlen=len; |
int dirlen=len; |
| char fullfilename[dirlen+strlen(imagename)+2]; |
char fullfilename[dirlen+strlen((char *)imagename)+2]; |
| |
|
| memcpy(fullfilename, path, dirlen); |
memcpy(fullfilename, path, dirlen); |
| if (fullfilename[dirlen-1]!=DIRSEP) |
if (fullfilename[dirlen-1]!=DIRSEP) |