Diff for /gforth/Attic/engine.c between versions 1.14 and 1.31

version 1.14, 1994/09/08 17:20:05 version 1.31, 1995/11/07 18:06:37
Line 1 Line 1
 /*  /* Gforth virtual machine (aka inner interpreter)
   $Id$  
   Copyright 1992 by the ANSI figForth Development Group    Copyright (C) 1995 Free Software Foundation, Inc.
   
     This file is part of Gforth.
   
     Gforth is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License
     as published by the Free Software Foundation; either version 2
     of the License, or (at your option) any later version.
   
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
   
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */  */
   
 #include <ctype.h>  #include <ctype.h>
Line 14 Line 30
 #include <stdlib.h>  #include <stdlib.h>
 #include <time.h>  #include <time.h>
 #include <sys/time.h>  #include <sys/time.h>
   #include <unistd.h>
   #include <errno.h>
   #include <pwd.h>
 #include "forth.h"  #include "forth.h"
 #include "io.h"  #include "io.h"
   #include "threading.h"
   
   #ifndef SEEK_SET
   /* should be defined in stdio.h, but some systems don't have it */
   #define SEEK_SET 0
   #endif
   
   #define IOR(flag)       ((flag)? -512-errno : 0)
   
 typedef union {  typedef union {
   struct {    struct {
 #ifdef BIG_ENDIAN  #ifdef WORDS_BIGENDIAN
     Cell high;      Cell high;
     Cell low;      Cell low;
 #else  #else
Line 41  typedef struct F83Name { Line 68  typedef struct F83Name {
 #define F83NAME_SMUDGE(np)      (((np)->countetc & 0x40) != 0)  #define F83NAME_SMUDGE(np)      (((np)->countetc & 0x40) != 0)
 #define F83NAME_IMMEDIATE(np)   (((np)->countetc & 0x20) != 0)  #define F83NAME_IMMEDIATE(np)   (((np)->countetc & 0x20) != 0)
   
 /* NEXT and NEXT1 are split into several parts to help scheduling,  
    unless CISC_NEXT is defined */  
 #ifdef CISC_NEXT  
 #define NEXT1_P1  
 #define NEXT_P1  
 #define DEF_CA  
 #ifdef DIRECT_THREADED  
 #define NEXT1_P2 ({goto *cfa;})  
 #else  
 #define NEXT1_P2 ({goto **cfa;})  
 #endif /* DIRECT_THREADED */  
 #define NEXT_P2 ({cfa = *ip++; NEXT1_P2;})  
 #else /* CISC_NEXT */  
 #ifdef DIRECT_THREADED  
 #define NEXT1_P1  
 #define NEXT1_P2 ({goto *cfa;})  
 #define DEF_CA  
 #else /* DIRECT_THREADED */  
 #define NEXT1_P1 ({ca = *cfa;})  
 #define NEXT1_P2 ({goto *ca;})  
 #define DEF_CA  Label ca;  
 #endif /* DIRECT_THREADED */  
 #define NEXT_P1 ({cfa=*ip++; NEXT1_P1;})  
 #define NEXT_P2 NEXT1_P2  
 #endif /* CISC_NEXT */  
   
 #define NEXT1 ({DEF_CA NEXT1_P1; NEXT1_P2;})  
 #define NEXT ({DEF_CA NEXT_P1; NEXT_P2;})  
   
 #ifdef USE_TOS  #ifdef USE_TOS
 #define IF_TOS(x) x  #define IF_TOS(x) x
 #else  #else
Line 84  typedef struct F83Name { Line 82  typedef struct F83Name {
 #define FTOS (fp[0])  #define FTOS (fp[0])
 #endif  #endif
   
   Cell *SP;
   Float *FP;
 int emitcounter;  int emitcounter;
 #define NULLC '\0'  #define NULLC '\0'
   
Line 116  char *cstr(Char *from, UCell size, int c Line 116  char *cstr(Char *from, UCell size, int c
   return oldnextscratch;    return oldnextscratch;
 }  }
   
   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");
       s2 = from+1;
       s2_len = size-1;
     } else {
       int i;
       for (i=1; i<size && from[i]!='/'; i++)
         ;
       {
         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);
     }
   }
      
   
 #define NEWLINE '\n'  #define NEWLINE '\n'
   
   #ifndef HAVE_RINT
   #define rint(x) floor((x)+0.5)
   #endif
   
 static char* fileattr[6]={"r","rb","r+","r+b","w+","w+b"};  static char* fileattr[6]={"r","rb","r+","r+b","w","wb"};
   
 static Address up0=NULL;  static Address up0=NULL;
   
 #if defined(i386) && defined(FORCE_REG)  /* if machine.h has not defined explicit registers, define them as implicit */
 #  define REG(reg) __asm__(reg)  #ifndef IPREG
   #define IPREG
 Label *engine(Xt *ip0, Cell *sp0, Cell *rp, Float *fp, Address lp)  #endif
 {  #ifndef SPREG
    register Xt *ip REG("%esi")=ip0;  #define SPREG
    register Cell *sp REG("%edi")=sp0;  #endif
   #ifndef RPREG
 #else  #define RPREG
 #  define REG(reg)  #endif
   #ifndef FPREG
 Label *engine(Xt *ip, Cell *sp, Cell *rp, Float *fp, Address lp)  #define FPREG
 {  #endif
   #ifndef LPREG
   #define LPREG
   #endif
   #ifndef CFAREG
   #define CFAREG
   #endif
   #ifndef UPREG
   #define UPREG
 #endif  #endif
   #ifndef TOSREG
   #define TOSREG
   #endif
   #ifndef FTOSREG
   #define FTOSREG
   #endif
   
   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 cfa  {
 #ifdef i386    register Xt *ip IPREG = ip0;
 #  ifdef USE_TOS    register Cell *sp SPREG = sp0;
    REG("%ecx")    register Cell *rp RPREG = rp0;
 #  else    register Float *fp FPREG = fp0;
    REG("%edx")    register Address lp LPREG = lp0;
 #  endif  #ifdef CFA_NEXT
 #endif    register Xt cfa CFAREG;
    ;  #endif
   Address up=up0;    register Address up UPREG = up0;
     IF_TOS(register Cell TOS TOSREG;)
     IF_FTOS(register Float FTOS FTOSREG;)
   static Label symbols[]= {    static Label symbols[]= {
     &&docol,      &&docol,
     &&docon,      &&docon,
     &&dovar,      &&dovar,
     &&douser,      &&douser,
     &&dodefer,      &&dodefer,
       &&dofield,
     &&dodoes,      &&dodoes,
     &&dodoes,  /* dummy for does handler address */      &&dodoes,  /* dummy for does handler address */
 #include "prim_labels.i"  #include "prim_labels.i"
   };    };
   IF_TOS(register Cell TOS;)  
   IF_FTOS(Float FTOS;)  
 #ifdef CPU_DEP  #ifdef CPU_DEP
   CPU_DEP;    CPU_DEP;
 #endif  #endif
   
   #ifdef DEBUG
     fprintf(stderr,"ip=%x, sp=%x, rp=%x, fp=%x, lp=%x, up=%x\n",
             (unsigned)ip,(unsigned)sp,(unsigned)rp,
             (unsigned)fp,(unsigned)lp,(unsigned)up);
   #endif
   
   if (ip == NULL)    if (ip == NULL)
     return symbols;      return 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;
   NEXT;    NEXT;
       
  docol:   docol:
   #ifndef CFA_NEXT
     {
       Xt cfa; GETCFA(cfa);
   #endif
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x: col: %08x\n",(Cell)ip,(Cell)PFA1(cfa));    fprintf(stderr,"%08lx: col: %08lx\n",(Cell)ip,(Cell)PFA1(cfa));
 #endif  #endif
 #ifdef i386  #ifdef CISC_NEXT
   /* this is the simple version */    /* this is the simple version */
   *--rp = (Cell)ip;    *--rp = (Cell)ip;
   ip = (Xt *)PFA1(cfa);    ip = (Xt *)PFA1(cfa);
     NEXT_P0;
   NEXT;    NEXT;
 #endif  #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       The following version may be better (for scheduling), but probably has
      problems with code fields employing calls and delay slots       problems with code fields employing calls and delay slots
Line 197  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 270  Label *engine(Xt *ip, Cell *sp, Cell *rp
     ip = current_ip+1;      ip = current_ip+1;
     NEXT1_P2;      NEXT1_P2;
   }    }
     #endif
   #ifndef CFA_NEXT
     }
   #endif
   
  docon:   docon:
   #ifndef CFA_NEXT
     {
       Xt cfa; GETCFA(cfa);
   #endif
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x: con: %08x\n",(Cell)ip,*(Cell*)PFA1(cfa));    fprintf(stderr,"%08lx: con: %08lx\n",(Cell)ip,*(Cell*)PFA1(cfa));
 #endif  #endif
 #ifdef USE_TOS  #ifdef USE_TOS
   *sp-- = TOS;    *sp-- = TOS;
Line 208  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 289  Label *engine(Xt *ip, Cell *sp, Cell *rp
 #else  #else
   *--sp = *(Cell *)PFA1(cfa);    *--sp = *(Cell *)PFA1(cfa);
 #endif  #endif
   #ifndef CFA_NEXT
     }
   #endif
     NEXT_P0;
   NEXT;    NEXT;
       
  dovar:   dovar:
   #ifndef CFA_NEXT
     {
       Xt cfa; GETCFA(cfa);
   #endif
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x: var: %08x\n",(Cell)ip,(Cell)PFA1(cfa));    fprintf(stderr,"%08lx: var: %08lx\n",(Cell)ip,(Cell)PFA1(cfa));
 #endif  #endif
 #ifdef USE_TOS  #ifdef USE_TOS
   *sp-- = TOS;    *sp-- = TOS;
Line 220  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 309  Label *engine(Xt *ip, Cell *sp, Cell *rp
 #else  #else
   *--sp = (Cell)PFA1(cfa);    *--sp = (Cell)PFA1(cfa);
 #endif  #endif
   #ifndef CFA_NEXT
     }
   #endif
     NEXT_P0;
   NEXT;    NEXT;
       
   /* !! user? */  
     
  douser:   douser:
   #ifndef CFA_NEXT
     {
       Xt cfa; GETCFA(cfa);
   #endif
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x: user: %08x\n",(Cell)ip,(Cell)PFA1(cfa));    fprintf(stderr,"%08lx: user: %08lx\n",(Cell)ip,(Cell)PFA1(cfa));
 #endif  #endif
 #ifdef USE_TOS  #ifdef USE_TOS
   *sp-- = TOS;    *sp-- = TOS;
Line 234  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 329  Label *engine(Xt *ip, Cell *sp, Cell *rp
 #else  #else
   *--sp = (Cell)(up+*(Cell*)PFA1(cfa));    *--sp = (Cell)(up+*(Cell*)PFA1(cfa));
 #endif  #endif
   #ifndef CFA_NEXT
     }
   #endif
     NEXT_P0;
   NEXT;    NEXT;
       
  dodefer:   dodefer:
   #ifndef CFA_NEXT
     {
       Xt cfa; GETCFA(cfa);
   #endif
   #ifdef DEBUG
     fprintf(stderr,"%08lx: defer: %08lx\n",(Cell)ip,*(Cell*)PFA1(cfa));
   #endif
     EXEC(*(Xt *)PFA1(cfa));
   #ifndef CFA_NEXT
     }
   #endif
   
    dofield:
   #ifndef CFA_NEXT
     {
       Xt cfa; GETCFA(cfa);
   #endif
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x: defer: %08x\n",(Cell)ip,(Cell)PFA1(cfa));    fprintf(stderr,"%08lx: field: %08lx\n",(Cell)ip,(Cell)PFA1(cfa));
 #endif  #endif
   cfa = *(Xt *)PFA1(cfa);    TOS += *(Cell*)PFA1(cfa); 
   NEXT1;  #ifndef CFA_NEXT
     }
   #endif
     NEXT_P0;
     NEXT;
   
  dodoes:   dodoes:
   /* this assumes the following structure:    /* this assumes the following structure:
Line 261  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 381  Label *engine(Xt *ip, Cell *sp, Cell *rp
      pfa:       pfa:
             
      */       */
   #ifndef CFA_NEXT
     {
       Xt cfa; GETCFA(cfa);
   
   /*    fprintf(stderr, "Got CFA %08lx at doescode %08lx/%08lx: does: %08lx\n",cfa,(Cell)ip,(Cell)PFA(cfa),(Cell)DOES_CODE1(cfa));*/
   #endif
 #ifdef DEBUG  #ifdef DEBUG
   printf("%08x/%08x: does: %08x\n",(Cell)ip,(Cell)cfa,*(Cell)PFA(cfa));    fprintf(stderr,"%08lx/%08lx: does: %08lx\n",(Cell)ip,(Cell)PFA(cfa),(Cell)DOES_CODE1(cfa));
   fflush(stdout);    fflush(stderr);
 #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 */
Line 274  Label *engine(Xt *ip, Cell *sp, Cell *rp Line 400  Label *engine(Xt *ip, Cell *sp, Cell *rp
 #else  #else
   *--sp = (Cell)PFA(cfa);    *--sp = (Cell)PFA(cfa);
 #endif  #endif
   #ifndef CFA_NEXT
   /*    fprintf(stderr,"TOS = %08lx, IP=%08lx\n", TOS, IP);*/
     }
   #endif
     NEXT_P0;
   NEXT;    NEXT;
     
 #include "primitives.i"  #include "primitives.i"
 }  }

Removed from v.1.14  
changed lines
  Added in v.1.31


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