tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }