aboutsummaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-01-24 14:52:07 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-01-24 14:52:07 +0000
commitdb0afc5d2d22958d7c0ccdcf9c7ecf94af16b41c (patch)
tree54db8eb40f8c2ec84196eaab46c3ca9fc7bf90cb /eval.c
parentf852ce8969fc93f8330b25ac49a45b47d83805d6 (diff)
downloadruby-db0afc5d2d22958d7c0ccdcf9c7ecf94af16b41c.tar.gz
eval.c: copy special exception
* eval.c (setup_exception): make unfrozen copy of special exception before setting up a cause. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57415 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/eval.c b/eval.c
index 4c6e8e98b4..e16d59b8bb 100644
--- a/eval.c
+++ b/eval.c
@@ -470,6 +470,17 @@ sysstack_error_p(VALUE exc)
return exc == sysstack_error || (!SPECIAL_CONST_P(exc) && RBASIC_CLASS(exc) == rb_eSysStackError);
}
+static inline int
+special_exception_p(rb_thread_t *th, VALUE exc)
+{
+ enum ruby_special_exceptions i;
+ const VALUE *exceptions = th->vm->special_exceptions;
+ for (i = 0; i < ruby_special_error_count; ++i) {
+ if (exceptions[i] == exc) return TRUE;
+ }
+ return FALSE;
+}
+
static void
setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
{
@@ -487,6 +498,9 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
nocause = 0;
}
+ else if (special_exception_p(th, mesg)) {
+ mesg = ruby_vm_special_exception_copy(mesg);
+ }
if (cause != Qundef) {
exc_setup_cause(mesg, cause);
}
@@ -503,9 +517,6 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
if (sysstack_error_p(mesg)) {
if (NIL_P(rb_attr_get(mesg, idBt))) {
at = rb_vm_backtrace_object();
- if (mesg == sysstack_error) {
- mesg = ruby_vm_sysstack_error_copy();
- }
rb_ivar_set(mesg, idBt, at);
rb_ivar_set(mesg, idBt_locations, at);
}