[BUG: ruby 1.9.3dev (2011-08-02 revision 32810) [i686-linux]] C の Proc の比較のバグ

$B<G$H?=$7$^$9!#(B

Proc#eq(C $B$N4X?t$O(B proc.c $BFb$N(B proc_eq)$B$G!"(BC $B$GDj5A$7$?(B
Proc
(rb_proc_new
$B$J$I$rMQ$$$FDj5A(B)$B$NHf3S$r9T$&2U=j$KIT6q9g$,$"$j$^$9!#(B
C $B$GDj5A$7$?(B Proc $B$KBP$7$F$b(B iseq
$B$r8+$FHf3S$r9T$C$F$$$k$?$a!"%a%b%j$N>u(B
$B67G!2?$G(B segv $B$rEG$$$?$j(B false $B$N$O$:$,(B true
$B$K$J$C$?$j$7$^$9!#(B

$BLdBj$H$J$k(B proc_eq $B$O0J2<$N$h$&$K$J$C$F$$$F!"(BProc
$B$N<oN`$K$+$+$o$i$:!"(B
proc->block.iseq->iseq_size, proc->block.iseq->local_size,
proc->block.iseq->iseq $B$rMQ$$$FHf3S$7$F$$$^$9!#(B
proc->block.iseq $B$,(B IFUNC_NODE
$B$@$C$?>l9g$O!"4X?t%]%$%s%?$NHf3S$J$I!"JL(B
$B$NJ}K!$GHf3S$r9T$&$Y$-$G$9!#(B

/* $BLdBj$N4X?t(B */
static VALUE
proc_eq(VALUE self, VALUE other)
{
if (self == other) {
return Qtrue;
}
else {
if (rb_obj_is_proc(other)) {
rb_proc_t *p1, *p2;
GetProcPtr(self, p1);
GetProcPtr(other, p2);
if (p1->envval == p2->envval &&
p1->block.iseq->iseq_size == p2->block.iseq->iseq_size &&
p1->block.iseq->local_size == p2->block.iseq->local_size &&
MEMCMP(p1->block.iseq->iseq, p2->block.iseq->iseq, VALUE,
p1->block.iseq->iseq_size) == 0) {
return Qtrue;
}
}
}
return Qfalse;
}

$BE:IU$9$k(B sample.zip $B$K!"(Bproc_eq
$B$KBP$9$k%Q%C%A$HLdBj$H$J$k%3!<%I$NNc$r$^(B
$B$H$a$FF~$l$F$*$-$^$9!#(B
$B:#2s$N%Q%C%A$G$O!"(BRUBY_VM_IFUNC_P $B$G(B C $B$N(B Proc
$B$+$I$&$+$rH=Dj$7!"(Bproc $B#2(B
$B$D$,6&$K(B C $B$N(B Proc $B$@$C$?>l9g$O!"(Bnode->nd_cfnc,
node->nd_aid,
node->nd_tval $B$GHf3S$7$^$9!#(B

$B;29M$K$7$F$$$?$@$1$l$P9,$$$G$9!#(B
$B$h$m$7$/$*4j$$$$$?$7$^$9!#(B

/* $B%Q%C%A(B */
diff --git proc.c proc.c
index 427d1fe…e304295 100644
— proc.c
+++ proc.c
@@ -766,7 +766,18 @@ proc_eq(VALUE self, VALUE other)
rb_proc_t *p1, *p2;
GetProcPtr(self, p1);
GetProcPtr(other, p2);

  •       if (p1->envval == p2->envval &&
    
  •       if (RUBY_VM_IFUNC_P(p1->block.iseq) &&
    

RUBY_VM_IFUNC_P(p2->block.iseq)) {

  •           NODE *nd_ifunc1, *nd_ifunc2;
    
  •           nd_ifunc1 = (NODE *)p1->block.iseq;
    
  •           nd_ifunc2 = (NODE *)p2->block.iseq;
    
  •           if(nd_ifunc1->nd_cfnc == nd_ifunc2->nd_cfnc &&
    
  •              nd_ifunc1->nd_aid == nd_ifunc2->nd_aid &&
    
  •              rb_funcall(nd_ifunc1->nd_tval, idEq, 1,
    

nd_ifunc2->nd_tval)) {

  •               return Qtrue;
    
  •           }
    
  •       } else if (p1->envval == p2->envval &&
    
  •           !RUBY_VM_IFUNC_P(p1->block.iseq) &&
    

!RUBY_VM_IFUNC_P(p2->block.iseq) &&
p1->block.iseq->iseq_size == p2->block.iseq->iseq_size
&&
p1->block.iseq->local_size == p2->block.iseq->local_size
&&
MEMCMP(p1->block.iseq->iseq, p2->block.iseq->iseq,
VALUE,