From 633df8de16203da72dff1a010740fdf92f9f7f5c Mon Sep 17 00:00:00 2001 From: ko1 Date: Tue, 25 Dec 2007 12:37:16 +0000 Subject: [PATCH] * compile.c (iseq_compile_each): fix stack consistency error (break is compiled to throw instead of jump insn). these problems are reported by Yusuke ENDOH * bootstraptest/test_knownbug.rb, test_syntax.rb: move fixed test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14699 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 +++++++ bootstraptest/test_knownbug.rb | 24 -------------------- bootstraptest/test_syntax.rb | 40 +++++++++++++++++++++++++++++++--- compile.c | 20 ++++++++++++++++- 4 files changed, 64 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 94abdaad877354..f4aadbc5afe71d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Tue Dec 25 21:32:54 2007 Koichi Sasada + + * compile.c (iseq_compile_each): fix stack consistency error + (break is compiled to throw instead of jump insn). + these problems are reported by Yusuke ENDOH + + * bootstraptest/test_knownbug.rb, test_syntax.rb: move fixed test. + Tue Dec 25 21:32:44 2007 Tanaka Akira * parse.y (struct parser_params): make parser_ruby_sourcefile common diff --git a/bootstraptest/test_knownbug.rb b/bootstraptest/test_knownbug.rb index 24e3c5483a8d88..39dc6a9b8beb05 100644 --- a/bootstraptest/test_knownbug.rb +++ b/bootstraptest/test_knownbug.rb @@ -2,27 +2,3 @@ # This test file concludes tests which point out known bugs. # So all tests will cause failure. # - -assert_normal_exit %q{ - begin - raise - rescue - counter = 2 - while true - counter -= 1 - break if counter == 0 - next - retry - end - end -}, 'reported by Yusuke ENDOH' - -assert_normal_exit %q{ - counter = 2 - while true - counter -= 1 - break if counter == 0 - next - "#{ break }" - end -}, 'reported by Yusuke ENDOH' diff --git a/bootstraptest/test_syntax.rb b/bootstraptest/test_syntax.rb index 8d87ab990b2f61..ed47d5987698bd 100644 --- a/bootstraptest/test_syntax.rb +++ b/bootstraptest/test_syntax.rb @@ -689,7 +689,7 @@ def foo "#{next}" end :ok -} +}, 'reported by Yusuke ENDOH' assert_equal 'ok', %q{ counter = 2 @@ -700,7 +700,7 @@ def foo redo end :ok -} +}, 'reported by Yusuke ENDOH' assert_equal 'ok', %q{ counter = 2 @@ -711,4 +711,38 @@ def foo "#{ redo }" end :ok -} +}, 'reported by Yusuke ENDOH' + +assert_normal_exit %q{ + begin + raise + rescue + counter = 2 + while true + counter -= 1 + break if counter == 0 + next + retry + end + end +}, 'reported by Yusuke ENDOH' + +assert_normal_exit %q{ + counter = 2 + while true + counter -= 1 + break if counter == 0 + next + "#{ break }" + end +}, 'reported by Yusuke ENDOH' + +assert_normal_exit %q{ + counter = 2 + while true + counter -= 1 + next if counter != 0 + "#{ break }" + end +}, 'reported by Yusuke ENDOH' + diff --git a/compile.c b/compile.c index 1960a3fa9972f6..1e26d454190275 100644 --- a/compile.c +++ b/compile.c @@ -2924,12 +2924,26 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) if (iseq->compile_data->redo_label != 0) { /* while/until */ +#if 0 add_ensure_iseq(ret, iseq); COMPILE_(ret, "break val (while/until)", node->nd_stts, iseq->compile_data->loopval_popped); ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label); - ADD_INSN(ret, nd_line(node), pop); + + if (poped) { + ADD_INSN(ret, nd_line(node), pop); + } +#else + level = 0x8000 | 0x4000; + COMPILE(ret, "break val (while/until)", node->nd_stts); + ADD_INSN1(ret, nd_line(node), throw, + INT2FIX(level | 0x02) /* TAG_BREAK */ ); + + if (poped) { + ADD_INSN(ret, nd_line(node), pop); + } +#endif } else if (iseq->type == ISEQ_TYPE_BLOCK) { break_by_insn: @@ -3089,6 +3103,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) ADD_INSN(ret, nd_line(node), putnil); ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x04) /* TAG_RETRY */ ); + + if (poped) { + ADD_INSN(ret, nd_line(node), pop); + } } else { COMPILE_ERROR((ERROR_ARGS "Invalid retry"));