Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE

This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.

FPIIM-449

Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/test/mjsunit/wasm/asm-wasm.js b/test/mjsunit/wasm/asm-wasm.js
index 8dfe85a..3f936f5 100644
--- a/test/mjsunit/wasm/asm-wasm.js
+++ b/test/mjsunit/wasm/asm-wasm.js
@@ -15,7 +15,9 @@
   return {caller: caller};
 }
 
-assertEquals(11, _WASMEXP_.asmCompileRun(EmptyTest.toString()));
+assertEquals(11, _WASMEXP_.instantiateModuleFromAsm(
+      EmptyTest.toString()).caller());
+
 
 function IntTest() {
   "use asm";
@@ -24,7 +26,7 @@
     b = b|0;
     var c = (b + 1)|0
     var d = 3.0;
-    var e = d | 0;  // double conversion
+    var e = ~~d;  // double conversion
     return (a + c + 1)|0;
   }
 
@@ -35,7 +37,9 @@
   return {caller: caller};
 }
 
-assertEquals(101, _WASMEXP_.asmCompileRun(IntTest.toString()));
+assertEquals(101, _WASMEXP_.instantiateModuleFromAsm(
+      IntTest.toString()).caller());
+
 
 function Float64Test() {
   "use asm";
@@ -59,7 +63,9 @@
   return {caller: caller};
 }
 
-assertEquals(1, _WASMEXP_.asmCompileRun(Float64Test.toString()));
+assertEquals(1, _WASMEXP_.instantiateModuleFromAsm(
+      Float64Test.toString()).caller());
+
 
 function BadModule() {
   "use asm";
@@ -78,9 +84,10 @@
 }
 
 assertThrows(function() {
-  _WASMEXP_.asmCompileRun(BadModule.toString())
+  _WASMEXP_.instantiateModuleFromAsm(BadModule.toString()).caller();
 });
 
+
 function TestReturnInBlock() {
   "use asm";
 
@@ -98,7 +105,9 @@
   return {caller: caller};
 }
 
-assertEquals(1, _WASMEXP_.asmCompileRun(TestReturnInBlock.toString()));
+assertEquals(1, _WASMEXP_.instantiateModuleFromAsm(
+      TestReturnInBlock.toString()).caller());
+
 
 function TestWhileSimple() {
   "use asm";
@@ -114,7 +123,9 @@
   return {caller: caller};
 }
 
-assertEquals(5, _WASMEXP_.asmCompileRun(TestWhileSimple.toString()));
+assertEquals(5, _WASMEXP_.instantiateModuleFromAsm(
+      TestWhileSimple.toString()).caller());
+
 
 function TestWhileWithoutBraces() {
   "use asm";
@@ -129,7 +140,9 @@
   return {caller: caller};
 }
 
-assertEquals(4, _WASMEXP_.asmCompileRun(TestWhileWithoutBraces.toString()));
+assertEquals(4, _WASMEXP_.instantiateModuleFromAsm(
+      TestWhileWithoutBraces.toString()).caller());
+
 
 function TestReturnInWhile() {
   "use asm";
@@ -146,7 +159,9 @@
   return {caller: caller};
 }
 
-assertEquals(6, _WASMEXP_.asmCompileRun(TestReturnInWhile.toString()));
+assertEquals(6, _WASMEXP_.instantiateModuleFromAsm(
+      TestReturnInWhile.toString()).caller());
+
 
 function TestReturnInWhileWithoutBraces() {
   "use asm";
@@ -161,7 +176,10 @@
   return {caller: caller};
 }
 
-assertEquals(7, _WASMEXP_.asmCompileRun(TestReturnInWhileWithoutBraces.toString()));
+assertEquals(
+    7, _WASMEXP_.instantiateModuleFromAsm(
+      TestReturnInWhileWithoutBraces.toString()).caller());
+
 
 function TestBreakInWhile() {
   "use asm";
@@ -176,7 +194,9 @@
   return {caller: caller};
 }
 
-assertEquals(8, _WASMEXP_.asmCompileRun(TestBreakInWhile.toString()));
+assertEquals(8, _WASMEXP_.instantiateModuleFromAsm(
+      TestBreakInWhile.toString()).caller());
+
 
 function TestBreakInNestedWhile() {
   "use asm";
@@ -198,7 +218,9 @@
   return {caller: caller};
 }
 
-assertEquals(9, _WASMEXP_.asmCompileRun(TestBreakInNestedWhile.toString()));
+assertEquals(9, _WASMEXP_.instantiateModuleFromAsm(
+      TestBreakInNestedWhile.toString()).caller());
+
 
 function TestBreakInBlock() {
   "use asm";
@@ -218,7 +240,9 @@
   return {caller: caller};
 }
 
-assertEquals(10, _WASMEXP_.asmCompileRun(TestBreakInBlock.toString()));
+assertEquals(10, _WASMEXP_.instantiateModuleFromAsm(
+      TestBreakInBlock.toString()).caller());
+
 
 function TestBreakInNamedWhile() {
   "use asm";
@@ -237,7 +261,9 @@
   return {caller: caller};
 }
 
-assertEquals(11, _WASMEXP_.asmCompileRun(TestBreakInNamedWhile.toString()));
+assertEquals(11, _WASMEXP_.instantiateModuleFromAsm(
+      TestBreakInNamedWhile.toString()).caller());
+
 
 function TestContinue() {
   "use asm";
@@ -258,7 +284,9 @@
   return {caller: caller};
 }
 
-assertEquals(-5, _WASMEXP_.asmCompileRun(TestContinue.toString()));
+assertEquals(-5, _WASMEXP_.instantiateModuleFromAsm(
+      TestContinue.toString()).caller());
+
 
 function TestContinueInNamedWhile() {
   "use asm";
@@ -284,7 +312,9 @@
   return {caller: caller};
 }
 
-assertEquals(20, _WASMEXP_.asmCompileRun(TestContinueInNamedWhile.toString()));
+assertEquals(20, _WASMEXP_.instantiateModuleFromAsm(
+      TestContinueInNamedWhile.toString()).caller());
+
 
 function TestNot() {
   "use asm";
@@ -297,7 +327,9 @@
   return {caller:caller};
 }
 
-assertEquals(1, _WASMEXP_.asmCompileRun(TestNot.toString()));
+assertEquals(1, _WASMEXP_.instantiateModuleFromAsm(
+      TestNot.toString()).caller());
+
 
 function TestNotEquals() {
   "use asm";
@@ -313,7 +345,9 @@
   return {caller:caller};
 }
 
-assertEquals(21, _WASMEXP_.asmCompileRun(TestNotEquals.toString()));
+assertEquals(21, _WASMEXP_.instantiateModuleFromAsm(
+      TestNotEquals.toString()).caller());
+
 
 function TestUnsignedComparison() {
   "use asm";
@@ -329,7 +363,9 @@
   return {caller:caller};
 }
 
-assertEquals(22, _WASMEXP_.asmCompileRun(TestUnsignedComparison.toString()));
+assertEquals(22, _WASMEXP_.instantiateModuleFromAsm(
+      TestUnsignedComparison.toString()).caller());
+
 
 function TestMixedAdd() {
   "use asm";
@@ -350,7 +386,9 @@
   return {caller:caller};
 }
 
-assertEquals(23, _WASMEXP_.asmCompileRun(TestMixedAdd.toString()));
+assertEquals(23, _WASMEXP_.instantiateModuleFromAsm(
+      TestMixedAdd.toString()).caller());
+
 
 function TestInt32HeapAccess(stdlib, foreign, buffer) {
   "use asm";
@@ -368,27 +406,49 @@
   return {caller: caller};
 }
 
-assertEquals(7, _WASMEXP_.asmCompileRun(TestInt32HeapAccess.toString()));
+assertEquals(7, _WASMEXP_.instantiateModuleFromAsm(
+      TestInt32HeapAccess.toString()).caller());
+
+
+function TestInt32HeapAccessExternal() {
+  var memory = new ArrayBuffer(1024);
+  var memory_int32 = new Int32Array(memory);
+  var module = _WASMEXP_.instantiateModuleFromAsm(
+      TestInt32HeapAccess.toString(), null, memory);
+  module.__init__();
+  assertEquals(7, module.caller());
+  assertEquals(7, memory_int32[2]);
+}
+
+TestInt32HeapAccessExternal();
+
 
 function TestHeapAccessIntTypes() {
   var types = [
-    ['Int8Array', '>> 0'],
-    ['Uint8Array', '>> 0'],
-    ['Int16Array', '>> 1'],
-    ['Uint16Array', '>> 1'],
-    ['Int32Array', '>> 2'],
-    ['Uint32Array', '>> 2'],
+    [Int8Array, 'Int8Array', '>> 0'],
+    [Uint8Array, 'Uint8Array', '>> 0'],
+    [Int16Array, 'Int16Array', '>> 1'],
+    [Uint16Array, 'Uint16Array', '>> 1'],
+    [Int32Array, 'Int32Array', '>> 2'],
+    [Uint32Array, 'Uint32Array', '>> 2'],
   ];
   for (var i = 0; i < types.length; i++) {
     var code = TestInt32HeapAccess.toString();
-    code = code.replace('Int32Array', types[i][0]);
-    code = code.replace(/>> 2/g, types[i][1]);
-    assertEquals(7, _WASMEXP_.asmCompileRun(code));
+    code = code.replace('Int32Array', types[i][1]);
+    code = code.replace(/>> 2/g, types[i][2]);
+    var memory = new ArrayBuffer(1024);
+    var memory_view = new types[i][0](memory);
+    var module = _WASMEXP_.instantiateModuleFromAsm(code, null, memory);
+    module.__init__();
+    assertEquals(7, module.caller());
+    assertEquals(7, memory_view[2]);
+    assertEquals(7, _WASMEXP_.instantiateModuleFromAsm(code).caller());
   }
 }
 
 TestHeapAccessIntTypes();
 
+
 function TestFloatHeapAccess(stdlib, foreign, buffer) {
   "use asm";
 
@@ -411,7 +471,22 @@
   return {caller: caller};
 }
 
-assertEquals(1, _WASMEXP_.asmCompileRun(TestFloatHeapAccess.toString()));
+assertEquals(1, _WASMEXP_.instantiateModuleFromAsm(
+      TestFloatHeapAccess.toString()).caller());
+
+
+function TestFloatHeapAccessExternal() {
+  var memory = new ArrayBuffer(1024);
+  var memory_float64 = new Float64Array(memory);
+  var module = _WASMEXP_.instantiateModuleFromAsm(
+      TestFloatHeapAccess.toString(), null, memory);
+  module.__init__();
+  assertEquals(1, module.caller());
+  assertEquals(9.0, memory_float64[1]);
+}
+
+TestFloatHeapAccessExternal();
+
 
 function TestConvertI32() {
   "use asm";
@@ -427,7 +502,9 @@
   return {caller:caller};
 }
 
-assertEquals(24, _WASMEXP_.asmCompileRun(TestConvertI32.toString()));
+assertEquals(24, _WASMEXP_.instantiateModuleFromAsm(
+      TestConvertI32.toString()).caller());
+
 
 function TestConvertF64FromInt() {
   "use asm";
@@ -443,7 +520,9 @@
   return {caller:caller};
 }
 
-assertEquals(25, _WASMEXP_.asmCompileRun(TestConvertF64FromInt.toString()));
+assertEquals(25, _WASMEXP_.instantiateModuleFromAsm(
+      TestConvertF64FromInt.toString()).caller());
+
 
 function TestConvertF64FromUnsigned() {
   "use asm";
@@ -461,7 +540,9 @@
   return {caller:caller};
 }
 
-assertEquals(26, _WASMEXP_.asmCompileRun(TestConvertF64FromUnsigned.toString()));
+assertEquals(26, _WASMEXP_.instantiateModuleFromAsm(
+      TestConvertF64FromUnsigned.toString()).caller());
+
 
 function TestModInt() {
   "use asm";
@@ -475,7 +556,9 @@
   return {caller:caller};
 }
 
-assertEquals(-27, _WASMEXP_.asmCompileRun(TestModInt.toString()));
+assertEquals(-27, _WASMEXP_.instantiateModuleFromAsm(
+      TestModInt.toString()).caller());
+
 
 function TestModUnsignedInt() {
   "use asm";
@@ -489,7 +572,9 @@
   return {caller:caller};
 }
 
-assertEquals(8, _WASMEXP_.asmCompileRun(TestModUnsignedInt.toString()));
+assertEquals(8, _WASMEXP_.instantiateModuleFromAsm(
+      TestModUnsignedInt.toString()).caller());
+
 
 function TestModDouble() {
   "use asm";
@@ -506,7 +591,9 @@
   return {caller:caller};
 }
 
-assertEquals(28, _WASMEXP_.asmCompileRun(TestModDouble.toString()));
+assertEquals(28, _WASMEXP_.instantiateModuleFromAsm(
+      TestModDouble.toString()).caller());
+
 
 /*
 TODO: Fix parsing of negative doubles
@@ -526,9 +613,11 @@
   return {caller:caller};
 }
 
-assertEquals(28, _WASMEXP_.asmCompileRun(TestModDoubleNegative.toString()));
+assertEquals(28, _WASMEXP_.instantiateModuleFromAsm(
+      TestModDoubleNegative.toString()).caller());
 */
 
+
 function TestNamedFunctions() {
   "use asm";
 
@@ -552,6 +641,7 @@
 module.init();
 assertEquals(77.5, module.add());
 
+
 function TestGlobalsWithInit() {
   "use asm";
 
@@ -569,6 +659,7 @@
 module.__init__();
 assertEquals(77.5, module.add());
 
+
 function TestForLoop() {
   "use asm"
 
@@ -584,7 +675,9 @@
   return {caller:caller};
 }
 
-assertEquals(54, _WASMEXP_.asmCompileRun(TestForLoop.toString()));
+assertEquals(54, _WASMEXP_.instantiateModuleFromAsm(
+      TestForLoop.toString()).caller());
+
 
 function TestForLoopWithoutInit() {
   "use asm"
@@ -601,7 +694,9 @@
   return {caller:caller};
 }
 
-assertEquals(100, _WASMEXP_.asmCompileRun(TestForLoopWithoutInit.toString()));
+assertEquals(100, _WASMEXP_.instantiateModuleFromAsm(
+      TestForLoopWithoutInit.toString()).caller());
+
 
 function TestForLoopWithoutCondition() {
   "use asm"
@@ -621,7 +716,9 @@
   return {caller:caller};
 }
 
-assertEquals(66, _WASMEXP_.asmCompileRun(TestForLoopWithoutCondition.toString()));
+assertEquals(66, _WASMEXP_.instantiateModuleFromAsm(
+      TestForLoopWithoutCondition.toString()).caller());
+
 
 function TestForLoopWithoutNext() {
   "use asm"
@@ -637,7 +734,9 @@
   return {caller:caller};
 }
 
-assertEquals(41, _WASMEXP_.asmCompileRun(TestForLoopWithoutNext.toString()));
+assertEquals(41, _WASMEXP_.instantiateModuleFromAsm(
+      TestForLoopWithoutNext.toString()).caller());
+
 
 function TestForLoopWithoutBody() {
   "use asm"
@@ -652,7 +751,9 @@
   return {caller:caller};
 }
 
-assertEquals(45, _WASMEXP_.asmCompileRun(TestForLoopWithoutBody.toString()));
+assertEquals(45, _WASMEXP_.instantiateModuleFromAsm(
+      TestForLoopWithoutBody.toString()).caller());
+
 
 function TestDoWhile() {
   "use asm"
@@ -670,7 +771,9 @@
   return {caller:caller};
 }
 
-assertEquals(84, _WASMEXP_.asmCompileRun(TestDoWhile.toString()));
+assertEquals(84, _WASMEXP_.instantiateModuleFromAsm(
+      TestDoWhile.toString()).caller());
+
 
 function TestConditional() {
   "use asm"
@@ -683,7 +786,9 @@
   return {caller:caller};
 }
 
-assertEquals(41, _WASMEXP_.asmCompileRun(TestConditional.toString()));
+assertEquals(41, _WASMEXP_.instantiateModuleFromAsm(
+      TestConditional.toString()).caller());
+
 
 function TestSwitch() {
   "use asm"
@@ -710,7 +815,9 @@
   return {caller:caller};
 }
 
-assertEquals(23, _WASMEXP_.asmCompileRun(TestSwitch.toString()));
+assertEquals(23, _WASMEXP_.instantiateModuleFromAsm(
+      TestSwitch.toString()).caller());
+
 
 function TestSwitchFallthrough() {
   "use asm"
@@ -731,7 +838,9 @@
   return {caller:caller};
 }
 
-assertEquals(42, _WASMEXP_.asmCompileRun(TestSwitchFallthrough.toString()));
+assertEquals(42, _WASMEXP_.instantiateModuleFromAsm(
+      TestSwitchFallthrough.toString()).caller());
+
 
 function TestNestedSwitch() {
   "use asm"
@@ -756,7 +865,9 @@
   return {caller:caller};
 }
 
-assertEquals(43, _WASMEXP_.asmCompileRun(TestNestedSwitch.toString()));
+assertEquals(43, _WASMEXP_.instantiateModuleFromAsm(
+      TestNestedSwitch.toString()).caller());
+
 
 function TestInitFunctionWithNoGlobals() {
   "use asm";
@@ -771,6 +882,7 @@
 module.__init__();
 assertEquals(51, module.caller());
 
+
 function TestExportNameDifferentFromFunctionName() {
   "use asm";
   function caller() {
@@ -783,3 +895,458 @@
     TestExportNameDifferentFromFunctionName.toString());
 module.__init__();
 assertEquals(55, module.alt_caller());
+
+
+function TestFunctionTableSingleFunction() {
+  "use asm";
+
+  function dummy() {
+    return 71;
+  }
+
+  function caller() {
+    return function_table[0&0]() | 0;
+  }
+
+  var function_table = [dummy]
+
+  return {caller:caller};
+}
+
+assertEquals(71, _WASMEXP_.instantiateModuleFromAsm(
+      TestFunctionTableSingleFunction.toString()).caller());
+
+
+function TestFunctionTableMultipleFunctions() {
+  "use asm";
+
+  function inc1(x) {
+    x = x|0;
+    return (x+1)|0;
+  }
+
+  function inc2(x) {
+    x = x|0;
+    return (x+2)|0;
+  }
+
+  function caller() {
+    if (function_table[0&1](50) == 51) {
+      if (function_table[1&1](60) == 62) {
+        return 73;
+      }
+    }
+    return 0;
+  }
+
+  var function_table = [inc1, inc2]
+
+  return {caller:caller};
+}
+
+assertEquals(73, _WASMEXP_.instantiateModuleFromAsm(
+      TestFunctionTableMultipleFunctions.toString()).caller());
+
+
+function TestFunctionTable() {
+  "use asm";
+
+  function add(a, b) {
+    a = a|0;
+    b = b|0;
+    return (a+b)|0;
+  }
+
+  function sub(a, b) {
+    a = a|0;
+    b = b|0;
+    return (a-b)|0;
+  }
+
+  function inc(a) {
+    a = a|0;
+    return (a+1)|0;
+  }
+
+  function caller(table_id, fun_id, arg1, arg2) {
+    table_id = table_id|0;
+    fun_id = fun_id|0;
+    arg1 = arg1|0;
+    arg2 = arg2|0;
+    if (table_id == 0) {
+      return funBin[fun_id&3](arg1, arg2)|0;
+    } else if (table_id == 1) {
+      return fun[fun_id&0](arg1)|0;
+    }
+    return 0;
+  }
+
+  var funBin = [add, sub, sub, add];
+  var fun = [inc];
+
+  return {caller:caller};
+}
+
+var module = _WASMEXP_.instantiateModuleFromAsm(TestFunctionTable.toString());
+module.__init__();
+assertEquals(55, module.caller(0, 0, 33, 22));
+assertEquals(11, module.caller(0, 1, 33, 22));
+assertEquals(9, module.caller(0, 2, 54, 45));
+assertEquals(99, module.caller(0, 3, 54, 45));
+assertEquals(23, module.caller(0, 4, 12, 11));
+assertEquals(31, module.caller(1, 0, 30, 11));
+
+
+function TestForeignFunctions() {
+  function AsmModule(stdlib, foreign, buffer) {
+    "use asm";
+
+    var setVal = foreign.setVal;
+    var getVal = foreign.getVal;
+
+    function caller(initial_value, new_value) {
+      initial_value = initial_value|0;
+      new_value = new_value|0;
+      if ((getVal()|0) == (initial_value|0)) {
+        setVal(new_value|0);
+        return getVal()|0;
+      }
+      return 0;
+    }
+
+    return {caller:caller};
+  }
+
+  function ffi(initial_val) {
+    var val = initial_val;
+
+    function getVal() {
+      return val;
+    }
+
+    function setVal(new_val) {
+      val = new_val;
+    }
+
+    return {getVal:getVal, setVal:setVal};
+  }
+
+  var foreign = new ffi(23);
+
+  var module = _WASMEXP_.instantiateModuleFromAsm(AsmModule.toString(),
+                                                  foreign, null);
+
+  module.__init__();
+  assertEquals(103, module.caller(23, 103));
+}
+
+TestForeignFunctions();
+
+
+function TestForeignFunctionMultipleUse() {
+  function AsmModule(stdlib, foreign, buffer) {
+    "use asm";
+
+    var getVal = foreign.getVal;
+
+    function caller(int_val, double_val) {
+      int_val = int_val|0;
+      double_val = +double_val;
+      if ((getVal()|0) == (int_val|0)) {
+        if ((+getVal()) == (+double_val)) {
+          return 89;
+        }
+      }
+      return 0;
+    }
+
+    return {caller:caller};
+  }
+
+  function ffi() {
+    function getVal() {
+      return 83.25;
+    }
+
+    return {getVal:getVal};
+  }
+
+  var foreign = new ffi();
+
+  var module = _WASMEXP_.instantiateModuleFromAsm(AsmModule.toString(),
+                                                  foreign, null);
+
+  module.__init__();
+  assertEquals(89, module.caller(83, 83.25));
+}
+
+TestForeignFunctionMultipleUse();
+
+
+function TestForeignVariables() {
+  function AsmModule(stdlib, foreign, buffer) {
+    "use asm";
+
+    var i1 = foreign.foo | 0;
+    var f1 = +foreign.bar;
+    var i2 = foreign.baz | 0;
+    var f2 = +foreign.baz;
+
+    function geti1() {
+      return i1|0;
+    }
+
+    function getf1() {
+      return +f1;
+    }
+
+    function geti2() {
+      return i2|0;
+    }
+
+    function getf2() {
+      return +f2;
+    }
+
+    return {geti1:geti1, getf1:getf1, geti2:geti2, getf2:getf2};
+  }
+
+  function TestCase(env, i1, f1, i2, f2) {
+    var module = _WASMEXP_.instantiateModuleFromAsm(
+        AsmModule.toString(), env);
+    module.__init__();
+    assertEquals(i1, module.geti1());
+    assertEquals(f1, module.getf1());
+    assertEquals(i2, module.geti2());
+    assertEquals(f2, module.getf2());
+  }
+
+  // Check normal operation.
+  TestCase({foo: 123, bar: 234.5, baz: 345.7}, 123, 234.5, 345, 345.7);
+  // Check partial operation.
+  TestCase({baz: 345.7}, 0, NaN, 345, 345.7);
+  // Check that undefined values are converted to proper defaults.
+  TestCase({qux: 999}, 0, NaN, 0, NaN);
+  // Check that an undefined ffi is ok.
+  TestCase(undefined, 0, NaN, 0, NaN);
+  // Check that true values are converted properly.
+  TestCase({foo: true, bar: true, baz: true}, 1, 1.0, 1, 1.0);
+  // Check that false values are converted properly.
+  TestCase({foo: false, bar: false, baz: false}, 0, 0, 0, 0);
+  // Check that null values are converted properly.
+  TestCase({foo: null, bar: null, baz: null}, 0, 0, 0, 0);
+  // Check that string values are converted properly.
+  TestCase({foo: 'hi', bar: 'there', baz: 'dude'}, 0, NaN, 0, NaN);
+  TestCase({foo: '0xff', bar: '234', baz: '456.1'}, 255, 234, 456, 456.1, 456);
+  // Check that Date values are converted properly.
+  TestCase({foo: new Date(123), bar: new Date(456),
+            baz: new Date(789)}, 123, 456, 789, 789);
+  // Check that list values are converted properly.
+  TestCase({foo: [], bar: [], baz: []}, 0, 0, 0, 0);
+  // Check that object values are converted properly.
+  TestCase({foo: {}, bar: {}, baz: {}}, 0, NaN, 0, NaN);
+  // Check that getter object values are converted properly.
+  var o = {
+    get foo() {
+      return 123.4;
+    }
+  };
+  TestCase({foo: o.foo, bar: o.foo, baz: o.foo}, 123, 123.4, 123, 123.4);
+  // Check that getter object values are converted properly.
+  var o = {
+    get baz() {
+      return 123.4;
+    }
+  };
+  TestCase(o, 0, NaN, 123, 123.4);
+  // Check that objects with valueOf are converted properly.
+  var o = {
+    valueOf: function() { return 99; }
+  };
+  TestCase({foo: o, bar: o, baz: o}, 99, 99, 99, 99);
+  // Check that function values are converted properly.
+  TestCase({foo: TestCase, bar: TestCase, qux: TestCase}, 0, NaN, 0, NaN);
+  // Check that a missing ffi object is safe.
+  TestCase(undefined, 0, NaN, 0, NaN);
+}
+
+TestForeignVariables();
+
+
+(function() {
+  function TestByteHeapAccessCompat(stdlib, foreign, buffer) {
+    "use asm";
+
+    var HEAP8 = new stdlib.Uint8Array(buffer);
+    var HEAP32 = new stdlib.Int32Array(buffer);
+
+    function store(i, v) {
+      i = i | 0;
+      v = v | 0;
+      HEAP32[i >> 2] = v;
+    }
+
+    function storeb(i, v) {
+      i = i | 0;
+      v = v | 0;
+      HEAP8[i | 0] = v;
+    }
+
+    function load(i) {
+      i = i | 0;
+      return HEAP8[i] | 0;
+    }
+
+    function iload(i) {
+      i = i | 0;
+      return HEAP8[HEAP32[i >> 2] | 0] | 0;
+    }
+
+    return {load: load, iload: iload, store: store, storeb: storeb};
+  }
+
+  var m = _WASMEXP_.instantiateModuleFromAsm(
+      TestByteHeapAccessCompat.toString());
+  m.store(0, 20);
+  m.store(4, 21);
+  m.store(8, 22);
+  m.storeb(20, 123);
+  m.storeb(21, 42);
+  m.storeb(22, 77);
+  assertEquals(123, m.load(20));
+  assertEquals(42, m.load(21));
+  assertEquals(77, m.load(22));
+  assertEquals(123, m.iload(0));
+  assertEquals(42, m.iload(4));
+  assertEquals(77, m.iload(8));
+})();
+
+
+(function TestGlobalBlock() {
+  function Module(stdlib, foreign, buffer) {
+    "use asm";
+
+    var x = foreign.x | 0, y = foreign.y | 0;
+
+    function test() {
+      return (x + y) | 0;
+    }
+
+    return {test: test};
+  }
+
+  var m = _WASMEXP_.instantiateModuleFromAsm(
+      Module.toString(), { x: 4, y: 11 });
+  m.__init__();
+  assertEquals(15, m.test());
+})();
+
+
+(function TestComma() {
+  function CommaModule() {
+    "use asm";
+
+    function ifunc(a, b) {
+      a = +a;
+      b = b | 0;
+      return (a, b) | 0;
+    }
+
+    function dfunc(a, b) {
+      a = a | 0;
+      b = +b;
+      return +(a, b);
+    }
+
+    return {ifunc: ifunc, dfunc: dfunc};
+  }
+
+  var m = _WASMEXP_.instantiateModuleFromAsm(CommaModule.toString());
+  assertEquals(123, m.ifunc(456.7, 123));
+  assertEquals(123.4, m.dfunc(456, 123.4));
+})();
+
+
+(function TestOr() {
+  function Module() {
+    "use asm";
+    function func() {
+      var x = 1;
+      var y = 2;
+      return (x | y) | 0;
+    }
+    return {func: func};
+  }
+
+  var m = _WASMEXP_.instantiateModuleFromAsm(Module.toString());
+  assertEquals(3, m.func());
+})();
+
+
+(function TestAnd() {
+  function Module() {
+    "use asm";
+    function func() {
+      var x = 3;
+      var y = 2;
+      return (x & y) | 0;
+    }
+    return {func: func};
+  }
+
+  var m = _WASMEXP_.instantiateModuleFromAsm(Module.toString());
+  assertEquals(2, m.func());
+})();
+
+
+(function TestXor() {
+  function Module() {
+    "use asm";
+    function func() {
+      var x = 3;
+      var y = 2;
+      return (x ^ y) | 0;
+    }
+    return {func: func};
+  }
+
+  var m = _WASMEXP_.instantiateModuleFromAsm(Module.toString());
+  assertEquals(1, m.func());
+})();
+
+
+(function TestIntishAssignment() {
+  function Module(stdlib, foreign, heap) {
+    "use asm";
+    var HEAP32 = new stdlib.Int32Array(heap);
+    function func() {
+      var a = 1;
+      var b = 2;
+      HEAP32[0] = a + b;
+      return HEAP32[0] | 0;
+    }
+    return {func: func};
+  }
+
+  var m = _WASMEXP_.instantiateModuleFromAsm(Module.toString());
+  assertEquals(3, m.func());
+})();
+
+
+(function TestFloatishAssignment() {
+  function Module(stdlib, foreign, heap) {
+    "use asm";
+    var HEAPF32 = new stdlib.Float32Array(heap);
+    var fround = stdlib.Math.fround;
+    function func() {
+      var a = fround(1.0);
+      var b = fround(2.0);
+      HEAPF32[0] = a + b;
+      return +HEAPF32[0];
+    }
+    return {func: func};
+  }
+
+  var m = _WASMEXP_.instantiateModuleFromAsm(Module.toString());
+  assertEquals(3, m.func());
+})  // TODO(bradnelson): Enable when Math.fround implementation lands.