Emptstack dumps core

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

emptstack e$B$r;H$&$H%i%Y%k$Ne(B sp
e$B$N7W;;$,@5$7$/$G$-$J$/$J$j$^$9!#e(B
e$B6qBNE*$K$O!"0J2<$Ne(B 3 e$B$D$N%W%m%0%i%`$,$9$Y$FMn$A$^$9!#e(B

next e$B$,e(B emptstack e$B$K%3%s%Q%$%k$5$l$kNce(B

1.times do
[
1, 2, 3, 4, 5, 6, 7, 8,
begin
false ? next : p
break while true
end
]
end

redo e$B$,e(B emptstack e$B$K%3%s%Q%$%k$5$l$kNce(B

1.times do
[
1, 2, 3, 4, 5, 6, 7, 8,
begin
false ? redo : p
break while true
end
]
end

return e$B$,e(B emptstack e$B$K%3%s%Q%$%k$5$l$kNce(B

def foo
[
1, 2, 3, 4, 5, 6, 7, 8,
begin
false ? return : p
break while true
end
]
end
foo

e$B$H$j$"$($:e(B emptstack
e$B$N;HMQ$r$"$-$i$a$k1~5^=hCV$N%Q%C%A$G$9!#e(B
e$B$?$@$7@-G=Nt2=$O$=$l$J$j$K$"$kM=46$,$7$^$9e(B (e$BD4$Y$F$^$;$se(B)
e$B!#e(B

Index: compile.c

— compile.c (revision 14778)
+++ compile.c (working copy)
@@ -2993,11 +2993,8 @@
}
else if (iseq->compile_data->end_label) {
debugs(“next in block\n”);

  •  ADD_INSN (ret, nd_line(node), emptstack);
    
  •  COMPILE(ret, "next val", node->nd_stts);
    
  •  add_ensure_iseq(ret, iseq);
    
  •  ADD_INSNL(ret, nd_line(node), jump,
    
  •      iseq->compile_data->end_label);
    
  •  pop_after_throw = poped;
    
  •  goto next_by_throw;
    
    }
    else if (iseq->type == ISEQ_TYPE_EVAL) {
    next_in_eval:
    @@ -3057,13 +3054,8 @@
    COMPILE_ERROR((ERROR_ARGS “Can’t escape from eval with redo”));
    }
    else if (iseq->compile_data->start_label) {
  •  ADD_INSN (ret, nd_line(node), emptstack);
    
  •  add_ensure_iseq(ret, iseq);
    
  •  ADD_INSNL(ret, nd_line(node), jump,
    
  •      iseq->compile_data->start_label);
    
  •  if (!poped) { /* for stack consistency */
    
  • ADD_INSN(ret, nd_line(node), putnil);
  •  }
    
  •  pop_after_throw = poped;
    
  •  goto redo_by_throw;
    
    }
    else {
    rb_iseq_t *ip;
    @@ -3808,22 +3800,12 @@
    break;
    }
    else {
  • if (is->type == ISEQ_TYPE_METHOD) {

  •    ADD_INSN(ret, nd_line(node), emptstack);
    
  • }

  • COMPILE(ret, “return nd_stts (return val)”, node->nd_stts);

  • if (is->type == ISEQ_TYPE_METHOD) {

  •    add_ensure_iseq(ret, iseq);
    
  •    ADD_INSN(ret, nd_line(node), leave);
    
  • ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x01) /* TAG_RETURN */
    );
  • if (poped) {
  •    ADD_INSN(ret, nd_line(node), pop);
    
    }
  • else {
  •    ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x01) /* 
    

TAG_RETURN */ );

  •    if (poped) {
    
  •  ADD_INSN(ret, nd_line(node), pop);
    
  •    }
    
  • }
    break;
    }
    }

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

Yusuke ENDOH wrote:

07/12/29 e$B$Ke(B Yusuke ENDOH[email protected] e$B$5$s$O=q$-$^$7$?e(B:

e$B$H$j$“$($:e(B emptstack e$B$N;HMQ$r$”$-$i$a$k1~5^=hCV$N%Q%C%A$G$9!#e(B
e$B$?$@$7@-G=Nt2=$O$=$l$J$j$K$"$kM=46$,$7$^$9e(B (e$BD4$Y$F$^$;$se(B) e$B!#e(B
(snip)

e$B$3$N%Q%C%A$K$O%P%0$,$"$j$^$7$?!#$3$N%Q%C%A$@$H0J2<$GMn$A$^$9!#e(B

e$B!!$I$&$b$“$j$,$H$&$4$6$$$^$9!#$3$l$O!”$3$J$$$@e(B IRC
e$B$K$$$C$F$$$?$h$&e(B
e$B$K!"H4K\E*$J2~B$$,I,MW$@$H;W$C$F$$$^$9!Je(Bexplicit e$B$Ke(B sp
e$B$rD4$Y$kJ}K!!K!#e(B

e$B!!:#$“$k%”%$%G%"$O!"e(B

  • while e$B$N@hF,$J$I!“$”$o$;$J$1$l$P$J$i$J$$>l=j$K%i%Y%k$rCV$/e(B (L)
  • emptstack e$B$NBe$o$j$Ke(B adjuststack L e$B$N$h$&$JL?Na$rCV$/e(B
    adjuststack e$B$O2>A[E*$JL?Nae(B
  • e$B:G8e$N%3%s%Q%$%k;~!"e(BL e$B$Ne(B sp e$B$r8+$F!"e(Badjuststack
    e$B$re(B pop
    e$B$rB3$1$kL?Na$KCV$-49$($ke(B

e$B!!$?$@$7!“$3$l$@$He(B sp e$B$N7W;;$N$?$a$Ke(B 1 pass
e$BA}$($F$7$^$&$H$$$&7gE@$,e(B
e$B$”$j$^$9!#@hF|1sF#$5$s$,8@$C$F$$$?$h$&$K!“e(Bcompile_each
e$B<B9TCf$Ke(B sp
e$B$r7W;;$9$k$N$,0lHV%7%s%W%k$G$9$h$M!#e(BADD_INSN e$BEyEy$Ge(B sp
e$B$r7W;;$9$k$Ne(B
e$B$,$$$$$N$+$b$7$l$^$;$s$,!”??7u$K9M$($F$_$J$$$H$A$g$C$H<+?.$,$“$j$^$;e(B
e$B$s!#$b$7$3$l$,8=<BE*$K2DG=$@$H$9$k$H!”>e5-e(B adjuststack
e$B$rA^F~$9$kIte(B
e$BJ,$O$=$N$^$^e(B pop e$BL?Na$KCV$-49$($i$l$^$9$M!#e(B

e$B1sF#$G$9!#e(B

07/12/29 e$B$Ke(B Yusuke ENDOH[email protected] e$B$5$s$O=q$-$^$7$?e(B:

e$B$H$j$“$($:e(B emptstack e$B$N;HMQ$r$”$-$i$a$k1~5^=hCV$N%Q%C%A$G$9!#e(B
e$B$?$@$7@-G=Nt2=$O$=$l$J$j$K$"$kM=46$,$7$^$9e(B (e$BD4$Y$F$^$;$se(B) e$B!#e(B
(snip)

e$B$3$N%Q%C%A$K$O%P%0$,$"$j$^$7$?!#$3$N%Q%C%A$@$H0J2<$GMn$A$^$9!#e(B

def m
p yield
end

m do
x = begin
ensure
next 1
break 2
end
end

e$B$"$s$^$j$A$c$s$HDI$C$F$J$$$G$9$,!"e(BNODE_BREAK e$B$Ne(B throw
e$B$N8e$Ke(B
if(poped) ADD_INSN(pop) e$B$,B-$j$J$$$h$&$G$9!#85$N%Q%C%A$Ke(B
e$B2C$($F0J2<$,I,MW$G$9!#e(B

— compile.c 2007-12-29 15:09:52.000000000 +0900
+++ compile.c 2007-12-29 15:10:04.000000000 +0900
@@ -2951,6 +2951,9 @@
COMPILE(ret, “break val (block)”, node->nd_stts);
ADD_INSN1(ret, nd_line(node), throw,
INT2FIX(level | 0x02) /* TAG_BREAK */ );

  •       if (poped) {
    
  •           ADD_INSN(ret, nd_line(node), pop);
    
  •       }
      }
      else if (iseq->type == ISEQ_TYPE_EVAL) {
        break_in_eval:
    

compile.c e$B$Ne(B NODE_BREAK e$B!“e(BNODE_NEXT e$B!“e(BNODE_REDO
e$B$N$”$?$j$K%P%0$,e(B
e$BF~$j$d$9$$$N$O!”$3$N$"$?$j$N%3!<%I$,$D$.$O$.$@$i$1$K$J$C$F$$$F!"e(B
e$B;kG’@-$,0-$$$N$,860x$N0l$D$G$O$J$$$+$H;W$$$^$7$?e(B (e$B@UG$E>2Ge(B)
e$B!#e(B

e$B$3$l$i$N%3%s%Q%$%kJ}K!$Oe(B (throw e$B$N%%Z%i%s%Ie(B (= level)
e$B0J30e(B)e$B$Oe(B
e$B$[$\BP>NE
$K$J$k$N$,<+A3$@$H;W$$$^$9!#$J$N$G%3!<%I$N8+$?L$b$J$k$Y$/e(B
e$BBP>NE*$K$9$k%Q%C%A$r=q$$$F$_$^$7$?!#e(B

Index: compile.c

— compile.c (revision 14780)
+++ compile.c (working copy)
@@ -2920,93 +2920,51 @@
break;
}
case NODE_BREAK:{

  • unsigned long level = 0;
  • 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);
    
  •  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:
  •  /* escape from block */
    
  •  COMPILE(ret, "break val (block)", node->nd_stts);
    
  •  ADD_INSN1(ret, nd_line(node), throw,
    
  •      INT2FIX(level | 0x02) /* TAG_BREAK */ );
    
  • }
  • else if (iseq->type == ISEQ_TYPE_EVAL) {
  • if (iseq->compile_data->redo_label == 0 && iseq->type ==
    ISEQ_TYPE_EVAL) {
    break_in_eval:
    COMPILE_ERROR((ERROR_ARGS “Can’t escape from eval with break”));
    }
    else {
  •  rb_iseq_t *ip = iseq->parent_iseq;
    
  •  unsigned long level = 0;
    
  •  rb_iseq_t *ip = iseq;
     while (ip) {
    
  • level++;
    if (ip->compile_data->redo_label != 0) {
  •    level = 0x8000;
    
  •    if (ip->compile_data->loopval_popped == 0) {
    
  •  /* need value */
    
  •  level |= 0x4000;
    
  •    }
    
  •    goto break_by_insn;
    
  •    level = 0x8000 | 0x4000;
    
  •    break;
    
    }
    else if (ip->type == ISEQ_TYPE_BLOCK) {
    level <<= 16;
  •    goto break_by_insn;
    
  •    break;
    
    }
    else if (ip->type == ISEQ_TYPE_EVAL) {
    goto break_in_eval;
    }
  • level++;
    ip = ip->parent_iseq;
    }
  •  COMPILE_ERROR((ERROR_ARGS "Invalid break"));
    
  •  if (ip != 0) {
    
  • COMPILE(ret, “break val”, node->nd_stts);
  • ADD_INSN1(ret, nd_line(node), throw,
  •    INT2FIX(level | 0x02) /* TAG_BREAK */ );
    
  • if (poped) {
  •    ADD_INSN(ret, nd_line(node), pop);
    
  • }
  •  }
    
  •  else {
    
  • COMPILE_ERROR((ERROR_ARGS “Invalid break”));
  •  }
    
    }
    break;
    }
    case NODE_NEXT:{
  • unsigned long level = 0;

  • int pop_after_throw = 0;

  • if (iseq->compile_data->redo_label != 0) {

  •  /* next in while loop */
    
  •  debugs("next in while\n");
    
  •  pop_after_throw = poped;
    
  •  goto next_by_throw;
    
  • }

  • else if (iseq->compile_data->end_label) {

  •  debugs("next in block\n");
    
  •  ADD_INSN (ret, nd_line(node), emptstack);
    
  •  COMPILE(ret, "next val", node->nd_stts);
    
  •  add_ensure_iseq(ret, iseq);
    
  •  ADD_INSNL(ret, nd_line(node), jump,
    
  •      iseq->compile_data->end_label);
    
  • }

  • else if (iseq->type == ISEQ_TYPE_EVAL) {

  • if (iseq->compile_data->redo_label == 0 && iseq->type ==
    ISEQ_TYPE_EVAL) {
    next_in_eval:
    COMPILE_ERROR((ERROR_ARGS “Can’t escape from eval with next”));
    }
    else {
  •  rb_iseq_t *ip;
    
  • next_by_throw:
  •  ip = iseq;
    
  •  unsigned long level = 0;
    
  •  rb_iseq_t *ip = iseq;
     while (ip) {
    
    level = 0x8000;
    if (ip->compile_data->redo_label != 0) {
    @@ -3026,7 +2984,7 @@
    COMPILE(ret, “next val”, node->nd_stts);
    ADD_INSN1(ret, nd_line(node), throw,
    INT2FIX(level | 0x03) /* TAG_NEXT */ );
  • if (pop_after_throw) {
  • if (poped) {
    ADD_INSN(ret, nd_line(node), pop);
    }
    }
    @@ -3037,40 +2995,13 @@
    break;
    }
    case NODE_REDO:{
  • int pop_after_throw = 0;
  • if (iseq->compile_data->redo_label) {
  •  debugs("redo in while");
    

-#if 1

  •  pop_after_throw = poped;
    
  •  goto redo_by_throw;
    

-#else

  •  add_ensure_iseq(ret, iseq);
    
  •  ADD_INSNL(ret, nd_line(node), jump,
    
  •      iseq->compile_data->redo_label);
    
  •  if (!poped) { /* for stack consistency */
    
  • ADD_INSN(ret, nd_line(node), putnil);
  •  }
    

-#endif

  • }
  • else if (iseq->type == ISEQ_TYPE_EVAL) {
  • if (iseq->compile_data->redo_label == 0 && iseq->type ==
    ISEQ_TYPE_EVAL) {
    redo_in_eval:
    COMPILE_ERROR((ERROR_ARGS “Can’t escape from eval with redo”));
    }
  • else if (iseq->compile_data->start_label) {
  •  ADD_INSN (ret, nd_line(node), emptstack);
    
  •  add_ensure_iseq(ret, iseq);
    
  •  ADD_INSNL(ret, nd_line(node), jump,
    
  •      iseq->compile_data->start_label);
    
  •  if (!poped) { /* for stack consistency */
    
  • ADD_INSN(ret, nd_line(node), putnil);
  •  }
    
  • }
    else {
  •  rb_iseq_t *ip;
    
  •  unsigned long level;
    
  • redo_by_throw:
  •  level = 0x8000 | 0x4000;
    
  •  ip = iseq;
    
  •  rb_iseq_t *ip = iseq;
    
  •  unsigned long level = 0x8000 | 0x4000;
     while (ip) {
    
    if (ip->compile_data->redo_label != 0) {
    break;
    @@ -3088,7 +3019,7 @@
    ADD_INSN1(ret, nd_line(node), throw,
    INT2FIX(level | 0x05) /* TAG_REDO */ );
  • if (pop_after_throw) {
  • if (poped) {
    ADD_INSN(ret, nd_line(node), pop);
    }
    }
    @@ -3808,22 +3739,12 @@
    break;
    }
    else {
  • if (is->type == ISEQ_TYPE_METHOD) {

  •    ADD_INSN(ret, nd_line(node), emptstack);
    
  • }

  • COMPILE(ret, “return nd_stts (return val)”, node->nd_stts);

  • if (is->type == ISEQ_TYPE_METHOD) {

  •    add_ensure_iseq(ret, iseq);
    
  •    ADD_INSN(ret, nd_line(node), leave);
    
  • ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x01) /* TAG_RETURN */
    );
  • if (poped) {
  •    ADD_INSN(ret, nd_line(node), pop);
    
    }
  • else {
  •    ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x01) /* 
    

TAG_RETURN */ );

  •    if (poped) {
    
  •  ADD_INSN(ret, nd_line(node), pop);
    
  •    }
    
  • }
    break;
    }
    }

e$B1sF#$G$9!#e(B

07/12/29 e$B$Ke(B SASADA Koichi[email protected] e$B$5$s$O=q$-$^$7$?e(B:

e$B$rB3$1$kL?Na$KCV$-49$($ke(B

e$B$?$@$7!“$3$l$@$He(B sp e$B$N7W;;$N$?$a$Ke(B 1 pass e$BA}$($F$7$^$&$H$$$&7gE@$,e(B
e$B$”$j$^$9!#e(B

n e$B2sJ,e(B pop e$B$r$9$kL?Nae(B (popn?) e$B$rDI2C$9$l$Pe(B
iseq_set_sequence e$B$G$G$-$ke(B
e$B5$$,$7$^$9!#e(B

e$B@hF|1sF#$5$s$,8@$C$F$$$?$h$&$K!“e(Bcompile_each e$B<B9TCf$Ke(B sp
e$B$r7W;;$9$k$N$,0lHV%7%s%W%k$G$9$h$M!#e(BADD_INSN e$BEyEy$Ge(B sp e$B$r7W;;$9$k$Ne(B
e$B$,$$$$$N$+$b$7$l$^$;$s$,!”??7u$K9M$($F$_$J$$$H$A$g$C$H<+?.$,$“$j$^$;e(B
e$B$s!#$b$7$3$l$,8=<BE*$K2DG=$@$H$9$k$H!”>e5-e(B adjuststack e$B$rA^F~$9$kIte(B
e$BJ,$O$=$N$^$^e(B pop e$BL?Na$KCV$-49$($i$l$^$9$M!#e(B

e$B<B$O:#$=$l$r$d$C$F$_$F$^$9!#$^$@e(B make test
e$B$GBgNL$K%(%i!<$,=P$k>uBVe(B
e$B$G$9$1$I!#e(Bcompile_data e$B$Ke(B int sp
e$B$r;}$?$;$F!“e(Bnew_insn_core e$B$G$=$Ne(B sp e$B$re(B
insn_stack_increase e$B$r$9$k46$8$G$9!#e(B
e$B$7$+$7$3$N%”%W%m!<%A$@$He(B ADD_INSN
e$B$,I{:nMQ$r;}$D$3$H$K$J$k$N$G!"e(B
e$B$d$C$Q$j%3!<%I$N2DFI@-!&%a%s%F%J%s%9@-$,2<$,$j$=$&$J46?($G$9!#e(B

e$B$$$C$=e(B insn_stack_increase e$B$r;H$o$:$K!“3Fe(B NODE
e$B$N%3%s%Q%$%kItJ,$Ge(B
e$BL@<(E*$Ke(B sp e$B$r7W;;$9$k%3!<%I$rA^F~$7$F$$$C$?J}$,$$$$$N$+$b!#e(B
e$B$=$C$A$NJ}$,e(B ADD_INSN e$BKh$Ke(B sp
e$B7W;;$r$7$J$/$F$$$$J,B.$=$&$G$b$”$j$^$9!#e(B