diff options
Diffstat (limited to 'js/src/jit-test/tests/asm.js')
102 files changed, 7712 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/asm.js/bug1007512.js b/js/src/jit-test/tests/asm.js/bug1007512.js new file mode 100644 index 0000000000..657fed6210 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1007512.js @@ -0,0 +1,8 @@ +// |jit-test| error: TypeError + +new(function(stdlib, n, heap) { + "use asm" + var x = new stdlib.Uint32Array(heap) + function f() {} + return f +}) diff --git a/js/src/jit-test/tests/asm.js/bug1008636.js b/js/src/jit-test/tests/asm.js/bug1008636.js new file mode 100644 index 0000000000..03e52e9b17 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1008636.js @@ -0,0 +1,12 @@ +// |jit-test| error:TypeError +// stdlib is undefined + +(function(stdlib, n, heap) { + "use asm" + var Int16ArrayView = new stdlib.Int16Array(heap) + function f() { + var x = 4. + Int16ArrayView[~~((1 ? .0 : .9) % x) >> 1] = 0 + u(x) + } +})() diff --git a/js/src/jit-test/tests/asm.js/bug1126251.js b/js/src/jit-test/tests/asm.js/bug1126251.js new file mode 100644 index 0000000000..77aa56dbeb --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1126251.js @@ -0,0 +1,15 @@ +load(libdir + "asm.js"); + +// Bug 1126251 +var v = asmLink(asmCompile('global', ` + "use asm"; + var frd = global.Math.fround; + function e() { + var x = frd(.1e+71); + x = frd(x / x); + return +x; + } + return e; +`), this)(); + +assertEq(v, NaN); diff --git a/js/src/jit-test/tests/asm.js/bug1161298.js b/js/src/jit-test/tests/asm.js/bug1161298.js new file mode 100644 index 0000000000..19da18e17e --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1161298.js @@ -0,0 +1,12 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer || largeArrayBufferSupported() + +// The length exceeds INT32_MAX and should be rejected. + +var failed = false; +try { + var sab = new SharedArrayBuffer((2147483648)); +} +catch (e) { + failed = true; +} +assertEq(failed, true); diff --git a/js/src/jit-test/tests/asm.js/bug1174372.js b/js/src/jit-test/tests/asm.js/bug1174372.js new file mode 100644 index 0000000000..e7031ea104 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1174372.js @@ -0,0 +1,6 @@ +// |jit-test| --no-baseline; --non-writable-jitcode +(function(stdlib, foreign, heap) { + "use asm"; + function f() {} + return f; +})(); diff --git a/js/src/jit-test/tests/asm.js/bug1219954.js b/js/src/jit-test/tests/asm.js/bug1219954.js new file mode 100644 index 0000000000..305369a936 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1219954.js @@ -0,0 +1,10 @@ +// |jit-test| slow; skip-if: !('oomTest' in this) +"use strict"; + +let g = (function() { + "use asm"; + function f() {} + return f; +})(); + +oomTest(() => "" + g); diff --git a/js/src/jit-test/tests/asm.js/bug1268955-usestrict-semantics.js b/js/src/jit-test/tests/asm.js/bug1268955-usestrict-semantics.js new file mode 100644 index 0000000000..501c4392da --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1268955-usestrict-semantics.js @@ -0,0 +1,19 @@ + +var scope = {}; +scope.mod = eval(`"use strict"; (function() { "use asm"; function f() {} return f; });`); + +scope.fun = scope.mod(); + +var caught = false; +for (let callee of ['mod', 'fun']) { + for (let getter of ['caller', 'arguments']) { + caught = false; + try { + scope[callee][getter]; + } catch (e) { + caught = true; + assertEq(e instanceof TypeError, true); + } + assertEq(caught, true); + } +} diff --git a/js/src/jit-test/tests/asm.js/bug1276028.js b/js/src/jit-test/tests/asm.js/bug1276028.js new file mode 100644 index 0000000000..6ef823e247 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1276028.js @@ -0,0 +1,6 @@ +load(libdir + "asm.js"); + +var f = asmLink(asmCompile(USE_ASM + "function a234567() { return 42 } return a234567")); +assertEq(f(), 42); +enableGeckoProfiling(); +assertEq(f(), 42); diff --git a/js/src/jit-test/tests/asm.js/bug1306506.js b/js/src/jit-test/tests/asm.js/bug1306506.js new file mode 100644 index 0000000000..69cfc7b0ed --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1306506.js @@ -0,0 +1,7 @@ +f = (function(stdlib, foreign, heap) { + "use asm"; + function f() { + return (1, 1 / 0)|0; + } + return f; +}); diff --git a/js/src/jit-test/tests/asm.js/bug1385428.js b/js/src/jit-test/tests/asm.js/bug1385428.js new file mode 100644 index 0000000000..c586ec8f3e --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1385428.js @@ -0,0 +1,18 @@ +// |jit-test| skip-if: !('oomTest' in this) + +loadFile(` +try { + Array.prototype.splice.call({ get length() { + "use asm" + function f() {} + return f; +} }); +} catch (e) { + assertEq(e, s2, "wrong error thrown: " + e); +} +`); +function loadFile(lfVarx) { + try { + oomTest(new Function(lfVarx)); + } catch (lfVare) {} +} diff --git a/js/src/jit-test/tests/asm.js/bug1421565.js b/js/src/jit-test/tests/asm.js/bug1421565.js new file mode 100644 index 0000000000..04ab718305 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1421565.js @@ -0,0 +1,19 @@ +// |jit-test| --ion-offthread-compile=off; skip-if: !isAsmJSCompilationAvailable() || !('oomTest' in this) + +load(libdir + "asm.js"); + +oomTest( + function() { + eval(` + function f(stdlib, foreign, buffer) { + "use asm"; + var i32 = new stdlib.Int32Array(buffer); + function set(v) { + v=v|0; + i32[5] = v; + } + return set; + } + `); + } +); diff --git a/js/src/jit-test/tests/asm.js/bug1493475.js b/js/src/jit-test/tests/asm.js/bug1493475.js new file mode 100644 index 0000000000..8a015d1471 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1493475.js @@ -0,0 +1,8 @@ +// |jit-test| skip-if: helperThreadCount() === 0 + +offThreadCompileToStencil("\ + (function(stdlib, foreign) {\ + \"use asm\";\ + function() {};\ + })();\ +"); diff --git a/js/src/jit-test/tests/asm.js/bug1565301.js b/js/src/jit-test/tests/asm.js/bug1565301.js new file mode 100644 index 0000000000..77feaa1e26 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1565301.js @@ -0,0 +1,29 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable() || helperThreadCount() === 0 + +const maxSize = Math.pow(2, 29) - 1; + +// We just don't want to crash during compilation here. + +evaluate(` + offThreadCompileToStencil("\\ + g = (function(t,foreign){\\ + \\"use asm\\";\\ + var ff = foreign.ff;\\ + function f() {\\ + +ff()\\ + }\\ + return f\\ +", { lineNumber: (${maxSize})}); +`); + +evaluate(` + offThreadCompileToStencil("\\ + g = (function(t,foreign){\\ + \\"use asm\\";\\ + var ff = foreign.ff;\\ + function f() {\\ + +ff()\\ + }\\ + return f\\ +", { lineNumber: (${maxSize + 1})}); +`); diff --git a/js/src/jit-test/tests/asm.js/bug1602675.js b/js/src/jit-test/tests/asm.js/bug1602675.js new file mode 100644 index 0000000000..facc68cf9e --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug1602675.js @@ -0,0 +1,19 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable() +// +// Confusion between TA constructor and TA view led to invalid wasm code +// generation and a subsequent failure in the wasm verifier. This code should +// not validate; we should fall back to JS execution. + +function f(stdlib, foreign, buffer) { + "use asm"; + var i32 =stdlib.Int32Array + function g(i) { + i=i|0; + var j=0; + for (; (j>>>0) < 100000; j=(j+1)|0) + i32[i>>2] = j; + } + return g +} +var g = f(this, null, new ArrayBuffer(1<<16)); +g(1<<16); diff --git a/js/src/jit-test/tests/asm.js/bug855526.js b/js/src/jit-test/tests/asm.js/bug855526.js new file mode 100644 index 0000000000..fd75b137d4 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug855526.js @@ -0,0 +1,13 @@ +// Don't assert. +try { + eval('\ + function asmModule(g, foreign, heap) {\ + "use asm";\ + let HEAP8 = new g.Int8Array(heap);\ + function f() { return 17; } \ + return {f: f};\ + }\ + let m = asmModule("", "", 1, "");\ + '); +} catch (ex) { +} diff --git a/js/src/jit-test/tests/asm.js/bug885976.js b/js/src/jit-test/tests/asm.js/bug885976.js new file mode 100644 index 0000000000..303a8d07f2 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug885976.js @@ -0,0 +1,12 @@ +// |jit-test| error: TypeError +function test(stdlib, foreign) { + "use asm" + var ff = foreign.ff + function f(y) { + y = +y; + ff(0); + } + return f; +}; +f = test(this, {ff: Object.defineProperty}); +f(); diff --git a/js/src/jit-test/tests/asm.js/bug923867.js b/js/src/jit-test/tests/asm.js/bug923867.js new file mode 100644 index 0000000000..59bd296b8f --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug923867.js @@ -0,0 +1,8 @@ +(function(a) { + "use asm" + var Infinity = a.Infinity + function f() { + Infinity - (2 ? (1. / .0) : +0) + } + return f +})(this)() diff --git a/js/src/jit-test/tests/asm.js/bug927389.js b/js/src/jit-test/tests/asm.js/bug927389.js new file mode 100644 index 0000000000..ad2ea74d7b --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug927389.js @@ -0,0 +1,6 @@ +(function() { + "use asm" + function f() { + +~~1.1 + } +})() diff --git a/js/src/jit-test/tests/asm.js/bug928450.js b/js/src/jit-test/tests/asm.js/bug928450.js new file mode 100644 index 0000000000..a12036735d --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug928450.js @@ -0,0 +1,18 @@ +(function() { + "use asm"; + function f() { + i((1.5 != 2.) ? 3 : 0); + } + return f; +})(); + +// Bug 933104 +(function() { + "use asm"; + function f(x) { + x = +x; + x = -2.; + (x > -1.5) ? 0 : 0; + } + return f; +})() diff --git a/js/src/jit-test/tests/asm.js/bug940864.js b/js/src/jit-test/tests/asm.js/bug940864.js new file mode 100644 index 0000000000..4df37bb400 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug940864.js @@ -0,0 +1,10 @@ +function a() +{ + "use asm"; + function f() + { + return (((((-1) >>> (0+0)) | 0) % 10000) >> (0+0)) | 0; + } + return f; +} +assertEq(a()(), -1); diff --git a/js/src/jit-test/tests/asm.js/bug941877.js b/js/src/jit-test/tests/asm.js/bug941877.js new file mode 100644 index 0000000000..c2033cf8d9 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/bug941877.js @@ -0,0 +1,164 @@ +load(libdir + "asm.js"); + +function FunctionBody(f) { + var str = f.toString(); + var firstBrace = str.indexOf('{'); + var lastBrace = str.lastIndexOf('}'); + return str.substr(firstBrace + 1, lastBrace - firstBrace - 1); +} + +var F = (function (stdlib, n, heap) { + var Int16ArrayView = new stdlib.Int16Array(heap); + function f(i0, d1) { + i0 = i0 | 0 + d1 = +d1 + var d2 = 1. + var i3 = 0 + Int16ArrayView[0] = i0 + d2 = (.0 / .0) + switch ((i0 + i0) | 0) { + case 0: + d2 = .0 + break + }; + (((i3 - (0 < 0)) >>> ((.0 < -0) + (.0 > .0))) / 0) >> (0 + (((0 + 0) ^ +(9 > 0)) | 0)) + } + return f; +}); + +var compiled = asmCompile('stdlib', 'n', 'heap', USE_ASM + FunctionBody(F)); +asmLink(compiled, this, null, new ArrayBuffer(BUF_MIN))(); + +var F = (function(stdlib, n, heap) { + var Float64ArrayView = new stdlib.Float64Array(heap) + function f() { + Float64ArrayView[0] = +(0xffffffff / 0xffffffff >> 0) + } + return f; +}); + +var compiled = asmCompile('stdlib', 'n', 'heap', USE_ASM + FunctionBody(F)); +asmLink(compiled, this, null, new ArrayBuffer(BUF_MIN))(); + +function test0(x) +{ + return (x >>> 0) % 10; +} +assertEq(test0(25), 5); +assertEq(test0(24), 4); +assertEq(test0(23), 3); +assertEq(test0(0), 0); +assertEq(test0(4294967295), 5); + +function test1(x) +{ + return (x >>> 2) % 10; +} +assertEq(test1(25), 6); +assertEq(test1(24), 6); +assertEq(test1(23), 5); +assertEq(test1(4294967295), 3); + +function test2(x, y) +{ + return (x >>> 0) % (y >>> 0); +} +assertEq(test2(25, 3), 1); +assertEq(test2(24, 4), 0); +assertEq(test2(4294967295, 10), 5); +assertEq(test2(23, 0), NaN); + +function test3() +{ + function f(x, y) + { + x = x|0; + y = y|0; + var t = 0; + t = (((x|0) % (y|0))|0) > -2; + return t|0; + } + return f; +} +var compiled = asmCompile(USE_ASM + FunctionBody(test3)); +var linked = asmLink(compiled); +assertEq(linked(4294967290, 4294967295), 1); +assertEq(linked(4294967290, 4294967295), 1); + +function test4() +{ + function f(x, y) + { + x = x|0; + y = y|0; + var t = 0; + t = (((x>>>0) % (y>>>0)) >>> 0) > 0; + return t|0; + } + return f; +} +var compiled = asmCompile(USE_ASM + FunctionBody(test4)); +var linked = asmLink(compiled); +assertEq(linked(4294967290, 4294967295), 1); +assertEq(linked(4294967290, 4294967295), 1); + +function test5() +{ + function f(x, y) + { + x = x|0; + y = y|0; + var t = 0.; + t = +(((x>>>0) % (y>>>0)) >>> 0) * 1.01; + return +t; + } + return f; +} +var compiled = asmCompile(USE_ASM + FunctionBody(test5)); +var linked = asmLink(compiled); +assertEq(linked(4294967290, 4294967295), 4337916962.9); +assertEq(linked(4294967290, 4294967295), 4337916962.9); + +function test6() +{ + function f(x, y) + { + x = x|0; + y = y|0; + return ((x>>>1) % (y>>>1))|0; + } + return f; +} +var compiled = asmCompile(USE_ASM + FunctionBody(test6)); +var linked = asmLink(compiled); +assertEq(linked(23847, 7), 1); +assertEq(linked(23848, 7), 2); + +function test7() +{ + function f(x) + { + x = x|0; + return ((x>>>0) / 8)|0; + } + return f; +} +var compiled = asmCompile(USE_ASM + FunctionBody(test7)); +var linked = asmLink(compiled); +assertEq(linked(23847, 7), 2980); +assertEq(linked(23848, 7), 2981); + +function test8() +{ + function f(i,j) + { + i=i|0;j=j|0; + return ((i>>>0)/(j>>>0))|0; + } + return f; +} +var compiled = asmCompile(USE_ASM + FunctionBody(test8)); +var linked = asmLink(compiled); +assertEq(linked(2147483647, 0), 0); +assertEq(linked(2147483646, 0), 0); diff --git a/js/src/jit-test/tests/asm.js/directives.txt b/js/src/jit-test/tests/asm.js/directives.txt new file mode 100644 index 0000000000..5e1df0378d --- /dev/null +++ b/js/src/jit-test/tests/asm.js/directives.txt @@ -0,0 +1 @@ +|jit-test| test-also=--no-asmjs; test-also=--disable-wasm-huge-memory; skip-variant-if: --disable-wasm-huge-memory, !wasmHugeMemorySupported(); diff --git a/js/src/jit-test/tests/asm.js/import-function-toPrimitive.js b/js/src/jit-test/tests/asm.js/import-function-toPrimitive.js new file mode 100644 index 0000000000..aa529b465d --- /dev/null +++ b/js/src/jit-test/tests/asm.js/import-function-toPrimitive.js @@ -0,0 +1,26 @@ +var counter = 0; + +function f(stdlib, foreign) +{ + "use asm"; + var a = +foreign.a; + var b = +foreign.b; + function g() {} + return g; +} + +var foreign = + { + a: function() {}, + b: /value that doesn't coerce purely/, + }; + +foreign.a[Symbol.toPrimitive] = + function() + { + counter++; + return 0; + }; + +f(null, foreign); +assertEq(counter, 1); diff --git a/js/src/jit-test/tests/asm.js/nested-rewind.js b/js/src/jit-test/tests/asm.js/nested-rewind.js new file mode 100644 index 0000000000..231eef1f6a --- /dev/null +++ b/js/src/jit-test/tests/asm.js/nested-rewind.js @@ -0,0 +1,9 @@ +function g(x = + function() { + "use asm"; + function f(){} + return f; + } +) { + "use asm"; +} diff --git a/js/src/jit-test/tests/asm.js/neuter-during-arguments-coercion.js b/js/src/jit-test/tests/asm.js/neuter-during-arguments-coercion.js new file mode 100644 index 0000000000..bfe8913e79 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/neuter-during-arguments-coercion.js @@ -0,0 +1,27 @@ +load(libdir + "asm.js"); + +function f(stdlib, foreign, buffer) +{ + "use asm"; + var i32 = new stdlib.Int32Array(buffer); + function set(v) + { + v=v|0; + i32[5] = v; + } + return set; +} +if (isAsmJSCompilationAvailable()) + assertEq(isAsmJSModule(f), true); + +var i32 = new Int32Array(65536); +var buffer = i32.buffer; +var set = f(this, null, buffer); +if (isAsmJSCompilationAvailable()) + assertEq(isAsmJSFunction(set), true); + +try +{ + set({ valueOf() { detachArrayBuffer(buffer); return 17; } }); +} +catch (e) { /* if an exception thrown, swallow */ } diff --git a/js/src/jit-test/tests/asm.js/oom-helper-thread-plus-validation-error.js b/js/src/jit-test/tests/asm.js/oom-helper-thread-plus-validation-error.js new file mode 100644 index 0000000000..2d80e98d3c --- /dev/null +++ b/js/src/jit-test/tests/asm.js/oom-helper-thread-plus-validation-error.js @@ -0,0 +1,10 @@ +// |jit-test| skip-if: !('oomAfterAllocations' in this) + +oomAfterAllocations(10, 2); +evaluate(`function mod(stdlib, ffi, heap) { + "use asm"; + function f3(k) { + k = k | 0; + } + function g3(k) {} +}`); diff --git a/js/src/jit-test/tests/asm.js/oom-helper-thread.js b/js/src/jit-test/tests/asm.js/oom-helper-thread.js new file mode 100644 index 0000000000..18165c01b3 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/oom-helper-thread.js @@ -0,0 +1,4 @@ +// |jit-test| exitstatus: 3; skip-if: !('oomAfterAllocations' in this) + +oomAfterAllocations(50, 2); +eval("(function() {'use asm'; function f() { return +pow(.0, .0) })") diff --git a/js/src/jit-test/tests/asm.js/testAddressErrors.js b/js/src/jit-test/tests/asm.js/testAddressErrors.js new file mode 100644 index 0000000000..1b89b278ad --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testAddressErrors.js @@ -0,0 +1,46 @@ +load(libdir + "asm.js"); + +setIonCheckGraphCoherency(false); + +// constants +var buf = new ArrayBuffer(BUF_MIN); + +// An unshifted literal constant byte index in the range 0 to 2^31-1 inclusive should give a link failure. +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0x7fffffff]|0 } return f'), this, null, buf); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x1fffffff]|0 } return f'), this, null, buf); + + +// An unshifted literal constant byte index outside the range 0 to 2^31-1 inclusive should cause an error compiling. +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x20000000]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x3fffffff]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x40000000]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x7fffffff]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x80000000]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x8fffffff]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0xffffffff]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x100000000]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0x80000000]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0xffffffff]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0x100000000]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int16Array(b); function f() {return arr[-1]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[-2]|0 } return f'); + +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[10-12]|0 } return f'); + +// An intish shifted literal constant index should not fail to compile or link. +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0x3fffffff>>0]|0 } return f'), this, null, buf)(), 0); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x3fffffff>>2]|0 } return f'), this, null, buf)(), 0); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0xffffffff>>0]|0 } return f'), this, null, buf)(), 0); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0xffffffff>>2]|0 } return f'), this, null, buf)(), 0); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[-1>>0]|0 } return f'), this, null, buf)(), 0); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[-1>>2]|0 } return f'), this, null, buf)(), 0); +// Unsigned (intish) folded constant index. +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0xffffffff>>>0]|0 } return f'), this, null, buf)(), 0); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {arr[0] = 1; return arr[(0xffffffff+1)>>>0]|0 } return f'), this, null, buf)(), 1); + +// A non-intish shifted literal constant index should cause an error compiling. +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0x100000000>>0]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x100000000>>2]|0 } return f'); + +// Folded non-intish constant expressions should cause an error compiling. +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0xffffffff+1]|0 } return f'); diff --git a/js/src/jit-test/tests/asm.js/testBasic.js b/js/src/jit-test/tests/asm.js/testBasic.js new file mode 100644 index 0000000000..13cc7c455b --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBasic.js @@ -0,0 +1,173 @@ +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +assertAsmTypeFail(USE_ASM); +assertAsmTypeFail(USE_ASM + 'return'); +assertAsmTypeFail(USE_ASM + 'function f(){}'); +assertAsmTypeFail(USE_ASM + 'function f(){} return 0'); +assertAsmTypeFail(USE_ASM + 'function f(){} return g'); +assertAsmTypeFail(USE_ASM + 'function f(){} function f(){} return f'); +assertAsmTypeFail(USE_ASM + 'function f(){}; function g(){}; return {f, g}'); +assertAsmTypeFail(USE_ASM + 'var f = f;'); +assertAsmTypeFail(USE_ASM + 'var f=0; function f(){} return f'); +assertAsmTypeFail(USE_ASM + 'var f=glob.Math.imul; return {}'); +assertAsmTypeFail('glob', USE_ASM + 'var f=glob.Math.imul; function f(){} return f'); +assertAsmTypeFail('glob','foreign', USE_ASM + 'var f=foreign.foo; function f(){} return f'); +assertAsmTypeFail(USE_ASM + 'function f(){} var f=[f,f]; return f'); +assertAsmTypeFail('"use strict";' + USE_ASM + 'function f() {} return f'); +assertAsmTypeFail(USE_ASM + '"use strict"; function f() {} return f'); +assertAsmTypeFail(USE_ASM + '"use foopy" + 1; function f() {} return f'); +assertAsmTypeFail(USE_ASM + 'function f() { "use strict"; } return f'); +assertEq(asmLink(asmCompile(USE_ASM + '"use asm"; function f() {} return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + '"use foopy"; function f() {} return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + '"use foopy"; "use blarg"; function f() {} return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { "use asm"; } return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { "use foopy"; } return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { "use foopy"; "use blarg"; } return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(i) { "use foopy"; i=i|0; } return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(i) { "use foopy"; "use asm"; i=i|0; } return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + '"use warm"; function f(i) { "use cold"; i=i|0 } function g() { "use hot"; return 0 } return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + '"use warm"; function f(i) { "use cold"; i=i|0 } function g() { "use asm"; return 0 } return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(){} return f'))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(){;} return f'))(), undefined); +assertAsmTypeFail(USE_ASM + 'function f(i,j){;} return f'); +assertEq(asmLink(asmCompile('"use asm";; function f(){};;; return f;;'))(), undefined); +assertAsmTypeFail(USE_ASM + 'function f(x){} return f'); +assertAsmTypeFail(USE_ASM + 'function f(){if (0) return; return 1} return f'); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(x){x=x|0} return f'))(42), undefined); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(x){x=x|0; return x|0} return f'))(42), 42); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(x){x=x|0; return x|0;;;} return f'))(42), 42); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(x,y){x=x|0;y=y|0; return (x+y)|0} return f'))(44, -2), 42); +assertAsmTypeFail('a', USE_ASM + 'function a(){} return a'); +assertAsmTypeFail('a','b','c', USE_ASM + 'var c'); +assertAsmTypeFail('a','b','c', USE_ASM + 'var c=0'); +assertAsmTypeFail(USE_ASM + 'c=0;return {}'); +assertAsmTypeFail('x','x', USE_ASM + 'function a(){} return a'); +assertAsmTypeFail('x','y','x', USE_ASM + 'function a(){} return a'); +assertEq(asmLink(asmCompile('x', USE_ASM + 'function a(){} return a'))(), undefined); +assertEq(asmLink(asmCompile('x','y', USE_ASM + 'function a(){} return a'))(), undefined); +assertEq(asmLink(asmCompile('x','y','z', USE_ASM + 'function a(){} return a'))(), undefined); +assertAsmTypeFail('x','y', USE_ASM + 'function y(){} return f'); +assertEq(asmLink(asmCompile('x', USE_ASM + 'function f(){} return f'), 1, 2, 3)(), undefined); +assertEq(asmLink(asmCompile('x', USE_ASM + 'function f(){} return f'), 1)(), undefined); +assertEq(asmLink(asmCompile('x','y', USE_ASM + 'function f(){} return f'), 1, 2)(), undefined); + +assertEq(asmLink(asmCompile(USE_ASM + 'function f(i) {i=i|0} return f'))(42), undefined); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() {var i=0;; var j=1;} return f'))(), undefined); // bug 877965 second part +assertAsmTypeFail(USE_ASM + 'function f(i) {i=i|0;var i} return f'); +assertAsmTypeFail(USE_ASM + 'function f(i) {i=i|0;var i=0} return f'); + +assertAsmTypeFail('glob', USE_ASM + 'var im=glob.imul; function f() {} return f'); +assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), null); +assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), {}); +assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), {imul:Math.imul}); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), {Math:{imul:Math.imul}})(2,3), 6); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), this)(8,4), 32); + +var module = asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'); +assertAsmLinkAlwaysFail(module, null, null); +assertAsmLinkFail(module, this, null, null); +assertAsmLinkFail(module, this, null, null); +assertAsmLinkAlwaysFail(module, this, null, new ArrayBuffer(1)); +assertAsmLinkFail(module, this, null, new ArrayBuffer(4)); +assertAsmLinkFail(module, this, null, new ArrayBuffer(100)); +assertAsmLinkFail(module, this, null, new ArrayBuffer(4092)); +assertAsmLinkFail(module, this, null, new ArrayBuffer(64000)); +assertAsmLinkFail(module, this, null, new ArrayBuffer(BUF_MIN+4)); +assertAsmLinkDeprecated(module, this, null, new ArrayBuffer(4096)); +assertAsmLinkDeprecated(module, this, null, new ArrayBuffer(2*4096)); +assertAsmLinkDeprecated(module, this, null, new ArrayBuffer(4*4096)); +assertAsmLinkDeprecated(module, this, null, new ArrayBuffer(32*1024)); +assertEq(asmLink(module, this, null, new ArrayBuffer(BUF_MIN))(), undefined); + +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i]|0; return i|0}; return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>1]|0; return i|0}; return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>1]|0; return i|0}; return f'); +assertAsmLinkAlwaysFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f'), this, null, new ArrayBuffer(BUF_MIN-1)); +assertEq(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f')(this, null, new ArrayBuffer(BUF_MIN))(), 0); + +var exp = asmLink(asmCompile(USE_ASM + "return {}")); +assertEq(Object.keys(exp).length, 0); + +var exp = asmLink(asmCompile(USE_ASM + "function f() { return 3 } return {f:f,f:f}")); +assertEq(exp.f(), 3); +assertEq(Object.keys(exp).join(), 'f'); + +var exp = asmLink(asmCompile(USE_ASM + "function f() { return 4 } return {f1:f,f2:f}")); +assertEq(exp.f1(), 4); +assertEq(exp.f2(), 4); +assertEq(Object.keys(exp).sort().join(), 'f1,f2'); +assertEq(exp.f1, exp.f2); + +assertAsmTypeFail(USE_ASM + "function f() { return 3 } return {1:f}"); +assertAsmTypeFail(USE_ASM + "function f() { return 3 } return {__proto__:f}"); +assertAsmTypeFail(USE_ASM + "function f() { return 3 } return {get x() {} }"); + +var exp = asmLink(asmCompile(USE_ASM + 'function internal() { return ((g()|0)+2)|0 } function f() { return 1 } function g() { return 2 } function h() { return internal()|0 } return {f:f,g1:g,h1:h}')); +assertEq(exp.f(), 1); +assertEq(exp.g1(), 2); +assertEq(exp.h1(), 4); +assertEq(Object.keys(exp).join(), 'f,g1,h1'); + +// can't test destructuring args with Function constructor +function assertTypeFailInEval(str) +{ + if (!isAsmJSCompilationAvailable()) + return; + + assertWarning(() => { + eval(str); + }, /asm.js type error:/) +} +assertTypeFailInEval('function f({}) { "use asm"; function g() {} return g }'); +assertTypeFailInEval('function f({global}) { "use asm"; function g() {} return g }'); +assertTypeFailInEval('function f(global, {imports}) { "use asm"; function g() {} return g }'); +assertTypeFailInEval('function f(g = 2) { "use asm"; function g() {} return g }'); +assertTypeFailInEval('function *f() { "use asm"; function g() {} return g }'); +assertAsmTypeFail(USE_ASM + 'function *f(){}'); +assertTypeFailInEval('f => { "use asm"; function g() {} return g }'); +assertTypeFailInEval('var f = { method() {"use asm"; return {}} }'); +assertAsmTypeFail(USE_ASM + 'return {m() {}};'); +assertTypeFailInEval('var f = { get p() {"use asm"; return {}} }'); +assertAsmTypeFail(USE_ASM + 'return {get p() {}};'); +assertTypeFailInEval('var f = { set p(x) {"use asm"; return {}} }'); +assertAsmTypeFail(USE_ASM + 'return {set p(x) {}};'); +assertTypeFailInEval('class f { constructor() {"use asm"; return {}} }'); +assertAsmTypeFail(USE_ASM + 'class c { constructor() {}}; return c;'); + +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'var)') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'return)') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'var z=-2w') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'var z=-2w;') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'function') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'function f') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'function f(') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'function f()') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'function f() {') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'function f() {} var') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'function f() {} var TBL=-2w; return f') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'function f() {} var TBL=-2w return f') }, SyntaxError); +assertThrowsInstanceOf(function() { new Function(USE_ASM + 'function () {}') }, SyntaxError); +assertNoWarning(function() { parse("function f() { 'use asm'; function g() {} return g }") }); + +// Test asm.js->asm.js, wasm->asm.js, asm.js->wasm imports: + +var f = asmLink(asmCompile(USE_ASM + 'function f() {} return f')); +var g = asmLink(asmCompile('glob', 'ffis', USE_ASM + 'var f = ffis.f; function g() { return f(1)|0; } return g'), null, {f}); +assertEq(g(), 0); + +if (wasmIsSupported()) { + var h = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`(module + (import "imp" "f" (func $f (param i32) (result i32))) + (func $h (result i32) (call $f (i32.const 1))) + (export "h" (func $h)) + )`)), {imp:{f}}).exports.h; + assertEq(h(), 0); + + var i = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`(module (func $i) (export "i" (func $i)))`))).exports.i + var j = asmLink(asmCompile('glob', 'ffis', USE_ASM + 'var i = ffis.i; function j() { return i(1)|0; } return j'), null, {i}); + assertEq(j(), 0); +} + +var exp = asmLink(asmCompile(USE_ASM + "function f() { return 0 } return {f:f}")); +assertEq(Object.isFrozen(exp), false); diff --git a/js/src/jit-test/tests/asm.js/testBug1046688.js b/js/src/jit-test/tests/asm.js/testBug1046688.js new file mode 100644 index 0000000000..8c71543bea --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1046688.js @@ -0,0 +1,11 @@ +enableGeckoProfiling(); +for (var j = 0; j < 1000; ++j) { + (function(stdlib) { + "use asm"; + var pow = stdlib.Math.pow; + function f() { + return +pow(.0, .0) + } + return f; +})(this)() +} diff --git a/js/src/jit-test/tests/asm.js/testBug1057248.js b/js/src/jit-test/tests/asm.js/testBug1057248.js new file mode 100644 index 0000000000..39aeffe290 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1057248.js @@ -0,0 +1,133 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer || !isAsmJSCompilationAvailable() + +Random = { + weighted: function(wa) { + var a = []; + for (var i = 0; i < wa.length; ++i) { + for (var j = 0; j < wa[i]; ++j) {} + } + } +} +s = (function() { + Random.weighted([{ + n() {} + }, { + n() {} + }, { + n() {} + }, { + w: 5, + n() {} + } + ]) +})() +var builtinObjectNames = []; +(function() { + function exploreDeeper(a, a) { + var s = Object.getOwnPropertyNames(a) + for (var j = 0; j < s.length; ++j) { + if (typeof h == "" && n != "") {} + } + builtinObjectNames.push() + } + exploreDeeper(Math, "") +})(this, false) +r = autoExpr(Random.weighted([])); +r = autoExpr(Random.weighted([])); +(Random.weighted([])); +r = (Random.weighted([])) +v = autoExpr(Random.weighted([]), true); +r = autoExpr(Random.weighted([{ + n() {} + } +]), true) +function autoExpr() {} +function makeStatement() {} +s = Random.weighted([{ + n() {} + } +]) +a = Random.weighted([{}, {}, {}, {}, {}, { + n() {} + } +]) +a = Random.weighted([{ + n() {} + }, {}, {} +]) +var recursiveFunctions = [{ + text: "(function(){{}})" + }, { + text: "(function(){if(0){}(1)})", + n() {} + }, { + text: "(function(){t:[]()})", + n() {} + }, { + text: "(function(){g()})", + n() {} + } +]; +(function s() { + for (var i = 0; i < recursiveFunctions.length; ++i) { + a = recursiveFunctions[i]; + var text = a.text + a = eval(text.replace(/@/, "")) + } + function g() {} + s = Random.weighted([{ + w: 1, + n() {} + }, { + n() {} + }, // + { + n() {} + }, // + { + n() {} + }, { + w: 0, + n() {} + }, { + n() {} + }, { + n() {} + }, { + w: 1, + n() {} + }, { + w: makeStatement + }, { + w: 5 + } + ]) + t = function() {} + function c() {} +})() +function testMathyFunction(f, inputs) { + var r = []; + for (var j = 0; j < inputs.length; ++j) { + for (var k = 0; k < inputs.length; ++k) { + try { + f(inputs[j]) + } catch (e) {} + } + } + JSON.stringify([]) +} +mathy2 = (function(stdlib, foreign, heap) { + "use asm"; + var Float32ArrayView = new stdlib.Float32Array(heap) + function f(i0) { + i0 = i0 | 0; + (Float32ArrayView[-i0 >> 2]) = 1. + } + return f +})(this, { +}, new SharedArrayBuffer(4096)) +testMathyFunction(mathy2, [-0]) +mathy5 = (function(y) { + ((function() {})(mathy2(y)())) +}) +testMathyFunction(mathy5, [Math.PI]) diff --git a/js/src/jit-test/tests/asm.js/testBug1111327.js b/js/src/jit-test/tests/asm.js/testBug1111327.js new file mode 100644 index 0000000000..45f4e848b1 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1111327.js @@ -0,0 +1,10 @@ +// |jit-test| skip-if: !getBuildConfiguration()['arm-simulator'] +// Single-step profiling currently only works in the ARM simulator + +load(libdir + "asm.js"); + +enableGeckoProfiling(); +enableSingleStepProfiling(); +var m = asmCompile(USE_ASM + 'function f() {} return f'); +asmLink(m)(); +asmLink(m)(); diff --git a/js/src/jit-test/tests/asm.js/testBug1117255.js b/js/src/jit-test/tests/asm.js/testBug1117255.js new file mode 100644 index 0000000000..6e1b9c2389 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1117255.js @@ -0,0 +1,16 @@ +// |jit-test| skip-if: getBuildConfiguration()['wasi'] + +function f(stdlib, foreign, buffer) { + "use asm"; + var i32 = new stdlib.Int32Array(buffer); + function g(i) { + i=i|0; + var j=0; + for (; (j>>>0) < 100000; j=(j+1)|0) + i32[i>>2] = j; + } + return g +} +var g = f(this, null, new ArrayBuffer(1<<16)); +timeout(.1, function cb() { return true }); +g(1<<16); diff --git a/js/src/jit-test/tests/asm.js/testBug1125561.js b/js/src/jit-test/tests/asm.js/testBug1125561.js new file mode 100644 index 0000000000..9d0d99ca43 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1125561.js @@ -0,0 +1,47 @@ +load(libdir + "asm.js"); + +setJitCompilerOption("ion.warmup.trigger", 0); +setJitCompilerOption("baseline.warmup.trigger", 0); +setJitCompilerOption("offthread-compilation.enable", 0); + +function ffi1() { assertJitStackInvariants() } +function ffi2() { return { valueOf() { assertJitStackInvariants() } } } + +// FFI with no coercion +var m = asmCompile('stdlib', 'foreign', ` + "use asm"; + var ffi = foreign.ffi; + function f() { ffi(); } + return f +`); +var f = asmLink(m, null, {ffi:ffi1}); +f(); +f(); + +// FFI with ToInt32 coercion +var m = asmCompile('stdlib', 'foreign', ` + "use asm"; + var ffi = foreign.ffi; + function f() { ffi() | 0; } + return f +`); +var f = asmLink(m, null, {ffi:ffi1}); +f(); +f(); +var f = asmLink(m, null, {ffi:ffi2}); +f(); +f(); + +// FFI with ToNumber coercion +var m = asmCompile('stdlib', 'foreign', ` + "use asm"; + var ffi = foreign.ffi; + function f() { +ffi(); } + return f +`); +var f = asmLink(m, this, {ffi:ffi1}); +f(); +f(); +var f = asmLink(m, this, {ffi:ffi2}); +f(); +f(); diff --git a/js/src/jit-test/tests/asm.js/testBug1147144-2.js b/js/src/jit-test/tests/asm.js/testBug1147144-2.js new file mode 100644 index 0000000000..b5b6a45958 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1147144-2.js @@ -0,0 +1,17 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable()||!Function.prototype.toSource + +function test() { +load(libdir + 'asm.js'); +load(libdir + 'asserts.js'); + +assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`).toSource(), "(function asmModule() {\n [native code]\n})"); +assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`)().toSource(), "function asmFun() {\n [native code]\n}"); +assertEq((evaluate(`function asmModule2() { "use asm"; function asmFun() {} return asmFun }`), asmModule2).toSource(), "function asmModule2() {\n [native code]\n}"); +assertEq((evaluate(`function asmModule4() { "use asm"; function asmFun() {} return asmFun }`), asmModule4)().toSource(), "function asmFun() {\n [native code]\n}"); +assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`).toSource(), "(function anonymous() {\n [native code]\n})"); +assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`)().toSource(), "function asmFun() {\n [native code]\n}"); +} + +var g = newGlobal({ discardSource: true }); +g.libdir = libdir; +g.evaluate(test.toString() + "test()"); diff --git a/js/src/jit-test/tests/asm.js/testBug1147144.js b/js/src/jit-test/tests/asm.js/testBug1147144.js new file mode 100644 index 0000000000..8c1f214e25 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1147144.js @@ -0,0 +1,18 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable() + +function test() { +load(libdir + 'asm.js'); +load(libdir + 'asserts.js'); + +assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`).toString(), "function asmModule() {\n [native code]\n}"); +assertEq(eval(`(function asmModule() { "use asm"; function asmFun() {} return asmFun })`)().toString(), "function asmFun() {\n [native code]\n}"); +assertEq((evaluate(`function asmModule1() { "use asm"; function asmFun() {} return asmFun }`), asmModule1).toString(), "function asmModule1() {\n [native code]\n}"); +assertEq((evaluate(`function asmModule3() { "use asm"; function asmFun() {} return asmFun }`), asmModule3)().toString(), "function asmFun() {\n [native code]\n}"); +assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`).toString(), "function anonymous() {\n [native code]\n}"); +assertEq(asmCompile(USE_ASM + `function asmFun() {} return asmFun`)().toString(), "function asmFun() {\n [native code]\n}"); +assertThrowsInstanceOf(()=>asmCompile('stdlib',USE_ASM + "var sin=stdlib.Math.sin;return {}")({Math:{}}), Error); +} + +var g = newGlobal({ discardSource: true }); +g.libdir = libdir; +g.evaluate(test.toString() + "test()"); diff --git a/js/src/jit-test/tests/asm.js/testBug1219098.js b/js/src/jit-test/tests/asm.js/testBug1219098.js new file mode 100644 index 0000000000..6096f2685f --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1219098.js @@ -0,0 +1,14 @@ +load(libdir + "asm.js"); + +var bigScript = ` + function wee() { return 42 } + function asmModule() { 'use asm'; function f() { return 43 } return f} +` + ' '.repeat(10 * 1024 * 1024); + +eval(bigScript); + +if (isAsmJSCompilationAvailable()) + assertEq(isAsmJSModule(asmModule), true); + +assertEq(wee(), 42); +assertEq(eval('(' + wee.toString() + ')')(), 42); diff --git a/js/src/jit-test/tests/asm.js/testBug1236484.js b/js/src/jit-test/tests/asm.js/testBug1236484.js new file mode 100644 index 0000000000..61a8b49dc5 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1236484.js @@ -0,0 +1,10 @@ +var lfcode = new Array(); +lfcode.push("gczeal(2, 1);"); +lfcode.push(` +function test(stdlib, foreign) { + "use asm" + function f(y) {} + return f +}`); +for (var i = 0; i < 2; ++i) + evaluate(lfcode.shift()); diff --git a/js/src/jit-test/tests/asm.js/testBug1236541.js b/js/src/jit-test/tests/asm.js/testBug1236541.js new file mode 100644 index 0000000000..baa6517915 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1236541.js @@ -0,0 +1,15 @@ +enableGeckoProfiling(); + +function mod() { + "use asm"; + function f(i0) { + i0 = i0 | 0 + switch (0) { + case 0: + } + } + return f; +} + +mod()(); +mod()(); diff --git a/js/src/jit-test/tests/asm.js/testBug1236552.js b/js/src/jit-test/tests/asm.js/testBug1236552.js new file mode 100644 index 0000000000..b91a170406 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1236552.js @@ -0,0 +1,3 @@ +g = newGlobal({newCompartment: true}); +Debugger(g).memory.trackingAllocationSites = true; +evaluate("function h() { 'use asm'; return {}}", { global: g }); diff --git a/js/src/jit-test/tests/asm.js/testBug1255954.js b/js/src/jit-test/tests/asm.js/testBug1255954.js new file mode 100644 index 0000000000..004136bc18 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1255954.js @@ -0,0 +1,12 @@ +// |jit-test| slow; skip-if: !('oomTest' in this) + +const USE_ASM = '"use asm";'; +function asmCompile() { + var f = Function.apply(null, arguments); +} +oomTest(() => { + try { + function f(b) {} + } catch (exc0) {} + f(asmCompile(USE_ASM + "function f() { var i=42; return i|0; for(;1;) {} return 0 } return f")); +}); diff --git a/js/src/jit-test/tests/asm.js/testBug1291887.js b/js/src/jit-test/tests/asm.js/testBug1291887.js new file mode 100644 index 0000000000..7632f0bf3b --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1291887.js @@ -0,0 +1,13 @@ +(function(stdlib) { + "use asm" + var log = stdlib.Math.log + + function f(x) { + x = +x + var y = 3. + return 0, y + return +log(x) + y + } + + return f +})(this) diff --git a/js/src/jit-test/tests/asm.js/testBug1301191.js b/js/src/jit-test/tests/asm.js/testBug1301191.js new file mode 100644 index 0000000000..2624907ee6 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1301191.js @@ -0,0 +1,24 @@ +// |jit-test| exitstatus:6; skip-if: getBuildConfiguration()['wasi'] +timeout(1); +// Adapted from randomly chosen test: js/src/jit-test/tests/asm.js/testBug975182.js +(function() { + g = (function(t, foreign) { + "use asm"; + var ff = foreign.ff; + function f() { + ff() + } + return f + })(this, { + ff: arguments.callee + }) +})() +function m(f) { + var i = 0; + while (true) { + f(); + if ((i++ % 1000) === 0) + gc(); + } +} +m(g); diff --git a/js/src/jit-test/tests/asm.js/testBug1357053.js b/js/src/jit-test/tests/asm.js/testBug1357053.js new file mode 100644 index 0000000000..054e2e35ad --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1357053.js @@ -0,0 +1,15 @@ +// |jit-test| --arm-asm-nop-fill=1 + +try { + enableSingleStepProfiling(); + disableSingleStepProfiling(); +} catch(e) { + // Single step profiling not supported here. + quit(); +} + +enableGeckoProfiling(); +var m = new Function('g', "'use asm'; var tof=g.Math.fround; var fun=g.Math.ceil; function f(d) { d=tof(d); return tof(fun(d)) } return f"); +var f = m(this); +enableSingleStepProfiling(); +f(.1); diff --git a/js/src/jit-test/tests/asm.js/testBug1359612.js b/js/src/jit-test/tests/asm.js/testBug1359612.js new file mode 100644 index 0000000000..f2a2255322 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1359612.js @@ -0,0 +1,9 @@ +load(libdir + 'asm.js'); + +asmLink(asmCompile('stdlib', 'foreign', USE_ASM + ` + var ff = foreign.ff; + function f() { + ff(+1); + } + return f +`), this, { ff: Math.log1p }); diff --git a/js/src/jit-test/tests/asm.js/testBug1360390.js b/js/src/jit-test/tests/asm.js/testBug1360390.js new file mode 100644 index 0000000000..eadd57876c --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1360390.js @@ -0,0 +1,13 @@ +load(libdir + "asm.js"); + +var code = ` + "use asm"; + var ff = foreign.ff; + function f(x) { + x = +x + return ~~x + (ff(3 ^ 9 / 7), 1) & 1; + } + return f; +`; + +assertEq(asmLink(asmCompile("b", "foreign", code), 0, { ff: decodeURIComponent })(Infinity), 1); diff --git a/js/src/jit-test/tests/asm.js/testBug1437534.js b/js/src/jit-test/tests/asm.js/testBug1437534.js new file mode 100644 index 0000000000..ca6daf2b5e --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1437534.js @@ -0,0 +1,19 @@ +let __v_11662 = `(function module() { "use asm";function foo(`; +const __v_11663 = +551; +for (let __v_11665 = 0; __v_11665 < __v_11663; ++__v_11665) { + __v_11662 += `arg${__v_11665},`; +} +try { + __v_11662 += `arg${__v_11663}){`; +} catch (e) {} +for (let __v_11666 = 0; __v_11666 <= __v_11663; ++__v_11666) { + __v_11662 += `arg${__v_11666}=+arg${__v_11666};`; +} + __v_11662 += "return 10;}function bar(){return foo("; +for (let __v_11667 = 0; __v_11667 < __v_11663; ++__v_11667) { + __v_11662 += "0.0,"; +} + __v_11662 += "1.0)|0;}"; + __v_11662 += "return bar})()()"; +const __v_11664 = eval(__v_11662);
\ No newline at end of file diff --git a/js/src/jit-test/tests/asm.js/testBug1437546.js b/js/src/jit-test/tests/asm.js/testBug1437546.js new file mode 100644 index 0000000000..d8f45fcd27 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1437546.js @@ -0,0 +1,6 @@ +const __v_16876 = 50000; +const __v_16877 = '"use asm";\nfunction f() { LOCALS }\nreturn f;'; +for (var __v_16878 = __v_16876; __v_16878 < __v_16876 + 2; ++__v_16878) { + const __v_16879 = __v_16877.replace('LOCALS', Array(__v_16878).fill().map((__v_16882, __v_16883) => 'var l' + __v_16883 + ' = 0;').join('\n')); + const __v_16880 = new Function(__v_16879); +}
\ No newline at end of file diff --git a/js/src/jit-test/tests/asm.js/testBug1674353.js b/js/src/jit-test/tests/asm.js/testBug1674353.js new file mode 100644 index 0000000000..7b1f8bb23c --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug1674353.js @@ -0,0 +1,13 @@ +// |jit-test| skip-if: getBuildConfiguration()["pointer-byte-size"] != 8 + +var stdlib = this; +// The significance of this constant is that it is a 31-bit value that is larger +// than the largest valid wasm32 heap size on 32-bit platforms -- valid sizes +// are limited to floor(INT32_MAX/64K). It is however not a valid asm.js heap +// length, because too many of the low-order bits are set. +var buffer = new ArrayBuffer((2097120) * 1024); +m = (function Module(stdlib, foreign, heap) { + "use asm"; + var mem = new stdlib.Int16Array(heap); + return {}; +})(stdlib, {}, buffer); diff --git a/js/src/jit-test/tests/asm.js/testBug855442.js b/js/src/jit-test/tests/asm.js/testBug855442.js new file mode 100644 index 0000000000..cd95449f01 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug855442.js @@ -0,0 +1,8 @@ +gczeal(2,4); +function asmModule(g, foreign, heap) { + "use asm"; + var HEAP8 = new g.Int8Array(heap); + function f() {} + return {f: f}; +} +asmModule(this, 2, new ArrayBuffer(2048)); diff --git a/js/src/jit-test/tests/asm.js/testBug863867.js b/js/src/jit-test/tests/asm.js/testBug863867.js new file mode 100644 index 0000000000..4d5a2dce18 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug863867.js @@ -0,0 +1,34 @@ +assertEq((function() { + 'use asm'; + function _main() { + var $1=0, $2=0, $3=0, $4=0, $5=0, $6=0, $7=0, $8=0, $9=0, $10=0, label=0; + label = 1; + while (1) { + switch (label | 0) { + case 1: + $2 = $1 + 14 | 0; + $3 = $1; + label = 20; + break; + case 20: + $5 = $2; + $4 = $3; + label = 24; + break; + case 24: + $7 = $5 + 1 | 0; + $8 = $4 + 1 | 0; + return $8|0; + case 49: + $9 = $6 + 1 | 0; + if ($10) { + $6 = $9; + break; + } + return 0; + } + } + return 0; + } + return _main; +})()(), 1); diff --git a/js/src/jit-test/tests/asm.js/testBug878435.js b/js/src/jit-test/tests/asm.js/testBug878435.js new file mode 100644 index 0000000000..965b280025 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug878435.js @@ -0,0 +1,11 @@ +function g() +{ + "use asm"; + function f() + { + return (0 > (0x80000000 | 0)) | 0; + } + return f; +} + +assertEq(g()(), (0 > (0x80000000 | 0)) | 0); diff --git a/js/src/jit-test/tests/asm.js/testBug878495.js b/js/src/jit-test/tests/asm.js/testBug878495.js new file mode 100644 index 0000000000..a4c01f4d4f --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug878495.js @@ -0,0 +1,10 @@ +var disassemble = disassemble || false; +if (disassemble) +{ + disassemble("-r", (function() { + (function() { + "use asm" + return {} + })() + })) +} diff --git a/js/src/jit-test/tests/asm.js/testBug878520.js b/js/src/jit-test/tests/asm.js/testBug878520.js new file mode 100644 index 0000000000..fbc3358720 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug878520.js @@ -0,0 +1,9 @@ +function surprise(depth) { + arguments.callee.caller(depth); +} + +(function(depth) { + function foo() { function asmModule() { 'use asm'; return {} } }; + if (depth) + surprise(depth - 1); +})(2); diff --git a/js/src/jit-test/tests/asm.js/testBug892291.js b/js/src/jit-test/tests/asm.js/testBug892291.js new file mode 100644 index 0000000000..9e0ae97610 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug892291.js @@ -0,0 +1,10 @@ +function a(stdlib) { + "use asm"; + var imul = stdlib.Math.imul; + function f() { + return ((imul(-800, 0xf8ba1243)|0) % -1)|0; + } + return f; +} +var f = a(this); +assertEq(f(), 0); diff --git a/js/src/jit-test/tests/asm.js/testBug893364.js b/js/src/jit-test/tests/asm.js/testBug893364.js new file mode 100644 index 0000000000..8a0eadd35f --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug893364.js @@ -0,0 +1,14 @@ +function m() +{ + "use asm"; + function f() + { + var x = 0; + var y = 0; + x = (((0x77777777 - 0xcccccccc) | 0) % -1) | 0; + y = (((0x7FFFFFFF + 0x7FFFFFFF) | 0) % -1) | 0; + return (x+y)|0; + } + return f; +} +assertEq(m()(), 0) diff --git a/js/src/jit-test/tests/asm.js/testBug893368.js b/js/src/jit-test/tests/asm.js/testBug893368.js new file mode 100644 index 0000000000..b149390e77 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug893368.js @@ -0,0 +1,13 @@ +function m(stdlib) +{ + "use asm"; + var abs = stdlib.Math.abs; + function f(p) + { + p = p|0; + return ((abs(p|0)|0) % 3)|0; + } + return f; +} +var f = m(this); +assertEq(f(0x80000000), -2); diff --git a/js/src/jit-test/tests/asm.js/testBug907085.js b/js/src/jit-test/tests/asm.js/testBug907085.js new file mode 100644 index 0000000000..fb35331dfb --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug907085.js @@ -0,0 +1,22 @@ +try { + s.e +} catch (e) {} +o = o = s2 = /x/ +for (let e in []); +x = s2 +schedulegc(21) +eval("x.e=x.t") +try { + (function() { + this.eval("\ + (function(stdlib,fgn,heap) {\ + \"use asm\";\ + var Vie = new stdlib.Float64Array(heap);\ + var Iew = new stdlib.Int8Array(heap);\ + function f(){\ + ent\ + }\ + })()\ + ") + })() +} catch (e) {} diff --git a/js/src/jit-test/tests/asm.js/testBug952022.js b/js/src/jit-test/tests/asm.js/testBug952022.js new file mode 100644 index 0000000000..12f5d71f8d --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug952022.js @@ -0,0 +1,57 @@ +function g(f) { + for (var j = 0; j < 9; ++j) { + try { + f() + } catch (e) {} + } +} +function h(code) { + Function(code)(); +} +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +g([]); +h("\ + m = (function(stdlib, foreign) { \ + \"use asm\";\ + var ff=foreign.ff;\ + function f(){\ + ff(0);\ + } \ + return f \ + })(this , { \ + ff: arguments.callee.caller\ + });\ + g(m , []);\ +"); +h("\ + m = undefined;\ + gc();\ +") diff --git a/js/src/jit-test/tests/asm.js/testBug965767.js b/js/src/jit-test/tests/asm.js/testBug965767.js new file mode 100644 index 0000000000..95ddc6522d --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug965767.js @@ -0,0 +1,2098 @@ +var buffer = new ArrayBuffer(4096); + +function testmod (glob, env, b) { + 'use asm'; + var f32=new glob.Float32Array(b) + function fn1() { + f32[0 >> 2]=2.0 + f32[4 >> 2]=2.125 + f32[8 >> 2]=2.25 + f32[12 >> 2]=2.375 + f32[16 >> 2]=2.5 + f32[20 >> 2]=2.625 + f32[24 >> 2]=2.75 + f32[28 >> 2]=2.875 + f32[32 >> 2]=3.0 + f32[36 >> 2]=3.125 + f32[40 >> 2]=3.25 + f32[44 >> 2]=3.375 + f32[48 >> 2]=3.5 + f32[52 >> 2]=3.625 + f32[56 >> 2]=3.75 + f32[60 >> 2]=3.875 + f32[64 >> 2]=4.0 + f32[68 >> 2]=4.25 + f32[72 >> 2]=4.5 + f32[76 >> 2]=4.75 + f32[80 >> 2]=5.0 + f32[84 >> 2]=5.25 + f32[88 >> 2]=5.5 + f32[92 >> 2]=5.75 + f32[96 >> 2]=6.0 + f32[100 >> 2]=6.25 + f32[104 >> 2]=6.5 + f32[108 >> 2]=6.75 + f32[112 >> 2]=7.0 + f32[116 >> 2]=7.25 + f32[120 >> 2]=7.5 + f32[124 >> 2]=7.75 + f32[128 >> 2]=8.0 + f32[132 >> 2]=8.5 + f32[136 >> 2]=9.0 + f32[140 >> 2]=9.5 + f32[144 >> 2]=10.0 + f32[148 >> 2]=10.5 + f32[152 >> 2]=11.0 + f32[156 >> 2]=11.5 + f32[160 >> 2]=12.0 + f32[164 >> 2]=12.5 + f32[168 >> 2]=13.0 + f32[172 >> 2]=13.5 + f32[176 >> 2]=14.0 + f32[180 >> 2]=14.5 + f32[184 >> 2]=15.0 + f32[188 >> 2]=15.5 + f32[192 >> 2]=16.0 + f32[196 >> 2]=17.0 + f32[200 >> 2]=18.0 + f32[204 >> 2]=19.0 + f32[208 >> 2]=20.0 + f32[212 >> 2]=21.0 + f32[216 >> 2]=22.0 + f32[220 >> 2]=23.0 + f32[224 >> 2]=24.0 + f32[228 >> 2]=25.0 + f32[232 >> 2]=26.0 + f32[236 >> 2]=27.0 + f32[240 >> 2]=28.0 + f32[244 >> 2]=29.0 + f32[248 >> 2]=30.0 + f32[252 >> 2]=31.0 + f32[256 >> 2]=0.125 + f32[260 >> 2]=0.1328125 + f32[264 >> 2]=0.140625 + f32[268 >> 2]=0.1484375 + f32[272 >> 2]=0.15625 + f32[276 >> 2]=0.1640625 + f32[280 >> 2]=0.171875 + f32[284 >> 2]=0.1796875 + f32[288 >> 2]=0.1875 + f32[292 >> 2]=0.1953125 + f32[296 >> 2]=0.203125 + f32[300 >> 2]=0.2109375 + f32[304 >> 2]=0.21875 + f32[308 >> 2]=0.2265625 + f32[312 >> 2]=0.234375 + f32[316 >> 2]=0.2421875 + f32[320 >> 2]=0.25 + f32[324 >> 2]=0.265625 + f32[328 >> 2]=0.28125 + f32[332 >> 2]=0.296875 + f32[336 >> 2]=0.3125 + f32[340 >> 2]=0.328125 + f32[344 >> 2]=0.34375 + f32[348 >> 2]=0.359375 + f32[352 >> 2]=0.375 + f32[356 >> 2]=0.390625 + f32[360 >> 2]=0.40625 + f32[364 >> 2]=0.421875 + f32[368 >> 2]=0.4375 + f32[368 >> 2]=0.4375 + f32[372 >> 2]=0.453125 + f32[376 >> 2]=0.46875 + f32[380 >> 2]=0.484375 + f32[384 >> 2]=0.5 + f32[388 >> 2]=0.53125 + f32[392 >> 2]=0.5625 + f32[396 >> 2]=0.59375 + f32[400 >> 2]=0.625 + f32[404 >> 2]=0.65625 + f32[408 >> 2]=0.6875 + f32[412 >> 2]=0.71875 + f32[416 >> 2]=0.75 + f32[420 >> 2]=0.78125 + f32[424 >> 2]=0.8125 + f32[428 >> 2]=0.84375 + f32[432 >> 2]=0.875 + f32[436 >> 2]=0.90625 + f32[440 >> 2]=0.9375 + f32[444 >> 2]=0.96875 + f32[448 >> 2]=1.0 + f32[452 >> 2]=1.0625 + f32[456 >> 2]=1.125 + f32[460 >> 2]=1.1875 + f32[464 >> 2]=1.25 + f32[468 >> 2]=1.3125 + f32[472 >> 2]=1.375 + f32[476 >> 2]=1.4375 + f32[480 >> 2]=1.5 + f32[484 >> 2]=1.5625 + f32[488 >> 2]=1.625 + f32[492 >> 2]=1.6875 + f32[496 >> 2]=1.75 + f32[500 >> 2]=1.8125 + f32[504 >> 2]=1.875 + f32[508 >> 2]=1.9375 + f32[512 >> 2]=-2.0 + f32[516 >> 2]=-2.125 + f32[520 >> 2]=-2.25 + f32[524 >> 2]=-2.375 + f32[528 >> 2]=-2.5 + f32[532 >> 2]=-2.625 + f32[536 >> 2]=-2.75 + f32[540 >> 2]=-2.875 + f32[544 >> 2]=-3.0 + f32[548 >> 2]=-3.125 + f32[552 >> 2]=-3.25 + f32[556 >> 2]=-3.375 + f32[560 >> 2]=-3.5 + f32[564 >> 2]=-3.625 + f32[568 >> 2]=-3.75 + f32[572 >> 2]=-3.875 + f32[576 >> 2]=-4.0 + f32[580 >> 2]=-4.25 + f32[584 >> 2]=-4.5 + f32[588 >> 2]=-4.75 + f32[592 >> 2]=-5.0 + f32[596 >> 2]=-5.25 + f32[600 >> 2]=-5.5 + f32[604 >> 2]=-5.75 + f32[608 >> 2]=-6.0 + f32[612 >> 2]=-6.25 + f32[616 >> 2]=-6.5 + f32[620 >> 2]=-6.75 + f32[624 >> 2]=-7.0 + f32[628 >> 2]=-7.25 + f32[632 >> 2]=-7.5 + f32[636 >> 2]=-7.75 + f32[640 >> 2]=-8.0 + f32[644 >> 2]=-8.5 + f32[648 >> 2]=-9.0 + f32[652 >> 2]=-9.5 + f32[656 >> 2]=-10.0 + f32[660 >> 2]=-10.5 + f32[664 >> 2]=-11.0 + f32[668 >> 2]=-11.5 + f32[672 >> 2]=-12.0 + f32[676 >> 2]=-12.5 + f32[680 >> 2]=-13.0 + f32[684 >> 2]=-13.5 + f32[688 >> 2]=-14.0 + f32[692 >> 2]=-14.5 + f32[696 >> 2]=-15.0 + f32[700 >> 2]=-15.5 + f32[704 >> 2]=-16.0 + f32[708 >> 2]=-17.0 + f32[712 >> 2]=-18.0 + f32[716 >> 2]=-19.0 + f32[720 >> 2]=-20.0 + f32[724 >> 2]=-21.0 + f32[728 >> 2]=-22.0 + f32[732 >> 2]=-23.0 + f32[736 >> 2]=-24.0 + f32[740 >> 2]=-25.0 + f32[744 >> 2]=-26.0 + f32[748 >> 2]=-27.0 + f32[752 >> 2]=-28.0 + f32[756 >> 2]=-29.0 + f32[760 >> 2]=-30.0 + f32[764 >> 2]=-31.0 + f32[768 >> 2]=-0.125 + f32[768 >> 2]=-0.125 + f32[772 >> 2]=-0.1328125 + f32[776 >> 2]=-0.140625 + f32[780 >> 2]=-0.1484375 + f32[784 >> 2]=-0.15625 + f32[788 >> 2]=-0.1640625 + f32[792 >> 2]=-0.171875 + f32[796 >> 2]=-0.1796875 + f32[800 >> 2]=-0.1875 + f32[804 >> 2]=-0.1953125 + f32[808 >> 2]=-0.203125 + f32[812 >> 2]=-0.2109375 + f32[816 >> 2]=-0.21875 + f32[820 >> 2]=-0.2265625 + f32[824 >> 2]=-0.234375 + f32[828 >> 2]=-0.2421875 + f32[832 >> 2]=-0.25 + f32[836 >> 2]=-0.265625 + f32[840 >> 2]=-0.28125 + f32[844 >> 2]=-0.296875 + f32[848 >> 2]=-0.3125 + f32[852 >> 2]=-0.328125 + f32[856 >> 2]=-0.34375 + f32[860 >> 2]=-0.359375 + f32[864 >> 2]=-0.375 + f32[868 >> 2]=-0.390625 + f32[872 >> 2]=-0.40625 + f32[876 >> 2]=-0.421875 + f32[880 >> 2]=-0.4375 + f32[884 >> 2]=-0.453125 + f32[888 >> 2]=-0.46875 + f32[892 >> 2]=-0.484375 + f32[896 >> 2]=-0.5 + f32[900 >> 2]=-0.53125 + f32[904 >> 2]=-0.5625 + f32[908 >> 2]=-0.59375 + f32[912 >> 2]=-0.625 + f32[916 >> 2]=-0.65625 + f32[920 >> 2]=-0.6875 + f32[924 >> 2]=-0.71875 + f32[928 >> 2]=-0.75 + f32[932 >> 2]=-0.78125 + f32[936 >> 2]=-0.8125 + f32[940 >> 2]=-0.84375 + f32[944 >> 2]=-0.875 + f32[948 >> 2]=-0.90625 + f32[952 >> 2]=-0.9375 + f32[956 >> 2]=-0.96875 + f32[960 >> 2]=-1.0 + f32[964 >> 2]=-1.0625 + f32[968 >> 2]=-1.125 + f32[972 >> 2]=-1.1875 + f32[976 >> 2]=-1.25 + f32[980 >> 2]=-1.3125 + f32[984 >> 2]=-1.375 + f32[988 >> 2]=-1.4375 + f32[992 >> 2]=-1.5 + f32[996 >> 2]=-1.5625 + f32[1000 >> 2]=-1.625 + f32[1004 >> 2]=-1.6875 + f32[1008 >> 2]=-1.75 + f32[1012 >> 2]=-1.8125 + f32[1016 >> 2]=-1.875 + f32[1020 >> 2]=-1.9375 + + // Some cases that should not be encoded as an immediate on the ARM. + + // All the low zero bits set. + f32[1024 >> 2]=2.1249998 + f32[1028 >> 2]=2.2499998 + f32[1032 >> 2]=2.3749998 + f32[1036 >> 2]=2.4999998 + f32[1040 >> 2]=2.6249998 + f32[1044 >> 2]=2.7499998 + f32[1048 >> 2]=2.8749998 + f32[1052 >> 2]=2.9999998 + f32[1056 >> 2]=3.1249998 + f32[1060 >> 2]=3.2499998 + f32[1064 >> 2]=3.3749998 + f32[1068 >> 2]=3.4999998 + f32[1072 >> 2]=3.6249998 + f32[1076 >> 2]=3.7499998 + f32[1080 >> 2]=3.8749998 + f32[1084 >> 2]=3.9999998 + f32[1088 >> 2]=4.2499995 + f32[1092 >> 2]=4.4999995 + f32[1096 >> 2]=4.7499995 + f32[1100 >> 2]=4.9999995 + f32[1104 >> 2]=5.2499995 + f32[1108 >> 2]=5.4999995 + f32[1112 >> 2]=5.7499995 + f32[1116 >> 2]=5.9999995 + f32[1120 >> 2]=6.2499995 + f32[1124 >> 2]=6.4999995 + f32[1128 >> 2]=6.7499995 + f32[1132 >> 2]=6.9999995 + f32[1136 >> 2]=7.2499995 + f32[1140 >> 2]=7.4999995 + f32[1144 >> 2]=7.7499995 + f32[1148 >> 2]=7.9999995 + f32[1152 >> 2]=8.499999 + f32[1156 >> 2]=8.999999 + f32[1160 >> 2]=9.499999 + f32[1164 >> 2]=9.999999 + f32[1168 >> 2]=10.499999 + f32[1172 >> 2]=10.999999 + f32[1176 >> 2]=11.499999 + f32[1180 >> 2]=11.999999 + f32[1184 >> 2]=12.499999 + f32[1188 >> 2]=12.999999 + f32[1192 >> 2]=13.499999 + f32[1196 >> 2]=13.999999 + f32[1200 >> 2]=14.499999 + f32[1204 >> 2]=14.999999 + f32[1208 >> 2]=15.499999 + f32[1212 >> 2]=15.999999 + f32[1216 >> 2]=16.999998 + f32[1220 >> 2]=17.999998 + f32[1224 >> 2]=18.999998 + f32[1228 >> 2]=19.999998 + f32[1232 >> 2]=20.999998 + f32[1236 >> 2]=21.999998 + f32[1240 >> 2]=22.999998 + f32[1244 >> 2]=23.999998 + f32[1248 >> 2]=24.999998 + f32[1252 >> 2]=25.999998 + f32[1256 >> 2]=26.999998 + f32[1260 >> 2]=27.999998 + f32[1264 >> 2]=28.999998 + f32[1268 >> 2]=29.999998 + f32[1272 >> 2]=30.999998 + f32[1276 >> 2]=31.999998 + f32[1280 >> 2]=0.13281249 + f32[1284 >> 2]=0.14062499 + f32[1288 >> 2]=0.14843749 + f32[1292 >> 2]=0.15624999 + f32[1296 >> 2]=0.16406249 + f32[1300 >> 2]=0.17187499 + f32[1304 >> 2]=0.17968749 + f32[1308 >> 2]=0.18749999 + f32[1312 >> 2]=0.19531249 + f32[1316 >> 2]=0.20312499 + f32[1320 >> 2]=0.21093749 + f32[1324 >> 2]=0.21874999 + f32[1328 >> 2]=0.22656249 + f32[1332 >> 2]=0.23437499 + f32[1336 >> 2]=0.24218749 + f32[1340 >> 2]=0.24999999 + f32[1344 >> 2]=0.26562497 + f32[1348 >> 2]=0.28124997 + f32[1352 >> 2]=0.29687497 + f32[1356 >> 2]=0.31249997 + f32[1360 >> 2]=0.32812497 + f32[1364 >> 2]=0.34374997 + f32[1368 >> 2]=0.35937497 + f32[1372 >> 2]=0.37499997 + f32[1376 >> 2]=0.39062497 + f32[1380 >> 2]=0.40624997 + f32[1384 >> 2]=0.42187497 + f32[1388 >> 2]=0.43749997 + f32[1392 >> 2]=0.45312497 + f32[1396 >> 2]=0.46874997 + f32[1400 >> 2]=0.48437497 + f32[1404 >> 2]=0.49999997 + f32[1408 >> 2]=0.53124994 + f32[1412 >> 2]=0.56249994 + f32[1416 >> 2]=0.59374994 + f32[1420 >> 2]=0.62499994 + f32[1424 >> 2]=0.65624994 + f32[1428 >> 2]=0.68749994 + f32[1432 >> 2]=0.71874994 + f32[1436 >> 2]=0.74999994 + f32[1440 >> 2]=0.78124994 + f32[1444 >> 2]=0.81249994 + f32[1448 >> 2]=0.84374994 + f32[1452 >> 2]=0.87499994 + f32[1456 >> 2]=0.90624994 + f32[1460 >> 2]=0.93749994 + f32[1464 >> 2]=0.96874994 + f32[1468 >> 2]=0.99999994 + f32[1472 >> 2]=1.0624999 + f32[1476 >> 2]=1.1249999 + f32[1480 >> 2]=1.1874999 + f32[1484 >> 2]=1.2499999 + f32[1488 >> 2]=1.3124999 + f32[1488 >> 2]=1.3124999 + f32[1492 >> 2]=1.3749999 + f32[1496 >> 2]=1.4374999 + f32[1500 >> 2]=1.4999999 + f32[1504 >> 2]=1.5624999 + f32[1508 >> 2]=1.6249999 + f32[1512 >> 2]=1.6874999 + f32[1516 >> 2]=1.7499999 + f32[1520 >> 2]=1.8124999 + f32[1524 >> 2]=1.8749999 + f32[1528 >> 2]=1.9374999 + f32[1532 >> 2]=1.9999999 + f32[1536 >> 2]=-2.1249998 + f32[1540 >> 2]=-2.2499998 + f32[1544 >> 2]=-2.3749998 + f32[1548 >> 2]=-2.4999998 + f32[1552 >> 2]=-2.6249998 + f32[1556 >> 2]=-2.7499998 + f32[1560 >> 2]=-2.8749998 + f32[1564 >> 2]=-2.9999998 + f32[1568 >> 2]=-3.1249998 + f32[1572 >> 2]=-3.2499998 + f32[1576 >> 2]=-3.3749998 + f32[1580 >> 2]=-3.4999998 + f32[1584 >> 2]=-3.6249998 + f32[1588 >> 2]=-3.7499998 + f32[1592 >> 2]=-3.8749998 + f32[1596 >> 2]=-3.9999998 + f32[1600 >> 2]=-4.2499995 + f32[1604 >> 2]=-4.4999995 + f32[1608 >> 2]=-4.7499995 + f32[1612 >> 2]=-4.9999995 + f32[1616 >> 2]=-5.2499995 + f32[1620 >> 2]=-5.4999995 + f32[1624 >> 2]=-5.7499995 + f32[1628 >> 2]=-5.9999995 + f32[1632 >> 2]=-6.2499995 + f32[1636 >> 2]=-6.4999995 + f32[1640 >> 2]=-6.7499995 + f32[1644 >> 2]=-6.9999995 + f32[1648 >> 2]=-7.2499995 + f32[1652 >> 2]=-7.4999995 + f32[1656 >> 2]=-7.7499995 + f32[1660 >> 2]=-7.9999995 + f32[1664 >> 2]=-8.499999 + f32[1668 >> 2]=-8.999999 + f32[1672 >> 2]=-9.499999 + f32[1676 >> 2]=-9.999999 + f32[1680 >> 2]=-10.499999 + f32[1684 >> 2]=-10.999999 + f32[1688 >> 2]=-11.499999 + f32[1692 >> 2]=-11.999999 + f32[1696 >> 2]=-12.499999 + f32[1700 >> 2]=-12.999999 + f32[1704 >> 2]=-13.499999 + f32[1708 >> 2]=-13.999999 + f32[1712 >> 2]=-14.499999 + f32[1716 >> 2]=-14.999999 + f32[1720 >> 2]=-15.499999 + f32[1724 >> 2]=-15.999999 + f32[1728 >> 2]=-16.999998 + f32[1732 >> 2]=-17.999998 + f32[1736 >> 2]=-18.999998 + f32[1740 >> 2]=-19.999998 + f32[1744 >> 2]=-20.999998 + f32[1748 >> 2]=-21.999998 + f32[1752 >> 2]=-22.999998 + f32[1756 >> 2]=-23.999998 + f32[1760 >> 2]=-24.999998 + f32[1764 >> 2]=-25.999998 + f32[1768 >> 2]=-26.999998 + f32[1772 >> 2]=-27.999998 + f32[1776 >> 2]=-28.999998 + f32[1780 >> 2]=-29.999998 + f32[1784 >> 2]=-30.999998 + f32[1788 >> 2]=-31.999998 + f32[1792 >> 2]=-0.13281249 + f32[1796 >> 2]=-0.14062499 + f32[1800 >> 2]=-0.14843749 + f32[1804 >> 2]=-0.15624999 + f32[1808 >> 2]=-0.16406249 + f32[1812 >> 2]=-0.17187499 + f32[1816 >> 2]=-0.17968749 + f32[1820 >> 2]=-0.18749999 + f32[1824 >> 2]=-0.19531249 + f32[1828 >> 2]=-0.20312499 + f32[1832 >> 2]=-0.21093749 + f32[1836 >> 2]=-0.21874999 + f32[1840 >> 2]=-0.22656249 + f32[1844 >> 2]=-0.23437499 + f32[1848 >> 2]=-0.24218749 + f32[1852 >> 2]=-0.24999999 + f32[1856 >> 2]=-0.26562497 + f32[1860 >> 2]=-0.28124997 + f32[1864 >> 2]=-0.29687497 + f32[1868 >> 2]=-0.31249997 + f32[1872 >> 2]=-0.32812497 + f32[1876 >> 2]=-0.34374997 + f32[1880 >> 2]=-0.35937497 + f32[1884 >> 2]=-0.37499997 + f32[1888 >> 2]=-0.39062497 + f32[1888 >> 2]=-0.39062497 + f32[1892 >> 2]=-0.40624997 + f32[1896 >> 2]=-0.42187497 + f32[1900 >> 2]=-0.43749997 + f32[1904 >> 2]=-0.45312497 + f32[1908 >> 2]=-0.46874997 + f32[1912 >> 2]=-0.48437497 + f32[1916 >> 2]=-0.49999997 + f32[1920 >> 2]=-0.53124994 + f32[1924 >> 2]=-0.56249994 + f32[1928 >> 2]=-0.59374994 + f32[1932 >> 2]=-0.62499994 + f32[1936 >> 2]=-0.65624994 + f32[1940 >> 2]=-0.68749994 + f32[1944 >> 2]=-0.71874994 + f32[1948 >> 2]=-0.74999994 + f32[1952 >> 2]=-0.78124994 + f32[1956 >> 2]=-0.81249994 + f32[1960 >> 2]=-0.84374994 + f32[1964 >> 2]=-0.87499994 + f32[1968 >> 2]=-0.90624994 + f32[1972 >> 2]=-0.93749994 + f32[1976 >> 2]=-0.96874994 + f32[1980 >> 2]=-0.99999994 + f32[1984 >> 2]=-1.0624999 + f32[1988 >> 2]=-1.1249999 + f32[1992 >> 2]=-1.1874999 + f32[1996 >> 2]=-1.2499999 + f32[2000 >> 2]=-1.3124999 + f32[2004 >> 2]=-1.3749999 + f32[2008 >> 2]=-1.4374999 + f32[2012 >> 2]=-1.4999999 + f32[2016 >> 2]=-1.5624999 + f32[2020 >> 2]=-1.6249999 + f32[2024 >> 2]=-1.6874999 + f32[2028 >> 2]=-1.7499999 + f32[2032 >> 2]=-1.8124999 + f32[2036 >> 2]=-1.8749999 + f32[2040 >> 2]=-1.9374999 + f32[2044 >> 2]=-1.9999999 + + // Just the lowest zero bit set. + f32[2048 >> 2]=2.0000002 + f32[2052 >> 2]=2.1250002 + f32[2056 >> 2]=2.2500002 + f32[2060 >> 2]=2.3750002 + f32[2064 >> 2]=2.5000002 + f32[2068 >> 2]=2.6250002 + f32[2072 >> 2]=2.7500002 + f32[2076 >> 2]=2.8750002 + f32[2080 >> 2]=3.0000002 + f32[2084 >> 2]=3.1250002 + f32[2088 >> 2]=3.2500002 + f32[2092 >> 2]=3.3750002 + f32[2096 >> 2]=3.5000002 + f32[2100 >> 2]=3.6250002 + f32[2104 >> 2]=3.7500002 + f32[2108 >> 2]=3.8750002 + f32[2112 >> 2]=4.0000005 + f32[2116 >> 2]=4.2500005 + f32[2120 >> 2]=4.5000005 + f32[2124 >> 2]=4.7500005 + f32[2128 >> 2]=5.0000005 + f32[2132 >> 2]=5.2500005 + f32[2136 >> 2]=5.5000005 + f32[2140 >> 2]=5.7500005 + f32[2140 >> 2]=5.7500005 + f32[2144 >> 2]=6.0000005 + f32[2148 >> 2]=6.2500005 + f32[2152 >> 2]=6.5000005 + f32[2156 >> 2]=6.7500005 + f32[2160 >> 2]=7.0000005 + f32[2164 >> 2]=7.2500005 + f32[2168 >> 2]=7.5000005 + f32[2172 >> 2]=7.7500005 + f32[2176 >> 2]=8.000001 + f32[2180 >> 2]=8.500001 + f32[2184 >> 2]=9.000001 + f32[2188 >> 2]=9.500001 + f32[2192 >> 2]=10.000001 + f32[2196 >> 2]=10.500001 + f32[2200 >> 2]=11.000001 + f32[2204 >> 2]=11.500001 + f32[2208 >> 2]=12.000001 + f32[2212 >> 2]=12.500001 + f32[2216 >> 2]=13.000001 + f32[2220 >> 2]=13.500001 + f32[2224 >> 2]=14.000001 + f32[2228 >> 2]=14.500001 + f32[2232 >> 2]=15.000001 + f32[2236 >> 2]=15.500001 + f32[2240 >> 2]=16.000002 + f32[2244 >> 2]=17.000002 + f32[2248 >> 2]=18.000002 + f32[2252 >> 2]=19.000002 + f32[2256 >> 2]=20.000002 + f32[2260 >> 2]=21.000002 + f32[2264 >> 2]=22.000002 + f32[2268 >> 2]=23.000002 + f32[2272 >> 2]=24.000002 + f32[2276 >> 2]=25.000002 + f32[2280 >> 2]=26.000002 + f32[2284 >> 2]=27.000002 + f32[2288 >> 2]=28.000002 + f32[2292 >> 2]=29.000002 + f32[2296 >> 2]=30.000002 + f32[2300 >> 2]=31.000002 + f32[2304 >> 2]=0.12500001 + f32[2308 >> 2]=0.13281251 + f32[2312 >> 2]=0.14062501 + f32[2316 >> 2]=0.14843751 + f32[2320 >> 2]=0.15625001 + f32[2324 >> 2]=0.16406251 + f32[2328 >> 2]=0.17187501 + f32[2332 >> 2]=0.17968751 + f32[2336 >> 2]=0.18750001 + f32[2340 >> 2]=0.19531251 + f32[2344 >> 2]=0.20312501 + f32[2348 >> 2]=0.21093751 + f32[2352 >> 2]=0.21875001 + f32[2356 >> 2]=0.22656251 + f32[2360 >> 2]=0.23437501 + f32[2364 >> 2]=0.24218751 + f32[2368 >> 2]=0.25000003 + f32[2372 >> 2]=0.26562503 + f32[2376 >> 2]=0.28125003 + f32[2380 >> 2]=0.29687503 + f32[2384 >> 2]=0.31250003 + f32[2388 >> 2]=0.32812503 + f32[2392 >> 2]=0.34375003 + f32[2396 >> 2]=0.35937503 + f32[2400 >> 2]=0.37500003 + f32[2404 >> 2]=0.39062503 + f32[2408 >> 2]=0.40625003 + f32[2412 >> 2]=0.42187503 + f32[2416 >> 2]=0.43750003 + f32[2420 >> 2]=0.45312503 + f32[2424 >> 2]=0.46875003 + f32[2428 >> 2]=0.48437503 + f32[2432 >> 2]=0.50000006 + f32[2436 >> 2]=0.53125006 + f32[2440 >> 2]=0.56250006 + f32[2444 >> 2]=0.59375006 + f32[2448 >> 2]=0.62500006 + f32[2452 >> 2]=0.65625006 + f32[2456 >> 2]=0.68750006 + f32[2460 >> 2]=0.71875006 + f32[2464 >> 2]=0.75000006 + f32[2468 >> 2]=0.78125006 + f32[2472 >> 2]=0.81250006 + f32[2476 >> 2]=0.84375006 + f32[2480 >> 2]=0.87500006 + f32[2484 >> 2]=0.90625006 + f32[2488 >> 2]=0.93750006 + f32[2492 >> 2]=0.96875006 + f32[2496 >> 2]=1.0000001 + f32[2500 >> 2]=1.0625001 + f32[2504 >> 2]=1.1250001 + f32[2508 >> 2]=1.1875001 + f32[2512 >> 2]=1.2500001 + f32[2516 >> 2]=1.3125001 + f32[2520 >> 2]=1.3750001 + f32[2524 >> 2]=1.4375001 + f32[2528 >> 2]=1.5000001 + f32[2532 >> 2]=1.5625001 + f32[2536 >> 2]=1.6250001 + f32[2540 >> 2]=1.6875001 + f32[2540 >> 2]=1.6875001 + f32[2544 >> 2]=1.7500001 + f32[2548 >> 2]=1.8125001 + f32[2552 >> 2]=1.8750001 + f32[2556 >> 2]=1.9375001 + f32[2560 >> 2]=-2.0000002 + f32[2564 >> 2]=-2.1250002 + f32[2568 >> 2]=-2.2500002 + f32[2572 >> 2]=-2.3750002 + f32[2576 >> 2]=-2.5000002 + f32[2580 >> 2]=-2.6250002 + f32[2584 >> 2]=-2.7500002 + f32[2588 >> 2]=-2.8750002 + f32[2592 >> 2]=-3.0000002 + f32[2596 >> 2]=-3.1250002 + f32[2600 >> 2]=-3.2500002 + f32[2604 >> 2]=-3.3750002 + f32[2608 >> 2]=-3.5000002 + f32[2612 >> 2]=-3.6250002 + f32[2616 >> 2]=-3.7500002 + f32[2620 >> 2]=-3.8750002 + f32[2624 >> 2]=-4.0000005 + f32[2628 >> 2]=-4.2500005 + f32[2632 >> 2]=-4.5000005 + f32[2636 >> 2]=-4.7500005 + f32[2640 >> 2]=-5.0000005 + f32[2644 >> 2]=-5.2500005 + f32[2648 >> 2]=-5.5000005 + f32[2652 >> 2]=-5.7500005 + f32[2656 >> 2]=-6.0000005 + f32[2660 >> 2]=-6.2500005 + f32[2664 >> 2]=-6.5000005 + f32[2668 >> 2]=-6.7500005 + f32[2672 >> 2]=-7.0000005 + f32[2676 >> 2]=-7.2500005 + f32[2680 >> 2]=-7.5000005 + f32[2684 >> 2]=-7.7500005 + f32[2688 >> 2]=-8.000001 + f32[2692 >> 2]=-8.500001 + f32[2696 >> 2]=-9.000001 + f32[2700 >> 2]=-9.500001 + f32[2704 >> 2]=-10.000001 + f32[2708 >> 2]=-10.500001 + f32[2712 >> 2]=-11.000001 + f32[2716 >> 2]=-11.500001 + f32[2720 >> 2]=-12.000001 + f32[2724 >> 2]=-12.500001 + f32[2728 >> 2]=-13.000001 + f32[2732 >> 2]=-13.500001 + f32[2736 >> 2]=-14.000001 + f32[2740 >> 2]=-14.500001 + f32[2744 >> 2]=-15.000001 + f32[2748 >> 2]=-15.500001 + f32[2752 >> 2]=-16.000002 + f32[2756 >> 2]=-17.000002 + f32[2760 >> 2]=-18.000002 + f32[2764 >> 2]=-19.000002 + f32[2768 >> 2]=-20.000002 + f32[2772 >> 2]=-21.000002 + f32[2776 >> 2]=-22.000002 + f32[2780 >> 2]=-23.000002 + f32[2784 >> 2]=-24.000002 + f32[2788 >> 2]=-25.000002 + f32[2792 >> 2]=-26.000002 + f32[2796 >> 2]=-27.000002 + f32[2800 >> 2]=-28.000002 + f32[2804 >> 2]=-29.000002 + f32[2808 >> 2]=-30.000002 + f32[2812 >> 2]=-31.000002 + f32[2816 >> 2]=-0.12500001 + f32[2820 >> 2]=-0.13281251 + f32[2824 >> 2]=-0.14062501 + f32[2828 >> 2]=-0.14843751 + f32[2832 >> 2]=-0.15625001 + f32[2836 >> 2]=-0.16406251 + f32[2840 >> 2]=-0.17187501 + f32[2844 >> 2]=-0.17968751 + f32[2848 >> 2]=-0.18750001 + f32[2852 >> 2]=-0.19531251 + f32[2856 >> 2]=-0.20312501 + f32[2860 >> 2]=-0.21093751 + f32[2864 >> 2]=-0.21875001 + f32[2868 >> 2]=-0.22656251 + f32[2872 >> 2]=-0.23437501 + f32[2876 >> 2]=-0.24218751 + f32[2880 >> 2]=-0.25000003 + f32[2884 >> 2]=-0.26562503 + f32[2888 >> 2]=-0.28125003 + f32[2892 >> 2]=-0.29687503 + f32[2896 >> 2]=-0.31250003 + f32[2900 >> 2]=-0.32812503 + f32[2904 >> 2]=-0.34375003 + f32[2908 >> 2]=-0.35937503 + f32[2912 >> 2]=-0.37500003 + f32[2916 >> 2]=-0.39062503 + f32[2920 >> 2]=-0.40625003 + f32[2924 >> 2]=-0.42187503 + f32[2928 >> 2]=-0.43750003 + f32[2932 >> 2]=-0.45312503 + f32[2936 >> 2]=-0.46875003 + f32[2940 >> 2]=-0.48437503 + f32[2940 >> 2]=-0.48437503 + f32[2944 >> 2]=-0.50000006 + f32[2948 >> 2]=-0.53125006 + f32[2952 >> 2]=-0.56250006 + f32[2956 >> 2]=-0.59375006 + f32[2960 >> 2]=-0.62500006 + f32[2964 >> 2]=-0.65625006 + f32[2968 >> 2]=-0.68750006 + f32[2972 >> 2]=-0.71875006 + f32[2976 >> 2]=-0.75000006 + f32[2980 >> 2]=-0.78125006 + f32[2984 >> 2]=-0.81250006 + f32[2988 >> 2]=-0.84375006 + f32[2992 >> 2]=-0.87500006 + f32[2996 >> 2]=-0.90625006 + f32[3000 >> 2]=-0.93750006 + f32[3004 >> 2]=-0.96875006 + f32[3008 >> 2]=-1.0000001 + f32[3012 >> 2]=-1.0625001 + f32[3016 >> 2]=-1.1250001 + f32[3020 >> 2]=-1.1875001 + f32[3024 >> 2]=-1.2500001 + f32[3028 >> 2]=-1.3125001 + f32[3032 >> 2]=-1.3750001 + f32[3036 >> 2]=-1.4375001 + f32[3040 >> 2]=-1.5000001 + f32[3044 >> 2]=-1.5625001 + f32[3048 >> 2]=-1.6250001 + f32[3052 >> 2]=-1.6875001 + f32[3056 >> 2]=-1.7500001 + f32[3060 >> 2]=-1.8125001 + f32[3064 >> 2]=-1.8750001 + f32[3068 >> 2]=-1.9375001 + + // Just the highest zero bit set. + f32[3073 >> 2]=2.0625 + f32[3073 >> 2]=2.0625 + f32[3077 >> 2]=2.1875 + f32[3081 >> 2]=2.3125 + f32[3085 >> 2]=2.4375 + f32[3089 >> 2]=2.5625 + f32[3093 >> 2]=2.6875 + f32[3097 >> 2]=2.8125 + f32[3101 >> 2]=2.9375 + f32[3105 >> 2]=3.0625 + f32[3109 >> 2]=3.1875 + f32[3113 >> 2]=3.3125 + f32[3117 >> 2]=3.4375 + f32[3121 >> 2]=3.5625 + f32[3125 >> 2]=3.6875 + f32[3129 >> 2]=3.8125 + f32[3133 >> 2]=3.9375 + f32[3137 >> 2]=4.125 + f32[3141 >> 2]=4.375 + f32[3145 >> 2]=4.625 + f32[3149 >> 2]=4.875 + f32[3153 >> 2]=5.125 + f32[3157 >> 2]=5.375 + f32[3161 >> 2]=5.625 + f32[3165 >> 2]=5.875 + f32[3169 >> 2]=6.125 + f32[3173 >> 2]=6.375 + f32[3177 >> 2]=6.625 + f32[3181 >> 2]=6.875 + f32[3185 >> 2]=7.125 + f32[3189 >> 2]=7.375 + f32[3193 >> 2]=7.625 + f32[3197 >> 2]=7.875 + f32[3201 >> 2]=8.25 + f32[3205 >> 2]=8.75 + f32[3209 >> 2]=9.25 + f32[3213 >> 2]=9.75 + f32[3217 >> 2]=10.25 + f32[3221 >> 2]=10.75 + f32[3225 >> 2]=11.25 + f32[3229 >> 2]=11.75 + f32[3233 >> 2]=12.25 + f32[3237 >> 2]=12.75 + f32[3241 >> 2]=13.25 + f32[3245 >> 2]=13.75 + f32[3249 >> 2]=14.25 + f32[3253 >> 2]=14.75 + f32[3257 >> 2]=15.25 + f32[3261 >> 2]=15.75 + f32[3265 >> 2]=16.5 + f32[3269 >> 2]=17.5 + f32[3273 >> 2]=18.5 + f32[3277 >> 2]=19.5 + f32[3281 >> 2]=20.5 + f32[3285 >> 2]=21.5 + f32[3289 >> 2]=22.5 + f32[3293 >> 2]=23.5 + f32[3297 >> 2]=24.5 + f32[3301 >> 2]=25.5 + f32[3305 >> 2]=26.5 + f32[3309 >> 2]=27.5 + f32[3313 >> 2]=28.5 + f32[3317 >> 2]=29.5 + f32[3321 >> 2]=30.5 + f32[3325 >> 2]=31.5 + f32[3329 >> 2]=0.12890625 + f32[3333 >> 2]=0.13671875 + f32[3337 >> 2]=0.14453125 + f32[3341 >> 2]=0.15234375 + f32[3345 >> 2]=0.16015625 + f32[3349 >> 2]=0.16796875 + f32[3353 >> 2]=0.17578125 + f32[3357 >> 2]=0.18359375 + f32[3361 >> 2]=0.19140625 + f32[3365 >> 2]=0.19921875 + f32[3369 >> 2]=0.20703125 + f32[3373 >> 2]=0.21484375 + f32[3377 >> 2]=0.22265625 + f32[3381 >> 2]=0.23046875 + f32[3385 >> 2]=0.23828125 + f32[3389 >> 2]=0.24609375 + f32[3393 >> 2]=0.2578125 + f32[3397 >> 2]=0.2734375 + f32[3401 >> 2]=0.2890625 + f32[3405 >> 2]=0.3046875 + f32[3409 >> 2]=0.3203125 + f32[3413 >> 2]=0.3359375 + f32[3417 >> 2]=0.3515625 + f32[3421 >> 2]=0.3671875 + f32[3425 >> 2]=0.3828125 + f32[3429 >> 2]=0.3984375 + f32[3433 >> 2]=0.4140625 + f32[3437 >> 2]=0.4296875 + f32[3441 >> 2]=0.4453125 + f32[3445 >> 2]=0.4609375 + f32[3449 >> 2]=0.4765625 + f32[3453 >> 2]=0.4921875 + f32[3457 >> 2]=0.515625 + f32[3461 >> 2]=0.546875 + f32[3465 >> 2]=0.578125 + f32[3469 >> 2]=0.609375 + f32[3473 >> 2]=0.640625 + f32[3473 >> 2]=0.640625 + f32[3477 >> 2]=0.671875 + f32[3481 >> 2]=0.703125 + f32[3485 >> 2]=0.734375 + f32[3489 >> 2]=0.765625 + f32[3493 >> 2]=0.796875 + f32[3497 >> 2]=0.828125 + f32[3501 >> 2]=0.859375 + f32[3505 >> 2]=0.890625 + f32[3509 >> 2]=0.921875 + f32[3513 >> 2]=0.953125 + f32[3517 >> 2]=0.984375 + f32[3521 >> 2]=1.03125 + f32[3525 >> 2]=1.09375 + f32[3529 >> 2]=1.15625 + f32[3533 >> 2]=1.21875 + f32[3537 >> 2]=1.28125 + f32[3541 >> 2]=1.34375 + f32[3545 >> 2]=1.40625 + f32[3549 >> 2]=1.46875 + f32[3553 >> 2]=1.53125 + f32[3557 >> 2]=1.59375 + f32[3561 >> 2]=1.65625 + f32[3565 >> 2]=1.71875 + f32[3569 >> 2]=1.78125 + f32[3573 >> 2]=1.84375 + f32[3577 >> 2]=1.90625 + f32[3581 >> 2]=1.96875 + f32[3585 >> 2]=-2.0625 + f32[3589 >> 2]=-2.1875 + f32[3593 >> 2]=-2.3125 + f32[3597 >> 2]=-2.4375 + f32[3601 >> 2]=-2.5625 + f32[3605 >> 2]=-2.6875 + f32[3609 >> 2]=-2.8125 + f32[3613 >> 2]=-2.9375 + f32[3617 >> 2]=-3.0625 + f32[3621 >> 2]=-3.1875 + f32[3625 >> 2]=-3.3125 + f32[3629 >> 2]=-3.4375 + f32[3633 >> 2]=-3.5625 + f32[3637 >> 2]=-3.6875 + f32[3641 >> 2]=-3.8125 + f32[3645 >> 2]=-3.9375 + f32[3649 >> 2]=-4.125 + f32[3653 >> 2]=-4.375 + f32[3657 >> 2]=-4.625 + f32[3661 >> 2]=-4.875 + f32[3665 >> 2]=-5.125 + f32[3669 >> 2]=-5.375 + f32[3673 >> 2]=-5.625 + f32[3677 >> 2]=-5.875 + f32[3681 >> 2]=-6.125 + f32[3685 >> 2]=-6.375 + f32[3689 >> 2]=-6.625 + f32[3693 >> 2]=-6.875 + f32[3697 >> 2]=-7.125 + f32[3701 >> 2]=-7.375 + f32[3705 >> 2]=-7.625 + f32[3709 >> 2]=-7.875 + f32[3713 >> 2]=-8.25 + f32[3717 >> 2]=-8.75 + f32[3721 >> 2]=-9.25 + f32[3725 >> 2]=-9.75 + f32[3729 >> 2]=-10.25 + f32[3733 >> 2]=-10.75 + f32[3737 >> 2]=-11.25 + f32[3741 >> 2]=-11.75 + f32[3745 >> 2]=-12.25 + f32[3749 >> 2]=-12.75 + f32[3753 >> 2]=-13.25 + f32[3757 >> 2]=-13.75 + f32[3761 >> 2]=-14.25 + f32[3765 >> 2]=-14.75 + f32[3769 >> 2]=-15.25 + f32[3773 >> 2]=-15.75 + f32[3777 >> 2]=-16.5 + f32[3781 >> 2]=-17.5 + f32[3785 >> 2]=-18.5 + f32[3789 >> 2]=-19.5 + f32[3793 >> 2]=-20.5 + f32[3797 >> 2]=-21.5 + f32[3801 >> 2]=-22.5 + f32[3805 >> 2]=-23.5 + f32[3809 >> 2]=-24.5 + f32[3813 >> 2]=-25.5 + f32[3817 >> 2]=-26.5 + f32[3821 >> 2]=-27.5 + f32[3825 >> 2]=-28.5 + f32[3829 >> 2]=-29.5 + f32[3833 >> 2]=-30.5 + f32[3837 >> 2]=-31.5 + f32[3841 >> 2]=-0.12890625 + f32[3845 >> 2]=-0.13671875 + f32[3849 >> 2]=-0.14453125 + f32[3853 >> 2]=-0.15234375 + f32[3857 >> 2]=-0.16015625 + f32[3861 >> 2]=-0.16796875 + f32[3865 >> 2]=-0.17578125 + f32[3869 >> 2]=-0.18359375 + f32[3873 >> 2]=-0.19140625 + f32[3873 >> 2]=-0.19140625 + f32[3877 >> 2]=-0.19921875 + f32[3881 >> 2]=-0.20703125 + f32[3885 >> 2]=-0.21484375 + f32[3889 >> 2]=-0.22265625 + f32[3893 >> 2]=-0.23046875 + f32[3897 >> 2]=-0.23828125 + f32[3901 >> 2]=-0.24609375 + f32[3905 >> 2]=-0.2578125 + f32[3909 >> 2]=-0.2734375 + f32[3913 >> 2]=-0.2890625 + f32[3917 >> 2]=-0.3046875 + f32[3921 >> 2]=-0.3203125 + f32[3925 >> 2]=-0.3359375 + f32[3929 >> 2]=-0.3515625 + f32[3933 >> 2]=-0.3671875 + f32[3937 >> 2]=-0.3828125 + f32[3941 >> 2]=-0.3984375 + f32[3945 >> 2]=-0.4140625 + f32[3949 >> 2]=-0.4296875 + f32[3953 >> 2]=-0.4453125 + f32[3957 >> 2]=-0.4609375 + f32[3961 >> 2]=-0.4765625 + f32[3965 >> 2]=-0.4921875 + f32[3969 >> 2]=-0.515625 + f32[3973 >> 2]=-0.546875 + f32[3977 >> 2]=-0.578125 + f32[3981 >> 2]=-0.609375 + f32[3985 >> 2]=-0.640625 + f32[3989 >> 2]=-0.671875 + f32[3993 >> 2]=-0.703125 + f32[3997 >> 2]=-0.734375 + f32[4001 >> 2]=-0.765625 + f32[4005 >> 2]=-0.796875 + f32[4009 >> 2]=-0.828125 + f32[4013 >> 2]=-0.859375 + f32[4017 >> 2]=-0.890625 + f32[4021 >> 2]=-0.921875 + f32[4025 >> 2]=-0.953125 + f32[4029 >> 2]=-0.984375 + f32[4033 >> 2]=-1.03125 + f32[4037 >> 2]=-1.09375 + f32[4041 >> 2]=-1.15625 + f32[4045 >> 2]=-1.21875 + f32[4049 >> 2]=-1.28125 + f32[4053 >> 2]=-1.34375 + f32[4057 >> 2]=-1.40625 + f32[4061 >> 2]=-1.46875 + f32[4065 >> 2]=-1.53125 + f32[4069 >> 2]=-1.59375 + f32[4073 >> 2]=-1.65625 + f32[4077 >> 2]=-1.71875 + f32[4081 >> 2]=-1.78125 + f32[4085 >> 2]=-1.84375 + f32[4089 >> 2]=-1.90625 + f32[4093 >> 2]=-1.96875 + }; + + return { + fn1: fn1 + }; +}; + +var asm = testmod(this, {}, buffer); + +asm.fn1() + +var f32=new Float32Array(buffer); +assertEq(f32[0 >> 2], 2.0) +assertEq(f32[4 >> 2], 2.125) +assertEq(f32[8 >> 2], 2.25) +assertEq(f32[12 >> 2], 2.375) +assertEq(f32[16 >> 2], 2.5) +assertEq(f32[20 >> 2], 2.625) +assertEq(f32[24 >> 2], 2.75) +assertEq(f32[28 >> 2], 2.875) +assertEq(f32[32 >> 2], 3.0) +assertEq(f32[36 >> 2], 3.125) +assertEq(f32[40 >> 2], 3.25) +assertEq(f32[44 >> 2], 3.375) +assertEq(f32[48 >> 2], 3.5) +assertEq(f32[52 >> 2], 3.625) +assertEq(f32[56 >> 2], 3.75) +assertEq(f32[60 >> 2], 3.875) +assertEq(f32[64 >> 2], 4.0) +assertEq(f32[68 >> 2], 4.25) +assertEq(f32[72 >> 2], 4.5) +assertEq(f32[76 >> 2], 4.75) +assertEq(f32[80 >> 2], 5.0) +assertEq(f32[84 >> 2], 5.25) +assertEq(f32[88 >> 2], 5.5) +assertEq(f32[92 >> 2], 5.75) +assertEq(f32[96 >> 2], 6.0) +assertEq(f32[100 >> 2], 6.25) +assertEq(f32[104 >> 2], 6.5) +assertEq(f32[108 >> 2], 6.75) +assertEq(f32[112 >> 2], 7.0) +assertEq(f32[116 >> 2], 7.25) +assertEq(f32[120 >> 2], 7.5) +assertEq(f32[124 >> 2], 7.75) +assertEq(f32[128 >> 2], 8.0) +assertEq(f32[132 >> 2], 8.5) +assertEq(f32[136 >> 2], 9.0) +assertEq(f32[140 >> 2], 9.5) +assertEq(f32[144 >> 2], 10.0) +assertEq(f32[148 >> 2], 10.5) +assertEq(f32[152 >> 2], 11.0) +assertEq(f32[156 >> 2], 11.5) +assertEq(f32[160 >> 2], 12.0) +assertEq(f32[164 >> 2], 12.5) +assertEq(f32[168 >> 2], 13.0) +assertEq(f32[172 >> 2], 13.5) +assertEq(f32[176 >> 2], 14.0) +assertEq(f32[180 >> 2], 14.5) +assertEq(f32[184 >> 2], 15.0) +assertEq(f32[188 >> 2], 15.5) +assertEq(f32[192 >> 2], 16.0) +assertEq(f32[196 >> 2], 17.0) +assertEq(f32[200 >> 2], 18.0) +assertEq(f32[204 >> 2], 19.0) +assertEq(f32[208 >> 2], 20.0) +assertEq(f32[212 >> 2], 21.0) +assertEq(f32[216 >> 2], 22.0) +assertEq(f32[220 >> 2], 23.0) +assertEq(f32[224 >> 2], 24.0) +assertEq(f32[228 >> 2], 25.0) +assertEq(f32[232 >> 2], 26.0) +assertEq(f32[236 >> 2], 27.0) +assertEq(f32[240 >> 2], 28.0) +assertEq(f32[244 >> 2], 29.0) +assertEq(f32[248 >> 2], 30.0) +assertEq(f32[252 >> 2], 31.0) +assertEq(f32[256 >> 2], 0.125) +assertEq(f32[260 >> 2], 0.1328125) +assertEq(f32[264 >> 2], 0.140625) +assertEq(f32[268 >> 2], 0.1484375) +assertEq(f32[272 >> 2], 0.15625) +assertEq(f32[276 >> 2], 0.1640625) +assertEq(f32[280 >> 2], 0.171875) +assertEq(f32[284 >> 2], 0.1796875) +assertEq(f32[288 >> 2], 0.1875) +assertEq(f32[292 >> 2], 0.1953125) +assertEq(f32[296 >> 2], 0.203125) +assertEq(f32[300 >> 2], 0.2109375) +assertEq(f32[304 >> 2], 0.21875) +assertEq(f32[308 >> 2], 0.2265625) +assertEq(f32[312 >> 2], 0.234375) +assertEq(f32[316 >> 2], 0.2421875) +assertEq(f32[320 >> 2], 0.25) +assertEq(f32[324 >> 2], 0.265625) +assertEq(f32[328 >> 2], 0.28125) +assertEq(f32[332 >> 2], 0.296875) +assertEq(f32[336 >> 2], 0.3125) +assertEq(f32[340 >> 2], 0.328125) +assertEq(f32[344 >> 2], 0.34375) +assertEq(f32[348 >> 2], 0.359375) +assertEq(f32[348 >> 2], 0.359375) +assertEq(f32[352 >> 2], 0.375) +assertEq(f32[356 >> 2], 0.390625) +assertEq(f32[360 >> 2], 0.40625) +assertEq(f32[364 >> 2], 0.421875) +assertEq(f32[368 >> 2], 0.4375) +assertEq(f32[372 >> 2], 0.453125) +assertEq(f32[376 >> 2], 0.46875) +assertEq(f32[380 >> 2], 0.484375) +assertEq(f32[384 >> 2], 0.5) +assertEq(f32[388 >> 2], 0.53125) +assertEq(f32[392 >> 2], 0.5625) +assertEq(f32[396 >> 2], 0.59375) +assertEq(f32[400 >> 2], 0.625) +assertEq(f32[404 >> 2], 0.65625) +assertEq(f32[408 >> 2], 0.6875) +assertEq(f32[412 >> 2], 0.71875) +assertEq(f32[416 >> 2], 0.75) +assertEq(f32[420 >> 2], 0.78125) +assertEq(f32[424 >> 2], 0.8125) +assertEq(f32[428 >> 2], 0.84375) +assertEq(f32[432 >> 2], 0.875) +assertEq(f32[436 >> 2], 0.90625) +assertEq(f32[440 >> 2], 0.9375) +assertEq(f32[444 >> 2], 0.96875) +assertEq(f32[448 >> 2], 1.0) +assertEq(f32[452 >> 2], 1.0625) +assertEq(f32[456 >> 2], 1.125) +assertEq(f32[460 >> 2], 1.1875) +assertEq(f32[464 >> 2], 1.25) +assertEq(f32[468 >> 2], 1.3125) +assertEq(f32[472 >> 2], 1.375) +assertEq(f32[476 >> 2], 1.4375) +assertEq(f32[480 >> 2], 1.5) +assertEq(f32[484 >> 2], 1.5625) +assertEq(f32[488 >> 2], 1.625) +assertEq(f32[492 >> 2], 1.6875) +assertEq(f32[496 >> 2], 1.75) +assertEq(f32[500 >> 2], 1.8125) +assertEq(f32[504 >> 2], 1.875) +assertEq(f32[508 >> 2], 1.9375) +assertEq(f32[512 >> 2], -2.0) +assertEq(f32[516 >> 2], -2.125) +assertEq(f32[520 >> 2], -2.25) +assertEq(f32[524 >> 2], -2.375) +assertEq(f32[528 >> 2], -2.5) +assertEq(f32[532 >> 2], -2.625) +assertEq(f32[536 >> 2], -2.75) +assertEq(f32[540 >> 2], -2.875) +assertEq(f32[544 >> 2], -3.0) +assertEq(f32[548 >> 2], -3.125) +assertEq(f32[552 >> 2], -3.25) +assertEq(f32[556 >> 2], -3.375) +assertEq(f32[560 >> 2], -3.5) +assertEq(f32[564 >> 2], -3.625) +assertEq(f32[568 >> 2], -3.75) +assertEq(f32[572 >> 2], -3.875) +assertEq(f32[576 >> 2], -4.0) +assertEq(f32[580 >> 2], -4.25) +assertEq(f32[584 >> 2], -4.5) +assertEq(f32[588 >> 2], -4.75) +assertEq(f32[592 >> 2], -5.0) +assertEq(f32[596 >> 2], -5.25) +assertEq(f32[600 >> 2], -5.5) +assertEq(f32[604 >> 2], -5.75) +assertEq(f32[608 >> 2], -6.0) +assertEq(f32[612 >> 2], -6.25) +assertEq(f32[616 >> 2], -6.5) +assertEq(f32[620 >> 2], -6.75) +assertEq(f32[624 >> 2], -7.0) +assertEq(f32[628 >> 2], -7.25) +assertEq(f32[632 >> 2], -7.5) +assertEq(f32[636 >> 2], -7.75) +assertEq(f32[640 >> 2], -8.0) +assertEq(f32[644 >> 2], -8.5) +assertEq(f32[648 >> 2], -9.0) +assertEq(f32[652 >> 2], -9.5) +assertEq(f32[656 >> 2], -10.0) +assertEq(f32[660 >> 2], -10.5) +assertEq(f32[664 >> 2], -11.0) +assertEq(f32[668 >> 2], -11.5) +assertEq(f32[672 >> 2], -12.0) +assertEq(f32[676 >> 2], -12.5) +assertEq(f32[680 >> 2], -13.0) +assertEq(f32[684 >> 2], -13.5) +assertEq(f32[688 >> 2], -14.0) +assertEq(f32[692 >> 2], -14.5) +assertEq(f32[696 >> 2], -15.0) +assertEq(f32[700 >> 2], -15.5) +assertEq(f32[704 >> 2], -16.0) +assertEq(f32[708 >> 2], -17.0) +assertEq(f32[712 >> 2], -18.0) +assertEq(f32[716 >> 2], -19.0) +assertEq(f32[720 >> 2], -20.0) +assertEq(f32[724 >> 2], -21.0) +assertEq(f32[728 >> 2], -22.0) +assertEq(f32[732 >> 2], -23.0) +assertEq(f32[736 >> 2], -24.0) +assertEq(f32[740 >> 2], -25.0) +assertEq(f32[744 >> 2], -26.0) +assertEq(f32[748 >> 2], -27.0) +assertEq(f32[748 >> 2], -27.0) +assertEq(f32[752 >> 2], -28.0) +assertEq(f32[756 >> 2], -29.0) +assertEq(f32[760 >> 2], -30.0) +assertEq(f32[764 >> 2], -31.0) +assertEq(f32[768 >> 2], -0.125) +assertEq(f32[772 >> 2], -0.1328125) +assertEq(f32[776 >> 2], -0.140625) +assertEq(f32[780 >> 2], -0.1484375) +assertEq(f32[784 >> 2], -0.15625) +assertEq(f32[788 >> 2], -0.1640625) +assertEq(f32[792 >> 2], -0.171875) +assertEq(f32[796 >> 2], -0.1796875) +assertEq(f32[800 >> 2], -0.1875) +assertEq(f32[804 >> 2], -0.1953125) +assertEq(f32[808 >> 2], -0.203125) +assertEq(f32[812 >> 2], -0.2109375) +assertEq(f32[816 >> 2], -0.21875) +assertEq(f32[820 >> 2], -0.2265625) +assertEq(f32[824 >> 2], -0.234375) +assertEq(f32[828 >> 2], -0.2421875) +assertEq(f32[832 >> 2], -0.25) +assertEq(f32[836 >> 2], -0.265625) +assertEq(f32[840 >> 2], -0.28125) +assertEq(f32[844 >> 2], -0.296875) +assertEq(f32[848 >> 2], -0.3125) +assertEq(f32[852 >> 2], -0.328125) +assertEq(f32[856 >> 2], -0.34375) +assertEq(f32[860 >> 2], -0.359375) +assertEq(f32[864 >> 2], -0.375) +assertEq(f32[868 >> 2], -0.390625) +assertEq(f32[872 >> 2], -0.40625) +assertEq(f32[876 >> 2], -0.421875) +assertEq(f32[880 >> 2], -0.4375) +assertEq(f32[884 >> 2], -0.453125) +assertEq(f32[888 >> 2], -0.46875) +assertEq(f32[892 >> 2], -0.484375) +assertEq(f32[896 >> 2], -0.5) +assertEq(f32[900 >> 2], -0.53125) +assertEq(f32[904 >> 2], -0.5625) +assertEq(f32[908 >> 2], -0.59375) +assertEq(f32[912 >> 2], -0.625) +assertEq(f32[916 >> 2], -0.65625) +assertEq(f32[920 >> 2], -0.6875) +assertEq(f32[924 >> 2], -0.71875) +assertEq(f32[928 >> 2], -0.75) +assertEq(f32[932 >> 2], -0.78125) +assertEq(f32[936 >> 2], -0.8125) +assertEq(f32[940 >> 2], -0.84375) +assertEq(f32[944 >> 2], -0.875) +assertEq(f32[948 >> 2], -0.90625) +assertEq(f32[952 >> 2], -0.9375) +assertEq(f32[956 >> 2], -0.96875) +assertEq(f32[960 >> 2], -1.0) +assertEq(f32[964 >> 2], -1.0625) +assertEq(f32[968 >> 2], -1.125) +assertEq(f32[972 >> 2], -1.1875) +assertEq(f32[976 >> 2], -1.25) +assertEq(f32[980 >> 2], -1.3125) +assertEq(f32[984 >> 2], -1.375) +assertEq(f32[988 >> 2], -1.4375) +assertEq(f32[992 >> 2], -1.5) +assertEq(f32[996 >> 2], -1.5625) +assertEq(f32[1000 >> 2], -1.625) +assertEq(f32[1004 >> 2], -1.6875) +assertEq(f32[1008 >> 2], -1.75) +assertEq(f32[1012 >> 2], -1.8125) +assertEq(f32[1016 >> 2], -1.875) +assertEq(f32[1020 >> 2], -1.9375) + +assertEq(f32[1024 >> 2], 2.124999761581421) +assertEq(f32[1028 >> 2], 2.249999761581421) +assertEq(f32[1032 >> 2], 2.374999761581421) +assertEq(f32[1036 >> 2], 2.499999761581421) +assertEq(f32[1040 >> 2], 2.624999761581421) +assertEq(f32[1044 >> 2], 2.749999761581421) +assertEq(f32[1048 >> 2], 2.874999761581421) +assertEq(f32[1052 >> 2], 2.999999761581421) +assertEq(f32[1056 >> 2], 3.124999761581421) +assertEq(f32[1060 >> 2], 3.249999761581421) +assertEq(f32[1064 >> 2], 3.374999761581421) +assertEq(f32[1068 >> 2], 3.499999761581421) +assertEq(f32[1072 >> 2], 3.624999761581421) +assertEq(f32[1076 >> 2], 3.749999761581421) +assertEq(f32[1080 >> 2], 3.874999761581421) +assertEq(f32[1084 >> 2], 3.999999761581421) +assertEq(f32[1088 >> 2], 4.249999523162842) +assertEq(f32[1092 >> 2], 4.499999523162842) +assertEq(f32[1096 >> 2], 4.749999523162842) +assertEq(f32[1100 >> 2], 4.999999523162842) +assertEq(f32[1104 >> 2], 5.249999523162842) +assertEq(f32[1108 >> 2], 5.499999523162842) +assertEq(f32[1112 >> 2], 5.749999523162842) +assertEq(f32[1116 >> 2], 5.999999523162842) +assertEq(f32[1120 >> 2], 6.249999523162842) +assertEq(f32[1124 >> 2], 6.499999523162842) +assertEq(f32[1128 >> 2], 6.749999523162842) +assertEq(f32[1132 >> 2], 6.999999523162842) +assertEq(f32[1136 >> 2], 7.249999523162842) +assertEq(f32[1140 >> 2], 7.499999523162842) +assertEq(f32[1144 >> 2], 7.749999523162842) +assertEq(f32[1148 >> 2], 7.999999523162842) +assertEq(f32[1152 >> 2], 8.499999046325684) +assertEq(f32[1156 >> 2], 8.999999046325684) +assertEq(f32[1160 >> 2], 9.499999046325684) +assertEq(f32[1164 >> 2], 9.999999046325684) +assertEq(f32[1168 >> 2], 10.499999046325684) +assertEq(f32[1172 >> 2], 10.999999046325684) +assertEq(f32[1176 >> 2], 11.499999046325684) +assertEq(f32[1180 >> 2], 11.999999046325684) +assertEq(f32[1184 >> 2], 12.499999046325684) +assertEq(f32[1184 >> 2], 12.499999046325684) +assertEq(f32[1188 >> 2], 12.999999046325684) +assertEq(f32[1192 >> 2], 13.499999046325684) +assertEq(f32[1196 >> 2], 13.999999046325684) +assertEq(f32[1200 >> 2], 14.499999046325684) +assertEq(f32[1204 >> 2], 14.999999046325684) +assertEq(f32[1208 >> 2], 15.499999046325684) +assertEq(f32[1212 >> 2], 15.999999046325684) +assertEq(f32[1216 >> 2], 16.999998092651367) +assertEq(f32[1220 >> 2], 17.999998092651367) +assertEq(f32[1224 >> 2], 18.999998092651367) +assertEq(f32[1228 >> 2], 19.999998092651367) +assertEq(f32[1232 >> 2], 20.999998092651367) +assertEq(f32[1236 >> 2], 21.999998092651367) +assertEq(f32[1240 >> 2], 22.999998092651367) +assertEq(f32[1244 >> 2], 23.999998092651367) +assertEq(f32[1248 >> 2], 24.999998092651367) +assertEq(f32[1252 >> 2], 25.999998092651367) +assertEq(f32[1256 >> 2], 26.999998092651367) +assertEq(f32[1260 >> 2], 27.999998092651367) +assertEq(f32[1264 >> 2], 28.999998092651367) +assertEq(f32[1268 >> 2], 29.999998092651367) +assertEq(f32[1272 >> 2], 30.999998092651367) +assertEq(f32[1276 >> 2], 31.999998092651367) +assertEq(f32[1280 >> 2], 0.1328124850988388) +assertEq(f32[1284 >> 2], 0.1406249850988388) +assertEq(f32[1288 >> 2], 0.1484374850988388) +assertEq(f32[1292 >> 2], 0.1562499850988388) +assertEq(f32[1296 >> 2], 0.1640624850988388) +assertEq(f32[1300 >> 2], 0.1718749850988388) +assertEq(f32[1304 >> 2], 0.1796874850988388) +assertEq(f32[1308 >> 2], 0.1874999850988388) +assertEq(f32[1312 >> 2], 0.1953124850988388) +assertEq(f32[1316 >> 2], 0.2031249850988388) +assertEq(f32[1320 >> 2], 0.2109374850988388) +assertEq(f32[1324 >> 2], 0.2187499850988388) +assertEq(f32[1328 >> 2], 0.2265624850988388) +assertEq(f32[1332 >> 2], 0.2343749850988388) +assertEq(f32[1336 >> 2], 0.2421874850988388) +assertEq(f32[1340 >> 2], 0.2499999850988388) +assertEq(f32[1344 >> 2], 0.2656249701976776) +assertEq(f32[1348 >> 2], 0.2812499701976776) +assertEq(f32[1352 >> 2], 0.2968749701976776) +assertEq(f32[1356 >> 2], 0.3124999701976776) +assertEq(f32[1360 >> 2], 0.3281249701976776) +assertEq(f32[1364 >> 2], 0.3437499701976776) +assertEq(f32[1368 >> 2], 0.3593749701976776) +assertEq(f32[1372 >> 2], 0.3749999701976776) +assertEq(f32[1376 >> 2], 0.3906249701976776) +assertEq(f32[1380 >> 2], 0.4062499701976776) +assertEq(f32[1384 >> 2], 0.4218749701976776) +assertEq(f32[1388 >> 2], 0.4374999701976776) +assertEq(f32[1392 >> 2], 0.4531249701976776) +assertEq(f32[1396 >> 2], 0.4687499701976776) +assertEq(f32[1400 >> 2], 0.4843749701976776) +assertEq(f32[1404 >> 2], 0.4999999701976776) +assertEq(f32[1408 >> 2], 0.5312499403953552) +assertEq(f32[1412 >> 2], 0.5624999403953552) +assertEq(f32[1416 >> 2], 0.5937499403953552) +assertEq(f32[1420 >> 2], 0.6249999403953552) +assertEq(f32[1424 >> 2], 0.6562499403953552) +assertEq(f32[1428 >> 2], 0.6874999403953552) +assertEq(f32[1432 >> 2], 0.7187499403953552) +assertEq(f32[1436 >> 2], 0.7499999403953552) +assertEq(f32[1440 >> 2], 0.7812499403953552) +assertEq(f32[1444 >> 2], 0.8124999403953552) +assertEq(f32[1448 >> 2], 0.8437499403953552) +assertEq(f32[1452 >> 2], 0.8749999403953552) +assertEq(f32[1456 >> 2], 0.9062499403953552) +assertEq(f32[1460 >> 2], 0.9374999403953552) +assertEq(f32[1464 >> 2], 0.9687499403953552) +assertEq(f32[1468 >> 2], 0.9999999403953552) +assertEq(f32[1472 >> 2], 1.0624998807907104) +assertEq(f32[1476 >> 2], 1.1249998807907104) +assertEq(f32[1480 >> 2], 1.1874998807907104) +assertEq(f32[1484 >> 2], 1.2499998807907104) +assertEq(f32[1488 >> 2], 1.3124998807907104) +assertEq(f32[1492 >> 2], 1.3749998807907104) +assertEq(f32[1496 >> 2], 1.4374998807907104) +assertEq(f32[1500 >> 2], 1.4999998807907104) +assertEq(f32[1504 >> 2], 1.5624998807907104) +assertEq(f32[1508 >> 2], 1.6249998807907104) +assertEq(f32[1512 >> 2], 1.6874998807907104) +assertEq(f32[1516 >> 2], 1.7499998807907104) +assertEq(f32[1520 >> 2], 1.8124998807907104) +assertEq(f32[1524 >> 2], 1.8749998807907104) +assertEq(f32[1528 >> 2], 1.9374998807907104) +assertEq(f32[1532 >> 2], 1.9999998807907104) +assertEq(f32[1536 >> 2], -2.124999761581421) +assertEq(f32[1540 >> 2], -2.249999761581421) +assertEq(f32[1544 >> 2], -2.374999761581421) +assertEq(f32[1548 >> 2], -2.499999761581421) +assertEq(f32[1552 >> 2], -2.624999761581421) +assertEq(f32[1556 >> 2], -2.749999761581421) +assertEq(f32[1560 >> 2], -2.874999761581421) +assertEq(f32[1564 >> 2], -2.999999761581421) +assertEq(f32[1568 >> 2], -3.124999761581421) +assertEq(f32[1572 >> 2], -3.249999761581421) +assertEq(f32[1576 >> 2], -3.374999761581421) +assertEq(f32[1580 >> 2], -3.499999761581421) +assertEq(f32[1584 >> 2], -3.624999761581421) +assertEq(f32[1584 >> 2], -3.624999761581421) +assertEq(f32[1588 >> 2], -3.749999761581421) +assertEq(f32[1592 >> 2], -3.874999761581421) +assertEq(f32[1596 >> 2], -3.999999761581421) +assertEq(f32[1600 >> 2], -4.249999523162842) +assertEq(f32[1604 >> 2], -4.499999523162842) +assertEq(f32[1608 >> 2], -4.749999523162842) +assertEq(f32[1612 >> 2], -4.999999523162842) +assertEq(f32[1616 >> 2], -5.249999523162842) +assertEq(f32[1620 >> 2], -5.499999523162842) +assertEq(f32[1624 >> 2], -5.749999523162842) +assertEq(f32[1628 >> 2], -5.999999523162842) +assertEq(f32[1632 >> 2], -6.249999523162842) +assertEq(f32[1636 >> 2], -6.499999523162842) +assertEq(f32[1640 >> 2], -6.749999523162842) +assertEq(f32[1644 >> 2], -6.999999523162842) +assertEq(f32[1648 >> 2], -7.249999523162842) +assertEq(f32[1652 >> 2], -7.499999523162842) +assertEq(f32[1656 >> 2], -7.749999523162842) +assertEq(f32[1660 >> 2], -7.999999523162842) +assertEq(f32[1664 >> 2], -8.499999046325684) +assertEq(f32[1668 >> 2], -8.999999046325684) +assertEq(f32[1672 >> 2], -9.499999046325684) +assertEq(f32[1676 >> 2], -9.999999046325684) +assertEq(f32[1680 >> 2], -10.499999046325684) +assertEq(f32[1684 >> 2], -10.999999046325684) +assertEq(f32[1688 >> 2], -11.499999046325684) +assertEq(f32[1692 >> 2], -11.999999046325684) +assertEq(f32[1696 >> 2], -12.499999046325684) +assertEq(f32[1700 >> 2], -12.999999046325684) +assertEq(f32[1704 >> 2], -13.499999046325684) +assertEq(f32[1708 >> 2], -13.999999046325684) +assertEq(f32[1712 >> 2], -14.499999046325684) +assertEq(f32[1716 >> 2], -14.999999046325684) +assertEq(f32[1720 >> 2], -15.499999046325684) +assertEq(f32[1724 >> 2], -15.999999046325684) +assertEq(f32[1728 >> 2], -16.999998092651367) +assertEq(f32[1732 >> 2], -17.999998092651367) +assertEq(f32[1736 >> 2], -18.999998092651367) +assertEq(f32[1740 >> 2], -19.999998092651367) +assertEq(f32[1744 >> 2], -20.999998092651367) +assertEq(f32[1748 >> 2], -21.999998092651367) +assertEq(f32[1752 >> 2], -22.999998092651367) +assertEq(f32[1756 >> 2], -23.999998092651367) +assertEq(f32[1760 >> 2], -24.999998092651367) +assertEq(f32[1764 >> 2], -25.999998092651367) +assertEq(f32[1768 >> 2], -26.999998092651367) +assertEq(f32[1772 >> 2], -27.999998092651367) +assertEq(f32[1776 >> 2], -28.999998092651367) +assertEq(f32[1780 >> 2], -29.999998092651367) +assertEq(f32[1784 >> 2], -30.999998092651367) +assertEq(f32[1788 >> 2], -31.999998092651367) +assertEq(f32[1792 >> 2], -0.1328124850988388) +assertEq(f32[1796 >> 2], -0.1406249850988388) +assertEq(f32[1800 >> 2], -0.1484374850988388) +assertEq(f32[1804 >> 2], -0.1562499850988388) +assertEq(f32[1808 >> 2], -0.1640624850988388) +assertEq(f32[1812 >> 2], -0.1718749850988388) +assertEq(f32[1816 >> 2], -0.1796874850988388) +assertEq(f32[1820 >> 2], -0.1874999850988388) +assertEq(f32[1824 >> 2], -0.1953124850988388) +assertEq(f32[1828 >> 2], -0.2031249850988388) +assertEq(f32[1832 >> 2], -0.2109374850988388) +assertEq(f32[1836 >> 2], -0.2187499850988388) +assertEq(f32[1840 >> 2], -0.2265624850988388) +assertEq(f32[1844 >> 2], -0.2343749850988388) +assertEq(f32[1848 >> 2], -0.2421874850988388) +assertEq(f32[1852 >> 2], -0.2499999850988388) +assertEq(f32[1856 >> 2], -0.2656249701976776) +assertEq(f32[1860 >> 2], -0.2812499701976776) +assertEq(f32[1864 >> 2], -0.2968749701976776) +assertEq(f32[1868 >> 2], -0.3124999701976776) +assertEq(f32[1872 >> 2], -0.3281249701976776) +assertEq(f32[1876 >> 2], -0.3437499701976776) +assertEq(f32[1880 >> 2], -0.3593749701976776) +assertEq(f32[1884 >> 2], -0.3749999701976776) +assertEq(f32[1888 >> 2], -0.3906249701976776) +assertEq(f32[1892 >> 2], -0.4062499701976776) +assertEq(f32[1896 >> 2], -0.4218749701976776) +assertEq(f32[1900 >> 2], -0.4374999701976776) +assertEq(f32[1904 >> 2], -0.4531249701976776) +assertEq(f32[1908 >> 2], -0.4687499701976776) +assertEq(f32[1912 >> 2], -0.4843749701976776) +assertEq(f32[1916 >> 2], -0.4999999701976776) +assertEq(f32[1920 >> 2], -0.5312499403953552) +assertEq(f32[1924 >> 2], -0.5624999403953552) +assertEq(f32[1928 >> 2], -0.5937499403953552) +assertEq(f32[1932 >> 2], -0.6249999403953552) +assertEq(f32[1936 >> 2], -0.6562499403953552) +assertEq(f32[1940 >> 2], -0.6874999403953552) +assertEq(f32[1944 >> 2], -0.7187499403953552) +assertEq(f32[1948 >> 2], -0.7499999403953552) +assertEq(f32[1952 >> 2], -0.7812499403953552) +assertEq(f32[1956 >> 2], -0.8124999403953552) +assertEq(f32[1960 >> 2], -0.8437499403953552) +assertEq(f32[1964 >> 2], -0.8749999403953552) +assertEq(f32[1968 >> 2], -0.9062499403953552) +assertEq(f32[1972 >> 2], -0.9374999403953552) +assertEq(f32[1976 >> 2], -0.9687499403953552) +assertEq(f32[1980 >> 2], -0.9999999403953552) +assertEq(f32[1984 >> 2], -1.0624998807907104) +assertEq(f32[1984 >> 2], -1.0624998807907104) +assertEq(f32[1988 >> 2], -1.1249998807907104) +assertEq(f32[1992 >> 2], -1.1874998807907104) +assertEq(f32[1996 >> 2], -1.2499998807907104) +assertEq(f32[2000 >> 2], -1.3124998807907104) +assertEq(f32[2004 >> 2], -1.3749998807907104) +assertEq(f32[2008 >> 2], -1.4374998807907104) +assertEq(f32[2012 >> 2], -1.4999998807907104) +assertEq(f32[2016 >> 2], -1.5624998807907104) +assertEq(f32[2020 >> 2], -1.6249998807907104) +assertEq(f32[2024 >> 2], -1.6874998807907104) +assertEq(f32[2028 >> 2], -1.7499998807907104) +assertEq(f32[2032 >> 2], -1.8124998807907104) +assertEq(f32[2036 >> 2], -1.8749998807907104) +assertEq(f32[2040 >> 2], -1.9374998807907104) +assertEq(f32[2044 >> 2], -1.9999998807907104) + +assertEq(f32[2048 >> 2], 2.000000238418579) +assertEq(f32[2052 >> 2], 2.125000238418579) +assertEq(f32[2056 >> 2], 2.250000238418579) +assertEq(f32[2060 >> 2], 2.375000238418579) +assertEq(f32[2064 >> 2], 2.500000238418579) +assertEq(f32[2068 >> 2], 2.625000238418579) +assertEq(f32[2072 >> 2], 2.750000238418579) +assertEq(f32[2076 >> 2], 2.875000238418579) +assertEq(f32[2080 >> 2], 3.000000238418579) +assertEq(f32[2084 >> 2], 3.125000238418579) +assertEq(f32[2088 >> 2], 3.250000238418579) +assertEq(f32[2092 >> 2], 3.375000238418579) +assertEq(f32[2096 >> 2], 3.500000238418579) +assertEq(f32[2100 >> 2], 3.625000238418579) +assertEq(f32[2104 >> 2], 3.750000238418579) +assertEq(f32[2108 >> 2], 3.875000238418579) +assertEq(f32[2112 >> 2], 4.000000476837158) +assertEq(f32[2116 >> 2], 4.250000476837158) +assertEq(f32[2120 >> 2], 4.500000476837158) +assertEq(f32[2124 >> 2], 4.750000476837158) +assertEq(f32[2128 >> 2], 5.000000476837158) +assertEq(f32[2132 >> 2], 5.250000476837158) +assertEq(f32[2136 >> 2], 5.500000476837158) +assertEq(f32[2140 >> 2], 5.750000476837158) +assertEq(f32[2144 >> 2], 6.000000476837158) +assertEq(f32[2148 >> 2], 6.250000476837158) +assertEq(f32[2152 >> 2], 6.500000476837158) +assertEq(f32[2156 >> 2], 6.750000476837158) +assertEq(f32[2160 >> 2], 7.000000476837158) +assertEq(f32[2164 >> 2], 7.250000476837158) +assertEq(f32[2168 >> 2], 7.500000476837158) +assertEq(f32[2172 >> 2], 7.750000476837158) +assertEq(f32[2176 >> 2], 8.000000953674316) +assertEq(f32[2180 >> 2], 8.500000953674316) +assertEq(f32[2184 >> 2], 9.000000953674316) +assertEq(f32[2188 >> 2], 9.500000953674316) +assertEq(f32[2192 >> 2], 10.000000953674316) +assertEq(f32[2196 >> 2], 10.500000953674316) +assertEq(f32[2200 >> 2], 11.000000953674316) +assertEq(f32[2204 >> 2], 11.500000953674316) +assertEq(f32[2208 >> 2], 12.000000953674316) +assertEq(f32[2212 >> 2], 12.500000953674316) +assertEq(f32[2216 >> 2], 13.000000953674316) +assertEq(f32[2220 >> 2], 13.500000953674316) +assertEq(f32[2224 >> 2], 14.000000953674316) +assertEq(f32[2228 >> 2], 14.500000953674316) +assertEq(f32[2228 >> 2], 14.500000953674316) +assertEq(f32[2232 >> 2], 15.000000953674316) +assertEq(f32[2236 >> 2], 15.500000953674316) +assertEq(f32[2240 >> 2], 16.000001907348633) +assertEq(f32[2244 >> 2], 17.000001907348633) +assertEq(f32[2248 >> 2], 18.000001907348633) +assertEq(f32[2252 >> 2], 19.000001907348633) +assertEq(f32[2256 >> 2], 20.000001907348633) +assertEq(f32[2260 >> 2], 21.000001907348633) +assertEq(f32[2264 >> 2], 22.000001907348633) +assertEq(f32[2268 >> 2], 23.000001907348633) +assertEq(f32[2272 >> 2], 24.000001907348633) +assertEq(f32[2276 >> 2], 25.000001907348633) +assertEq(f32[2280 >> 2], 26.000001907348633) +assertEq(f32[2284 >> 2], 27.000001907348633) +assertEq(f32[2288 >> 2], 28.000001907348633) +assertEq(f32[2292 >> 2], 29.000001907348633) +assertEq(f32[2296 >> 2], 30.000001907348633) +assertEq(f32[2300 >> 2], 31.000001907348633) +assertEq(f32[2304 >> 2], 0.1250000149011612) +assertEq(f32[2308 >> 2], 0.1328125149011612) +assertEq(f32[2312 >> 2], 0.1406250149011612) +assertEq(f32[2316 >> 2], 0.1484375149011612) +assertEq(f32[2320 >> 2], 0.1562500149011612) +assertEq(f32[2324 >> 2], 0.1640625149011612) +assertEq(f32[2328 >> 2], 0.1718750149011612) +assertEq(f32[2332 >> 2], 0.1796875149011612) +assertEq(f32[2336 >> 2], 0.1875000149011612) +assertEq(f32[2340 >> 2], 0.1953125149011612) +assertEq(f32[2344 >> 2], 0.2031250149011612) +assertEq(f32[2348 >> 2], 0.2109375149011612) +assertEq(f32[2352 >> 2], 0.2187500149011612) +assertEq(f32[2356 >> 2], 0.2265625149011612) +assertEq(f32[2360 >> 2], 0.2343750149011612) +assertEq(f32[2364 >> 2], 0.2421875149011612) +assertEq(f32[2368 >> 2], 0.2500000298023224) +assertEq(f32[2372 >> 2], 0.2656250298023224) +assertEq(f32[2376 >> 2], 0.2812500298023224) +assertEq(f32[2380 >> 2], 0.2968750298023224) +assertEq(f32[2384 >> 2], 0.3125000298023224) +assertEq(f32[2388 >> 2], 0.3281250298023224) +assertEq(f32[2392 >> 2], 0.3437500298023224) +assertEq(f32[2396 >> 2], 0.3593750298023224) +assertEq(f32[2400 >> 2], 0.3750000298023224) +assertEq(f32[2404 >> 2], 0.3906250298023224) +assertEq(f32[2408 >> 2], 0.4062500298023224) +assertEq(f32[2412 >> 2], 0.4218750298023224) +assertEq(f32[2416 >> 2], 0.4375000298023224) +assertEq(f32[2420 >> 2], 0.4531250298023224) +assertEq(f32[2424 >> 2], 0.4687500298023224) +assertEq(f32[2428 >> 2], 0.4843750298023224) +assertEq(f32[2432 >> 2], 0.5000000596046448) +assertEq(f32[2436 >> 2], 0.5312500596046448) +assertEq(f32[2440 >> 2], 0.5625000596046448) +assertEq(f32[2444 >> 2], 0.5937500596046448) +assertEq(f32[2448 >> 2], 0.6250000596046448) +assertEq(f32[2452 >> 2], 0.6562500596046448) +assertEq(f32[2456 >> 2], 0.6875000596046448) +assertEq(f32[2460 >> 2], 0.7187500596046448) +assertEq(f32[2464 >> 2], 0.7500000596046448) +assertEq(f32[2468 >> 2], 0.7812500596046448) +assertEq(f32[2472 >> 2], 0.8125000596046448) +assertEq(f32[2476 >> 2], 0.8437500596046448) +assertEq(f32[2480 >> 2], 0.8750000596046448) +assertEq(f32[2484 >> 2], 0.9062500596046448) +assertEq(f32[2488 >> 2], 0.9375000596046448) +assertEq(f32[2492 >> 2], 0.9687500596046448) +assertEq(f32[2496 >> 2], 1.0000001192092896) +assertEq(f32[2500 >> 2], 1.0625001192092896) +assertEq(f32[2504 >> 2], 1.1250001192092896) +assertEq(f32[2508 >> 2], 1.1875001192092896) +assertEq(f32[2512 >> 2], 1.2500001192092896) +assertEq(f32[2516 >> 2], 1.3125001192092896) +assertEq(f32[2520 >> 2], 1.3750001192092896) +assertEq(f32[2524 >> 2], 1.4375001192092896) +assertEq(f32[2528 >> 2], 1.5000001192092896) +assertEq(f32[2532 >> 2], 1.5625001192092896) +assertEq(f32[2536 >> 2], 1.6250001192092896) +assertEq(f32[2540 >> 2], 1.6875001192092896) +assertEq(f32[2544 >> 2], 1.7500001192092896) +assertEq(f32[2548 >> 2], 1.8125001192092896) +assertEq(f32[2552 >> 2], 1.8750001192092896) +assertEq(f32[2556 >> 2], 1.9375001192092896) +assertEq(f32[2560 >> 2], -2.000000238418579) +assertEq(f32[2564 >> 2], -2.125000238418579) +assertEq(f32[2568 >> 2], -2.250000238418579) +assertEq(f32[2572 >> 2], -2.375000238418579) +assertEq(f32[2576 >> 2], -2.500000238418579) +assertEq(f32[2580 >> 2], -2.625000238418579) +assertEq(f32[2584 >> 2], -2.750000238418579) +assertEq(f32[2588 >> 2], -2.875000238418579) +assertEq(f32[2592 >> 2], -3.000000238418579) +assertEq(f32[2596 >> 2], -3.125000238418579) +assertEq(f32[2600 >> 2], -3.250000238418579) +assertEq(f32[2604 >> 2], -3.375000238418579) +assertEq(f32[2608 >> 2], -3.500000238418579) +assertEq(f32[2612 >> 2], -3.625000238418579) +assertEq(f32[2616 >> 2], -3.750000238418579) +assertEq(f32[2620 >> 2], -3.875000238418579) +assertEq(f32[2624 >> 2], -4.000000476837158) +assertEq(f32[2628 >> 2], -4.250000476837158) +assertEq(f32[2628 >> 2], -4.250000476837158) +assertEq(f32[2632 >> 2], -4.500000476837158) +assertEq(f32[2636 >> 2], -4.750000476837158) +assertEq(f32[2640 >> 2], -5.000000476837158) +assertEq(f32[2644 >> 2], -5.250000476837158) +assertEq(f32[2648 >> 2], -5.500000476837158) +assertEq(f32[2652 >> 2], -5.750000476837158) +assertEq(f32[2656 >> 2], -6.000000476837158) +assertEq(f32[2660 >> 2], -6.250000476837158) +assertEq(f32[2664 >> 2], -6.500000476837158) +assertEq(f32[2668 >> 2], -6.750000476837158) +assertEq(f32[2672 >> 2], -7.000000476837158) +assertEq(f32[2676 >> 2], -7.250000476837158) +assertEq(f32[2680 >> 2], -7.500000476837158) +assertEq(f32[2684 >> 2], -7.750000476837158) +assertEq(f32[2688 >> 2], -8.000000953674316) +assertEq(f32[2692 >> 2], -8.500000953674316) +assertEq(f32[2696 >> 2], -9.000000953674316) +assertEq(f32[2700 >> 2], -9.500000953674316) +assertEq(f32[2704 >> 2], -10.000000953674316) +assertEq(f32[2708 >> 2], -10.500000953674316) +assertEq(f32[2712 >> 2], -11.000000953674316) +assertEq(f32[2716 >> 2], -11.500000953674316) +assertEq(f32[2720 >> 2], -12.000000953674316) +assertEq(f32[2724 >> 2], -12.500000953674316) +assertEq(f32[2728 >> 2], -13.000000953674316) +assertEq(f32[2732 >> 2], -13.500000953674316) +assertEq(f32[2736 >> 2], -14.000000953674316) +assertEq(f32[2740 >> 2], -14.500000953674316) +assertEq(f32[2744 >> 2], -15.000000953674316) +assertEq(f32[2748 >> 2], -15.500000953674316) +assertEq(f32[2752 >> 2], -16.000001907348633) +assertEq(f32[2756 >> 2], -17.000001907348633) +assertEq(f32[2760 >> 2], -18.000001907348633) +assertEq(f32[2764 >> 2], -19.000001907348633) +assertEq(f32[2768 >> 2], -20.000001907348633) +assertEq(f32[2772 >> 2], -21.000001907348633) +assertEq(f32[2776 >> 2], -22.000001907348633) +assertEq(f32[2780 >> 2], -23.000001907348633) +assertEq(f32[2784 >> 2], -24.000001907348633) +assertEq(f32[2788 >> 2], -25.000001907348633) +assertEq(f32[2792 >> 2], -26.000001907348633) +assertEq(f32[2796 >> 2], -27.000001907348633) +assertEq(f32[2800 >> 2], -28.000001907348633) +assertEq(f32[2804 >> 2], -29.000001907348633) +assertEq(f32[2808 >> 2], -30.000001907348633) +assertEq(f32[2812 >> 2], -31.000001907348633) +assertEq(f32[2816 >> 2], -0.1250000149011612) +assertEq(f32[2820 >> 2], -0.1328125149011612) +assertEq(f32[2824 >> 2], -0.1406250149011612) +assertEq(f32[2828 >> 2], -0.1484375149011612) +assertEq(f32[2832 >> 2], -0.1562500149011612) +assertEq(f32[2836 >> 2], -0.1640625149011612) +assertEq(f32[2840 >> 2], -0.1718750149011612) +assertEq(f32[2844 >> 2], -0.1796875149011612) +assertEq(f32[2848 >> 2], -0.1875000149011612) +assertEq(f32[2852 >> 2], -0.1953125149011612) +assertEq(f32[2856 >> 2], -0.2031250149011612) +assertEq(f32[2860 >> 2], -0.2109375149011612) +assertEq(f32[2864 >> 2], -0.2187500149011612) +assertEq(f32[2868 >> 2], -0.2265625149011612) +assertEq(f32[2872 >> 2], -0.2343750149011612) +assertEq(f32[2876 >> 2], -0.2421875149011612) +assertEq(f32[2880 >> 2], -0.2500000298023224) +assertEq(f32[2884 >> 2], -0.2656250298023224) +assertEq(f32[2888 >> 2], -0.2812500298023224) +assertEq(f32[2892 >> 2], -0.2968750298023224) +assertEq(f32[2896 >> 2], -0.3125000298023224) +assertEq(f32[2900 >> 2], -0.3281250298023224) +assertEq(f32[2904 >> 2], -0.3437500298023224) +assertEq(f32[2908 >> 2], -0.3593750298023224) +assertEq(f32[2912 >> 2], -0.3750000298023224) +assertEq(f32[2916 >> 2], -0.3906250298023224) +assertEq(f32[2920 >> 2], -0.4062500298023224) +assertEq(f32[2924 >> 2], -0.4218750298023224) +assertEq(f32[2928 >> 2], -0.4375000298023224) +assertEq(f32[2932 >> 2], -0.4531250298023224) +assertEq(f32[2936 >> 2], -0.4687500298023224) +assertEq(f32[2940 >> 2], -0.4843750298023224) +assertEq(f32[2944 >> 2], -0.5000000596046448) +assertEq(f32[2948 >> 2], -0.5312500596046448) +assertEq(f32[2952 >> 2], -0.5625000596046448) +assertEq(f32[2956 >> 2], -0.5937500596046448) +assertEq(f32[2960 >> 2], -0.6250000596046448) +assertEq(f32[2964 >> 2], -0.6562500596046448) +assertEq(f32[2968 >> 2], -0.6875000596046448) +assertEq(f32[2972 >> 2], -0.7187500596046448) +assertEq(f32[2976 >> 2], -0.7500000596046448) +assertEq(f32[2980 >> 2], -0.7812500596046448) +assertEq(f32[2984 >> 2], -0.8125000596046448) +assertEq(f32[2988 >> 2], -0.8437500596046448) +assertEq(f32[2992 >> 2], -0.8750000596046448) +assertEq(f32[2996 >> 2], -0.9062500596046448) +assertEq(f32[3000 >> 2], -0.9375000596046448) +assertEq(f32[3004 >> 2], -0.9687500596046448) +assertEq(f32[3008 >> 2], -1.0000001192092896) +assertEq(f32[3012 >> 2], -1.0625001192092896) +assertEq(f32[3016 >> 2], -1.1250001192092896) +assertEq(f32[3020 >> 2], -1.1875001192092896) +assertEq(f32[3024 >> 2], -1.2500001192092896) +assertEq(f32[3028 >> 2], -1.3125001192092896) +assertEq(f32[3028 >> 2], -1.3125001192092896) +assertEq(f32[3032 >> 2], -1.3750001192092896) +assertEq(f32[3036 >> 2], -1.4375001192092896) +assertEq(f32[3040 >> 2], -1.5000001192092896) +assertEq(f32[3044 >> 2], -1.5625001192092896) +assertEq(f32[3048 >> 2], -1.6250001192092896) +assertEq(f32[3052 >> 2], -1.6875001192092896) +assertEq(f32[3056 >> 2], -1.7500001192092896) +assertEq(f32[3060 >> 2], -1.8125001192092896) +assertEq(f32[3064 >> 2], -1.8750001192092896) +assertEq(f32[3068 >> 2], -1.9375001192092896) + +assertEq(f32[3072 >> 2], 2.0625) +assertEq(f32[3076 >> 2], 2.1875) +assertEq(f32[3080 >> 2], 2.3125) +assertEq(f32[3084 >> 2], 2.4375) +assertEq(f32[3088 >> 2], 2.5625) +assertEq(f32[3092 >> 2], 2.6875) +assertEq(f32[3096 >> 2], 2.8125) +assertEq(f32[3100 >> 2], 2.9375) +assertEq(f32[3104 >> 2], 3.0625) +assertEq(f32[3108 >> 2], 3.1875) +assertEq(f32[3112 >> 2], 3.3125) +assertEq(f32[3116 >> 2], 3.4375) +assertEq(f32[3120 >> 2], 3.5625) +assertEq(f32[3124 >> 2], 3.6875) +assertEq(f32[3128 >> 2], 3.8125) +assertEq(f32[3132 >> 2], 3.9375) +assertEq(f32[3136 >> 2], 4.125) +assertEq(f32[3140 >> 2], 4.375) +assertEq(f32[3144 >> 2], 4.625) +assertEq(f32[3148 >> 2], 4.875) +assertEq(f32[3152 >> 2], 5.125) +assertEq(f32[3156 >> 2], 5.375) +assertEq(f32[3160 >> 2], 5.625) +assertEq(f32[3164 >> 2], 5.875) +assertEq(f32[3168 >> 2], 6.125) +assertEq(f32[3172 >> 2], 6.375) +assertEq(f32[3176 >> 2], 6.625) +assertEq(f32[3180 >> 2], 6.875) +assertEq(f32[3184 >> 2], 7.125) +assertEq(f32[3188 >> 2], 7.375) +assertEq(f32[3192 >> 2], 7.625) +assertEq(f32[3196 >> 2], 7.875) +assertEq(f32[3200 >> 2], 8.25) +assertEq(f32[3204 >> 2], 8.75) +assertEq(f32[3208 >> 2], 9.25) +assertEq(f32[3212 >> 2], 9.75) +assertEq(f32[3216 >> 2], 10.25) +assertEq(f32[3220 >> 2], 10.75) +assertEq(f32[3224 >> 2], 11.25) +assertEq(f32[3224 >> 2], 11.25) +assertEq(f32[3228 >> 2], 11.75) +assertEq(f32[3232 >> 2], 12.25) +assertEq(f32[3236 >> 2], 12.75) +assertEq(f32[3240 >> 2], 13.25) +assertEq(f32[3244 >> 2], 13.75) +assertEq(f32[3248 >> 2], 14.25) +assertEq(f32[3252 >> 2], 14.75) +assertEq(f32[3256 >> 2], 15.25) +assertEq(f32[3260 >> 2], 15.75) +assertEq(f32[3264 >> 2], 16.5) +assertEq(f32[3268 >> 2], 17.5) +assertEq(f32[3272 >> 2], 18.5) +assertEq(f32[3276 >> 2], 19.5) +assertEq(f32[3280 >> 2], 20.5) +assertEq(f32[3284 >> 2], 21.5) +assertEq(f32[3288 >> 2], 22.5) +assertEq(f32[3292 >> 2], 23.5) +assertEq(f32[3296 >> 2], 24.5) +assertEq(f32[3300 >> 2], 25.5) +assertEq(f32[3304 >> 2], 26.5) +assertEq(f32[3308 >> 2], 27.5) +assertEq(f32[3312 >> 2], 28.5) +assertEq(f32[3316 >> 2], 29.5) +assertEq(f32[3320 >> 2], 30.5) +assertEq(f32[3324 >> 2], 31.5) +assertEq(f32[3328 >> 2], 0.12890625) +assertEq(f32[3332 >> 2], 0.13671875) +assertEq(f32[3336 >> 2], 0.14453125) +assertEq(f32[3340 >> 2], 0.15234375) +assertEq(f32[3344 >> 2], 0.16015625) +assertEq(f32[3348 >> 2], 0.16796875) +assertEq(f32[3352 >> 2], 0.17578125) +assertEq(f32[3356 >> 2], 0.18359375) +assertEq(f32[3360 >> 2], 0.19140625) +assertEq(f32[3364 >> 2], 0.19921875) +assertEq(f32[3368 >> 2], 0.20703125) +assertEq(f32[3372 >> 2], 0.21484375) +assertEq(f32[3376 >> 2], 0.22265625) +assertEq(f32[3380 >> 2], 0.23046875) +assertEq(f32[3384 >> 2], 0.23828125) +assertEq(f32[3388 >> 2], 0.24609375) +assertEq(f32[3392 >> 2], 0.2578125) +assertEq(f32[3396 >> 2], 0.2734375) +assertEq(f32[3400 >> 2], 0.2890625) +assertEq(f32[3404 >> 2], 0.3046875) +assertEq(f32[3408 >> 2], 0.3203125) +assertEq(f32[3412 >> 2], 0.3359375) +assertEq(f32[3416 >> 2], 0.3515625) +assertEq(f32[3420 >> 2], 0.3671875) +assertEq(f32[3424 >> 2], 0.3828125) +assertEq(f32[3428 >> 2], 0.3984375) +assertEq(f32[3432 >> 2], 0.4140625) +assertEq(f32[3436 >> 2], 0.4296875) +assertEq(f32[3440 >> 2], 0.4453125) +assertEq(f32[3444 >> 2], 0.4609375) +assertEq(f32[3448 >> 2], 0.4765625) +assertEq(f32[3452 >> 2], 0.4921875) +assertEq(f32[3456 >> 2], 0.515625) +assertEq(f32[3460 >> 2], 0.546875) +assertEq(f32[3464 >> 2], 0.578125) +assertEq(f32[3468 >> 2], 0.609375) +assertEq(f32[3472 >> 2], 0.640625) +assertEq(f32[3476 >> 2], 0.671875) +assertEq(f32[3480 >> 2], 0.703125) +assertEq(f32[3484 >> 2], 0.734375) +assertEq(f32[3488 >> 2], 0.765625) +assertEq(f32[3492 >> 2], 0.796875) +assertEq(f32[3496 >> 2], 0.828125) +assertEq(f32[3500 >> 2], 0.859375) +assertEq(f32[3504 >> 2], 0.890625) +assertEq(f32[3508 >> 2], 0.921875) +assertEq(f32[3512 >> 2], 0.953125) +assertEq(f32[3516 >> 2], 0.984375) +assertEq(f32[3520 >> 2], 1.03125) +assertEq(f32[3524 >> 2], 1.09375) +assertEq(f32[3528 >> 2], 1.15625) +assertEq(f32[3532 >> 2], 1.21875) +assertEq(f32[3536 >> 2], 1.28125) +assertEq(f32[3540 >> 2], 1.34375) +assertEq(f32[3544 >> 2], 1.40625) +assertEq(f32[3548 >> 2], 1.46875) +assertEq(f32[3552 >> 2], 1.53125) +assertEq(f32[3556 >> 2], 1.59375) +assertEq(f32[3560 >> 2], 1.65625) +assertEq(f32[3564 >> 2], 1.71875) +assertEq(f32[3568 >> 2], 1.78125) +assertEq(f32[3572 >> 2], 1.84375) +assertEq(f32[3576 >> 2], 1.90625) +assertEq(f32[3580 >> 2], 1.96875) +assertEq(f32[3584 >> 2], -2.0625) +assertEq(f32[3588 >> 2], -2.1875) +assertEq(f32[3592 >> 2], -2.3125) +assertEq(f32[3596 >> 2], -2.4375) +assertEq(f32[3600 >> 2], -2.5625) +assertEq(f32[3604 >> 2], -2.6875) +assertEq(f32[3608 >> 2], -2.8125) +assertEq(f32[3612 >> 2], -2.9375) +assertEq(f32[3616 >> 2], -3.0625) +assertEq(f32[3620 >> 2], -3.1875) +assertEq(f32[3624 >> 2], -3.3125) +assertEq(f32[3624 >> 2], -3.3125) +assertEq(f32[3628 >> 2], -3.4375) +assertEq(f32[3632 >> 2], -3.5625) +assertEq(f32[3636 >> 2], -3.6875) +assertEq(f32[3640 >> 2], -3.8125) +assertEq(f32[3644 >> 2], -3.9375) +assertEq(f32[3648 >> 2], -4.125) +assertEq(f32[3652 >> 2], -4.375) +assertEq(f32[3656 >> 2], -4.625) +assertEq(f32[3660 >> 2], -4.875) +assertEq(f32[3664 >> 2], -5.125) +assertEq(f32[3668 >> 2], -5.375) +assertEq(f32[3672 >> 2], -5.625) +assertEq(f32[3676 >> 2], -5.875) +assertEq(f32[3680 >> 2], -6.125) +assertEq(f32[3684 >> 2], -6.375) +assertEq(f32[3688 >> 2], -6.625) +assertEq(f32[3692 >> 2], -6.875) +assertEq(f32[3696 >> 2], -7.125) +assertEq(f32[3700 >> 2], -7.375) +assertEq(f32[3704 >> 2], -7.625) +assertEq(f32[3708 >> 2], -7.875) +assertEq(f32[3712 >> 2], -8.25) +assertEq(f32[3716 >> 2], -8.75) +assertEq(f32[3720 >> 2], -9.25) +assertEq(f32[3724 >> 2], -9.75) +assertEq(f32[3728 >> 2], -10.25) +assertEq(f32[3732 >> 2], -10.75) +assertEq(f32[3736 >> 2], -11.25) +assertEq(f32[3740 >> 2], -11.75) +assertEq(f32[3744 >> 2], -12.25) +assertEq(f32[3748 >> 2], -12.75) +assertEq(f32[3752 >> 2], -13.25) +assertEq(f32[3756 >> 2], -13.75) +assertEq(f32[3760 >> 2], -14.25) +assertEq(f32[3764 >> 2], -14.75) +assertEq(f32[3768 >> 2], -15.25) +assertEq(f32[3772 >> 2], -15.75) +assertEq(f32[3776 >> 2], -16.5) +assertEq(f32[3780 >> 2], -17.5) +assertEq(f32[3784 >> 2], -18.5) +assertEq(f32[3788 >> 2], -19.5) +assertEq(f32[3792 >> 2], -20.5) +assertEq(f32[3796 >> 2], -21.5) +assertEq(f32[3800 >> 2], -22.5) +assertEq(f32[3804 >> 2], -23.5) +assertEq(f32[3808 >> 2], -24.5) +assertEq(f32[3812 >> 2], -25.5) +assertEq(f32[3816 >> 2], -26.5) +assertEq(f32[3820 >> 2], -27.5) +assertEq(f32[3824 >> 2], -28.5) +assertEq(f32[3828 >> 2], -29.5) +assertEq(f32[3832 >> 2], -30.5) +assertEq(f32[3836 >> 2], -31.5) +assertEq(f32[3840 >> 2], -0.12890625) +assertEq(f32[3844 >> 2], -0.13671875) +assertEq(f32[3848 >> 2], -0.14453125) +assertEq(f32[3852 >> 2], -0.15234375) +assertEq(f32[3856 >> 2], -0.16015625) +assertEq(f32[3860 >> 2], -0.16796875) +assertEq(f32[3864 >> 2], -0.17578125) +assertEq(f32[3868 >> 2], -0.18359375) +assertEq(f32[3872 >> 2], -0.19140625) +assertEq(f32[3876 >> 2], -0.19921875) +assertEq(f32[3880 >> 2], -0.20703125) +assertEq(f32[3884 >> 2], -0.21484375) +assertEq(f32[3888 >> 2], -0.22265625) +assertEq(f32[3892 >> 2], -0.23046875) +assertEq(f32[3896 >> 2], -0.23828125) +assertEq(f32[3900 >> 2], -0.24609375) +assertEq(f32[3904 >> 2], -0.2578125) +assertEq(f32[3908 >> 2], -0.2734375) +assertEq(f32[3912 >> 2], -0.2890625) +assertEq(f32[3916 >> 2], -0.3046875) +assertEq(f32[3920 >> 2], -0.3203125) +assertEq(f32[3924 >> 2], -0.3359375) +assertEq(f32[3928 >> 2], -0.3515625) +assertEq(f32[3932 >> 2], -0.3671875) +assertEq(f32[3936 >> 2], -0.3828125) +assertEq(f32[3940 >> 2], -0.3984375) +assertEq(f32[3944 >> 2], -0.4140625) +assertEq(f32[3948 >> 2], -0.4296875) +assertEq(f32[3952 >> 2], -0.4453125) +assertEq(f32[3956 >> 2], -0.4609375) +assertEq(f32[3960 >> 2], -0.4765625) +assertEq(f32[3964 >> 2], -0.4921875) +assertEq(f32[3968 >> 2], -0.515625) +assertEq(f32[3972 >> 2], -0.546875) +assertEq(f32[3976 >> 2], -0.578125) +assertEq(f32[3980 >> 2], -0.609375) +assertEq(f32[3984 >> 2], -0.640625) +assertEq(f32[3988 >> 2], -0.671875) +assertEq(f32[3992 >> 2], -0.703125) +assertEq(f32[3996 >> 2], -0.734375) +assertEq(f32[4000 >> 2], -0.765625) +assertEq(f32[4004 >> 2], -0.796875) +assertEq(f32[4008 >> 2], -0.828125) +assertEq(f32[4012 >> 2], -0.859375) +assertEq(f32[4016 >> 2], -0.890625) +assertEq(f32[4020 >> 2], -0.921875) +assertEq(f32[4024 >> 2], -0.953125) +assertEq(f32[4024 >> 2], -0.953125) +assertEq(f32[4028 >> 2], -0.984375) +assertEq(f32[4032 >> 2], -1.03125) +assertEq(f32[4036 >> 2], -1.09375) +assertEq(f32[4040 >> 2], -1.15625) +assertEq(f32[4044 >> 2], -1.21875) +assertEq(f32[4048 >> 2], -1.28125) +assertEq(f32[4052 >> 2], -1.34375) +assertEq(f32[4056 >> 2], -1.40625) +assertEq(f32[4060 >> 2], -1.46875) +assertEq(f32[4064 >> 2], -1.53125) +assertEq(f32[4068 >> 2], -1.59375) +assertEq(f32[4072 >> 2], -1.65625) +assertEq(f32[4076 >> 2], -1.71875) +assertEq(f32[4080 >> 2], -1.78125) +assertEq(f32[4084 >> 2], -1.84375) +assertEq(f32[4088 >> 2], -1.90625) +assertEq(f32[4092 >> 2], -1.96875) diff --git a/js/src/jit-test/tests/asm.js/testBug975182.js b/js/src/jit-test/tests/asm.js/testBug975182.js new file mode 100644 index 0000000000..41c627148f --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug975182.js @@ -0,0 +1,20 @@ +Function("\ + g = (function(t,foreign){\ + \"use asm\";\ + var ff = foreign.ff;\ + function f() {\ + +ff()\ + }\ + return f\ + })(this, {\ + ff: arguments.callee\ + }, new ArrayBuffer(4096))\ +")() +function m(f) { + for (var j = 0; j < 6000; ++j) { + f(); + if ((j % 1000) === 0) + gc(); + } +} +m(g); diff --git a/js/src/jit-test/tests/asm.js/testBug989166.js b/js/src/jit-test/tests/asm.js/testBug989166.js new file mode 100644 index 0000000000..c96d19de46 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug989166.js @@ -0,0 +1,8 @@ +(function(stdlib) { + "use asm"; + var pow = stdlib.Math.pow + function f() { + return +pow(.0, .0) + } + return f +})(this, {}, ArrayBuffer)() diff --git a/js/src/jit-test/tests/asm.js/testBug999790.js b/js/src/jit-test/tests/asm.js/testBug999790.js new file mode 100644 index 0000000000..85f92c22f7 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug999790.js @@ -0,0 +1,65 @@ +function CanBeConstructed(f) { + var caught = false; + try { + new f; + } catch (e) { + caught = true; + } + return !caught; +} + +function IsConstructedFunction(f) { + return f.hasOwnProperty('length') + && f.hasOwnProperty('name') + && f.hasOwnProperty('prototype') + && f.prototype.hasOwnProperty('constructor') + && f.prototype.constructor === f; +} + +function IsntConstructedFunction(f) { + return !f.hasOwnProperty('length') + && !f.hasOwnProperty('name') + && !f.hasOwnProperty('prototype') +} + +var m = function() { + "use asm" + function g(){} + return g; +}; +assertEq(CanBeConstructed(m), true, "asm.js modules can't be constructed"); + +var objM = new m; +assertEq(IsConstructedFunction(objM), true); + +var g = m(); +assertEq(CanBeConstructed(g), true, "asm.js functions can't be constructed"); +// g is a ctor returning an primitive value, thus an empty object +assertEq(Object.getOwnPropertyNames(new g).length, 0); + +var n = function() { + "use asm" + function g(){return 42.0} + function h(){return 42} + return { + g: g, + h: h + }; +}; +assertEq(CanBeConstructed(n), true, "asm.js modules can't be constructed"); + +var objN = new n; +// objN is an object with attributes g and h +assertEq(IsntConstructedFunction(objN), true); +assertEq(objN.hasOwnProperty('g'), true); +assertEq(objN.hasOwnProperty('h'), true); + +assertEq(IsConstructedFunction(objN.g), true); +assertEq(IsConstructedFunction(objN.h), true); + +var h = n().h; +assertEq(CanBeConstructed(h), true, "asm.js functions can't be constructed"); +// h is a ctor returning an primitive value, thus an empty object +assertEq(Object.getOwnPropertyNames(new h).length, 0); + +assertEq(typeof(function() {"use asm"; return {}}.prototype) !== 'undefined', true); diff --git a/js/src/jit-test/tests/asm.js/testBullet.js b/js/src/jit-test/tests/asm.js/testBullet.js new file mode 100644 index 0000000000..e8b8c98949 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBullet.js @@ -0,0 +1,6 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable() + +setIonCheckGraphCoherency(false); +load(libdir + 'bullet.js'); +var results = runBullet(); +assertEq(results.asmJSValidated, true); diff --git a/js/src/jit-test/tests/asm.js/testCall.js b/js/src/jit-test/tests/asm.js/testCall.js new file mode 100644 index 0000000000..e1e14cb47d --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testCall.js @@ -0,0 +1,75 @@ +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +assertAsmTypeFail(USE_ASM+"function f(){i=i|0} function g() { f(0) } return g"); +assertAsmTypeFail(USE_ASM+"function f(i){i=i|0} function g() { f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){} function g() { f()|0 } return g"); +assertAsmTypeFail(USE_ASM+"function f(){} function g() { +f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){} function g() { return f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0} function g() { +f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0} function g() { f()|f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0.0} function g() { f()|0 } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0.0} function g() { ~~f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0.0} function g() { -f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(i,j,k,l){i=i|0;j=j|0;k=k|0;l=l|0} function g() { f(0,1,2) } return g"); +assertAsmTypeFail(USE_ASM+"function f(i,j,k,l){i=i|0;j=j|0;k=k|0;l=l|0} function g() { f(0,1,2,3,4) } return g"); +assertAsmTypeFail(USE_ASM+"function f(i){i=i|0} function g() { f(.1) } return g"); +assertAsmTypeFail(USE_ASM+"function f(i){i=+i} function g() { f(1) } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0} function g() { var i=0.1; i=f()|0 } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0} function g() { var i=0.1; i=+f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0.1} function g() { var i=0; i=f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0.1} function g() { var i=0; i=f()|0 } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0.1} function g() { var i=0; i=+f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){} function g() { (1, f()) } return g"); + +assertEq(asmLink(asmCompile(USE_ASM+"var x=0; function f() {x=42} function g() { return (f(),x)|0 } return g"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM+"function f() {return 42} function g() { return f()|0 } return g"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM+"function g(i) { i=i|0; return (i+2)|0 } function h(i) { i=i|0; return ((g(i)|0)+8)|0 } return h"))(50), 60); +assertEq(asmLink(asmCompile(USE_ASM+"function g(i) { i=i|0; return (i+2)|0 } function h(i) { i=i|0; return ((g(i)|0)+i)|0 } return h"))(50), 102); +assertEq(asmLink(asmCompile(USE_ASM+"function g(i) { i=+i; return +(i+.1) } function h(i) { i=+i; return +(+g(i)+.2) } return h"))(20), 20+.1+.2); +assertEq(asmLink(asmCompile(USE_ASM+"function g(i,j) { i=i|0;j=j|0; return (i-j)|0 } function h(j,i) { j=j|0;i=i|0; return ((g(i,j)|0)+8)|0 } return h"))(10,20), 18); +assertEq(asmLink(asmCompile(USE_ASM+"function g(i,j) { i=i|0;j=+j; return +(+~~i+j) } function h(i,j) { i=i|0;j=+j; return +(+g(i,j)+8.6) } return h"))(10, 1.5), 10+1.5+8.6); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o) { i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0; return (n-o)|0 } return f"))(1,2,3,4,5,6,100), -94); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0; return (o-p)|0 } return f"))(1,2,3,4,5,6,100,20), 80); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0; return (((o+p)|0) + ((o+p)|0))|0 } return f"))(1,2,3,4,5,6,30,20), 100); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p,q,r) { i=+i;j=+j;k=+k;l=+l;m=+m;n=+n;o=+o;p=+p;q=+q;r=+r; return +(q-r) } return f"))(1,2,3,4,5,6,7,8,40.2,1.4), 40.2-1.4); + +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o) { i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0; return (n-o)|0 } function g(i,j) { i=i|0;j=j|0; return f(0,0,0,0,0,i,j)|0 } return g"))(20,5), 15); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0; return (o-p)|0 } function g(i,j) { i=i|0;j=j|0; return f(0,0,0,0,0,0,i,j)|0 } return g"))(20,5), 15); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=+i;j=+j;k=+k;l=+l;m=+m;n=+n;o=+o;p=+p; return +(o-p) } function g(i,j) { i=+i;j=+j; return +f(0.0,0.0,0.0,0.0,0.0,0.0,i,j) } return g"))(.5, .1), .5-.1); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0; return (o-p)|0 } function g(i,j) { i=i|0;j=j|0; var k=0; k=(i+j)|0; return ((f(0,0,0,0,0,0,i,j)|0)+k)|0 } return g"))(20,10), 40); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=+i;j=+j;k=+k;l=+l;m=+m;n=+n;o=+o;p=+p; return +(o-p) } function g(i,j) { i=+i;j=+j; var k=0.1; k=i+j; return +(+f(0.0,0.0,0.0,0.0,0.0,0.0,i,j)+k) } return g"))(.5, .1), (.5+.1)+(.5-.1)); + +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p,q) { i=i|0;j=j|0;k=k|0;l=l|0;m=+m;n=n|0;o=o|0;p=+p;q=q|0; return +((m-p) + +~~q) } function g(i,j,k) { i=+i;j=+j;k=k|0; return +f(0,0,0,0,j,0,0,i,k) } return g"))(.5, 20.1, 4), (20.1-.5)+4); + +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0; return (o-p)|0 } function g(i,j) { i=i|0;j=j|0; return f(0,0,0,0,0,0,f(0,0,0,0,0,0,i,j)|0,j)|0 } return g"))(20,5), 10); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0; return (o-p)|0 } function g(i,j) { i=i|0;j=j|0; return f(0,0,0,0,0,0,f(0,0,0,0,0,0,i,j)|0,f(0,0,0,0,0,0,j,i)|0)|0 } return g"))(20,5), 30); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=+i;j=+j;k=+k;l=+l;m=+m;n=+n;o=+o;p=+p; return +(o-p) } function g(i,j) { i=+i;j=+j; return +f(0.0,0.0,0.0,0.0,0.0,0.0,+f(0.0,0.0,0.0,0.0,0.0,0.0,i,j),j) } return g"))(10.3, .2), 10.3-.2-.2); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p) { i=+i;j=+j;k=+k;l=+l;m=+m;n=+n;o=+o;p=+p; return +(o-p) } function g(i,j) { i=+i;j=+j; return +f(0.0,0.0,0.0,0.0,0.0,0.0,+f(0.0,0.0,0.0,0.0,0.0,0.0,i,j),+f(0.0,0.0,0.0,0.0,0.0,0.0,j,i)) } return g"))(10.3, .2), (10.3-.2)-(.2-10.3)); +assertEq(asmLink(asmCompile(USE_ASM+"function f(i,j,k,l,m,n,o,p,q) { i=i|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0;q=q|0; return (o-p)|0 } function g(i,j) { i=i|0;j=j|0; return f(0,0,0,0,0,0,i,f(0,0,0,0,0,0,i,j,0)|0,0)|0 } return g"))(20,5), 5); + +assertEq(asmLink(asmCompile(USE_ASM+"function f(i) {i=i|0; return i|0} function g() { return 42; return f(13)|0 } return g"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM+"function e() { return 42 } function f(i) { i=i|0; switch(i|0) { case 0: return e()|0; default: return 13 } return 0 } function g() { return f(0)|0 } return g"))(), 42); + +var rec = asmLink(asmCompile(USE_ASM+"function rec() { rec() } return rec")); +assertThrowsInstanceOf(rec, InternalError); + +var rec = asmLink(asmCompile(USE_ASM+"function rec(i) { i=i|0; if (!i) return 0; return ((rec((i-1)|0)|0)+1)|0 } return rec")); +assertEq(rec(100), 100); +assertEq(rec(1000), 1000); +assertThrowsInstanceOf(() => rec(100000000000), InternalError); +assertEq(rec(2000), 2000); + +assertAsmTypeFail(USE_ASM+"function f(){return 0} function g() { var i=0; i=f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0.0} function g() { var i=0.0; i=f() } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0} function g() { return (f()+1)|0 } return g"); +assertAsmTypeFail(USE_ASM+"function f(){return 0.0} function g() { return +(f()+1.0) } return g"); + +assertEq(asmLink(asmCompile(USE_ASM + "const M = 42; function f() { return M } function g() { return f()|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "const M = -42; function f() { return M } function g() { return f()|0 } return f"))(), -42); +assertAsmTypeFail(USE_ASM + "const M = 42; function f() { return M } function g() { return +f() } return f"); +assertEq(asmLink(asmCompile(USE_ASM + "const M = 42.1; function f() { return M } function g() { return +f() } return f"))(), 42.1); +assertAsmTypeFail(USE_ASM + "const M = 42.1; function f() { return M } function g() { return f()|0 } return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + "var tof = glob.Math.fround; const M = tof(42); function f() { return M } function g() { return tof(f()) } return f"), this)(), 42); +assertAsmTypeFail('glob', USE_ASM + "var tof = glob.Math.fround; const M = tof(42); function f() { return M } function g() { return +f() } return f"); diff --git a/js/src/jit-test/tests/asm.js/testCloning.js b/js/src/jit-test/tests/asm.js/testCloning.js new file mode 100644 index 0000000000..d4ecb43a25 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testCloning.js @@ -0,0 +1,48 @@ +load(libdir + "asm.js"); + +var code = asmCompile(USE_ASM + "function g() { return 42 } return g"); +assertEq(asmLink(code)(), 42); +assertEq(asmLink(code)(), 42); + +var code = evaluate("(function() { " + USE_ASM + " function g() { return 43 } return g})", {fileName: null}); +assertEq(asmLink(code)(), 43); +assertEq(asmLink(code)(), 43); + +var code = asmCompile('glob', 'ffis', 'buf', USE_ASM + 'var i32=new glob.Int32Array(buf); function g() { return i32[0]|0 } return g'); +var i32_1 = new Int32Array(BUF_MIN/4); +i32_1[0] = 42; +var i32_2 = new Int32Array(BUF_MIN/4); +i32_2[0] = 13; +assertEq(asmLink(code, this, null, i32_1.buffer)(), 42); +assertEq(asmLink(code, this, null, i32_2.buffer)(), 13); +var i32_3 = new Int32Array(4097); +assertAsmLinkFail(code, this, null, i32_3.buffer); + +var code = asmCompile('glob', 'ffis', USE_ASM + 'var ffi=ffis.ffi; function g(n) { n=n|0; var i=0; for(; (i|0)<(n|0); i=(i+1)|0) ffi() } return g'); +var calls1 = 0, calls2 = 0; +function ffi1() { calls1++ } +function ffi2() { calls2++ } +asmLink(code, null, {ffi:ffi1})(100000); +assertEq(calls1, 100000); +assertEq(calls2, 0); +calls1 = 0; +asmLink(code, null, {ffi:ffi2})(50000); +assertEq(calls1, 0); +assertEq(calls2, 50000); + +var code = asmCompile(USE_ASM + 'var g = 0; function h() { g=(g+1)|0; return g|0 } return h'); +var h1 = code(); +assertEq(h1(), 1); +assertEq(h1(), 2); +var h2 = code(); +assertEq(h2(), 1); +assertEq(h1(), 3); +assertEq(h2(), 2); +assertEq(h1(), 4); + +var code = asmCompile(USE_ASM + "return {}"); +var h1 = code(); +var h2 = code(); +assertEq(h1 === h2, false); +assertEq(Object.keys(h1).length, 0); +assertEq(Object.keys(h2).length, 0); diff --git a/js/src/jit-test/tests/asm.js/testCompoundPlusMinus.js b/js/src/jit-test/tests/asm.js/testCompoundPlusMinus.js new file mode 100644 index 0000000000..9b070541e3 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testCompoundPlusMinus.js @@ -0,0 +1,14 @@ +load(libdir + "asm.js"); + +assertAsmTypeFail(USE_ASM + "function f(i,j,k) { i=i|0;j=+j;k=+k; return (i+(j+k))|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i,j,k) { i=i|0;j=j|0;k=+k; return +((i+j)+k) } return f"); +assertAsmTypeFail('imp', USE_ASM + "var ffi=imp.ffi; function f(i) { i=i|0; return (i+ffi())|0 } return f"); + +assertEq(asmLink(asmCompile(USE_ASM + "function f(i,j,k) { i=i|0;j=j|0;k=k|0; return (i+j+k)|0 } return f"))(1,2,3), 6); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i,j,k) { i=i|0;j=j|0;k=k|0; return (i+j-k)|0 } return f"))(1,2,3), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i,j,k) { i=i|0;j=j|0;k=k|0; return (i-j+k)|0 } return f"))(1,2,3), 2); + +const INT32_MAX = Math.pow(2,31)-1; +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return (i+i+i+i+i+i+i+i+i+i)|0 } return f"))(INT32_MAX), (10*INT32_MAX)|0); +const INT32_MIN = -Math.pow(2,31); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return (i+i+i+i+i+i+i+i+i+i)|0 } return f"))(INT32_MIN), (10*INT32_MIN)|0); diff --git a/js/src/jit-test/tests/asm.js/testControlFlow.js b/js/src/jit-test/tests/asm.js/testControlFlow.js new file mode 100644 index 0000000000..40711cd6ce --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testControlFlow.js @@ -0,0 +1,374 @@ +load(libdir + "asm.js"); + +assertEq(asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=+j; if (i) return j; return j+1.0 } return f"))(0, 1.2), 1.2+1.0); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=+j; if (i) return j; return +~~i } return f"))(1,1.4), 1.4); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; if (i) return j^0; return i^1 } return f"))(1, 1), 1); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; if (i) return j^0; return i|0 } return f"))(1,8), 8); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; if ((i|0) == 0) return 10; else if ((i|0) == 1) return 12; else if ((i|0) == 2) return 14; return 0} return f"))(2), 14); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; if ((i|0) == 0) return 10; else if ((i|0) == 1) return 12; else if ((i|0) == 2) return 14; else return 16; return 0} return f"))(3), 16); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; if ((i|0) == 0) i = 10; else if ((i|0) == 1) return 12; return (i|0) } return f"))(0), 10); + +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; if (i) return 0; } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; if (i) return 0; else return 1 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; if (i) return 0; return 1.0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { if (0) return 0; 1 } return f"); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { while (0) {} return 0} return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { for (;0;) {} return 0} return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { do {} while(0); return 0} return f"))(), 0); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { while (0) ; return 0} return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { for (;0;) ; return 0} return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { do ; while(0); return 0} return f"))(), 0); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { do {} while (0); while (0); return 0} return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i = 0; do {} while (0); return i|0} return f"))(), 0); + +assertAsmTypeFail(USE_ASM + "function f(d) {d=+d; while (d) {}; return 0} return f"); +assertAsmTypeFail(USE_ASM + "function f(d) {d=+d; for (;d;) {}; return 0} return f"); +assertAsmTypeFail(USE_ASM + "function f(d) {d=+d; do {} while (d); return 0} return f"); + +assertEq(asmLink(asmCompile(USE_ASM + "function f(j) {j=j|0; var i=0; while ((i|0) < (j|0)) i=(i+4)|0; return i|0} return f"))(6), 8); +assertEq(asmLink(asmCompile(USE_ASM + "function f(j) {j=j|0; var i=0; for (;(i|0) < (j|0);) i=(i+4)|0; return i|0} return f"))(6), 8); +assertEq(asmLink(asmCompile(USE_ASM + "function f(j) {j=j|0; var i=0; do { i=(i+4)|0; } while ((i|0) < (j|0)); return i|0} return f"))(6), 8); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { while(1) return 42; return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { for(;1;) return 42; return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { do return 42; while(1); return 0 } return f"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; while(1) { if (i) return 13; return 42 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; for(;1;) { if (i) return 13; return 42 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; do { if (i) return 13; return 42 } while(1); return 0 } return f"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; while(1) { break; while(1) {} } return 42 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; for(;;) { break; for(;;) {} } return 42 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; do { break; do {} while(1) {} } while(1); return 42 } return f"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=1; while(1) { if (i) return 42; return 13 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=1; for(;1;) { if (i) return 42; return 13 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=1; do { if (i) return 42; return 13 } while(1); return 0 } return f"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; while(1) { if (i) return 13; else return 42; return 13 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; for(;;) { if (i) return 13; else return 42; return 13 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; do { if (i) return 13; else return 42; return 13 } while(1); return 0 } return f"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; while((i|0) < 3) { if (i) return 42; i=(i+1)|0 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; for(;(i|0) < 3;) { if (i) return 42; i=(i+1)|0 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; do { if (i) return 42; i=(i+1)|0 } while((i|0) < 3); return 0 } return f"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; while((i|0) < 3) { if (!i) i=(i+1)|0; return 42 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; for(;(i|0) < 3;) { if (!i) i=(i+1)|0; return 42 } return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; do { if (!i) i=(i+1)|0; return 42 } while((i|0) < 3); return 0 } return f"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=42; return i|0; while(1) {} return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=42; return i|0; for(;1;) {} return 0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=42; return i|0; do {} while(1); return 0 } return f"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; while((i|0) < 10) if ((i|0) == 4) break; else i=(i+1)|0; return i|0 } return f"))(), 4); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; for(; (i|0) < 10;) if ((i|0) == 4) break; else i=(i+1)|0; return i|0 } return f"))(), 4); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; do if ((i|0) == 4) break; else i=(i+1)|0; while((i|0) < 10); return i|0 } return f"))(), 4); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0,sum=0; while ((i=(i+1)|0)<2) { sum=(sum+1)|0; if ((i&1)==0) continue; sum=(sum+100)|0 } return sum|0 } return f"))(), 101); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0,sum=0; for (;(i=(i+1)|0)<2;) { sum=(sum+1)|0; if ((i&1)==0) continue; sum=(sum+100)|0 } return sum|0 } return f"))(), 101); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0,sum=0; do { sum=(sum+1)|0; if ((i&1)==0) continue; sum=(sum+100)|0 } while((i=(i+1)|0)<2); return sum|0 } return f"))(), 102); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; x:a:y:while(1) { i=1; while(1) { i=2; break a; } i=3; } return i|0 } return f"))(), 2); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; x:a:y:for(;;) { i=1; while(1) { i=2; break a; } i=3; } return i|0 } return f"))(), 2); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; x:a:y:do { i=1; while(1) { i=2; break a; } i=3; } while(1); return i|0 } return f"))(), 2); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; a:b:while((i|0) < 5) { i=(i+1)|0; while(1) continue b; } return i|0 } return f"))(), 5); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; a:b:for(;(i|0) < 5;) { i=(i+1)|0; while(1) continue b; } return i|0 } return f"))(), 5); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; a:b:do { i=(i+1)|0; while(1) continue b; } while((i|0) < 5); return i|0 } return f"))(), 5); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; return 0; a:b:while((i|0) < 5) { i=(i+1)|0; while(1) continue b; } return i|0 } return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; return 0; a:b:for(;(i|0) < 5;) { i=(i+1)|0; while(1) continue b; } return i|0 } return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; return 0; a:b:do { i=(i+1)|0; while(1) continue b; } while((i|0) < 5); return i|0 } return f"))(), 0); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=42; a:{ break a; i=2; } b:{ c:{ break b; i=3 } i=4 } return i|0 } return f"))(), 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; a:b:for(;(i|0) < 5;i=(i+1)|0) { while(1) continue b; } return i|0 } return f"))(), 5); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=42,sum=0; for(i=1;(i|0)<4;i=(i+1)|0) sum=(sum+i)|0; return sum|0 } return f"))(), 6); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=42,sum=0; for(i=1;(i|0)<8;i=(i+1)|0) { if ((i&1) == 0) continue; sum=(sum+i)|0; } return sum|0 } return f"))(), 16); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; while(1) { i=(i+1)|0; if ((i|0) > 10) break; } return i|0 } return f"))(), 11); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; for(;1;i=(i+1)|0) { if ((i|0) > 10) break; } return i|0 } return f"))(), 11); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; do { if ((i|0) > 10) break; i=(i+1)|0 } while(1); return i|0 } return f"))(), 11); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; while(1){ if ((i|0)>0) break; while (1) { i=i+1|0; if ((i|0)==1) break; } } return i|0; } return f"))(), 1); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; for(;;){ if ((i|0)>0) break; while (1) { i=i+1|0; if ((i|0)==1) break; } } return i|0; } return f"))(), 1); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; do{ if ((i|0)>0) break; while (1) { i=i+1|0; if ((i|0)==1) break; } }while(1); return i|0; } return f"))(), 1); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0,sum=0; while(1){ if ((i|0)>5) break; while (1) { i=i+1|0; sum=(sum+i)|0; if ((i|0)>3) break; } } return sum|0; } return f"))(), 21); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0,sum=0; for(;;){ if ((i|0)>5) break; while (1) { i=i+1|0; sum=(sum+i)|0; if ((i|0)>3) break; } } return sum|0; } return f"))(), 21); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0,sum=0; do{ if ((i|0)>5) break; while (1) { i=i+1|0; sum=(sum+i)|0; if ((i|0)>3) break; } }while(1); return sum|0; } return f"))(), 21); + +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; while(1) { if (i) { break; } else { return i|0 } i = 1 } return i|0 } return f"))(3), 3); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; for(;1;) { if (i) { break; } else { return i|0 } i = 1 } return i|0 } return f"))(3), 3); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; do { if (i) { break; } else { return i|0 } i = 1 } while (0); return i|0 } return f"))(3), 3); + +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; while(1) { if (i) { return i|0 } else { return i|0 } i = 1 } return i|0 } return f"))(3), 3); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; for(;;) { if (i) { return i|0 } else { return i|0 } i = 1 } return i|0 } return f"))(3), 3); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; do { if (i) { return i|0 } else { return i|0 } i = 1 } while (0); return i|0 } return f"))(3), 3); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() {var j=1,i=0; while(j){ if(0) continue; j=i } return j|0 } return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {var j=1,i=0; for(;j;){ if(0) continue; j=i } return j|0 } return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {var j=1,i=0; do{ if(0) continue; j=i } while(j) return j|0 } return f"))(), 0); + +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; for(;;) { return i|0 } return 0 } return f"))(42), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f(n) { n=n|0; var i=0,s=0; for(;;i=(i+1)|0) { if (~~i==~~n) return s|0; s=(s+i)|0 } return 0 } return f"))(8), 28); + +var f = asmLink(asmCompile(USE_ASM + "function f(n,m) { n=n|0;m=m|0; var i=0,sum=0; while((n|0)>(m|0) ? ((i|0)<(n|0))|0 : ((i|0)<(m|0))|0) { sum = (sum+i)|0; i=(i+1)|0 } return sum|0 } return f")); +assertEq(f(1,5), 10); +assertEq(f(6,5), 15); + +var f = asmLink(asmCompile(USE_ASM + "function f(n,m) { n=n|0;m=m|0; var i=0,sum=0; for(; (n|0)>(m|0) ? ((i|0)<(n|0))|0 : ((i|0)<(m|0))|0; i=(i+1)|0) { sum = (sum+i)|0 } return sum|0 } return f")); +assertEq(f(1,5), 10); +assertEq(f(6,5), 15); + +var f = asmLink(asmCompile(USE_ASM + "function f(n,m) { n=n|0;m=m|0; var i=0,sum=0; do { sum = (sum+i)|0; i=(i+1)|0 } while((n|0)>(m|0) ? ((i|0)<(n|0))|0 : ((i|0)<(m|0))|0); return sum|0 } return f")); +assertEq(f(1,5), 10); +assertEq(f(6,5), 15); + +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: return 0; case 1: return 0 } return 0} return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: return 0; case 2: return 0; case 1: return 0 } return 0} return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; switch(1) { case 1: return 0; case 1: return 0 } return 0} return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0; switch(i) {}; return i|0 } return f"); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; switch(i|0) {}; return i|0 } return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; switch(i|0) { default: i=42 } return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; switch(i|0) { default: i=42; break } return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; switch(i|0) { case 0: i=42 } return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; switch(i|0) { case 0: i=42; break } return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; switch(i|0) { case 0: default: i=42 } return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=0; switch(i|0) { case 0: default: i=42; break } return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=1; switch(i|0) { case 0: case 2: break; default: i=42 } return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=1; switch(i|0) { case 0: case 2: break; default: i=42; break } return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return 42; switch(1) { case 1: return 13 } return 14 } return f"))(), 42); + +var exp = asmLink(asmCompile(USE_ASM + "var x=0; function a() { return x|0 } function b(i) { i=i|0; x=i } function c(i) { i=i|0; if (i) b(i); } return {a:a,b:b,c:c}")); +assertEq(exp.c(10), undefined); +assertEq(exp.a(), 10); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: i=-1; break; case 133742: i=2; break; default: i=42; break } return i|0 } return f")); +assertEq(f(1), -1); +assertEq(f(2), 42); +assertEq(f(133742), 2); +assertEq(f(133743), 42); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case 1: i=42; break; default: i=13 } return i|0 } return f")); +assertEq(f(-1), 13); +assertEq(f(0), 13); +assertEq(f(1), 42); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; switch(i|0) { case -1: i=42; break; default: i=13 } return i|0 } return f")); +assertEq(f(-1), 42); +assertEq(f(0), 13); +assertEq(f(1), 13); +assertEq(f(0xffffffff), 42); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; var sum=0; switch(i|0) { case -1: sum=(sum+1)|0; case 1: sum=(sum+1)|0; case 3: sum=(sum+1)|0; default: sum=(sum+100)|0; } return sum|0 } return f")); +assertEq(f(-1), 103); +assertEq(f(0), 100); +assertEq(f(1), 102); +assertEq(f(2), 100); +assertEq(f(3), 101); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; var sum=0; switch(i|0) { case -1: sum=10; break; case 1: sum=11; break; case 3: sum=12; break; default: sum=13; } return sum|0 } return f")); +assertEq(f(-1), 10); +assertEq(f(0), 13); +assertEq(f(1), 11); +assertEq(f(2), 13); +assertEq(f(3), 12); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=8,sum=0; a:for(; (i|0)<20; i=(i+1)|0) { switch(i&3) { case 0:case 1:sum=(sum+i)|0;break;case 2:sum=(sum+100)|0;continue;default:break a} sum=(sum+10)|0; } sum=(sum+1000)|0; return sum|0 } return f"))(), 1137); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { a: do{break a;}while(0); a: do{break a;}while(0); return 42 } return f"))(), 42); +assertEq(asmLink(asmCompile('g', USE_ASM + "function f() { g:{ return 42 } return 13 } return f"), null)(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f(x) {x=x|0;switch (x|0) {case 31:return 13;case 9: {x = 3;if ((x|0) <= 0) {return -1;}}}return 1;} return f"))(31), 13); + +var imp = { ffi:function() { throw "Wrong" } }; +assertEq(asmLink(asmCompile('glob','imp', USE_ASM + "var ffi=imp.ffi; function f() { var i=0; return (i+1)|0; return ffi(i|0)|0 } return f"), null, imp)(), 1); + +assertEq(asmLink(asmCompile(USE_ASM + 'function f() {var k = 1;if (1) {for(k = 1; k|0; k=k-1|0) {}} return 1}; return f'))(), 1); + +// Ternaries conditionals +// +// Basic ternaries +var f = asmLink(asmCompile(USE_ASM + "function f() { return 0; if (1) return -1; return -2} return f")); +assertEq(f(5), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(x) { x=x|0; var a=2;if(x?1:0)a=1;else a=0; return a|0 } return f")); +assertEq(f(1), 1); +assertEq(f(0), 0); + +var guard = (function() { + var called_ = false; + return { + called: function(){ return called_ }, + call: function(){ called_ = true } + } +})(); + +var f = asmLink(asmCompile('glob', 'ffi', USE_ASM + "var func=ffi.func; function f(x) { x=x|0; var a=2;if(x?1:1)a=1; else {func();a=0}return a|0 } return f"), this, {func: guard.call}); +assertEq(f(1), 1); +assertEq(f(0), 1); +assertEq(guard.called(), false); + +var f = asmLink(asmCompile('glob', 'ffi', USE_ASM + "var func=ffi.func; function f(x) { x=x|0; var a=2;if(x?0:0){a=1; func()}else a=0;return a|0 } return f"), this, {func: guard.call}); +assertEq(f(1), 0); +assertEq(f(0), 0); +assertEq(guard.called(), false); + +var f = asmLink(asmCompile('glob', 'ffi', USE_ASM + "var func=ffi.func; function f(x,y) { x=x|0;y=y|0; var a=2;if(x?func()|0:y)a=1;else a=0; return a|0 } return f"), this, {func: guard.call}); +assertEq(f(0,1), 1); +assertEq(guard.called(), false); + +var f = asmLink(asmCompile('glob', 'ffi', USE_ASM + "var func=ffi.func; function f(x,y) { x=x|0;y=y|0; var a=2;if(x?y:func()|0)a=1;else a=0; return a|0 } return f"), this, {func: guard.call}); +assertEq(f(1,0), 0); +assertEq(guard.called(), false); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y) { x=x|0;y=y|0; var a=2;if(x?0:y)a=1;else a=0; return a|0 } return f")); +assertEq(f(1,1), 0); +assertEq(f(1,0), 0); +assertEq(f(0,0), 0); +assertEq(f(0,1), 1); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y) { x=x|0;y=y|0; var a=2;if(x?y:1)a=1;else a=0; return a|0 } return f")); +assertEq(f(1,1), 1); +assertEq(f(1,0), 0); +assertEq(f(0,0), 1); +assertEq(f(0,1), 1); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=2;if(x?y:z)a=1;else a=0; return a|0 } return f")); +for (var i = 0; i < 2; ++i) + for (var j = 0; j < 2; ++j) + for (var k = 0; k < 2; ++k) + assertEq(f(i,j,k), ((i && j) || (!i && k))|0); + +// Complex ternaries +function CheckTwoArgsTwoOptions(f) { + function check(x,y) { + return (x > 2 && y < 5) | 0; + } + for (var a = -10; a < 10; a++) + for (var b = -10; b < 10; b++) + assertEq(f(a,b), check(a,b)); +} + +function CheckThreeArgsTwoOptions(f) { + function check(x,y,z) { + return (x > 2 && y < 5 && z > -1) | 0; + } + for (var a = -10; a < 10; a++) + for (var b = -10; b < 10; b++) + for (var c = -10; c < 10; c++) + assertEq(f(a,b,c), check(a,b,c)); +} + +// Ternaries with && semantics +var f = asmLink(asmCompile(USE_ASM + "function f(x,y) { x=x|0;y=y|0; var z=0; if((x|0) > 2 ? (y|0) < 5 : 0) z=1; return z|0;} return f")); +CheckTwoArgsTwoOptions(f); +var f = asmLink(asmCompile(USE_ASM + "function f(x,y) { x=x|0;y=y|0; var z=2; if((x|0) > 2 ? (y|0) < 5 : 0) z=1; else z=0; return z|0;} return f")); +CheckTwoArgsTwoOptions(f); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=0; if((x|0) > 2 ? ((y|0) < 5 ? (z|0) > -1 : 0) : 0) a=1; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=2; if((x|0) > 2 ? ((y|0) < 5 ? (z|0) > -1 : 0) : 0) a=1; else a=0; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=0; if((x|0) > 2 ? (y|0) < 5 : 0) {if ((z|0) > -1) a=1}; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=2; if((x|0) > 2 ? (y|0) < 5 : 0) {if ((z|0) > -1) a=1; else a=0;} else a=0; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=0; if(((x|0) == 3 ? 1 : ((x|0) > 3)) ? ((y|0) < 5 ? (z|0) > -1 : 0) : 0) a=1; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=2; if(((x|0) == 3 ? 1 : ((x|0) > 3)) ? ((y|0) < 5 ? (z|0) > -1 : 0) : 0) a=1; else a=0; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=0; if((x|0) == 3 ? 1 : (x|0) > 3) {if ((y|0) < 5 ? (z|0) > -1 : 0) a=1;} return a|0;} return f")); +CheckThreeArgsTwoOptions(f); +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=2; if((x|0) == 3 ? 1 : (x|0) > 3) {if ((y|0) < 5 ? (z|0) > -1 : 0) a=1; else a=0;} else a=0; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); + +// Ternaries with || semantics +var f = asmLink(asmCompile(USE_ASM + "function f(x,y) { x=x|0;y=y|0; var z=1; if((x|0) <= 2 ? 1 : (y|0) >= 5) z=0; return z|0;} return f")); +CheckTwoArgsTwoOptions(f); +var f = asmLink(asmCompile(USE_ASM + "function f(x,y) { x=x|0;y=y|0; var z=2; if((x|0) <= 2 ? 1 : (y|0) >= 5) z=0; else z=1; return z|0;} return f")); +CheckTwoArgsTwoOptions(f); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=1; if((x|0) <= 2 ? 1 : ((y|0) >= 5 ? 1 : (z|0) <= -1)) a=0; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=2; if((x|0) <= 2 ? 1 : ((y|0) >= 5 ? 1 : (z|0) <= -1)) a=0; else a=1; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=1; if((x|0) <= 2 ? 1 : (y|0) >= 5) a=0; else if ((z|0) <= -1) a=0; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=2; if((x|0) <= 2 ? 1 : (y|0) >= 5) a=0; else if ((z|0) <= -1) a=0; else a=1; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); + +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=1; if(((x|0) != 3 ? ((x|0) <= 3) : 0) ? 1 : ((y|0) >= 5 ? 1 : (z|0) <= -1)) a=0; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); +var f = asmLink(asmCompile(USE_ASM + "function f(x,y,z) { x=x|0;y=y|0;z=z|0; var a=2; if(((x|0) != 3 ? ((x|0) <= 3) : 0) ? 1 : ((y|0) >= 5 ? 1 : (z|0) <= -1)) a=0; else a=1; return a|0;} return f")); +CheckThreeArgsTwoOptions(f); + +// Massive test +var code = '"use asm";\ + function g(x,y) {\ + x=x|0;\ + y=y|0;\ + var z = 0;\ + if ((y|0) == 1337) {\ + z = 1;\ + } else if ((x|0) == 1 ? 1 : ((x|0) < 0 ? (y|0) == 1 : 0)) {\ + z = 2;\ + } else if ((x|0) == 2) {\ + z = 3;\ + } else if ((x|0) == 3 ? 1 : (x|0) == 4) {\ + z = 4;\ + } else if ((x|0) == 5 ? (y|0) > 5 : 0) {\ + z = 5;\ + } else {\ + z = 6;\ + }\ + return z|0;\ + }\ + return g;'; + +var m = asmLink(asmCompile(code)); + +assertEq(m(0, 1337), 1); +assertEq(m(0, 1338), 6); +assertEq(m(0, 0), 6); +assertEq(m(0, 1), 6); +assertEq(m(0, 1336), 6); +assertEq(m(1, 1337), 1); +assertEq(m(2, 1337), 1); +assertEq(m(3, 1337), 1); +assertEq(m(4, 1337), 1); +assertEq(m(5, 1337), 1); + +assertEq(m(1, 10), 2); +assertEq(m(1, 1336), 2); +assertEq(m(-1, 10), 6); +assertEq(m(-1, 2), 6); +assertEq(m(-1, -1), 6); +assertEq(m(-1, 1), 2); +assertEq(m(-9, 1), 2); + +assertEq(m(2, 1), 3); +assertEq(m(2, 0), 3); +assertEq(m(2, 6), 3); + +assertEq(m(3, 1), 4); +assertEq(m(3, 0), 4); +assertEq(m(3, 6), 4); +assertEq(m(3, 3), 4); +assertEq(m(4, 1), 4); +assertEq(m(4, 0), 4); +assertEq(m(4, 6), 4); +assertEq(m(4, 3), 4); + +assertEq(m(5, -1), 6); +assertEq(m(5, 4), 6); +assertEq(m(5, 5), 6); +assertEq(m(5, 6), 5); +assertEq(m(5, 10), 5); diff --git a/js/src/jit-test/tests/asm.js/testDebugModeDisables.js b/js/src/jit-test/tests/asm.js/testDebugModeDisables.js new file mode 100644 index 0000000000..9c04cbf264 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testDebugModeDisables.js @@ -0,0 +1,9 @@ +// |jit-test| + +load(libdir + "asm.js"); + +// Turn on debugging for the current global. +var g = newGlobal({newCompartment: true}); +var dbg = new g.Debugger(this); + +assertAsmTypeFail("'use asm'; function f() {} return f"); diff --git a/js/src/jit-test/tests/asm.js/testExpressions.js b/js/src/jit-test/tests/asm.js/testExpressions.js new file mode 100644 index 0000000000..0e04ac0db2 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testExpressions.js @@ -0,0 +1,403 @@ +load(libdir + "asm.js"); + +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0.0; return (i+j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0.0,j=0; return (i+j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0.0; return (i-j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0.0,j=0; return (i-j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0.0; return (i*j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0.0,j=0; return (i*j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0; return (i*j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0; return (i*1048576)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0; return (i*-1048576)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0; return (i + (j*4))|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var two30 = 1073741824; return (((two30 * 524288 * 16) + 1) & 1)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0.0; return (i/j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0.0,j=0; return (i/j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=1,j=1; return (i/j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0.0; return (i%j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0.0,j=0; return (i%j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0.0,j=0; return (i<j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0.0; return (i<j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0; return (i<j)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0.0; return (-i)|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0; return (-(i+j))|0 } return f"); + +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0,k=0; k = (i|0)/(k|0) } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0,k=0; k = (i>>>0)/(k>>>0) } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0,k=0; k = (i|0)%(k|0) } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var i=0,j=0,k=0; k = (i>>>0)%(k>>>0) } return f"); + +const UINT32_MAX = Math.pow(2,32)-1; +const INT32_MIN = -Math.pow(2,31); +const INT32_MAX = Math.pow(2,31)-1; + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return (i*2)|0 } return f")); +assertEq(f(0), 0); +assertEq(f(INT32_MIN), (2*INT32_MIN)|0); +assertEq(f(INT32_MAX), (2*INT32_MAX)|0); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return (2*i)|0 } return f")); +assertEq(f(0), 0); +assertEq(f(INT32_MIN), (2*INT32_MIN)|0); +assertEq(f(INT32_MAX), (2*INT32_MAX)|0); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return (i*1048575)|0 } return f")); +assertEq(f(0), 0); +assertEq(f(2), (1048575*2)|0); +assertEq(f(-1), (1048575*-1)|0); +assertEq(f(INT32_MIN), (1048575*INT32_MIN)|0); +assertEq(f(INT32_MAX), (1048575*INT32_MAX)|0); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return (1048575*i)|0 } return f")); +assertEq(f(0), 0); +assertEq(f(2), (1048575*2)|0); +assertEq(f(-1), (1048575*-1)|0); +assertEq(f(INT32_MIN), (1048575*INT32_MIN)|0); +assertEq(f(INT32_MAX), (1048575*INT32_MAX)|0); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; var j=0; j=~i; return j|0 } return f")); +assertEq(f(0), ~0); +assertEq(f(3), ~3); +assertEq(f(-3), ~-3); +assertEq(f(INT32_MAX), ~INT32_MAX); +assertEq(f(INT32_MIN), ~INT32_MIN); +assertEq(f(UINT32_MAX), ~UINT32_MAX); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=+i; var j=0; j=~~i; return j|0 } return f")); +assertEq(f(0), 0); +assertEq(f(3.5), 3); +assertEq(f(-3.5), -3); +assertEq(f(INT32_MAX), INT32_MAX); +assertEq(f(INT32_MIN), INT32_MIN); +assertEq(f(UINT32_MAX), -1); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; var j=0.0; j=+~~i; return +j } return f")); +assertEq(f(0), 0); +assertEq(f(INT32_MAX), INT32_MAX); +assertEq(f(INT32_MIN), INT32_MIN); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; var j=0.1; j=+(i>>>0); return +j } return f")); +assertEq(f(0), 0); +assertEq(f(INT32_MAX), INT32_MAX); +assertEq(f(UINT32_MAX), UINT32_MAX); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return (-i)|0 } return f")); +assertEq(f(0), 0); +assertEq(f(-0), 0); +assertEq(f(1), -1); +assertEq(f(INT32_MAX), INT32_MIN+1); +assertEq(f(INT32_MIN), INT32_MIN); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=+i; return +(-i) } return f")); +assertEq(f(0), -0); +assertEq(f(-0), 0); +assertEq(f(-1), 1); +assertEq(f(1), -1); +assertEq(f(Math.pow(2,50)), -Math.pow(2,50)); +assertEq(f(1.54e20), -1.54e20); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return ((i|0) < (j|0))|0 } return f")); +assertEq(f(0, 1), 1); +assertEq(f(1, 0), 0); +assertEq(f(1, 1), 0); +assertEq(f(INT32_MIN, INT32_MAX), 1); +assertEq(f(INT32_MAX, INT32_MIN), 0); +assertEq(f(0, INT32_MAX), 1); +assertEq(f(INT32_MAX, 0), 0); +assertEq(f(INT32_MIN, 0), 1); +assertEq(f(0, INT32_MIN), 0); +assertEq(f(UINT32_MAX, 0), 1); +assertEq(f(0, UINT32_MAX), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return ((i>>>0) < (j>>>0))|0 } return f")); +assertEq(f(0, 1), 1); +assertEq(f(1, 0), 0); +assertEq(f(1, 1), 0); +assertEq(f(INT32_MIN, INT32_MAX), 0); +assertEq(f(INT32_MAX, INT32_MIN), 1); +assertEq(f(0, INT32_MAX), 1); +assertEq(f(INT32_MAX, 0), 0); +assertEq(f(INT32_MIN, 0), 0); +assertEq(f(0, INT32_MIN), 1); +assertEq(f(UINT32_MAX, 0), 0); +assertEq(f(0, UINT32_MAX), 1); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var k=0; k=(i|0)==(j|0); return k|0 } return f")); +assertEq(f(1,2), 0); +assertEq(f(1,1), 1); +assertEq(f(2,1), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var k=0; k=(i|0)!=(j|0); return k|0 } return f")); +assertEq(f(1,2), 1); +assertEq(f(1,1), 0); +assertEq(f(2,1), 1); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var k=0; k=(i|0)<(j|0); return k|0 } return f")); +assertEq(f(1,2), 1); +assertEq(f(1,1), 0); +assertEq(f(1,0), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var k=0; k=(i|0)>(j|0); return k|0 } return f")); +assertEq(f(1,2), 0); +assertEq(f(1,1), 0); +assertEq(f(1,0), 1); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var k=0; k=(i|0)<=(j|0); return k|0 } return f")); +assertEq(f(1,2), 1); +assertEq(f(1,1), 1); +assertEq(f(1,0), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var k=0; k=(i|0)>=(j|0); return k|0 } return f")); +assertEq(f(1,2), 0); +assertEq(f(1,1), 1); +assertEq(f(1,0), 1); + +assertEq(asmLink(asmCompile(USE_ASM + "const I=2; function f(i) { i=i|0; var k=0; k=(i|0)<I; return k|0 } return f"))(1), 1); +assertEq(asmLink(asmCompile(USE_ASM + "const I=2; function f(i) { i=i|0; var k=0; k=(i>>>0)<I; return k|0 } return f"))(1), 1); +assertEq(asmLink(asmCompile(USE_ASM + "const I=-2; function f(i) { i=i|0; var k=0; k=(i|0)<I; return k|0 } return f"))(-1), 0); +assertAsmTypeFail(USE_ASM + "const I=-2; function f(i) { i=i|0; var k=0; k=(i>>>0)<I; return k|0 } return f"); +assertAsmTypeFail(USE_ASM + "const I=0x80000000; function f(i) { i=i|0; var k=0; k=(i|0)<I; return k|0 } return f"); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return ((i|0)/(j|0))|0 } return f")); +assertEq(f(4,2), 2); +assertEq(f(3,2), 1); +assertEq(f(3,-2), -1); +assertEq(f(-3,-2), 1); +assertEq(f(0, -1), 0); +assertEq(f(0, INT32_MAX), 0); +assertEq(f(0, INT32_MIN), 0); +assertEq(f(INT32_MAX, 0), 0); +assertEq(f(INT32_MIN, 0), 0); +assertEq(f(-1, INT32_MAX), 0); +assertEq(f(-1, INT32_MIN), 0); +assertEq(f(INT32_MAX, -1), -INT32_MAX); +assertEq(f(INT32_MIN, -1), INT32_MIN); // !! +assertEq(f(INT32_MAX, INT32_MAX), 1); +assertEq(f(INT32_MAX, INT32_MIN), 0); +assertEq(f(INT32_MIN, INT32_MAX), -1); +assertEq(f(INT32_MIN, INT32_MIN), 1); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return ((i>>>0)/(j>>>0))|0 } return f")); +assertEq(f(4,2), 2); +assertEq(f(3,2), 1); +assertEq(f(3,-2), 0); +assertEq(f(-3,-2), 0); +assertEq(f(0, -1), 0); +assertEq(f(0, INT32_MAX), 0); +assertEq(f(0, INT32_MIN), 0); +assertEq(f(0, UINT32_MAX), 0); +assertEq(f(INT32_MAX, 0), 0); +assertEq(f(INT32_MIN, 0), 0); +assertEq(f(UINT32_MAX, 0), 0); +assertEq(f(-1, INT32_MAX), 2); +assertEq(f(-1, INT32_MIN), 1); +assertEq(f(-1, UINT32_MAX), 1); +assertEq(f(INT32_MAX, -1), 0); +assertEq(f(INT32_MIN, -1), 0); +assertEq(f(UINT32_MAX, -1), 1); +assertEq(f(INT32_MAX, INT32_MAX), 1); +assertEq(f(INT32_MAX, INT32_MIN), 0); +assertEq(f(UINT32_MAX, INT32_MAX), 2); +assertEq(f(INT32_MAX, UINT32_MAX), 0); +assertEq(f(UINT32_MAX, UINT32_MAX), 1); +assertEq(f(INT32_MIN, INT32_MAX), 1); +assertEq(f(INT32_MIN, UINT32_MAX), 0); +assertEq(f(INT32_MIN, INT32_MIN), 1); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var k = 0; k = (i|0)%(j|0)|0; return k|0 } return f")); +assertEq(f(4,2), 0); +assertEq(f(3,2), 1); +assertEq(f(3,-2), 1); +assertEq(f(-3,-2), -1); +assertEq(f(0, -1), 0); +assertEq(f(0, INT32_MAX), 0); +assertEq(f(0, INT32_MIN), 0); +assertEq(f(INT32_MAX, 0), 0); +assertEq(f(INT32_MIN, 0), 0); +assertEq(f(-1, INT32_MAX), -1); +assertEq(f(-1, INT32_MIN), -1); +assertEq(f(INT32_MAX, -1), 0); +assertEq(f(INT32_MIN, -1), 0); // !! +assertEq(f(INT32_MAX, INT32_MAX), 0); +assertEq(f(INT32_MAX, INT32_MIN), INT32_MAX); +assertEq(f(INT32_MIN, INT32_MAX), -1); +assertEq(f(INT32_MIN, INT32_MIN), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var k = 0; k = (i|0)%4|0; return k|0 } return f")); +assertEq(f(0), 0); +assertEq(f(-1), -1); +assertEq(f(-3), -3); +assertEq(f(-4), 0); +assertEq(f(INT32_MIN), 0); +assertEq(f(3), 3); +assertEq(f(4), 0); +assertEq(f(INT32_MAX), 3); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var k = 0; k = (i>>>0)%(j>>>0)|0; return k|0 } return f")); +assertEq(f(4,2), 0); +assertEq(f(3,2), 1); +assertEq(f(3,-2), 3); +assertEq(f(-3,-2), -3); +assertEq(f(0, -1), 0); +assertEq(f(0, INT32_MAX), 0); +assertEq(f(0, INT32_MIN), 0); +assertEq(f(0, UINT32_MAX), 0); +assertEq(f(INT32_MAX, 0), 0); +assertEq(f(INT32_MIN, 0), 0); +assertEq(f(UINT32_MAX, 0), 0); +assertEq(f(-1, INT32_MAX), 1); +assertEq(f(-1, INT32_MIN), INT32_MAX); +assertEq(f(-1, UINT32_MAX), 0); +assertEq(f(INT32_MAX, -1), INT32_MAX); +assertEq(f(INT32_MIN, -1), INT32_MIN); +assertEq(f(UINT32_MAX, -1), 0); +assertEq(f(INT32_MAX, INT32_MAX), 0); +assertEq(f(INT32_MAX, INT32_MIN), INT32_MAX); +assertEq(f(UINT32_MAX, INT32_MAX), 1); +assertEq(f(INT32_MAX, UINT32_MAX), INT32_MAX); +assertEq(f(UINT32_MAX, UINT32_MAX), 0); +assertEq(f(INT32_MIN, INT32_MAX), 1); +assertEq(f(INT32_MIN, UINT32_MAX), INT32_MIN); +assertEq(f(INT32_MIN, INT32_MIN), 0); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return (4 / 2)|0 } return f"))(), 2); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return (3 / 2)|0 } return f"))(), 1); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return (4 % 2)|0 } return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return (3 % 2)|0 } return f"))(), 1); + +assertAsmTypeFail(USE_ASM + "function f() { var i=42,j=1.1; return +(i?i:j) } return f"); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return 0; 1 ? 1 : 1; return 0; } return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=42,j=1.1; return +(i?+(i|0):j) } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=42,j=1; return (i?i:j)|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var i=42,j=1; return 13; return (i?i:j)|0 } return f"))(), 13); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return (0 > (-(~~1) >>> 0)) | 0; } return f"))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return 0 < 4294967294 | 0; } return f"))(), 1); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return ((i|0)>(j|0)?(i+10)|0:(j+100)|0)|0 } return f")); +assertEq(f(2, 4), 104); +assertEq(f(-2, -4), 8); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j,k) { i=i|0;j=j|0;k=k|0; return ((i|0)>(j|0) ? (i|0)>(k|0) ? i : k : (j|0)>(k|0) ? j : k)|0 } return f")); +assertEq(f(1,2,3), 3); +assertEq(f(1,3,2), 3); +assertEq(f(2,1,3), 3); +assertEq(f(2,3,1), 3); +assertEq(f(3,1,2), 3); +assertEq(f(3,2,1), 3); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; var a=0,b=0; a=i>>>0 < 4294967292; b=(i|0) < -4; return (j ? a : b)|0 } return f")); +assertEq(f(1,true), 1); +assertEq(f(-1,true), 0); +assertEq(f(-5,true), 1); +assertEq(f(1,false), 0); +assertEq(f(-1,false), 0); +assertEq(f(-5,false), 1); + +assertAsmTypeFail('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return (i32[0]+1)|0 } return f"); +new Float64Array(BUF_64KB)[0] = 2.3; +assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] + 2.0) } return f"), this, null, BUF_64KB)(), 2.3+2); +assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] - 2.0) } return f"), this, null, BUF_64KB)(), 2.3-2); +assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] * 2.0) } return f"), this, null, BUF_64KB)(), 2.3*2); +assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] / 2.0) } return f"), this, null, BUF_64KB)(), 2.3/2); +assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +(f64[0] % 2.0) } return f"), this, null, BUF_64KB)(), 2.3%2); +assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "function f() { return +-f64[0] } return f"), this, null, BUF_64KB)(), -2.3); +assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "var sqrt=glob.Math.sqrt; function f() { return +sqrt(f64[0]) } return f"), this, null, BUF_64KB)(), Math.sqrt(2.3)); +new Int32Array(BUF_64KB)[0] = 42; +assertEq(asmLink(asmCompile('glob','imp','b', USE_ASM + HEAP_IMPORTS + "var imul=glob.Math.imul; function f() { return imul(i32[0], 2)|0 } return f"), this, null, BUF_64KB)(), 84); + +// beware ye phis of comparisons and integers +var f = asmLink(asmCompile(USE_ASM + "function g(i) { i=i|0; if (i) { i = ((i|0) == 2); } else { i=(i-1)|0 } return i|0; } return g ")); +assertEq(f(0), -1); +assertEq(f(1), 0); +assertEq(f(2), 1); +var f = asmLink(asmCompile(USE_ASM + "function g(i) { i=i|0; if (i) { i = !i } else { i=(i-1)|0 } return i|0; } return g ")); +assertEq(f(0), -1); +assertEq(f(1), 0); +assertEq(f(2), 0); + +// beware ye constant-evaluate of boolean-producing operators +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return (4 | (2 == 2))|0 } return f"))(), 5); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return (4 | (!2))|0 } return f"))(), 4); + +// get that order-of-operations right! +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob','imp','buf', USE_ASM + "var i32=new glob.Int32Array(buf); var x=0; function a() { return x|0 } function b() { x=42; return 0 } function f() { i32[((b()|0) & 0x3) >> 2] = a()|0 } return f"), this, null, buf)(); +assertEq(new Int32Array(buf)[0], 42); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { var a=0,i=0; for (; ~~i!=4; i=(i+1)|0) { a = (a*5)|0; if (+(a>>>0) != 0.0) return 1; } return 0; } return f"))(), 0) + +// Signed integer division by a power of two. +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return ((i|0)/1)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), Math.pow(2,i)); + assertEq(f(Math.pow(2,i)-1), Math.pow(2,i)-1); + assertEq(f(-Math.pow(2,i)), -Math.pow(2,i)); + assertEq(f(-Math.pow(2,i)-1), -Math.pow(2,i)-1); +} +assertEq(f(INT32_MIN), INT32_MIN); +assertEq(f(INT32_MAX), INT32_MAX); +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return ((i|0)/2)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), (Math.pow(2,i)/2)|0); + assertEq(f(Math.pow(2,i)-1), ((Math.pow(2,i)-1)/2)|0); + assertEq(f(-Math.pow(2,i)), (-Math.pow(2,i)/2)|0); + assertEq(f(-Math.pow(2,i)-1), ((-Math.pow(2,i)-1)/2)|0); +} +assertEq(f(INT32_MIN), (INT32_MIN/2)|0); +assertEq(f(INT32_MAX), (INT32_MAX/2)|0); +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return ((i|0)/4)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), (Math.pow(2,i)/4)|0); + assertEq(f(Math.pow(2,i)-1), ((Math.pow(2,i)-1)/4)|0); + assertEq(f(-Math.pow(2,i)), (-Math.pow(2,i)/4)|0); + assertEq(f(-Math.pow(2,i)-1), ((-Math.pow(2,i)-1)/4)|0); +} +assertEq(f(INT32_MIN), (INT32_MIN/4)|0); +assertEq(f(INT32_MAX), (INT32_MAX/4)|0); +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return ((i|0)/1073741824)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), (Math.pow(2,i)/Math.pow(2,30))|0); + assertEq(f(Math.pow(2,i)-1), ((Math.pow(2,i)-1)/Math.pow(2,30))|0); + assertEq(f(-Math.pow(2,i)), (-Math.pow(2,i)/Math.pow(2,30))|0); + assertEq(f(-Math.pow(2,i)-1), ((-Math.pow(2,i)-1)/Math.pow(2,30))|0); +} +assertEq(f(INT32_MIN), (INT32_MIN/Math.pow(2,30))|0); +assertEq(f(INT32_MAX), (INT32_MAX/Math.pow(2,30))|0); +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return ((((i|0)/1)|0)+i)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), (Math.pow(2,i) * 2)|0); + assertEq(f(Math.pow(2,i) - 1), ((Math.pow(2,i) - 1) * 2)|0); + assertEq(f(-Math.pow(2,i)), (-Math.pow(2,i) * 2)|0); + assertEq(f(-Math.pow(2,i) - 1), ((-Math.pow(2,i) - 1) * 2)|0); +} +assertEq(f(INT32_MIN), (INT32_MIN * 2)|0); +assertEq(f(INT32_MAX), (INT32_MAX * 2)|0); + +// Signed integer division by a power of two - with a non-negative numerator! +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((i|0)/1)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), Math.pow(2,i)); + assertEq(f(Math.pow(2,i+1)-1), Math.pow(2,i+1)-1); +} +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((i|0)/2)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), (Math.pow(2,i)/2)|0); + assertEq(f(Math.pow(2,i+1)-1), ((Math.pow(2,i+1)-1)/2)|0); +} +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((i|0)/4)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), (Math.pow(2,i)/4)|0); + assertEq(f(Math.pow(2,i+1)-1), ((Math.pow(2,i+1)-1)/4)|0); +} +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((i|0)/1073741824)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), (Math.pow(2,i)/Math.pow(2,30))|0); + assertEq(f(Math.pow(2,i+1)-1), ((Math.pow(2,i+1)-1)/Math.pow(2,30))|0); +} +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; i=(i&2147483647)|0; return ((((i|0)/1)|0)+i)|0; } return f;")); +for (let i = 0; i < 31; i++) { + assertEq(f(Math.pow(2,i)), (Math.pow(2,i) * 2)|0); + assertEq(f(Math.pow(2,i+1) - 1), ((Math.pow(2,i+1) - 1) * 2)|0); +} +assertEq(asmLink(asmCompile(USE_ASM + "var g=0; function f(x, y) { x = x|0; y = y|0; g = (x>>>0)%(y>>>0)|0; return (x|0)%(y|0)|0; } return f;"))(0xff40001, 0xfff80000), 0x40001); diff --git a/js/src/jit-test/tests/asm.js/testFFI.js b/js/src/jit-test/tests/asm.js/testFFI.js new file mode 100644 index 0000000000..5f2884793a --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testFFI.js @@ -0,0 +1,175 @@ +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +function ffi(a,b,c,d) { + return a+b+c+d; +} + +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}); +assertEq(f(1), 23); + +var counter = 0; +function inc() { return counter++ } +function add1(x) { return x+1 } +function add2(x,y) { return x+y } +function add3(x,y,z) { return x+y+z } +function addN() { + var sum = 0; + for (var i = 0; i < arguments.length; i++) + sum += arguments[i]; + return sum; +} +var imp = { inc:inc, add1:add1, add2:add2, add3:add3, addN:addN, identity: x => x }; + +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { incc() } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { var i = 0; return (i + inc)|0 } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { inc = 0 } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return (inc() + 1)|0 } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return +((inc()|0) + 1.1) } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return +(inc() + 1.1) } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return (+inc() + 1)|0 } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { var i = 0; inc(i>>>0) } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { if (0) return inc(); return } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { inc(inc()) } return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { g(inc()) } function g() {} return f'); +assertAsmTypeFail('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { inc()|inc() } return f'); + +assertAsmLinkFail(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc()|0 } return f'), null, {}); +assertAsmLinkFail(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc()|0 } return f'), null, {inc:0}); +assertAsmLinkFail(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function f() { return inc()|0 } return f'), null, {inc:{}}); + +assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function g() { inc() } return g'), null, imp)(), undefined); +assertEq(counter, 1); + +var f = asmLink(asmCompile('glob', 'imp', USE_ASM + 'var inc=imp.inc; function g() { return inc()|0 } return g'), null, imp); +assertEq(f(), 1); +assertEq(counter, 2); +assertEq(f(), 2); +assertEq(counter, 3); + +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); +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); +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); +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); +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); +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); + +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); +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); + +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)); +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)); + +counter = 0; +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); +assertEq(counter, 4); + +var recurse = function(i,j) { if (i == 0) return j; return f(i-1,j+1)+j } +imp.recurse = recurse; +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); +assertEq(f(0,3.3), 3.3); +assertEq(f(1,3.3), 3.3+4.3); +assertEq(f(2,3.3), 3.3+4.3+5.3); + +function maybeThrow(i, j) { + if (i == 0) + throw j; + try { + return f(i-1, j); + } catch(e) { + assertEq(typeof e, "number"); + return e; + } +} +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}); +assertThrowsValue(function() { f(0,0) }, 1); +assertThrowsValue(function() { f(0,Math.pow(2,31)-1) }, -Math.pow(2,31)); +assertEq(f(1,0), 2); +assertEq(f(2,0), 3); +assertEq(f(3,0), 4); +assertEq(f(4,5), 10); + +var recurse = function(i,j) { if (i == 0) throw j; f(i-1,j) } +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}); +assertThrowsValue(function() { f(0,2.4) }, 2.4+4); +assertThrowsValue(function() { f(1,2.4) }, 2.4+8); +assertThrowsValue(function() { f(8,2.4) }, 2.4+36); + +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); + +// Test asm.js => ion paths +setJitCompilerOption("ion.warmup.trigger", 10); +setJitCompilerOption("baseline.warmup.trigger", 0); +setJitCompilerOption("offthread-compilation.enable", 0); + +// In registers on x64 and ARM, on the stack for x86 +function ffiIntFew(a,b,c,d) { return d+1 } +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}); +for (var i = 0; i < 40; i++) + assertEq(f(i), i+4); + +// Stack and registers for x64 and ARM, stack for x86 +function ffiIntMany(a,b,c,d,e,f,g,h,i,j) { return j+1 } +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}); +for (var i = 0; i < 15; i++) + assertEq(f(i), i+10); + +// In registers on x64 and ARM, on the stack for x86 +function ffiDoubleFew(a,b,c,d) { return d+1 } +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}); +for (var i = 0; i < 15; i++) + assertEq(f(i), i+4); + +// Stack and registers for x64 and ARM, stack for x86 +function ffiDoubleMany(a,b,c,d,e,f,g,h,i,j) { return j+1 } +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}); +for (var i = 0; i < 15; i++) + assertEq(f(i), i+10); + +// Test the throw path +function ffiThrow(n) { if (n == 14) throw new Error('yolo'); } +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}); +var i = 0; +try { + for (; i < 15; i++) + f(i); + throw 'assume unreachable'; +} catch (e) { + assertEq(e.message, 'yolo'); + assertEq(i, 14); +} + +// OOL conversion paths +var INT32_MAX = Math.pow(2, 31) - 1; +function ffiOOLConvertInt(n) { if (n == 40) return valueToConvert; return 42; } +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}); +for (var i = 0; i < 40; i++) + assertEq(f(i), 42); +valueToConvert = INT32_MAX + 1; +assertEq(f(40), INT32_MAX + 1 | 0); +function testBadConversions(f) { + valueToConvert = {valueOf: function () { throw new Error("FAIL"); }}; + + var errMsg; + try { + f(40); + } catch(e) { + errMsg = e.message; + } + assertEq(errMsg, "FAIL"); + + valueToConvert = {valueOf: function () { throw "FAIL"; }}; + assertThrowsValue(() => f(40), "FAIL"); + + valueToConvert = Symbol(); + assertThrowsInstanceOf(() => f(40), TypeError); +} +testBadConversions(f); + +function ffiOOLConvertDouble(n) { if (n == 40) return valueToConvert; return 42.5; } +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}); +for (var i = 0; i < 40; i++) + assertEq(f(i), 42.5); +valueToConvert = {valueOf: function() { return 13.37 }}; +assertEq(f(40), 13.37); +testBadConversions(f); diff --git a/js/src/jit-test/tests/asm.js/testFastHeapAccess.js b/js/src/jit-test/tests/asm.js/testFastHeapAccess.js new file mode 100644 index 0000000000..09bd89693f --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testFastHeapAccess.js @@ -0,0 +1,81 @@ +load(libdir + "asm.js"); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=j|0; u32[((i<<2)+32 & 0xffff)>>2] = j } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + f(i, i); +var u32 = new Uint32Array(BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(u32[8+i], i); +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return u32[((i<<2)+32 & 0xffff)>>2]|0 } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(f(i), i); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=j|0; u32[(i<<2 & 0xffff)>>2] = j } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + f(i, i); +var u32 = new Uint32Array(BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(u32[i], i); +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return u32[(i<<2 & 0xffff)>>2]|0 } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(f(i), i); + +// For legacy compatibility, test Int8/Uint8 accesses with no shift. +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=j|0; u8[i+20 & 0xffff] = j } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + f(i, i); +var u8 = new Uint8Array(BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(u8[i+20], i); +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return u8[i+20 & 0xffff]|0 } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(f(i), i); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=j|0; u8[(i+20 & 0xffff)>>0] = j } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + f(i, i); +var u8 = new Uint8Array(BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(u8[i+20], i); +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return u8[(i+20 & 0xffff)>>0]|0 } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(f(i), i); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j,k) {i=i|0;j=j|0;k=k|0; i32[(i + (j<<2) & 0xffff) >> 2] = k } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + f(32, i, i); +var u32 = new Uint32Array(BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(u32[8+i], i); +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=j|0; return i32[(i + (j<<2) & 0xffff) >> 2]|0 } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(f(32, i), i); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j,k) {i=i|0;j=j|0;k=k|0; i32[(((i + (j<<2))|0) + 16 & 0xffff) >> 2] = k } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + f(32, i, i); +var u32 = new Uint32Array(BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(u32[8+i+4], i); +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=j|0; return i32[(((i + (j<<2))|0) + 16 & 0xffff) >> 2]|0 } return f'); +var f = asmLink(code, this, null, BUF_64KB); +for (var i = 0; i < 100; i++) + assertEq(f(32, i), i); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=j|0; return ((i32[(i+(j<<2)&0xffff)>>2]|0) + (i32[(((i+(j<<2))|0)+4&0xffff)>>2]|0))|0 } return f'); +var f = asmLink(code, this, null, BUF_64KB); +var i32 = new Uint32Array(BUF_64KB); +i32[11] = 3; +i32[12] = 97; +assertEq(f(12,8), 100); diff --git a/js/src/jit-test/tests/asm.js/testFloat32.js b/js/src/jit-test/tests/asm.js/testFloat32.js new file mode 100644 index 0000000000..34f893b072 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testFloat32.js @@ -0,0 +1,321 @@ +load(libdir + "asm.js"); +const TO_FLOAT32 = "var toF = glob.Math.fround;"; +const HEAP32 = "var f32 = new glob.Float32Array(heap);"; +const HEAP64 = "var f64 = new glob.Float64Array(heap);" +var heap = new ArrayBuffer(BUF_MIN); + +// Module linking +assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() {} return f"), null); +assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() {} return f"), {fround: Math.fround}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() {} return f"), {Math: {fround: Math.imul}}); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() {} return f"), {Math:{fround: Math.fround}})(), undefined); + +// Argument coercions +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = unknown(x); } return f"); +assertAsmTypeFail('glob', USE_ASM + "function f(i) { i = toF(i); } return f"); +assertAsmTypeFail('glob', USE_ASM + "var cos = glob.Math.cos; function f(x) { x = cos(x); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF(); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF(x, x); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF('hi'); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF(loat); } return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(i) { i = toF(i); } return f"), this)(), undefined); + +// Local variables declarations +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = unknown(); } return f"); +assertAsmTypeFail('glob', USE_ASM + "var cos = glob.Math.cos; function f() { var i = cos(); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(x, x); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF('hi'); } return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(5); } return f"), this)(), undefined); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(5.); } return f"), this)(), undefined); + +// Return values +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(4, 4); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF({}); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(x); } return f"); + +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(42); } return f"), this)(), 42); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(0.); } return f"), this)(), 0); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(-0.); } return f"), this)(), -0); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var inf = glob.Infinity; function f() { return toF(inf); } return f"), this)(), Infinity); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(13.37); } return f"), this)(), Math.fround(13.37)); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return +toF(4.); } return f"), this)(), 4); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return +~~toF(4.5); } return f"), this)(), 4); + +// Assign values +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(5.); i = 5; return toF(i); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(5.); i = 6.; return toF(i); } return f"); + +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(-0.); return toF(i); } return f"), this)(), -0); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(0.); return toF(i); } return f"), this)(), 0); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(5.); return toF(i); } return f"), this)(), 5); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(5.); i = toF(42); return toF(i); } return f"), this)(), 42); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(5.); i = toF(6.); return toF(i); } return f"), this)(), 6); + +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { var i = toF(5.); f32[0] = toF(6.); i = f32[0]; return toF(i); } return f"); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { var i = toF(5.); f32[0] = toF(6.); i = toF(f32[0]); return toF(i); } return f"), this, null, heap)(), 6); + +// Special array assignments (the other ones are tested in testHeapAccess) +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { var i = 5.; f32[0] = i; return toF(f32[0]); } return f"), this, null, heap)(), 5); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "var f64 = new glob.Float64Array(heap); function f() { var i = toF(5.); f64[0] = i; return +f64[0]; } return f"), this, null, heap)(), 5); + +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 1.5; return +f32[0]; } return f"), this, null, heap)(), 1.5); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + HEAP64 + "function f() { f64[0] = 1.5; return toF(f64[0]); } return f"), this, null, heap)(), 1.5); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + HEAP64 + "function f() { f32[0] = toF(42); f64[0] = f32[0]; return +f64[0]; } return f"), this, null, heap)(), 42); + +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = toF(-1.4013e-45) / toF(42.); } return f"), this, null, heap)(), undefined); + +// Coercions +// -> from Float32 +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { var n = 0; n = toF(4.5) | 0; } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { var i = toF(5.); var n = 0; n = i | 0; return n | 0; } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF(x); var n = 0; n = ~~(x + x) >>> 0; return n | 0; } return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF(x); var n = 0.; n = +x; return +n; } return f"), this)(16.64), Math.fround(16.64)); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF(x); var n = 0; n = ~~x; return n | 0; } return f"), this)(16.64), 16); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF(x); var n = 0; n = ~~x >>> 0; return n | 0; } return f"), this)(16.64), 16); + +// -> from float? +function makeCoercion(coercionFunc) { + return USE_ASM + HEAP32 + TO_FLOAT32 + "function f(x) { x = toF(x); f32[0] = x; return " + coercionFunc('f32[0]') + " } return f"; +} +assertAsmTypeFail('glob', 'ffi', 'heap', makeCoercion(x => x + '|0')); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', makeCoercion(x => '+' + x)), this, null, heap)(16.64), Math.fround(16.64)); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', makeCoercion(x => 'toF(' + x + ')')), this, null, heap)(16.64), Math.fround(16.64)); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', makeCoercion(x => '~~+' + x + '|0')), this, null, heap)(16.64), 16); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', makeCoercion(x => '~~toF(' + x + ')|0')), this, null, heap)(16.64), 16); + +// -> to Float32 +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = x|0; return toF(~~x); } return f"), this)(23), 23); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = x|0; return toF(x >> 0); } return f"), this)(23), 23); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = +x; return toF(x); } return f"), this)(13.37), Math.fround(13.37)); + +UINT32_MAX = Math.pow(2, 32)-1; +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = x|0; return toF(x >>> 0); } return f"), this)(-1), Math.fround(UINT32_MAX)); +var tof = asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = x|0; return toF(x>>>0) } return f"), this); +for (x of [0, 1, 10, 64, 1025, 65000, Math.pow(2,30), Math.pow(2,31), Math.pow(2,32)-2, Math.pow(2,32)-1]) + assertEq(tof(x), Math.fround(x)); + +// Global variables imports +assertAsmTypeFail('glob', USE_ASM + "var x = toF(); function f() {} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = some(3); function f() {} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = toF(); function f() {} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = toF(3, 4); function f() {} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = toF({x: 3}); function f() {} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = toF(true); function f() {} return f"); +assertAsmTypeFail('glob', USE_ASM + "var x = toF(3);" + TO_FLOAT32 + "function f() {} return f"); + +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var x = toF(3.5); function f() {} return f"), this)(), undefined); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var x = toF(3); function f() {} return f"), this)(), undefined); +assertEq(asmLink(asmCompile('glob', 'ffi', USE_ASM + TO_FLOAT32 + "var x = toF(ffi.x); function f() {} return f"), this, {x:3})(), undefined); +assertEq(asmLink(asmCompile('glob', 'ffi', USE_ASM + TO_FLOAT32 + "var x = toF(ffi.x); function f() {} return f"), this, {x:3.5})(), undefined); + +// Global variables uses +values = [2.01, 13.37, -3.141592653] +specials = [NaN, Infinity] + +for (v of values) { + assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var x = toF(" + v + "); function f() {return toF(x);} return f"), this)(), Math.fround(v)); + assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "const x = toF(" + v + "); function f() {return toF(x);} return f"), this)(), Math.fround(v)); + assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var x = toF(0.); function f() {x = toF(" + v + "); return toF(x);} return f"), this)(), Math.fround(v)); + assertEq(asmLink(asmCompile('glob', 'ffi', USE_ASM + TO_FLOAT32 + "var x = toF(ffi.x); function f() {return toF(x);} return f"), this, {x:v})(), Math.fround(v)); +} + +for (v of specials) { + assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var special = glob." + v + "; var g=toF(0.); function f() {g=toF(special); return toF(g);} return f"), this)(), Math.fround(v)); +} + +// Math builtins +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var imul = glob.Math.imul; function f() {var x = toF(1.5), y = toF(2.4); return imul(x, y) | 0;} return f"); + +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var abs = glob.Math.abs; function f() {var x = toF(1.5); return abs(x) | 0;} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var abs = glob.Math.abs; function f() {var x = toF(1.5); return +abs(x);} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var abs = glob.Math.abs; function f() {var x = toF(1.5); return +toF(abs(x));} return f"), this)(), 1.5); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var abs = glob.Math.abs; function f() {var x = toF(1.5); return toF(abs(x))} return f"), this)(), Math.fround(1.5)); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var abs = glob.Math.abs; function f() {var x = toF(-1.5); return toF(abs(x))} return f"), this)(), Math.fround(1.5)); + +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var sqrt = glob.Math.sqrt; function f() {var x = toF(1.5); return sqrt(x) | 0;} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var sqrt = glob.Math.sqrt; function f() {var x = toF(1.5); return +sqrt(x);} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var sqrt = glob.Math.sqrt; function f() {var x = toF(1.5); return +toF(sqrt(x));} return f"), this)(), Math.fround(Math.sqrt(Math.fround(1.5)))); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var sqrt = glob.Math.sqrt; function f() {var x = toF(2.25); return toF(sqrt(x))} return f"), this)(), Math.fround(1.5)); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var sqrt = glob.Math.sqrt; function f() {var x = toF(-1.); return toF(sqrt(x))} return f"), this)(), NaN); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var sqrt = glob.Math.sqrt; var inf = glob.Infinity; function f() {var x = toF(0.); x = toF(inf); return toF(sqrt(x))} return f"), this)(), Infinity); + +// float?s +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + HEAP32 + TO_FLOAT32 + "var sqrt = glob.Math.sqrt; function f(x) { x = toF(x); f32[0] = x; return toF(sqrt(f32[0])) } return f"), this, null, heap)(64), Math.fround(8)); + +// The only other Math functions that can receive float32 as arguments and that strictly commute are floor and ceil (see +// also bug 969203). +var floorModule = asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.floor; function f(x) {x = toF(x); return toF(g(x))} return f"), this); +for (v of [-10.5, -1.2345, -1, 0, 1, 3.141592653, 13.37, Math.Infinity, NaN]) + assertEq(floorModule(v), Math.fround(Math.floor(Math.fround(v)))); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + HEAP32 + TO_FLOAT32 + "var floor = glob.Math.floor; function f(x) { x = toF(x); f32[0] = x; return toF(floor(f32[0])) } return f"), this, null, heap)(13.37), 13); + +var ceilModule = asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.ceil; function f(x) {x = toF(x); return toF(g(x))} return f"), this); +for (v of [-10.5, -1.2345, -1, 0, 1, 3.141592653, 13.37, Math.Infinity, NaN]) + assertEq(ceilModule(v), Math.fround(Math.ceil(Math.fround(v)))); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + HEAP32 + TO_FLOAT32 + "var ceil = glob.Math.ceil; function f(x) { x = toF(x); f32[0] = x; return toF(ceil(f32[0])) } return f"), this, null, heap)(13.37), 14); + +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.cos; function f(x) {x = toF(x); return toF(g(x))} return f"); + +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.cos; function f(x) {x = toF(x); return +(g(x))} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.cos; function f(x) {x = x|0; return toF(g(x))} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.cos; function f(x) {x = toF(x); return g(x) | 0} return f"); + +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.cos; function f(x) {x = +x; return toF(g(+x))} return f"), this)(5), Math.fround(Math.cos(5))); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.cos; function f(x) {x = +x; return toF(g(x))} return f"), this)(5), Math.fround(Math.cos(5))); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + HEAP32 + TO_FLOAT32 + "var g = glob.Math.cos; function f(x) { x = toF(x); return toF(+g(+x)) } return f"), this, null, heap)(3.14159265358), -1); + +// Math functions with arity of two are not specialized for floats, so we shouldn't feed them with floats arguments or +// return type +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.pow; function f(x) {x = toF(x); return toF(g(x, 2.))} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.pow; function f(x) {x = toF(x); return +g(x, 2.)} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.pow; function f(x) {x = toF(x); return toF(g(+x, 2.))} return f"), this)(3), 9); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.pow; function f(x) {x = toF(x); return +g(+x, 2.)} return f"), this)(3), 9); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = glob.Math.pow; function f(x) {x = toF(x); return toF(+g(+x, 2.))} return f"), this)(3), 9); + +// Other function calls +// -> Signature comparisons +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function g(x){x=toF(x); return toF(x);} function f() {var x=toF(4.); var y=toF(0.); var z = 0.; y=toF(g(x)); z = +g(x); return toF(z); } return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var sqrt=glob.Math.sqrt; function g(x){x=toF(x); return toF(sqrt(x));} function f() {var x=toF(4.); var y=toF(0.); var z = 0.; y = toF(g(x)); z = +toF(g(x)); return toF(z); } return f"), this)(), 2); + +// -> FFI +var FFI = "var ffi = env.ffi;"; +assertAsmTypeFail('glob', 'env', USE_ASM + TO_FLOAT32 + FFI + "function f() {var x = toF(3.14); return +ffi(x);} return f"); +assertAsmTypeFail('glob', 'env', USE_ASM + TO_FLOAT32 + FFI + "function f() {var x = toF(3.14); return toF(ffi(+x));} return f"); + +var env = {ffi: function(x) { return x+1; }}; // use registers +assertEq(asmLink(asmCompile('glob', 'env', USE_ASM + TO_FLOAT32 + FFI + "function f(x) {x = toF(x); return toF(+ffi(+x));} return f"), this, env)(5), Math.fround(6)); +env = {ffi: function(a,b,c,d,e,f,g,h,i) { return a+b+c+d+e+f+g+h+i; }}; // use stack arguments (> 8 arguments on linux x64) +assertEq(asmLink(asmCompile('glob', 'env', USE_ASM + TO_FLOAT32 + FFI + "function f(x) {x = toF(x); return toF(+ffi(+x, 1., 2., 3., 4., 5., -5., -4., 1.));} return f"), this, env)(5), Math.fround(12)); + +// -> Internal calls +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function g(x){x=toF(x);return toF(+x + 1.);} function f(x) {x = +x; return toF(g(x));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function g(x){x=toF(x);return toF(+x + 1.);} function f(x) {x = x|0; return toF(g(x));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function g(x){x=toF(x);return toF(+x + 1.);} function f(x) {x = x|0; return toF(g(x));} return f"); + +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function g(x){x=toF(x);return toF(+x + 1.);} function f(x) {x = toF(x); return toF(g(x));} return f"), this, env)(5), Math.fround(6)); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function g(x,y){x=toF(x);y=toF(y);return toF(+x + +y);} function f(x) {x = toF(x); return toF(g(x, toF(1.)));} return f"), this, env)(5), Math.fround(6)); + +// --> internal calls with unused return values +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var g = 4; function s(x) { x = +x; g = (g + ~~x)|0; return g|0;} function f(x) { x = +x; toF(s(x)); return g|0} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = 4; function s(x) { x = +x; g = (g + ~~x)|0; return toF(g|0);} function f(x) { x = +x; toF(s(x)); return g|0} return f"), this)(3), 7); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = 4; function s(x) { x = toF(x); g = (g + ~~x)|0; return toF(g|0);} function f(x) { x = toF(x); return (toF(s(x)), g)|0} return f"), this)(3), 7); + +// --> coerced calls +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = 4; function s(x) { x = toF(x); g = (g + ~~x)|0; return +(g|0);} function f(x) { x = toF(x); return toF(+s(x))} return f"), this)(3), 7); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = 4; function s(x) { x = toF(x); g = (g + ~~x)|0; return g|0;} function f(x) { x = toF(x); return toF(s(x)|0)} return f"), this)(3), 7); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var g = 4; function s(x) { x = toF(x); g = (g + ~~x)|0; return toF(g|0);} function f(x) { x = toF(x); return toF(toF(s(x)))} return f"), this)(3), 7); + +// --> test pressure on registers in internal calls when there are |numArgs| arguments +for (numArgs of [5, 9, 17, 33, 65, 129]) { + let code = (function(n) { + let args = "", coercions = "", sum = "", call="x"; + for (let i = 0; i < n; i++) { + let name = 'a' + i; + args += name + ((i == n-1)?'':','); + coercions += name + '=toF(' + name + ');'; + sum += ((i>0)?'+':'') + ' +' + name; + call += (i==0)?'':',toF(' + i + '.)' + } + return "function g(" + args + "){" + coercions + "return toF(" + sum + ");}" + +"function f(x) { x = toF(x); return toF(g(" + call + "))}"; + })(numArgs); + assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + code + "return f"), this, env)(5), Math.fround(5 + numArgs * (numArgs-1) / 2)); +} + +// -> Pointer calls +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function a(x){x=toF(x);return toF(+x + .5);} function b(x){x=toF(x);return toF(+x - .5);} function f(x, n) {x=+x;n=n|0;return toF(t[n&1](x));} var t=[a,b]; return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function a(x){x=toF(x);return toF(+x + .5);} function b(x){x=toF(x);return toF(+x - .5);} function f(x, n) {x=x|0;n=n|0;return toF(t[n&1](x));} var t=[a,b]; return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function a(x){x=toF(x);return toF(+x + .5);} function b(x){x=toF(x);return toF(+x - .5);} function f(x, n) {x=toF(x);n=n|0;return t[n&1](x)|0;} var t=[a,b]; return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function a(x){x=toF(x);return toF(+x + .5);} function b(x){x=toF(x);return toF(+x - .5);} function f(x, n) {x=toF(x);n=n|0;return +t[n&1](x);} var t=[a,b]; return f"); + +code = asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function a(x){x=toF(x);return toF(+x + .5);} function b(x){x=toF(x);return toF(+x - .5);}" + + "function f(x, n) {x=toF(x);n=n|0;return toF(t[n&1](x));} var t=[a,b]; return f"), this); +assertEq(code(0, 0), .5); +assertEq(code(0, 1), -.5); +assertEq(code(13.37, 0), Math.fround(13.37 + .5)); +assertEq(code(13.37, 1), Math.fround(13.37 - .5)); + +// Arithmetic operations +// -> mul +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(3 * toF(4.));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(3. * toF(4.)); } return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return +(toF(3.) * toF(4.));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(3) * toF(4) * toF(5));} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(3.) * toF(4.)); } return f"), this)(), 12); + +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(3 * f32[0]);} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(3. * f32[0]);} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return +(toF(3.) * f32[0]);} return f"); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(toF(3.) * f32[0]);} return f"), this, null, heap)(), 12); + +var mul = asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x=toF(x); return toF(x * toF(4.));} return f"), this); +assertEq(mul(Infinity), Infinity); +assertEq(mul(NaN), NaN); +assertEq(mul(0), 0); +assertEq(mul(1), 4); +assertEq(mul(0.33), Math.fround(0.33 * 4)); + +// -> add +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(3 + toF(4.));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(3.5 + toF(4.));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return +(toF(3.5) + toF(4.));} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(3.5) + toF(4.)); } return f"), this)(), 7.5); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(3.5) + toF(4.) + toF(4.5));} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(toF(3.5) + toF(4.)) + toF(4.5)); } return f"), this)(), 12); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(toF(3) + f32[0]);} return f"), this, null, heap)(), 7); + +// --> no additions with float? or floatish +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(3 + f32[0]);} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(3. + f32[0]);} return f"); + +// -> sub +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(3 - toF(4.));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(3.5 - toF(4.));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return +(toF(3.5) - toF(4.));} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(3.5) - toF(4.)); } return f"), this)(), -.5); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(3.5) - toF(4.) - toF(4.5));} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(toF(3.5) - toF(4.)) - toF(4.5)); } return f"), this)(), -5); + +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(3.5) + toF(4.) - toF(4.5));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(3.5) - toF(4.) + toF(4.5));} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(toF(3.5) + toF(4.)) - toF(4.5)); } return f"), this)(), 3); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(toF(3.5) - toF(4.)) + toF(4.5)); } return f"), this)(), 4); + +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(3 - f32[0]);} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(3. - f32[0]);} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return +(toF(3) - f32[0]);} return f"); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(toF(3) - f32[0]);} return f"), this, null, heap)(), -1); + +// -> div +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(3 / toF(4.));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(3.5 / toF(4.));} return f"); +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return +(toF(3.5) / toF(4.));} return f"); +assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(12.) / toF(4.)); } return f"), this)(), 3); + +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(3 / f32[0]);} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return toF(3. / f32[0]);} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 4.; return +(toF(3) / f32[0]);} return f"); +assertEq(asmLink(asmCompile('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { f32[0] = 2.; return toF(toF(4) / f32[0]);} return f"), this, null, heap)(), 2); + +// -> mod +assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "function f() { return toF(toF(3.5) % toF(4.));} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { return toF(f32[0] % toF(4.));} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { return toF(toF(3.5) % f32[0]);} return f"); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { return toF(f32[1] % f32[0]);} return f"); + +// Comparisons +for (op of ['==', '!=', '<', '>', '<=', '>=']) { + let code = asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF(x); if( x " + op + " toF(3.) ) return 1; else return 0; return -1; } return f"), this); + let ternary = asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = toF(x); return ((x " + op + " toF(3.)) ? 1 : 0)|0 } return f"), this); + for (v of [-5, 0, 2.5, 3, 13.37, NaN, Infinity]) { + let expected = eval("("+ v + " " + op + " 3)|0"); + assertEq(code(v) | 0, expected); + assertEq(ternary(v) | 0, expected); + } + + assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { if( f32[0] " + op + " toF(3.) ) return 1; else return 0; return -1; } return f"); + assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + TO_FLOAT32 + HEAP32 + "function f() { if( (toF(1.) + toF(2.)) " + op + " toF(3.) ) return 1; else return 0; return -1; } return f"); +} + diff --git a/js/src/jit-test/tests/asm.js/testFloatingPoint.js b/js/src/jit-test/tests/asm.js/testFloatingPoint.js new file mode 100644 index 0000000000..bad22028e0 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testFloatingPoint.js @@ -0,0 +1,134 @@ +load(libdir + "asm.js"); + +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return 1.1 } return f"))(), 1.1); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return +(+(i|0) + .1) } return f"))(1), 1.1); +assertEq(asmLink(asmCompile(USE_ASM + "function f(d) { d=+d; return +d } return f"))(1.1), 1.1); +assertEq(asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return +(d+e) } return f"))(1.0, .1), 1.1); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i,e) { i=i|0;e=+e; return +(+~~i+e) } return f"))(1, .1), 1.1); +assertEq(asmLink(asmCompile(USE_ASM + "function f(d,i) { d=+d;i=i|0; return +(d + +(i|0)) } return f"))(.1, 1), 1.1); +assertEq(asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return +(d-e) } return f"))(1.1, .8), (1.1-.8)); +assertEq(asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return +(d*e) } return f"))(1.1, 2.2), (1.1*2.2)); +assertEq(asmLink(asmCompile(USE_ASM + "function g() { var i=2; return (~~(i=(i+1)|0))|0 } return g"))(), 3); + +var f = asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return (d<e)|0 } return f")); +assertEq(f(1.1, 2.2), 1); +assertEq(f(1.1, 1.1), 0); +assertEq(f(2.1, 1.1), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return (d<=e)|0 } return f")); +assertEq(f(1.1, 2.2), 1); +assertEq(f(1.1, 1.1), 1); +assertEq(f(2.1, 1.1), 0); +assertEq(f(NaN, 1.1), 0); +assertEq(f(1.1, NaN), 0); +assertEq(f(NaN, NaN), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return (d>e)|0 } return f")); +assertEq(f(2.1, 1.1), 1); +assertEq(f(1.1, 1.1), 0); +assertEq(f(1.1, 2.1), 0); +assertEq(f(NaN, 1.1), 0); +assertEq(f(1.1, NaN), 0); +assertEq(f(NaN, NaN), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return (d>=e)|0 } return f")); +assertEq(f(2.1, 1.1), 1); +assertEq(f(1.0, 1.1), 0); +assertEq(f(1.1, 2.1), 0); +assertEq(f(NaN, 1.1), 0); +assertEq(f(1.1, NaN), 0); +assertEq(f(NaN, NaN), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return (d==e)|0 } return f")); +assertEq(f(2.1, 1.1), 0); +assertEq(f(1.1, 1.1), 1); +assertEq(f(1.1, 2.1), 0); +assertEq(f(NaN, 1.1), 0); +assertEq(f(1.1, NaN), 0); +assertEq(f(NaN, NaN), 0); + +var f = asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return (d!=e)|0 } return f")); +assertEq(f(2.1, 1.1), 1); +assertEq(f(1.1, 1.1), 0); +assertEq(f(1.1, 2.1), 1); +assertEq(f(NaN, 1.1), 1); +assertEq(f(1.1, NaN), 1); +assertEq(f(NaN, NaN), 1); + +var f = asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return +(d/e) } return f")); +assertEq(f(1.1, .1), (1.1/.1)); +assertEq(f(1.1, 0), (1.1/0)); +assertEq(f(1.1, -0), (1.1/-0)); + +var f = asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return +(d%e) } return f")); +assertEq(f(1.1, .1), (1.1%.1)); +assertEq(f(1.1, 0), (1.1%0)); +assertEq(f(1.1, -0), (1.1%-0)); + +var f = asmLink(asmCompile(USE_ASM + "function f(d) { d=+d; var i = 0; i = ~~d; return i|0 } return f")); +assertEq(f(1.0), 1); +assertEq(f(1.9), 1); +assertEq(f(1.9999), 1); +assertEq(f(2.0), 2); +assertEq(f(Math.pow(2,40)), ~~Math.pow(2,40)); +assertEq(f(-Math.pow(2,40)), ~~-Math.pow(2,40)); +assertEq(f(4000000000), ~~4000000000); +assertEq(f(-4000000000), ~~-4000000000); +assertEq(f(NaN), 0); +assertEq(f(Infinity), 0); +assertEq(f(-Infinity), 0); + +assertAsmTypeFail(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return +((i|0)/(j|0)) } return f"); +assertAsmTypeFail(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return +(i+j) } return f"); +assertAsmTypeFail(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return +(i-j) } return f"); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return +(((i|0)/(j|0))|0) } return f")); +assertEq(f(1,0), 0); +assertEq(f(-Math.pow(2,31),-1), -Math.pow(2,31)); + +var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return +(((i|0)%(j|0))|0) } return f")); +assertEq(f(1,0), 0); +assertEq(f(-Math.pow(2,31),-1), 0); + +var {f,g} = asmLink(asmCompile(USE_ASM + "function f() { return 3.5 } function g(d) { d=+d; return +(d+3.5) } return {f:f,g:g}")); +assertEq(f(), 3.5); +assertEq(g(1), 1+3.5); + +var buf = new ArrayBuffer(BUF_MIN); +var f64 = new Float64Array(buf); +var i32 = new Int32Array(buf); +var u32 = new Uint32Array(buf); +var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[0] } return f'), this, null, buf); +f64[0] = 0; +assertEq(f(), 0); +f64[0] = -1; +assertEq(f(), -1); +f64[0] = 1; +assertEq(f(), 1); +f64[0] = Infinity; +assertEq(f(), Infinity); +f64[0] = -Infinity; +assertEq(f(), -Infinity); + +function ffi(d) { str = String(d) } +var g = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'var ffi=imp.ffi; function g() { ffi(+f64[0]) } return g'), this, {ffi:ffi}, buf); +var h = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function g() { return +(+f64[0] < 0.0 ? -+f64[0] : +f64[0]) } return g'), this, null, buf) + +function ffi1() { return 2.6 } +assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + "var ffi1=imp.ffi1; function g() { var i=0,j=0.0; i=ffi1()|0; j=+ffi1(); return +(+(i|0)+j) } return g"), null, {ffi1:ffi1})(), 2+2.6); + +// that sounds dangerous! +var a = [0,1,0xffff0000,0x7fff0000,0xfff80000,0x7ff80000,0xfffc0000,0x7ffc0000,0xffffffff,0x0000ffff,0x00008fff7]; +for (i of a) { + for (j of a) { + u32[0] = i; + u32[1] = j; + + assertEq(f(), f64[0]); + + g(); + assertEq(str, String(f64[0])); + + assertEq(h(), Math.abs(f64[0])); + } +} diff --git a/js/src/jit-test/tests/asm.js/testFunctionPtr.js b/js/src/jit-test/tests/asm.js/testFunctionPtr.js new file mode 100644 index 0000000000..9998356f04 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testFunctionPtr.js @@ -0,0 +1,74 @@ +load(libdir + "asm.js"); + +assertAsmTypeFail('imp', USE_ASM + "function f() {} var imp=[f]; return f"); +assertAsmTypeFail(USE_ASM + "function f() {} var eval=[f]; return f"); +assertAsmTypeFail(USE_ASM + "var tbl=0; function f() {} var tbl=[f]; return f"); +assertAsmTypeFail(USE_ASM + "function f() {} var tbl; return f"); +assertAsmTypeFail(USE_ASM + "function f() {} var tbl=[]; return f"); +assertAsmTypeFail(USE_ASM + "function f() {} var tbl=[f,f,f]; return f"); +assertAsmTypeFail(USE_ASM + "function f() {} var tbl=[1]; return f"); +assertAsmTypeFail(USE_ASM + "var g = 0; function f() {} var tbl=[g]; return f"); +assertAsmTypeFail(USE_ASM + "function f() {} function g(i) {i=i|0} var tbl=[f,g]; return f"); +assertAsmTypeFail(USE_ASM + "function f() {} function g() {return 0} var tbl=[f,g]; return f"); +assertAsmTypeFail(USE_ASM + "function f(i) {i=i|0} function g(i) {i=+i} var tbl=[f,g]; return f"); +assertAsmTypeFail(USE_ASM + "function f() {return 0} function g() {return 0.0} var tbl=[f,g]; return f"); +assertAsmTypeFail(USE_ASM + "var tbl=0; function g() {tbl[0&1]()|0} return g"); +assertEq(asmLink(asmCompile(USE_ASM + "function f() { return 42 } var tbl=[f]; return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 0} function g() {return 1} var tbl=[f,g]; return f"))(), 0); + +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return ([])[i&1]()|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return f[i&1]()|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return tbl[i]()|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return tbl[i&0]()|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return tbl[i&3]()|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g(i,j) { i=i|0;j=+j; return tbl[j&1]()|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return tbl[i&1](1)|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function f(i) {i=i|0} function g(i) { i=i|0; return tbl[i&1]()|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function f(i) {i=i|0} function g(i) { i=i|0; return tbl[i&1](3.0)|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function f(d) {d=+d} function g(i) { i=i|0; return tbl[i&1](3)|0 } var tbl=[f,f]; return g"); +assertAsmTypeFail(USE_ASM + "function g() {tbl[0&1]()|0} return g"); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return tbl[i&1]()|0 } var tbl=[f,f]; return g"))(0), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g(i) { i=i|0; return tbl[i&1]()|0 } const tbl=[f,f]; return g"))(0), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() {return 13} function h(i) { i=i|0; return tbl[i&1]()|0 } var tbl=[f,g]; return h"))(1), 13); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() {return 13} function h(i) { i=i|0; return tbl[i&1]()|0 } const tbl=[f,g]; return h"))(1), 13); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() {return 13} function h(i) { i=i|0; return tbl2[i&1]()|0 } var tbl1=[f,g]; var tbl2=[g,f]; return h"))(1), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() {return 13} function h(i) { i=i|0; return tbl2[i&1]()|0 } const tbl1=[f,g]; const tbl2=[g,f]; return h"))(1), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() {return 13} function h(i) { i=i|0; return tbl2[i&3]()|0 } var tbl1=[f,g]; var tbl2=[g,g,g,f]; return h"))(3), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() {return 13} function h(i) { i=i|0; return tbl2[i&3]()|0 } const tbl1=[f,g]; const tbl2=[g,g,g,f]; return h"))(3), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() {return 13} function h(i) { i=i|0; return tbl1[i&1]()|0 } var tbl1=[f,g]; var tbl2=[g,g,g,f]; return h"))(1), 13); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() {return 13} function h(i) { i=i|0; return tbl1[i&1]()|0 } const tbl1=[f,g]; const tbl2=[g,g,g,f]; return h"))(1), 13); +assertEq(asmLink(asmCompile(USE_ASM + "var i=0,j=0; function f() {return i|0} function g() {return j|0} function h(x) { x=x|0; i=5;j=10; return tbl2[x&3]()|0 } var tbl1=[f,g]; var tbl2=[g,g,g,f]; return h"))(3), 5); +assertEq(asmLink(asmCompile(USE_ASM + "var i=0,j=0; function f() {return i|0} function g() {return j|0} function h(x) { x=x|0; i=5;j=10; return tbl2[x&3]()|0 } const tbl1=[f,g]; const tbl2=[g,g,g,f]; return h"))(3), 5); +assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + "var ffi=imp.ffi; function f() {return ffi()|0} function g() {return 13} function h(x) { x=x|0; return tbl2[x&3]()|0 } var tbl2=[g,g,g,f]; return h"), null, {ffi:function(){return 20}})(3), 20); +assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + "const ffi=imp.ffi; function f() {return ffi()|0} function g() {return 13} function h(x) { x=x|0; return tbl2[x&3]()|0 } const tbl2=[g,g,g,f]; return h"), null, {ffi:function(){return 20}})(3), 20); +assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + "var ffi=imp.ffi; var i=0; function f() {return ((ffi()|0)+i)|0} function g() {return 13} function h(x) { x=x|0; i=2; return tbl2[x&3]()|0 } var tbl2=[g,g,g,f]; return h"), null, {ffi:function(){return 20}})(3), 22) +;assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + "const ffi=imp.ffi; var i=0; function f() {return ((ffi()|0)+i)|0} function g() {return 13} function h(x) { x=x|0; i=2; return tbl2[x&3]()|0 } const tbl2=[g,g,g,f]; return h"), null, {ffi:function(){return 20}})(3), 22); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) {i=i|0; return +((i+1)|0)} function g(d) { d=+d; return +(d+2.5) } function h(i,j) { i=i|0;j=j|0; return +tbl2[i&1](+tbl1[i&1](j)) } var tbl1=[f,f]; var tbl2=[g,g]; return h"))(0,10), 11+2.5); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) {i=i|0; return +((i+1)|0)} function g(d) { d=+d; return +(d+2.5) } function h(i,j) { i=i|0;j=j|0; return +tbl2[i&1](+tbl1[i&1](j)) } const tbl1=[f,f]; const tbl2=[g,g]; return h"))(0,10), 11+2.5); + +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g() { return tbl[0]()|0 } var tbl=[f]; return g"); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() { return tbl[0&0]()|0 } var tbl=[f]; return g"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f() {return 42} function g() { return tbl[0&0]()|0 } const tbl=[f]; return g"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f1() {return 42} function f2() {return 13} function g() { return tbl[1&1]()|0 } var tbl=[f1,f2]; return g"))(), 13); +assertEq(asmLink(asmCompile(USE_ASM + "function f1() {return 42} function f2() {return 13} function g() { return tbl[1&1]()|0 } const tbl=[f1,f2]; return g"))(), 13); + +// Test some literal constant paths. +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g() { return tbl[0&4294967295]()|0 } var tbl=[f]; return g"); +assertAsmTypeFail(USE_ASM + "const i=4294967295; function f() {return 42} function g() { return tbl[0&i]()|0 } var tbl=[f]; return g"); +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g() { return tbl[0&-1]()|0 } var tbl=[f]; return g"); +assertAsmTypeFail(USE_ASM + "const i=-1; function f() {return 42} function g() { return tbl[0&i]()|0 } var tbl=[f]; return g"); +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g() { return tbl[0&0x80000000]()|0 } var tbl=[f]; return g"); +assertAsmTypeFail(USE_ASM + "const i=0x80000000; function f() {return 42} function g() { return tbl[0&i]()|0 } var tbl=[f]; return g"); +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g() { return tbl[0&-2147483648]()|0 } var tbl=[f]; return g"); +assertAsmTypeFail(USE_ASM + "const i=-2147483648; function f() {return 42} function g() { return tbl[0&i]()|0 } var tbl=[f]; return g"); +assertAsmTypeFail(USE_ASM + "const i=0; function f() {return 42} function g() { return tbl[0&i]()|0 } var tbl=[f]; return g"); +// Limited by the inability to test really large tables. +assertAsmTypeFail(USE_ASM + "function f() {return 42} function g() { return tbl[0&0x7fffffff]()|0 } var tbl=[f]; return g"); + +var f = asmLink(asmCompile(USE_ASM + "function f1(d) {d=+d; return +(d/2.0)} function f2(d) {d=+d; return +(d+10.0)} function g(i,j) { i=i|0;j=+j; return +tbl[i&1](+tbl[(i+1)&1](j)) } var tbl=[f1,f2]; return g")); +assertEq(f(0,10.2), (10.2+10)/2); +assertEq(f(1,10.2), (10.2/2)+10); + +var f = asmLink(asmCompile('glob','imp', USE_ASM + "var ffi=imp.ffi; function f(){return 13} function g(){return 42} function h(i) { i=i|0; var j=0; ffi(1); j=TBL[i&7]()|0; ffi(1.5); return j|0 } var TBL=[f,g,f,f,f,f,f,f]; return h"), null, {ffi:function(){}}); +for (var i = 0; i < 100; i++) + assertEq(f(i), (i%8 == 1) ? 42 : 13); diff --git a/js/src/jit-test/tests/asm.js/testGetter.js b/js/src/jit-test/tests/asm.js/testGetter.js new file mode 100644 index 0000000000..9a97463550 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testGetter.js @@ -0,0 +1,11 @@ +function asmJSGetter() { + "use asm"; + return {} +} +var sym = Symbol(); +var o = {}; +o.__defineGetter__(sym, asmJSGetter); + +for (var i = 0; i < 10; i++) { + o[sym]; +} diff --git a/js/src/jit-test/tests/asm.js/testGlobals.js b/js/src/jit-test/tests/asm.js/testGlobals.js new file mode 100644 index 0000000000..1e9fc3ac9c --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testGlobals.js @@ -0,0 +1,164 @@ +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +assertAsmTypeFail(USE_ASM + "var i; function f(){} return f"); +assertEq(asmLink(asmCompile(USE_ASM + "var i=0; function f(){} return f"))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + "const i=0; function f(){} return f"))(), undefined); +assertEq(asmLink(asmCompile(USE_ASM + "var i=42; function f(){ return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "const i=42; function f(){ return i|0 } return f"))(), 42); +assertEq(asmLink(asmCompile(USE_ASM + "var i=4.2; function f(){ return +i } return f"))(), 4.2); +assertEq(asmLink(asmCompile(USE_ASM + "const i=4.2; function f(){ return +i } return f"))(), 4.2); +assertAsmTypeFail(USE_ASM + "var i=42; function f(){ return +(i+.1) } return f"); +assertAsmTypeFail(USE_ASM + "const i=42; function f(){ return +(i+.1) } return f"); +assertAsmTypeFail(USE_ASM + "var i=1.2; function f(){ return i|0 } return f"); +assertAsmTypeFail(USE_ASM + "const i=1.2; function f(){ return i|0 } return f"); +assertAsmTypeFail(USE_ASM + "var i=0; function f(e){ e=+e; i=e } return f"); +assertAsmTypeFail(USE_ASM + "var d=0.1; function f(i){ i=i|0; d=i } return f"); +assertEq(asmLink(asmCompile(USE_ASM + "var i=13; function f(j) { j=j|0; i=j; return i|0 } return f"))(42), 42); +assertEq(asmLink(asmCompile(USE_ASM + "var d=.1; function f(e) { e=+e; d=e; return +e } return f"))(42.1), 42.1); +assertEq(asmLink(asmCompile(USE_ASM + "var i=13; function f(i, j) { i=i|0; j=j|0; i=j; return i|0 } return f"))(42,43), 43); +assertEq(asmLink(asmCompile(USE_ASM + "var i=13; function f(j) { j=j|0; var i=0; i=j; return i|0 } return f"))(42), 42); + +var f = asmLink(asmCompile(USE_ASM + "var i=13; function f(j) { j=j|0; if ((j|0) != -1) { i=j } else { return i|0 } return 0 } return f")); +assertEq(f(-1), 13); +assertEq(f(42), 0); +assertEq(f(-1), 42); + +assertAsmTypeFail(USE_ASM + "var i=13; function f() { var j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "var i=13.37; function f() { var j=i; return +j } return f"); +assertAsmTypeFail('global', USE_ASM + "var f32 = global.Math.fround; var i=f32(13.37); function f() { var j=i; return f32(j) } return f"); + +assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { var j=i; return +j } return f'), {Infinity:Infinity})(), Infinity); +assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { var j=i; return +j } return f'), {NaN:NaN})(), NaN); + +assertEq(asmLink(asmCompile(USE_ASM + "const i=13; function f() { var j=i; return j|0 } return f"))(), 13); +assertEq(asmLink(asmCompile(USE_ASM + "const i=13.37; function f() { var j=i; return +j } return f"))(), 13.37); +assertEq(asmLink(asmCompile('global', USE_ASM + "var f32 = global.Math.fround; const i=f32(13.37); function f() { var j=i; return f32(j) } return f"), this)(), Math.fround(13.37)); + +assertAsmTypeFail(USE_ASM + "function f() { var j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function i(){} function f() { var j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f() { var j=i; return j|0 } var i = [f]; return f"); +assertAsmTypeFail('global', USE_ASM + "var i=global.Math.fround; function f() { var j=i; return j|0 } return f"); +assertAsmTypeFail('global', 'imp', USE_ASM + "var i=imp.f; function f() { var j=i; return j|0 } return f"); +assertAsmTypeFail('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { var j=i; return j|0 } return f"); +assertAsmTypeFail('global', 'imp', USE_ASM + "var i=+imp.i; function f() { var j=i; return +j } return f"); +assertAsmTypeFail('global', 'imp', USE_ASM + "const i=imp.i|0; function f() { var j=i; return j|0 } return f"); +assertAsmTypeFail('global', 'imp', USE_ASM + "const i=+imp.i; function f() { var j=i; return +j } return f"); +assertAsmTypeFail('global', 'imp', 'heap', USE_ASM + "var i=new global.Float32Array(heap); function f() { var j=i; return +j } return f"); + +assertAsmTypeFail('global', USE_ASM + "var i=global; function f() { return i|0 } return f"); +assertAsmTypeFail('global', USE_ASM + "const i=global; function f() { return i|0 } return f"); +assertAsmTypeFail('global', USE_ASM + "var i=global|0; function f() { return i|0 } return f"); +assertAsmTypeFail('global', USE_ASM + "const i=global|0; function f() { return i|0 } return f"); +assertAsmTypeFail('global', USE_ASM + "var j=0;var i=j.i|0; function f() { return i|0 } return f"); +assertAsmTypeFail('global', USE_ASM + "var i=global.i|0; function f() { return i|0 } return f"); +assertAsmTypeFail('global', USE_ASM + "const i=global.i|0; function f() { return i|0 } return f"); +assertAsmTypeFail('global', USE_ASM + "var i=global.i|0; function f() { return i|0 } return f"); +assertAsmTypeFail('global', USE_ASM + 'var i=global.Infinity; function f() { i = 0.0 } return f'); +assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), undefined); +assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'const i=global.Infinity; function f() { return +i } return f'), undefined); +assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), null); +assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'const i=global.Infinity; function f() { return +i } return f'), null); +assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), 3); +assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), {}); +assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), {Infinity:NaN}); +assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), {Infinity:-Infinity}); +assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), {Infinity:Infinity})(), Infinity); +assertEq(asmLink(asmCompile('global', USE_ASM + 'const i=global.Infinity; function f() { return +i } return f'), {Infinity:Infinity})(), Infinity); +assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), this)(), Infinity); +assertEq(asmLink(asmCompile('global', USE_ASM + 'const i=global.Infinity; function f() { return +i } return f'), this)(), Infinity); +assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), undefined); +assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), null); +assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), 3); +assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), {}); +assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), {Infinity:Infinity}); +assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), {Infinity:-Infinity}); +assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), {NaN:NaN})(), NaN); +assertEq(asmLink(asmCompile('global', USE_ASM + 'const i=global.NaN; function f() { return +i } return f'), {NaN:NaN})(), NaN); +assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), this)(), NaN); +assertEq(asmLink(asmCompile('global', USE_ASM + 'const i=global.NaN; function f() { return +i } return f'), this)(), NaN); + +assertAsmLinkFail(asmCompile('glob','foreign','buf', USE_ASM + 'var t = new glob.Int32Array(buf); function f() {} return f'), {get Int32Array(){return Int32Array}}, null, new ArrayBuffer(4096)) +assertAsmLinkFail(asmCompile('glob','foreign','buf', USE_ASM + 'const t = new glob.Int32Array(buf); function f() {} return f'), {get Int32Array(){return Int32Array}}, null, new ArrayBuffer(4096)) +assertAsmLinkFail(asmCompile('glob','foreign','buf', USE_ASM + 'var t = new glob.Int32Array(buf); function f() {} return f'), new Proxy(this, {}), null, new ArrayBuffer(4096)) +assertAsmLinkFail(asmCompile('glob','foreign','buf', USE_ASM + 'const t = new glob.Int32Array(buf); function f() {} return f'), new Proxy(this, {}), null, new ArrayBuffer(4096)) +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Math.sin; function f() {} return f'), {get Math(){return Math}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Math.sin; function f() {} return f'), new Proxy(this, {})); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Math.sin; function f() {} return f'), {Math:{get sin(){return Math.sin}}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Math.sin; function f() {} return f'), {Math:new Proxy(Math, {})}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Infinity; function f() {} return f'), {get Infinity(){return Infinity}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Infinity; function f() {} return f'), new Proxy(this, {})); +assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x|0; function f() {} return f'), null, {get x(){return 42}}) +assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.x; function f() {} return f'), null, {get x(){return 42}}) +assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x|0; function f() {} return f'), null, new Proxy({x:42}, {})); +assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.x; function f() {} return f'), null, new Proxy({x:42}, {})); +assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x; function f() {} return f'), null, {get x(){return function(){}}}) +assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x; function f() {} return f'), null, new Proxy({x:function(){}}, {})); +assertAsmTypeFail('global', 'imp', USE_ASM + "var i=imp; function f() { return i|0 } return f"); +assertAsmTypeFail('global', 'imp', USE_ASM + "var j=0;var i=j.i|0; function f() { return i|0 } return f"); +assertAsmLinkAlwaysFail(asmCompile('global','imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f"), null, undefined); +assertAsmLinkAlwaysFail(asmCompile('global','imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f"), this, undefined); +assertAsmLinkAlwaysFail(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f"), null, null); +assertAsmLinkAlwaysFail(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f"), this, null); +assertAsmLinkFail(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f"), this, 42); +assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f")(null, {i:42})), 42); +assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "const i=imp.i|0; function f() { return i|0 } return f")(null, {i:42})), 42); +assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f")(null, {i:1.4})), 1); +assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "const i=imp.i|0; function f() { return i|0 } return f")(null, {i:1.4})), 1); +assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=+imp.i; function f() { return +i } return f")(null, {i:42})), 42); +assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "const i=+imp.i; function f() { return +i } return f")(null, {i:42})), 42); +assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=+imp.i; function f() { return +i } return f")(this, {i:1.4})), 1.4); +assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "const i=+imp.i; function f() { return +i } return f")(this, {i:1.4})), 1.4); +assertEq(asmLink(asmCompile(USE_ASM + "var g=0; function f() { var i=42; while (1) { break; } g = i; return g|0 } return f"))(), 42); +assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.x; function f() {} return f'), null, {x:{valueOf:function() { return 42 }}}); +assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x|0; function f() {} return f'), null, {x:{valueOf:function() { return 42 }}}); +assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x|0; function f() { return i|0} return f'), null, {x:"blah"})(), 0); +assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.x; function f() { return +i} return f'), null, {x:"blah"})(), NaN); +assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var tof = glob.Math.fround; var i = tof(foreign.x); function f() { return +i} return f'), this, {x:"blah"})(), NaN); +assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var i = foreign.x|0; function f() { return i|0} return f')(null, {x:Symbol("blah")}), TypeError); +assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var i = +foreign.x; function f() { return +i} return f')(null, {x:Symbol("blah")}), TypeError); +assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var tof = glob.Math.fround; var i = tof(foreign.x); function f() { return +i} return f')(this, {x:Symbol("blah")}), TypeError); + +// Temporary workaround; this test can be removed when Emscripten is fixed and +// the fix has propagated out to most apps: +assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.i|0; function f() { return i|0} return f'), null, {i:function(){}})(), 0); +assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.i; function f() { return +i} return f'), null, {i:function(){}})(), NaN); +assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var tof = glob.Math.fround; var i = tof(foreign.i); function f() { return +i} return f'), this, {i:function(){}})(), NaN); +var module = asmCompile('glob','foreign', USE_ASM + 'var i = foreign.i|0; function f() { return i|0} return f'); +var fun = function() {} +fun.valueOf = function() {} +assertAsmLinkFail(module, null, {i:fun}); +var fun = function() {} +fun.toString = function() {} +assertAsmLinkFail(module, null, {i:fun}); +var fun = function() {} +var origFunToString = Function.prototype.toString; +Function.prototype.toString = function() {} +assertAsmLinkFail(module, null, {i:fun}); +Function.prototype.toString = origFunToString; +assertEq(asmLink(module, null, {i:fun})(), 0); +Function.prototype.valueOf = function() {} +assertAsmLinkFail(module, null, {i:fun}); +delete Function.prototype.valueOf; +assertEq(asmLink(module, null, {i:fun})(), 0); +var origObjValueOf = Object.prototype.valueOf; +Object.prototype.valueOf = function() {} +assertAsmLinkFail(module, null, {i:fun}); +Object.prototype.valueOf = origObjValueOf; +assertEq(asmLink(module, null, {i:fun})(), 0); +Object.prototype.toString = function() {} +assertEq(asmLink(module, null, {i:fun})(), 0); + +var f1 = asmCompile('global', 'foreign', 'heap', USE_ASM + 'var i32 = new global.Int32Array(heap); function g() { return i32[4]|0 } return g'); +var global = this; +var ab = new ArrayBuffer(4096); +var p = new Proxy(global, + {has:function(name) { f1(global, null, ab); return true}, + getOwnPropertyDescriptor:function(name) { return {configurable:true, value:Int32Array}}}); +new Int32Array(ab)[4] = 42; +assertEq(f1(p, null, ab)(), 42); + +// GVN checks +assertEq(asmLink(asmCompile(USE_ASM + "var g=0; function f() { var x = 0; g = 1; x = g; return (x+g)|0 } return f"))(), 2); +assertEq(asmLink(asmCompile(USE_ASM + "var g=0; function f() { var x = 0; g = 1; x = g; g = 2; return (x+g)|0 } return f"))(), 3); +assertEq(asmLink(asmCompile(USE_ASM + "var g=0; var h=0; function f() { var x = 0; g = 1; x = g; h = 3; return (x+g)|0 } return f"))(), 2); diff --git a/js/src/jit-test/tests/asm.js/testHeapAccess.js b/js/src/jit-test/tests/asm.js/testHeapAccess.js new file mode 100644 index 0000000000..6a7f7f5fa0 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testHeapAccess.js @@ -0,0 +1,511 @@ +load(libdir + "asm.js"); + +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[0>>2] = 4.0; return i32[0>>2]|0; } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[0>>2] = 4; return +f32[0>>2]; } return f'); + +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { var x=0,y=0; return i8[x+y]|0 } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { var x=0,y=0; return u8[x+y]|0 } return f'); + +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[0>>0]|0 }; return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[0>>1]|0 }; return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[0>>4]|0 }; return f'); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[0]|0 }; return f'), this, null, new ArrayBuffer(BUF_MIN))(), 0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0), 0); + +// In order to allow following tests work on both big-endian and little- +// endian architectures we need to define least significant byte (lsb) and +// least significant word (lsw). +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i8[0]|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +var lsb=0; +var lsw=0 +if (f(0x12345678) == 0x12) { + lsb=3; + lsw=1; +} + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i8[' + lsb + ']|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7f),0x7f); +assertEq(f(0xff),-1); +assertEq(f(0x100),0); + +{ + var buf = new ArrayBuffer(BUF_MIN); + var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + '/* not a clone */ function f(i) {i=i|0; i32[0] = i; return i8[' + lsb + ']|0}; return f'); + var f = asmLink(code, this, null, buf); + assertEq(f(0),0); + assertEq(f(0x7f),0x7f); + assertEq(f(0xff),-1); + assertEq(f(0x100),0); + + // Bug 1088655 + assertEq(asmLink(asmCompile('stdlib', 'foreign', 'heap', USE_ASM + 'var i32=new stdlib.Int32Array(heap); function f(i) {i=i|0;var j=0x10000;return (i32[j>>2] = i)|0 } return f'), this, null, buf)(1), 1); +} + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u8[' + lsb + ']|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7f),0x7f); +assertEq(f(0xff),0xff); +assertEq(f(0x100),0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i16[' + lsw + ']|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7fff),0x7fff); +assertEq(f(0xffff),-1); +assertEq(f(0x10000),0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u16[' + lsw + ']|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7fff),0x7fff); +assertEq(f(0xffff),0xffff); +assertEq(f(0x10000),0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i32[0]|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7fffffff),0x7fffffff); +assertEq(f(0xffffffff),-1); +assertEq(f(0x100000000),0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u32[0]|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7fffffff),0x7fffffff); +assertEq(f(0xffffffff),-1); +assertEq(f(0x100000000),0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i8[' + lsb + ']|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7f),0x7f); +assertEq(f(0xff),-1); +assertEq(f(0x100),0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u8[' + lsb + ']|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7f),0x7f); +assertEq(f(0xff),0xff); +assertEq(f(0x100),0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i8[0] = i; return i8[0]|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7f),0x7f); +assertEq(f(0xff),-1); +assertEq(f(0x100),0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i8[0] = i; return u8[0]|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0),0); +assertEq(f(0x7f),0x7f); +assertEq(f(0xff),0xff); +assertEq(f(0x100),0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return (~~+f64[i>>3])|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0, 1.3), 1); +assertEq(f(BUF_MIN-8, 2.5), 2); +assertEq(f(BUF_MIN, 3.8), 0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return (~~f64[i>>3])|0}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0, 1.3), 1); +assertEq(f(BUF_MIN-8, 2.5), 2); +assertEq(f(BUF_MIN, 3.8), 0); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return +f64[i>>3]}; return f'); +var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); +assertEq(f(0, 1.3), 1.3); +assertEq(f(BUF_MIN-8, 2.5), 2.5); +assertEq(f(BUF_MIN, 3.8), NaN); + +var i32 = new Int32Array(BUF_MIN); +i32[0] = 42; +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[1] = i32[0] }; return f'), this, null, i32.buffer)(); +assertEq(i32[1], 42); + +var f64 = new Float64Array(BUF_MIN); +f64[0] = 42; +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[1] = f64[0] }; return f'), this, null, f64.buffer)(); +assertEq(f64[1], 42); + +var i32 = new Int32Array(BUF_MIN/4); +i32[0] = 13; +i32[1] = 0xfffeeee; +var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return i32[((i<<2)+1)>>2]|0 }; return f'), this, null, i32.buffer); +assertEq(f(0), 13); +assertEq(f(1), 0xfffeeee); +var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return i32[((i<<2)+2)>>2]|0 }; return f'), this, null, i32.buffer); +assertEq(f(0), 13); +assertEq(f(1), 0xfffeeee); +var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return i32[(i<<1)>>2]|0 }; return f'), this, null, i32.buffer); +assertEq(f(0), 13); +assertEq(f(1), 13); +assertEq(f(2), 0xfffeeee); +assertEq(f(3), 0xfffeeee); + +var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return i32[(i<<2)>>2]|0 }; return f'), this, null, i32.buffer); +assertEq(f(0), 13); +assertEq(f(1), 0xfffeeee); + +var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return i32[((i<<2)+4)>>2]|0 }; return f'), this, null, i32.buffer); +assertEq(f(0), 0xfffeeee); + +// For legacy compatibility, test Int8/Uint8 accesses with no shift. +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[7&0xffff] = 41 } return f'), this, null, BUF_64KB)(); +assertEq(new Uint8Array(BUF_64KB)[7], 41); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[7&0xffff] = -41 } return f'), this, null, BUF_64KB)(); +assertEq(new Int8Array(BUF_64KB)[7], -41); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[(7&0xffff)>>0] = 41 } return f'), this, null, BUF_64KB)(); +assertEq(new Uint8Array(BUF_64KB)[7], 41); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[(7&0xffff)>>0] = -41 } return f'), this, null, BUF_64KB)(); +assertEq(new Int8Array(BUF_64KB)[7], -41); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[(6&0xffff)>>1] = 0xabc } return f'), this, null, BUF_64KB)(); +assertEq(new Uint16Array(BUF_64KB)[3], 0xabc); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[(6&0xffff)>>1] = -0xabc } return f'), this, null, BUF_64KB)(); +assertEq(new Int16Array(BUF_64KB)[3], -0xabc); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[(4&0xffff)>>2] = 0xabcde } return f'), this, null, BUF_64KB)(); +assertEq(new Uint32Array(BUF_64KB)[1], 0xabcde); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[(4&0xffff)>>2] = -0xabcde } return f'), this, null, BUF_64KB)(); +assertEq(new Int32Array(BUF_64KB)[1], -0xabcde); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[(4&0xffff)>>2] = 1.0 } return f'), this, null, BUF_64KB)(); +assertEq(new Float32Array(BUF_64KB)[1], 1.0); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[(8&0xffff)>>3] = 1.3 } return f'), this, null, BUF_64KB)(); +assertEq(new Float64Array(BUF_64KB)[1], 1.3); + +new Float32Array(BUF_64KB)[1] = 1.0; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[(4&0xffff)>>2] } return f'), this, null, BUF_64KB)(), 1.0); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'var toFloat32 = glob.Math.fround; function f() { return toFloat32(f32[(4&0xffff)>>2]) } return f'), this, null, BUF_64KB)(), 1.0); +new Float64Array(BUF_64KB)[1] = 1.3; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[(8&0xffff)>>3] } return f'), this, null, BUF_64KB)(), 1.3); + +asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u8[255]; u8[i] } return f'); +// For legacy compatibility, test Int8/Uint8 accesses with no shift. +asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u8[i&0xff]; u8[255] } return f'); +asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u8[(i&0xff)>>0]; u8[255] } return f'); +asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u32[63]; u32[i>>2] } return f'); +asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u32[i>>2]; u32[63] } return f'); + +var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u32[64] } return f'); +asmLink(code, this, null, new ArrayBuffer(BUF_MIN)); + +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u32[12] = i } return f'), this, null, BUF_64KB)(11); +assertEq(new Int32Array(BUF_64KB)[12], 11); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[12]|0 } return f'), this, null, BUF_64KB)(), 11); +new Float64Array(BUF_64KB)[0] = 3.5; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +-f64[0] } return f'), this, null, BUF_64KB)(), -3.5); + +// Test constant loads. +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[1] = -1 } return f'), this, null, buf)(); +assertEq(new Uint8Array(buf)[0], 0); +assertEq(new Uint8Array(buf)[1], 255); +assertEq(new Uint8Array(buf)[2], 0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[4095] = -1 } return f'), this, null, buf)(); +assertEq(new Uint8Array(buf)[4094], 0); +assertEq(new Uint8Array(buf)[4095], 255); +assertEq(new Uint8Array(buf)[4096], 0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[4096] = -1 } return f'), this, null, buf)(); +assertEq(new Uint8Array(buf)[4095], 0); +assertEq(new Uint8Array(buf)[4096], 255); +assertEq(new Uint8Array(buf)[4097], 0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[' + BUF_MIN + '] = -1 } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[258048] = -1 } return f'), this, null, buf)(); +assertEq(new Uint8Array(buf)[258047], 0); +assertEq(new Uint8Array(buf)[258048], 255); +assertEq(new Uint8Array(buf)[258049], 0); + +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[1] = -1 } return f'), this, null, buf)(); +assertEq(new Int8Array(buf)[0], 0); +assertEq(new Int8Array(buf)[1], -1); +assertEq(new Int8Array(buf)[2], 0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[4095] = -1 } return f'), this, null, buf)(); +assertEq(new Int8Array(buf)[4094], 0); +assertEq(new Int8Array(buf)[4095], -1); +assertEq(new Int8Array(buf)[4096], 0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[4096] = -1 } return f'), this, null, buf)(); +assertEq(new Int8Array(buf)[4095], 0); +assertEq(new Int8Array(buf)[4096], -1); +assertEq(new Int8Array(buf)[4097], 0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[' + BUF_MIN + '] = -1 } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[258048] = -1 } return f'), this, null, buf)(); +assertEq(new Int8Array(buf)[258047], 0); +assertEq(new Int8Array(buf)[258048], -1); +assertEq(new Int8Array(buf)[258049], 0); + +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[1] = -1 } return f'), this, null, buf)(); +assertEq(new Uint16Array(buf)[0], 0); +assertEq(new Uint16Array(buf)[1], 65535); +assertEq(new Uint16Array(buf)[2], 0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[' + (BUF_MIN/2-1) + '] = -1 } return f'), this, null, buf)(); +assertEq(new Uint16Array(buf)[BUF_MIN/2-2], 0); +assertEq(new Uint16Array(buf)[BUF_MIN/2-1], 65535); +assertEq(new Uint16Array(buf)[BUF_MIN/2], undefined); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[' + (BUF_MIN/4) + '] = -1 } return f'), this, null, buf)(); +assertEq(new Uint16Array(buf)[BUF_MIN/4-1], 0); +assertEq(new Uint16Array(buf)[BUF_MIN/4], 65535); +assertEq(new Uint16Array(buf)[BUF_MIN/4+1], 0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[' + (BUF_MIN/2) + '] = -1 } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[126976] = -1 } return f'), this, null, buf)(); +assertEq(new Uint16Array(buf)[126975], 0); +assertEq(new Uint16Array(buf)[126976], 65535); +assertEq(new Uint16Array(buf)[126977], 0); + +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[1] = -1 } return f'), this, null, buf)(); +assertEq(new Int16Array(buf)[0], 0); +assertEq(new Int16Array(buf)[1], -1); +assertEq(new Int16Array(buf)[2], 0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[' + (BUF_MIN/2-1) + '] = -1 } return f'), this, null, buf)(); +assertEq(new Int16Array(buf)[BUF_MIN/2-2], 0); +assertEq(new Int16Array(buf)[BUF_MIN/2-1], -1); +assertEq(new Int16Array(buf)[BUF_MIN/2], undefined); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[' + (BUF_MIN/4) + '] = -1 } return f'), this, null, buf)(); +assertEq(new Int16Array(buf)[BUF_MIN/4-1], 0); +assertEq(new Int16Array(buf)[BUF_MIN/4], -1); +assertEq(new Int16Array(buf)[BUF_MIN/4+1], 0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[' + (BUF_MIN/2) + '] = -1 } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[126976] = -1 } return f'), this, null, buf)(); +assertEq(new Int16Array(buf)[126975], 0); +assertEq(new Int16Array(buf)[126976], -1); +assertEq(new Int16Array(buf)[126977], 0); + +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[1] = -1 } return f'), this, null, buf)(); +assertEq(new Uint32Array(buf)[0], 0); +assertEq(new Uint32Array(buf)[1], 4294967295); +assertEq(new Uint32Array(buf)[2], 0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[' + (BUF_MIN/4-1) + '] = -1 } return f'), this, null, buf)(); +assertEq(new Uint32Array(buf)[BUF_MIN/4-2], 0); +assertEq(new Uint32Array(buf)[BUF_MIN/4-1], 4294967295); +assertEq(new Uint32Array(buf)[BUF_MIN/4], undefined); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[' + (BUF_MIN/8) + '] = -1 } return f'), this, null, buf)(); +assertEq(new Uint32Array(buf)[BUF_MIN/8-1], 0); +assertEq(new Uint32Array(buf)[BUF_MIN/8], 4294967295); +assertEq(new Uint32Array(buf)[BUF_MIN/8+1], 0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[' + (BUF_MIN/4) + '] = -1 } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[61440] = -1 } return f'), this, null, buf)(); +assertEq(new Uint32Array(buf)[61439], 0); +assertEq(new Uint32Array(buf)[61440], 4294967295); +assertEq(new Uint32Array(buf)[61441], 0); + +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[1] = -1 } return f'), this, null, buf)(); +assertEq(new Int32Array(buf)[0], 0); +assertEq(new Int32Array(buf)[1], -1); +assertEq(new Int32Array(buf)[2], 0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[' + (BUF_MIN/4-1) + '] = -1 } return f'), this, null, buf)(); +assertEq(new Int32Array(buf)[BUF_MIN/4-2], 0); +assertEq(new Int32Array(buf)[BUF_MIN/4-1], -1); +assertEq(new Int32Array(buf)[BUF_MIN/4], undefined); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[' + (BUF_MIN/8) + '] = -1 } return f'), this, null, buf)(); +assertEq(new Int32Array(buf)[BUF_MIN/8-1], 0); +assertEq(new Int32Array(buf)[BUF_MIN/8], -1); +assertEq(new Int32Array(buf)[BUF_MIN/8+1], 0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[' + (BUF_MIN/4) + '] = -1 } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[61440] = -1 } return f'), this, null, buf)(); +assertEq(new Int32Array(buf)[61439], 0); +assertEq(new Int32Array(buf)[61440], -1); +assertEq(new Int32Array(buf)[61441], 0); + +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[1] = -1.0 } return f'), this, null, buf)(); +assertEq(new Int32Array(buf)[0], 0); +assertEq(new Float32Array(buf)[1], -1.0); +assertEq(new Int32Array(buf)[2], 0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[' + (BUF_MIN/4-1) + '] = -1.0 } return f'), this, null, buf)(); +assertEq(new Int32Array(buf)[BUF_MIN/4-2], 0); +assertEq(new Float32Array(buf)[BUF_MIN/4-1], -1.0); +assertEq(new Int32Array(buf)[BUF_MIN/4], undefined); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[' + (BUF_MIN/8) + '] = -1.0 } return f'), this, null, buf)(); +assertEq(new Int32Array(buf)[BUF_MIN/8-1], 0); +assertEq(new Float32Array(buf)[BUF_MIN/8], -1.0); +assertEq(new Int32Array(buf)[BUF_MIN/8+1], 0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[' + (BUF_MIN/4) + '] = -1.0 } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[61440] = -1.0 } return f'), this, null, buf)(); +assertEq(new Float32Array(buf)[61439], 0.0); +assertEq(new Float32Array(buf)[61440], -1.0); +assertEq(new Float32Array(buf)[61441], 0.0); + +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[1] = -1.0 } return f'), this, null, buf)(); +assertEq(new Float64Array(buf)[0], 0.0); +assertEq(new Float64Array(buf)[1], -1.0); +assertEq(new Float64Array(buf)[2], 0.0); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[' + (BUF_MIN/8-1) + '] = -1.0 } return f'), this, null, buf)(); +assertEq(new Float64Array(buf)[BUF_MIN/8-2], 0.0); +assertEq(new Float64Array(buf)[BUF_MIN/8-1], -1.0); +assertEq(new Float64Array(buf)[BUF_MIN/8], undefined); +var buf = new ArrayBuffer(BUF_MIN); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[' + (BUF_MIN/16) + '] = -1.0 } return f'), this, null, buf)(); +assertEq(new Float64Array(buf)[BUF_MIN/16-1], 0.0); +assertEq(new Float64Array(buf)[BUF_MIN/16], -1.0); +assertEq(new Float64Array(buf)[BUF_MIN/16+1], 0.0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[' + (BUF_MIN/8) + '] = -1.0 } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[28672] = -1.0 } return f'), this, null, buf)(); +assertEq(new Float64Array(buf)[28671], 0.0); +assertEq(new Float64Array(buf)[28672], -1.0); +assertEq(new Float64Array(buf)[28673], 0.0); + + +var buf = new ArrayBuffer(BUF_MIN); +new Uint8Array(buf)[1] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[1]|0; } return f'), this, null, buf)(),255); +new Int8Array(buf)[1] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i8[1]|0; } return f'), this, null, buf)(),-1); +var buf = new ArrayBuffer(262144); +new Uint8Array(buf)[126976] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[126976]|0; } return f'), this, null, buf)(),255); +new Int8Array(buf)[126976] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i8[126976]|0; } return f'), this, null, buf)(),-1); + +var buf = new ArrayBuffer(BUF_MIN); +new Uint16Array(buf)[1] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u16[1]|0; } return f'), this, null, buf)(),65535); +new Int16Array(buf)[1] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i16[1]|0; } return f'), this, null, buf)(),-1); +var buf = new ArrayBuffer(262144); +new Uint16Array(buf)[126976] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u16[126976]|0; } return f'), this, null, buf)(),65535); +new Int16Array(buf)[126976] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i16[126976]|0; } return f'), this, null, buf)(),-1); + +var buf = new ArrayBuffer(BUF_MIN); +new Uint32Array(buf)[1] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[1]|0; } return f'), this, null, buf)(),-1); +new Int32Array(buf)[1] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[1]|0; } return f'), this, null, buf)(),-1); +var buf = new ArrayBuffer(262144); +new Int32Array(buf)[61440] = -1; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[61440]|0; } return f'), this, null, buf)(),-1); + +var buf = new ArrayBuffer(BUF_MIN); +new Float32Array(buf)[1] = -1.0; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[1]; } return f'), this, null, buf)(),-1.0); +new Float32Array(buf)[BUF_MIN/4-1] = -1.0; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[' + (BUF_MIN/4-1) + ']; } return f'), this, null, buf)(),-1.0); +new Float32Array(buf)[BUF_MIN/8] = -1.0; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[' + (BUF_MIN/8) + ']; } return f'), this, null, buf)(),-1.0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[' + (BUF_MIN/4) + ']; } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +new Float32Array(buf)[61440] = -1.0; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[61440]; } return f'), this, null, buf)(),-1.0); + +var buf = new ArrayBuffer(BUF_MIN); +new Float64Array(buf)[1] = -1.0; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[1]; } return f'), this, null, buf)(),-1.0); +new Float64Array(buf)[BUF_MIN/8-1] = -1.0; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[' + (BUF_MIN/8-1) + ']; } return f'), this, null, buf)(),-1.0); +new Float64Array(buf)[BUF_MIN/16] = -1.0; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[' + (BUF_MIN/16) + ']; } return f'), this, null, buf)(),-1.0); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[' + (BUF_MIN/8) + ']; } return f'), this, null, buf); +var buf = new ArrayBuffer(262144); +new Float64Array(buf)[28672] = -1.0; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[28672]; } return f'), this, null, buf)(),-1.0); + +// Bug 913867 +var buf = new ArrayBuffer(BUF_MIN); +new Int32Array(buf)[0] = 0x55aa5a5a; +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f1() { i32[0] = 1; return 8; }; function f() { return i32[((f1()|0)&0)>>2]|0; } return f'), this, null, buf)(),1); +assertEq(new Int32Array(buf)[0], 1); + +// Bug 882012 +assertEq(asmLink(asmCompile('stdlib', 'foreign', 'heap', USE_ASM + "var id=foreign.id;var doubles=new stdlib.Float64Array(heap);function g(){doubles[0]=+id(2.0);return +doubles[0];}return g"), this, {id: function(x){return x;}}, BUF_64KB)(), 2.0); + +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[4294967295]|0; } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=4294967295; function f() { return u8[i]|0; } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[-1]|0; } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=-1; function f() { return u8[i]|0; } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x80000000]|0; } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=0x80000000; function f() { return u8[i]|0; } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[-2147483648]|0; } return f'); +assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=-2147483648; function f() { return u8[i]|0; } return f'); + +// GVN checks +var buf = new ArrayBuffer(BUF_MIN); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'var i=0; function f() { var x = 0, y = 0; u8[0] = 1; u8[1] = 2; x = 0|u8[i]; i = x; y = 0|u8[i]; return y|0;} return f'), this, null, buf)(),2); +assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'var i=0; function f() { var x = 0, y = 0; u8[0] = 1; u8[1] = 2; x = 0|u8[i]; y = 0|u8[i]; return (x+y)|0;} return f'), this, null, buf)(),2); + +// Heap length constraints +var m = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'); +assertAsmLinkAlwaysFail(m, this, null, new ArrayBuffer(0xffff)); +assertEq(asmLink(m, this, null, new ArrayBuffer(0x10000))(0),0); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0x10010)); +assertEq(asmLink(m, this, null, new ArrayBuffer(0x20000))(0),0); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0xfe0000)); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0xfe0010)); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0xfe0000)); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0xff8000)); +var buf = new ArrayBuffer(0x100000); +new Uint8Array(buf)[0x4242] = 0xAA; +var f = asmLink(m, this, null, buf); +assertEq(f(0),0); +assertEq(f(0x4242),0xAA); +assertEq(f(0x100000),0); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0x104000)); +assertEq(asmLink(m, this, null, new ArrayBuffer(0x200000))(0),0); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0x3f8000)); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0x3fe000)); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0x3fc000)); +assertEq(asmLink(m, this, null, new ArrayBuffer(0x400000))(0),0); +assertAsmLinkFail(m, this, null, new ArrayBuffer(0x410000)); +assertEq(asmLink(m, this, null, new ArrayBuffer(0x800000))(0),0); +var buf = new ArrayBuffer(0x1000000); +new Uint8Array(buf)[0x424242] = 0xAA; +var f = asmLink(m, this, null, buf); +assertEq(f(0),0); +assertEq(f(0x424242),0xAA); +assertEq(f(0x1000000),0); +assertEq(asmLink(m, this, null, new ArrayBuffer(0x2000000))(0),0); +assertEq(asmLink(m, this, null, new ArrayBuffer(0x3000000))(0),0); + +// Heap offsets +var asmMod = function test (glob, env, b) { + 'use asm'; + var i8 = new glob.Int8Array(b); + function f(i) { + i = i | 0; + i = i & 1; + i = (i - 0x40000)|0; + i8[0x3ffff] = 0; + return i8[(i + 0x7fffe) >> 0] | 0; + } + return f; +}; +var buffer = new ArrayBuffer(0x40000); +var asm = asmMod(this, {}, buffer); +assertEq(asm(-1),0); diff --git a/js/src/jit-test/tests/asm.js/testJumpRange.js b/js/src/jit-test/tests/asm.js/testJumpRange.js new file mode 100644 index 0000000000..10e37752de --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testJumpRange.js @@ -0,0 +1,26 @@ +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +var fatFunc = USE_ASM + '\n'; +for (var i = 0; i < 100; i++) + fatFunc += "function f" + i + "() { return ((f" + (i+1) + "()|0)+1)|0 }\n"; +fatFunc += "function f100() { return 42 }\n"; +fatFunc += "return f0"; + +for (let threshold of [0, 50, 100, 5000, -1]) { + setJitCompilerOption("jump-threshold", threshold); + + assertEq(asmCompile( + USE_ASM + ` + function h() { return ((g()|0)+2)|0 } + function g() { return ((f()|0)+1)|0 } + function f() { return 42 } + return h + `)()(), 45); + + enableGeckoProfiling(); + asmLink(asmCompile(USE_ASM + 'function f() {} function g() { f() } function h() { g() } return h'))(); + disableGeckoProfiling(); + + assertEq(asmCompile(fatFunc)()(), 142); +} diff --git a/js/src/jit-test/tests/asm.js/testLargeHeap.js b/js/src/jit-test/tests/asm.js/testLargeHeap.js new file mode 100644 index 0000000000..6ae545115d --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testLargeHeap.js @@ -0,0 +1,9 @@ +// |jit-test| skip-if: !largeArrayBufferSupported() + +load(libdir + "asm.js"); + +// This is a validly structured length but it is too large for our asm.js +// implementation: for the sake of simplicity, we draw the line at 7fff_ffff (ie +// really at 7f00_0000 given constraints on the format of the address). +var buf = new ArrayBuffer(0x8000_0000); +assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[' + BUF_MIN + '] = -1 } return f'), this, null, buf); diff --git a/js/src/jit-test/tests/asm.js/testLinkErrorAssert.js b/js/src/jit-test/tests/asm.js/testLinkErrorAssert.js new file mode 100644 index 0000000000..9084d72a26 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testLinkErrorAssert.js @@ -0,0 +1,20 @@ +// This test should not assert. + +function asmModule(g, foreign, heap) { + "use asm"; + let HEAP8 = new g.Int8Array(heap); + + function f() { return 99; } + return {f: f}; +} + +// linking error +let m = asmModule(this, 2, new ArrayBuffer(4095)); + +print(m.f()); + +// linking error +let m2 = asmModule(this, 2, new ArrayBuffer(2048)); + +print(m2.f()); + diff --git a/js/src/jit-test/tests/asm.js/testLiterals.js b/js/src/jit-test/tests/asm.js/testLiterals.js new file mode 100644 index 0000000000..1a24002af3 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testLiterals.js @@ -0,0 +1,50 @@ +load(libdir + 'asm.js'); + +assertAsmTypeFail(USE_ASM + 'function f(d) { d=+d; var e=0; e=d; return +e } return f'); +assertAsmTypeFail(USE_ASM + 'function f(d) { d=+d; var e=1e1; e=d; return +e } return f'); +assertAsmTypeFail(USE_ASM + 'function f(d) { d=+d; var e=+0; e=d; return +e } return f'); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { var e=-0; return +e } return f'))(-0), -0); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { var e=-0.0; return +e } return f'))(-0), -0); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(d) { d=+d; var e=0.0; e=d; return +e } return f'))(0.1), 0.1); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(d) { d=+d; var e=-0.0; e=d; return +e } return f'))(0.1), 0.1); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(d) { d=+d; var e=10.0; e=d; return +e } return f'))(0.1), 0.1); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(d) { d=+d; var e=-10.0; e=d; return +e } return f'))(0.1), 0.1); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(d) { d=+d; var e=1.0e2; e=d; return +e } return f'))(0.1), 0.1); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(d) { d=+d; var e=-1.0e2; e=d; return +e } return f'))(0.1), 0.1); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(d) { d=+d; var e=1.0e0; e=d; return +e } return f'))(0.1), 0.1); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(d) { d=+d; var e=-1.0e0; e=d; return +e } return f'))(0.1), 0.1); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { return 0.0 } function g() { var d=0.1; d=+f(); return +d } return g'))(), 0); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { return -0.0 } function g() { var d=0.1; d=+f(); return +d } return g'))(), -0); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { return 10.0 } function g() { var d=0.1; d=+f(); return +d } return g'))(), 10); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { return -10.0 } function g() { var d=0.1; d=+f(); return +d } return g'))(), -10.0); + +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=1e10; j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=9007199254740991e0; j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=9007199254740992e0; j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=9007199254740993e0; j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=-9007199254740991e0; j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=-9007199254740992e0; j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=-9007199254740993e0; j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=1e100; j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=1e10000; j=i; return j|0 } return f"); +assertAsmTypeFail(USE_ASM + "function f(i) { i=i|0; var j=1000000000000000000; j=i; return j|0 } return f"); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; var j=1e0; j=i; return j|0 } return f"))(42), 42); +assertEq(asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; var j=1e9; j=i; return j|0 } return f"))(42), 42); + +assertAsmTypeFail(USE_ASM + 'function f() { var i=-2147483649; return i|0 } return f'); +assertAsmTypeFail(USE_ASM + 'function f() { var i=4294967296; return i|0 } return f'); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { var i=-2147483648; return i|0 } return f'))(), -2147483648); +assertEq(asmLink(asmCompile(USE_ASM + 'function f() { var i=4294967295; return i|0 } return f'))(), 4294967295|0); +assertAsmTypeFail(USE_ASM + 'function f(i) { i=i|0; return (i+-2147483649)|0 } return f'); +assertAsmTypeFail(USE_ASM + 'function f(i) { i=i|0; return (i+4294967296)|0 } return f'); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(i) { i=i|0; return (i+-2147483648)|0 } return f'))(0), -2147483648); +assertEq(asmLink(asmCompile(USE_ASM + 'function f(i) { i=i|0; return (i+4294967295)|0 } return f'))(0), 4294967295|0); + +assertAsmTypeFail(USE_ASM + 'var i=-2147483649; function f() { return i|0 } return f'); +assertAsmTypeFail(USE_ASM + 'const i=-2147483649; function f() { return i|0 } return f'); +assertAsmTypeFail(USE_ASM + 'var i=4294967296; function f() { return i|0 } return f'); +assertAsmTypeFail(USE_ASM + 'const i=4294967296; function f() { return i|0 } return f'); +assertEq(asmLink(asmCompile(USE_ASM + 'var i=-2147483648; function f() { return i|0 } return f'))(), -2147483648); +assertEq(asmLink(asmCompile(USE_ASM + 'const i=-2147483648; function f() { return i|0 } return f'))(), -2147483648); +assertEq(asmLink(asmCompile(USE_ASM + 'var i=4294967295; function f() { return i|0 } return f'))(), 4294967295|0); +assertEq(asmLink(asmCompile(USE_ASM + 'const i=4294967295; function f() { return i|0 } return f'))(), 4294967295|0); diff --git a/js/src/jit-test/tests/asm.js/testMathLib.js b/js/src/jit-test/tests/asm.js/testMathLib.js new file mode 100644 index 0000000000..5c2eb9db46 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testMathLib.js @@ -0,0 +1,189 @@ +load(libdir + "asm.js"); + +function testUnary(f, g) { + var numbers = [NaN, Infinity, -Infinity, -10000, -3.4, -0, 0, 3.4, 10000]; + for (n of numbers) + assertEq(f(n), g(n)); +} + +const FROUND = 'var fround=glob.Math.fround;'; + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sin; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sin:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sin; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sin:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sin; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sin:Math.sin}}), Math.sin); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'const sq=glob.Math.sin; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sin:Math.sin}}), Math.sin); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var co=glob.Math.cos; function f(d) { d=+d; return +co(d) } return f'), {Math:{cos:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var co=glob.Math.cos; function f(d) { d=+d; return +co(d) } return f'), {Math:{cos:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var co=glob.Math.cos; function f(d) { d=+d; return +co(d) } return f'), {Math:{cos:Math.cos}}), Math.cos); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ta=glob.Math.tan; function f(d) { d=+d; return +ta(d) } return f'), {Math:{tan:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ta=glob.Math.tan; function f(d) { d=+d; return +ta(d) } return f'), {Math:{tan:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var ta=glob.Math.tan; function f(d) { d=+d; return +ta(d) } return f'), {Math:{tan:Math.tan}}), Math.tan); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var as=glob.Math.asin; function f(d) { d=+d; return +as(d) } return f'), {Math:{asin:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var as=glob.Math.asin; function f(d) { d=+d; return +as(d) } return f'), {Math:{asin:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var as=glob.Math.asin; function f(d) { d=+d; return +as(d) } return f'), {Math:{asin:Math.asin}}), Math.asin); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ac=glob.Math.acos; function f(d) { d=+d; return +ac(d) } return f'), {Math:{acos:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ac=glob.Math.acos; function f(d) { d=+d; return +ac(d) } return f'), {Math:{acos:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var ac=glob.Math.acos; function f(d) { d=+d; return +ac(d) } return f'), {Math:{acos:Math.acos}}), Math.acos); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan; function f(d) { d=+d; return +at(d) } return f'), {Math:{atan:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan; function f(d) { d=+d; return +at(d) } return f'), {Math:{atan:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan; function f(d) { d=+d; return +at(d) } return f'), {Math:{atan:Math.atan}}), Math.atan); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ce=glob.Math.ceil; function f(d) { d=+d; return +ce(d) } return f'), {Math:{ceil:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ce=glob.Math.ceil; function f(d) { d=+d; return +ce(d) } return f'), {Math:{ceil:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var ce=glob.Math.ceil; function f(d) { d=+d; return +ce(d) } return f'), {Math:{ceil:Math.ceil}}), Math.ceil); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var fl=glob.Math.floor; function f(d) { d=+d; return +fl(d) } return f'), {Math:{floor:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var fl=glob.Math.floor; function f(d) { d=+d; return +fl(d) } return f'), {Math:{floor:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var fl=glob.Math.floor; function f(d) { d=+d; return +fl(d) } return f'), {Math:{floor:Math.floor}}), Math.floor); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var exq=glob.Math.exp; function f(d) { d=+d; return +exq(d) } return f'), {Math:{exp:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var exq=glob.Math.exp; function f(d) { d=+d; return +exq(d) } return f'), {Math:{exp:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var exq=glob.Math.exp; function f(d) { d=+d; return +exq(d) } return f'), {Math:{exp:Math.exp}}), Math.exp); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var lo=glob.Math.log; function f(d) { d=+d; return +lo(d) } return f'), {Math:{log:Math.sqrt}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var lo=glob.Math.log; function f(d) { d=+d; return +lo(d) } return f'), {Math:{log:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var lo=glob.Math.log; function f(d) { d=+d; return +lo(d) } return f'), {Math:{log:Math.log}}), Math.log); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sqrt; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sqrt:Math.sin}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sqrt; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sqrt:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sqrt; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sqrt:Math.sqrt}}), Math.sqrt); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; return +abs(d) } return f'), {Math:{abs:Math.sin}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; return +abs(d) } return f'), {Math:{abs:null}}); +testUnary(asmLink(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; return +abs(d) } return f'), {Math:{abs:Math.abs}}), Math.abs); + +var f = asmLink(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(i) { i=i|0; return abs(i|0)|0 } return f'), this); +for (n of [-Math.pow(2,31)-1, -Math.pow(2,31), -Math.pow(2,31)+1, -1, 0, 1, Math.pow(2,31)-2, Math.pow(2,31)-1, Math.pow(2,31)]) + assertEq(f(n), Math.abs(n|0)|0); + +var f = asmLink(asmCompile('glob', USE_ASM + 'var clz32=glob.Math.clz32; function f(i) { i=i|0; return clz32(i)|0 } return f'), this); +for (n of [0, 1, 2, 15, 16, Math.pow(2,31)-1, Math.pow(2,31), Math.pow(2,31)+1, Math.pow(2,32)-1, Math.pow(2,32), Math.pow(2,32)+1]) + assertEq(f(n), Math.clz32(n|0)); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var clz32=glob.Math.clz32; function f(i, j) { i=i|0;j=j|0; return (clz32(i) < (j|0))|0 } return f'), this)(0x1, 30), 0); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var clz32=glob.Math.clz32; function f(i, j) { i=i|0;j=j|0; return (clz32(i) < (j>>>0))|0 } return f'), this)(0x1, 30), 0); + +var doubleNumbers = [NaN, Infinity, -Infinity, -10000, -3.4, -0, 0, 3.4, 10000]; +var floatNumbers = []; +for (var x of doubleNumbers) floatNumbers.push(Math.fround(x)); +var intNumbers = [-Math.pow(2,31), -10000, -3, -1, 0, 3, 10000, Math.pow(2,31), Math.pow(2,31)+1]; + +function testBinary(f, g, numbers) { + for (n of numbers) + for (o of numbers) + assertEq(f(n,o), g(n,o)); +} + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var po=glob.Math.pow; function f(d,e) { d=+d;e=+e; return +po(d,e) } return f'), {Math:{pow:Math.sin}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var po=glob.Math.pow; function f(d,e) { d=+d;e=+e; return +po(d,e) } return f'), {Math:{pow:null}}); +testBinary(asmLink(asmCompile('glob', USE_ASM + 'var po=glob.Math.pow; function f(d,e) { d=+d;e=+e; return +po(d,e) } return f'), {Math:{pow:Math.pow}}), Math.pow, doubleNumbers); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan2; function f(d,e) { d=+d;e=+e; return +at(d,e) } return f'), {Math:{atan2:Math.sin}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan2; function f(d,e) { d=+d;e=+e; return +at(d,e) } return f'), {Math:{atan2:null}}); +testBinary(asmLink(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan2; function f(d,e) { d=+d;e=+e; return +at(d,e) } return f'), {Math:{atan2:Math.atan2}}), Math.atan2, doubleNumbers); + +function coercedMin(...args) { for (var i = 0; i < args.length; i++) args[i] = args[i]|0; return Math.min(...args) } +function coercedMax(...args) { for (var i = 0; i < args.length; i++) args[i] = args[i]|0; return Math.max(...args) } +assertAsmTypeFail('glob', USE_ASM + 'var min=glob.Math.min; function f(d) { d=+d; return +min(d) } return f'); +assertAsmTypeFail('glob', 'ffi', 'heap', USE_ASM + 'var i32=new glob.Int32Array(heap); var min=glob.Math.min; function f() { return min(i32[0], 5)|0 } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var min=glob.Math.min; function f(x) { x=x|0; return min(3 + x, 5)|0 } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var min=glob.Math.min; function f(x) { x=x|0; return min(5, 3 + x)|0 } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var min=glob.Math.min; function f(x) { x=x|0; return min(x, 1)|0 } return f'); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(d,e) { d=+d;e=+e; return +min(d,e) } return f'), {Math:{min:Math.sin}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(d,e) { d=+d;e=+e; return +min(d,e) } return f'), {Math:{min:null}}); +testBinary(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(d,e) { d=+d;e=+e; return +min(d,e) } return f'), {Math:{min:Math.min}}), Math.min, doubleNumbers); +testBinary(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; var f32=glob.Math.fround; function f(d,e) { d=f32(d);e=f32(e); return f32(min(d,e)) } return f'), this), Math.min, floatNumbers); +testBinary(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(d,e) { d=d|0;e=e|0; return min(d|0,e|0)|0} return f'), {Math:{min:Math.min}}), coercedMin, intNumbers); + +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; function f(d,e) { d=+d;e=+e; return +max(d,e) } return f'), {Math:{max:Math.sin}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; function f(d,e) { d=+d;e=+e; return +max(d,e) } return f'), {Math:{max:null}}); +testBinary(asmLink(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; function f(d,e) { d=+d;e=+e; return +max(d,e) } return f'), {Math:{max:Math.max}}), Math.max, doubleNumbers); +testBinary(asmLink(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; var f32=glob.Math.fround; function f(d,e) { d=f32(d);e=f32(e); return f32(max(d,e)) } return f'), this), Math.max, floatNumbers); +testBinary(asmLink(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; function f(d,e) { d=d|0;e=e|0; return max(d|0,e|0)|0} return f'), {Math:{max:Math.max}}), coercedMax, intNumbers); + +function testTernary(f, g, numbers) { + for (n of numbers) + for (o of numbers) + for (p of numbers) + assertEq(f(n,o,p), g(n,o,p)); +} + +assertAsmTypeFail('glob', USE_ASM + 'var min=glob.Math.min; function f(d,e,g) { d=+d;e=+e;g=g|0; return +min(d,e,g) } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var max=glob.Math.max; function f(d,e,g) { d=d|0;e=e|0;g=+g; return max(d,e,g)|0 } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var min=glob.Math.min; function f(d,e,g) { d=+d;e=+e;g=+g; return min(d,e,g)|0 } return f'); +testTernary(asmLink(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; function f(d,e,g) { d=d|0;e=e|0;g=g|0; return +max(d|0,e|0,g|0) } return f'), {Math:{max:Math.max}}), coercedMax, intNumbers); +testTernary(asmLink(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; function f(d,e,g) { d=d|0;e=e|0;g=g|0; return max(d|0,e|0,g|0)|0 } return f'), {Math:{max:Math.max}}), coercedMax, intNumbers); +testTernary(asmLink(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; function f(d,e,g) { d=+d;e=+e;g=+g; return +max(d,e,g) } return f'), {Math:{max:Math.max}}), Math.max, doubleNumbers); +testTernary(asmLink(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; var _=glob.Math.fround; function f(d,e,g) { d=_(d);e=_(e);g=_(g); return _(max(d,e,g)) } return f'), this), Math.max, floatNumbers); +testTernary(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(d,e,g) { d=d|0;e=e|0;g=g|0; return min(d|0,e|0,g|0)|0 } return f'), {Math:{min:Math.min}}), coercedMin, intNumbers); +testTernary(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(d,e,g) { d=+d;e=+e;g=+g; return +min(d,e,g) } return f'), {Math:{min:Math.min}}), Math.min, doubleNumbers); +testTernary(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; var _=glob.Math.fround; function f(d,e,g) { d=_(d);e=_(e);g=_(g); return _(min(d,e,g)) } return f'), this), Math.min, floatNumbers); + +// Implicit return coercions of math functions +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i) { i=i|0; i = im(i,i); return i|0 } return f'), this)(3), 9); +assertAsmTypeFail('glob', USE_ASM + 'var im=glob.Math.imul; function f(d) { d=+d; d = im(d, d) } return f'); +assertAsmTypeFail('glob', USE_ASM + FROUND + 'var im=glob.Math.imul; function f(d) { d=fround(d); d = im(d, d) } return f'); + +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=d|0; d = abs(d|0); return +(d>>>0) } return f'), this)(-1), 1); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=d|0; var m = 0; m = (-1)>>>0; return (abs(d|0) < (m>>>0))|0 } return f'), this)(42), 1); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; d = abs(d); return +d } return f'), this)(-1.5), 1.5); +assertEq(asmLink(asmCompile('glob', USE_ASM + FROUND + 'var abs=glob.Math.abs; function f(d) { d=fround(d); d = fround(abs(d)); return +d } return f'), this)(-1.5), 1.5); +assertAsmTypeFail('glob', USE_ASM + FROUND + 'var abs=glob.Math.abs; function f(d) { d=fround(d); d = abs(d); return +d } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=d|0; var m = 0; m = -1; return (abs(d|0) < (m|0))|0 } return f'); + +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var sqrt=glob.Math.sqrt; function f(d) { d=+d; d = sqrt(d); return +d } return f'), this)(256), 16); +assertEq(asmLink(asmCompile('glob', USE_ASM + FROUND + 'var sqrt=glob.Math.sqrt; function f(d) { d=fround(d); d = fround(sqrt(d)); return +d } return f'), this)(13.37), Math.fround(Math.sqrt(Math.fround(13.37)))); +assertAsmTypeFail('glob', USE_ASM + FROUND + 'var sqrt=glob.Math.sqrt; function f(d) { d=fround(d); d = sqrt(d); return fround(d) } return f'); +assertAsmTypeFail('glob', USE_ASM + FROUND + 'var sqrt=glob.Math.sqrt; function f(d) { d=fround(d); d = sqrt(d); return d } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var sqrt=glob.Math.sqrt; function f(n) { n=n|0; var d=0.; d = sqrt(n|0) } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var sqrt=glob.Math.sqrt; function f(n) { n=n|0; var d=3.; n = sqrt(d)|0 } return f'); + +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(d) { d=+d; d = min(d, 13.); return +d } return f'), this)(12), 12); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(d) { d=d|0; d = min(d|0, 11); return d|0 } return f'), this)(12), 11); +assertEq(asmLink(asmCompile('glob', USE_ASM + FROUND + 'var min=glob.Math.min; function f(d) { d=fround(d); d = min(d, fround(13.37)); return fround(d) } return f'), this)(14), Math.fround(13.37)); + +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var sin=glob.Math.sin; function f(d) { d=+d; d = sin(d); return +d } return f'), this)(Math.PI), Math.sin(Math.PI)); +assertAsmTypeFail('glob', USE_ASM + FROUND + 'var sin=glob.Math.sin; function f(d) { d=fround(d); d = sin(d) } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var sin=glob.Math.sin; function f(d) { d=d|0; d = sin(d) } return f'); + +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var pow=glob.Math.pow; function f(d) { d=+d; d = pow(d,d); return +d } return f'), this)(3), 27); +assertAsmTypeFail('glob', USE_ASM + FROUND + 'var pow=glob.Math.pow; function f(d) { d=fround(d); d = pow(d, d) } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var pow=glob.Math.pow; function f(d) { d=d|0; d = pow(d, d) } return f'); + +assertAsmTypeFail('glob', USE_ASM + 'var sin=glob.Math.sin; function f(d) { d=+d; var i=0; i = sin(d)|0; } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var pow=glob.Math.pow; function f(d) { d=+d; var i=0; i = pow(d,d)|0; } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var atan2=glob.Math.atan2; function f(d) { d=+d; var i=0; i = atan2(d,d)|0; } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var sqrt=glob.Math.sqrt; function f(d) { d=+d; sqrt(d)|0; } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; abs(d)|0; } return f'); + +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i) { i=i|0; var d=0.0; d = +im(i,i); return +d } return f'), this)(42), Math.imul(42, 42)); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(i) { i=i|0; var d=0.0; d = +abs(i|0); return +d } return f'), this)(-42), 42); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(i) { i=i|0; var d=0.0; d = +min(i|0, 0); return +d } return f'), this)(-42), -42); +assertEq(asmLink(asmCompile('glob', USE_ASM + FROUND + 'var min=glob.Math.min; function f(i) { i=i|0; var d=fround(0); d = fround(min(i|0, 0)); return +d } return f'), this)(-42), -42); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; function f(i) { i=i|0; var d=0.0; d = +max(i|0, 0); return +d } return f'), this)(-42), 0); +assertEq(asmLink(asmCompile('glob', USE_ASM + FROUND + 'var max=glob.Math.max; function f(i) { i=i|0; var d=fround(0); d = fround(max(i|0, 0)); return +d } return f'), this)(-42), 0); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var min=glob.Math.min; function f(d) { d=+d; var i=0; i = ~~min(d, 0.)|0; return i|0 } return f'), this)(-42), -42); +assertEq(asmLink(asmCompile('glob', USE_ASM + FROUND + 'var min=glob.Math.min; function f(d) { d=fround(d); var i=0; i = ~~min(d, fround(0))|0; return i|0 } return f'), this)(-42), -42); +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var max=glob.Math.max; function f(d) { d=+d; var i=0; i = ~~max(d, 0.)|0; return i|0 } return f'), this)(-42), 0); +assertEq(asmLink(asmCompile('glob', USE_ASM + FROUND + 'var max=glob.Math.max; function f(d) { d=fround(d); var i=0; i = ~~max(d, fround(0))|0; return i|0 } return f'), this)(-42), 0); + +assertEq(asmLink(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(i) { i=i|0; var d=0.0; return +d; +abs(i|0); return 3.0;} return f'), this)(-42), 0); + +assertAsmTypeFail('glob', USE_ASM + 'var tau=glob.Math.TAU; function f() {} return f'); +assertAsmTypeFail('glob', USE_ASM + 'var pi=glob.Math.PI; function f() { return pi | 0 } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var pi=glob.Math.PI; function f() { return +pi() } return f'); +assertAsmTypeFail('glob', USE_ASM + 'var pi=glob.Math.PI; function f() { pi = +3; } return f'); +assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var pi=glob.Math.PI; function f() {} return f'), {}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var pi=glob.Math.PI; function f() {} return f'), {Math: {}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var pi=glob.Math.PI; function f() {} return f'), {Math: {PI: Math.cos}}); +assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var pi=glob.Math.PI; function f() {} return f'), {Math: {PI: Math.SQRT2}}); + +for (var c of ['E', 'LN10', 'LN2', 'LOG2E', 'LOG10E', 'PI', 'SQRT1_2', 'SQRT2']) { + var f = asmLink(asmCompile('glob', USE_ASM + 'var x=glob.Math.' + c +'; function f() { return +x } return f'), this); + assertEq(f(), eval('Math.' + c)); +} diff --git a/js/src/jit-test/tests/asm.js/testModuleFunctions.js b/js/src/jit-test/tests/asm.js/testModuleFunctions.js new file mode 100644 index 0000000000..2e3c80f45f --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testModuleFunctions.js @@ -0,0 +1,41 @@ + +function testUniqueness(asmJSModule) { + var f = asmJSModule(); + var g = asmJSModule(); + assertEq(f === g, false); + f.x = 4; + assertEq(f.x, 4); + assertEq(g.x, undefined); +} + +function deffun() { + if (Math.sin) { + function inner() { "use asm"; function g() {} return g } + } + return inner; +} + +testUniqueness(deffun); + +function lambda() { + var x = function inner() { "use asm"; function g() {} return g }; + return x; +} + +testUniqueness(lambda); + +function inEval() { + eval("function inner() { 'use asm'; function g() {} return g }"); + return inner; +} + +testUniqueness(inEval); + +function inWith() { + with ({}) { + function inner() { "use asm"; function g() {} return g } + } + return inner; +} + +testUniqueness(inWith); diff --git a/js/src/jit-test/tests/asm.js/testNeuter.js b/js/src/jit-test/tests/asm.js/testNeuter.js new file mode 100644 index 0000000000..32f3b47e70 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testNeuter.js @@ -0,0 +1,43 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable() + +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +var m = asmCompile('stdlib', 'foreign', 'buffer', + `"use asm"; + var i32 = new stdlib.Int32Array(buffer); + function set(i,j) { + i=i|0; + j=j|0; + i32[i>>2] = j; + } + function get(i) { + i=i|0; + return i32[i>>2]|0 + } + return {get:get, set:set}`); + +var buffer = new ArrayBuffer(BUF_MIN); +var {get, set} = asmLink(m, this, null, buffer); +set(4, 42); +assertEq(get(4), 42); +assertThrowsInstanceOf(() => detachArrayBuffer(buffer), Error); + +var m = asmCompile('stdlib', 'foreign', 'buffer', + `"use asm"; + var i32 = new stdlib.Int32Array(buffer); + var ffi = foreign.ffi; + function inner(i) { + i=i|0; + ffi(); + return i32[i>>2]|0 + } + return inner`); + +var buffer = new ArrayBuffer(BUF_MIN); +function ffi1() +{ + assertThrowsInstanceOf(() => detachArrayBuffer(buffer), Error); +} + +var inner = asmLink(m, this, {ffi: ffi1}, buffer); diff --git a/js/src/jit-test/tests/asm.js/testParallelCompile.js b/js/src/jit-test/tests/asm.js/testParallelCompile.js new file mode 100644 index 0000000000..cc962bd55f --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testParallelCompile.js @@ -0,0 +1,21 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable() || helperThreadCount() === 0 + +load(libdir + "asm.js"); + +var module = "'use asm';\n"; +for (var i = 0; i < 100; i++) { + module += "function f" + i + "(i) {\n"; + module += " i=i|0; var j=0; j=(i+1)|0; i=(j-4)|0; i=(i+j)|0; return i|0\n"; + module += "}\n"; +} +module += "return f0"; +var script = "(function() {\n" + module + "})"; + +for (var i = 0; i < 10; i++) { + offThreadCompileToStencil(script); + var f = new Function(module); + var stencil = finishOffThreadStencil(); + var g = evalStencil(stencil); + assertEq(isAsmJSModule(f), true); + assertEq(isAsmJSModule(g), true); +} diff --git a/js/src/jit-test/tests/asm.js/testProfiling.js b/js/src/jit-test/tests/asm.js/testProfiling.js new file mode 100644 index 0000000000..8e5ff4a781 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testProfiling.js @@ -0,0 +1,232 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable() || !getBuildConfiguration()['arm-simulator'] +// Single-step profiling currently only works in the ARM simulator + +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +function checkSubSequence(got, expect) +{ + var got_i = 0; + EXP: for (var exp_i = 0; exp_i < expect.length; exp_i++) { + var item = expect[exp_i]; + // Scan for next match in got. + while (got_i < got.length) { + if (got[got_i++] == expect[exp_i]) + continue EXP; + } + print("MISMATCH: " + got.join(",") + "\n" + + " VS " + expect.join(",")); + return false; + } + return true; +} + +function assertStackContainsSeq(got, expect) +{ + var normalized = []; + + for (var i = 0; i < got.length; i++) { + if (got[i].length == 0) + continue; + var parts = got[i].split(','); + for (var j = 0; j < parts.length; j++) { + var frame = parts[j]; + frame = frame.replace(/ \([^\)]*\)/g, ""); + frame = frame.replace(/fast exit trampoline to native/g, "N"); + frame = frame.replace(/^call to( asm.js)? native .*\(in wasm\)$/g, "N"); + frame = frame.replace(/(fast|slow) exit trampoline/g, "<"); + frame = frame.replace(/(fast|slow) entry trampoline/g, ">"); + frame = frame.replace(/(\/[^\/,<]+)*\/testProfiling.js/g, ""); + frame = frame.replace(/testBuiltinD2D/g, ""); + frame = frame.replace(/testBuiltinF2F/g, ""); + frame = frame.replace(/testBuiltinDD2D/g, ""); + frame = frame.replace(/assertThrowsInstanceOf/g, ""); + frame = frame.replace(/^ffi[12]?/g, ""); + normalized.push(frame); + } + } + + var gotNorm = normalized.join(',').replace(/,+/g, ","); + gotNorm = gotNorm.replace(/^,/, "").replace(/,$/, ""); + + assertEq(checkSubSequence(gotNorm.split(','), expect.split(',')), true); +} + +// Test profiling enablement while asm.js is running. +var stacks; +var ffi = function(enable) { + if (enable == +1) + enableGeckoProfiling(); + enableSingleStepProfiling(); + stacks = disableSingleStepProfiling(); + if (enable == -1) + disableGeckoProfiling(); +} +var f = asmLink(asmCompile('global','ffis',USE_ASM + "var ffi=ffis.ffi; function g(i) { i=i|0; ffi(i|0) } function f(i) { i=i|0; g(i|0) } return f"), null, {ffi}); +f(0); +assertStackContainsSeq(stacks, ""); +f(+1); +assertStackContainsSeq(stacks, "<,g,f,>"); +f(0); +assertStackContainsSeq(stacks, "<,g,f,>"); +f(-1); +assertStackContainsSeq(stacks, "<,g,f,>"); +f(0); +assertStackContainsSeq(stacks, ""); + +// Enable profiling for the rest of the tests. +enableGeckoProfiling(); + +var f = asmLink(asmCompile(USE_ASM + "function f() { return 42 } return f")); +enableSingleStepProfiling(); +assertEq(f(), 42); +var stacks = disableSingleStepProfiling(); +assertStackContainsSeq(stacks, ">,f,>,>"); + +var m = asmCompile(USE_ASM + "function g(i) { i=i|0; return (i+1)|0 } function f() { return g(42)|0 } return f"); +for (var i = 0; i < 3; i++) { + var f = asmLink(m); + enableSingleStepProfiling(); + assertEq(f(), 43); + var stacks = disableSingleStepProfiling(); + assertStackContainsSeq(stacks, ">,f,>,g,f,>,f,>,>"); +} + +var m = asmCompile(USE_ASM + "function g1() { return 1 } function g2() { return 2 } function f(i) { i=i|0; return TBL[i&1]()|0 } var TBL=[g1,g2]; return f"); +for (var i = 0; i < 3; i++) { + var f = asmLink(m); + enableSingleStepProfiling(); + assertEq(f(0), 1); + assertEq(f(1), 2); + var stacks = disableSingleStepProfiling(); + assertStackContainsSeq(stacks, ">,f,>,g1,f,>,f,>,>,>,f,>,g2,f,>,f,>,>"); +} + +function testBuiltinD2D(name) { + var m = asmCompile('g', USE_ASM + "var fun=g.Math." + name + "; function f(d) { d=+d; return +fun(d) } return f"); + for (var i = 0; i < 3; i++) { + var f = asmLink(m, this); + enableSingleStepProfiling(); + assertEq(f(.1), eval("Math." + name + "(.1)")); + var stacks = disableSingleStepProfiling(); + assertStackContainsSeq(stacks, ">,f,>,N,f,>,f,>,>"); + } +} +for (name of ['sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'ceil', 'floor', 'exp', 'log']) + testBuiltinD2D(name); + +function testBuiltinF2F(name) { + var m = asmCompile('g', USE_ASM + "var tof=g.Math.fround; var fun=g.Math." + name + "; function f(d) { d=tof(d); return tof(fun(d)) } return f"); + for (var i = 0; i < 3; i++) { + var f = asmLink(m, this); + enableSingleStepProfiling(); + assertEq(f(.1), eval("Math.fround(Math." + name + "(Math.fround(.1)))")); + var stacks = disableSingleStepProfiling(); + assertStackContainsSeq(stacks, ">,f,>,N,f,>,f,>,>"); + } +} +for (name of ['ceil', 'floor']) + testBuiltinF2F(name); + +function testBuiltinDD2D(name) { + var m = asmCompile('g', USE_ASM + "var fun=g.Math." + name + "; function f(d, e) { d=+d; e=+e; return +fun(d,e) } return f"); + for (var i = 0; i < 3; i++) { + var f = asmLink(m, this); + enableSingleStepProfiling(); + assertEq(f(.1, .2), eval("Math." + name + "(.1, .2)")); + var stacks = disableSingleStepProfiling(); + assertStackContainsSeq(stacks, ">,f,>,N,f,>,f,>,>"); + } +} +for (name of ['atan2', 'pow']) + testBuiltinDD2D(name); + +// FFI tests: +setJitCompilerOption("ion.warmup.trigger", 10); +setJitCompilerOption("baseline.warmup.trigger", 0); +setJitCompilerOption("offthread-compilation.enable", 0); + +var m = asmCompile('g','ffis', USE_ASM + "var ffi1=ffis.ffi1, ffi2=ffis.ffi2; function f() { return ((ffi1()|0) + (ffi2()|0))|0 } return f"); + +var ffi1 = function() { return 10 } +var ffi2 = function() { return 73 } +var f = asmLink(m, null, {ffi1,ffi2}); + +// Interp FFI exit +enableSingleStepProfiling(); +assertEq(f(), 83); +var stacks = disableSingleStepProfiling(); +assertStackContainsSeq(stacks, ">,f,>,<,f,>,f,>,<,f,>,f,>,>"); + +// Ion FFI exit +for (var i = 0; i < 20; i++) + assertEq(f(), 83); +enableSingleStepProfiling(); +assertEq(f(), 83); +var stacks = disableSingleStepProfiling(); +assertStackContainsSeq(stacks, ">,f,>,<,f,>,f,>,<,f,>,f,>,>"); + +var ffi1 = function() { return { valueOf() { return 20 } } } +var ffi2 = function() { return { valueOf() { return 74 } } } +var f = asmLink(m, null, {ffi1,ffi2}); + +// Interp FFI exit +enableSingleStepProfiling(); +assertEq(f(), 94); +var stacks = disableSingleStepProfiling(); +assertStackContainsSeq(stacks, ">,f,>,<,f,>,f,>,<,f,>,f,>,>"); // TODO: add 'valueOf' once interp shows up + +// Ion FFI exit +for (var i = 0; i < 20; i++) + assertEq(f(), 94); +enableSingleStepProfiling(); +assertEq(f(), 94); +var stacks = disableSingleStepProfiling(); +assertStackContainsSeq(stacks, ">,f,>,<,f,>,f,>,<,f,>,f,>,>"); // TODO: add 'valueOf' once interp shows up + +var ffi1 = function() { return 15 } +var ffi2 = function() { return f2() + 17 } +var {f1,f2} = asmLink(asmCompile('g','ffis', USE_ASM + "var ffi1=ffis.ffi1, ffi2=ffis.ffi2; function f2() { return ffi1()|0 } function f1() { return ffi2()|0 } return {f1:f1, f2:f2}"), null, {ffi1, ffi2}); +// Interpreter FFI exit +enableSingleStepProfiling(); +assertEq(f1(), 32); +var stacks = disableSingleStepProfiling(); +assertStackContainsSeq(stacks, ">,f1,>,<,f1,>,>,<,f1,>,f2,>,<,f1,>,<,f2,>,<,f1,>,f2,>,<,f1,>,>,<,f1,>,<,f1,>,f1,>,>"); + + +// Ion FFI exit +var jitOptions = getJitCompilerOptions(); +if (jitOptions['baseline.enable']) { + for (var i = 0; i < 20; i++) + assertEq(f1(), 32); + enableSingleStepProfiling(); + assertEq(f1(), 32); + var stacks = disableSingleStepProfiling(); + assertStackContainsSeq(stacks, ">,f1,>,<,f1,>,>,<,f1,>,f2,>,<,f1,>,<,f2,>,<,f1,>,f2,>,<,f1,>,>,<,f1,>,<,f1,>,f1,>,>"); +} + +// Thunks +setJitCompilerOption("jump-threshold", 0); +var h = asmLink(asmCompile(USE_ASM + 'function f() {} function g() { f() } function h() { g() } return h')); +enableSingleStepProfiling(); +h(); +var stacks = disableSingleStepProfiling(); +assertStackContainsSeq(stacks, ">,h,>,g,h,>,f,g,h,>,g,h,>,h,>,>"); +setJitCompilerOption("jump-threshold", -1); + +// This takes forever to run. +// Stack-overflow exit test +//var limit = -1; +//var maxct = 0; +//function ffi(ct) { if (ct == limit) { enableSingleStepProfiling(); print("enabled"); } maxct = ct; } +//var f = asmLink(asmCompile('g', 'ffis',USE_ASM + "var ffi=ffis.ffi; var ct=0; function rec(){ ct=(ct+1)|0; ffi(ct|0); rec() } function f() { ct=0; rec() } return f"), null, {ffi}); +//// First find the stack limit: +//var caught = false; +//try { f() } catch (e) { caught = true; assertEq(String(e).indexOf("too much recursion") >= 0, true) } +//assertEq(caught, true); +//limit = maxct; +//print("Setting limit"); +//var caught = false; +//try { f() } catch (e) { caught = true; print("caught"); assertEq(String(e).indexOf("too much recursion") >= 0, true) } +//var stacks = disableSingleStepProfiling(); +//assertEq(String(stacks).indexOf("rec") >= 0, true); diff --git a/js/src/jit-test/tests/asm.js/testRangeAnalysis.js b/js/src/jit-test/tests/asm.js/testRangeAnalysis.js new file mode 100644 index 0000000000..6418bc1b39 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testRangeAnalysis.js @@ -0,0 +1,15 @@ +// Bug 894781 +function m(stdlib) +{ + "use asm"; + var abs = stdlib.Math.abs; + function f(d) + { + d = +d; + return (~~(5.0 - +abs(d)))|0; + } + return f; +} +var f = m(this); +assertEq(f(0.2), 4); +assertEq(f(NaN), 0); diff --git a/js/src/jit-test/tests/asm.js/testSource-2.js b/js/src/jit-test/tests/asm.js/testSource-2.js new file mode 100644 index 0000000000..34cd3ae06b --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testSource-2.js @@ -0,0 +1,368 @@ +// |jit-test| skip-if: !Function.prototype.toSource + +(function() { +/* + * NO ARGUMENT + */ + +function f0() { + "use asm"; + function g() {} + return g; + +} + +var bodyOnly = '"use asm";\n\ + function g() {}\n\ + return g;\n'; + +var funcBody = 'function f0() {\n\ + "use asm";\n\ + function g() {}\n\ + return g;\n\n\ +}'; + +assertEq(f0.toSource(), funcBody); + +var f0 = function() { + "use asm"; + function g() {} + return g; + +} + +funcBody1 = funcBody.replace('function f0','function'); +assertEq(f0.toSource(), '(' + funcBody1 + ')'); + +var g = function g0() { + "use asm"; + function g() {} + return g; + +} + +funcBody2 = funcBody.replace('function f0', 'function g0'); +assertEq(g.toSource(), '(' + funcBody2 + ')'); + +f0 = new Function(bodyOnly); +assertEq(f0.toSource(), "(function anonymous(\n) {\n" + bodyOnly + "\n})"); + +if (isAsmJSCompilationAvailable()) { + var m = new Function(bodyOnly); + assertEq(isAsmJSModule(m), true); + assertEq(m.toSource(), "(function anonymous(\n) {\n" + bodyOnly + "\n})"); +} + +})(); + +(function() { +/* + * ONE ARGUMENT + */ +function f1(glob) { + "use asm"; + function g() {} + return g; + +} + +var bodyOnly = '"use asm";\n\ + function g() {}\n\ + return g;\n'; + +var funcBody = 'function f1(glob) {\n\ + "use asm";\n\ + function g() {}\n\ + return g;\n\n\ +}'; + +assertEq(f1.toSource(), funcBody); + +f1 = function(glob) { + "use asm"; + function g() {} + return g; + +} + +funcBody1 = funcBody.replace('function f1', 'function'); +assertEq(f1.toSource(), '(' + funcBody1 + ')'); + +var g = function g0(glob) { + "use asm"; + function g() {} + return g; + +} + +funcBody2 = funcBody.replace('function f1', 'function g0'); +assertEq(g.toSource(), '(' + funcBody2 + ')'); + +f1 = new Function('glob', bodyOnly); +assertEq(f1.toSource(), "(function anonymous(glob\n) {\n" + bodyOnly + "\n})"); + +if (isAsmJSCompilationAvailable()) { + var m = new Function('glob', bodyOnly); + assertEq(isAsmJSModule(m), true); + assertEq(m.toSource(), "(function anonymous(glob\n) {\n" + bodyOnly + "\n})"); +} + +})(); + + +(function() { +/* + * TWO ARGUMENTS + */ +function f2(glob, ffi) { + "use asm"; + function g() {} + return g; + +} + +var bodyOnly = '"use asm";\n\ + function g() {}\n\ + return g;\n'; + +var funcBody = 'function f2(glob, ffi) {\n\ + "use asm";\n\ + function g() {}\n\ + return g;\n\n\ +}'; + +assertEq(f2.toSource(), funcBody); + +f2 = function(glob, ffi) { + "use asm"; + function g() {} + return g; + +} + +funcBody1 = funcBody.replace('function f2', 'function'); +assertEq(f2.toSource(), '(' + funcBody1 + ')'); + +var g = function g0(glob, ffi) { + "use asm"; + function g() {} + return g; + +} + +var funcBody2 = funcBody.replace('function f2', 'function g0'); +assertEq(g.toSource(), '(' + funcBody2 + ')'); + +f2 = new Function('glob', 'ffi', bodyOnly); +assertEq(f2.toSource(), "(function anonymous(glob,ffi\n) {\n" + bodyOnly + "\n})"); + +if (isAsmJSCompilationAvailable()) { + var m = new Function('glob', 'ffi', bodyOnly); + assertEq(isAsmJSModule(m), true); + assertEq(m.toSource(), "(function anonymous(glob,ffi\n) {\n" + bodyOnly + "\n})"); +} + +})(); + + +(function() { +/* + * THREE ARGUMENTS + */ +function f3(glob, ffi, heap) { + "use asm"; + function g() {} + return g; + +} + +var bodyOnly = '"use asm";\n\ + function g() {}\n\ + return g;\n'; + +var funcBody = 'function f3(glob, ffi, heap) {\n\ + "use asm";\n\ + function g() {}\n\ + return g;\n\n\ +}'; + +assertEq(f3.toSource(), funcBody); + +f3 = function(glob, ffi, heap) { + "use asm"; + function g() {} + return g; + +} + +funcBody1 = funcBody.replace('function f3', 'function'); +assertEq(f3.toSource(), '(' + funcBody1 + ')'); + +var g = function g0(glob, ffi, heap) { + "use asm"; + function g() {} + return g; + +} + +funcBody2 = funcBody.replace('function f3', 'function g0'); +assertEq(g.toSource(), '(' + funcBody2 + ')'); + +f3 = new Function('glob', 'ffi', 'heap', bodyOnly); +assertEq(f3.toSource(), "(function anonymous(glob,ffi,heap\n) {\n" + bodyOnly + "\n})"); + +if (isAsmJSCompilationAvailable()) { + var m = new Function('glob', 'ffi', 'heap', bodyOnly); + assertEq(isAsmJSModule(m), true); + assertEq(m.toSource(), "(function anonymous(glob,ffi,heap\n) {\n" + bodyOnly + "\n})"); +} + +})(); + +/* Modules in "use strict" context */ +(function() { + +var funcSource = + `function(glob, ffi, heap) { + "use asm"; + function g() {} + return g; + }`; + +var f4 = eval("\"use strict\";\n(" + funcSource + ")"); + +var expectedToString = funcSource; +var expectedToSource = '(' + expectedToString + ')'; + +assertEq(f4.toSource(), expectedToSource); + +if (isAsmJSCompilationAvailable()) { + var f5 = eval("\"use strict\";\n(" + funcSource + ")"); + assertEq(isAsmJSModule(f5), true); + assertEq(f5.toSource(), expectedToSource); +} +})(); + +/* Functions */ +(function() { + +var noSrc = "function noArgument() {\n\ + return 42;\n\ +}" +var oneSrc = "function oneArgument(x) {\n\ + x = x | 0;\n\ + return x + 1 | 0;\n\ +}"; +var twoSrc = "function twoArguments(x, y) {\n\ + x = x | 0;\n\ + y = y | 0;\n\ + return x + y | 0;\n\ +}"; +var threeSrc = "function threeArguments(a, b, c) {\n\ + a = +a;\n\ + b = +b;\n\ + c = +c;\n\ + return +(+(a * b) + c);\n\ +}"; + +var funcBody = '\n\ + "use asm";\n' + + noSrc + '\n' + + oneSrc + '\n' + + twoSrc + '\n' + + threeSrc + '\n' + + 'return {\n\ + no: noArgument,\n\ + one: oneArgument,\n\ + two: twoArguments,\n\ + three: threeArguments\n\ + }'; + +var g = new Function(funcBody); +var moduleG = g(); + +function checkFuncSrc(m) { + assertEq(m.no.toSource(), noSrc); + + assertEq(m.one.toSource(), oneSrc); + + assertEq(m.two.toSource(), twoSrc); + + assertEq(m.three.toSource(), threeSrc); +} +checkFuncSrc(moduleG); + +if (isAsmJSCompilationAvailable()) { + var g2 = new Function(funcBody); + assertEq(isAsmJSModule(g2), true); + m = g2(); + checkFuncSrc(m); + + var moduleDecl = 'function g3() {' + funcBody + '}'; + eval(moduleDecl); + m = g3(); + assertEq(isAsmJSModule(g3), true); + checkFuncSrc(m); + + eval('var x = 42;' + moduleDecl); + m = g3(); + assertEq(isAsmJSModule(g3), true); + checkFuncSrc(m); +} + +})(); + +/* Functions in "use strict" context */ +(function () { + +var funcCode = 'function g(x) {\n\ + x=x|0;\n\ + return x + 1 | 0;}'; +var moduleCode = 'function () {\n\ + "use asm";\n' + funcCode + '\n\ + return g;\n\ + }', + useStrict = '"use strict";'; + +var f5 = eval(useStrict + ";\n(" + moduleCode + "())"); + +var expectedToString = funcCode; +var expectedToSource = expectedToString + +assertEq(f5.toSource(), expectedToSource); + +if (isAsmJSCompilationAvailable()) { + var mf5 = eval("\"use strict\";\n(" + moduleCode + ")"); + assertEq(isAsmJSModule(mf5), true); + var f5 = mf5(); + assertEq(f5.toSource(), expectedToSource); +} + +})(); + +/* Functions in "use strict" context with dynamic linking failure */ +(function () { + +var funcCode = 'function g(x) {\n\ + x=x|0;\n\ + return x + 1 | 0;}'; +var moduleCode = 'function (glob) {\n\ + "use asm";\n\ + var fround = glob.Math.fround;\n\ + ' + funcCode + '\n\ + return g;\n\ + }', + useStrict = '"use strict";'; + +var f6 = eval(useStrict + ";\n(" + moduleCode + "({Math:{}}))"); + +assertEq(f6.toSource(), funcCode); + +if (isAsmJSCompilationAvailable()) { + var mf6 = eval("\"use strict\";\n(" + moduleCode + ")"); + assertEq(isAsmJSModule(mf6), true); + var f6 = mf6({Math:{}}); + assertEq(f6.toSource(), funcCode); +} + +})(); diff --git a/js/src/jit-test/tests/asm.js/testSource.js b/js/src/jit-test/tests/asm.js/testSource.js new file mode 100644 index 0000000000..5e0fbb3a22 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testSource.js @@ -0,0 +1,385 @@ +(function() { +/* + * NO ARGUMENT + */ + +function f0() { + "use asm"; + function g() {} + return g; + +} + +var bodyOnly = '"use asm";\n\ + function g() {}\n\ + return g;\n'; + +var funcBody = 'function f0() {\n\ + "use asm";\n\ + function g() {}\n\ + return g;\n\n\ +}'; + +assertEq(f0.toString(), funcBody); + +var f0 = function() { + "use asm"; + function g() {} + return g; + +} + +funcBody1 = funcBody.replace('function f0','function'); +assertEq(f0.toString(), funcBody1); + +var g = function g0() { + "use asm"; + function g() {} + return g; + +} + +funcBody2 = funcBody.replace('function f0', 'function g0'); +assertEq(g.toString(), funcBody2); + +f0 = new Function(bodyOnly); +assertEq(f0.toString(), "function anonymous(\n) {\n" + bodyOnly + "\n}"); + +if (isAsmJSCompilationAvailable()) { + var m = new Function(bodyOnly); + assertEq(isAsmJSModule(m), true); + assertEq(m.toString(), "function anonymous(\n) {\n" + bodyOnly + "\n}"); +} + +})(); + +(function() { +/* + * ONE ARGUMENT + */ +function f1(glob) { + "use asm"; + function g() {} + return g; + +} + +var bodyOnly = '"use asm";\n\ + function g() {}\n\ + return g;\n'; + +var funcBody = 'function f1(glob) {\n\ + "use asm";\n\ + function g() {}\n\ + return g;\n\n\ +}'; + +assertEq(f1.toString(), funcBody); + +f1 = function(glob) { + "use asm"; + function g() {} + return g; + +} + +funcBody1 = funcBody.replace('function f1', 'function'); +assertEq(f1.toString(), funcBody1); + +var g = function g0(glob) { + "use asm"; + function g() {} + return g; + +} + +funcBody2 = funcBody.replace('function f1', 'function g0'); +assertEq(g.toString(), funcBody2); + +f1 = new Function('glob', bodyOnly); +assertEq(f1.toString(), "function anonymous(glob\n) {\n" + bodyOnly + "\n}"); + +if (isAsmJSCompilationAvailable()) { + var m = new Function('glob', bodyOnly); + assertEq(isAsmJSModule(m), true); + assertEq(m.toString(), "function anonymous(glob\n) {\n" + bodyOnly + "\n}"); +} + +})(); + + +(function() { +/* + * TWO ARGUMENTS + */ +function f2(glob, ffi) { + "use asm"; + function g() {} + return g; + +} + +var bodyOnly = '"use asm";\n\ + function g() {}\n\ + return g;\n'; + +var funcBody = 'function f2(glob, ffi) {\n\ + "use asm";\n\ + function g() {}\n\ + return g;\n\n\ +}'; + +assertEq(f2.toString(), funcBody); + +f2 = function(glob, ffi) { + "use asm"; + function g() {} + return g; + +} + +funcBody1 = funcBody.replace('function f2', 'function'); +assertEq(f2.toString(), funcBody1); + +var g = function g0(glob, ffi) { + "use asm"; + function g() {} + return g; + +} + +var funcBody2 = funcBody.replace('function f2', 'function g0'); +assertEq(g.toString(), funcBody2); + +f2 = new Function('glob', 'ffi', bodyOnly); +assertEq(f2.toString(), "function anonymous(glob,ffi\n) {\n" + bodyOnly + "\n}"); + +if (isAsmJSCompilationAvailable()) { + var m = new Function('glob', 'ffi', bodyOnly); + assertEq(isAsmJSModule(m), true); + assertEq(m.toString(), "function anonymous(glob,ffi\n) {\n" + bodyOnly + "\n}"); +} + +})(); + + +(function() { +/* + * THREE ARGUMENTS + */ +function f3(glob, ffi, heap) { + "use asm"; + function g() {} + return g; + +} + +var bodyOnly = '"use asm";\n\ + function g() {}\n\ + return g;\n'; + +var funcBody = 'function f3(glob, ffi, heap) {\n\ + "use asm";\n\ + function g() {}\n\ + return g;\n\n\ +}'; + +assertEq(f3.toString(), funcBody); + +f3 = function(glob, ffi, heap) { + "use asm"; + function g() {} + return g; + +} + +funcBody1 = funcBody.replace('function f3', 'function'); +assertEq(f3.toString(), funcBody1); + +var g = function g0(glob, ffi, heap) { + "use asm"; + function g() {} + return g; + +} + +funcBody2 = funcBody.replace('function f3', 'function g0'); +assertEq(g.toString(), funcBody2); + +f3 = new Function('glob', 'ffi', 'heap', bodyOnly); +assertEq(f3.toString(), "function anonymous(glob,ffi,heap\n) {\n" + bodyOnly + "\n}"); + +if (isAsmJSCompilationAvailable()) { + var m = new Function('glob', 'ffi', 'heap', bodyOnly); + assertEq(isAsmJSModule(m), true); + assertEq(m.toString(), "function anonymous(glob,ffi,heap\n) {\n" + bodyOnly + "\n}"); +} + +})(); + +/* Modules in "use strict" context */ +(function() { + +var funcSource = + `function(glob, ffi, heap) { + "use asm"; + function g() {} + return g; + }`; + +var f4 = eval("\"use strict\";\n(" + funcSource + ")"); + +var expectedToString = funcSource; + +assertEq(f4.toString(), expectedToString); + +if (isAsmJSCompilationAvailable()) { + var f5 = eval("\"use strict\";\n(" + funcSource + ")"); + assertEq(isAsmJSModule(f5), true); + assertEq(f5.toString(), expectedToString); +} +})(); + +/* Functions */ +(function() { + +var noSrc = "function noArgument() {\n\ + return 42;\n\ +}" +var oneSrc = "function oneArgument(x) {\n\ + x = x | 0;\n\ + return x + 1 | 0;\n\ +}"; +var twoSrc = "function twoArguments(x, y) {\n\ + x = x | 0;\n\ + y = y | 0;\n\ + return x + y | 0;\n\ +}"; +var threeSrc = "function threeArguments(a, b, c) {\n\ + a = +a;\n\ + b = +b;\n\ + c = +c;\n\ + return +(+(a * b) + c);\n\ +}"; + +var funcBody = '\n\ + "use asm";\n' + + noSrc + '\n' + + oneSrc + '\n' + + twoSrc + '\n' + + threeSrc + '\n' + + 'return {\n\ + no: noArgument,\n\ + one: oneArgument,\n\ + two: twoArguments,\n\ + three: threeArguments\n\ + }'; + +var g = new Function(funcBody); +var moduleG = g(); + +function checkFuncSrc(m) { + assertEq(m.no.toString(), noSrc); + + assertEq(m.one.toString(), oneSrc); + + assertEq(m.two.toString(), twoSrc); + + assertEq(m.three.toString(), threeSrc); +} +checkFuncSrc(moduleG); + +if (isAsmJSCompilationAvailable()) { + var g2 = new Function(funcBody); + assertEq(isAsmJSModule(g2), true); + m = g2(); + checkFuncSrc(m); + + var moduleDecl = 'function g3() {' + funcBody + '}'; + eval(moduleDecl); + m = g3(); + assertEq(isAsmJSModule(g3), true); + checkFuncSrc(m); + + eval('var x = 42;' + moduleDecl); + m = g3(); + assertEq(isAsmJSModule(g3), true); + checkFuncSrc(m); +} + +})(); + +/* Functions in "use strict" context */ +(function () { + +var funcCode = 'function g(x) {\n\ + x=x|0;\n\ + return x + 1 | 0;}'; +var moduleCode = 'function () {\n\ + "use asm";\n' + funcCode + '\n\ + return g;\n\ + }', + useStrict = '"use strict";'; + +var f5 = eval(useStrict + ";\n(" + moduleCode + "())"); + +var expectedToString = funcCode; + +assertEq(f5.toString(), expectedToString); + +if (isAsmJSCompilationAvailable()) { + var mf5 = eval("\"use strict\";\n(" + moduleCode + ")"); + assertEq(isAsmJSModule(mf5), true); + var f5 = mf5(); + assertEq(f5.toString(), expectedToString); +} + +})(); + +/* Functions in "use strict" context with dynamic linking failure */ +(function () { + +var funcCode = 'function g(x) {\n\ + x=x|0;\n\ + return x + 1 | 0;}'; +var moduleCode = 'function (glob) {\n\ + "use asm";\n\ + var fround = glob.Math.fround;\n\ + ' + funcCode + '\n\ + return g;\n\ + }', + useStrict = '"use strict";'; + +var f6 = eval(useStrict + ";\n(" + moduleCode + "({Math:{}}))"); + +assertEq(f6.toString(), funcCode); + +if (isAsmJSCompilationAvailable()) { + var mf6 = eval("\"use strict\";\n(" + moduleCode + ")"); + assertEq(isAsmJSModule(mf6), true); + var f6 = mf6({Math:{}}); + assertEq(f6.toString(), funcCode); +} + +})(); + +/* Column number > 0. */ +(function() { + +var asmSource = `function evaluate() { + "use asm"; + function another() {} + function func() {} + return func +}` + +var m = evaluate(` +var f = x =>(${asmSource}); +f()`, { + columnNumber: 100 +}); + +assertEq(m.toString(), asmSource); +assertEq(m().toString(), `function func() {}`) + +})(); diff --git a/js/src/jit-test/tests/asm.js/testStackWalking.js b/js/src/jit-test/tests/asm.js/testStackWalking.js new file mode 100644 index 0000000000..48f781a323 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testStackWalking.js @@ -0,0 +1,97 @@ +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +function matchStack(stackString, stackArray) +{ + var match = 0; + for (name of stackArray) { + match = stackString.indexOf(name, match); + if (match === -1) + throw name + " not found in the stack " + stack; + } +} + +var stack; +function dumpStack() +{ + stack = new Error().stack +} + +setJitCompilerOption("ion.warmup.trigger", 10); +setJitCompilerOption("baseline.warmup.trigger", 0); +setJitCompilerOption("offthread-compilation.enable", 0); + +var callFFI = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function f() { return ffi()|0 } return f"); + +var f = asmLink(callFFI, null, {ffi:dumpStack}); +for (var i = 0; i < 15; i++) { + stack = null; + f(); + matchStack(stack, ['dumpStack', 'f']); +} + +if (isAsmJSCompilationAvailable()) { + var callFFI = asmCompile('global', 'ffis', USE_ASM + "var ffi=ffis.ffi; function f() { return ffi()|0 } return f"); + assertEq(isAsmJSModule(callFFI), true); + stack = null; + f(); + matchStack(stack, ['dumpStack', 'f']); +} + +var f1 = asmLink(callFFI, null, {ffi:dumpStack}); +var f2 = asmLink(callFFI, null, {ffi:function middle() { f1() }}); +stack = null; +(function outer() { f2() })(); +matchStack(stack, ["dumpStack", "f", "middle", "f"]); + +function returnStackDumper() { return { valueOf:function() { stack = new Error().stack } } } +var f = asmLink(callFFI, null, {ffi:returnStackDumper}); +for (var i = 0; i < 15; i++) { + stack = null; + f(); + matchStack(stack, ['valueOf', 'f']); +} + +var caught = false; +try { + stack = null; + asmLink(asmCompile(USE_ASM + "function asmRec() { asmRec() } return asmRec"))(); +} catch (e) { + caught = true; + matchStack(e.stack, ['asmRec', 'asmRec', 'asmRec', 'asmRec']); +} +assertEq(caught, true); + +var caught = false; +try { + callFFI(null, {ffi:Object.defineProperty})(); +} catch (e) { + caught = true; +} +assertEq(caught, true); + +asmLink(callFFI, null, {ffi:eval})(); +asmLink(callFFI, null, {ffi:Function})(); +asmLink(callFFI, null, {ffi:Error})(); + +var manyCalls = asmCompile('global', 'ffis', + USE_ASM + + "var ffi=ffis.ffi;\ + function f1(a,b,c,d,e,f,g,h,i,j,k) { \ + a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;k=k|0; \ + ffi(); \ + return (a+b+c+d+e+f+g+h+i+j+k)|0; \ + } \ + function f2() { \ + return f1(1,2,3,4,5,6,7,8,f1(1,2,3,4,5,6,7,8,9,10,11)|0,10,11)|0; \ + } \ + function f3() { return 13 } \ + function f4(i) { \ + i=i|0; \ + return TBL[i&3]()|0; \ + } \ + var TBL=[f3, f3, f2, f3]; \ + return f4;"); +stack = null; +assertEq(asmLink(manyCalls, null, {ffi:dumpStack})(2), 123); +matchStack(stack, ['dumpStack', 'f1', 'f2', 'f4']); diff --git a/js/src/jit-test/tests/asm.js/testStealing.js b/js/src/jit-test/tests/asm.js/testStealing.js new file mode 100644 index 0000000000..8751cea49e --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testStealing.js @@ -0,0 +1,18 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable() + +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +var code = USE_ASM + "var i32 = new stdlib.Int32Array(buf); function f() { return i32[0]|0 } return f"; + +var ab = new ArrayBuffer(BUF_MIN); +new Int32Array(ab)[0] = 42; + +var f = asmLink(asmCompile('stdlib', 'ffi', 'buf', code), this, null, ab); +assertEq(f(), 42); + +assertThrowsInstanceOf(() => detachArrayBuffer(ab), Error); +assertEq(f(), 42); + +assertThrowsInstanceOf(() => serialize(ab, [ab]), Error); +assertEq(f(), 42); diff --git a/js/src/jit-test/tests/asm.js/testTimeout1.js b/js/src/jit-test/tests/asm.js/testTimeout1.js new file mode 100644 index 0000000000..c1bc6a09df --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testTimeout1.js @@ -0,0 +1,8 @@ +// |jit-test| exitstatus: 6; skip-if: getBuildConfiguration()['wasi'] + +load(libdir + "asm.js"); + +var g = asmLink(asmCompile(USE_ASM + "function f() {} function g() { while(1) { f() } } return g")); +timeout(1); +g(); +assertEq(true, false); diff --git a/js/src/jit-test/tests/asm.js/testTimeout2.js b/js/src/jit-test/tests/asm.js/testTimeout2.js new file mode 100644 index 0000000000..0c6b82fdce --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testTimeout2.js @@ -0,0 +1,8 @@ +// |jit-test| exitstatus: 6; skip-if: getBuildConfiguration()['wasi'] + +load(libdir + "asm.js"); + +var g = asmLink(asmCompile(USE_ASM + "function g() { while(1) {} } return g")); +timeout(1); +g(); +assertEq(true, false); diff --git a/js/src/jit-test/tests/asm.js/testTimeout3.js b/js/src/jit-test/tests/asm.js/testTimeout3.js new file mode 100644 index 0000000000..9de1449b97 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testTimeout3.js @@ -0,0 +1,8 @@ +// |jit-test| exitstatus: 6; skip-if: getBuildConfiguration()['wasi'] + +load(libdir + "asm.js"); + +var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; if (!i) return; f((i-1)|0); f((i-1)|0); f((i-1)|0); f((i-1)|0); f((i-1)|0); } return f")); +timeout(1); +f(100); +assertEq(true, false); diff --git a/js/src/jit-test/tests/asm.js/testTimeout4.js b/js/src/jit-test/tests/asm.js/testTimeout4.js new file mode 100644 index 0000000000..4e67b712d9 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testTimeout4.js @@ -0,0 +1,8 @@ +// |jit-test| exitstatus: 6; skip-if: getBuildConfiguration()['wasi'] + +load(libdir + "asm.js"); + +var g = asmLink(asmCompile(USE_ASM + "function f(d) { d=+d; d=d*.1; d=d/.4; return +d } function g() { while(1) { +f(1.1) } } return g")); +timeout(1); +g(); +assertEq(true, false); diff --git a/js/src/jit-test/tests/asm.js/testTimeout5.js b/js/src/jit-test/tests/asm.js/testTimeout5.js new file mode 100644 index 0000000000..85971cf127 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testTimeout5.js @@ -0,0 +1,12 @@ +// |jit-test| exitstatus: 6; skip-if: getBuildConfiguration()['wasi'] + +load(libdir + "asm.js"); + +enableGeckoProfiling(); + +var f = asmLink(asmCompile('glob', 'ffis', 'buf', USE_ASM + "function f() { var i=0; while (1) { i=(i+1)|0 } } return f")); +timeout(1); +if (getBuildConfiguration()["arm-simulator"]) + enableSingleStepProfiling(); +f(); +assertEq(true, false); diff --git a/js/src/jit-test/tests/asm.js/testTimeout6.js b/js/src/jit-test/tests/asm.js/testTimeout6.js new file mode 100644 index 0000000000..451b5f236e --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testTimeout6.js @@ -0,0 +1,12 @@ +// |jit-test| exitstatus: 6; skip-if: getBuildConfiguration()['wasi'] + +load(libdir + "asm.js"); + +enableGeckoProfiling(); + +var f = asmLink(asmCompile('glob', 'ffis', 'buf', USE_ASM + "function g() { var i=0; while (1) { i=(i+1)|0 } } function f() { g() } return f")); +timeout(1); +if (getBuildConfiguration()["arm-simulator"]) + enableSingleStepProfiling(); +f(); +assertEq(true, false); diff --git a/js/src/jit-test/tests/asm.js/testTimeout7.js b/js/src/jit-test/tests/asm.js/testTimeout7.js new file mode 100644 index 0000000000..10fcb71d1a --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testTimeout7.js @@ -0,0 +1,17 @@ +// |jit-test| exitstatus: 6; skip-if: helperThreadCount() == 0 + +var job = offThreadCompileToStencil(` + function asmModule() { + "use asm"; + function f() { + while(1) { + } + } + return f; + } +`); +var stencil = finishOffThreadStencil(job); +evalStencil(stencil); +timeout(1); +asmModule()(); +assertEq(true, false); diff --git a/js/src/jit-test/tests/asm.js/testUseAsmWarnings.js b/js/src/jit-test/tests/asm.js/testUseAsmWarnings.js new file mode 100644 index 0000000000..2c260dd98f --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testUseAsmWarnings.js @@ -0,0 +1,14 @@ +load(libdir + "asm.js"); + +assertAsmDirectiveFail("'use asm'"); +assertAsmDirectiveFail("eval('\"use asm\";');"); +assertAsmDirectiveFail("{ eval('\"use asm\";'); }"); +assertAsmDirectiveFail("if (Math) { 'use asm'; }"); +assertAsmDirectiveFail("function f(){ { 'use asm'; } }"); +assertAsmDirectiveFail("function f(){ ; 'use asm'; }"); +assertAsmDirectiveFail("function f(){ 1; 'use asm'; }"); +assertAsmDirectiveFail("function f(){ var x; 'use asm'; }"); +assertAsmDirectiveFail("function f(){ if (Math) { 'use asm'; } }"); +assertAsmDirectiveFail("(function(){ eval('\"use asm\";') })()"); +assertAsmDirectiveFail("new Function('{\"use asm\";}')"); +assertAsmDirectiveFail("new Function('if (Math){\"use asm\";}')"); diff --git a/js/src/jit-test/tests/asm.js/testX86ByteStore.js b/js/src/jit-test/tests/asm.js/testX86ByteStore.js new file mode 100644 index 0000000000..05556a5d9a --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testX86ByteStore.js @@ -0,0 +1,77 @@ +load(libdir + "asm.js"); + +var body = +' "use asm";\ + var i8=new global.Int8Array(buffer);\ + function g(i,j,k) {\ + i=i|0;\ + j=j|0;\ + k=k|0;\ + var a=0,b=0,c=0,d=0,e=0,f=0;\ + a=(i+j)|0;\ + b=(k+j)|0;\ + c=(i+k)|0;\ + b=(a+b)|0;\ + d=(b+c+i+j)|0;\ + e=(a+j+c)|0;\ + f=(a+i+k)|0;\ + i8[i] = f;\ + return (a+b+c+d+e+f)|0;\ + }\ + return g;'; + +var buf=new ArrayBuffer(BUF_MIN); +var g = asmLink(asmCompile('global','foreign','buffer',body), this, null, buf); +assertEq(g(1,2,3), 46); +assertEq(new Int8Array(buf)[1], 7); + +var body = +' "use asm";\ + var i8=new global.Int8Array(buffer);\ + function g(i,j,k) {\ + i=i|0;\ + j=j|0;\ + k=k|0;\ + var a=0,b=0,c=0,d=0,e=0,f=0;\ + a=(i+j)|0;\ + b=(k+j)|0;\ + c=(i+k)|0;\ + b=(a+b)|0;\ + d=(b+c+i+j)|0;\ + e=(a+j+c)|0;\ + f=(a+i+k)|0;\ + i8[i] = e;\ + return (a+b+c+d+e+f)|0;\ + }\ + return g;'; + +var buf=new ArrayBuffer(BUF_MIN); +var g = asmLink(asmCompile('global','foreign','buffer',body), this, null, buf); +assertEq(g(1,2,3), 46); +assertEq(new Int8Array(buf)[1], 9); + +var body = +' "use asm";\ + var i8=new global.Int8Array(buffer);\ + function g(i,j,k) {\ + i=i|0;\ + j=j|0;\ + k=k|0;\ + var a=0,b=0,c=0,d=0,e=0,f=0,g=0;\ + a=(i+j)|0;\ + b=(k+j)|0;\ + c=(i+k)|0;\ + b=(a+b)|0;\ + d=(b+c+i+j)|0;\ + e=(a+j+c)|0;\ + f=(a+i+k)|0;\ + g=(f+j+b)|0;\ + i8[i] = g;\ + return (a+b+c+d+e+f+g)|0;\ + }\ + return g;'; + +var buf=new ArrayBuffer(BUF_MIN); +var g = asmLink(asmCompile('global','foreign','buffer',body), this, null, buf); +assertEq(g(1,2,3), 63); +assertEq(new Int8Array(buf)[1], 17); diff --git a/js/src/jit-test/tests/asm.js/testZOOB.js b/js/src/jit-test/tests/asm.js/testZOOB.js new file mode 100644 index 0000000000..1d211cdc98 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testZOOB.js @@ -0,0 +1,122 @@ +// |jit-test| skip-if: !isAsmJSCompilationAvailable() +load(libdir + "asm.js"); +load(libdir + "asserts.js"); + +// This test runs a lot of code and is very slow with --ion-eager. Use a minimum +// Ion warmup trigger of 5 to avoid timeouts. +if (getJitCompilerOptions()["ion.warmup.trigger"] < 5) + setJitCompilerOption("ion.warmup.trigger", 5); + +var ab = new ArrayBuffer(BUF_MIN); + +// Compute a set of interesting indices. +indices = [0] +for (var i of [4,1024,BUF_MIN,Math.pow(2,30),Math.pow(2,31),Math.pow(2,32),Math.pow(2,33)]) { + for (var j of [-2,-1,0,1,2]) { + for (var k of [1,-1]) + indices.push((i+j)*k); + } +} + +function testInt(ctor, shift, scale, disp) { + var arr = new ctor(ab); + + var c = asmCompile('glob', 'imp', 'b', + USE_ASM + + 'var arr=new glob.' + ctor.name + '(b); ' + + 'function load(i) {i=i|0; return arr[((i<<' + scale + ')+' + disp + ')>>' + shift + ']|0 } ' + + 'function store(i,j) {i=i|0;j=j|0; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = j } ' + + 'function storeZero(i) {i=i|0; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = 0 } ' + + 'function storeNegOne(i) {i=i|0; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = -1 } ' + + 'return { load: load, store: store, storeZero: storeZero, storeNegOne: storeNegOne }'); + var f = asmLink(c, this, null, ab); + + var v = arr[0]; + arr[0] = -1; + var negOne = arr[0]|0; + arr[0] = v; + + for (var i of indices) { + var index = ((i<<scale)+disp)>>shift; + v = arr[index]|0; + + // Loads + assertEq(f.load(i), v); + + // Stores of immediates + arr[index] = 1; + f.storeZero(i); + assertEq(arr[index]|0, 0); + f.storeNegOne(i); + assertEq(arr[index]|0, index>>>0 < arr.length ? negOne : 0); + + // Stores + arr[index] = ~v; + f.store(i, v); + assertEq(arr[index]|0, v); + } +} + +function testFloat(ctor, shift, scale, disp, coercion) { + var arr = new ctor(ab); + + var c = asmCompile('glob', 'imp', 'b', + USE_ASM + + 'var arr=new glob.' + ctor.name + '(b); ' + + 'var toF = glob.Math.fround; ' + + 'function load(i) {i=i|0; return ' + coercion + '(arr[((i<<' + scale + ')+' + disp + ')>>' + shift + ']) } ' + + 'function store(i,j) {i=i|0;j=+j; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = j } ' + + 'return { load: load, store: store }'); + var f = asmLink(c, this, null, ab); + + for (var i of indices) { + var index = ((i<<scale)+disp)>>shift; + var v = +arr[index]; + + // Loads + assertEq(f.load(i), v); + + // Stores + arr[index] = ~v; + f.store(i, v); + assertEq(+arr[index], v); + } +} + +function testFloat32(ctor, shift, scale, disp) { + testFloat(ctor, shift, scale, disp, "toF"); +} +function testFloat64(ctor, shift, scale, disp) { + testFloat(ctor, shift, scale, disp, "+"); +} + +function assertEqX4(observed, expected) { + assertEq(observed.x, expected.x); + assertEq(observed.y, expected.y); + assertEq(observed.z, expected.z); + assertEq(observed.w, expected.w); +} + +function test(tester, ctor, shift) { + var arr = new ctor(ab); + for (var i = 0; i < arr.length; i++) + arr[i] = Math.imul(i, Math.imul((i & 1), 2) - 1); + for (scale of [0,1,2,3]) { + for (disp of [0,1,2,8,Math.pow(2,30),Math.pow(2,31)-1,Math.pow(2,31),Math.pow(2,32)-1]) + tester(ctor, shift, scale, disp); + } + for (var i = 0; i < arr.length; i++) { + var v = arr[i]; + arr[i] = Math.imul(i, Math.imul((i & 1), 2) - 1); + assertEq(arr[i], v); + } +} + +test(testInt, Int8Array, 0); +test(testInt, Uint8Array, 0); +test(testInt, Int16Array, 1); +test(testInt, Uint16Array, 1); +test(testInt, Int32Array, 2); +test(testInt, Uint32Array, 2); +test(testFloat32, Float32Array, 2); +test(testFloat64, Float64Array, 3); |