Meta programming might dump core

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

e$B$/$@$i$J$$Js9p$P$+$j$G62=L$G$9$,!"e(B[ruby-dev:31848]
e$B$H;w$?$h$&$J%P%0$re(B
e$BE,Ev$KC5$7$F$_$^$7$?!#e(B1.9 e$B$P$C$+$j$G$9!#e(B

e$B860x$rD4$Y$k5$NO$,L5$$$N$GJs9p$@$1$G$9$_$^$;$s!#e(B

e$BLse(B 100 e$BK|%(%s%H%j$N%O%C%7%e%j%F%i%ke(B:

$ time ./ruby -ve ‘eval("{" + “0=>0,” * 1000000 + “0=>0}”)’
ruby 1.9.0 (2007-09-24 patchlevel 0) [i686-linux]
(eval):1: – control frame ----------
c:0006 p:261958 s:302670847 b:0012 l:000004 d:000011 EVAL (eval):1
c:0005 p:---- s:0011 b:0011 l:000010 d:000010 FINISH :new
c:0004 p:---- s:0009 b:0009 l:000008 d:000008 CFUNC :eval
c:0003 p:0018 s:0005 b:0005 l:000004 d:000004 TOP -e:1
c:0002 p:---- s:0003 b:0003 l:000002 d:000002 FINISH :inherited
c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------

SEGV recieved in SEGV handler

real 0m13.298s
user 0m6.130s
sys 0m6.510s

e$BLse(B 100 e$BK|JQ?t$NB?=EBeF~e(B:

$ time ./ruby -ve ‘p eval(“x,” * 1000000 + “=0”)’
ruby 1.9.0 (2007-09-24 patchlevel 0) [i686-linux]
(eval):1: – control frame ----------
c:0006 p:0006 s:1000015 b:0014 l:000004 d:000013 EVAL (eval):1
c:0005 p:---- s:0012 b:0012 l:000011 d:000011 FINISH :new
c:0004 p:---- s:0010 b:0010 l:000009 d:000009 CFUNC :eval
c:0003 p:0016 s:0006 b:0005 l:000004 d:000004 TOP -e:1
c:0002 p:---- s:0003 b:0003 l:000002 d:000002 FINISH :inherited
c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------

SEGV recieved in SEGV handler

real 0m8.164s
user 0m3.510s
sys 0m4.580s

e$BLse(B 100 e$BK|0z?t$N%a%=%C%I8F$S=P$7e(B:

$ time ./ruby -ve ‘def foo(*a); end; eval(“foo(” + “0,” * 1000000 +
“0)”)’
ruby 1.9.0 (2007-09-24 patchlevel 0) [i686-linux]
(eval):1: – control frame ----------
c:0006 p:261957 s:302705663 b:0012 l:000004 d:000011 EVAL (eval):1
c:0005 p:---- s:0011 b:0011 l:000010 d:000010 FINISH :new
c:0004 p:---- s:0009 b:0009 l:000008 d:000008 CFUNC :eval
c:0003 p:0018 s:0005 b:0005 l:000004 d:000004 TOP -e:1
c:0002 p:---- s:0003 b:0003 l:000002 d:000002 FINISH :inherited
c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------

SEGV recieved in SEGV handler

real 0m6.178s
user 0m2.910s
sys 0m3.200s

false e$B$,e(B || e$B$Ge(B 25000 e$B8DO"$J$C$?<0e(B:

$ time ./ruby -ve ‘eval(“false||” * 25000 + “true”)’
ruby 1.9.0 (2007-09-24 patchlevel 0) [i686-linux]
e$B%;%0%a%s%F!<%7%g%s0cH?$G$9e(B

real 0m3.888s
user 0m3.390s
sys 0m0.490s

e$B$J$+$@$G$9!#e(B

At Tue, 25 Sep 2007 02:49:24 +0900,
Yusuke ENDOH wrote in [ruby-dev:31850]:

e$BLse(B 100 e$BK|%(%s%H%j$N%O%C%7%e%j%F%i%ke(B:

key=>valuee$B$NCM$r@h$Ke(BVMe$B%9%?%C%/$K$9$Y$F@Q$s$G$+$ie(Bnewhashe$B$r<B9T$9e(B
e$B$k$N$G!"$=$3$G%!<%P!<%U%m!<$7$F$$$^$9!#0lAH$:$DDI2C$7$F$$$/$H$$e(B
e$B$&$N$O!"B.EYE
$JLdBj$+$i$5$5$@$5$s$,5$$KF~$i$J$$$h$&$G!#e(B

e$B;W$$IU$/$N$O$3$N$"$?$j!#e(B
(a) e$BB.EY$O>/!9$"$-$i$a$F!"0lAH$:$DDI2Ce(B
(b) VMe$B%9%?%C%/$r3NJ]$G$-$k$+3NG’$9$kL?Na$rDI2Ce(B

e$BLse(B 100 e$BK|JQ?t$NB?=EBeF~e(B:

e$B$3$l$be(Bexpandarraye$B$Ge(B100e$BK|8D$KE83+$9$k$H$-$K%*!<%P!<%U%m!<$7$F$$$^e(B
e$B$9!#e(Bexpandarraye$B$O%5%$%:$,$o$+$C$F$$$k$N$G!"%A%’%C%/$rF~$l$l$P$$e(B
e$B$$$N$G$O$J$$$+$H!#e(B

e$BLse(B 100 e$BK|0z?t$N%a%=%C%I8F$S=P$7e(B:

e$B$3$l$b0z?t$r0lEY%9%?%C%/$KA4It@Q$`$N$G0J2<F1J8!#e(B

false e$B$,e(B || e$B$Ge(B 25000 e$B8DO"$J$C$?<0e(B:

$ time ./ruby -ve ‘eval(“false||” * 25000 + “true”)’
ruby 1.9.0 (2007-09-24 patchlevel 0) [i686-linux]
e$B%;%0%a%s%F!<%7%g%s0cH?$G$9e(B

e$B$3$C$A$Oe(Bbytecodee$B$K%3%s%Q%$%k$9$k$H$3$m$G%^%7%s%9%?%C%/%*!<%P!<%Ue(B
e$B%m!<$7$F$$$^$9!#e(B

e$B$3$NNc$K$D$$$F$O2sHr$9$k$N$O4JC1$G$9$,!"$b$C$HJ#;($K%M%9%H$7$F$$e(B
e$B$?$j$9$k$H$*e$2$G$7$g$&!#e(B

Index: compile.c

— compile.c (revision 13509)
+++ compile.c (working copy)
@@ -1795,9 +1795,14 @@ compile_branch_condition(rb_iseq_t *iseq
LABEL *then_label, LABEL *else_label)
{

  • again:
    switch (nd_type(cond)) {
    case NODE_NOT:
  • compile_branch_condition(iseq, ret, cond->nd_body, else_label,
  •     then_label);
    
  • break;
  • {

  •  LABEL *tmp = else_label;
    
  •  else_label = then_label;
    
  •  then_label = tmp;
    
  •  cond = cond->nd_body;
    
  •  goto again;
    
  • }

    case NODE_AND:
    

@@ -1807,7 +1812,6 @@ compile_branch_condition(rb_iseq_t *iseq
else_label);
ADD_LABEL(ret, label);

  •  compile_branch_condition(iseq, ret, cond->nd_2nd, then_label,
    
  •         else_label);
    
  •  break;
    
  •  cond = cond->nd_2nd;
    
  •  goto again;
    
    }
    case NODE_OR:
    @@ -1817,7 +1821,6 @@ compile_branch_condition(rb_iseq_t *iseq
    label);
    ADD_LABEL(ret, label);
  •  compile_branch_condition(iseq, ret, cond->nd_2nd, then_label,
    
  •         else_label);
    
  •  break;
    
  •  cond = cond->nd_2nd;
    
  •  goto again;
    
    }
    case NODE_LIT: /* NODE_LIT is always not true */
    @@ -3187,18 +3190,20 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_
    case NODE_OR:{
    LABEL *end_label = NEW_LABEL(nd_line(node));
  • COMPILE(ret, “nd_1st”, node->nd_1st);
  • if (!poped) {
  •  ADD_INSN(ret, nd_line(node), dup);
    
  • }
  • if (type == NODE_AND) {
  •  ADD_INSNL(ret, nd_line(node), branchunless, end_label);
    
  • }
  • else {
  •  ADD_INSNL(ret, nd_line(node), branchif, end_label);
    
  • }
  • if (!poped) {
  •  ADD_INSN(ret, nd_line(node), pop);
    
  • }
  • COMPILE_(ret, “nd_2nd”, node->nd_2nd, poped);
  • do {
  •  COMPILE(ret, "nd_1st", node->nd_1st);
    
  •  if (!poped) {
    
  • ADD_INSN(ret, nd_line(node), dup);
  •  }
    
  •  if (type == NODE_AND) {
    
  • ADD_INSNL(ret, nd_line(node), branchunless, end_label);
  •  }
    
  •  else {
    
  • ADD_INSNL(ret, nd_line(node), branchif, end_label);
  •  }
    
  •  if (!poped) {
    
  • ADD_INSN(ret, nd_line(node), pop);
  •  }
    
  • } while ((node = node->nd_2nd) != 0 && nd_type(node) == type);
  • COMPILE_(ret, “nd_2nd”, node, poped);
    ADD_LABEL(ret, end_label);
    break;