From 56f6c15dabadbb5d4cc0ba90ea3ee69210400511 Mon Sep 17 00:00:00 2001 From: usa Date: Sun, 4 Apr 2021 23:28:16 +0000 Subject: [PATCH] backported a part of a569bc09e25a2ba813d0bec1228d9ff65330a3db picked up by Jeremy Evans [Backport #17305] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67922 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- eval.c | 116 ++++++++++++++++++++++++++++++------------------------ version.h | 2 +- 2 files changed, 65 insertions(+), 53 deletions(-) diff --git a/eval.c b/eval.c index 1eeaec56cb..47c9cac2b7 100644 --- a/eval.c +++ b/eval.c @@ -896,6 +896,66 @@ rb_need_block(void) } } +/*! + * \copydoc rb_rescue2 + * \param[in] args exception classes, terminated by 0. + */ +static VALUE +rb_vrescue2(VALUE (* b_proc) (VALUE), VALUE data1, + VALUE (* r_proc) (VALUE, VALUE), VALUE data2, + va_list args) +{ + enum ruby_tag_type state; + rb_execution_context_t * volatile ec = GET_EC(); + rb_control_frame_t *volatile cfp = ec->cfp; + volatile VALUE result = Qfalse; + volatile VALUE e_info = ec->errinfo; + + EC_PUSH_TAG(ec); + if ((state = EC_EXEC_TAG()) == TAG_NONE) { + retry_entry: + result = (*b_proc) (data1); + } + else if (result) { + /* escape from r_proc */ + if (state == TAG_RETRY) { + state = 0; + ec->errinfo = Qnil; + result = Qfalse; + goto retry_entry; + } + } + else { + rb_vm_rewind_cfp(ec, cfp); + + if (state == TAG_RAISE) { + int handle = FALSE; + VALUE eclass; + + while ((eclass = va_arg(args, VALUE)) != 0) { + if (rb_obj_is_kind_of(ec->errinfo, eclass)) { + handle = TRUE; + break; + } + } + + if (handle) { + result = Qnil; + state = 0; + if (r_proc) { + result = (*r_proc) (data2, ec->errinfo); + } + ec->errinfo = e_info; + } + } + } + EC_POP_TAG(); + if (state) + EC_JUMP_TAG(ec, state); + + return result; +} + /*! An equivalent of \c rescue clause. * * Equivalent to begin .. rescue err_type .. end @@ -922,58 +982,10 @@ VALUE rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1, VALUE (* r_proc) (ANYARGS), VALUE data2, ...) { - enum ruby_tag_type state; - rb_execution_context_t * volatile ec = GET_EC(); - rb_control_frame_t *volatile cfp = ec->cfp; - volatile VALUE result = Qfalse; - volatile VALUE e_info = ec->errinfo; - va_list args; - - EC_PUSH_TAG(ec); - if ((state = EC_EXEC_TAG()) == TAG_NONE) { - retry_entry: - result = (*b_proc) (data1); - } - else if (result) { - /* escape from r_proc */ - if (state == TAG_RETRY) { - state = 0; - ec->errinfo = Qnil; - result = Qfalse; - goto retry_entry; - } - } - else { - rb_vm_rewind_cfp(ec, cfp); - - if (state == TAG_RAISE) { - int handle = FALSE; - VALUE eclass; - - va_init_list(args, data2); - while ((eclass = va_arg(args, VALUE)) != 0) { - if (rb_obj_is_kind_of(ec->errinfo, eclass)) { - handle = TRUE; - break; - } - } - va_end(args); - - if (handle) { - result = Qnil; - state = 0; - if (r_proc) { - result = (*r_proc) (data2, ec->errinfo); - } - ec->errinfo = e_info; - } - } - } - EC_POP_TAG(); - if (state) - EC_JUMP_TAG(ec, state); - - return result; + va_list ap; + va_start(ap, data2); + return rb_vrescue2((VALUE (*)(VALUE))b_proc, data1, (VALUE (*)(VALUE, VALUE))r_proc, data2, ap); + va_end(ap); } /*! An equivalent of \c rescue clause. diff --git a/version.h b/version.h index c4d0636924..b64ba5ea84 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ #define RUBY_VERSION "2.6.7" #define RUBY_RELEASE_DATE "2021-04-05" -#define RUBY_PATCHLEVEL 181 +#define RUBY_PATCHLEVEL 182 #define RUBY_RELEASE_YEAR 2021 #define RUBY_RELEASE_MONTH 4