[Bug: trunk] Fwd: [ruby-list:47272] case when $B@0?t$H<B?t$NHf3S(B (ruby 1.9)

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

e$B!!K\7o$r%P%0$H$7$FEPO?$7$^$9!%e(B

-------- Original Message --------
Subject: [ruby-list:47272] case when e$B@0?t$H<B?t$NHf3Se(B (ruby 1.9)
Date: Fri, 30 Jul 2010 14:41:58 +0900
From: e$B>.EDe(B e$BMxDLe(B [email protected]
Reply-To: [email protected]
To: [email protected] (ruby mailing list)

e$B>.EDMxDL$H?=$7$^$9!#e(B

ruby 1.9.1 e$B$G$NF0:n$,$*$+$7$$$h$&$K;W$&$N$G$9$,!"$I$&$G$9$+!#e(B

$ ruby -e ’
puts RUBY_VERSION
case 1
when 1.0 ; puts “SAME”
else puts “DIFFERNT”
end ’

=> 1.9.1
DIFFERNT

=> 1.8.7
SAME

when e$B@a$rJQ?t$K$9$k$H$A$c$s$HF0$-$^$9!#e(B

T.Oda

e$B%A%1%C%He(B #3696 e$B$,99?7$5$l$^$7$?!#e(B (by Ikuo KOBORI)

e$B>.KY$H$$$$$^$9!#e(B

e$B0J2<$N$h$&$K$7$F=$@5$G$-$^$7$?$N$G!“Js9p$7$^$9!#e(B
whene$B$K$”$i$o$l$k$N$,$9$Y$FDj?t$N$H$-!“@0?t$@$m$&$HIbF0>.?tE@?t$G$”$m$&$H%O%C%7%e%F!<%V%k$KEPO?$7$F$$$^$9!#e(B
e$B$9$k$H>.?t$H@0?t$NAH$_9g$o$;$G$O!"Hf3S$7$F$b0lCW$7$J$/$J$C$F$7$^$$$^$9!Je(B1
e$B$He(B 1.0 e$B$N>l9g$J$I!K!#e(B
e$B$J$N$G>.?t$r@0?t$K4]$a$F$b@:EY$,Mn$A$J$$$H$-$O!“JQ49$7$F$+$i%F!<%V%k$KEPO?$9$k$h$&$K$7$^$7$?!#e(Bcase
e$B$K>.?t$,$”$i$o$l$?$H$-$bF1MM$G$9!#e(B

e$B$=$NB>$N>l9g$K$O%F!<%V%k$r:n$C$?$H$7$F$b!“F~$kJ*$H7?$,0lCW$7$F$$$J$$$HCM$OF1$8$K$J$k$3$H$O$J$$$N$G!”$=$l$>$lFCJL07$$$K$7$^$7$?!#$3$&$9$k$3$H$Ge(B
case
e$B$KFH<+$N%*%V%8%'%/%H$,EO$5$l$?$H$-$KBP1~$G$-$^$9!#Nc$($P$D$.$N$h$&$J>l9g$G$9!#e(B

class C
def ==(other)
true
end
end

obj = C.new
case obj
when 1
p “OK”
else
p “NG”
end

e$B$3$N$H$-$K$be(B “OK” e$B$H=PNO$5$l$k$h$&$K$J$j$^$9!#e(B

diff --git a/compile.c b/compile.c
index 2fd804c…f5f3508 100644
— a/compile.c
+++ b/compile.c
@@ -2302,14 +2302,22 @@ case_when_optimizable_literal(NODE * node)
{
switch (nd_type(node)) {
case NODE_LIT: {

  • VALUE v = node->nd_lit;
  • if (SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cNumeric)) {
  •  return v;
    
  • }
  • break;
  •    VALUE v = node->nd_lit;
    
  •    if ((SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cInteger))) {
    
  •        return v;
    
  •    }
    
  •    if (rb_obj_is_kind_of(v, rb_cFloat)) {
    
  •        if (RFLOAT_VALUE(v) == (long long)RFLOAT_VALUE(v)) {
    
  •            return rb_funcall(v, rb_intern("to_i") , 0);
    
  •        }
    
  •        else {
    
  •            return v;
    
  •        }
    
  •    }
    
  •    break;
     }
     case NODE_STR:
    
  • return node->nd_lit;
  •    return node->nd_lit;
    
    }
    return Qfalse;
    }
    diff --git a/insns.def b/insns.def
    index fcd97ae…bcf5aa8 100644
    — a/insns.def
    +++ b/insns.def
    @@ -1260,28 +1260,40 @@ opt_case_dispatch
    (…, VALUE key)
    () // inc += -1;
    {
  • if (BASIC_OP_UNREDEFINED_P(BOP_EQQ)) {
  • VALUE val;
  • if (st_lookup(RHASH_TBL(hash), key, &val)) {
  •  JUMP(FIX2INT(val));
    
  • }
  • else {
  •  JUMP(else_offset);
    
  • }
  • }
  • else {
  • struct opt_case_dispatch_i_arg arg;
  • struct opt_case_dispatch_i_arg arg;
  • arg.obj = key;
  • arg.label = -1;
  • st_foreach(RHASH_TBL(hash), opt_case_dispatch_i, (st_data_t)&arg);
  • if (arg.label != -1) {
  •  JUMP(arg.label);
    
  • }
  • else {
  •  JUMP(else_offset);
    
  • }
  • switch(TYPE(key))
  • {
  •  case T_FLOAT:
    
  •      if (RFLOAT_VALUE(key) == (long long)RFLOAT_VALUE(key)) {
    
  •          key = rb_funcall(key, rb_intern("to_i") , 0);
    
  •      }
    
  •  case T_SYMBOL: /* fall through */
    
  •  case T_FIXNUM:
    
  •  case T_BIGNUM:
    
  •  case T_STRING:
    
  •    if (BASIC_OP_UNREDEFINED_P(BOP_EQQ)) {
    
  •        VALUE val;
    
  •        if (st_lookup(RHASH_TBL(hash), key, &val)) {
    
  •            JUMP(FIX2INT(val));
    
  •        }
    
  •        else {
    
  •            JUMP(else_offset);
    
  •        }
    
  •        break;
    
  •    }
    
  •  default: /* fall through (else) */
    
  •      arg.obj = key;
    
  •      arg.label = -1;
    
  •      st_foreach(RHASH_TBL(hash), opt_case_dispatch_i, 
    

(st_data_t)&arg);
+

  •      if (arg.label != -1) {
    
  •          JUMP(arg.label);
    
  •      }
    
  •      else {
    
  •          JUMP(else_offset);
    
  •      }
    
  •      break;
    
    }
    }

http://redmine.ruby-lang.org/issues/show/3696

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:42179] [Ruby 1.9-Bug#3696] Fwd:
[ruby-list:47272] case when e$B@0?t$H<B?t$NHf3Se(B (ruby 1.9)”
on Sun, 5 Sep 2010 09:11:48 +0900, _ wanabe [email protected]
writes:

|e$B%Q%C%A$"$j$,$H$&$4$6$$$^$9!#GR8+$7$^$7$?!#e(B
|e$BBg6Z$G$O%P%C%A%j$@$H;W$&$N$G$9$,!"e(Blong long e$B$r;H$C$F$$$k$H$3$m$de(B
|e$BB.EYE*$KITMx$Je(B rb_obj_is_kind_of() e$B$r;H$C$F$$$k$H$3$m$J$Ie(B
|e$B$4$/:Y$+$$ItJ,$,5$$K$J$C$?$N$G>/$7JQ$($F$$^$7$?!#e(B
|
|VM e$B$NJQ99$G$O$"$j$^$9$,!"1F6A$O8BDjE*$H;W$o$l$k$N$Ge(B
|e$B%3%
%C%H$7$F$7$^$*$&$H;W$$$^$9$,$h$m$7$$$G$7$g$&$+!#e(B

e$B$I$&$>!#e(B

e$B%A%1%C%He(B #3696 e$B$,99?7$5$l$^$7$?!#e(B (by _ wanabe)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

This issue was solved with changeset r29203.
Koichi, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


http://redmine.ruby-lang.org/issues/show/3696

e$B%A%1%C%He(B #3696 e$B$,99?7$5$l$^$7$?!#e(B (by _ wanabe)

ruby -v ruby 1.9.3dev (2010-09-01 trunk 29077)
[i386-mingw32]e$B$K%;%C%He(B

e$B%o%J%Y$H?=$7$^$9!#e(B

e$B%Q%C%A$"$j$,$H$&$4$6$$$^$9!#GR8+$7$^$7$?!#e(B
e$BBg6Z$G$O%P%C%A%j$@$H;W$&$N$G$9$,!"e(Blong long
e$B$r;H$C$F$$$k$H$3$m$de(B
e$BB.EYE*$KITMx$Je(B rb_obj_is_kind_of() e$B$r;H$C$F$$$k$H$3$m$J$Ie(B
e$B$4$/:Y$+$$ItJ,$,5$$K$J$C$?$N$G>/$7JQ$($F$_$^$7$?!#e(B

VM e$B$NJQ99$G$O$"$j$^$9$,!"1F6A$O8BDjE*$H;W$o$l$k$N$Ge(B
e$B%3%_%C%H$7$F$7$^$*$&$H;W$$$^$9$,$h$m$7$$$G$7$g$&$+!#e(B

diff --git a/compile.c b/compile.c
index 2fd804c…189ee43 100644
— a/compile.c
+++ b/compile.c
@@ -2303,6 +2303,10 @@ case_when_optimizable_literal(NODE * node)
switch (nd_type(node)) {
case NODE_LIT: {
VALUE v = node->nd_lit;

  • if (TYPE(v) == T_FLOAT &&
  •  RFLOAT_VALUE(v) == (LONG_LONG)RFLOAT_VALUE(v)) {
    
  •  return LL2NUM(RFLOAT_VALUE(v));
    
  • }
    if (SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cNumeric)) {
    return v;
    }
    diff --git a/insns.def b/insns.def
    index fcd97ae…d6f8153 100644
    — a/insns.def
    +++ b/insns.def
    @@ -1260,16 +1260,26 @@ opt_case_dispatch
    (…, VALUE key)
    () // inc += -1;
    {
  • if (BASIC_OP_UNREDEFINED_P(BOP_EQQ)) {
  • VALUE val;
  • if (st_lookup(RHASH_TBL(hash), key, &val)) {
  •  JUMP(FIX2INT(val));
    
  • }
  • else {
  •  JUMP(else_offset);
    
  • switch(TYPE(key)) {
  •  case T_FLOAT:
    
  • if (RFLOAT_VALUE(key) == (LONG_LONG)RFLOAT_VALUE(key)) {
  •  key = LL2NUM(RFLOAT_VALUE(key));
    
  • }
  •  case T_SYMBOL: /* fall through */
    
  •  case T_FIXNUM:
    
  •  case T_BIGNUM:
    
  •  case T_STRING:
    
  • if (BASIC_OP_UNREDEFINED_P(BOP_EQQ)) {
  •  VALUE val;
    
  •  if (st_lookup(RHASH_TBL(hash), key, &val)) {
    
  • JUMP(FIX2INT(val));
  •  }
    
  •  else {
    
  • JUMP(else_offset);
  •  }
    
  •  break;
    
    }
  • }
  • else {
  •  default: { /* fall through (else) */
    

    struct opt_case_dispatch_i_arg arg;

    arg.obj = key;
    @@ -1282,6 +1292,7 @@ opt_case_dispatch
    else {
    JUMP(else_offset);
    }

  •  }
    

    }
    }


http://redmine.ruby-lang.org/issues/show/3696

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

e$B!!$3$N7o$,$“$C$F!“e(Bopt_case_dispatch
e$B$r8+$F$$$?$s$G$9$,!”%R%C%H$7$J$$$H$-e(B
e$B$N5sF0$K$D$$$F!”>/$79M$($F$_$^$7$?!#e(B

e$B!!%R%C%H$7$J$$$H$-!J7?$,$3$N:GE,2=$G$-$k7?$8$c$J$+$C$?!"$b$7$/$OCM$,0c$Ce(B
e$B$?!K$H$-$O!"e(Bst_foreach e$B$Ge(B === e$B$r9T$$!“e(Bcase/when
e$B$r<B8=$7$F$$$^$9!#$G$9e(B
e$B$,!”$$$/$D$+$NM}M3$+$i!J$?$V$s!K!"e(B===
e$B$r=g$K9T$&%P%$%H%3!<%I$b!JL5BL$K!Ke(B
e$B@8@.$5$l$F$$$^$9!#$D$^$j!"e(Bopt_case_dispatch
e$B$+$i!“C1$KH4$1$k$@$1$G$b!”$-e(B
e$B$A$s$He(B === e$B$r$9$k$o$1$G$9!#e(B

e$B!!$5$F!“$I$C$A$,B.$$$N$+!”$HD4$Y$?$H$3$m!“e(Bst_foreach
e$B$h$j$b!”%P%$%H%3!<e(B
e$B%I<B9T$KG$$;$?$[$&$,<c43B.$$$3$H$,$o$+$j$^$7$?!#e(Bst_foreach
e$B$G$?$I$k%j%9e(B
e$B%H$,D9$1$l$PD9$$$[$I!“$=$N798~$,82Cx$G$”$k$3$H$,$o$+$j$^$7$?!#e(B

e$B!!M}M3$O!“e(Bforeach e$B$G$?$I$k$h$j$be(B VM
e$B$G$?$I$kJ}$,B.$$$H$+!”$=$&$$$&$N$@$He(B
e$B;W$$$^$9!#e(B

e$B!!$H$$$&$o$1$G!“$=$NJs9p$H!”=$@5$r$*Aw$j$7$^$9!#e(B

e$B!!2?EY$bF1$8%O%C%7%e$KBP$7$Fe(B Hash#each e$B$9$k$h$&$J%3!<%I$Oe(B
eval e$B$GE83+$7e(B
e$B$A$c$C$?J}$,B.$$$+$b$M!“$H$$$&CN8+$G$b$”$j$^$9$,!“$5$F$=$&$$$&%1!<%9$O$Ie(B
e$B$l$@$1$”$k$s$@$m$&$+!)e(B

mswin32
http://www.atdot.net/fp_store/f.0tse9l/file.graph.png

linux32 (on VirtualBox)
http://www.atdot.net/fp_store/f.7tse9l/file.graph.png

e$B%0%i%U$O!"e(B
e$B2#<4$,!V<:GT$9$ke(B when e$B$N?t!Je(Bst_foreach
e$B$G$?$I$k2s?t!K!We(B
e$B=D<4$,!V<B9T;~4V!JIC!K!We(B
e$B$G$9!#e(B

e$B$A$J$_$K!"$b$A$m$s%R%C%H$9$k$H$-$Oe(B when
e$B$N?t$O4X78$J$/B.$$$G$9!#e(B

e$B%F%9%H%3!<%I!'e(B
require ‘benchmark’

n = 10_000_000
Benchmark.bm{|x|
[true, false, Object.new].each{|obj|
20.times{|i|
ary = (0…i).to_a
obj = i if obj == true
x.report(“#{obj}\t#{i+1}”){
eval %Q{
n.times{
case obj
when #{ary.join(", ")}
# ignore
else
# ignore
end
}
}
}
}
}
}

e$B%Q%C%A!'e(B

Index: insns.def

— insns.def (revision 29350)
+++ insns.def (working copy)
@@ -1281,20 +1281,8 @@
}
break;
}

  •  default: { /* fall through (else) */
    
  • struct opt_case_dispatch_i_arg arg;
  • arg.obj = key;
  • arg.label = -1;
  • st_foreach(RHASH_TBL(hash), opt_case_dispatch_i, (st_data_t)&arg);
  • if (arg.label != -1) {
  •  JUMP(arg.label);
    
  • }
  • else {
  •  JUMP(else_offset);
    
  • }
  •  }
    
  •  default:
    
  • break;
    }
    }

Index: vm_insnhelper.c

— vm_insnhelper.c (revision 29350)
+++ vm_insnhelper.c (working copy)
@@ -1699,22 +1699,3 @@
return Qundef;
}

-struct opt_case_dispatch_i_arg {

  • VALUE obj;
  • int label;
    -};

-static int
-opt_case_dispatch_i(st_data_t key, st_data_t data, st_data_t p)
-{

  • struct opt_case_dispatch_i_arg *arg = (void *)p;
  • if (RTEST(rb_funcall((VALUE)key, idEqq, 1, arg->obj))) {
  • arg->label = FIX2INT((VALUE)data);
  • return ST_STOP;
  • }
  • else {
  • return ST_CONTINUE;
  • }
    -}