1 /* exceptions.h
2  *  Copyright (C) 2001-2010, Parrot Foundation.
3  *  Overview:
4  *     define the internal interpreter exceptions
5  *  Data Structure and Algorithms:
6  *  History:
7  *  Notes:
8  *  References:
9  */
10 
11 #ifndef PARROT_EXCEPTIONS_H_GUARD
12 #define PARROT_EXCEPTIONS_H_GUARD
13 
14 #include "parrot/compiler.h"
15 
16 /* Prototypes */
17 
18 /* Exception Types
19  * the first types are real exceptions and have Python exception
20  * names.
21  */
22 
23 /* &gen_from_enum(except_types.pasm) */
24 typedef enum {
25     EXCEPTION_BAD_BUFFER_SIZE = 0x00000,
26     EXCEPTION_MISSING_ENCODING_NAME,
27     EXCEPTION_INVALID_STRING_REPRESENTATION,
28     EXCEPTION_ICU_ERROR,
29     EXCEPTION_UNIMPLEMENTED,
30 
31     EXCEPTION_NULL_REG_ACCESS,
32     EXCEPTION_NO_REG_FRAMES,
33     EXCEPTION_SUBSTR_OUT_OF_STRING,
34     EXCEPTION_ORD_OUT_OF_STRING,
35     EXCEPTION_MALFORMED_UTF8,
36     EXCEPTION_MALFORMED_UTF16,
37     EXCEPTION_MALFORMED_UTF32,
38     EXCEPTION_INVALID_CHARACTER,
39     EXCEPTION_INVALID_CHARTYPE,
40     EXCEPTION_INVALID_ENCODING,
41     EXCEPTION_INVALID_CHARCLASS,
42     EXCEPTION_NEG_REPEAT,
43     EXCEPTION_NEG_SUBSTR,
44     EXCEPTION_NEG_SLEEP,
45     EXCEPTION_NEG_CHOP,
46     EXCEPTION_INVALID_OPERATION,
47     EXCEPTION_ARG_OP_NOT_HANDLED,
48     EXCEPTION_KEY_NOT_FOUND,
49     EXCEPTION_JIT_UNAVAILABLE,
50     EXCEPTION_EXEC_UNAVAILABLE,
51     EXCEPTION_INTERP_ERROR,
52     EXCEPTION_PARROT_USAGE_ERROR,
53     EXCEPTION_PIO_ERROR,
54     EXCEPTION_PARROT_POINTER_ERROR,
55     EXCEPTION_DIV_BY_ZERO,
56     EXCEPTION_PIO_NOT_IMPLEMENTED,
57     EXCEPTION_ALLOCATION_ERROR,
58     EXCEPTION_INTERNAL_PANIC,
59     EXCEPTION_OUT_OF_BOUNDS,
60     EXCEPTION_JIT_ERROR,
61     EXCEPTION_EXEC_ERROR,
62     EXCEPTION_ILL_INHERIT,
63     EXCEPTION_NO_PREV_CS,
64     EXCEPTION_NO_CLASS,
65     EXCEPTION_LEX_NOT_FOUND,
66     EXCEPTION_PAD_NOT_FOUND,
67     EXCEPTION_ATTRIB_NOT_FOUND,
68     EXCEPTION_GLOBAL_NOT_FOUND,
69     EXCEPTION_EXTERNAL_ERROR,
70     EXCEPTION_METHOD_NOT_FOUND,
71     EXCEPTION_VTABLE_NOT_FOUND,
72     EXCEPTION_WRITE_TO_CONSTCLASS,
73     EXCEPTION_NOSPAWN,
74     EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
75     EXCEPTION_ERR_OVERFLOW,
76     EXCEPTION_LOSSY_CONVERSION,
77     EXCEPTION_ROLE_COMPOSITION_METHOD_CONFLICT,
78     EXCEPTION_UNEXPECTED_NULL,
79     EXCEPTION_LIBRARY_ERROR,
80     EXCEPTION_LIBRARY_NOT_LOADED,
81     EXCEPTION_SYNTAX_ERROR,
82     EXCEPTION_MALFORMED_PACKFILE,
83     EXCEPTION_DIE,
84     EXCEPTION_ALL = 0x0ffff,
85 
86     CONTROL_RETURN = 0x10000,
87     CONTROL_OK,
88     CONTROL_BREAK,
89     CONTROL_CONTINUE,
90     CONTROL_ERROR,
91     CONTROL_TAKE,
92     CONTROL_LEAVE,
93     CONTROL_EXIT,
94     CONTROL_LOOP_NEXT,
95     CONTROL_LOOP_LAST,
96     CONTROL_LOOP_REDO,
97     CONTROL_ALL = 0x1ffff,
98 
99     EXCEPTION_TYPE_ALL_MASK = 0xffff
100 } exception_type_enum;
101 
102 /* &end_gen */
103 
104 /* &gen_from_enum(except_severity.pasm) subst(s/(\w+)/uc($1)/e) */
105 
106 typedef enum {
107     EXCEPT_normal  = 0,
108     EXCEPT_warning = 1,
109     EXCEPT_error   = 2,
110     EXCEPT_severe  = 3,
111     EXCEPT_fatal   = 4,
112     EXCEPT_doomed  = 5,
113     EXCEPT_exit    = 6
114 } exception_severity;
115 
116 /* &end_gen */
117 
118 /* HEADERIZER BEGIN: src/exceptions.c */
119 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
120 
121 PARROT_EXPORT
122 PARROT_DOES_NOT_RETURN_WHEN_FALSE
123 void Parrot_assert(
124     INTVAL condition,
125     ARGIN(const char *condition_string),
126     ARGIN(const char *file),
127     unsigned int line)
128         __attribute__nonnull__(2)
129         __attribute__nonnull__(3);
130 
131 PARROT_EXPORT
132 PARROT_DOES_NOT_RETURN
133 PARROT_COLD
134 void Parrot_confess(
135     ARGIN(const char *cond),
136     ARGIN(const char *file),
137     unsigned int line)
138         __attribute__nonnull__(1)
139         __attribute__nonnull__(2);
140 
141 PARROT_EXPORT
142 void Parrot_ex_add_c_handler(PARROT_INTERP, ARGIN(Parrot_runloop *jp))
143         __attribute__nonnull__(1)
144         __attribute__nonnull__(2);
145 
146 PARROT_EXPORT
147 PARROT_CANNOT_RETURN_NULL
148 PMC * Parrot_ex_build_exception(PARROT_INTERP,
149     INTVAL severity,
150     long error,
151     ARGIN_NULLOK(STRING *msg))
152         __attribute__nonnull__(1);
153 
154 PARROT_EXPORT
155 PARROT_WARN_UNUSED_RESULT
156 PARROT_CAN_RETURN_NULL
157 PMC * Parrot_ex_get_current_handler(PARROT_INTERP, ARGIN_NULLOK(PMC *expmc))
158         __attribute__nonnull__(1);
159 
160 PARROT_EXPORT
161 void Parrot_ex_mark_unhandled(PARROT_INTERP, ARGIN(PMC *exception))
162         __attribute__nonnull__(1)
163         __attribute__nonnull__(2);
164 
165 PARROT_EXPORT
166 PARROT_DOES_NOT_RETURN
167 PARROT_COLD
168 void Parrot_ex_rethrow_from_c(PARROT_INTERP, ARGIN(PMC *exception))
169         __attribute__nonnull__(1)
170         __attribute__nonnull__(2);
171 
172 PARROT_EXPORT
173 PARROT_WARN_UNUSED_RESULT
174 PARROT_CAN_RETURN_NULL
175 opcode_t * Parrot_ex_rethrow_from_op(PARROT_INTERP, ARGIN(PMC *exception))
176         __attribute__nonnull__(1)
177         __attribute__nonnull__(2);
178 
179 PARROT_EXPORT
180 PARROT_DOES_NOT_RETURN
181 PARROT_COLD
182 void Parrot_ex_throw_from_c(PARROT_INTERP, ARGIN(PMC *exception))
183         __attribute__nonnull__(1)
184         __attribute__nonnull__(2);
185 
186 PARROT_EXPORT
187 PARROT_DOES_NOT_RETURN
188 PARROT_COLD
189 void Parrot_ex_throw_from_c_args(PARROT_INTERP,
190     ARGIN_NULLOK(void *ret_addr),
191     int exitcode,
192     ARGIN(const char *format),
193     ...)
194         __attribute__nonnull__(1)
195         __attribute__nonnull__(4);
196 
197 PARROT_EXPORT
198 PARROT_DOES_NOT_RETURN
199 PARROT_COLD
200 void Parrot_ex_throw_from_c_noargs(PARROT_INTERP,
201     int exitcode,
202     ARGIN(const char *msg))
203         __attribute__nonnull__(1)
204         __attribute__nonnull__(3);
205 
206 PARROT_EXPORT
207 PARROT_CAN_RETURN_NULL
208 opcode_t * Parrot_ex_throw_from_op(PARROT_INTERP,
209     ARGIN(PMC *exception),
210     ARGIN_NULLOK(void *dest))
211         __attribute__nonnull__(1)
212         __attribute__nonnull__(2);
213 
214 PARROT_EXPORT
215 PARROT_CAN_RETURN_NULL
216 opcode_t * Parrot_ex_throw_from_op_args(PARROT_INTERP,
217     ARGIN_NULLOK(void *dest),
218     int ex_type,
219     ARGIN(const char *format),
220     ...)
221         __attribute__nonnull__(1)
222         __attribute__nonnull__(4);
223 
224 PARROT_DOES_NOT_RETURN
225 PARROT_COLD
226 void die_from_exception(PARROT_INTERP, ARGIN(PMC *exception))
227         __attribute__nonnull__(1)
228         __attribute__nonnull__(2);
229 
230 PARROT_CANNOT_RETURN_NULL
231 STRING * Parrot_ex_build_complete_backtrace_string(PARROT_INTERP,
232     ARGIN(PMC * ex))
233         __attribute__nonnull__(1)
234         __attribute__nonnull__(2);
235 
236 void Parrot_print_backtrace(void);
237 #define ASSERT_ARGS_Parrot_assert __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
238        PARROT_ASSERT_ARG(condition_string) \
239     , PARROT_ASSERT_ARG(file))
240 #define ASSERT_ARGS_Parrot_confess __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
241        PARROT_ASSERT_ARG(cond) \
242     , PARROT_ASSERT_ARG(file))
243 #define ASSERT_ARGS_Parrot_ex_add_c_handler __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
244        PARROT_ASSERT_ARG(interp) \
245     , PARROT_ASSERT_ARG(jp))
246 #define ASSERT_ARGS_Parrot_ex_build_exception __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
247        PARROT_ASSERT_ARG(interp))
248 #define ASSERT_ARGS_Parrot_ex_get_current_handler __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
249        PARROT_ASSERT_ARG(interp))
250 #define ASSERT_ARGS_Parrot_ex_mark_unhandled __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
251        PARROT_ASSERT_ARG(interp) \
252     , PARROT_ASSERT_ARG(exception))
253 #define ASSERT_ARGS_Parrot_ex_rethrow_from_c __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
254        PARROT_ASSERT_ARG(interp) \
255     , PARROT_ASSERT_ARG(exception))
256 #define ASSERT_ARGS_Parrot_ex_rethrow_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
257        PARROT_ASSERT_ARG(interp) \
258     , PARROT_ASSERT_ARG(exception))
259 #define ASSERT_ARGS_Parrot_ex_throw_from_c __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
260        PARROT_ASSERT_ARG(interp) \
261     , PARROT_ASSERT_ARG(exception))
262 #define ASSERT_ARGS_Parrot_ex_throw_from_c_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
263        PARROT_ASSERT_ARG(interp) \
264     , PARROT_ASSERT_ARG(format))
265 #define ASSERT_ARGS_Parrot_ex_throw_from_c_noargs __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
266        PARROT_ASSERT_ARG(interp) \
267     , PARROT_ASSERT_ARG(msg))
268 #define ASSERT_ARGS_Parrot_ex_throw_from_op __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
269        PARROT_ASSERT_ARG(interp) \
270     , PARROT_ASSERT_ARG(exception))
271 #define ASSERT_ARGS_Parrot_ex_throw_from_op_args __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
272        PARROT_ASSERT_ARG(interp) \
273     , PARROT_ASSERT_ARG(format))
274 #define ASSERT_ARGS_die_from_exception __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
275        PARROT_ASSERT_ARG(interp) \
276     , PARROT_ASSERT_ARG(exception))
277 #define ASSERT_ARGS_Parrot_ex_build_complete_backtrace_string \
278      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
279        PARROT_ASSERT_ARG(interp) \
280     , PARROT_ASSERT_ARG(ex))
281 #define ASSERT_ARGS_Parrot_print_backtrace __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
282 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
283 /* HEADERIZER END: src/exceptions.c */
284 
285 /* having a modified version of PARROT_ASSERT which resolves as an integer
286  * rvalue lets us put ASSERT_ARGS() at the top of the list of local variables.
287  * Thus, we can catch bad pointers before any of the local initialization
288  * logic is run.  And it always returns 0, so headerizer can chain them in
289  * ASSERT_ARGS_* macros like:
290  * int _ASSERT_ARGS = PARROT_ASSERT_ARG(a) || PARROT_ASSERT_ARG(b) || ...
291  */
292 #ifdef NDEBUG
293 #  define PARROT_ASSERT(x) /*@-noeffect@*/((void)0)/*@=noeffect@*/
294 #  define PARROT_ASSERT_ARG(x) (0)
295 #  define PARROT_FAILURE(x) /*@-noeffect@*/((void)0)/*@=noeffect@*/
296 #  define PARROT_ASSERT_MSG(x, s) /*@-noeffect@*/((void)0)/*@=noeffect@*/
297 #  define ASSERT_ARGS(a)
298 #else
299 #  define PARROT_ASSERT(x) (x) ? ((void)0) : Parrot_confess(#x, __FILE__, __LINE__)
300 #  define PARROT_ASSERT_ARG(x) ((x) ? (0) : (Parrot_confess(#x, __FILE__, __LINE__), 0))
301 #  define PARROT_FAILURE(x) Parrot_confess((x), __FILE__, __LINE__)
302 #  define PARROT_ASSERT_MSG(x, s) ((x) ? (0) : (Parrot_confess(s, __FILE__, __LINE__), 0))
303 
304 #  ifdef __GNUC__
305 #    define ASSERT_ARGS(a) ASSERT_ARGS_ ## a ;
306 #  else
307 #    define ASSERT_ARGS(a)
308 #  endif /* __GNUC__ */
309 
310 #endif /* NDEBUG */
311 
312 #endif /* PARROT_EXCEPTIONS_H_GUARD */
313 
314 /*
315  * Local variables:
316  *   c-file-style: "parrot"
317  * End:
318  * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
319  */
320