summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-30 12:40:20 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-30 12:40:20 +0000
commitbcdcee47381aa7314a6b249074078f8298d12c7a (patch)
tree7aa4d14162ae92ac7b32e739659b9b35994b41fb /compile.c
parentb33a168e65c64f2d852b3911e34bd4faab451ab8 (diff)
merge revision(s) 66326,66649: [Backport #15385]
Fix infinite loop by ensure * compile.c (iseq_insert_nop_between_end_and_cont): insert nop so that the end of rescue and continuing points are not same, to get rid of infinite loop. [Bug #15385] test_optimization.rb: increase timeout for RubyCI https://rubyci.org/logs/rubyci.s3.amazonaws.com/opensuseleap/ruby-trunk/log/20181230T040002Z.fail.html.gz git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@67702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/compile.c b/compile.c
index 27f4a9c21c..417ee210bd 100644
--- a/compile.c
+++ b/compile.c
@@ -1226,6 +1226,27 @@ new_child_iseq(rb_iseq_t *iseq, const NODE *const node,
return ret_iseq;
}
+static void
+iseq_insert_nop_between_end_and_cont(rb_iseq_t *iseq)
+{
+ VALUE catch_table_ary = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ unsigned int i, tlen = (unsigned int)RARRAY_LEN(catch_table_ary);
+ const VALUE *tptr = RARRAY_CONST_PTR(catch_table_ary);
+ for (i = 0; i < tlen; i++) {
+ const VALUE *ptr = RARRAY_CONST_PTR(tptr[i]);
+ LINK_ELEMENT *end = (LINK_ELEMENT *)(ptr[2] & ~1);
+ LINK_ELEMENT *cont = (LINK_ELEMENT *)(ptr[4] & ~1);
+ LINK_ELEMENT *e;
+ for (e = end; e && (IS_LABEL(e) || IS_TRACE(e)); e = e->next) {
+ if (e == cont) {
+ INSN *nop = new_insn_core(iseq, 0, BIN(nop), 0, 0);
+ ELEM_INSERT_NEXT(end, &nop->link);
+ break;
+ }
+ }
+ }
+}
+
static int
iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
{
@@ -1257,6 +1278,9 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
dump_disasm_list(FIRST_ELEMENT(anchor));
}
+ debugs("[compile step 3.4 (iseq_insert_nop_between_end_and_cont)]\n");
+ iseq_insert_nop_between_end_and_cont(iseq);
+
debugs("[compile step 4.1 (iseq_set_sequence)]\n");
if (!iseq_set_sequence(iseq, anchor)) return COMPILE_NG;
if (compile_debug > 5)
@@ -5382,15 +5406,8 @@ compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
ADD_LABEL(ret, lstart);
CHECK(COMPILE_(ret, "ensure head", node->nd_head, (popped | last_leave)));
ADD_LABEL(ret, lend);
- if (LIST_INSN_SIZE_ZERO(ensr)) {
- ADD_INSN(ret, line, nop);
- }
- else {
- ADD_SEQ(ret, ensr);
- if (!popped && last_leave) {
- ADD_INSN(ret, line, putnil);
- }
- }
+ ADD_SEQ(ret, ensr);
+ if (!popped && last_leave) ADD_INSN(ret, line, putnil);
ADD_LABEL(ret, lcont);
if (last_leave) ADD_INSN(ret, line, pop);