@@ -5356,9 +5356,22 @@ add_ensure_range(rb_iseq_t *iseq, struct ensure_range *erange,
53565356 erange -> next = ne ;
53575357}
53585358
5359+ static bool
5360+ can_add_ensure_iseq (const rb_iseq_t * iseq )
5361+ {
5362+ if (ISEQ_COMPILE_DATA (iseq )-> in_rescue && ISEQ_COMPILE_DATA (iseq )-> ensure_node_stack ) {
5363+ return false;
5364+ }
5365+ else {
5366+ return true;
5367+ }
5368+ }
5369+
53595370static void
53605371add_ensure_iseq (LINK_ANCHOR * const ret , rb_iseq_t * iseq , int is_return )
53615372{
5373+ assert (can_add_ensure_iseq (iseq ));
5374+
53625375 struct iseq_compile_data_ensure_node_stack * enlp =
53635376 ISEQ_COMPILE_DATA (iseq )-> ensure_node_stack ;
53645377 struct iseq_compile_data_ensure_node_stack * prev_enlp = enlp ;
@@ -6850,7 +6863,7 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
68506863 const int line = nd_line (node );
68516864 unsigned long throw_flag = 0 ;
68526865
6853- if (ISEQ_COMPILE_DATA (iseq )-> redo_label != 0 ) {
6866+ if (ISEQ_COMPILE_DATA (iseq )-> redo_label != 0 && can_add_ensure_iseq ( iseq ) ) {
68546867 /* while/until */
68556868 LABEL * splabel = NEW_LABEL (0 );
68566869 ADD_LABEL (ret , splabel );
@@ -6909,7 +6922,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
69096922 const int line = nd_line (node );
69106923 unsigned long throw_flag = 0 ;
69116924
6912- if (ISEQ_COMPILE_DATA (iseq )-> redo_label != 0 ) {
6925+ if (ISEQ_COMPILE_DATA (iseq )-> redo_label != 0 && can_add_ensure_iseq ( iseq ) ) {
69136926 LABEL * splabel = NEW_LABEL (0 );
69146927 debugs ("next in while loop\n" );
69156928 ADD_LABEL (ret , splabel );
@@ -6922,7 +6935,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
69226935 ADD_INSN (ret , line , putnil );
69236936 }
69246937 }
6925- else if (ISEQ_COMPILE_DATA (iseq )-> end_label ) {
6938+ else if (ISEQ_COMPILE_DATA (iseq )-> end_label && can_add_ensure_iseq ( iseq ) ) {
69266939 LABEL * splabel = NEW_LABEL (0 );
69276940 debugs ("next in block\n" );
69286941 ADD_LABEL (ret , splabel );
@@ -6982,7 +6995,7 @@ compile_redo(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
69826995{
69836996 const int line = nd_line (node );
69846997
6985- if (ISEQ_COMPILE_DATA (iseq )-> redo_label ) {
6998+ if (ISEQ_COMPILE_DATA (iseq )-> redo_label && can_add_ensure_iseq ( iseq ) ) {
69866999 LABEL * splabel = NEW_LABEL (0 );
69877000 debugs ("redo in while" );
69887001 ADD_LABEL (ret , splabel );
@@ -6994,7 +7007,7 @@ compile_redo(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
69947007 ADD_INSN (ret , line , putnil );
69957008 }
69967009 }
6997- else if (iseq -> body -> type != ISEQ_TYPE_EVAL && ISEQ_COMPILE_DATA (iseq )-> start_label ) {
7010+ else if (iseq -> body -> type != ISEQ_TYPE_EVAL && ISEQ_COMPILE_DATA (iseq )-> start_label && can_add_ensure_iseq ( iseq ) ) {
69987011 LABEL * splabel = NEW_LABEL (0 );
69997012
70007013 debugs ("redo in block" );
@@ -7080,7 +7093,14 @@ compile_rescue(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
70807093 lstart -> rescued = LABEL_RESCUE_BEG ;
70817094 lend -> rescued = LABEL_RESCUE_END ;
70827095 ADD_LABEL (ret , lstart );
7083- CHECK (COMPILE (ret , "rescue head" , node -> nd_head ));
7096+
7097+ bool prev_in_rescue = ISEQ_COMPILE_DATA (iseq )-> in_rescue ;
7098+ ISEQ_COMPILE_DATA (iseq )-> in_rescue = true;
7099+ {
7100+ CHECK (COMPILE (ret , "rescue head" , node -> nd_head ));
7101+ }
7102+ ISEQ_COMPILE_DATA (iseq )-> in_rescue = prev_in_rescue ;
7103+
70847104 ADD_LABEL (ret , lend );
70857105 if (node -> nd_else ) {
70867106 ADD_INSN (ret , line , pop );
@@ -7241,7 +7261,7 @@ compile_return(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
72417261
72427262 CHECK (COMPILE (ret , "return nd_stts (return val)" , retval ));
72437263
7244- if (type == ISEQ_TYPE_METHOD ) {
7264+ if (type == ISEQ_TYPE_METHOD && can_add_ensure_iseq ( iseq ) ) {
72457265 add_ensure_iseq (ret , iseq , 1 );
72467266 ADD_TRACE (ret , RUBY_EVENT_RETURN );
72477267 ADD_INSN (ret , line , leave );
0 commit comments