tor-browser

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

bigintptr-cmp.js (11578B)


      1 const i64 = new BigInt64Array([
      2  -0x8000_0000n,
      3  -0x7fff_ffffn,
      4 
      5  -1n,
      6  0n,
      7  1n,
      8 
      9  0x7fff_ffffn,
     10 ]);
     11 
     12 function gcd(a, b) {
     13  a |= 0;
     14  b |= 0;
     15  while (b !== 0) {
     16    [a, b] = [b, a % b];
     17  }
     18  return Math.abs(a);
     19 }
     20 
     21 function assertAllCombinationsTested(xs, ys, n) {
     22  // If the array lengths are relatively prime and their product is at least
     23  // |n| long, all possible combinations are tested at least once. Make sure
     24  // we test each combination at least three times.
     25  var m = 3;
     26 
     27  assertEq(gcd(xs.length, ys.length), 1);
     28  assertEq(m * xs.length * ys.length <= n, true);
     29 }
     30 
     31 function fillWithZeros(ta) {
     32  let length = ta.length;
     33  let zeros = 1;
     34  while (gcd(length, length + zeros) !== 1) {
     35    zeros++;
     36  }
     37 
     38  let result = new ta.constructor(length + zeros);
     39  result.set(ta);
     40  return result;
     41 }
     42 
     43 function testIPtr() {
     44  for (var i = 0; i < 200; ++i) {
     45    var v = i64[i % i64.length];
     46 
     47    // Apply an operation to execute BigInt as IntPtr codepaths.
     48    var x = v < 0 ? 1n : v > 0 ? -1n : 0n;
     49    v += x;
     50 
     51    // Cast to Int128 to ensure non-optimized BigInt comparison is used.
     52    var eq_zero = v == BigInt.asIntN(128, 0n);
     53    var lt_zero = v < BigInt.asIntN(128, 0n);
     54 
     55    var eq_one = v == BigInt.asIntN(128, 1n);
     56    var lt_one = v < BigInt.asIntN(128, 1n);
     57 
     58    var eq_neg_one = v == BigInt.asIntN(128, -1n);
     59    var lt_neg_one = v < BigInt.asIntN(128, -1n);
     60 
     61    var eq_i31 = v == BigInt.asIntN(128, 0x8000_0000n);
     62    var lt_i31 = v < BigInt.asIntN(128, 0x8000_0000n);
     63 
     64    var eq_i32 = v == BigInt.asIntN(128, 0x1_0000_0000n);
     65    var lt_i32 = v < BigInt.asIntN(128, 0x1_0000_0000n);
     66 
     67    // BigInt constant
     68    assertEq(v == 0n, eq_zero);
     69    assertEq(v != 0n, !eq_zero);
     70    assertEq(v < 0n, lt_zero && !eq_zero);
     71    assertEq(v <= 0n, lt_zero || eq_zero);
     72    assertEq(v > 0n, !lt_zero && !eq_zero);
     73    assertEq(v >= 0n, !lt_zero || eq_zero);
     74 
     75    assertEq(v == 1n, eq_one);
     76    assertEq(v != 1n, !eq_one);
     77    assertEq(v < 1n, lt_one && !eq_one);
     78    assertEq(v <= 1n, lt_one || eq_one);
     79    assertEq(v > 1n, !lt_one && !eq_one);
     80    assertEq(v >= 1n, !lt_one || eq_one);
     81 
     82    assertEq(v == -1n, eq_neg_one);
     83    assertEq(v != -1n, !eq_neg_one);
     84    assertEq(v < -1n, lt_neg_one && !eq_neg_one);
     85    assertEq(v <= -1n, lt_neg_one || eq_neg_one);
     86    assertEq(v > -1n, !lt_neg_one && !eq_neg_one);
     87    assertEq(v >= -1n, !lt_neg_one || eq_neg_one);
     88 
     89    assertEq(v == 0x8000_0000n, eq_i31);
     90    assertEq(v != 0x8000_0000n, !eq_i31);
     91    assertEq(v < 0x8000_0000n, lt_i31 && !eq_i31);
     92    assertEq(v <= 0x8000_0000n, lt_i31 || eq_i31);
     93    assertEq(v > 0x8000_0000n, !lt_i31 && !eq_i31);
     94    assertEq(v >= 0x8000_0000n, !lt_i31 || eq_i31);
     95 
     96    assertEq(v == 0x1_0000_0000n, eq_i32);
     97    assertEq(v != 0x1_0000_0000n, !eq_i32);
     98    assertEq(v < 0x1_0000_0000n, lt_i32 && !eq_i32);
     99    assertEq(v <= 0x1_0000_0000n, lt_i32 || eq_i32);
    100    assertEq(v > 0x1_0000_0000n, !lt_i32 && !eq_i32);
    101    assertEq(v >= 0x1_0000_0000n, !lt_i32 || eq_i32);
    102  }
    103 }
    104 testIPtr();
    105 
    106 function testIPtr_R() {
    107  for (var i = 0; i < 200; ++i) {
    108    var v = i64[i % i64.length];
    109 
    110    // Apply an operation to execute BigInt as IntPtr codepaths.
    111    var x = v < 0 ? 1n : v > 0 ? -1n : 0n;
    112    v += x;
    113 
    114    // Cast to Int128 to ensure non-optimized BigInt comparison is used.
    115    var eq_zero = v == BigInt.asIntN(128, 0n);
    116    var lt_zero = v < BigInt.asIntN(128, 0n);
    117 
    118    var eq_one = v == BigInt.asIntN(128, 1n);
    119    var lt_one = v < BigInt.asIntN(128, 1n);
    120 
    121    var eq_neg_one = v == BigInt.asIntN(128, -1n);
    122    var lt_neg_one = v < BigInt.asIntN(128, -1n);
    123 
    124    var eq_i31 = v == BigInt.asIntN(128, 0x8000_0000n);
    125    var lt_i31 = v < BigInt.asIntN(128, 0x8000_0000n);
    126 
    127    var eq_i32 = v == BigInt.asIntN(128, 0x1_0000_0000n);
    128    var lt_i32 = v < BigInt.asIntN(128, 0x1_0000_0000n);
    129 
    130    // BigInt constant. (Reserved operands)
    131    assertEq(0n == v, eq_zero);
    132    assertEq(0n != v, !eq_zero);
    133    assertEq(0n > v, lt_zero && !eq_zero);
    134    assertEq(0n >= v, lt_zero || eq_zero);
    135    assertEq(0n < v, !lt_zero && !eq_zero);
    136    assertEq(0n <= v, !lt_zero || eq_zero);
    137 
    138    assertEq(1n == v, eq_one);
    139    assertEq(1n != v, !eq_one);
    140    assertEq(1n > v, lt_one && !eq_one);
    141    assertEq(1n >= v, lt_one || eq_one);
    142    assertEq(1n < v, !lt_one && !eq_one);
    143    assertEq(1n <= v, !lt_one || eq_one);
    144 
    145    assertEq(-1n == v, eq_neg_one);
    146    assertEq(-1n != v, !eq_neg_one);
    147    assertEq(-1n > v, lt_neg_one && !eq_neg_one);
    148    assertEq(-1n >= v, lt_neg_one || eq_neg_one);
    149    assertEq(-1n < v, !lt_neg_one && !eq_neg_one);
    150    assertEq(-1n <= v, !lt_neg_one || eq_neg_one);
    151 
    152    assertEq(0x8000_0000n == v, eq_i31);
    153    assertEq(0x8000_0000n != v, !eq_i31);
    154    assertEq(0x8000_0000n > v, lt_i31 && !eq_i31);
    155    assertEq(0x8000_0000n >= v, lt_i31 || eq_i31);
    156    assertEq(0x8000_0000n < v, !lt_i31 && !eq_i31);
    157    assertEq(0x8000_0000n <= v, !lt_i31 || eq_i31);
    158 
    159    assertEq(0x1_0000_0000n == v, eq_i32);
    160    assertEq(0x1_0000_0000n != v, !eq_i32);
    161    assertEq(0x1_0000_0000n > v, lt_i32 && !eq_i32);
    162    assertEq(0x1_0000_0000n >= v, lt_i32 || eq_i32);
    163    assertEq(0x1_0000_0000n < v, !lt_i32 && !eq_i32);
    164    assertEq(0x1_0000_0000n <= v, !lt_i32 || eq_i32);
    165  }
    166 }
    167 testIPtr_R();
    168 
    169 function testIPtr_I32Constant() {
    170  for (var i = 0; i < 200; ++i) {
    171    var v = i64[i % i64.length];
    172 
    173    // Apply an operation to execute BigInt as IntPtr codepaths.
    174    var x = v < 0 ? 1n : v > 0 ? -1n : 0n;
    175    v += x;
    176 
    177    // Cast to Int128 to ensure non-optimized BigInt comparison is used.
    178    var eq_zero = v == BigInt.asIntN(128, 0n);
    179    var lt_zero = v < BigInt.asIntN(128, 0n);
    180 
    181    var eq_one = v == BigInt.asIntN(128, 1n);
    182    var lt_one = v < BigInt.asIntN(128, 1n);
    183 
    184    var eq_neg_one = v == BigInt.asIntN(128, -1n);
    185    var lt_neg_one = v < BigInt.asIntN(128, -1n);
    186 
    187    var eq_i31 = v == BigInt.asIntN(128, 0x8000_0000n);
    188    var lt_i31 = v < BigInt.asIntN(128, 0x8000_0000n);
    189 
    190    var eq_i32 = v == BigInt.asIntN(128, 0x1_0000_0000n);
    191    var lt_i32 = v < BigInt.asIntN(128, 0x1_0000_0000n);
    192 
    193    // Int32 constant
    194    assertEq(v == 0, eq_zero);
    195    assertEq(v != 0, !eq_zero);
    196    assertEq(v < 0, lt_zero && !eq_zero);
    197    assertEq(v <= 0, lt_zero || eq_zero);
    198    assertEq(v > 0, !lt_zero && !eq_zero);
    199    assertEq(v >= 0, !lt_zero || eq_zero);
    200 
    201    assertEq(v == 1, eq_one);
    202    assertEq(v != 1, !eq_one);
    203    assertEq(v < 1, lt_one && !eq_one);
    204    assertEq(v <= 1, lt_one || eq_one);
    205    assertEq(v > 1, !lt_one && !eq_one);
    206    assertEq(v >= 1, !lt_one || eq_one);
    207 
    208    assertEq(v == -1, eq_neg_one);
    209    assertEq(v != -1, !eq_neg_one);
    210    assertEq(v < -1, lt_neg_one && !eq_neg_one);
    211    assertEq(v <= -1, lt_neg_one || eq_neg_one);
    212    assertEq(v > -1, !lt_neg_one && !eq_neg_one);
    213    assertEq(v >= -1, !lt_neg_one || eq_neg_one);
    214  }
    215 }
    216 testIPtr_I32Constant();
    217 
    218 function testIPtr_I32Constant_R() {
    219  for (var i = 0; i < 200; ++i) {
    220    var v = i64[i % i64.length];
    221 
    222    // Apply an operation to execute BigInt as IntPtr codepaths.
    223    var x = v < 0 ? 1n : v > 0 ? -1n : 0n;
    224    v += x;
    225 
    226    // Cast to Int128 to ensure non-optimized BigInt comparison is used.
    227    var eq_zero = v == BigInt.asIntN(128, 0n);
    228    var lt_zero = v < BigInt.asIntN(128, 0n);
    229 
    230    var eq_one = v == BigInt.asIntN(128, 1n);
    231    var lt_one = v < BigInt.asIntN(128, 1n);
    232 
    233    var eq_neg_one = v == BigInt.asIntN(128, -1n);
    234    var lt_neg_one = v < BigInt.asIntN(128, -1n);
    235 
    236    var eq_i31 = v == BigInt.asIntN(128, 0x8000_0000n);
    237    var lt_i31 = v < BigInt.asIntN(128, 0x8000_0000n);
    238 
    239    var eq_i32 = v == BigInt.asIntN(128, 0x1_0000_0000n);
    240    var lt_i32 = v < BigInt.asIntN(128, 0x1_0000_0000n);
    241 
    242    // Int32 constant. (Reversed operands)
    243    assertEq(0 == v, eq_zero);
    244    assertEq(0 != v, !eq_zero);
    245    assertEq(0 > v, lt_zero && !eq_zero);
    246    assertEq(0 >= v, lt_zero || eq_zero);
    247    assertEq(0 < v, !lt_zero && !eq_zero);
    248    assertEq(0 <= v, !lt_zero || eq_zero);
    249 
    250    assertEq(1 == v, eq_one);
    251    assertEq(1 != v, !eq_one);
    252    assertEq(1 > v, lt_one && !eq_one);
    253    assertEq(1 >= v, lt_one || eq_one);
    254    assertEq(1 < v, !lt_one && !eq_one);
    255    assertEq(1 <= v, !lt_one || eq_one);
    256 
    257    assertEq(-1 == v, eq_neg_one);
    258    assertEq(-1 != v, !eq_neg_one);
    259    assertEq(-1 > v, lt_neg_one && !eq_neg_one);
    260    assertEq(-1 >= v, lt_neg_one || eq_neg_one);
    261    assertEq(-1 < v, !lt_neg_one && !eq_neg_one);
    262    assertEq(-1 <= v, !lt_neg_one || eq_neg_one);
    263  }
    264 }
    265 testIPtr_I32Constant_R();
    266 
    267 function testIPtr_TooLargeConstant() {
    268  for (var i = 0; i < 200; ++i) {
    269    var v = i64[i % i64.length];
    270 
    271    // Apply an operation to execute BigInt as IntPtr codepaths.
    272    var x = v < 0 ? 1n : v > 0 ? -1n : 0n;
    273    v += x;
    274 
    275    // BigInt constant too large for I64.
    276    assertEq(v == 0x8000_0000_0000_0000n, false);
    277    assertEq(v != 0x8000_0000_0000_0000n, true);
    278    assertEq(v < 0x8000_0000_0000_0000n, true);
    279    assertEq(v <= 0x8000_0000_0000_0000n, true);
    280    assertEq(v > 0x8000_0000_0000_0000n, false);
    281    assertEq(v >= 0x8000_0000_0000_0000n, false);
    282 
    283    assertEq(v == -0x8000_0000_0000_0001n, false);
    284    assertEq(v != -0x8000_0000_0000_0001n, true);
    285    assertEq(v < -0x8000_0000_0000_0001n, false);
    286    assertEq(v <= -0x8000_0000_0000_0001n, false);
    287    assertEq(v > -0x8000_0000_0000_0001n, true);
    288    assertEq(v >= -0x8000_0000_0000_0001n, true);
    289 
    290    assertEq(v == 0x1_0000_0000_0000_0000n, false);
    291    assertEq(v != 0x1_0000_0000_0000_0000n, true);
    292    assertEq(v < 0x1_0000_0000_0000_0000n, true);
    293    assertEq(v <= 0x1_0000_0000_0000_0000n, true);
    294    assertEq(v > 0x1_0000_0000_0000_0000n, false);
    295    assertEq(v >= 0x1_0000_0000_0000_0000n, false);
    296  }
    297 }
    298 testIPtr_TooLargeConstant();
    299 
    300 function testIPtr_TooLargeConstant_R() {
    301  for (var i = 0; i < 200; ++i) {
    302    var v = i64[i % i64.length];
    303 
    304    // Apply an operation to execute BigInt as IntPtr codepaths.
    305    var x = v < 0 ? 1n : v > 0 ? -1n : 0n;
    306    v += x;
    307 
    308    // BigInt constant too large for I64. (Reserved operands)
    309    assertEq(0x8000_0000_0000_0000n == v, false);
    310    assertEq(0x8000_0000_0000_0000n != v, true);
    311    assertEq(0x8000_0000_0000_0000n > v, true);
    312    assertEq(0x8000_0000_0000_0000n >= v, true);
    313    assertEq(0x8000_0000_0000_0000n < v, false);
    314    assertEq(0x8000_0000_0000_0000n <= v, false);
    315 
    316    assertEq(-0x8000_0000_0000_0001n == v, false);
    317    assertEq(-0x8000_0000_0000_0001n != v, true);
    318    assertEq(-0x8000_0000_0000_0001n > v, false);
    319    assertEq(-0x8000_0000_0000_0001n >= v, false);
    320    assertEq(-0x8000_0000_0000_0001n < v, true);
    321    assertEq(-0x8000_0000_0000_0001n <= v, true);
    322 
    323    assertEq(0x1_0000_0000_0000_0000n == v, false);
    324    assertEq(0x1_0000_0000_0000_0000n != v, true);
    325    assertEq(0x1_0000_0000_0000_0000n > v, true);
    326    assertEq(0x1_0000_0000_0000_0000n >= v, true);
    327    assertEq(0x1_0000_0000_0000_0000n < v, false);
    328    assertEq(0x1_0000_0000_0000_0000n <= v, false);
    329  }
    330 }
    331 testIPtr_TooLargeConstant_R();
    332 
    333 // Compare IntPtr against IntPtr.
    334 function testIIPtr() {
    335  var r64 = fillWithZeros(i64);
    336  assertAllCombinationsTested(i64, r64, 500);
    337 
    338  for (var i = 0; i < 500; ++i) {
    339    var v = i64[i % i64.length];
    340    var w = r64[i % r64.length];
    341 
    342    // Apply an operation to execute BigInt as IntPtr codepaths.
    343    var x = v < 0 ? 1n : v > 0 ? -1n : 0n;
    344    v += x;
    345    w += x;
    346 
    347    // Cast to Int128 to ensure non-optimized BigInt comparison is used.
    348    var eq = v == BigInt.asIntN(128, w);
    349    var lt = v < BigInt.asIntN(128, w);
    350 
    351    assertEq(v == w, eq);
    352    assertEq(v != w, !eq);
    353    assertEq(v < w, lt && !eq);
    354    assertEq(v <= w, lt || eq);
    355    assertEq(v > w, !lt && !eq);
    356    assertEq(v >= w, !lt || eq);
    357  }
    358 }
    359 testIIPtr();