| /* do not edit automatically generated by mc from RTExceptions. */ |
| /* RTExceptions.mod runtime exception handler routines. |
| |
| Copyright (C) 2008-2025 Free Software Foundation, Inc. |
| Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. |
| |
| 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 |
| <http://www.gnu.org/licenses/>. */ |
| |
| #include "config.h" |
| #include "system.h" |
| #include <stdbool.h> |
| # 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_C |
| |
| #include "GRTExceptions.h" |
| # 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__opaque; |
| |
| struct RTExceptions__T2_a { char array[MaxBuffer+1]; }; |
| struct RTExceptions__T1_r { |
| RTExceptions__T2 buffer; |
| unsigned int number; |
| RTExceptions_Handler handlers; |
| RTExceptions_EHBlock__opaque 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__opaque freeEHB; |
| static RTExceptions_EHBlock__opaque 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__opaque 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__opaque 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__opaque 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<int> (libc_write (2, const_cast<void*> (static_cast<const void*>(a)), static_cast<size_t> (StrLib_StrLen ((const char *) a, _a_high)))); |
| } |
| |
| |
| /* |
| findHandler - |
| */ |
| |
| static RTExceptions_Handler findHandler (RTExceptions_EHBlock__opaque 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<RTExceptions_PtrToChar> (s); |
| f = static_cast<RTExceptions_PtrToChar> (s); |
| while ((*p) != ASCII_nul) |
| { |
| if ((*p) == '/') |
| { |
| p += 1; |
| f = p; |
| } |
| else |
| { |
| p += 1; |
| } |
| } |
| return static_cast<void *> (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<RTExceptions_PtrToChar> (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<RTExceptions_PtrToChar> (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__opaque New (void) |
| { |
| RTExceptions_EHBlock__opaque 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__opaque 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<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 614, 9, const_cast<void*> (static_cast<const void*>("indexf")), const_cast<void*> (static_cast<const void*>("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<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 626, 9, const_cast<void*> (static_cast<const void*>("range")), const_cast<void*> (static_cast<const void*>("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<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 638, 9, const_cast<void*> (static_cast<const void*>("casef")), const_cast<void*> (static_cast<const void*>("case selector out of range"))); |
| } |
| |
| |
| /* |
| invalidloc - raise an invalid location exception. |
| */ |
| |
| static void invalidloc (void * a) |
| { |
| RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_invalidLocation)), const_cast<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 650, 9, const_cast<void*> (static_cast<const void*>("invalidloc")), const_cast<void*> (static_cast<const void*>("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<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 662, 9, const_cast<void*> (static_cast<const void*>("function")), const_cast<void*> (static_cast<const void*>("... 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<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 674, 9, const_cast<void*> (static_cast<const void*>("wholevalue")), const_cast<void*> (static_cast<const void*>("illegal whole value exception"))); |
| } |
| |
| |
| /* |
| wholediv - raise a division by zero exception. |
| */ |
| |
| static void wholediv (void * a) |
| { |
| RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_wholeDivException)), const_cast<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 686, 9, const_cast<void*> (static_cast<const void*>("wholediv")), const_cast<void*> (static_cast<const void*>("illegal whole value exception"))); |
| } |
| |
| |
| /* |
| realvalue - raise an illegal real value exception. |
| */ |
| |
| static void realvalue (void * a) |
| { |
| RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_realValueException)), const_cast<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 698, 9, const_cast<void*> (static_cast<const void*>("realvalue")), const_cast<void*> (static_cast<const void*>("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<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 710, 9, const_cast<void*> (static_cast<const void*>("realdiv")), const_cast<void*> (static_cast<const void*>("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<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 722, 9, const_cast<void*> (static_cast<const void*>("complexvalue")), const_cast<void*> (static_cast<const void*>("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<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 734, 9, const_cast<void*> (static_cast<const void*>("complexdiv")), const_cast<void*> (static_cast<const void*>("complex number division by zero exception"))); |
| } |
| |
| |
| /* |
| protection - raise a protection exception. |
| */ |
| |
| static void protection (void * a) |
| { |
| RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_protException)), const_cast<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 746, 9, const_cast<void*> (static_cast<const void*>("protection")), const_cast<void*> (static_cast<const void*>("protection exception"))); |
| } |
| |
| |
| /* |
| systemf - raise a system exception. |
| */ |
| |
| static void systemf (void * a) |
| { |
| RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_sysException)), const_cast<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 758, 9, const_cast<void*> (static_cast<const void*>("systemf")), const_cast<void*> (static_cast<const void*>("system exception"))); |
| } |
| |
| |
| /* |
| coroutine - raise a coroutine exception. |
| */ |
| |
| static void coroutine (void * a) |
| { |
| RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_coException)), const_cast<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 770, 9, const_cast<void*> (static_cast<const void*>("coroutine")), const_cast<void*> (static_cast<const void*>("coroutine exception"))); |
| } |
| |
| |
| /* |
| exception - raise a exception exception. |
| */ |
| |
| static void exception (void * a) |
| { |
| RTExceptions_Raise ( ((unsigned int) (M2EXCEPTION_exException)), const_cast<void*> (static_cast<const void*>("../../gcc/m2/gm2-libs/RTExceptions.mod")), 782, 9, const_cast<void*> (static_cast<const void*>("exception")), const_cast<void*> (static_cast<const void*>("exception exception"))); |
| } |
| |
| |
| /* |
| Init - initialises this module. |
| */ |
| |
| static void Init (void) |
| { |
| inException = false; |
| freeHandler = NULL; |
| freeEHB = static_cast<RTExceptions_EHBlock__opaque> (NULL); |
| currentEHB = static_cast<RTExceptions_EHBlock__opaque> (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__opaque e; |
| |
| if (currentEHB != NULL) |
| { |
| currentEHB = static_cast<RTExceptions_EHBlock__opaque> (RTExceptions_KillExceptionBlock (static_cast<RTExceptions_EHBlock> (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 = static_cast<RTExceptions_EHBlock__opaque> (source); |
| } |
| |
| |
| /* |
| GetExceptionBlock - returns the active EHB. |
| */ |
| |
| extern "C" RTExceptions_EHBlock RTExceptions_GetExceptionBlock (void) |
| { |
| return static_cast<RTExceptions_EHBlock> (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 &static_cast<RTExceptions_EHBlock__opaque> (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 (static_cast<RTExceptions_EHBlock__opaque> (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 static_cast<RTExceptions_EHBlock__opaque> (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__opaque 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 static_cast<RTExceptions_EHBlock> (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) |
| { |
| static_cast<RTExceptions_EHBlock__opaque> (e)->handlers = KillHandlers (static_cast<RTExceptions_EHBlock__opaque> (e)->handlers); |
| static_cast<RTExceptions_EHBlock__opaque> (e)->right = freeEHB; |
| freeEHB = static_cast<RTExceptions_EHBlock__opaque> (e); |
| return static_cast<RTExceptions_EHBlock> (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 (static_cast<RTExceptions_EHBlock__opaque> (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 (static_cast<RTExceptions_EHBlock__opaque> (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 (static_cast<RTExceptions_EHBlock__opaque> (e), number); |
| if (h != NULL) |
| { |
| /* remove, h, */ |
| SubHandler (h); |
| if (h->stack != NULL) |
| { |
| AddHandler (static_cast<RTExceptions_EHBlock__opaque> (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__opaque e; |
| int n; |
| |
| e = static_cast<RTExceptions_EHBlock__opaque> (RTExceptions_GetExceptionBlock ()); |
| n = static_cast<int> (libc_write (2, RTExceptions_GetTextBuffer (static_cast<RTExceptions_EHBlock> (e)), libc_strlen (RTExceptions_GetTextBuffer (static_cast<RTExceptions_EHBlock> (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<M2EXCEPTION_M2Exceptions>(static_cast<int>(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 static_cast<RTExceptions_EHBlock> (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 (); |
| } |