tor-browser

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

pow-base-power-of-two.js (2021B)


      1 // |jit-test| skip-variant-if: --ion-eager, getBuildConfiguration("simulator")
      2 
      3 // Slow in simulators with --ion-eager.
      4 
      5 // Lowering provides a specialisation when the base operand is a constant which
      6 // is a power of two.
      7 
      8 load(libdir + "math.js");
      9 
     10 function test(x, y, z) {
     11    function pow(x, y) { return `Math.pow(${x}, ${y})` };
     12    function exp(x, y) { return `((${x}) ** ${y})` };
     13 
     14    function make(fn, x, y, z) {
     15        return Function(`
     16            // Load from array to prevent constant-folding.
     17            // (Ion is currently not smart enough to realise that both array
     18            // values are the same.)
     19            var ys = [${y}, ${y}];
     20            var zs = [${z}, ${z}];
     21            for (var i = 0; i < 200; ++i) {
     22                assertNear(${fn(x, "ys[i & 1]")}, zs[i & 1]);
     23            }
     24        `);
     25    }
     26 
     27    function double(v) {
     28        // NB: numberToDouble() always returns a double value.
     29        return `numberToDouble(${v})`;
     30    }
     31 
     32    function addTests(fn) {
     33        tests.push(make(fn, x, y, z));
     34        tests.push(make(fn, x, double(y), z));
     35        tests.push(make(fn, double(x), y, z));
     36        tests.push(make(fn, double(x), double(y), z));
     37    }
     38 
     39    var tests = [];
     40    addTests(pow);
     41    addTests(exp);
     42 
     43    for (var i = 0; i < tests.length; ++i) {
     44        for (var j = 0; j < 2; ++j) {
     45            tests[i]();
     46        }
     47    }
     48 }
     49 
     50 function* range(a, b, fn) {
     51    for (var i = a; i <= b; ++i) {
     52        yield fn(i);
     53    }
     54 }
     55 
     56 // Only 2^i with |i| ∈ {1..8} currently triggers the optimisation, but also test
     57 // the next power-of-two values, 1 and 0, and negative base-of-two values.
     58 var values = [
     59    ...range(1, 10, i => 2 ** i),
     60    1,
     61    0,
     62    ...range(1, 4, i => -(2 ** i)),
     63 ];
     64 
     65 for (var x of values) {
     66    test(x, 0, 1);
     67    test(x, 1, x);
     68    test(x, 2, x * x);
     69 
     70    // 0**(negative) is Infinity, 1**(negative) is 1.
     71    if (Math.abs(x) > 1) {
     72        test(x, -1076, 0);
     73    }
     74 
     75    // (negative)**(odd-negative) is -0.
     76    if (x > 1) {
     77        test(x, -1075, 0);
     78    }
     79 }