allgmem.c: Do not include config.h anymore.
[gcc.git] / libchill / exh.c
1 /* Implement runtime actions for CHILL.
2 Copyright (C) 1992,1993 Free Software Foundation, Inc.
3 Author: Wilfried Moser
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #define __CHILL_LIB__
22
23 #include <stdio.h>
24 #include <setjmp.h>
25 #include "rtltypes.h"
26
27 extern void cause_exception (char *exname, char *file, int lineno, int user_arg);
28 extern void unhandled_exception (char *exname, char *file, int lineno, int user_arg);
29
30 /* An action with a handler:
31 BODY ON (e1, e2): H12; (e3): H3; ELSE HE; END;
32 is translated into:
33
34 struct __ch_handler __tmp;
35 static struct __ch_handler_excepts _H[4] =
36 {
37 { <<e1>>, 1 },
38 { <<e2>>, 1 },
39 { <<e3>>, 2 },
40 { __ch_else_except, 3 },
41 };
42 __ch_link_handler(&__tmp);
43 __tmp.handlers = _H;
44 switch (setmp(&__tmp.jbuf))
45 {
46 case 0: BODY; __ch_unlink_handler(&__tmp); break;
47 case 1: H12; break;
48 case 2: H3; break;
49 case 3: HE; break;
50 }
51 */
52
53 /* this part contains all neccessary functions to handle exceptions in CHILL */
54
55 /* These two trivial function aren't inlines, to allow for
56 more flexibility (e.g. a per-thread exception stack). */
57
58 extern void __setexceptionStack (TExceptionHandlerStack *new);
59 extern TExceptionHandlerStack * __getexceptionStack (void);
60
61 void
62 __ch_link_handler (handler)
63 struct __ch_handler *handler;
64 {
65 handler->prev = __getexceptionStack ();
66 __setexceptionStack (handler);
67 }
68
69 void
70 __ch_unlink_handler (handler)
71 struct __ch_handler *handler;
72 {
73 __setexceptionStack (handler->prev);
74 }
75
76 /*
77 * function __cause_exception
78 *
79 * parameters:
80 * exnum name string of exception to raise
81 * file filename of CAUSE statement
82 * lineno linenumber of CAUSE statement
83 * user_arg user specified argument
84 *
85 * returns:
86 * never leave function with longjmp or abort
87 *
88 * abstract:
89 * search exceptionstack for last handler of caused exception,
90 * call userdefined function to signal exception,
91 * jump to handler with longjmp or call unhandled_exception
92 *
93 */
94
95 void
96 __cause_exception (ex, file, lineno, user_arg)
97 char *ex;
98 char *file;
99 int lineno;
100 int user_arg;
101 {
102 register struct __ch_handler *handler = __getexceptionStack();
103
104 /* call user defined cause function */
105 cause_exception (ex, file, lineno, user_arg);
106
107 for ( ; handler != NULL; handler = handler->prev)
108 {
109 register struct __ch_handled_excepts *list = handler->handlers;
110 for ( ; list->code != 0; list++ )
111 {
112 if (list->ex == __ch_else_except || EX_EQ(list->ex, ex)) /* found */
113 {
114 __setexceptionStack (handler->prev);
115 longjmp(handler->jbuf, list->code);
116 }
117 }
118 }
119
120 /* no handler found -- call unhandled_exception */
121 unhandled_exception (ex, file, lineno, user_arg);
122 abort ();
123 }
124
125 /*
126 * function __cause_ex1
127 *
128 * parameters:
129 * exnum name string of exception to raise
130 * file filename of CAUSE statement
131 * lineno linenumber of CAUSE statement
132 *
133 * returns:
134 * never leave function with longjmp or abort
135 *
136 * abstract:
137 * This is the function the compiler generated code calls.
138 * Search exceptionstack for last handler of caused exception,
139 * call userdefined function to signal exception,
140 * jump to handler with longjmp or call unhandled_exception
141 *
142 */
143
144 void
145 __cause_ex1 (ex, file, lineno)
146 char *ex;
147 char *file;
148 int lineno;
149 {
150 __cause_exception (ex, file, lineno, 0);
151 }