1 /*
2 * Error, fatal, and panic handling.
3 */
4
5 #include "duk_internal.h"
6
7 #define DUK__ERRFMT_BUFSIZE 256 /* size for formatting buffers */
8
9 #if defined(DUK_USE_VERBOSE_ERRORS)
10
duk_err_handle_error_fmt(duk_hthread * thr,const char * filename,duk_uint_t line_and_code,const char * fmt,...)11 DUK_INTERNAL void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...) {
12 va_list ap;
13 char msg[DUK__ERRFMT_BUFSIZE];
14 va_start(ap, fmt);
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) */
19 }
20
duk_err_handle_error(duk_hthread * thr,const char * filename,duk_uint_t line_and_code,const char * msg)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));
23 }
24
25 #else /* DUK_USE_VERBOSE_ERRORS */
26
duk_err_handle_error(duk_hthread * thr,duk_errcode_t code)27 DUK_INTERNAL void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code) {
28 duk_err_create_and_throw(thr, code);
29 }
30
31 #endif /* DUK_USE_VERBOSE_ERRORS */
32
33 /*
34 * Error throwing helpers
35 */
36
37 #if defined(DUK_USE_VERBOSE_ERRORS)
38 #if defined(DUK_USE_PARANOID_ERRORS)
duk_err_require_type_index(duk_hthread * thr,const char * filename,duk_int_t linenumber,duk_idx_t index,const char * expect_name)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);
42 }
43 #else
duk_err_require_type_index(duk_hthread * thr,const char * filename,duk_int_t linenumber,duk_idx_t index,const char * expect_name)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);
47 }
48 #endif
duk_err_range(duk_hthread * thr,const char * filename,duk_int_t linenumber,const char * message)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);
51 }
duk_err_api_index(duk_hthread * thr,const char * filename,duk_int_t linenumber,duk_idx_t index)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));
54 }
duk_err_api(duk_hthread * thr,const char * filename,duk_int_t linenumber,const char * message)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);
57 }
duk_err_unimplemented_defmsg(duk_hthread * thr,const char * filename,duk_int_t linenumber)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);
60 }
61 #if !defined(DUK_USE_BYTECODE_DUMP_SUPPORT)
duk_err_unsupported_defmsg(duk_hthread * thr,const char * filename,duk_int_t linenumber)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);
64 }
65 #endif
duk_err_internal_defmsg(duk_hthread * thr,const char * filename,duk_int_t linenumber)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);
68 }
duk_err_internal(duk_hthread * thr,const char * filename,duk_int_t linenumber,const char * message)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);
71 }
duk_err_alloc(duk_hthread * thr,const char * filename,duk_int_t linenumber,const char * 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);
74 }
75 #else
76 /* The file/line arguments are NULL and 0, they're ignored by DUK_ERROR_RAW()
77 * when non-verbose errors are used.
78 */
duk_err_type(duk_hthread * thr)79 DUK_INTERNAL void duk_err_type(duk_hthread *thr) {
80 DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_TYPE_ERROR, NULL);
81 }
duk_err_api(duk_hthread * thr)82 DUK_INTERNAL void duk_err_api(duk_hthread *thr) {
83 DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_API_ERROR, NULL);
84 }
duk_err_range(duk_hthread * thr)85 DUK_INTERNAL void duk_err_range(duk_hthread *thr) {
86 DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_RANGE_ERROR, NULL);
87 }
duk_err_syntax(duk_hthread * thr)88 DUK_INTERNAL void duk_err_syntax(duk_hthread *thr) {
89 DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_SYNTAX_ERROR, NULL);
90 }
duk_err_unimplemented(duk_hthread * thr)91 DUK_INTERNAL void duk_err_unimplemented(duk_hthread *thr) {
92 DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_UNIMPLEMENTED_ERROR, NULL);
93 }
duk_err_unsupported(duk_hthread * thr)94 DUK_INTERNAL void duk_err_unsupported(duk_hthread *thr) {
95 DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_UNSUPPORTED_ERROR, NULL);
96 }
duk_err_internal(duk_hthread * thr)97 DUK_INTERNAL void duk_err_internal(duk_hthread *thr) {
98 DUK_ERROR_RAW(thr, NULL, 0, DUK_ERR_INTERNAL_ERROR, NULL);
99 }
duk_err_alloc(duk_hthread * thr)100 DUK_INTERNAL void duk_err_alloc(duk_hthread *thr) {
101 DUK_ERROR_RAW(thr, NULL, thr, DUK_ERR_ALLOC_ERROR, NULL);
102 }
103 #endif
104
105 /*
106 * Default fatal error handler
107 */
108
duk_default_fatal_handler(duk_context * ctx,duk_errcode_t code,const char * msg)109 DUK_INTERNAL void duk_default_fatal_handler(duk_context *ctx, duk_errcode_t code, const char *msg) {
110 DUK_UNREF(ctx);
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);
114 #else
115 /* omit print */
116 #endif
117 DUK_D(DUK_DPRINT("default fatal handler called, code %ld -> calling DUK_PANIC()", (long) code));
118 DUK_PANIC(code, msg);
119 DUK_UNREACHABLE();
120 }
121
122 /*
123 * Default panic handler
124 */
125
126 #if !defined(DUK_USE_PANIC_HANDLER)
duk_default_panic_handler(duk_errcode_t code,const char * msg)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)
131 "calling abort"
132 #elif defined(DUK_USE_PANIC_EXIT)
133 "calling exit"
134 #elif defined(DUK_USE_PANIC_SEGFAULT)
135 "segfaulting on purpose"
136 #else
137 #error no DUK_USE_PANIC_xxx macro defined
138 #endif
139 ")\n", (long) code, (const char *) (msg ? msg : "null"));
140 DUK_FFLUSH(DUK_STDERR);
141 #else
142 /* omit print */
143 DUK_UNREF(code);
144 DUK_UNREF(msg);
145 #endif
146
147 #if defined(DUK_USE_PANIC_ABORT)
148 DUK_ABORT();
149 #elif defined(DUK_USE_PANIC_EXIT)
150 DUK_EXIT(-1);
151 #elif defined(DUK_USE_PANIC_SEGFAULT)
152 /* exit() afterwards to satisfy "noreturn" */
153 DUK_CAUSE_SEGFAULT(); /* SCANBUILD: "Dereference of null pointer", normal */
154 DUK_EXIT(-1);
155 #else
156 #error no DUK_USE_PANIC_xxx macro defined
157 #endif
158
159 DUK_UNREACHABLE();
160 }
161 #endif /* !DUK_USE_PANIC_HANDLER */
162
163 #undef DUK__ERRFMT_BUFSIZE
164