Infinite loop at peephole optimization

e$B1sF#$H?=$7$^$9!#e(B

while true; redo; end e$B$Ge(B YARV
e$B$N%3%s%Q%$%k$,;_$^$i$J$/$J$j$^$9!#e(B

$ ./ruby -ve ‘VM::InstructionSequence.compile(“while true; redo; end”)’
ruby 1.9.0 (2007-08-08 patchlevel 0) [i686-linux]

(e$B8G$^$ke(B)

peephole optimization e$B$r;_$a$k$H$A$c$s$H%3%s%Q%$%k$G$-$^$9!#e(B

$ ./ruby -ve ’
VM::InstructionSequence.compile_option = { :peephole_optimization =>
false }
puts VM::InstructionSequence.compile(“while true; redo; end”).disasm

ruby 1.9.0 (2007-08-08 patchlevel 0) [i686-linux]
== disasm: <ISeq:@>=================================
== catch table
| catch type: break st: 0002 ed: 0007 sp: 0000 cont: 0007
| catch type: next st: 0002 ed: 0007 sp: 0000 cont: 0004

catch type: redo st: 0002 ed: 0007 sp: 0000 cont: 0002

0000 jump 4 (
1)
0002 jump 2
0004 jump 2
0006 putnil
0007 leave

e$B8+$?46$8e(B iseq_peephole_optimize e$B$Ne(B goto again;
e$B$GL58B%k!<%W$7$F$$$k$h$&$G$9!#e(B
e$B@5$7$$=$@5$+$o$+$j$^$;$s$,!"$H$j$"$($:0J2<$GF0$/$h$&$K$J$j$^$7$?!#e(B

Index: compile.c

— compile.c (revision 12903)
+++ compile.c (working copy)
@@ -1318,8 +1318,10 @@
REMOVE_ELEM(&iobj->link);
}
else if (iobj != diobj && diobj->insn_id == BIN(jump)) {

  •  OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0);
    
  •  goto again;
    
  •  if (OPERAND_AT(iobj, 0) != OPERAND_AT(diobj, 0)) {
    
  • OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0);
  • goto again;
  •  }
    
    }
    else if (diobj->insn_id == BIN(leave)) {
    /*

e$B!!$5$5$@$G$9!#e(B

Yusuke ENDOH wrote:

else if (iobj != diobj && diobj->insn_id == BIN(jump)) {

  •  OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0);
    
  •  goto again;
    
  •  if (OPERAND_AT(iobj, 0) != OPERAND_AT(diobj, 0)) {
    
  • OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0);
  • goto again;
  •  }
    
    }
    else if (diobj->insn_id == BIN(leave)) {
    /*

e$B!!$"$j$,$H$&$4$6$$$^$9!#B?J,Bg>fIW$@$H;W$&$N$G%3%_%C%H$7$^$9!#e(B