summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/asm.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/asm.js')
-rw-r--r--js/src/jit-test/tests/asm.js/bug1007512.js8
-rw-r--r--js/src/jit-test/tests/asm.js/bug1008636.js12
-rw-r--r--js/src/jit-test/tests/asm.js/bug1126251.js15
-rw-r--r--js/src/jit-test/tests/asm.js/bug1161298.js12
-rw-r--r--js/src/jit-test/tests/asm.js/bug1174372.js6
-rw-r--r--js/src/jit-test/tests/asm.js/bug1219954.js10
-rw-r--r--js/src/jit-test/tests/asm.js/bug1268955-usestrict-semantics.js19
-rw-r--r--js/src/jit-test/tests/asm.js/bug1276028.js6
-rw-r--r--js/src/jit-test/tests/asm.js/bug1306506.js7
-rw-r--r--js/src/jit-test/tests/asm.js/bug1385428.js18
-rw-r--r--js/src/jit-test/tests/asm.js/bug1421565.js19
-rw-r--r--js/src/jit-test/tests/asm.js/bug1493475.js8
-rw-r--r--js/src/jit-test/tests/asm.js/bug1565301.js29
-rw-r--r--js/src/jit-test/tests/asm.js/bug1602675.js19
-rw-r--r--js/src/jit-test/tests/asm.js/bug855526.js13
-rw-r--r--js/src/jit-test/tests/asm.js/bug885976.js12
-rw-r--r--js/src/jit-test/tests/asm.js/bug923867.js8
-rw-r--r--js/src/jit-test/tests/asm.js/bug927389.js6
-rw-r--r--js/src/jit-test/tests/asm.js/bug928450.js18
-rw-r--r--js/src/jit-test/tests/asm.js/bug940864.js10
-rw-r--r--js/src/jit-test/tests/asm.js/bug941877.js164
-rw-r--r--js/src/jit-test/tests/asm.js/directives.txt1
-rw-r--r--js/src/jit-test/tests/asm.js/import-function-toPrimitive.js26
-rw-r--r--js/src/jit-test/tests/asm.js/nested-rewind.js9
-rw-r--r--js/src/jit-test/tests/asm.js/neuter-during-arguments-coercion.js27
-rw-r--r--js/src/jit-test/tests/asm.js/oom-helper-thread-plus-validation-error.js10
-rw-r--r--js/src/jit-test/tests/asm.js/oom-helper-thread.js4
-rw-r--r--js/src/jit-test/tests/asm.js/testAddressErrors.js46
-rw-r--r--js/src/jit-test/tests/asm.js/testBasic.js173
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1046688.js11
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1057248.js133
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1111327.js10
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1117255.js16
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1125561.js47
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1147144-2.js17
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1147144.js18
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1219098.js14
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1236484.js10
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1236541.js15
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1236552.js3
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1255954.js12
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1291887.js13
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1301191.js24
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1357053.js15
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1359612.js9
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1360390.js13
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1437534.js19
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1437546.js6
-rw-r--r--js/src/jit-test/tests/asm.js/testBug1674353.js13
-rw-r--r--js/src/jit-test/tests/asm.js/testBug855442.js8
-rw-r--r--js/src/jit-test/tests/asm.js/testBug863867.js34
-rw-r--r--js/src/jit-test/tests/asm.js/testBug878435.js11
-rw-r--r--js/src/jit-test/tests/asm.js/testBug878495.js10
-rw-r--r--js/src/jit-test/tests/asm.js/testBug878520.js9
-rw-r--r--js/src/jit-test/tests/asm.js/testBug892291.js10
-rw-r--r--js/src/jit-test/tests/asm.js/testBug893364.js14
-rw-r--r--js/src/jit-test/tests/asm.js/testBug893368.js13
-rw-r--r--js/src/jit-test/tests/asm.js/testBug907085.js22
-rw-r--r--js/src/jit-test/tests/asm.js/testBug952022.js57
-rw-r--r--js/src/jit-test/tests/asm.js/testBug965767.js2098
-rw-r--r--js/src/jit-test/tests/asm.js/testBug975182.js20
-rw-r--r--js/src/jit-test/tests/asm.js/testBug989166.js8
-rw-r--r--js/src/jit-test/tests/asm.js/testBug999790.js65
-rw-r--r--js/src/jit-test/tests/asm.js/testBullet.js6
-rw-r--r--js/src/jit-test/tests/asm.js/testCall.js75
-rw-r--r--js/src/jit-test/tests/asm.js/testCloning.js48
-rw-r--r--js/src/jit-test/tests/asm.js/testCompoundPlusMinus.js14
-rw-r--r--js/src/jit-test/tests/asm.js/testControlFlow.js374
-rw-r--r--js/src/jit-test/tests/asm.js/testDebugModeDisables.js9
-rw-r--r--js/src/jit-test/tests/asm.js/testExpressions.js403
-rw-r--r--js/src/jit-test/tests/asm.js/testFFI.js175
-rw-r--r--js/src/jit-test/tests/asm.js/testFastHeapAccess.js81
-rw-r--r--js/src/jit-test/tests/asm.js/testFloat32.js321
-rw-r--r--js/src/jit-test/tests/asm.js/testFloatingPoint.js134
-rw-r--r--js/src/jit-test/tests/asm.js/testFunctionPtr.js74
-rw-r--r--js/src/jit-test/tests/asm.js/testGetter.js11
-rw-r--r--js/src/jit-test/tests/asm.js/testGlobals.js164
-rw-r--r--js/src/jit-test/tests/asm.js/testHeapAccess.js511
-rw-r--r--js/src/jit-test/tests/asm.js/testJumpRange.js26
-rw-r--r--js/src/jit-test/tests/asm.js/testLargeHeap.js9
-rw-r--r--js/src/jit-test/tests/asm.js/testLinkErrorAssert.js20
-rw-r--r--js/src/jit-test/tests/asm.js/testLiterals.js50
-rw-r--r--js/src/jit-test/tests/asm.js/testMathLib.js189
-rw-r--r--js/src/jit-test/tests/asm.js/testModuleFunctions.js41
-rw-r--r--js/src/jit-test/tests/asm.js/testNeuter.js43
-rw-r--r--js/src/jit-test/tests/asm.js/testParallelCompile.js21
-rw-r--r--js/src/jit-test/tests/asm.js/testProfiling.js232
-rw-r--r--js/src/jit-test/tests/asm.js/testRangeAnalysis.js15
-rw-r--r--js/src/jit-test/tests/asm.js/testSource-2.js368
-rw-r--r--js/src/jit-test/tests/asm.js/testSource.js385
-rw-r--r--js/src/jit-test/tests/asm.js/testStackWalking.js97
-rw-r--r--js/src/jit-test/tests/asm.js/testStealing.js18
-rw-r--r--js/src/jit-test/tests/asm.js/testTimeout1.js8
-rw-r--r--js/src/jit-test/tests/asm.js/testTimeout2.js8
-rw-r--r--js/src/jit-test/tests/asm.js/testTimeout3.js8
-rw-r--r--js/src/jit-test/tests/asm.js/testTimeout4.js8
-rw-r--r--js/src/jit-test/tests/asm.js/testTimeout5.js12
-rw-r--r--js/src/jit-test/tests/asm.js/testTimeout6.js12
-rw-r--r--js/src/jit-test/tests/asm.js/testTimeout7.js17
-rw-r--r--js/src/jit-test/tests/asm.js/testUseAsmWarnings.js14
-rw-r--r--js/src/jit-test/tests/asm.js/testX86ByteStore.js77
-rw-r--r--js/src/jit-test/tests/asm.js/testZOOB.js122
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);