summaryrefslogtreecommitdiffstats
path: root/js/src/tests/js1_5/extensions/regress-226507.js
blob: 8d4fc0dd7726a52f146f9ceec9275fb951ea9ac5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 *
 * Date:    24 Nov 2003
 * SUMMARY: Testing for recursion check in js_EmitTree
 *
 * See http://bugzilla.mozilla.org/show_bug.cgi?id=226507
 * Igor's comments:
 *
 * "For example, with N in the test  set to 35, I got on my RedHat
 * Linux 10 box a segmentation fault from js after setting the stack limit
 * to 100K. When I set the stack limit to 20K I still got the segmentation fault.
 * Only after -s was changed to 15K, too-deep recursion was detected:
 *

 ~/w/js/x> ulimit -s
 100
 ~/w/js/x> js  fintest.js
 Segmentation fault
 ~/w/js/x> js -S $((20*1024)) fintest.js
 Segmentation fault
 ~/w/js/x> js -S $((15*1024)) fintest.js
 fintest.js:19: InternalError: too much recursion

 *
 * After playing with numbers it seems that while processing try/finally the
 * recursion in js_Emit takes 10 times more space the corresponding recursion
 * in the parser."
 *
 *
 * Note the use of the new -S option to the JS shell to limit stack size.
 * See http://bugzilla.mozilla.org/show_bug.cgi?id=225061. This in turn
 * can be passed to the JS shell by the test driver's -o option, as in:
 *
 * perl jsDriver.pl -e smdebug -fTEST.html -o "-S 100" -l js1_5/Regress
 *
 */
//-----------------------------------------------------------------------------
var UBound = 0;
var BUGNUMBER = 226507;
var summary = 'Testing for recursion check in js_EmitTree';
var status = '';
var statusitems = [];
var actual = '';
var actualvalues = [];
var expect= '';
var expectedvalues = [];


/*
 * With stack limit 100K on Linux debug build even N=30 already can cause
 * stack overflow; use 35 to trigger it for sure.
 */
var N = 350;

var counter = 0;
function f()
{
  ++counter;
}


/*
 * Example: if N were 3, this is what |source|
 * would end up looking like:
 *
 *     try { f(); } finally {
 *     try { f(); } finally {
 *     try { f(); } finally {
 *     f(1,1,1,1);
 *     }}}
 *
 */
var source = "".concat(
  repeat_str("try { f(); } finally {\n", N),
  "f(",
  repeat_str("1,", N),
  "1);\n",
  repeat_str("}", N));

// Repeat it for additional stress testing
source += source;

/*
 * In Rhino, eval() always uses interpreted mode.
 * To use compiled mode, use Script.exec() instead.
 */
if (typeof Script == 'undefined')
{
  print('Test skipped. Script not defined.');
  expect = actual = 0;
}
else
{
  try
  {
    var script = Script(source);
    script();


    status = inSection(1);
    actual = counter;
    expect = (N + 1) * 2;
  }
  catch(ex)
  {
    actual = ex + '';
  }
}
addThis();


//-----------------------------------------------------------------------------
test();
//-----------------------------------------------------------------------------



function repeat_str(str, repeat_count)
{
  var arr = new Array(--repeat_count);
  while (repeat_count != 0)
    arr[--repeat_count] = str;
  return str.concat.apply(str, arr);
}


function addThis()
{
  statusitems[UBound] = status;
  actualvalues[UBound] = actual;
  expectedvalues[UBound] = expect;
  UBound++;
}


function test()
{
  enterFunc('test');
  printBugNumber(BUGNUMBER);
  printStatus(summary);

  for (var i=0; i<UBound; i++)
  {
    reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
  }

  exitFunc ('test');
}