2 * Error, fatal, and panic handling.
5 #include "duk_internal.h"
7 #define DUK__ERRFMT_BUFSIZE 256 /* size for formatting buffers */
9 #if defined(DUK_USE_VERBOSE_ERRORS)
11 DUK_INTERNAL
void duk_err_handle_error_fmt(duk_hthread
*thr
, const char *filename
, duk_uint_t line_and_code
, const char *fmt
, ...) {
13 char msg
[DUK__ERRFMT_BUFSIZE
];
15 (void) DUK_VSNPRINTF(msg
, sizeof(msg
), fmt
, ap
);
16 msg
[sizeof(msg
) - 1] = (char) 0;
17 duk_err_create_and_throw(thr
, (duk_errcode_t
) (line_and_code
>> 24), msg
, filename
, (duk_int_t
) (line_and_code
& 0x00ffffffL
));
18 va_end(ap
); /* dead code, but ensures portability (see Linux man page notes) */
21 DUK_INTERNAL
void duk_err_handle_error(duk_hthread
*thr
, const char *filename
, duk_uint_t line_and_code
, const char *msg
) {
22 duk_err_create_and_throw(thr
, (duk_errcode_t
) (line_and_code
>> 24), msg
, filename
, (duk_int_t
) (line_and_code
& 0x00ffffffL
));
25 #else /* DUK_USE_VERBOSE_ERRORS */
27 DUK_INTERNAL
void duk_err_handle_error(duk_hthread
*thr
, duk_errcode_t code
) {
28 duk_err_create_and_throw(thr
, code
);
31 #endif /* DUK_USE_VERBOSE_ERRORS */
34 * Error throwing helpers
37 #if defined(DUK_USE_VERBOSE_ERRORS)
38 #if defined(DUK_USE_PARANOID_ERRORS)
39 DUK_INTERNAL
void duk_err_require_type_index(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
, duk_idx_t index
, const char *expect_name
) {
40 DUK_ERROR_RAW_FMT3(thr
, filename
, linenumber
, DUK_ERR_TYPE_ERROR
, "%s required, found %s (stack index %ld)",
41 expect_name
, duk_get_type_name((duk_context
*) thr
, index
), (long) index
);
44 DUK_INTERNAL
void duk_err_require_type_index(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
, duk_idx_t index
, const char *expect_name
) {
45 DUK_ERROR_RAW_FMT3(thr
, filename
, linenumber
, DUK_ERR_TYPE_ERROR
, "%s required, found %s (stack index %ld)",
46 expect_name
, duk_push_string_readable((duk_context
*) thr
, index
), (long) index
);
49 DUK_INTERNAL
void duk_err_range(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
, const char *message
) {
50 DUK_ERROR_RAW(thr
, filename
, linenumber
, DUK_ERR_RANGE_ERROR
, message
);
52 DUK_INTERNAL
void duk_err_api_index(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
, duk_idx_t index
) {
53 DUK_ERROR_RAW_FMT1(thr
, filename
, linenumber
, DUK_ERR_API_ERROR
, "invalid stack index %ld", (long) (index
));
55 DUK_INTERNAL
void duk_err_api(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
, const char *message
) {
56 DUK_ERROR_RAW(thr
, filename
, linenumber
, DUK_ERR_API_ERROR
, message
);
58 DUK_INTERNAL
void duk_err_unimplemented_defmsg(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
) {
59 DUK_ERROR_RAW(thr
, filename
, linenumber
, DUK_ERR_UNIMPLEMENTED_ERROR
, DUK_STR_UNIMPLEMENTED
);
61 #if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT)
62 DUK_INTERNAL
void duk_err_unsupported_defmsg(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
) {
63 DUK_ERROR_RAW(thr
, filename
, linenumber
, DUK_ERR_UNSUPPORTED_ERROR
, DUK_STR_UNSUPPORTED
);
66 DUK_INTERNAL
void duk_err_internal_defmsg(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
) {
67 DUK_ERROR_RAW(thr
, filename
, linenumber
, DUK_ERR_INTERNAL_ERROR
, DUK_STR_INTERNAL_ERROR
);
69 DUK_INTERNAL
void duk_err_internal(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
, const char *message
) {
70 DUK_ERROR_RAW(thr
, filename
, linenumber
, DUK_ERR_INTERNAL_ERROR
, message
);
72 DUK_INTERNAL
void duk_err_alloc(duk_hthread
*thr
, const char *filename
, duk_int_t linenumber
, const char *message
) {
73 DUK_ERROR_RAW(thr
, filename
, linenumber
, DUK_ERR_ALLOC_ERROR
, message
);
76 /* The file/line arguments are NULL and 0, they're ignored by DUK_ERROR_RAW()
77 * when non-verbose errors are used.
79 DUK_INTERNAL
void duk_err_type(duk_hthread
*thr
) {
80 DUK_ERROR_RAW(thr
, NULL
, 0, DUK_ERR_TYPE_ERROR
, NULL
);
82 DUK_INTERNAL
void duk_err_api(duk_hthread
*thr
) {
83 DUK_ERROR_RAW(thr
, NULL
, 0, DUK_ERR_API_ERROR
, NULL
);
85 DUK_INTERNAL
void duk_err_range(duk_hthread
*thr
) {
86 DUK_ERROR_RAW(thr
, NULL
, 0, DUK_ERR_RANGE_ERROR
, NULL
);
88 DUK_INTERNAL
void duk_err_syntax(duk_hthread
*thr
) {
89 DUK_ERROR_RAW(thr
, NULL
, 0, DUK_ERR_SYNTAX_ERROR
, NULL
);
91 DUK_INTERNAL
void duk_err_unimplemented(duk_hthread
*thr
) {
92 DUK_ERROR_RAW(thr
, NULL
, 0, DUK_ERR_UNIMPLEMENTED_ERROR
, NULL
);
94 DUK_INTERNAL
void duk_err_unsupported(duk_hthread
*thr
) {
95 DUK_ERROR_RAW(thr
, NULL
, 0, DUK_ERR_UNSUPPORTED_ERROR
, NULL
);
97 DUK_INTERNAL
void duk_err_internal(duk_hthread
*thr
) {
98 DUK_ERROR_RAW(thr
, NULL
, 0, DUK_ERR_INTERNAL_ERROR
, NULL
);
100 DUK_INTERNAL
void duk_err_alloc(duk_hthread
*thr
) {
101 DUK_ERROR_RAW(thr
, NULL
, thr
, DUK_ERR_ALLOC_ERROR
, NULL
);
106 * Default fatal error handler
109 DUK_INTERNAL
void duk_default_fatal_handler(duk_context
*ctx
, duk_errcode_t code
, const char *msg
) {
111 #if defined(DUK_USE_FILE_IO)
112 DUK_FPRINTF(DUK_STDERR
, "FATAL %ld: %s\n", (long) code
, (const char *) (msg
? msg
: "null"));
113 DUK_FFLUSH(DUK_STDERR
);
117 DUK_D(DUK_DPRINT("default fatal handler called, code %ld -> calling DUK_PANIC()", (long) code
));
118 DUK_PANIC(code
, msg
);
123 * Default panic handler
126 #if !defined(DUK_USE_PANIC_HANDLER)
127 DUK_INTERNAL
void duk_default_panic_handler(duk_errcode_t code
, const char *msg
) {
128 #if defined(DUK_USE_FILE_IO)
129 DUK_FPRINTF(DUK_STDERR
, "PANIC %ld: %s ("
130 #if defined(DUK_USE_PANIC_ABORT)
132 #elif defined(DUK_USE_PANIC_EXIT)
134 #elif defined(DUK_USE_PANIC_SEGFAULT)
135 "segfaulting on purpose"
137 #error no DUK_USE_PANIC_xxx macro defined
139 ")\n", (long) code
, (const char *) (msg
? msg
: "null"));
140 DUK_FFLUSH(DUK_STDERR
);
147 #if defined(DUK_USE_PANIC_ABORT)
149 #elif defined(DUK_USE_PANIC_EXIT)
151 #elif defined(DUK_USE_PANIC_SEGFAULT)
152 /* exit() afterwards to satisfy "noreturn" */
153 DUK_CAUSE_SEGFAULT(); /* SCANBUILD: "Dereference of null pointer", normal */
156 #error no DUK_USE_PANIC_xxx macro defined
161 #endif /* !DUK_USE_PANIC_HANDLER */
163 #undef DUK__ERRFMT_BUFSIZE