Diff for /gforth/engine/engine.c between versions 1.47 and 1.50

version 1.47, 2002/12/15 17:38:52 version 1.50, 2002/12/19 23:12:07
Line 19 Line 19
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
 */  */
   
 undefine(`symbols')  
   
 #include "config.h"  #include "config.h"
 #include "forth.h"  #include "forth.h"
 #include <ctype.h>  #include <ctype.h>
Line 84  struct Longname { Line 82  struct Longname {
   
 #define LONGNAME_COUNT(np)      ((np)->countetc & (((~((UCell)0))<<3)>>3))  #define LONGNAME_COUNT(np)      ((np)->countetc & (((~((UCell)0))<<3)>>3))
   
 Cell *SP;  
 Float *FP;  
 Address UP=NULL;  
   
 #if 0  
 /* not used currently */  
 int emitcounter;  
 #endif  
 #define NULLC '\0'  #define NULLC '\0'
   
 #ifdef MEMCMP_AS_SUBROUTINE  #ifdef MEMCMP_AS_SUBROUTINE
Line 99  extern int gforth_memcmp(const char * s1 Line 89  extern int gforth_memcmp(const char * s1
 #define memcmp(s1,s2,n) gforth_memcmp(s1,s2,n)  #define memcmp(s1,s2,n) gforth_memcmp(s1,s2,n)
 #endif  #endif
   
 #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 */  
 {  
   static struct cstr_buffer {  
     char *buffer;  
     size_t size;  
   } *buffers=NULL;  
   static int nbuffers=0;  
   static int used=0;  
   struct cstr_buffer *b;  
   
   if (buffers==NULL)  
     buffers=malloc(0);  
   if (clear)  
     used=0;  
   if (used>=nbuffers) {  
     buffers=realloc(buffers,sizeof(struct cstr_buffer)*(used+1));  
     buffers[used]=(struct cstr_buffer){malloc(0),0};  
     nbuffers=used+1;  
   }  
   b=&buffers[used];  
   if (size+1 > b->size) {  
     b->buffer = realloc(b->buffer,size+1);  
     b->size = size+1;  
   }  
   memcpy(b->buffer,from,size);  
   b->buffer[size]='\0';  
   used++;  
   return b->buffer;  
 }  
   
 char *tilde_cstr(Char *from, UCell size, int clear)  
 /* like cstr(), but perform tilde expansion on the string */  
 {  
   char *s1,*s2;  
   int s1_len, s2_len;  
   struct passwd *getpwnam (), *user_entry;  
   
   if (size<1 || from[0]!='~')  
     return cstr(from, size, clear);  
   if (size<2 || from[1]=='/') {  
     s1 = (char *)getenv ("HOME");  
     if(s1 == NULL)  
       s1 = "";  
     s2 = from+1;  
     s2_len = size-1;  
   } else {  
     UCell i;  
     for (i=1; i<size && from[i]!='/'; i++)  
       ;  
     if (i==2 && from[1]=='+') /* deal with "~+", i.e., the wd */  
       return cstr(from+3, size<3?0:size-3,clear);  
     {  
       char user[i];  
       memcpy(user,from+1,i-1);  
       user[i-1]='\0';  
       user_entry=getpwnam(user);  
     }  
     if (user_entry==NULL)  
       return cstr(from, size, clear);  
     s1 = user_entry->pw_dir;  
     s2 = from+i;  
     s2_len = size-i;  
   }  
   s1_len = strlen(s1);  
   if (s1_len>1 && s1[s1_len-1]=='/')  
     s1_len--;  
   {  
     char path[s1_len+s2_len];  
     memcpy(path,s1,s1_len);  
     memcpy(path+s1_len,s2,s2_len);  
     return cstr(path,s1_len+s2_len,clear);  
   }  
 }  
 #endif  
   
 DCell timeval2us(struct timeval *tvp)  
 {  
 #ifndef BUGGY_LONG_LONG  
   return (tvp->tv_sec*(DCell)1000000)+tvp->tv_usec;  
 #else  
   DCell d2;  
   DCell d1=mmul(tvp->tv_sec,1000000);  
   d2.lo = d1.lo+tvp->tv_usec;  
   d2.hi = d1.hi + (d2.lo<d1.lo);  
   return d2;  
 #endif  
 }  
   
 #define NEWLINE '\n'  #define NEWLINE '\n'
   
 #ifdef HAS_FILE  
 static char* fileattr[6]={"rb","rb","r+b","r+b","wb","wb"};  
 static char* pfileattr[6]={"r","r","r+","r+","w","w"};  
   
 #ifndef O_BINARY  
 #define O_BINARY 0  
 #endif  
 #ifndef O_TEXT  
 #define O_TEXT 0  
 #endif  
   
 static int ufileattr[6]= {  
   O_RDONLY|O_BINARY, O_RDONLY|O_BINARY,  
   O_RDWR  |O_BINARY, O_RDWR  |O_BINARY,  
   O_WRONLY|O_BINARY, O_WRONLY|O_BINARY };  
 #endif  
   
 /* conversion on fetch */  /* conversion on fetch */
   
 #define vm_Cell2f(_cell,_x)             ((_x)=(Bool)(_cell))  #define vm_Cell2f(_cell,_x)             ((_x)=(Bool)(_cell))
Line 298  static int ufileattr[6]= { Line 180  static int ufileattr[6]= {
 #endif  #endif
 #define SUPER_CONTINUE  #define SUPER_CONTINUE
   
 #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 *saved_ip;  
 Cell *rp;  
 #endif  
   
 #ifdef NO_IP  
 static Label next_code;  
 #endif  
   
 #ifdef DEBUG  #ifdef DEBUG
 #define CFA_TO_NAME(__cfa) \  #define CFA_TO_NAME(__cfa) \
       Cell len, i; \        Cell len, i; \
Line 324  static Label next_code; Line 194  static Label next_code;
       }        }
 #endif  #endif
   
 Xt *primtable(Label symbols[], Cell size)  #if !defined(ENGINE)
      /* used in primitive primtable for peephole optimization */  /* normal engine */
 {  #define VARIANT(v)      (v)
   Xt *xts = (Xt *)malloc(size*sizeof(Xt));  #define JUMP(target)    goto I_noop
   Cell i;  #define LABEL(name) I_##name:
   
   #elif ENGINE==2
   /* variant with padding between VM instructions for finding out
      cross-inst jumps (for dynamic code) */
   #define engine engine2
   #define VARIANT(v)      (v)
   #define JUMP(target)    goto I_noop
   #define LABEL(name) J_##name: asm(".skip 16"); I_##name:
   #define IN_ENGINE2
   
   #elif ENGINE==3
   /* variant with different immediate arguments for finding out
      immediate arguments (for native code) */
   #define engine engine3
   #define VARIANT(v)      ((v)^0xffffffff)
   #define JUMP(target)    goto K_lit
   #define LABEL(name) I_##name:
   #else
   #error illegal ENGINE value
   #endif /* ENGINE */
   
   #define LABEL2(name) K_##name:
   
   for (i=0; i<size; i++)  
     xts[i] = &symbols[i];  
   return xts;  
 }  
   
 define(enginerest,  Label *engine(Xt *ip0, Cell *sp0, Cell *rp0, Float *fp0, Address lp0)
 `(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
 */  */
Line 598  define(enginerest, Line 485  define(enginerest,
   NEXT;    NEXT;
 #endif  #endif
   
 #ifndef IN_ENGINE2  
 #define LABEL(name) I_##name:  
 #else  
 #define LABEL(name) J_##name: asm(".skip 16"); I_##name:  
 #endif  
 #define LABEL2(name) K_##name:  
 #include "prim.i"  #include "prim.i"
 #undef LABEL  
   after_last: return (Label *)0;    after_last: return (Label *)0;
   /*needed only to get the length of the last primitive */    /*needed only to get the length of the last primitive */
 }'  }
 )  
   
 #define VARIANT(v)      (v)  
 #define JUMP(target)    goto I_noop  
   
 Label *engine enginerest  
   
 #ifndef NO_DYNAMIC  
   
 #ifdef NO_IP  
 #undef VARIANT  
 #define VARIANT(v)      ((v)^0xffffffff)  
 #undef JUMP  
 #define JUMP(target)    goto K_lit  
 Label *engine3 enginerest  
 #endif  
   
 #undef VARIANT  
 #define VARIANT(v)      (v)  
 #undef JUMP  
 #define JUMP(target)    goto I_noop  
 #define IN_ENGINE2  
 Label *engine2 enginerest  
 #endif  

Removed from v.1.47  
changed lines
  Added in v.1.50


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