tor-browser

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

testFFI.js (9613B)


      1 load(libdir + "asm.js");
      2 load(libdir + "asserts.js");
      3 
      4 function ffi(a,b,c,d) {
      5    return a+b+c+d;
      6 }
      7 
      8 var f = asmLink(asmCompile('global','imp', USE_ASM + 'var ffi=imp.ffi; function g() { return 1 } function f() { var i=0; i=g()|0; return ((ffi(4,5,6,7)|0)+i)|0 } return f'), null, {ffi:ffi});
      9 assertEq(f(1), 23);
     10 
     11 var counter = 0;
     12 function inc() { return counter++ }
     13 function add1(x) { return x+1 }
     14 function add2(x,y) { return x+y }
     15 function add3(x,y,z) { return x+y+z }
     16 function addN() {
     17    var sum = 0;
     18    for (var i = 0; i < arguments.length; i++)
     19        sum += arguments[i];
     20    return sum;
     21 }
     22 var imp = { inc:inc, add1:add1, add2:add2, add3:add3, addN:addN, identity: x => x };
     23 
     24 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { incc() } return f');
     25 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { var i = 0; return (i + inc)|0 } return f');
     26 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { inc = 0 } return f');
     27 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return (inc() + 1)|0 } return f');
     28 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return +((inc()|0) + 1.1) } return f');
     29 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return +(inc() + 1.1) } return f');
     30 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return (+inc() + 1)|0 } return f');
     31 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { var i = 0; inc(i>>>0) } return f');
     32 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { if (0) return inc(); return } return f');
     33 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { inc(inc()) } return f');
     34 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { g(inc()) } function g() {} return f');
     35 assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { inc()|inc() } return f');
     36 
     37 assertAsmLinkFail(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc()|0 } return f'), null, {});
     38 assertAsmLinkFail(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc()|0 } return f'), null, {inc:0});
     39 assertAsmLinkFail(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc()|0 } return f'), null, {inc:{}});
     40 
     41 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function g() { inc() } return g'), null, imp)(), undefined);
     42 assertEq(counter, 1);
     43 
     44 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function g() { return inc()|0 } return g'), null, imp);
     45 assertEq(f(), 1);
     46 assertEq(counter, 2);
     47 assertEq(f(), 2);
     48 assertEq(counter, 3);
     49 
     50 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var add1=imp.add1; function g(i) { i=i|0; return add1(i|0)|0 } return g'), null, imp)(9), 10);
     51 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'const add1=imp.add1; function g(i) { i=i|0; return add1(i|0)|0 } return g'), null, imp)(9), 10);
     52 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var add3=imp.add3; function g() { var i=1,j=3,k=9; return add3(i|0,j|0,k|0)|0 } return g'), null, imp)(), 13);
     53 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'const add3=imp.add3; function g() { var i=1,j=3,k=9; return add3(i|0,j|0,k|0)|0 } return g'), null, imp)(), 13);
     54 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var add3=imp.add3; function g() { var i=1.4,j=2.3,k=32.1; return +add3(i,j,k) } return g'), null, imp)(), 1.4+2.3+32.1);
     55 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'const add3=imp.add3; function g() { var i=1.4,j=2.3,k=32.1; return +add3(i,j,k) } return g'), null, imp)(), 1.4+2.3+32.1);
     56 
     57 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var add3=imp.add3; function f(i,j,k) { i=i|0;j=+j;k=k|0; return add3(i|0,j,k|0)|0 } return f'), null, imp)(1, 2.5, 3), 6);
     58 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var addN=imp.addN; function f() { return +addN(1,2,3,4.1,5,6.1,7,8.1,9.1,10,11.1,12,13,14.1,15.1,16.1,17.1,18.1) } return f'), null, imp)(), 1+2+3+4.1+5+6.1+7+8.1+9.1+10+11.1+12+13+14.1+15.1+16.1+17.1+18.1);
     59 
     60 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var add2=imp.add2; function f(i,j) { i=i|0;j=+j; return +(+(add2(i|0,1)|0) + +add2(j,1) + +add2(+~~i,j)) } return f'), null, imp)(2, 5.5), 3+(5.5+1)+(2+5.5));
     61 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var addN=imp.addN; function f(i,j) { i=i|0;j=+j; return +(+addN(i|0,j,3,j,i|0) + +addN() + +addN(j,j,j)) } return f'), null, imp)(1, 2.2), (1+2.2+3+2.2+1)+(2.2+2.2+2.2));
     62 
     63 counter = 0;
     64 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var addN=imp.addN,inc=imp.inc; function f() { return ((addN(inc()|0,inc(3.3)|0,inc()|0)|0) + (addN(inc(0)|0)|0))|0 } return f'), null, imp)(), 6);
     65 assertEq(counter, 4);
     66 
     67 var recurse = function(i,j) { if (i == 0) return j; return f(i-1,j+1)+j }
     68 imp.recurse = recurse;
     69 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var r=imp.recurse; function f(i,j) { i=i|0;j=+j; return +r(i|0,j) } return f'), null, imp);
     70 assertEq(f(0,3.3), 3.3);
     71 assertEq(f(1,3.3), 3.3+4.3);
     72 assertEq(f(2,3.3), 3.3+4.3+5.3);
     73 
     74 function maybeThrow(i, j) {
     75    if (i == 0)
     76        throw j;
     77    try {
     78        return f(i-1, j);
     79    } catch(e) {
     80        assertEq(typeof e, "number");
     81        return e;
     82    }
     83 }
     84 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i, j) { i=i|0;j=j|0; return ffi(i|0, (j+1)|0)|0 } return f'), null, {ffi:maybeThrow});
     85 assertThrowsValue(function() { f(0,0) }, 1);
     86 assertThrowsValue(function() { f(0,Math.pow(2,31)-1) }, -Math.pow(2,31));
     87 assertEq(f(1,0), 2);
     88 assertEq(f(2,0), 3);
     89 assertEq(f(3,0), 4);
     90 assertEq(f(4,5), 10);
     91 
     92 var recurse = function(i,j) { if (i == 0) throw j; f(i-1,j) }
     93 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function g(i,j,k) { i=i|0;j=+j;k=k|0; if (!(k|0)) ffi(i|0,j)|0; else g(i, j+1.0, (k-1)|0) } function f(i,j) { i=i|0;j=+j; g(i,j,4) } return f'), null, {ffi:recurse});
     94 assertThrowsValue(function() { f(0,2.4) }, 2.4+4);
     95 assertThrowsValue(function() { f(1,2.4) }, 2.4+8);
     96 assertThrowsValue(function() { f(8,2.4) }, 2.4+36);
     97 
     98 assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var identity=imp.identity; function g(x) { x=+x; return +identity(x) } return g'), null, imp)(13.37), 13.37);
     99 
    100 // Test asm.js => ion paths
    101 setJitCompilerOption("ion.warmup.trigger", 10);
    102 setJitCompilerOption("baseline.warmup.trigger", 0);
    103 setJitCompilerOption("offthread-compilation.enable", 0);
    104 
    105 // In registers on x64 and ARM, on the stack for x86
    106 function ffiIntFew(a,b,c,d) { return d+1 }
    107 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return ffi(i|0,(i+1)|0,(i+2)|0,(i+3)|0)|0 } return f'), null, {ffi:ffiIntFew});
    108 for (var i = 0; i < 40; i++)
    109    assertEq(f(i), i+4);
    110 
    111 // Stack and registers for x64 and ARM, stack for x86
    112 function ffiIntMany(a,b,c,d,e,f,g,h,i,j) { return j+1 }
    113 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return ffi(i|0,(i+1)|0,(i+2)|0,(i+3)|0,(i+4)|0,(i+5)|0,(i+6)|0,(i+7)|0,(i+8)|0,(i+9)|0)|0 } return f'), null, {ffi:ffiIntMany});
    114 for (var i = 0; i < 15; i++)
    115    assertEq(f(i), i+10);
    116 
    117 // In registers on x64 and ARM, on the stack for x86
    118 function ffiDoubleFew(a,b,c,d) { return d+1 }
    119 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=+i; return +ffi(i,i+1.0,i+2.0,i+3.0) } return f'), null, {ffi:ffiDoubleFew});
    120 for (var i = 0; i < 15; i++)
    121    assertEq(f(i), i+4);
    122 
    123 // Stack and registers for x64 and ARM, stack for x86
    124 function ffiDoubleMany(a,b,c,d,e,f,g,h,i,j) { return j+1 }
    125 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=+i; return +ffi(i,i+1.0,i+2.0,i+3.0,i+4.0,i+5.0,i+6.0,i+7.0,i+8.0,i+9.0) } return f'), null, {ffi:ffiDoubleMany});
    126 for (var i = 0; i < 15; i++)
    127    assertEq(f(i), i+10);
    128 
    129 // Test the throw path
    130 function ffiThrow(n) { if (n == 14) throw new Error('yolo'); }
    131 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; ffi(i >> 0); } return f'), null, {ffi:ffiThrow});
    132 var i = 0;
    133 try {
    134    for (; i < 15; i++)
    135        f(i);
    136    throw 'assume unreachable';
    137 } catch (e) {
    138    assertEq(e.message, 'yolo');
    139    assertEq(i, 14);
    140 }
    141 
    142 // OOL conversion paths
    143 var INT32_MAX = Math.pow(2, 31) - 1;
    144 function ffiOOLConvertInt(n) { if (n == 40) return valueToConvert; return 42; }
    145 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return ffi(i >> 0) | 0; } return f'), null, {ffi:ffiOOLConvertInt});
    146 for (var i = 0; i < 40; i++)
    147    assertEq(f(i), 42);
    148 valueToConvert = INT32_MAX + 1;
    149 assertEq(f(40), INT32_MAX + 1 | 0);
    150 function testBadConversions(f) {
    151    valueToConvert = {valueOf: function () { throw new Error("FAIL"); }};
    152 
    153    var errMsg;
    154    try {
    155        f(40);
    156    } catch(e) {
    157        errMsg = e.message;
    158    }
    159    assertEq(errMsg, "FAIL");
    160 
    161    valueToConvert = {valueOf: function () { throw "FAIL"; }};
    162    assertThrowsValue(() => f(40), "FAIL");
    163 
    164    valueToConvert = Symbol();
    165    assertThrowsInstanceOf(() => f(40), TypeError);
    166 }
    167 testBadConversions(f);
    168 
    169 function ffiOOLConvertDouble(n) { if (n == 40) return valueToConvert; return 42.5; }
    170 var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var ffi=imp.ffi; function f(i) { i=i|0; return +ffi(i >> 0); } return f'), null, {ffi:ffiOOLConvertDouble});
    171 for (var i = 0; i < 40; i++)
    172    assertEq(f(i), 42.5);
    173 valueToConvert = {valueOf: function() { return 13.37 }};
    174 assertEq(f(40), 13.37);
    175 testBadConversions(f);