/* Main loop */ /* $Id$ */ #include #include #include #include #include #include "e.out.h" #include "logging.h" #include "nofloat.h" #include "global.h" #include "log.h" #include "io.h" #include "trap.h" #include "warn.h" #include "text.h" #include "read.h" #include "opcode.h" #include "m_sigtrp.h" #include "rsb.h" char mess_file[64] = "int.mess"; /* name of message file */ jmp_buf trapbuf; char *prog_name; int running; /* set if EM machine is running */ size maxstack; /* if set, max stack size */ size maxheap; /* if set, max heap size */ #ifdef LOGGING extern long inr; /* from log.c */ #endif /* LOGGING */ PRIVATE char *dflt_av[] = {"e.out", 0}; /* default arguments */ /* External definitions - too lazy to create a header file for each. */ extern void init(int , char **); extern void disassemble(void); extern void tally(void); extern void out_tally(void); /** Check dynamically that the interpreter can run on the target machine. */ static void check_requirements(char *name) { /* Verify that shift right supported signed shifts. According to ISO C90, * this is not mandatory, we should not support it here! */ int shrv = -4; if ((shrv >> 1) != -2) { fprintf(stderr, "%s compiled with compiler that does not support signed right shifts. Aborted.", name); exit(1); } } int main(int argc, char *argv[]) { register int i; register int nosetjmp = 1; int must_disassemble = 0; int must_tally = 0; prog_name = argv[0]; check_requirements(prog_name); /* Initialize the EM machine */ PreIgnMask = 0; FRALimit = FRALIMIT; for (i = 1; i < argc; i++) { if (*(argv[i]) == '-') { switch (*(argv[i] + 1)) { case 'd': /* disassembly */ must_disassemble = 1; break; case 'h': /* limit heap size */ maxheap = atol(argv[i] + 2); break; case 'I': /* IgnMask pre-setting */ if (atoi(argv[i] + 2) < 16) PreIgnMask = BIT(atoi(argv[i] + 2)); break; case 'm': /* messagefile name override */ strcpy(mess_file, argv[i] + 2); break; case 'r': /* FRALimit override */ FRALimit = atoi(argv[i] + 2); break; case 's': /* limit stack size */ maxstack = atol(argv[i] + 2); break; case 't': /* switch on tallying */ must_tally= 1; break; case 'W': /* disable warning */ set_wmask(atoi(argv[i] + 2)); break; default: fprintf(stderr, "%s: bad option: %s\n", prog_name, argv[i] ); exit(1); } } #ifdef LOGGING else if (logarg(argv[i])) { /* interesting for the logging machine */ } #endif /* LOGGING */ else break; } #ifdef LOGGING /* Initialize the logging machine */ init_log(); #endif /* LOGGING */ if (argc > i) init(argc - i, argv + i); else init(1, dflt_av); /* Text dump only? */ if (must_disassemble) { message( "text segment disassembly produced; program was not run"); disassemble(); close_down(0); } /* Analyse FLAGS word */ if (FLAGS&FB_TEST) must_test = 1; if ((FLAGS&FB_PROFILE) || (FLAGS&FB_FLOW) || (FLAGS&FB_COUNT)) must_tally = 1; #ifdef NOFLOAT if (FLAGS&FB_REALS) warning(WFLUSED); #endif /* NOFLOAT */ if (FLAGS&FB_EXTRA) warning(WEXTRIGN); /* Call first procedure */ running = 1; /* start the machine */ OnTrap = TR_HALT; /* default trap handling */ call(ENTRY, RSB_STP); /* Run the machine */ while (running) { #ifdef LOGGING inr++; if (must_log && inr >= log_start) { /* log this instruction */ logging = 1; } #endif /* LOGGING */ LOG(("@x9 PC = %lu OPCODE = %lu", PC, btol(text_loc(PC)) < SECONDARY ? btol(text_loc(PC)) : btol(text_loc(PC)) + btol(text_loc(PC+1)) )); newPC(PC); /* just check for validity */ do_instr(nextPCbyte()); /* here it happens */ if (must_tally) { tally(); } if (signalled) { /* a signal has come in during this instruction */ LOG(("@t1 signal %d caught by EM machine", signalled)); trap_signal(); } if (nosetjmp) { /* entry point after a trap occurred */ setjmp(trapbuf); nosetjmp = 0; } #ifdef LOGGING log_eoi(); #endif /* LOGGING */ } if (must_tally) { out_tally(); } if (ES_def == DEFINED) { message("program exits with status %ld", ES); close_down((int) ES); } else { message("program exits with undefined status"); close_down(0); } /*NOTREACHED*/ }