summaryrefslogtreecommitdiff
path: root/eval_error.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval_error.c')
-rw-r--r--eval_error.c587
1 files changed, 208 insertions, 379 deletions
diff --git a/eval_error.c b/eval_error.c
index f3d05a1043..cd7a607eaa 100644
--- a/eval_error.c
+++ b/eval_error.c
@@ -3,22 +3,26 @@
* included by eval.c
*/
-#define write_warn(str, x) \
- (NIL_P(str) ? warn_print(x) : (void)rb_str_cat_cstr(str, x))
-#define write_warn2(str, x, l) \
- (NIL_P(str) ? warn_print2(x, l) : (void)rb_str_cat(str, x, l))
-#define write_warn_enc(str, x, l, enc) \
- (NIL_P(str) ? warn_print2(x, l) : (void)rb_enc_str_buf_cat(str, x, l, enc))
#ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P
+#define write_warn(str, x) RB_GNUC_EXTENSION_BLOCK( \
+ NIL_P(str) ? \
+ warn_print(x) : (void)( \
+ (__builtin_constant_p(x)) ? \
+ rb_str_concat((str), rb_str_new((x), (long)strlen(x))) : \
+ rb_str_concat((str), rb_str_new2(x)) \
+ ) \
+ )
#define warn_print(x) RB_GNUC_EXTENSION_BLOCK( \
(__builtin_constant_p(x)) ? \
- rb_write_error2((x), (long)strlen(x)) : \
- rb_write_error(x) \
+ rb_write_error2((x), (long)strlen(x)) : \
+ rb_write_error(x) \
)
#else
+#define write_warn(str, x) NIL_P(str) ? rb_write_error((x)) : (void)rb_str_concat((str), rb_str_new2(x))
#define warn_print(x) rb_write_error(x)
#endif
+#define write_warn2(str,x,l) NIL_P(str) ? warn_print2(x,l) : (void)rb_str_concat((str), rb_str_new((x),(l)))
#define warn_print2(x,l) rb_write_error2((x),(l))
#define write_warn_str(str,x) NIL_P(str) ? rb_write_error_str(x) : (void)rb_str_concat((str), (x))
@@ -31,7 +35,7 @@ error_pos(const VALUE str)
{
VALUE pos = error_pos_str();
if (!NIL_P(pos)) {
- write_warn_str(str, pos);
+ write_warn_str(str, pos);
}
}
@@ -42,18 +46,18 @@ error_pos_str(void)
VALUE sourcefile = rb_source_location(&sourceline);
if (!NIL_P(sourcefile)) {
- ID caller_name;
- if (sourceline == 0) {
- return rb_sprintf("%"PRIsVALUE": ", sourcefile);
- }
- else if ((caller_name = rb_frame_callee()) != 0) {
- return rb_sprintf("%"PRIsVALUE":%d:in '%"PRIsVALUE"': ",
- sourcefile, sourceline,
- rb_id2str(caller_name));
- }
- else {
- return rb_sprintf("%"PRIsVALUE":%d: ", sourcefile, sourceline);
- }
+ ID caller_name;
+ if (sourceline == 0) {
+ return rb_sprintf("%"PRIsVALUE": ", sourcefile);
+ }
+ else if ((caller_name = rb_frame_callee()) != 0) {
+ return rb_sprintf("%"PRIsVALUE":%d:in `%"PRIsVALUE"': ",
+ sourcefile, sourceline,
+ rb_id2str(caller_name));
+ }
+ else {
+ return rb_sprintf("%"PRIsVALUE":%d: ", sourcefile, sourceline);
+ }
}
return Qnil;
}
@@ -64,17 +68,23 @@ set_backtrace(VALUE info, VALUE bt)
ID set_backtrace = rb_intern("set_backtrace");
if (rb_backtrace_p(bt)) {
- if (rb_method_basic_definition_p(CLASS_OF(info), set_backtrace)) {
- rb_exc_set_backtrace(info, bt);
- return;
- }
- else {
- bt = rb_backtrace_to_str_ary(bt);
- }
+ if (rb_method_basic_definition_p(CLASS_OF(info), set_backtrace)) {
+ rb_exc_set_backtrace(info, bt);
+ return;
+ }
+ else {
+ bt = rb_backtrace_to_str_ary(bt);
+ }
}
rb_check_funcall(info, set_backtrace, 1, &bt);
}
+static void
+error_print(rb_execution_context_t *ec)
+{
+ rb_ec_error_print(ec, ec->errinfo);
+}
+
#define CSI_BEGIN "\033["
#define CSI_SGR "m"
@@ -83,320 +93,181 @@ static const char bold[] = CSI_BEGIN"1"CSI_SGR;
static const char reset[] = CSI_BEGIN""CSI_SGR;
static void
-print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg, const VALUE str, int highlight)
+print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg, const VALUE str, int colored)
{
+ const char *einfo = "";
long elen = 0;
VALUE mesg;
- if (NIL_P(errat) || RARRAY_LEN(errat) == 0 ||
- NIL_P(mesg = RARRAY_AREF(errat, 0))) {
- error_pos(str);
- }
- else {
- write_warn_str(str, mesg);
- write_warn(str, ": ");
- }
-
- if (!NIL_P(emesg)) {
- elen = RSTRING_LEN(emesg);
- }
-
- if (eclass == rb_eRuntimeError && elen == 0) {
- if (highlight) write_warn(str, underline);
- write_warn(str, "unhandled exception");
- if (highlight) write_warn(str, reset);
- write_warn(str, "\n");
+ if (emesg != Qundef) {
+ if (NIL_P(errat) || RARRAY_LEN(errat) == 0 ||
+ NIL_P(mesg = RARRAY_AREF(errat, 0))) {
+ error_pos(str);
+ }
+ else {
+ write_warn_str(str, mesg);
+ write_warn(str, ": ");
+ }
+
+ if (colored) write_warn(str, bold);
+
+ if (!NIL_P(emesg)) {
+ einfo = RSTRING_PTR(emesg);
+ elen = RSTRING_LEN(emesg);
+ }
}
- else {
- VALUE epath;
-
- epath = rb_class_name(eclass);
- if (elen == 0) {
- if (highlight) write_warn(str, underline);
- write_warn_str(str, epath);
- if (highlight) write_warn(str, reset);
- write_warn(str, "\n");
- }
- else {
- write_warn_str(str, emesg);
- write_warn(str, "\n");
- }
- }
-}
-
-VALUE
-rb_decorate_message(const VALUE eclass, VALUE emesg, int highlight)
-{
- const char *einfo = "";
- long elen = 0;
- rb_encoding *eenc;
-
- VALUE str = rb_usascii_str_new_cstr("");
- if (!NIL_P(emesg) && rb_enc_asciicompat(eenc = rb_enc_get(emesg))) {
- einfo = RSTRING_PTR(emesg);
- elen = RSTRING_LEN(emesg);
- }
- else {
- eenc = NULL;
- }
if (eclass == rb_eRuntimeError && elen == 0) {
- if (highlight) write_warn(str, underline);
- write_warn(str, "unhandled exception");
- if (highlight) write_warn(str, reset);
+ if (colored) write_warn(str, underline);
+ write_warn(str, "unhandled exception\n");
}
else {
- VALUE epath;
-
- epath = rb_class_name(eclass);
- if (elen == 0) {
- if (highlight) write_warn(str, underline);
- write_warn_str(str, epath);
- if (highlight) write_warn(str, reset);
- }
- else {
- /* emesg is a String instance */
- const char *tail = 0;
-
- if (highlight) write_warn(str, bold);
- if (RSTRING_PTR(epath)[0] == '#')
- epath = 0;
- if ((tail = memchr(einfo, '\n', elen)) != 0) {
- write_warn_enc(str, einfo, tail - einfo, eenc);
- tail++; /* skip newline */
- }
- else {
- write_warn_str(str, emesg);
- }
- if (epath) {
- write_warn(str, " (");
- if (highlight) write_warn(str, underline);
+ VALUE epath;
+
+ epath = rb_class_name(eclass);
+ if (elen == 0) {
+ if (colored) write_warn(str, underline);
+ write_warn_str(str, epath);
+ write_warn(str, "\n");
+ }
+ else {
+ const char *tail = 0;
+ long len = elen;
+
+ if (RSTRING_PTR(epath)[0] == '#')
+ epath = 0;
+ if ((tail = memchr(einfo, '\n', elen)) != 0) {
+ len = tail - einfo;
+ tail++; /* skip newline */
+ }
+ write_warn_str(str, tail ? rb_str_subseq(emesg, 0, len) : emesg);
+ if (epath) {
+ write_warn(str, " (");
+ if (colored) write_warn(str, underline);
write_warn_str(str, epath);
- if (highlight) {
- write_warn(str, reset);
- write_warn(str, bold);
- }
- write_warn(str, ")");
- if (highlight) write_warn(str, reset);
- }
- if (tail && einfo+elen > tail) {
- if (!highlight) {
- write_warn(str, "\n");
- write_warn_enc(str, tail, einfo+elen-tail, eenc);
- }
- else {
- elen -= tail - einfo;
- einfo = tail;
- write_warn(str, "\n");
- while (elen > 0) {
- tail = memchr(einfo, '\n', elen);
- if (!tail || tail > einfo) {
- write_warn(str, bold);
- write_warn_enc(str, einfo, tail ? tail-einfo : elen, eenc);
- write_warn(str, reset);
- if (!tail) {
- break;
- }
- }
- elen -= tail - einfo;
- einfo = tail;
- do ++tail; while (tail < einfo+elen && *tail == '\n');
- write_warn_enc(str, einfo, tail-einfo, eenc);
- elen -= tail - einfo;
- einfo = tail;
- }
- }
- }
- }
+ if (colored) write_warn(str, reset);
+ if (colored) write_warn(str, bold);
+ write_warn(str, ")\n");
+ }
+ if (tail) {
+ write_warn_str(str, rb_str_subseq(emesg, tail - einfo, elen - len - 1));
+ }
+ if (tail ? einfo[elen-1] != '\n' : !epath) write_warn2(str, "\n", 1);
+ }
}
-
- RB_GC_GUARD(emesg);
-
- return str;
+ if (colored) write_warn(str, reset);
}
static void
-print_backtrace(const VALUE eclass, const VALUE errat, const VALUE str, int reverse, long backtrace_limit)
+print_backtrace(const VALUE eclass, const VALUE errat, const VALUE str, int reverse)
{
if (!NIL_P(errat)) {
- long i;
- long len = RARRAY_LEN(errat);
- const int threshold = 1000000000;
- int width = (len <= 1) ? INT_MIN : ((int)log10((double)(len > threshold ?
- ((len - 1) / threshold) :
- len - 1)) +
- (len < threshold ? 0 : 9) + 1);
-
- long skip_start = -1, skip_len = 0;
-
- // skip for stackoverflow
- if (eclass == rb_eSysStackError) {
- long trace_head = 9;
- long trace_tail = 4;
- long trace_max = trace_head + trace_tail + 5;
- if (len > trace_max) {
- skip_start = trace_head;
- skip_len = len - trace_max + 5;
- }
- }
-
- // skip for explicit limit
- if (backtrace_limit >= 0 && len > backtrace_limit + 2) {
- skip_start = backtrace_limit + 1;
- skip_len = len - skip_start;
- }
-
- for (i = 1; i < len; i++) {
- if (i == skip_start) {
- write_warn_str(str, rb_sprintf("\t ... %ld levels...\n", skip_len));
- i += skip_len;
- if (i >= len) break;
- }
- VALUE line = RARRAY_AREF(errat, reverse ? len - i : i);
- if (RB_TYPE_P(line, T_STRING)) {
- VALUE bt = rb_str_new_cstr("\t");
- if (reverse) rb_str_catf(bt, "%*ld: ", width, len - i);
- write_warn_str(str, rb_str_catf(bt, "from %"PRIsVALUE"\n", line));
- }
- }
- }
-}
-
-VALUE rb_get_detailed_message(VALUE exc, VALUE opt);
-
-static int
-shown_cause_p(VALUE cause, VALUE *shown_causes)
-{
- VALUE shown = *shown_causes;
- if (!shown) {
- *shown_causes = shown = rb_obj_hide(rb_ident_hash_new());
- }
- if (rb_hash_has_key(shown, cause)) return TRUE;
- rb_hash_aset(shown, cause, Qtrue);
- return FALSE;
-}
-
-static void
-show_cause(VALUE errinfo, VALUE str, VALUE opt, VALUE highlight, VALUE reverse, long backtrace_limit, VALUE *shown_causes)
-{
- VALUE cause = rb_attr_get(errinfo, id_cause);
- if (!NIL_P(cause) && rb_obj_is_kind_of(cause, rb_eException) &&
- !shown_cause_p(cause, shown_causes)) {
- volatile VALUE eclass = CLASS_OF(cause);
- VALUE errat = rb_get_backtrace(cause);
- VALUE emesg = rb_get_detailed_message(cause, opt);
- if (reverse) {
- show_cause(cause, str, opt, highlight, reverse, backtrace_limit, shown_causes);
- print_backtrace(eclass, errat, str, TRUE, backtrace_limit);
- print_errinfo(eclass, errat, emesg, str, RTEST(highlight));
- }
- else {
- print_errinfo(eclass, errat, emesg, str, RTEST(highlight));
- print_backtrace(eclass, errat, str, FALSE, backtrace_limit);
- show_cause(cause, str, opt, highlight, reverse, backtrace_limit, shown_causes);
- }
+ long i;
+ long len = RARRAY_LEN(errat);
+ int skip = eclass == rb_eSysStackError;
+ const int threshold = 1000000000;
+ int width = ((int)log10((double)(len > threshold ?
+ ((len - 1) / threshold) :
+ len - 1)) +
+ (len < threshold ? 0 : 9) + 1);
+
+#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
+#define TRACE_HEAD 8
+#define TRACE_TAIL 5
+
+ for (i = 1; i < len; i++) {
+ VALUE line = RARRAY_AREF(errat, reverse ? len - i : i);
+ if (RB_TYPE_P(line, T_STRING)) {
+ VALUE bt = rb_str_new_cstr("\t");
+ if (reverse) rb_str_catf(bt, "%*ld: ", width, len - i);
+ write_warn_str(str, rb_str_catf(bt, "from %"PRIsVALUE"\n", line));
+ }
+ if (skip && i == TRACE_HEAD && len > TRACE_MAX) {
+ write_warn_str(str, rb_sprintf("\t ... %ld levels...\n",
+ len - TRACE_HEAD - TRACE_TAIL));
+ i = len - TRACE_TAIL;
+ }
+ }
}
}
void
-rb_exc_check_circular_cause(VALUE exc)
-{
- VALUE cause = exc, shown_causes = 0;
- do {
- if (shown_cause_p(cause, &shown_causes)) {
- rb_raise(rb_eArgError, "circular causes");
- }
- } while (!NIL_P(cause = rb_attr_get(cause, id_cause)));
-}
-
-void
-rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE opt, VALUE highlight, VALUE reverse)
+rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlight, VALUE reverse)
{
volatile VALUE eclass;
- VALUE shown_causes = 0;
- long backtrace_limit = rb_backtrace_length_limit;
if (NIL_P(errinfo))
- return;
+ return;
- if (UNDEF_P(errat)) {
- errat = Qnil;
+ if (errat == Qundef) {
+ errat = Qnil;
}
eclass = CLASS_OF(errinfo);
+ if (NIL_P(reverse) || NIL_P(highlight)) {
+ VALUE tty = (VALUE)rb_stderr_tty_p();
+ if (NIL_P(reverse)) reverse = tty;
+ if (NIL_P(highlight)) highlight = tty;
+ }
if (reverse) {
- static const char traceback[] = "Traceback "
- "(most recent call last):\n";
- const int bold_part = rb_strlen_lit("Traceback");
- char buff[sizeof(traceback)+sizeof(bold)+sizeof(reset)-2], *p = buff;
- const char *msg = traceback;
- long len = sizeof(traceback) - 1;
- if (RTEST(highlight)) {
+ static const char traceback[] = "Traceback "
+ "(most recent call last):\n";
+ const int bold_part = rb_strlen_lit("Traceback");
+ char buff[sizeof(traceback)+sizeof(bold)+sizeof(reset)-2], *p = buff;
+ const char *msg = traceback;
+ long len = sizeof(traceback) - 1;
+ if (highlight) {
#define APPEND(s, l) (memcpy(p, s, l), p += (l))
- APPEND(bold, sizeof(bold)-1);
- APPEND(traceback, bold_part);
- APPEND(reset, sizeof(reset)-1);
- APPEND(traceback + bold_part, sizeof(traceback)-bold_part-1);
+ APPEND(bold, sizeof(bold)-1);
+ APPEND(traceback, bold_part);
+ APPEND(reset, sizeof(reset)-1);
+ APPEND(traceback + bold_part, sizeof(traceback)-bold_part-1);
#undef APPEND
- len = p - (msg = buff);
- }
- write_warn2(str, msg, len);
- show_cause(errinfo, str, opt, highlight, reverse, backtrace_limit, &shown_causes);
- print_backtrace(eclass, errat, str, TRUE, backtrace_limit);
- print_errinfo(eclass, errat, emesg, str, RTEST(highlight));
+ len = p - (msg = buff);
+ }
+ write_warn2(str, msg, len);
+ print_backtrace(eclass, errat, str, TRUE);
+ print_errinfo(eclass, errat, emesg, str, highlight!=0);
}
else {
- print_errinfo(eclass, errat, emesg, str, RTEST(highlight));
- print_backtrace(eclass, errat, str, FALSE, backtrace_limit);
- show_cause(errinfo, str, opt, highlight, reverse, backtrace_limit, &shown_causes);
+ print_errinfo(eclass, errat, emesg, str, highlight!=0);
+ print_backtrace(eclass, errat, str, FALSE);
}
}
-static void
-rb_ec_error_print_detailed(rb_execution_context_t *const ec, const VALUE errinfo, const VALUE str, VALUE emesg0)
+VALUE rb_get_message(VALUE exc);
+
+void
+rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo)
{
- volatile uint8_t raised_flag = ec->raised_flag;
+ volatile int raised_flag = ec->raised_flag;
volatile VALUE errat = Qundef;
- volatile bool written = false;
- volatile VALUE emesg = emesg0;
-
- VALUE opt = rb_hash_new();
- VALUE highlight = rb_stderr_tty_p() ? Qtrue : Qfalse;
- rb_hash_aset(opt, ID2SYM(rb_intern_const("highlight")), highlight);
+ volatile VALUE emesg = Qundef;
if (NIL_P(errinfo))
- return;
+ return;
rb_ec_raised_clear(ec);
EC_PUSH_TAG(ec);
if (EC_EXEC_TAG() == TAG_NONE) {
- errat = rb_get_backtrace(errinfo);
+ errat = rb_get_backtrace(errinfo);
}
- if (UNDEF_P(emesg)) {
- emesg = Qnil;
- emesg = rb_get_detailed_message(errinfo, opt);
+ if (emesg == Qundef) {
+ emesg = Qnil;
+ emesg = rb_get_message(errinfo);
}
- if (!written) {
- written = true;
- rb_error_write(errinfo, emesg, errat, str, opt, highlight, Qfalse);
- }
+ rb_error_write(errinfo, emesg, errat, Qnil, Qnil, Qnil);
EC_POP_TAG();
ec->errinfo = errinfo;
rb_ec_raised_set(ec, raised_flag);
}
-void
-rb_ec_error_print(rb_execution_context_t *volatile ec, volatile VALUE errinfo)
-{
- rb_ec_error_print_detailed(ec, errinfo, Qnil, Qundef);
-}
-
-#define undef_mesg_for(v, k) rb_fstring_lit("undefined"v" method '%1$s' for "k" '%2$s'")
+#define undef_mesg_for(v, k) rb_fstring_cstr("undefined"v" method `%1$s' for "k" `%2$s'")
#define undef_mesg(v) ( \
- is_mod ? \
- undef_mesg_for(v, "module") : \
- undef_mesg_for(v, "class"))
+ is_mod ? \
+ undef_mesg_for(v, "module") : \
+ undef_mesg_for(v, "class"))
void
rb_print_undef(VALUE klass, ID id, rb_method_visibility_t visi)
@@ -420,11 +291,11 @@ rb_print_undef_str(VALUE klass, VALUE name)
rb_name_err_raise_str(undef_mesg(""), klass, name);
}
-#define inaccessible_mesg_for(v, k) rb_fstring_lit("method '%1$s' for "k" '%2$s' is "v)
+#define inaccessible_mesg_for(v, k) rb_fstring_cstr("method `%1$s' for "k" `%2$s' is "v)
#define inaccessible_mesg(v) ( \
- is_mod ? \
- inaccessible_mesg_for(v, "module") : \
- inaccessible_mesg_for(v, "class"))
+ is_mod ? \
+ inaccessible_mesg_for(v, "module") : \
+ inaccessible_mesg_for(v, "class"))
void
rb_print_inaccessible(VALUE klass, ID id, rb_method_visibility_t visi)
@@ -434,8 +305,8 @@ rb_print_inaccessible(VALUE klass, ID id, rb_method_visibility_t visi)
switch (visi & METHOD_VISI_MASK) {
case METHOD_VISI_UNDEF:
case METHOD_VISI_PUBLIC: mesg = inaccessible_mesg(""); break;
- case METHOD_VISI_PRIVATE: mesg = inaccessible_mesg("private"); break;
- case METHOD_VISI_PROTECTED: mesg = inaccessible_mesg("protected"); break;
+ case METHOD_VISI_PRIVATE: mesg = inaccessible_mesg(" private"); break;
+ case METHOD_VISI_PROTECTED: mesg = inaccessible_mesg(" protected"); break;
default: UNREACHABLE;
}
rb_name_err_raise_str(mesg, klass, ID2SYM(id));
@@ -448,109 +319,67 @@ sysexit_status(VALUE err)
return NUM2INT(st);
}
-enum {
- EXITING_WITH_MESSAGE = 1,
- EXITING_WITH_STATUS = 2,
- EXITING_WITH_SIGNAL = 4
-};
-static int
-exiting_split(VALUE errinfo, volatile int *exitcode, volatile int *sigstatus)
-{
- int ex = EXIT_SUCCESS;
- VALUE signo;
- int sig = 0;
- int result = 0;
-
- if (NIL_P(errinfo)) return 0;
-
- if (THROW_DATA_P(errinfo)) {
- int throw_state = ((const struct vm_throw_data *)errinfo)->throw_state;
- ex = throw_state & VM_THROW_STATE_MASK;
- result |= EXITING_WITH_STATUS;
- }
- else if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
- ex = sysexit_status(errinfo);
- result |= EXITING_WITH_STATUS;
- }
- else if (rb_obj_is_kind_of(errinfo, rb_eSignal)) {
- signo = rb_ivar_get(errinfo, id_signo);
- sig = FIX2INT(signo);
- result |= EXITING_WITH_SIGNAL;
- /* no message when exiting by signal */
- if (signo == INT2FIX(SIGSEGV) || !rb_obj_is_instance_of(errinfo, rb_eSignal))
- /* except for SEGV and subclasses */
- result |= EXITING_WITH_MESSAGE;
- }
- else if (rb_obj_is_kind_of(errinfo, rb_eSystemCallError) &&
- FIXNUM_P(signo = rb_attr_get(errinfo, id_signo))) {
- sig = FIX2INT(signo);
- result |= EXITING_WITH_SIGNAL;
- /* no message when exiting by error to be mapped to signal */
- }
- else {
- ex = EXIT_FAILURE;
- result |= EXITING_WITH_STATUS | EXITING_WITH_MESSAGE;
- }
-
- if (exitcode && (result & EXITING_WITH_STATUS))
- *exitcode = ex;
- if (sigstatus && (result & EXITING_WITH_SIGNAL))
- *sigstatus = sig;
-
- return result;
-}
-
#define unknown_longjmp_status(status) \
rb_bug("Unknown longjmp status %d", status)
static int
-error_handle(rb_execution_context_t *ec, VALUE errinfo, enum ruby_tag_type ex)
+error_handle(int ex)
{
int status = EXIT_FAILURE;
+ rb_execution_context_t *ec = GET_EC();
if (rb_ec_set_raised(ec))
- return EXIT_FAILURE;
+ return EXIT_FAILURE;
switch (ex & TAG_MASK) {
case 0:
- status = EXIT_SUCCESS;
- break;
+ status = EXIT_SUCCESS;
+ break;
case TAG_RETURN:
- error_pos(Qnil);
- warn_print("unexpected return\n");
- break;
+ error_pos(Qnil);
+ warn_print("unexpected return\n");
+ break;
case TAG_NEXT:
- error_pos(Qnil);
- warn_print("unexpected next\n");
- break;
+ error_pos(Qnil);
+ warn_print("unexpected next\n");
+ break;
case TAG_BREAK:
- error_pos(Qnil);
- warn_print("unexpected break\n");
- break;
+ error_pos(Qnil);
+ warn_print("unexpected break\n");
+ break;
case TAG_REDO:
- error_pos(Qnil);
- warn_print("unexpected redo\n");
- break;
+ error_pos(Qnil);
+ warn_print("unexpected redo\n");
+ break;
case TAG_RETRY:
- error_pos(Qnil);
- warn_print("retry outside of rescue clause\n");
- break;
+ error_pos(Qnil);
+ warn_print("retry outside of rescue clause\n");
+ break;
case TAG_THROW:
- /* TODO: fix me */
- error_pos(Qnil);
- warn_print("unexpected throw\n");
- break;
- case TAG_RAISE:
- if (!(exiting_split(errinfo, &status, NULL) & EXITING_WITH_MESSAGE)) {
- break;
- }
- /* fallthrough */
+ /* TODO: fix me */
+ error_pos(Qnil);
+ warn_print("unexpected throw\n");
+ break;
+ case TAG_RAISE: {
+ VALUE errinfo = ec->errinfo;
+ if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
+ status = sysexit_status(errinfo);
+ }
+ else if (rb_obj_is_instance_of(errinfo, rb_eSignal) &&
+ rb_ivar_get(errinfo, id_signo) != INT2FIX(SIGSEGV)) {
+ /* no message when exiting by signal */
+ }
+ else {
+ rb_ec_error_print(ec, errinfo);
+ }
+ break;
+ }
case TAG_FATAL:
- rb_ec_error_print(ec, errinfo);
- break;
+ error_print(ec);
+ break;
default:
- unknown_longjmp_status(ex);
- break;
+ unknown_longjmp_status(ex);
+ break;
}
rb_ec_reset_raised(ec);
return status;