fromcharcode-charcodeat-zero.js (2630B)
1 function toCharCodes(str) { 2 return [...str].map(s => s.length === 1 ? [s.charCodeAt(0)] : [s.charCodeAt(0), s.charCodeAt(1)]) 3 .flat(); 4 } 5 6 function test() { 7 // [Ascii; Latin-1, non-Ascii; non-Latin-1; non-BMP] 8 const constant = "Aaรรกฤฤ๐๐"; 9 const charCodes = toCharCodes(constant); 10 11 // Create a linear, but non-constant string with the same contents. 12 const linear = String.fromCharCode(...charCodes); 13 assertEq(linear, constant); 14 15 // Optimisation applies for |MCharCodeAt(MFromCharCode(MCharCodeAt(str, idx)), 0|. 16 for (let i = 0; i < 500; ++i) { 17 let idx = i & 3; 18 19 // str[idx] is compiled to |MFromCharCode(MCharCodeAt(str, idx))|. 20 assertEq(constant[idx].charCodeAt(0), charCodes[idx]); 21 assertEq(linear[idx].charCodeAt(0), charCodes[idx]); 22 23 // str.charAt(idx) is compiled to |MFromCharCode(MCharCodeAt(str, idx))|. 24 assertEq(constant.charAt(idx).charCodeAt(0), charCodes[idx]); 25 assertEq(linear.charAt(idx).charCodeAt(0), charCodes[idx]); 26 } 27 } 28 for (let i = 0; i < 4; ++i) { 29 test(); 30 } 31 32 function testNonConstantIndex() { 33 // [Ascii; Latin-1, non-Ascii; non-Latin-1; non-BMP] 34 const constant = "Aaรรกฤฤ๐๐"; 35 const charCodes = toCharCodes(constant); 36 37 // Create a linear, but non-constant string with the same contents. 38 const linear = String.fromCharCode(...charCodes); 39 assertEq(linear, constant); 40 41 // No optimisation when the index isn't a constant zero. 42 let indices = [0, 1, 2, 3]; 43 for (let i = 0; i < 500; ++i) { 44 let idx = i & 3; 45 46 // Always zero, but too complicated to infer at compile time. 47 let zero = indices[idx] - idx; 48 49 assertEq(constant[idx].charCodeAt(zero), charCodes[idx]); 50 assertEq(linear[idx].charCodeAt(zero), charCodes[idx]); 51 52 assertEq(constant.charAt(idx).charCodeAt(zero), charCodes[idx]); 53 assertEq(linear.charAt(idx).charCodeAt(zero), charCodes[idx]); 54 } 55 } 56 for (let i = 0; i < 4; ++i) { 57 testNonConstantIndex(); 58 } 59 60 function testOOB() { 61 // [Ascii; Latin-1, non-Ascii; non-Latin-1; non-BMP] 62 const constant = "Aaรรกฤฤ๐๐"; 63 const charCodes = toCharCodes(constant); 64 65 // Create a linear, but non-constant string with the same contents. 66 const linear = String.fromCharCode(...charCodes); 67 assertEq(linear, constant); 68 69 // No optimisation when the index is out-of-bounds. 70 for (let i = 0; i < 500; ++i) { 71 let idx = i & 3; 72 73 assertEq(constant[idx].charCodeAt(1), NaN); 74 assertEq(linear[idx].charCodeAt(1), NaN); 75 76 assertEq(constant.charAt(idx).charCodeAt(1), NaN); 77 assertEq(linear.charAt(idx).charCodeAt(1), NaN); 78 } 79 } 80 for (let i = 0; i < 4; ++i) { 81 testOOB(); 82 }