/* Copyright (C) 1989, Digital Equipment Corporation */ /* All rights reserved. */ /* See the file COPYRIGHT for a full description. */ /* Last Modified On Fri Jul 20 09:37:17 1990 by muller */ /* Modified On Fri Jan 12 13:48:18 1990 by kalsow */ /* This is to have the copyright in the runtime object */ static char *copyright[] = { " SRC Modula-3 Non-commercial License", "", "SRC Modula-3 is distributed by Digital Equipment Corporation ('DIGITAL'),", "a corporation of the Commonwealth of Massachusetts. DIGITAL hereby grants", "to you a non-transferable, non-exclusive, royalty free worldwide license", "to use, copy, modify, prepare integrated and derivative works of and", "distribute SRC Modula-3 for non-commercial purposes, subject to your", "agreement to the following terms and conditions:", "", " - The SRC Modula-3 Non-commercial License shall be included in the code", " and must be retained in all copies of SRC Modula-3 (full or partial;", " original, modified, derivative, or otherwise):", "", " - You acquire no ownership right, title, or interest in SRC Modula-3", " except as provided herein.", "", " - You agree to make available to DIGITAL any improvements, extensions", " or enhancements of the software which materially improve its operation", " if such enhancements are distributed to others.", "", " - SRC Modula-3 is provided 'as is' and DIGITAL disclaims all warranties", " with regard to this software, including all implied warranties of", " merchantability and fitness of purpose. In no event shall DIGITAL be", " liable for any special, direct, indirect, or consequential damages or", " any damages whatsoever resulting from loss of use, data or profits,", " whether in an action of contract, negligence or other tortious action,", " arising out of or in connection with the use or performance of this", " software. ", "", "", " Copyright (C) 1990 Digital Equipment Corp.", " All Rights Reserved" }; #include #include #if defined (VAX) #include #endif #if defined (DS3100) #include #include #endif #if defined (HP300) #include #endif #include #include #include #include #include #include #include #include "M3RuntimeDecls.h" #define TRUE 1 #define FALSE 0 EXPORT struct { INITLINK *init; } Main; EXPORT char _Main__44; PRIVATE int generation = 1; PRIVATE int top_level_on = FALSE; PRIVATE jmp_buf top_level_jmp_buf; /*------------------*/ /* Runtime routines */ EXPORT EXCEPTION *FALL_EXCEPTION = NULL; PRIVATE EXCEPTION_NAME return_exception_name = "return exception"; PRIVATE EXCEPTION return_exception = {& return_exception_name, 0}; PRIVATE EXCEPTION_NAME exit_exception_name = "exit exception"; PRIVATE EXCEPTION exit_exception = {& exit_exception_name, 0}; EXPORT EXCEPTION *RETURN_EXCEPTION = & return_exception; EXPORT EXCEPTION *EXIT_EXCEPTION = & exit_exception; #include EXPORT void _M3Runtime__Error (va_alist) va_dcl { va_list args; char *fmt; fprintf (stderr, "\nruntime error: "); va_start (args); fmt = va_arg (args, char*); vfprintf (stderr, fmt, args); va_end (args); fprintf (stderr, "\n\n"); fflush (stderr); if (top_level_on) { longjmp (top_level_jmp_buf, 0); } else { /* stop and dump core */ kill (getpid (), SIGBUS); while (1); } } EXPORT void _M3Runtime__AssertFault () { _M3Runtime__Error ("ASSERT failed"); } EXPORT void _M3Runtime__StackOverflow () { _M3Runtime__Error ("stack overflow"); } EXPORT void _M3Runtime__ReturnFault () { _M3Runtime__Error ("missing return value"); } EXPORT void _M3Runtime__CaseFault () { _M3Runtime__Error ("unhandled value in CASE"); } EXPORT void _M3Runtime__TypecaseFault () { _M3Runtime__Error ("unhandled type in TYPECASE"); } EXPORT void _M3Runtime__RangeFault () { _M3Runtime__Error ("value out of range"); } EXPORT void _M3Runtime__HandlerFault (e) EXCEPTION_NAME *e; { _M3Runtime__Error ("unhandled exception \"%s\"", *e); } EXPORT void _M3Runtime__NarrowFault () { _M3Runtime__Error ("NARROW failed"); } EXPORT void _M3Runtime__RaisesFault (e) EXCEPTION_NAME *e; { _M3Runtime__Error ("exception \"%s\" not in the raise list", *e); } EXPORT void _M3Runtime__Raise (exception, arg, size) EXCEPTION_NAME *exception; ADDRESS arg; int size; { int found = FALSE; extern HANDLER *_ThreadSup__handlers; HANDLER *h = _ThreadSup__handlers; while (!found && h != NULL) { switch (h->class) { case EXCEPT_HC: { EXCEPTION_NAME **e = h->handles; /* is the current exception handled by this handler ? */ if (e == NULL) { /* yes, this one has an ELSE clause */ found = TRUE; } else { while (*e != NULL && *e != exception) { e++; } if (*e == NULL) { /* no, that doesnt handle our exception */ h = h->next; } else { /* yes it does */ found = TRUE; }} break; } case RAISES_HC: { /* we have to check that this procedure does indeed raise the current exception */ EXCEPTION_NAME **e; for (e = h->handles; e != NULL && *e != NULL && *e != exception; e++) ; if ((e == NULL) || (*e == NULL)) { RAISESFAULT (exception); } /* ok, but that does not gives us a handler */ h = h->next; break; } case FINALLY_HC: { /* we have to execute that if we find a handler, but not just now */ h = h->next; break; }}} if (h == NULL) { HANDLERFAULT(exception); } else { EXCEPTION *ex; ALLOC_EXCEPTION (ex, exception, arg, size); RAISE_FOR_SURE (ex); } } EXPORT void _M3Runtime__InitModule (l) INITLINK **l; { INITLINK *ll0 = *l; INITLINK *ll1 = *l; *l = (INITLINK *) NIL; while (ll1) { if (ll1->doFirst) { ll1->initProc (generation); } ll1 = ll1->link; } while (ll0) { if (! ll0->doFirst) { ll0->initProc (generation); } ll0 = ll0->link; } } /*------------------------------------------------- TYPE REGISTRATION ---*/ PRIVATE void print_text (o) char **o; { fprintf ("\"%s\"", *o); } PRIVATE void empty_map_proc (parent, p, r, c) int parent, p, r, c; { } PRIVATE typecell tc_null; PRIVATE typecell tc_null_init = { (TYPE) NIL, (TYPE) NIL, 0, (TYPE) NIL, 0, empty_map_proc, 0, 0, NIL, 0, 0, (PROC) NIL, (PROC) NIL, (PROC) NIL, "NULL", 0, 0 }; EXPORT TYPE TC_NULL = & tc_null; PRIVATE typecell tc_text; PRIVATE typecell tc_text_init = { (TYPE) NIL, (TYPE) NIL, 1, (TYPE) NIL, 0, empty_map_proc, 0, 0, NIL, 0, 0, (PROC) NIL, (PROC) NIL, print_text, "TEXT", 0, 0 }; EXPORT TYPE TC_TEXT = & tc_text; PRIVATE typecell tc_mutex; PRIVATE typecell tc_mutex_init = { (TYPE) NIL, (TYPE) NIL, 1, (TYPE) NIL, 0, empty_map_proc, 0, 0, NIL, 0, 0, (PROC) NIL, (PROC) NIL, (PROC) NIL, "MUTEX", 0, 0 }; EXPORT TYPE TC_MUTEX = & tc_mutex; /* UNTRACED ROOT is used for untraced objects */ PRIVATE int untraced_root_default_methods [] = {0, 0}; PRIVATE typecell tc_untraced_root; PRIVATE typecell tc_untraced_root_init = { (TYPE) NIL, (TYPE) NIL, 0, (TYPE) NIL, 0, empty_map_proc, 4, 8, (char *) untraced_root_default_methods, 0, 0, (PROC) NIL, (PROC) NIL, (PROC) NIL, "UNTRACED_ROOT", 0, 0 }; EXPORT TYPE TC_UNTRACED_ROOT = & tc_untraced_root; /* ROOT is used for traced objects */ PRIVATE int root_default_methods [] = {0, 0}; PRIVATE typecell tc_root; PRIVATE typecell tc_root_init = { (TYPE) NIL, (TYPE) NIL, 0, (TYPE) NIL, 0, empty_map_proc, 4, 8, (char *) root_default_methods, 0, 0, (PROC) NIL, (PROC) NIL, (PROC) NIL, "ROOT", 0, 0 }; EXPORT TYPE TC_ROOT = & tc_root; PRIVATE typecell tc_address; PRIVATE typecell tc_address_init = { (TYPE) NIL, (TYPE) NIL, 0, (TYPE) NIL, 0, (PROC) NIL, 0, 0, NIL, 0, 0, (PROC) NIL, (PROC) NIL, (PROC) NIL, "ADDRESS", 0, 0 }; EXPORT TYPE TC_ADDRESS = & tc_address; PRIVATE typecell tc_refany; EXPORT TYPE TC_REFANY = & tc_refany; EXPORT typecell one_word_filler = { (TYPE) NIL, (TYPE) NIL, 0, (TYPE) NIL, 0, empty_map_proc, 0, 0, NIL, 0, 0, (PROC) NIL, (PROC) NIL, (PROC) NIL, "one-word filler", 0, 0 }; EXPORT typecell multi_word_filler = { (TYPE) NIL, (TYPE) NIL, 0, (TYPE) NIL, 0, empty_map_proc, VARIABLE_SIZE, 0, NIL, 0, 0, (PROC) NIL, (PROC) NIL, (PROC) NIL, "multi-word filler", 0, 0 }; PRIVATE int type_count = 0; PRIVATE int allocated_types = 0; EXPORT TYPE *types = NULL; #define TYPES_INCREMENT 500; EXPORT int type_size (type_code) int type_code; { return (types[type_code]->datasize); } EXPORT TYPE type_cell (type_code) int type_code; { return (types[type_code]); } PRIVATE void dummy_print_type (o) char *o; { } EXPORT TYPE _M3Runtime__RegisterType (t, o) TYPE t; int o; { int i; t->opaque = o; t->typecode = type_count; if (type_count >= allocated_types) { allocated_types += TYPES_INCREMENT; types = (TYPE *) realloc (types, (allocated_types * sizeof (TYPE))); if (types == NULL) { fprintf (stderr, "could not extend space for types info\n"); exit (1); }} types [type_count] = t; type_count++; if (t->printProc == 0) { t->printProc = dummy_print_type; } return (t); } EXPORT TYPE _M3Runtime__IdentifyTypes (t1, t2) TYPE t1, t2; { if (t1->opaque) { if (t2->opaque) { _M3Runtime__Error ( "cannot identify 0x%x [%s] and 0x%x [%s];\n both are opaque", t1, t1->brand, t2, t2->brand); } else { t1->identified_with = t2; t1->opaque = 0; }} else if (t2->opaque) { t2->identified_with = t1; t2->opaque = 0; } else if ((t1->identified_with == t2) || (t2->identified_with == t1)) { /* ok, we already came there */ } else { _M3Runtime__Error ( "cannot identify 0x%x [%s] and 0x%x [%s];\n both are non-opaque", t1, t1->brand, t2, t2->brand); } } EXPORT TYPE _M3Runtime__CheckSubType (t1, t2) TYPE t1, t2; { TYPE t0 = t1; while (1) { if ((t0 == t2) || ((t0->fprint0 == t2->fprint0) && (t0->fprint1 == t2->fprint1))) { return; } if (t0->parent == (TYPE) NIL) { _M3Runtime__Error ("0x%x [%s] is not a subtype of 0x%x [%s]", t1, t1->brand, t2, t2->brand); } t0 = t0->parent; } } EXPORT int _M3Runtime__IsSubType (tc, t) int tc; TYPE t; { TYPE t0 = types[tc]; while (1) { if ((t0 == t) || ((t0->fprint0 == t->fprint0) && (t0->fprint1 == t->fprint1))){ return 1; } if (t0->parent == (TYPE) NIL) { return 0; } t0 = t0->parent; } } PRIVATE void setup_type (t) TYPE t; { if (t->identified_with != (TYPE) NIL) { TYPE tt = t->identified_with; setup_type (tt); t->parent = tt->parent; t->typecode = tt->typecode; t->mapProc = tt->mapProc; t->datasize = tt->datasize; t->methodsize = tt->methodsize; t->defaultMethods = tt->defaultMethods; t->dimensions = tt->dimensions; t->elemSize = tt->elemSize; t->initProc = tt->initProc; t->setupProc = tt->setupProc; if (tt->printProc != (PROC) NIL) { t->printProc = tt->printProc; } else { tt->printProc = t->printProc; } t->brand = tt->brand; t->fprint0 = tt->fprint0; t->fprint1 = tt->fprint1; } else { if (t->setupProc != (PROC) NIL) { if (t->parent != (TYPE) NIL) { setup_type (t->parent); } (* (t->setupProc)) (); t->setupProc = (PROC) NIL; }} } EXPORT void finish_type_registration (phase) { int it, it0, it1; if (phase != 1) { return; }; /* We have to verify that all the opaque types have been bound to something */ for (it = 0; it < type_count; it++) { TYPE t = types[it]; if (t->opaque) { _M3Runtime__Error ("the type 0x%x [%s] is still opaque", t, t->brand); }} /* Also, we call the setup procedures for the objects */ for (it = 0; it < type_count; it++) { setup_type (types [it]); } /* Then we identify the types that have the same fingerprints and other characterics, and make sure that no two types have the same brand */ for (it0 = 0; it0 < type_count; it0++) { register TYPE t0 = types [it0]; for (it1 = it0+1; it1 < type_count; it1++) { register TYPE t1 = types [it1]; if (t0->typecode != t1->typecode) { if ((t0->brand != NIL) && (t0->brand[0] != '\0') && (t1->brand != NIL) && (t1->brand[1] != '\0')) { if (strcmp (t0->brand, t1->brand) == 0) { /* two types have the same brand */ _M3Runtime__Error ("0x%x [%s] and 0x%x [%s] have the same brand", t0, t0->brand, t1, t1->brand); }} else if ((t0->fprint0 == t1->fprint0) && (t0->fprint1 == t1->fprint1) && (t0->datasize == t1->datasize) && (t0->methodsize == t1->methodsize) && (t0->dimensions == t1->dimensions) && (t0->elemSize == t1->elemSize)) { t1->typecode = t0->typecode; }}}} } EXPORT void finish_phase_0_type_registration () { finish_type_registration (0); } EXPORT void finish_phase_1_type_registration () { finish_type_registration (1); } EXPORT void finish_phase_2_type_registration () { finish_type_registration (2); } /*-------------------------------------------- MISC ---*/ EXPORT void print_object (o) refHeader *o; { if (o == 0) { fprintf (stderr, "NIL"); } else { void (*p) () = types [TYPECODE_OF (o-1)]->printProc; if (p != (PROC)NIL) { p (o); fprintf (stderr, "\n"); } else { fprintf (stderr, "sorry, no print proc\n"); }} } extern void init_gc(); EXPORT int env_argc; EXPORT char** env_argv; /* because TEXT is opaque and is present in every program, we have to force the inclusion of the Text module. We could import a version stamp, but we would need to change the run-time if the version stamp changes (and what if we remove version stamps ?). Rather, we import TextF.New (furthermore, that's where TEXT is revealed). */ IMPORT ADDRESS _TextF__New (); void init_runtime (argc, argv) int argc; char **argv; { env_argc = argc; env_argv = argv; /* initialize _runtime */ init_gc (); untraced_root_default_methods [0] = (int) TC_UNTRACED_ROOT; root_default_methods [0] = (int) TC_ROOT; if (types == NULL) { allocated_types = TYPES_INCREMENT; types = (TYPE *) malloc (allocated_types * sizeof (TYPE)); if (types == NULL) { fprintf (stderr, "could not extend space for types info\n"); exit (1); } } type_count = 0; /* Declare our local types; note that Text will get typecode 0; this is used by the compiler. */ tc_null = tc_null_init; _M3Runtime__RegisterType (TC_NULL, TC_NULL->opaque); tc_text = tc_text_init; _M3Runtime__RegisterType (TC_TEXT, TC_TEXT->opaque); tc_mutex = tc_mutex_init; _M3Runtime__RegisterType (TC_MUTEX, TC_MUTEX->opaque); tc_untraced_root = tc_untraced_root_init; _M3Runtime__RegisterType (TC_UNTRACED_ROOT, TC_UNTRACED_ROOT->opaque); tc_root = tc_root_init; _M3Runtime__RegisterType (TC_ROOT, TC_ROOT->opaque); tc_address = tc_address_init; _M3Runtime__RegisterType (TC_ADDRESS, TC_ADDRESS->opaque); _M3Runtime__RegisterType (&one_word_filler, one_word_filler.opaque); _M3Runtime__RegisterType (&multi_word_filler, multi_word_filler.opaque); /* make sure that we reference _TextF__New */ if (argc < 0) { /* we never go there, but the compiler cannot guess */ _TextF__New (); } } #if defined (VAX) || defined (DS3100) char first[] = "first"; char second[] = "second"; #if defined (DS3100) char *mc[] = {"/mnt1/muller/sticky/m8compiler", "m3compiler", "-V%d", "-S", "-C", "-D.:.ROOT/system/corelib/Interfaces", 0}; char *cpp[] = {"/mnt1/muller/sticky/cpp", "cpp", "-DLANGUAGE_C", "-DMIPSEL", "-I.ROOT/system/runtime", "-I/usr/include2.0", 0}; char *ccom[] = {"/mnt1/muller/sticky/ccom", "ccom", "-EL", "-Xg0", "-O0", "-XS/tmp/foo0", 0 }; char *ugen[] = {"/mnt1/muller/sticky/ugen", "ugen", "-G", "0", "-EL", "-g0", "-O0", "/tmp/foo1", "-o", "/tmp/foo4", "-t", "/tmp/foo0", "-temp", "/tmp/foo3", 0}; char *as1[] = {"/mnt1/muller/sticky/as1", "as1", "-G", "0", "-p1", "-EL", "-g0", "-O0", "/tmp/foo4", "-o", "foo.o", "-t", "/tmp/foo0", 0}; char *ld[] = {"/mnt1/muller/sticky/ld", "ld", "-N", "-A", "%s ", "-T", "%x ", "-o", "%s ", "-s", "foo.o", "-e", "%s_relay_%d", 0}; char *noenvp[] = {0}; int file2mc [2], mc2cpp [2], cpp2ccom[2], ccom_out, mc_in, mc_pid, cpp_pid, ccom_pid, n; char buff [4096]; #include #include #include extern int errno; int do_exec (args, indes, outdes, close0, close1) char *args[]; int indes, outdes, close0, close1; { int s, d; switch (s = vfork ()) { case -1: _M3Runtime__Error ("vfork"); break; case 0: /* in the child process */ if (outdes != -1) { close (1); if ((d = dup (outdes)) == -1) { _M3Runtime__Error ("dup [%d], outdes = %d, %s", errno, outdes, args[0]); } close (outdes); } if (indes != -1) { close (0); if ((d = dup (indes)) == -1) { _M3Runtime__Error ("dup [%d], indes = %d, %s", errno, indes, args[0]); } close (indes); } if (close0 != -1) { close (close0); } if (close1 != -1) { close (close1); } if ((s = execve (args[0], args+1, noenvp)) == -1); { _M3Runtime__Error ("execve[%d], %s", errno, args[0]); } break; default: /* in the parent process */ if (outdes != -1) { close (outdes); } if (indes != -1) { close (indes); } } return (s); } void mywait (s) int s; { union wait st; if (waitpid (s, &st, 0) == -1) { _M3Runtime__Error ("waitpid[%d]", errno); } } extern int collection_allowed; #endif main (argc, argv) int argc; char **argv; { char path [2000]; char command [1000], command2[1000], verb[1000], file[1000], proc[1000]; char *active = first; char *new = second; struct rusage old, now, delta, self, child; struct timeval oldt, nowt, deltat; struct timezone tz; struct exec header; int fd, size, sb, nb_words, rd; int j; /*collection_allowed = 0;*/ if ((argc <= 1) || (strcmp (argv[1], "-m3debug") != 0)) { user_main (argc, argv); exit (0); } gettimeofday (&oldt, &tz); /* keep only the external symbols of the running image */ sprintf (command, "cp /dev/null foo.c; cc -c foo.c; /bin/ld -S -x -A %s -o %s foo.o\n", argv[0], first); if (system (command)) { _M3Runtime__Error ("initial simplification"); } argv[1] = argv[0]; argc--; argv++; top_level_on = TRUE; old.ru_utime.tv_sec = 0; old.ru_utime.tv_usec = 0; old.ru_stime.tv_sec = 0; old.ru_stime.tv_usec = 0; old.ru_inblock = 0; old.ru_oublock = 0; old.ru_majflt = 0; old.ru_nswap = 0; setjmp (top_level_jmp_buf); while (1) { /**/ getrusage (0, &self); getrusage (-1, &child); now.ru_utime.tv_sec = self.ru_utime.tv_sec + child.ru_utime.tv_sec; now.ru_utime.tv_usec = self.ru_utime.tv_usec + child.ru_utime.tv_usec; if (now.ru_utime.tv_usec >= 1000000) { now.ru_utime.tv_usec -= 1000000; now.ru_utime.tv_sec += 1; } now.ru_stime.tv_sec = self.ru_stime.tv_sec + child.ru_stime.tv_sec; now.ru_stime.tv_usec = self.ru_stime.tv_usec + child.ru_stime.tv_usec; if (now.ru_stime.tv_usec >= 1000000) { now.ru_stime.tv_usec -= 1000000; now.ru_stime.tv_sec += 1; } now.ru_inblock = self.ru_inblock + child.ru_inblock; now.ru_oublock = self.ru_oublock + child.ru_oublock; now.ru_majflt = self.ru_majflt + child.ru_majflt; now.ru_nswap = self.ru_nswap + child.ru_nswap; delta.ru_utime.tv_sec = now.ru_utime.tv_sec - old.ru_utime.tv_sec; delta.ru_utime.tv_usec = now.ru_utime.tv_usec - old.ru_utime.tv_usec; if (delta.ru_utime.tv_usec < 0) { delta.ru_utime.tv_usec += 1000000; delta.ru_utime.tv_sec -= 1; } delta.ru_stime.tv_sec = now.ru_stime.tv_sec - old.ru_stime.tv_sec; delta.ru_stime.tv_usec = now.ru_stime.tv_usec - old.ru_stime.tv_usec; if (delta.ru_stime.tv_usec < 0) { delta.ru_stime.tv_usec += 1000000; delta.ru_stime.tv_sec -= 1; } delta.ru_inblock = now.ru_inblock - old.ru_inblock; delta.ru_oublock = now.ru_oublock - old.ru_oublock; delta.ru_majflt = now.ru_majflt - old.ru_majflt; delta.ru_nswap = now.ru_nswap - old.ru_nswap; old = now; /**/ gettimeofday (&nowt, &tz); deltat.tv_sec = nowt.tv_sec - oldt.tv_sec; deltat.tv_usec = nowt.tv_usec - oldt.tv_usec; if (deltat.tv_usec < 0) { deltat.tv_usec += 1000000; deltat.tv_sec -= 1;} oldt = nowt; /**/ printf ("%d.%2du %d.%2ds %d:%2d %d+%dio %dpf+%dw\n", delta.ru_utime.tv_sec, delta.ru_utime.tv_usec / 10000, delta.ru_stime.tv_sec, delta.ru_stime.tv_usec / 10000, deltat.tv_sec, deltat.tv_usec / 10000, delta.ru_inblock, delta.ru_oublock, delta.ru_majflt, delta.ru_nswap); /**/ /* printf ("%d:%ds\n", deltat.tv_sec, deltat.tv_usec / 10000); */ printf ("m3"); fflush (stdout); #if defined (DS3100) /* prepare the processes for the next round */ if (pipe (file2mc) != 0) { _M3Runtime__Error ("pip file - mc [%d]", errno); } if (pipe (mc2cpp) != 0) { _M3Runtime__Error ("pip mc - cpp [%d]", errno); } sprintf (mc[2]+2, "%d", generation); mc_pid = do_exec (mc, file2mc[0], mc2cpp[1], file2mc[1], mc2cpp[0]); if (pipe (cpp2ccom) != 0) { _M3Runtime__Error ("pip cpp - ccom [%d]", errno); } cpp_pid = do_exec (cpp, mc2cpp[0], cpp2ccom[1], file2mc[1], cpp2ccom[0]); ccom_out = open ("/tmp/foo1", O_WRONLY, 0777); ccom_pid = do_exec (ccom, cpp2ccom[0], ccom_out, file2mc[1], -1); #endif printf ("> "); fflush (stdout); if (gets (command2) == NULL) { verb[0] = 'q'; } else { nb_words = sscanf (command2, "%s%s%s", verb, file, proc+2); } gettimeofday (&oldt, &tz); switch (verb[0]) { case 'h': case '?': printf ("r - run the program\n"); printf ("u module - update module\n"); printf ("u module procedure - update module.procedure\n"); printf ("h - print this message\n"); printf ("? - print this message\n"); printf ("q - quit\n"); break; case 'r': user_main (argc, argv); break ; case 'q': #if defined (DS3100) kill (mc_pid, 9); kill (cpp_pid, 9); kill (ccom_pid, 9); #endif printf ("Bye \n"); exit (0); case 'l': case 'u': { sb = ((sbrk (0) + 1023) / 1024) * 1024; if (verb[0] == 'l') { sprintf (command, "set -x; .ROOT/system/compiler/m3compiler -V0 -D.:.ROOT/system/corelib/Interfaces -o foo.c %s.m3; cc -I.ROOT/system/runtime -g -c foo.c; /bin/ld -A %s -T %x -o %s -X foo.o; times\n", generation, file, active, sb, new); } else { if (nb_words==3) { proc[0]='-'; proc[1]='P'; } else {proc[0]='\0';} #if defined (VAX) sprintf (command, "set -x; time .ROOT/.boots/compiler/m3compiler %s -V%d -S -C -D.:.ROOT/system/corelib/Interfaces -o foo.c %s.m3; time gcc -pipe -I.ROOT/system/runtime -c foo.c; time /bin/ld -N -A %s -T %x -o %s -s foo.o -e _%s_relay_%d\n", proc, generation, file, active, sb, new, file, generation); } if (system (command)) { break; } #endif #if defined (DS3100) strcpy (command, file); strcat (command, ".m3"); mc_in = open (command, O_RDONLY, 0); while ((n = read (mc_in, buff, sizeof (buff))) != 0) { write (file2mc[1], buff, n); } close (mc_in); if (close (file2mc[1]) == -1) { _M3Runtime__Error ("close file - mc [%d]\n", errno); }; mywait (mc_pid); mywait (cpp_pid); mywait (ccom_pid); mywait (do_exec (ugen, -1, -1, -1, -1)); mywait (do_exec (as1, -1, -1, -1, -1)); ld[4] = active; sprintf (ld[6], "%x", sb); ld[8] = new; sprintf (ld[12], "%s_relay_%d", file, generation); mywait (do_exec (ld, -1, -1, -1, -1)); } #endif if ((fd = open (new, O_RDONLY, 0)) == -1) { _M3Runtime__Error ("load_file:open"); } if (read (fd, &header, sizeof (header)) != sizeof (header)) { _M3Runtime__Error ("load_file:read header"); } #if defined (DS3100) /* skip the secondary headers */ { off_t to = N_TXTOFF (header.ex_f, header.ex_o) - 8; if (to != lseek (fd, to, SEEK_SET)) { _M3Runtime__Error ("load_file: seek"); }} #endif size = header.a_text + header.a_data; if (sbrk (sb - sbrk(0) + size + header.a_bss) == -1) { _M3Runtime__Error ("load_file:sbrk"); } if ((rd = read (fd, sb, size)) != size) { _M3Runtime__Error ("load_file:read text & data (%d asked, %d done)", size, rd); } if (close (fd) != 0) { _M3Runtime__Error ("load_file:close"); } if (header.a_entry != 0) { ((void (*)()) header.a_entry) (); } if (verb[0] == 'l') { if (new == first) { active = first; new = second; } else { active = second; new = first; }} break; } default: fprintf (stderr, "What ?\n"); break; } generation++; } } #else main (argc, argv) int argc; char **argv; { user_main (argc, argv); exit (0); } #endif