]>
git.saurik.com Git - apple/javascriptcore.git/blob - tests/mozilla/ecma_3/Unicode/uc-005.js
   1 /* ***** BEGIN LICENSE BLOCK ***** 
   2 * Version: NPL 1.1/GPL 2.0/LGPL 2.1 
   4 * The contents of this file are subject to the Netscape Public License 
   5 * Version 1.1 (the "License"); you may not use this file except in 
   6 * compliance with the License. You may obtain a copy of the License at 
   7 * http://www.mozilla.org/NPL/ 
   9 * Software distributed under the License is distributed on an "AS IS" basis, 
  10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
  11 * for the specific language governing rights and limitations under the 
  14 * The Original Code is JavaScript Engine testing utilities. 
  16 * The Initial Developer of the Original Code is Netscape Communications Corp. 
  17 * Portions created by the Initial Developer are Copyright (C) 2002 
  18 * the Initial Developer. All Rights Reserved. 
  20 * Contributor(s): rogerl@netscape.com, pschwartau@netscape.com 
  22 * Alternatively, the contents of this file may be used under the terms of 
  23 * either the GNU General Public License Version 2 or later (the "GPL"), or 
  24 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 
  25 * in which case the provisions of the GPL or the LGPL are applicable instead 
  26 * of those above. If you wish to allow use of your version of this file only 
  27 * under the terms of either the GPL or the LGPL, and not to allow others to 
  28 * use your version of this file under the terms of the NPL, indicate your 
  29 * decision by deleting the provisions above and replace them with the notice 
  30 * and other provisions required by the GPL or the LGPL. If you do not delete 
  31 * the provisions above, a recipient may use your version of this file under 
  32 * the terms of any one of the NPL, the GPL or the LGPL. 
  34 * ***** END LICENSE BLOCK ***** 
  38 * SUMMARY: Testing identifiers with double-byte names 
  39 * See http://bugzilla.mozilla.org/show_bug.cgi?id=58274 
  41 * Here is a sample of the problem: 
  43 *    js> function f\u02B1 () {} 
  45 *    js> f\u02B1.toSource(); 
  48 *    js> f\u02B1.toSource().toSource(); 
  49 *    (new String("function f\xB1() {}")) 
  52 * See how the high-byte information (the 02) has been lost? 
  53 * The same thing was happening with the toString() method: 
  55 *    js> f\u02B1.toString(); 
  60 *    js> f\u02B1.toString().toSource(); 
  61 *    (new String("\nfunction f\xB1() {\n}\n")) 
  64 //----------------------------------------------------------------------------- 
  67 var summary 
= 'Testing identifiers with double-byte names'; 
  71 var actualvalues 
= []; 
  73 var expectedvalues 
= []; 
  77  * Define a function that uses double-byte identifiers in 
  78  * "every possible way" 
  80  * Then recover each double-byte identifier via f.toString(). 
  81  * To make this easier, put a 'Z' token before every one. 
  83  * Our eval string will be: 
  85  * sEval = "function Z\u02b1(Z\u02b2, b) { 
  86  *          try { Z\u02b3 : var Z\u02b4 = Z\u02b1; } 
  87  *          catch (Z\u02b5) { for (var Z\u02b6 in Z\u02b5) 
  88  *          {for (1; 1<0; Z\u02b7++) {new Array()[Z\u02b6] = 1;} };} }"; 
  90  * It will be helpful to build this string in stages: 
  92 var s0 
=  'function Z'; 
  94 var s2 
=  '\u02b2, b) {try { Z'; 
  95 var s3 
=  '\u02b3 : var Z'; 
  96 var s4 
=  '\u02b4 = Z'; 
  97 var s5 
=  '\u02b1; } catch (Z' 
  98 var s6 
=  '\u02b5) { for (var Z'; 
  99 var s7 
=  '\u02b6 in Z'; 
 100 var s8 
=  '\u02b5){for (1; 1<0; Z'; 
 101 var s9 
=  '\u02b7++) {new Array()[Z'; 
 102 var s10 
= '\u02b6] = 1;} };} }'; 
 106  * Concatenate these and eval() to create the function Z\u02b1 
 108 var sEval 
= s0 
+ s1 
+ s2 
+ s3 
+ s4 
+ s5 
+ s6 
+ s7 
+ s8 
+ s9 
+ s10
; 
 113  * Recover all the double-byte identifiers via Z\u02b1.toString(). 
 114  * We'll recover the 1st one as arrID[1], the 2nd one as arrID[2], 
 117 var arrID 
= getIdentifiers(Z
\u02b1); 
 121  * Now check that we got back what we put in - 
 123 status 
= inSection(1); 
 125 expect 
= s1
.charAt(0); 
 128 status 
= inSection(2); 
 130 expect 
= s2
.charAt(0); 
 133 status 
= inSection(3); 
 135 expect 
= s3
.charAt(0); 
 138 status 
= inSection(4); 
 140 expect 
= s4
.charAt(0); 
 143 status 
= inSection(5); 
 145 expect 
= s5
.charAt(0); 
 148 status 
= inSection(6); 
 150 expect 
= s6
.charAt(0); 
 153 status 
= inSection(7); 
 155 expect 
= s7
.charAt(0); 
 158 status 
= inSection(8); 
 160 expect 
= s8
.charAt(0); 
 163 status 
= inSection(9); 
 165 expect 
= s9
.charAt(0); 
 168 status 
= inSection(10); 
 170 expect 
= s10
.charAt(0); 
 176 //----------------------------------------------------------------------------- 
 178 //----------------------------------------------------------------------------- 
 183  * Goal: recover the double-byte identifiers from f.toString() 
 184  * by getting the very next character after each 'Z' token. 
 186  * The return value will be an array |arr| indexed such that 
 187  * |arr[1]| is the 1st identifier, |arr[2]| the 2nd, and so on. 
 189  * Note, however, f.toString() is implementation-independent. 
 190  * For example, it may begin with '\nfunction' instead of 'function'.  
 192  * Rhino uses a Unicode representation for f.toString(); whereas 
 193  * SpiderMonkey uses an ASCII representation, putting escape sequences 
 194  * for non-ASCII characters. For example, if a function is called f\u02B1, 
 195  * then in Rhino the toString() method will present a 2-character Unicode 
 196  * string for its name, whereas SpiderMonkey will present a 7-character 
 197  * ASCII string for its name: the string literal 'f\u02B1'. 
 199  * So we force the lexer to condense the string before we use it. 
 200  * This will give uniform results in Rhino and SpiderMonkey. 
 202 function getIdentifiers(f
) 
 204   var str 
= condenseStr(f
.toString()); 
 205   var arr 
= str
.split('Z'); 
 208    * The identifiers are the 1st char of each split substring 
 209    * EXCEPT the first one, which is just ('\n' +) 'function '. 
 211    * Thus note the 1st identifier will be stored in |arr[1]|, 
 212    * the 2nd one in |arr[2]|, etc., making the indexing easy - 
 215     arr
[i
] = arr
[i
].charAt(0); 
 221  * This function is the opposite of a functions like escape(), which take 
 222  * Unicode characters and return escape sequences for them. Here, we force 
 223  * the lexer to turn escape sequences back into single characters. 
 225  * Note we can't simply do |eval(str)|, since in practice |str| will be an 
 226  * identifier somewhere in the program (e.g. a function name); thus |eval(str)| 
 227  * would return the object that the identifier represents: not what we want. 
 229  * So we surround |str| lexicographically with quotes to force the lexer to 
 230  * evaluate it as a string. Have to strip out any linefeeds first, however - 
 232 function condenseStr(str
) 
 235    * You won't be able to do the next step if |str| has 
 236    * any carriage returns or linefeeds in it. For example: 
 238    *  js> eval("'" + '\nHello' + "'"); 
 239    *  1: SyntaxError: unterminated string literal: 
 243    * So replace them with the empty string - 
 245   str 
= str
.replace(/[\r\n]/g, '')  
 246   return eval("'" + str 
+ "'") 
 252   statusitems
[UBound
] = status
; 
 253   actualvalues
[UBound
] = actual
; 
 254   expectedvalues
[UBound
] = expect
; 
 263   printStatus(summary
); 
 265   for (var i
=0; i
<UBound
; i
++) 
 267     reportCompare(expectedvalues
[i
], actualvalues
[i
], statusitems
[i
]);