regress-179068.js (3900B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* 7 * 8 * Date: 09 November 2002 9 * SUMMARY: Test that interpreter can handle string literals exceeding 64K 10 * See http://bugzilla.mozilla.org/show_bug.cgi?id=179068 11 * 12 * Test that the interpreter can handle string literals exceeding 64K limit. 13 * For that the script passes to eval() "str ='LONG_STRING_LITERAL';" where 14 * LONG_STRING_LITERAL is a string with 200K chars. 15 * 16 * Igor Bukanov explains the technique used below: 17 * 18 * > Philip Schwartau wrote: 19 * >... 20 * > Here is the heart of the testcase: 21 * > 22 * > // Generate 200K long string 23 * > var long_str = duplicate(LONG_STR_SEED, N); 24 * > var str = ""; 25 * > eval("str='".concat(long_str, "';")); 26 * > var test_is_ok = (str.length == LONG_STR_SEED.length * N); 27 * > 28 * > 29 * > The testcase creates two identical strings, |long_str| and |str|. It 30 * > uses eval() simply to assign the value of |long_str| to |str|. Why is 31 * > it necessary to have the variable |str|, then? Why not just create 32 * > |long_str| and test it? Wouldn't this be enough: 33 * > 34 * > // Generate 200K long string 35 * > var long_str = duplicate(LONG_STR_SEED, N); 36 * > var test_is_ok = (long_str.length == LONG_STR_SEED.length * N); 37 * > 38 * > Or do we specifically need to test eval() to exercise the interpreter? 39 * 40 * The reason for eval is to test string literals like in 'a string literal 41 * with 100 000 characters...', Rhino deals fine with strings generated at 42 * run time where lengths > 64K. Without eval it would be necessary to have 43 * a test file excedding 64K which is not that polite for CVS and then a 44 * special treatment for the compiled mode in Rhino should be added. 45 * 46 * 47 * > 48 * > If so, is it important to use the concat() method in the assignment, as 49 * > you have done: |eval("str='".concat(long_str, "';"))|, or can we simply 50 * > do |eval("str = long_str;")| ? 51 * 52 * The concat is a replacement for eval("str='"+long_str+"';"), but as 53 * long_str is huge, this leads to constructing first a new string via 54 * "str='"+long_str and then another one via ("str='"+long_str) + "';" 55 * which takes time under JDK 1.1 on a something like StrongArm 200MHz. 56 * Calling concat makes less copies, that is why it is used in the 57 * duplicate function and this is faster then doing recursion like in the 58 * test case to test that 64K different string literals can be handled. 59 * 60 */ 61 //----------------------------------------------------------------------------- 62 var UBound = 0; 63 var BUGNUMBER = 179068; 64 var summary = 'Test that interpreter can handle string literals exceeding 64K'; 65 var status = ''; 66 var statusitems = []; 67 var actual = ''; 68 var actualvalues = []; 69 var expect= ''; 70 var expectedvalues = []; 71 var LONG_STR_SEED = "0123456789"; 72 var N = 20 * 1024; 73 var str = ""; 74 75 76 // Generate 200K long string and assign it to |str| via eval() 77 var long_str = duplicate(LONG_STR_SEED, N); 78 eval("str='".concat(long_str, "';")); 79 80 status = inSection(1); 81 actual = str.length == LONG_STR_SEED.length * N 82 expect = true; 83 addThis(); 84 85 86 87 //----------------------------------------------------------------------------- 88 test(); 89 //----------------------------------------------------------------------------- 90 91 92 93 function duplicate(str, count) 94 { 95 var tmp = new Array(count); 96 97 while (count != 0) 98 tmp[--count] = str; 99 100 return String.prototype.concat.apply("", tmp); 101 } 102 103 104 function addThis() 105 { 106 statusitems[UBound] = status; 107 actualvalues[UBound] = actual; 108 expectedvalues[UBound] = expect; 109 UBound++; 110 } 111 112 113 function test() 114 { 115 printBugNumber(BUGNUMBER); 116 printStatus(summary); 117 118 for (var i=0; i<UBound; i++) 119 { 120 reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); 121 } 122 }