]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | /* |
2 | * Error handling macros, assertion macro, error codes. | |
3 | * | |
4 | * There are three level of 'errors': | |
5 | * | |
6 | * 1. Ordinary errors, relative to a thread, cause a longjmp, catchable. | |
7 | * 2. Fatal errors, relative to a heap, cause fatal handler to be called. | |
8 | * 3. Panic errors, unrelated to a heap and cause a process exit. | |
9 | * | |
10 | * Panics are used by the default fatal error handler and by debug code | |
11 | * such as assertions. By providing a proper fatal error handler, user | |
12 | * code can avoid panics in non-debug builds. | |
13 | */ | |
14 | ||
15 | #ifndef DUK_ERROR_H_INCLUDED | |
16 | #define DUK_ERROR_H_INCLUDED | |
17 | ||
18 | /* | |
19 | * Error codes: defined in duktape.h | |
20 | * | |
21 | * Error codes are used as a shorthand to throw exceptions from inside | |
22 | * the implementation. The appropriate Ecmascript object is constructed | |
23 | * based on the code. Ecmascript code throws objects directly. The error | |
24 | * codes are defined in the public API header because they are also used | |
25 | * by calling code. | |
26 | */ | |
27 | ||
28 | /* | |
29 | * Normal error | |
30 | * | |
31 | * Normal error is thrown with a longjmp() through the current setjmp() | |
32 | * catchpoint record in the duk_heap. The 'curr_thread' of the duk_heap | |
33 | * identifies the throwing thread. | |
34 | * | |
35 | * Error formatting is usually unnecessary. The error macros provide a | |
36 | * zero argument version (no formatting) and separate macros for small | |
37 | * argument counts. Variadic macros are not used to avoid portability | |
38 | * issues and avoid the need for stash-based workarounds when they're not | |
39 | * available. Vararg calls are avoided for non-formatted error calls | |
40 | * because vararg call sites are larger than normal, and there are a lot | |
41 | * of call sites with no formatting. | |
42 | * | |
43 | * Note that special formatting provided by debug macros is NOT available. | |
44 | * | |
45 | * The _RAW variants allow the caller to specify file and line. This makes | |
46 | * it easier to write checked calls which want to use the call site of the | |
47 | * checked function, not the error macro call inside the checked function. | |
48 | */ | |
49 | ||
50 | #if defined(DUK_USE_VERBOSE_ERRORS) | |
51 | ||
52 | /* Because there are quite many call sites, pack error code (require at most | |
53 | * 8-bit) into a single argument. | |
54 | */ | |
55 | #define DUK_ERROR(thr,err,msg) do { \ | |
56 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ | |
57 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
58 | duk_err_handle_error((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \ | |
59 | } while (0) | |
60 | #define DUK_ERROR_RAW(thr,file,line,err,msg) do { \ | |
61 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ | |
62 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
63 | duk_err_handle_error((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \ | |
64 | } while (0) | |
65 | ||
66 | #define DUK_ERROR_FMT1(thr,err,fmt,arg1) do { \ | |
67 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ | |
68 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
69 | duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \ | |
70 | } while (0) | |
71 | #define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) do { \ | |
72 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ | |
73 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
74 | duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \ | |
75 | } while (0) | |
76 | ||
77 | #define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) do { \ | |
78 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ | |
79 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
80 | duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \ | |
81 | } while (0) | |
82 | #define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) do { \ | |
83 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ | |
84 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
85 | duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \ | |
86 | } while (0) | |
87 | ||
88 | #define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) do { \ | |
89 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ | |
90 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
91 | duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \ | |
92 | } while (0) | |
93 | #define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) do { \ | |
94 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ | |
95 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
96 | duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \ | |
97 | } while (0) | |
98 | ||
99 | #define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) do { \ | |
100 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \ | |
101 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
102 | duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \ | |
103 | } while (0) | |
104 | #define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) do { \ | |
105 | duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \ | |
106 | DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \ | |
107 | duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \ | |
108 | } while (0) | |
109 | ||
110 | #else /* DUK_USE_VERBOSE_ERRORS */ | |
111 | ||
112 | #define DUK_ERROR(thr,err,msg) duk_err_handle_error((thr), (err)) | |
113 | #define DUK_ERROR_RAW(thr,file,line,err,msg) duk_err_handle_error((thr), (err)) | |
114 | ||
115 | #define DUK_ERROR_FMT1(thr,err,fmt,arg1) DUK_ERROR((thr),(err),(fmt)) | |
116 | #define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt)) | |
117 | ||
118 | #define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) DUK_ERROR((thr),(err),(fmt)) | |
119 | #define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt)) | |
120 | ||
121 | #define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) DUK_ERROR((thr),(err),(fmt)) | |
122 | #define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt)) | |
123 | ||
124 | #define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR((thr),(err),(fmt)) | |
125 | #define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt)) | |
126 | ||
127 | #endif /* DUK_USE_VERBOSE_ERRORS */ | |
128 | ||
129 | /* | |
130 | * Fatal error | |
131 | * | |
132 | * There are no fatal error macros at the moment. There are so few call | |
133 | * sites that the fatal error handler is called directly. | |
134 | */ | |
135 | ||
136 | /* | |
137 | * Panic error | |
138 | * | |
139 | * Panic errors are not relative to either a heap or a thread, and cause | |
140 | * DUK_PANIC() macro to be invoked. Unless a user provides DUK_USE_PANIC_HANDLER, | |
141 | * DUK_PANIC() calls a helper which prints out the error and causes a process | |
142 | * exit. | |
143 | * | |
144 | * The user can override the macro to provide custom handling. A macro is | |
145 | * used to allow the user to have inline panic handling if desired (without | |
146 | * causing a potentially risky function call). | |
147 | * | |
148 | * Panics are only used in debug code such as assertions, and by the default | |
149 | * fatal error handler. | |
150 | */ | |
151 | ||
152 | #if defined(DUK_USE_PANIC_HANDLER) | |
153 | /* already defined, good */ | |
154 | #define DUK_PANIC(code,msg) DUK_USE_PANIC_HANDLER((code),(msg)) | |
155 | #else | |
156 | #define DUK_PANIC(code,msg) duk_default_panic_handler((code),(msg)) | |
157 | #endif /* DUK_USE_PANIC_HANDLER */ | |
158 | ||
159 | /* | |
160 | * Assert macro: failure causes panic. | |
161 | */ | |
162 | ||
163 | #if defined(DUK_USE_ASSERTIONS) | |
164 | ||
165 | /* the message should be a compile time constant without formatting (less risk); | |
166 | * we don't care about assertion text size because they're not used in production | |
167 | * builds. | |
168 | */ | |
169 | #define DUK_ASSERT(x) do { \ | |
170 | if (!(x)) { \ | |
171 | DUK_PANIC(DUK_ERR_ASSERTION_ERROR, \ | |
172 | "assertion failed: " #x \ | |
173 | " (" DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"); \ | |
174 | } \ | |
175 | } while (0) | |
176 | ||
177 | /* Assertion compatible inside a comma expression, evaluates to void. | |
178 | * Currently not compatible with DUK_USE_PANIC_HANDLER() which may have | |
179 | * a statement block. | |
180 | */ | |
181 | #if defined(DUK_USE_PANIC_HANDLER) | |
182 | /* XXX: resolve macro definition issue or call through a helper function? */ | |
183 | #define DUK_ASSERT_EXPR(x) ((void) 0) | |
184 | #else | |
185 | #define DUK_ASSERT_EXPR(x) \ | |
186 | ((void) ((x) ? 0 : (DUK_PANIC(DUK_ERR_ASSERTION_ERROR, \ | |
187 | "assertion failed: " #x \ | |
188 | " (" DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"), 0))) | |
189 | #endif | |
190 | ||
191 | #else /* DUK_USE_ASSERTIONS */ | |
192 | ||
193 | #define DUK_ASSERT(x) do { /* assertion omitted */ } while (0) | |
194 | ||
195 | #define DUK_ASSERT_EXPR(x) ((void) 0) | |
196 | ||
197 | #endif /* DUK_USE_ASSERTIONS */ | |
198 | ||
199 | /* this variant is used when an assert would generate a compile warning by | |
200 | * being always true (e.g. >= 0 comparison for an unsigned value | |
201 | */ | |
202 | #define DUK_ASSERT_DISABLE(x) do { /* assertion disabled */ } while (0) | |
203 | ||
204 | /* | |
205 | * Assertion helpers | |
206 | */ | |
207 | ||
208 | #if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING) | |
209 | #define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h) do { \ | |
210 | DUK_ASSERT((h) == NULL || DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) (h)) > 0); \ | |
211 | } while (0) | |
212 | #define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv) do { \ | |
213 | if ((tv) != NULL && DUK_TVAL_IS_HEAP_ALLOCATED((tv))) { \ | |
214 | DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(DUK_TVAL_GET_HEAPHDR((tv))) > 0); \ | |
215 | } \ | |
216 | } while (0) | |
217 | #else | |
218 | #define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h) /* no refcount check */ | |
219 | #define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv) /* no refcount check */ | |
220 | #endif | |
221 | ||
222 | #define DUK_ASSERT_TOP(ctx,n) DUK_ASSERT((duk_idx_t) duk_get_top((ctx)) == (duk_idx_t) (n)) | |
223 | ||
224 | #if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_PACKED_TVAL) | |
225 | #define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) do { \ | |
226 | duk_double_union duk__assert_tmp_du; \ | |
227 | duk__assert_tmp_du.d = (dval); \ | |
228 | DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&duk__assert_tmp_du)); \ | |
229 | } while (0) | |
230 | #else | |
231 | #define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) /* nop */ | |
232 | #endif | |
233 | ||
234 | /* | |
235 | * Helper for valstack space | |
236 | * | |
237 | * Caller of DUK_ASSERT_VALSTACK_SPACE() estimates the number of free stack entries | |
238 | * required for its own use, and any child calls which are not (a) Duktape API calls | |
239 | * or (b) Duktape calls which involve extending the valstack (e.g. getter call). | |
240 | */ | |
241 | ||
242 | #define DUK_VALSTACK_ASSERT_EXTRA 5 /* this is added to checks to allow for Duktape | |
243 | * API calls in addition to function's own use | |
244 | */ | |
245 | #if defined(DUK_USE_ASSERTIONS) | |
246 | #define DUK_ASSERT_VALSTACK_SPACE(thr,n) do { \ | |
247 | DUK_ASSERT((thr) != NULL); \ | |
248 | DUK_ASSERT((thr)->valstack_end - (thr)->valstack_top >= (n) + DUK_VALSTACK_ASSERT_EXTRA); \ | |
249 | } while (0) | |
250 | #else | |
251 | #define DUK_ASSERT_VALSTACK_SPACE(thr,n) /* no valstack space check */ | |
252 | #endif | |
253 | ||
254 | /* | |
255 | * Error throwing helpers | |
256 | * | |
257 | * The goal is to provide verbose and configurable error messages. Call | |
258 | * sites should be clean in source code and compile to a small footprint. | |
259 | * Small footprint is also useful for performance because small cold paths | |
260 | * reduce code cache pressure. Adding macros here only makes sense if there | |
261 | * are enough call sites to get concrete benefits. | |
262 | */ | |
263 | ||
264 | #if defined(DUK_USE_VERBOSE_ERRORS) | |
265 | /* Verbose errors with key/value summaries (non-paranoid) or without key/value | |
266 | * summaries (paranoid, for some security sensitive environments), the paranoid | |
267 | * vs. non-paranoid distinction affects only a few specific errors. | |
268 | */ | |
269 | #if defined(DUK_USE_PARANOID_ERRORS) | |
270 | #define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,index,expectname,lowmemstr) do { \ | |
271 | duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (index), (expectname)); \ | |
272 | } while (0) | |
273 | #else /* DUK_USE_PARANOID_ERRORS */ | |
274 | #define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,index,expectname,lowmemstr) do { \ | |
275 | duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (index), (expectname)); \ | |
276 | } while (0) | |
277 | #endif /* DUK_USE_PARANOID_ERRORS */ | |
278 | ||
279 | #define DUK_ERROR_UNIMPLEMENTED(thr,msg) do { \ | |
280 | DUK_ERROR((thr), DUK_ERR_UNIMPLEMENTED_ERROR, (msg)); \ | |
281 | } while (0) | |
282 | #define DUK_ERROR_UNIMPLEMENTED_DEFMSG(thr) do { \ | |
283 | duk_err_unimplemented_defmsg((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ | |
284 | } while (0) | |
285 | #define DUK_ERROR_UNSUPPORTED(thr,msg) do { \ | |
286 | DUK_ERROR((thr), DUK_ERR_UNSUPPORTED_ERROR, (msg)); \ | |
287 | } while (0) | |
288 | #if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT) | |
289 | #define DUK_ERROR_UNSUPPORTED_DEFMSG(thr) do { \ | |
290 | duk_err_unsupported_defmsg((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ | |
291 | } while (0) | |
292 | #endif | |
293 | #define DUK_ERROR_INTERNAL(thr,msg) do { \ | |
294 | duk_err_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ | |
295 | } while (0) | |
296 | #define DUK_ERROR_INTERNAL_DEFMSG(thr) do { \ | |
297 | duk_err_internal_defmsg((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \ | |
298 | } while (0) | |
299 | #define DUK_ERROR_ALLOC(thr,msg) do { \ | |
300 | duk_err_alloc((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ | |
301 | } while (0) | |
302 | #define DUK_ERROR_ALLOC_DEFMSG(thr) do { \ | |
303 | DUK_ERROR_ALLOC((thr), DUK_STR_ALLOC_FAILED); \ | |
304 | } while (0) | |
305 | /* DUK_ERR_ASSERTION_ERROR: no macros needed */ | |
306 | #define DUK_ERROR_API_INDEX(thr,index) do { \ | |
307 | duk_err_api_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (index)); \ | |
308 | } while (0) | |
309 | #define DUK_ERROR_API(thr,msg) do { \ | |
310 | duk_err_api((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ | |
311 | } while (0) | |
312 | /* DUK_ERR_UNCAUGHT_ERROR: no macros needed */ | |
313 | /* DUK_ERR_ERROR: no macros needed */ | |
314 | /* DUK_ERR_EVAL: no macros needed */ | |
315 | #define DUK_ERROR_RANGE(thr,msg) do { \ | |
316 | duk_err_range((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \ | |
317 | } while (0) | |
318 | /* DUK_ERR_REFERENCE_ERROR: no macros needed */ | |
319 | #define DUK_ERROR_SYNTAX(thr,msg) do { \ | |
320 | DUK_ERROR((thr), DUK_ERR_SYNTAX_ERROR, (msg)); \ | |
321 | } while (0) | |
322 | #define DUK_ERROR_TYPE(thr,msg) do { \ | |
323 | DUK_ERROR((thr), DUK_ERR_TYPE_ERROR, (msg)); \ | |
324 | } while (0) | |
325 | /* DUK_ERR_URI_ERROR: no macros needed */ | |
326 | #else /* DUK_USE_VERBOSE_ERRORS */ | |
327 | /* Non-verbose errors for low memory targets: no file, line, or message. */ | |
328 | ||
329 | #define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,index,expectname,lowmemstr) do { \ | |
330 | duk_err_type((thr)); \ | |
331 | } while (0) | |
332 | ||
333 | #define DUK_ERROR_UNIMPLEMENTED(thr,msg) do { \ | |
334 | duk_err_unimplemented((thr)); \ | |
335 | } while (0) | |
336 | #define DUK_ERROR_UNIMPLEMENTED_DEFMSG(thr) do { \ | |
337 | duk_err_unimplemented((thr)); \ | |
338 | } while (0) | |
339 | #define DUK_ERROR_UNSUPPORTED(thr,msg) do { \ | |
340 | duk_err_unsupported((thr)); \ | |
341 | } while (0) | |
342 | #define DUK_ERROR_UNSUPPORTED_DEFMSG(thr) do { \ | |
343 | duk_err_unsupported((thr)); \ | |
344 | } while (0) | |
345 | #define DUK_ERROR_INTERNAL(thr,msg) do { \ | |
346 | duk_err_internal((thr)); \ | |
347 | } while (0) | |
348 | #define DUK_ERROR_INTERNAL_DEFMSG(thr) do { \ | |
349 | duk_err_internal((thr)); \ | |
350 | } while (0) | |
351 | #define DUK_ERROR_ALLOC(thr,msg) do { \ | |
352 | duk_err_alloc((thr)); \ | |
353 | } while (0) | |
354 | #define DUK_ERROR_ALLOC_DEFMSG(thr) do { \ | |
355 | duk_err_alloc((thr)); \ | |
356 | } while (0) | |
357 | #define DUK_ERROR_API_INDEX(thr,index) do { \ | |
358 | duk_err_api((thr)); \ | |
359 | } while (0) | |
360 | #define DUK_ERROR_API(thr,msg) do { \ | |
361 | duk_err_api((thr)); \ | |
362 | } while (0) | |
363 | #define DUK_ERROR_RANGE(thr,msg) do { \ | |
364 | duk_err_range((thr)); \ | |
365 | } while (0) | |
366 | #define DUK_ERROR_SYNTAX(thr,msg) do { \ | |
367 | duk_err_syntax((thr)); \ | |
368 | } while (0) | |
369 | #define DUK_ERROR_TYPE(thr,msg) do { \ | |
370 | duk_err_type((thr)); \ | |
371 | } while (0) | |
372 | #endif /* DUK_USE_VERBOSE_ERRORS */ | |
373 | ||
374 | /* | |
375 | * Prototypes | |
376 | */ | |
377 | ||
378 | #if defined(DUK_USE_VERBOSE_ERRORS) | |
379 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg)); | |
380 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...)); | |
381 | #else /* DUK_USE_VERBOSE_ERRORS */ | |
382 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code)); | |
383 | #endif /* DUK_USE_VERBOSE_ERRORS */ | |
384 | ||
385 | #if defined(DUK_USE_VERBOSE_ERRORS) | |
386 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line)); | |
387 | #else | |
388 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)); | |
389 | #endif | |
390 | ||
391 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc)); | |
392 | ||
393 | #if defined(DUK_USE_AUGMENT_ERROR_CREATE) | |
394 | DUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_bool_t noblame_fileline); | |
395 | #endif | |
396 | #if defined(DUK_USE_AUGMENT_ERROR_THROW) | |
397 | DUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr); | |
398 | #endif | |
399 | ||
400 | #if defined(DUK_USE_VERBOSE_ERRORS) | |
401 | #if defined(DUK_USE_PARANOID_ERRORS) | |
402 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t index, const char *expect_name)); | |
403 | #else | |
404 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t index, const char *expect_name)); | |
405 | #endif | |
406 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_api_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t index)); | |
407 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_api(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); | |
408 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); | |
409 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unimplemented_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber)); | |
410 | #if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT) | |
411 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unsupported_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber)); | |
412 | #endif | |
413 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_internal_defmsg(duk_hthread *thr, const char *filename, duk_int_t linenumber)); | |
414 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); | |
415 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_alloc(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message)); | |
416 | #else /* DUK_VERBOSE_ERRORS */ | |
417 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr)); | |
418 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_syntax(duk_hthread *thr)); | |
419 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type(duk_hthread *thr)); | |
420 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_api(duk_hthread *thr)); | |
421 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unimplemented(duk_hthread *thr)); | |
422 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_unsupported(duk_hthread *thr)); | |
423 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_internal(duk_hthread *thr)); | |
424 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_alloc(duk_hthread *thr)); | |
425 | #endif /* DUK_VERBOSE_ERRORS */ | |
426 | ||
427 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_longjmp(duk_hthread *thr)); | |
428 | ||
429 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_default_fatal_handler(duk_context *ctx, duk_errcode_t code, const char *msg)); | |
430 | ||
431 | #if !defined(DUK_USE_PANIC_HANDLER) | |
432 | DUK_NORETURN(DUK_INTERNAL_DECL void duk_default_panic_handler(duk_errcode_t code, const char *msg)); | |
433 | #endif | |
434 | ||
435 | DUK_INTERNAL_DECL void duk_err_setup_heap_ljstate(duk_hthread *thr, duk_small_int_t lj_type); | |
436 | ||
437 | DUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t err_code); | |
438 | ||
439 | #endif /* DUK_ERROR_H_INCLUDED */ |