Forum: Ruby-dev [Bug #982] stack level too deep for long Array initialization

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 Martin Dürst (Guest)
on 2009-01-05 02:57
(Received via mailing list)
Bug #982: stack level too deep for long Array initialization
http://redmine.ruby-lang.org/issues/show/982

$B5/I<<T(B: Martin D$(D+d(Brst
$B%9%F!<%?%9(B: Open, $BM%@hEY(B: Normal
$BC4Ev<T(B: Koichi Sasada, $B%+%F%4%j(B: YARV, Target version: 1.9.2

$B<!$N%9%/%j%W%H$,(B stack level too deep (SystemStackError)
$B$G=*$o$j$^$9!#(B

ruby -e 'puts "A=["; 0.upto(1000000) { puts "  [22, 55]," }; puts "]"' |
ruby

$B$3$l$O(B Bug #943 [ruby-dev:37646]
$B$N%3%T!<$G!"D94|E*$K$I$&$9$k$N$+(B
$B$r9M$($k$H$a$N%P%0$G$9!#(B

ruby -e 'puts "A=[]"; 0.upto(1000000) { puts "A<<[22, 55]" }' | ruby

$B$G0U?^$N$b$N$,$G$-$k$,!"$I$&$7$F$b%G!<%?$N=i4|2=$r@k8@E*$G$G$-$J$/!"(B
$B<jB3E*$K$7$J$$$H$$$1$J$$$N$O$h$/$J$$$H;W$C$F$$$^$9!#%f!<%6$+$i8+$k$H(B
$B%a%>%I$N?<$$8F$S=P$7$J$I$,%9%?%C%/%*!<%P%U%m!<$K$J$k$N$OJ,$+$k$O$:(B
$B$G$9$,!"%G!<%?$N=i4|2=$@$1$G$=$&$$$&LdBj$K$J$k$N$O%S%C%/%j$9$k(B
$B$G$7$g$&!#(B

$B:{ED$5$s$K$h$j$^$9$H!"(B

>$B!!>e5-Nc$N$h$&$K!$6u$NG[Ns$r:n$C$F!$$=$l$K(B push $B$9$k$h$&$KJQ99$9$k$3$H$b(B
>$B2DG=$G$9$,!$$=$l$r=PMh$k$h$&$K$7$?$[$&$,$$$$$G$9$+$M$'!%$9$k$K$7$F$b!$(B
>1.9.2 $B$GL?NaDI2C$C$F$3$H$K$J$k$H;W$$$^$9$,!%$=$&JQ99$7$?$i!$$A$g$C$HB.EY(B
>$B$,CY$/$J$k$C$F$/$i$$$+$J$!!%(B

$B$b$&0l$D$N$d$jJ}$O(B stack level too deep
$B$K$J$C$?$H$-$K!"%9%?%C%/$K$"$k(B
$BG[Ns$NMWAG$r0l5$$KG[Ns$KDI2C$7!"<!$NMWAG$+$i$^$@%9%?%C%/$K:\$;$k$3$H(B
$B$,9M$($i$l$k!#$G$b!"$3$&$$$&$N$r<BAu$9$k$N$O$I$N$0$i$$Fq$7$$$G$7$g$&$+!#(B

$B$h$m$7$/$*4j$$$7$^$9!#(B    Martin.
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 Yusuke Endoh (Guest)
on 2009-01-06 19:12
(Received via mailing list)
$B%A%1%C%H(B #982 $B$,99?7$5$l$^$7$?!#(B (by Yusuke Endoh)


$B1sF#$G$9!#(B

> $B<!$N%9%/%j%W%H$,(B stack level too deep (SystemStackError) $B$G=*$o$j$^$9!#(B

> ruby -e 'puts "A=["; 0.upto(1000000) { puts "  [22, 55]," }; puts "]"' | ruby


$B$I$&$$$&$H$-$K$3$l$,I,MW$K$J$C$?$N$+6=L#$,$"$j$^$9!#(B


$B$=$l$O$=$l$H$7$F!"%Q%C%A$r=q$$$F$_$^$7$?!#(B

- concatarray $BL?Na$rGQ;_$7$F!"0z?t$r$H$k(B concatarrays
$BL?Na$rF3F~$7$?(B
- checkints $BL?Na$rF3F~$7$?(B
- $B5pBg$JG[Ns%j%F%i%k$O(B 1000 $B8D$4$H$K(B newarray
$B$7$F:G8e$K(B concatarrays $B$9$k(B

$B$H$j$"$($:G[Ns$@$1$NBP=h$J$N$G!"5pBg$J%O%C%7%e%j%F%i%k$r=q$/$H$?$V$sMn$A$^$9!#(B


Index: insns.def
===================================================================
--- insns.def  (revision 21356)
+++ insns.def  (working copy)
@@ -40,6 +40,20 @@
     /* none */
 }

+/**
+  @c check interrupts
+  @e check interrupts
+  @j
+ */
+DEFINE_INSN
+checkints
+()
+()
+()
+{
+    RUBY_VM_CHECK_INTS();
+}
+
 /**********************************************************/
 /* deal with variables                                    */
 /**********************************************************/
@@ -486,31 +500,27 @@

 /**
   @c put
-  @e concat two arrays
-  @j $BFs$D$NG[Ns(B ary1, ary2 $B$rO"7k$7%9%?%C%/$X%W%C%7%e$9$k!#(B
+  @e put concatenate arrays
+  @j $B%9%?%C%/%H%C%W$NG[Ns$r(B n
$B8DO"7k$7!$7k2L$r%9%?%C%/$K%W%C%7%e$9$k!#(B
  */
 DEFINE_INSN
-concatarray
-()
-(VALUE ary1, VALUE ary2st)
-(VALUE ary)
+concatarrays
+(rb_num_t num)
+(...)
+(VALUE val) // inc += 1 - num;
 {
-    const VALUE ary2 = ary2st;
-    VALUE tmp1 = rb_check_convert_type(ary1, T_ARRAY, "Array", "to_a");
-    VALUE tmp2 = rb_check_convert_type(ary2, T_ARRAY, "Array", "to_a");
+    int i;

-    if (NIL_P(tmp1)) {
-  tmp1 = rb_ary_new3(1, ary1);
+    val = rb_ary_new();
+    for (i = num - 1; i >= 0; i--) {
+  const VALUE v = TOPN(i);
+  VALUE tmp = rb_check_convert_type(v, T_ARRAY, "Array", "to_a");
+  if (NIL_P(tmp)) {
+      tmp = rb_ary_new3(1, v);
+  }
+  rb_ary_concat(val, tmp);
     }
-
-    if (NIL_P(tmp2)) {
-  tmp2 = rb_ary_new3(1, ary2);
-    }
-
-    if (tmp1 == ary1) {
-  tmp1 = rb_ary_dup(ary1);
-    }
-    ary = rb_ary_concat(tmp1, tmp2);
+    POPN(num);
 }

 /**
Index: compile.c
===================================================================
--- compile.c  (revision 21356)
+++ compile.c  (working copy)
@@ -2195,12 +2195,14 @@
     return COMPILE_OK;
 }

+#define ARRAY_LITERAL_SPLIT_THRESHOLD 1000
+
 static int
-compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root,
-         VALUE opt_p, int poped)
+compile_array(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root, int
poped)
 {
     NODE *node = node_root;
-    int len = node->nd_alen, line = nd_line(node), i=0;
+    int len = node->nd_alen, line = nd_line(node), i=0, split = 0;
+    VALUE opt_p = Qtrue;
     DECL_ANCHOR(anchor);

     INIT_ANCHOR(anchor);
@@ -2211,6 +2213,11 @@
            ruby_node_name(nd_type(node)));
       }

+      if (i > 0 && i % ARRAY_LITERAL_SPLIT_THRESHOLD == 0 && !poped) {
+    ADD_INSN1(anchor, line, newarray,
INT2FIX(ARRAY_LITERAL_SPLIT_THRESHOLD));
+    ADD_INSN(anchor, line, checkints);
+    split++;
+      }
       i++;
       if (opt_p && nd_type(node->nd_head) != NODE_LIT) {
     opt_p = Qfalse;
@@ -2243,17 +2250,36 @@
     }
     else {
   if (!poped) {
-      ADD_INSN1(anchor, line, newarray, INT2FIX(len));
+      if (len % ARRAY_LITERAL_SPLIT_THRESHOLD) {
+    ADD_INSN1(anchor, line, newarray, INT2FIX(len %
ARRAY_LITERAL_SPLIT_THRESHOLD));
+    split++;
+      }
+      if (split >= 2) ADD_INSN1(anchor, line, concatarrays,
INT2FIX(split));
   }
   APPEND_LIST(ret, anchor);
     }
     return len;
 }

-static VALUE
-compile_array(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root, VALUE
opt_p)
+static long
+compile_list(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root)
 {
-    return compile_array_(iseq, ret, node_root, opt_p, 0);
+    NODE *node = node_root;
+    int i = 0;
+
+    if (nd_type(node) != NODE_ZARRAY) {
+  while (node) {
+      if (nd_type(node) != NODE_ARRAY) {
+    rb_bug("compile_list: This node is not NODE_ARRAY, but %s",
+           ruby_node_name(nd_type(node)));
+      }
+      i++;
+      COMPILE(ret, "list element", node->nd_head);
+      node = node->nd_next;
+  }
+    }
+
+    return i;
 }

 static VALUE
@@ -2841,8 +2867,7 @@
       *flag |= VM_CALL_ARGS_SPLAT_BIT;

       if (next_is_array) {
-    argc = INT2FIX(compile_array(iseq, args, argn->nd_head, Qfalse) +
1);
-    POP_ELEMENT(args);
+    argc = INT2FIX(compile_list(iseq, args, argn->nd_head) + 1);
       }
       else {
     argn = argn->nd_head;
@@ -2851,8 +2876,7 @@
       break;
     }
     case NODE_ARRAY: {
-      argc = INT2FIX(compile_array(iseq, args, argn, Qfalse));
-      POP_ELEMENT(args);
+      argc = INT2FIX(compile_list(iseq, args, argn));
       break;
     }
     default: {
@@ -2862,10 +2886,7 @@
     }

     if (nsplat > 1) {
-  int i;
-  for (i=1; i<nsplat; i++) {
-      ADD_INSN(args_splat, nd_line(args), concatarray);
-  }
+  ADD_INSN1(args_splat, nd_line(args), concatarrays, INT2FIX(nsplat));
     }

     if (!LIST_SIZE_ZERO(args_splat)) {
@@ -3746,7 +3767,7 @@
       COMPILE(ret, "NODE_OP_ASGN1 args->head: ",
node->nd_args->nd_head);
       if (flag & VM_CALL_ARGS_SPLAT_BIT) {
     ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
-    ADD_INSN(ret, nd_line(node), concatarray);
+    ADD_INSN1(ret, nd_line(node), concatarrays, INT2FIX(2));
     ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
          argc, Qfalse, LONG2FIX(flag));
       }
@@ -3769,7 +3790,7 @@
       ADD_SEND(ret, nd_line(node), ID2SYM(id), INT2FIX(1));
       if (flag & VM_CALL_ARGS_SPLAT_BIT) {
     ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
-    ADD_INSN(ret, nd_line(node), concatarray);
+    ADD_INSN1(ret, nd_line(node), concatarrays, INT2FIX(2));
     ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
          argc, Qfalse, LONG2FIX(flag));
       }
@@ -4070,7 +4091,7 @@
           ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
       }
       ADD_INSN1(args, nd_line(node), newarray, INT2FIX(j));
-      ADD_INSN (args, nd_line(node), concatarray);
+      ADD_INSN1(args, nd_line(node), concatarrays, INT2FIX(2));
       /* argc is setteled at above */
         }
         else {
@@ -4098,7 +4119,7 @@
   break;
       }
       case NODE_ARRAY:{
-  compile_array_(iseq, ret, node, Qtrue, poped);
+  compile_array(iseq, ret, node, poped);
   break;
       }
       case NODE_ZARRAY:{
@@ -4127,8 +4148,7 @@
   INIT_ANCHOR(list);
   switch (type) {
     case NODE_ARRAY:{
-      compile_array(iseq, list, node->nd_head, Qfalse);
-      size = OPERAND_AT(POP_ELEMENT(list), 0);
+      size = INT2FIX(compile_list(iseq, list, node->nd_head));
       ADD_SEQ(ret, list);
       break;
     }
@@ -4426,14 +4446,14 @@
       case NODE_ARGSCAT:{
   COMPILE(ret, "argscat head", node->nd_head);
   COMPILE(ret, "argscat body", node->nd_body);
-  ADD_INSN(ret, nd_line(node), concatarray);
+  ADD_INSN1(ret, nd_line(node), concatarrays, INT2FIX(2));
   break;
       }
       case NODE_ARGSPUSH:{
   COMPILE(ret, "arsgpush head", node->nd_head);
   COMPILE(ret, "argspush body", node->nd_body);
   ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
-  ADD_INSN(ret, nd_line(node), concatarray);
+  ADD_INSN1(ret, nd_line(node), concatarrays, INT2FIX(2));
   break;
       }
       case NODE_SPLAT:{

--
Yusuke ENDOH <mame@tsg.ne.jp>

----------------------------------------
http://redmine.ruby-lang.org/issues/show/982
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 Yusuke Endoh (Guest)
on 2010-04-27 14:18
(Received via mailing list)
$B%A%1%C%H(B #982 $B$,99?7$5$l$^$7$?!#(B (by Yusuke Endoh)

Target version 1.9.2$B$+$i(B1.9.x$B$KJQ99(B
ruby -v -$B$K%;%C%H(B

$B1sF#$G$9!#(B

$B$5$5$@$5$s$,!V(B1.9.2
$B$K$OITMW$G$O$J$$$G$7$g$&$+!W$H$N8+2r$r=P$7$?$N$G!"(B
target $B$r(B 1.9.x $B$H$7$^$9!#EvLL$O(B Array#<<
$B$J$I$r;H$C$F$/$@$5$$!#(B

$B2?$H$+$7$FM_$7$$$H8@$&@<$,B??t$"$l$P!"Aa$a$KD>$5$l$k$+$b$7$l$^$;$s!#(B

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
http://redmine.ruby-lang.org/issues/show/982
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 "Martin Dürst" <redmine@ruby-lang.org> (Guest)
on 2010-11-12 10:47
(Received via mailing list)
チケット #982 が更新されました。 (by Martin Dürst)


> どういうときにこれが必要になったのか興味があります。

具体的に言いますと、GB-18030 の変換テーブルのためです。
This topic is locked and can not be replied to.