/* do not edit automatically generated by mc from RTExceptions. */ /* RTExceptions.mod runtime exception handler routines. Copyright (C) 2008-2024 Free Software Foundation, Inc. Contributed by Gaius Mulley . This file is part of GNU Modula-2. GNU Modula-2 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 3, or (at your option) any later version. GNU Modula-2 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. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ #include "config.h" #include "system.h" #include # if !defined (PROC_D) # define PROC_D typedef void (*PROC_t) (void); typedef struct { PROC_t proc; } PROC; # endif # if !defined (FALSE) # define FALSE (1==0) # endif # include "GStorage.h" # include "Gmcrts.h" #ifndef __cplusplus extern void throw (unsigned int); #endif #if defined(__cplusplus) # undef NULL # define NULL 0 #endif #define _RTExceptions_H #define _RTExceptions_C # include "GASCII.h" # include "GStrLib.h" # include "GStorage.h" # include "GSYSTEM.h" # include "Glibc.h" # include "GM2RTS.h" # include "GSysExceptions.h" # include "GM2EXCEPTION.h" typedef struct RTExceptions_ProcedureHandler_p RTExceptions_ProcedureHandler; # define MaxBuffer 4096 typedef struct RTExceptions__T1_r RTExceptions__T1; typedef char *RTExceptions_PtrToChar; typedef struct RTExceptions__T2_a RTExceptions__T2; typedef struct RTExceptions__T3_r RTExceptions__T3; typedef RTExceptions__T3 *RTExceptions_Handler; typedef RTExceptions__T1 *RTExceptions_EHBlock; typedef void (*RTExceptions_ProcedureHandler_t) (void); struct RTExceptions_ProcedureHandler_p { RTExceptions_ProcedureHandler_t proc; }; struct RTExceptions__T2_a { char array[MaxBuffer+1]; }; struct RTExceptions__T1_r { RTExceptions__T2 buffer; unsigned int number; RTExceptions_Handler handlers; RTExceptions_EHBlock right; }; struct RTExceptions__T3_r { RTExceptions_ProcedureHandler p; unsigned int n; RTExceptions_Handler right; RTExceptions_Handler left; RTExceptions_Handler stack; }; static bool inException; static RTExceptions_Handler freeHandler; static RTExceptions_EHBlock freeEHB; static RTExceptions_EHBlock currentEHB; static void * currentSource; /* Raise - invoke the exception handler associated with, number, in the active EHBlock. It keeps a record of the number and message in the EHBlock for later use. */ extern "C" void RTExceptions_Raise (unsigned int number, void * file, unsigned int line, unsigned int column, void * function, void * message) __attribute__ ((noreturn)); /* SetExceptionBlock - sets, source, as the active EHB. */ extern "C" void RTExceptions_SetExceptionBlock (RTExceptions_EHBlock source); /* GetExceptionBlock - returns the active EHB. */ extern "C" RTExceptions_EHBlock RTExceptions_GetExceptionBlock (void); /* GetTextBuffer - returns the address of the EHB buffer. */ extern "C" void * RTExceptions_GetTextBuffer (RTExceptions_EHBlock e); /* GetTextBufferSize - return the size of the EHB text buffer. */ extern "C" unsigned int RTExceptions_GetTextBufferSize (RTExceptions_EHBlock e); /* GetNumber - return the exception number associated with, source. */ extern "C" unsigned int RTExceptions_GetNumber (RTExceptions_EHBlock source); /* InitExceptionBlock - creates and returns a new exception block. */ extern "C" RTExceptions_EHBlock RTExceptions_InitExceptionBlock (void); /* KillExceptionBlock - destroys the EHB, e, and all its handlers. */ extern "C" RTExceptions_EHBlock RTExceptions_KillExceptionBlock (RTExceptions_EHBlock e); /* PushHandler - install a handler in EHB, e. */ extern "C" void RTExceptions_PushHandler (RTExceptions_EHBlock e, unsigned int number, RTExceptions_ProcedureHandler p); /* PopHandler - removes the handler associated with, number, from EHB, e. */ extern "C" void RTExceptions_PopHandler (RTExceptions_EHBlock e, unsigned int number); /* DefaultErrorCatch - displays the current error message in the current exception block and then calls HALT. */ extern "C" void RTExceptions_DefaultErrorCatch (void); /* BaseExceptionsThrow - configures the Modula-2 exceptions to call THROW which in turn can be caught by an exception block. If this is not called then a Modula-2 exception will simply call an error message routine and then HALT. */ extern "C" void RTExceptions_BaseExceptionsThrow (void); /* IsInExceptionState - returns TRUE if the program is currently in the exception state. */ extern "C" bool RTExceptions_IsInExceptionState (void); /* SetExceptionState - returns the current exception state and then sets the current exception state to, to. */ extern "C" bool RTExceptions_SetExceptionState (bool to); /* SwitchExceptionState - assigns, from, with the current exception state and then assigns the current exception to, to. */ extern "C" void RTExceptions_SwitchExceptionState (bool *from, bool to); /* GetBaseExceptionBlock - returns the initial language exception block created. */ extern "C" RTExceptions_EHBlock RTExceptions_GetBaseExceptionBlock (void); /* SetExceptionSource - sets the current exception source to, source. */ extern "C" void RTExceptions_SetExceptionSource (void * source); /* GetExceptionSource - returns the current exception source. */ extern "C" void * RTExceptions_GetExceptionSource (void); /* ErrorString - writes a string to stderr. */ static void ErrorString (const char *a_, unsigned int _a_high); /* findHandler - */ static RTExceptions_Handler findHandler (RTExceptions_EHBlock e, unsigned int number); /* InvokeHandler - invokes the associated handler for the current exception in the active EHB. */ static void InvokeHandler (void) __attribute__ ((noreturn)); /* DoThrow - throw the exception number in the exception block. */ static void DoThrow (void); /* addChar - adds, ch, to the current exception handler text buffer at index, i. The index in then incremented. */ static void addChar (char ch, unsigned int *i); /* stripPath - returns the filename from the path. */ static void * stripPath (void * s); /* addFile - adds the filename determined by, s, however it strips any preceeding path. */ static void addFile (void * s, unsigned int *i); /* addStr - adds a C string from address, s, into the current handler text buffer. */ static void addStr (void * s, unsigned int *i); /* addNum - adds a number, n, to the current handler text buffer. */ static void addNum (unsigned int n, unsigned int *i); /* New - returns a new EHBlock. */ static RTExceptions_EHBlock New (void); /* NewHandler - returns a new handler. */ static RTExceptions_Handler NewHandler (void); /* KillHandler - returns, NIL, and places, h, onto the free list. */ static RTExceptions_Handler KillHandler (RTExceptions_Handler h); /* KillHandlers - kills all handlers in the list. */ static RTExceptions_Handler KillHandlers (RTExceptions_Handler h); /* InitHandler - */ static RTExceptions_Handler InitHandler (RTExceptions_Handler h, RTExceptions_Handler l, RTExceptions_Handler r, RTExceptions_Handler s, unsigned int number, RTExceptions_ProcedureHandler proc); /* SubHandler - */ static void SubHandler (RTExceptions_Handler h); /* AddHandler - add, e, to the end of the list of handlers. */ static void AddHandler (RTExceptions_EHBlock e, RTExceptions_Handler h); /* indexf - raise an index out of bounds exception. */ static void indexf (void * a); /* range - raise an assignment out of range exception. */ static void range (void * a); /* casef - raise a case selector out of range exception. */ static void casef (void * a); /* invalidloc - raise an invalid location exception. */ static void invalidloc (void * a); /* function - raise a ... function ... exception. --fixme-- what does this exception catch? */ static void function (void * a); /* wholevalue - raise an illegal whole value exception. */ static void wholevalue (void * a); /* wholediv - raise a division by zero exception. */ static void wholediv (void * a); /* realvalue - raise an illegal real value exception. */ static void realvalue (void * a); /* realdiv - raise a division by zero in a real number exception. */ static void realdiv (void * a); /* complexvalue - raise an illegal complex value exception. */ static void complexvalue (void * a); /* complexdiv - raise a division by zero in a complex number exception. */ static void complexdiv (void * a); /* protection - raise a protection exception. */ static void protection (void * a); /* systemf - raise a system exception. */ static void systemf (void * a); /* coroutine - raise a coroutine exception. */ static void coroutine (void * a); /* exception - raise a exception exception. */ static void exception (void * a); /* Init - initialises this module. */ static void Init (void); /* TidyUp - deallocate memory used by this module. */ static void TidyUp (void); /* ErrorString - writes a string to stderr. */ static void ErrorString (const char *a_, unsigned int _a_high) { int n; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); n = static_cast (libc_write (2, &a, static_cast (StrLib_StrLen ((const char *) a, _a_high)))); } /* findHandler - */ static RTExceptions_Handler findHandler (RTExceptions_EHBlock e, unsigned int number) { RTExceptions_Handler h; h = e->handlers->right; while ((h != e->handlers) && (number != h->n)) { h = h->right; } if (h == e->handlers) { return NULL; } else { return h; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* InvokeHandler - invokes the associated handler for the current exception in the active EHB. */ static void InvokeHandler (void) { RTExceptions_Handler h; h = findHandler (currentEHB, currentEHB->number); if (h == NULL) { throw (RTExceptions_GetNumber (RTExceptions_GetExceptionBlock ())); } else { (*h->p.proc) (); M2RTS_HALT (-1); __builtin_unreachable (); } } /* DoThrow - throw the exception number in the exception block. */ static void DoThrow (void) { throw (RTExceptions_GetNumber (RTExceptions_GetExceptionBlock ())); } /* addChar - adds, ch, to the current exception handler text buffer at index, i. The index in then incremented. */ static void addChar (char ch, unsigned int *i) { if (((*i) <= MaxBuffer) && (currentEHB != NULL)) { currentEHB->buffer.array[(*i)] = ch; (*i) += 1; } } /* stripPath - returns the filename from the path. */ static void * stripPath (void * s) { RTExceptions_PtrToChar f; RTExceptions_PtrToChar p; p = static_cast (s); f = static_cast (s); while ((*p) != ASCII_nul) { if ((*p) == '/') { p += 1; f = p; } else { p += 1; } } return reinterpret_cast (f); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* addFile - adds the filename determined by, s, however it strips any preceeding path. */ static void addFile (void * s, unsigned int *i) { RTExceptions_PtrToChar p; p = static_cast (stripPath (s)); while ((p != NULL) && ((*p) != ASCII_nul)) { addChar ((*p), i); p += 1; } } /* addStr - adds a C string from address, s, into the current handler text buffer. */ static void addStr (void * s, unsigned int *i) { RTExceptions_PtrToChar p; p = static_cast (s); while ((p != NULL) && ((*p) != ASCII_nul)) { addChar ((*p), i); p += 1; } } /* addNum - adds a number, n, to the current handler text buffer. */ static void addNum (unsigned int n, unsigned int *i) { if (n < 10) { addChar ( ((char) ((n % 10)+ ((unsigned int) ('0')))), i); } else { addNum (n / 10, i); addNum (n % 10, i); } } /* New - returns a new EHBlock. */ static RTExceptions_EHBlock New (void) { RTExceptions_EHBlock e; if (freeEHB == NULL) { Storage_ALLOCATE ((void **) &e, sizeof (RTExceptions__T1)); } else { e = freeEHB; freeEHB = freeEHB->right; } return e; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* NewHandler - returns a new handler. */ static RTExceptions_Handler NewHandler (void) { RTExceptions_Handler h; if (freeHandler == NULL) { Storage_ALLOCATE ((void **) &h, sizeof (RTExceptions__T3)); } else { h = freeHandler; freeHandler = freeHandler->right; } return h; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* KillHandler - returns, NIL, and places, h, onto the free list. */ static RTExceptions_Handler KillHandler (RTExceptions_Handler h) { h->right = freeHandler; freeHandler = h; return NULL; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* KillHandlers - kills all handlers in the list. */ static RTExceptions_Handler KillHandlers (RTExceptions_Handler h) { h->left->right = freeHandler; freeHandler = h; return NULL; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* InitHandler - */ static RTExceptions_Handler InitHandler (RTExceptions_Handler h, RTExceptions_Handler l, RTExceptions_Handler r, RTExceptions_Handler s, unsigned int number, RTExceptions_ProcedureHandler proc) { h->p = proc; h->n = number; h->right = r; h->left = l; h->stack = s; return h; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* SubHandler - */ static void SubHandler (RTExceptions_Handler h) { h->right->left = h->left; h->left->right = h->right; } /* AddHandler - add, e, to the end of the list of handlers. */ static void AddHandler (RTExceptions_EHBlock e, RTExceptions_Handler h) { h->right = e->handlers; h->left = e->handlers->left; e->handlers->left->right = h; e->handlers->left = h; } /* indexf - raise an index out of bounds exception. */ static void indexf (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_indexException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 614, 9, const_cast (reinterpret_cast("indexf")), const_cast (reinterpret_cast("array index out of bounds"))); } /* range - raise an assignment out of range exception. */ static void range (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_rangeException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 626, 9, const_cast (reinterpret_cast("range")), const_cast (reinterpret_cast("assignment out of range"))); } /* casef - raise a case selector out of range exception. */ static void casef (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_caseSelectException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 638, 9, const_cast (reinterpret_cast("casef")), const_cast (reinterpret_cast("case selector out of range"))); } /* invalidloc - raise an invalid location exception. */ static void invalidloc (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_invalidLocation)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 650, 9, const_cast (reinterpret_cast("invalidloc")), const_cast (reinterpret_cast("invalid address referenced"))); } /* function - raise a ... function ... exception. --fixme-- what does this exception catch? */ static void function (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_functionException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 662, 9, const_cast (reinterpret_cast("function")), const_cast (reinterpret_cast("... function ... "))); /* --fixme-- what has happened ? */ } /* wholevalue - raise an illegal whole value exception. */ static void wholevalue (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_wholeValueException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 674, 9, const_cast (reinterpret_cast("wholevalue")), const_cast (reinterpret_cast("illegal whole value exception"))); } /* wholediv - raise a division by zero exception. */ static void wholediv (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_wholeDivException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 686, 9, const_cast (reinterpret_cast("wholediv")), const_cast (reinterpret_cast("illegal whole value exception"))); } /* realvalue - raise an illegal real value exception. */ static void realvalue (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_realValueException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 698, 9, const_cast (reinterpret_cast("realvalue")), const_cast (reinterpret_cast("illegal real value exception"))); } /* realdiv - raise a division by zero in a real number exception. */ static void realdiv (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_realDivException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 710, 9, const_cast (reinterpret_cast("realdiv")), const_cast (reinterpret_cast("real number division by zero exception"))); } /* complexvalue - raise an illegal complex value exception. */ static void complexvalue (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_complexValueException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 722, 9, const_cast (reinterpret_cast("complexvalue")), const_cast (reinterpret_cast("illegal complex value exception"))); } /* complexdiv - raise a division by zero in a complex number exception. */ static void complexdiv (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_complexDivException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 734, 9, const_cast (reinterpret_cast("complexdiv")), const_cast (reinterpret_cast("complex number division by zero exception"))); } /* protection - raise a protection exception. */ static void protection (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_protException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 746, 9, const_cast (reinterpret_cast("protection")), const_cast (reinterpret_cast("protection exception"))); } /* systemf - raise a system exception. */ static void systemf (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_sysException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 758, 9, const_cast (reinterpret_cast("systemf")), const_cast (reinterpret_cast("system exception"))); } /* coroutine - raise a coroutine exception. */ static void coroutine (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_coException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 770, 9, const_cast (reinterpret_cast("coroutine")), const_cast (reinterpret_cast("coroutine exception"))); } /* exception - raise a exception exception. */ static void exception (void * a) { RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_exException)), const_cast (reinterpret_cast("../../gcc/m2/gm2-libs/RTExceptions.mod")), 782, 9, const_cast (reinterpret_cast("exception")), const_cast (reinterpret_cast("exception exception"))); } /* Init - initialises this module. */ static void Init (void) { inException = false; freeHandler = NULL; freeEHB = NULL; currentEHB = RTExceptions_InitExceptionBlock (); currentSource = NULL; RTExceptions_BaseExceptionsThrow (); SysExceptions_InitExceptionHandlers ((SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) indexf}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) range}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) casef}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) invalidloc}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) function}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) wholevalue}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) wholediv}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) realvalue}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) realdiv}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) complexvalue}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) complexdiv}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) protection}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) systemf}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) coroutine}, (SysExceptions_PROCEXCEPTION) {(SysExceptions_PROCEXCEPTION_t) exception}); } /* TidyUp - deallocate memory used by this module. */ static void TidyUp (void) { RTExceptions_Handler f; RTExceptions_EHBlock e; if (currentEHB != NULL) { currentEHB = RTExceptions_KillExceptionBlock (currentEHB); } while (freeHandler != NULL) { f = freeHandler; freeHandler = freeHandler->right; Storage_DEALLOCATE ((void **) &f, sizeof (RTExceptions__T3)); } while (freeEHB != NULL) { e = freeEHB; freeEHB = freeEHB->right; Storage_DEALLOCATE ((void **) &e, sizeof (RTExceptions__T1)); } } /* Raise - invoke the exception handler associated with, number, in the active EHBlock. It keeps a record of the number and message in the EHBlock for later use. */ extern "C" void RTExceptions_Raise (unsigned int number, void * file, unsigned int line, unsigned int column, void * function, void * message) { unsigned int i; currentEHB->number = number; i = 0; addFile (file, &i); addChar (':', &i); addNum (line, &i); addChar (':', &i); addNum (column, &i); addChar (':', &i); addChar (' ', &i); addChar ('I', &i); addChar ('n', &i); addChar (' ', &i); addStr (function, &i); addChar (ASCII_nl, &i); addFile (file, &i); addChar (':', &i); addNum (line, &i); addChar (':', &i); addNum (column, &i); addChar (':', &i); addStr (message, &i); addChar (ASCII_nl, &i); addChar (ASCII_nul, &i); InvokeHandler (); } /* SetExceptionBlock - sets, source, as the active EHB. */ extern "C" void RTExceptions_SetExceptionBlock (RTExceptions_EHBlock source) { currentEHB = source; } /* GetExceptionBlock - returns the active EHB. */ extern "C" RTExceptions_EHBlock RTExceptions_GetExceptionBlock (void) { return currentEHB; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* GetTextBuffer - returns the address of the EHB buffer. */ extern "C" void * RTExceptions_GetTextBuffer (RTExceptions_EHBlock e) { return &e->buffer; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* GetTextBufferSize - return the size of the EHB text buffer. */ extern "C" unsigned int RTExceptions_GetTextBufferSize (RTExceptions_EHBlock e) { return sizeof (e->buffer); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* GetNumber - return the exception number associated with, source. */ extern "C" unsigned int RTExceptions_GetNumber (RTExceptions_EHBlock source) { return source->number; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* InitExceptionBlock - creates and returns a new exception block. */ extern "C" RTExceptions_EHBlock RTExceptions_InitExceptionBlock (void) { RTExceptions_EHBlock e; e = New (); e->number = UINT_MAX; e->handlers = NewHandler (); /* add the dummy onto the head */ e->handlers->right = e->handlers; /* add the dummy onto the head */ e->handlers->left = e->handlers; e->right = e; return e; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* KillExceptionBlock - destroys the EHB, e, and all its handlers. */ extern "C" RTExceptions_EHBlock RTExceptions_KillExceptionBlock (RTExceptions_EHBlock e) { e->handlers = KillHandlers (e->handlers); e->right = freeEHB; freeEHB = e; return NULL; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* PushHandler - install a handler in EHB, e. */ extern "C" void RTExceptions_PushHandler (RTExceptions_EHBlock e, unsigned int number, RTExceptions_ProcedureHandler p) { RTExceptions_Handler h; RTExceptions_Handler i; h = findHandler (e, number); if (h == NULL) { i = InitHandler (NewHandler (), NULL, NULL, NULL, number, p); } else { /* remove, h, */ SubHandler (h); /* stack it onto a new handler */ i = InitHandler (NewHandler (), NULL, NULL, h, number, p); } /* add new handler */ AddHandler (e, i); } /* PopHandler - removes the handler associated with, number, from EHB, e. */ extern "C" void RTExceptions_PopHandler (RTExceptions_EHBlock e, unsigned int number) { RTExceptions_Handler h; h = findHandler (e, number); if (h != NULL) { /* remove, h, */ SubHandler (h); if (h->stack != NULL) { AddHandler (e, h->stack); } h = KillHandler (h); } } /* DefaultErrorCatch - displays the current error message in the current exception block and then calls HALT. */ extern "C" void RTExceptions_DefaultErrorCatch (void) { RTExceptions_EHBlock e; int n; e = RTExceptions_GetExceptionBlock (); n = static_cast (libc_write (2, RTExceptions_GetTextBuffer (e), libc_strlen (RTExceptions_GetTextBuffer (e)))); M2RTS_HALT (-1); __builtin_unreachable (); } /* BaseExceptionsThrow - configures the Modula-2 exceptions to call THROW which in turn can be caught by an exception block. If this is not called then a Modula-2 exception will simply call an error message routine and then HALT. */ extern "C" void RTExceptions_BaseExceptionsThrow (void) { M2EXCEPTION_M2Exceptions i; for (i=M2EXCEPTION_indexException; i<=M2EXCEPTION_exException; i= static_cast(static_cast(i+1))) { RTExceptions_PushHandler (RTExceptions_GetExceptionBlock (), (unsigned int ) (i), (RTExceptions_ProcedureHandler) {(RTExceptions_ProcedureHandler_t) DoThrow}); } } /* IsInExceptionState - returns TRUE if the program is currently in the exception state. */ extern "C" bool RTExceptions_IsInExceptionState (void) { return inException; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* SetExceptionState - returns the current exception state and then sets the current exception state to, to. */ extern "C" bool RTExceptions_SetExceptionState (bool to) { bool old; old = inException; inException = to; return old; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* SwitchExceptionState - assigns, from, with the current exception state and then assigns the current exception to, to. */ extern "C" void RTExceptions_SwitchExceptionState (bool *from, bool to) { (*from) = inException; inException = to; } /* GetBaseExceptionBlock - returns the initial language exception block created. */ extern "C" RTExceptions_EHBlock RTExceptions_GetBaseExceptionBlock (void) { if (currentEHB == NULL) { M2RTS_Halt ((const char *) "currentEHB has not been initialized yet", 39, (const char *) "../../gcc/m2/gm2-libs/RTExceptions.mod", 38, (const char *) "GetBaseExceptionBlock", 21, 600); } else { return currentEHB; } ReturnException ("../../gcc/m2/gm2-libs/RTExceptions.def", 25, 1); __builtin_unreachable (); } /* SetExceptionSource - sets the current exception source to, source. */ extern "C" void RTExceptions_SetExceptionSource (void * source) { currentSource = source; } /* GetExceptionSource - returns the current exception source. */ extern "C" void * RTExceptions_GetExceptionSource (void) { return currentSource; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } extern "C" void _M2_RTExceptions_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { Init (); } extern "C" void _M2_RTExceptions_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { TidyUp (); }