michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * michael@0: * Date: 24 Nov 2003 michael@0: * SUMMARY: Testing for recursion check in js_EmitTree michael@0: * michael@0: * See http://bugzilla.mozilla.org/show_bug.cgi?id=226507 michael@0: * Igor's comments: michael@0: * michael@0: * "For example, with N in the test set to 35, I got on my RedHat michael@0: * Linux 10 box a segmentation fault from js after setting the stack limit michael@0: * to 100K. When I set the stack limit to 20K I still got the segmentation fault. michael@0: * Only after -s was changed to 15K, too-deep recursion was detected: michael@0: * michael@0: michael@0: ~/w/js/x> ulimit -s michael@0: 100 michael@0: ~/w/js/x> js fintest.js michael@0: Segmentation fault michael@0: ~/w/js/x> js -S $((20*1024)) fintest.js michael@0: Segmentation fault michael@0: ~/w/js/x> js -S $((15*1024)) fintest.js michael@0: fintest.js:19: InternalError: too much recursion michael@0: michael@0: * michael@0: * After playing with numbers it seems that while processing try/finally the michael@0: * recursion in js_Emit takes 10 times more space the corresponding recursion michael@0: * in the parser." michael@0: * michael@0: * michael@0: * Note the use of the new -S option to the JS shell to limit stack size. michael@0: * See http://bugzilla.mozilla.org/show_bug.cgi?id=225061. This in turn michael@0: * can be passed to the JS shell by the test driver's -o option, as in: michael@0: * michael@0: * perl jsDriver.pl -e smdebug -fTEST.html -o "-S 100" -l js1_5/Regress michael@0: * michael@0: */ michael@0: //----------------------------------------------------------------------------- michael@0: var UBound = 0; michael@0: var BUGNUMBER = 226507; michael@0: var summary = 'Testing for recursion check in js_EmitTree'; michael@0: var status = ''; michael@0: var statusitems = []; michael@0: var actual = ''; michael@0: var actualvalues = []; michael@0: var expect= ''; michael@0: var expectedvalues = []; michael@0: michael@0: michael@0: /* michael@0: * With stack limit 100K on Linux debug build even N=30 already can cause michael@0: * stack overflow; use 35 to trigger it for sure. michael@0: */ michael@0: var N = 350; michael@0: michael@0: var counter = 0; michael@0: function f() michael@0: { michael@0: ++counter; michael@0: } michael@0: michael@0: michael@0: /* michael@0: * Example: if N were 3, this is what |source| michael@0: * would end up looking like: michael@0: * michael@0: * try { f(); } finally { michael@0: * try { f(); } finally { michael@0: * try { f(); } finally { michael@0: * f(1,1,1,1); michael@0: * }}} michael@0: * michael@0: */ michael@0: var source = "".concat( michael@0: repeat_str("try { f(); } finally {\n", N), michael@0: "f(", michael@0: repeat_str("1,", N), michael@0: "1);\n", michael@0: repeat_str("}", N)); michael@0: michael@0: // Repeat it for additional stress testing michael@0: source += source; michael@0: michael@0: /* michael@0: * In Rhino, eval() always uses interpreted mode. michael@0: * To use compiled mode, use Script.exec() instead. michael@0: */ michael@0: if (typeof Script == 'undefined') michael@0: { michael@0: print('Test skipped. Script not defined.'); michael@0: expect = actual = 0; michael@0: } michael@0: else michael@0: { michael@0: try michael@0: { michael@0: var script = Script(source); michael@0: script(); michael@0: michael@0: michael@0: status = inSection(1); michael@0: actual = counter; michael@0: expect = (N + 1) * 2; michael@0: } michael@0: catch(ex) michael@0: { michael@0: actual = ex + ''; michael@0: } michael@0: } michael@0: addThis(); michael@0: michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: test(); michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: michael@0: michael@0: function repeat_str(str, repeat_count) michael@0: { michael@0: var arr = new Array(--repeat_count); michael@0: while (repeat_count != 0) michael@0: arr[--repeat_count] = str; michael@0: return str.concat.apply(str, arr); michael@0: } michael@0: michael@0: michael@0: function addThis() michael@0: { michael@0: statusitems[UBound] = status; michael@0: actualvalues[UBound] = actual; michael@0: expectedvalues[UBound] = expect; michael@0: UBound++; michael@0: } michael@0: michael@0: michael@0: function test() michael@0: { michael@0: enterFunc('test'); michael@0: printBugNumber(BUGNUMBER); michael@0: printStatus(summary); michael@0: michael@0: for (var i=0; i