Merge V8 5.2.361.47  DO NOT MERGE

https://chromium.googlesource.com/v8/v8/+/5.2.361.47

FPIIM-449

Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/test/mjsunit/wasm/adapter-frame.js b/test/mjsunit/wasm/adapter-frame.js
index 0e5d4b8..39164c7 100644
--- a/test/mjsunit/wasm/adapter-frame.js
+++ b/test/mjsunit/wasm/adapter-frame.js
@@ -27,8 +27,10 @@
 
   var builder = new WasmModuleBuilder();
   var sig = new Array();
-  sig.push(type);
+  sig.push(args);
   for (var i = 0; i < args; i++) sig.push(type);
+  sig.push(1);
+  sig.push(type);
   builder.addFunction("select", sig)
     .addBody([kExprGetLocal, which])
     .exportFunc();
diff --git a/test/mjsunit/wasm/asm-wasm-switch.js b/test/mjsunit/wasm/asm-wasm-switch.js
new file mode 100644
index 0000000..bbdb1a2
--- /dev/null
+++ b/test/mjsunit/wasm/asm-wasm-switch.js
@@ -0,0 +1,468 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-wasm
+
+(function TestSwitch0() {
+  function asmModule() {
+    "use asm"
+
+    function caller() {
+      var ret = 0;
+      var x = 7;
+      switch (x) {
+        case 1: {
+          return 0;
+        }
+        case 7: {
+          ret = 5;
+          break;
+        }
+        default: return 0;
+      }
+      return ret|0;
+    }
+
+    return {caller:caller};
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(5, wasm.caller());
+})();
+
+(function TestSwitch() {
+  function asmModule() {
+    "use asm"
+
+    function caller() {
+      var ret = 0;
+      var x = 7;
+      switch (x) {
+        case 1: return 0;
+        case 7: {
+          ret = 12;
+          break;
+        }
+        default: return 0;
+      }
+      switch (x) {
+        case 1: return 0;
+        case 8: return 0;
+        default: ret = (ret + 11)|0;
+      }
+      return ret|0;
+    }
+
+    return {caller:caller};
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(23, wasm.caller());
+})();
+
+(function TestSwitchFallthrough() {
+  function asmModule() {
+    "use asm"
+
+    function caller() {
+      var x = 17;
+      var ret = 0;
+      switch (x) {
+        case 17:
+        case 14: ret = 39;
+        case 1: ret = (ret + 3)|0;
+        case 4: break;
+        default: ret = (ret + 1)|0;
+      }
+      return ret|0;
+    }
+
+    return {caller:caller};
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(42, wasm.caller());
+})();
+
+(function TestNestedSwitch() {
+  function asmModule() {
+    "use asm"
+
+    function caller() {
+      var x = 3;
+      var y = -13;
+      switch (x) {
+        case 1: return 0;
+        case 3: {
+          switch (y) {
+            case 2: return 0;
+            case -13: return 43;
+            default: return 0;
+          }
+        }
+        default: return 0;
+      }
+      return 0;
+    }
+
+    return {caller:caller};
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(43, wasm.caller());
+})();
+
+(function TestSwitchWithDefaultOnly() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+        default: return -10;
+      }
+      return 0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(-10, wasm.main(2));
+  assertEquals(-10, wasm.main(54));
+})();
+
+(function TestEmptySwitch() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+      }
+      return 73;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(73, wasm.main(7));
+})();
+
+(function TestSwitchWithBrTable() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+        case 14: return 23;
+        case 12: return 25;
+        case 15: return 29;
+        case 19: return 34;
+        case 18: return 17;
+        case 16: return 16;
+        default: return -1;
+      }
+      return 0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(25, wasm.main(12));
+  assertEquals(23, wasm.main(14));
+  assertEquals(29, wasm.main(15));
+  assertEquals(16, wasm.main(16));
+  assertEquals(17, wasm.main(18));
+  assertEquals(34, wasm.main(19));
+  assertEquals(-1, wasm.main(-1));
+})();
+
+(function TestSwitchWithBalancedTree() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+        case 5: return 52;
+        case 1: return 11;
+        case 6: return 63;
+        case 9: return 19;
+        case -4: return -4;
+      }
+      return 0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(-4, wasm.main(-4));
+  assertEquals(11, wasm.main(1));
+  assertEquals(52, wasm.main(5));
+  assertEquals(63, wasm.main(6));
+  assertEquals(19, wasm.main(9));
+  assertEquals(0, wasm.main(11));
+})();
+
+(function TestSwitchHybrid() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      switch(x|0) {
+        case 1: return -4;
+        case 2: return 23;
+        case 3: return 32;
+        case 4: return 14;
+        case 7: return 17;
+        case 10: return 10;
+        case 11: return 121;
+        case 12: return 112;
+        case 13: return 31;
+        case 16: return 16;
+        default: return -1;
+      }
+      return 0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(-4, wasm.main(1));
+  assertEquals(23, wasm.main(2));
+  assertEquals(32, wasm.main(3));
+  assertEquals(14, wasm.main(4));
+  assertEquals(17, wasm.main(7));
+  assertEquals(10, wasm.main(10));
+  assertEquals(121, wasm.main(11));
+  assertEquals(112, wasm.main(12));
+  assertEquals(31, wasm.main(13));
+  assertEquals(16, wasm.main(16));
+  assertEquals(-1, wasm.main(20));
+})();
+
+(function TestSwitchFallthroughWithBrTable() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      var ret = 0;
+      switch(x|0) {
+        case 1: {
+          ret = 21;
+          break;
+        }
+        case 2: {
+          ret = 12;
+          break;
+        }
+        case 3: {
+          ret = 43;
+        }
+        case 4: {
+          ret = 54;
+          break;
+        }
+        default: {
+          ret = 10;
+          break;
+        }
+      }
+      return ret|0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(12, wasm.main(2));
+  assertEquals(10, wasm.main(10));
+  assertEquals(54, wasm.main(3));
+})();
+
+(function TestSwitchFallthroughHybrid() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      var ret = 0;
+      switch(x|0) {
+        case 1: {
+          ret = 1;
+          break;
+        }
+        case 2: {
+          ret = 2;
+          break;
+        }
+        case 3: {
+          ret = 3;
+          break;
+        }
+        case 4: {
+          ret = 4;
+        }
+        case 7: {
+          ret = 7;
+          break;
+        }
+        case 10: {
+          ret = 10;
+        }
+        case 16: {
+          ret = 16;
+          break;
+        }
+        case 17: {
+          ret = 17;
+          break;
+        }
+        case 18: {
+          ret = 18;
+          break;
+        }
+        case 19: {
+          ret = 19;
+        }
+        default: {
+          ret = -1;
+          break;
+        }
+      }
+      return ret|0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(7, wasm.main(4));
+  assertEquals(16, wasm.main(10));
+  assertEquals(-1, wasm.main(19));
+  assertEquals(-1, wasm.main(23));
+})();
+
+(function TestSwitchHybridWithNoDefault() {
+  function asmModule() {
+    "use asm";
+    function main(x) {
+      x = x|0;
+      var ret = 19;
+      switch(x|0) {
+        case 1: {
+          ret = 1;
+          break;
+        }
+        case 2: {
+          ret = 2;
+          break;
+        }
+        case 3: {
+          ret = 3;
+          break;
+        }
+        case 4: {
+          ret = 4;
+          break;
+        }
+        case 7: {
+          ret = 7;
+          break;
+        }
+      }
+      return ret|0;
+    }
+    return {
+      main: main,
+    };
+  }
+  var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+  assertEquals(2, wasm.main(2));
+  assertEquals(7, wasm.main(7));
+  assertEquals(19, wasm.main(-1));
+})();
+
+(function TestLargeSwitch() {
+  function LargeSwitchGenerator(begin, end, gap, handle_case) {
+    var str = "function asmModule() {\
+      \"use asm\";\
+      function main(x) {\
+        x = x|0;\
+        switch(x|0) {";
+    for (var i = begin; i <= end; i = i + gap) {
+      str = str.concat("case ", i.toString(), ": ", handle_case(i));
+    }
+    str = str.concat("default: return -1;\
+        }\
+        return -2;\
+      }\
+      return {main: main}; }");
+
+    var wasm = Wasm.instantiateModuleFromAsm(str);
+    return wasm;
+  }
+
+  var handle_case = function(k) {
+    return "return ".concat(k, ";");
+  }
+  var wasm = LargeSwitchGenerator(0, 513, 1, handle_case);
+  for (var i = 0; i <= 513; i++) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+
+  wasm = LargeSwitchGenerator(0, 1024, 3, handle_case);
+  for (var i = 0; i <= 1024; i = i + 3) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+
+  wasm = LargeSwitchGenerator(-2147483648, -2147483000, 1, handle_case);
+  for (var i = -2147483648; i <= -2147483000; i++) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+  assertEquals(-1, wasm.main(214748647));
+
+  wasm = LargeSwitchGenerator(-2147483648, -2147483000, 3, handle_case);
+  for (var i = -2147483648; i <= -2147483000; i = i + 3) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+  assertEquals(-1, wasm.main(214748647));
+
+  wasm = LargeSwitchGenerator(2147483000, 2147483647, 1, handle_case);
+  for (var i = 2147483000; i <= 2147483647; i++) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+  assertEquals(-1, wasm.main(-214748647));
+
+  wasm = LargeSwitchGenerator(2147483000, 2147483647, 4, handle_case);
+  for (var i = 2147483000; i <= 2147483647; i = i + 4) {
+    assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+  assertEquals(-1, wasm.main(-214748647));
+
+  handle_case = function(k) {
+    if (k != 7) return "return ".concat(k, ";");
+    else return "break;";
+  }
+  wasm = LargeSwitchGenerator(0, 1499, 7, handle_case);
+  for (var i = 0; i <= 1499; i = i + 7) {
+    if (i == 7) assertEquals(-2, wasm.main(i));
+    else assertEquals(i, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+
+  handle_case = function(k) {
+    if (k != 56) return "break;";
+    else return "return 23;";
+  }
+  wasm = LargeSwitchGenerator(0, 638, 2, handle_case);
+  for (var i = 0; i <= 638; i = i + 2) {
+    if (i == 56) assertEquals(23, wasm.main(i));
+    else assertEquals(-2, wasm.main(i));
+  }
+  assertEquals(-1, wasm.main(-1));
+})();
diff --git a/test/mjsunit/wasm/asm-wasm.js b/test/mjsunit/wasm/asm-wasm.js
index 2efb006..54d7d7a 100644
--- a/test/mjsunit/wasm/asm-wasm.js
+++ b/test/mjsunit/wasm/asm-wasm.js
@@ -23,6 +23,20 @@
 
 assertWasm(11, EmptyTest);
 
+function VoidReturnTest() {
+  "use asm";
+  function caller() {
+    empty();
+    return 19;
+  }
+  function empty() {
+    var x = 0;
+    if (x) return;
+  }
+  return {caller: caller};
+}
+
+assertWasm(19, VoidReturnTest);
 
 function IntTest() {
   "use asm";
@@ -193,6 +207,55 @@
 assertWasm(7, TestReturnInWhileWithoutBraces);
 
 
+function TestBreakInIf() {
+  "use asm";
+
+  function caller() {
+    label: {
+      if(1) break label;
+      return 11;
+    }
+    return 12;
+  }
+
+  return {caller: caller};
+}
+
+assertWasm(12, TestBreakInIf);
+
+function TestBreakInIfInDoWhileFalse() {
+  "use asm";
+
+  function caller() {
+    do {
+      if(1) break;
+      return 11;
+    } while(0);
+    return 12;
+  }
+
+  return {caller: caller};
+}
+
+assertWasm(12, TestBreakInIfInDoWhileFalse);
+
+function TestBreakInElse() {
+  "use asm";
+
+  function caller() {
+    do {
+      if(0) ;
+      else break;
+      return 14;
+    } while(0);
+    return 15;
+  }
+
+  return {caller: caller};
+}
+
+assertWasm(15, TestBreakInElse);
+
 function TestBreakInWhile() {
   "use asm";
 
@@ -209,6 +272,22 @@
 assertWasm(8, TestBreakInWhile);
 
 
+function TestBreakInIfInWhile() {
+  "use asm";
+
+  function caller() {
+    while(1) {
+      if (1) break;
+      else break;
+    }
+    return 8;
+  }
+
+  return {caller: caller};
+}
+
+assertWasm(8, TestBreakInIfInWhile);
+
 function TestBreakInNestedWhile() {
   "use asm";
 
@@ -769,82 +848,6 @@
 assertWasm(41, TestConditional);
 
 
-function TestSwitch() {
-  "use asm"
-
-  function caller() {
-    var ret = 0;
-    var x = 7;
-    switch (x) {
-      case 1: return 0;
-      case 7: {
-        ret = 12;
-        break;
-      }
-      default: return 0;
-    }
-    switch (x) {
-      case 1: return 0;
-      case 8: return 0;
-      default: ret = (ret + 11)|0;
-    }
-    return ret|0;
-  }
-
-  return {caller:caller};
-}
-
-assertWasm(23, TestSwitch);
-
-
-function TestSwitchFallthrough() {
-  "use asm"
-
-  function caller() {
-    var x = 17;
-    var ret = 0;
-    switch (x) {
-      case 17:
-      case 14: ret = 39;
-      case 1: ret = (ret + 3)|0;
-      case 4: break;
-      default: ret = (ret + 1)|0;
-    }
-    return ret|0;
-  }
-
-  return {caller:caller};
-}
-
-assertWasm(42, TestSwitchFallthrough);
-
-
-function TestNestedSwitch() {
-  "use asm"
-
-  function caller() {
-    var x = 3;
-    var y = -13;
-    switch (x) {
-      case 1: return 0;
-      case 3: {
-        switch (y) {
-          case 2: return 0;
-          case -13: return 43;
-          default: return 0;
-        }
-      }
-      default: return 0;
-    }
-    return 0;
-  }
-
-  return {caller:caller};
-}
-
-assertWasm(43, TestNestedSwitch);
-
-
 (function () {
 function TestInitFunctionWithNoGlobals() {
   "use asm";
diff --git a/test/mjsunit/wasm/calls.js b/test/mjsunit/wasm/calls.js
index 11cc92a..94e97e6 100644
--- a/test/mjsunit/wasm/calls.js
+++ b/test/mjsunit/wasm/calls.js
@@ -37,20 +37,42 @@
   assertFalse(exp === null);
   assertFalse(exp === 0);
   assertEquals("function", typeof exp);
-
   return exp;
 }
 
+(function I64SubTest() {
+
+  var builder = new WasmModuleBuilder();
+
+  builder.addMemory(1, 1, true);
+  builder.addFunction("sub", kSig_l_ll)
+    .addBody([           // --
+      kExprGetLocal, 0,  // --
+      kExprGetLocal, 1,  // --
+      kExprI64Sub])      // --
+    .exportFunc()
+
+  var module = builder.instantiate();
+  assertModule(module, kPageSize);
+
+  // Check the properties of the sub function.
+  var sub = assertFunction(module, "sub");
+  assertEquals(-55, sub(33, 88));
+  assertEquals(-55555, sub(33333, 88888));
+  assertEquals(-5555555, sub(3333333, 8888888));
+})();
+
 (function SubTest() {
 
   var builder = new WasmModuleBuilder();
 
   builder.addMemory(1, 1, true);
-  builder.addFunction("sub", [kAstI32, kAstI32, kAstI32])
+  builder.addFunction("sub", kSig_i_ii)
     .addBody([
-      kExprI32Sub,                  // --
       kExprGetLocal, 0,             // --
-      kExprGetLocal, 1])            // --
+      kExprGetLocal, 1,             // --
+      kExprI32Sub,                  // --
+    ])
     .exportFunc()
 
   var module = builder.instantiate();
@@ -70,7 +92,7 @@
 
   var kPages = 2;
   builder.addMemory(kPages, kPages, true);
-  builder.addFunction("nop", [kAstStmt])
+  builder.addFunction("nop", kSig_v_v)
     .addBody([kExprNop])
     .exportFunc();
 
@@ -87,11 +109,12 @@
 
   var kPages = 3;
   builder.addMemory(kPages, kPages, true);
-  builder.addFunction("flt", [kAstI32, kAstF64, kAstF64])
+  builder.addFunction("flt", kSig_i_dd)
     .addBody([
-      kExprF64Lt,           // --
       kExprGetLocal, 0,     // --
-      kExprGetLocal, 1])    // --
+      kExprGetLocal, 1,     // --
+      kExprF64Lt            // --
+    ])                      // --
     .exportFunc();
 
   var module = builder.instantiate();
diff --git a/test/mjsunit/wasm/divrem-trap.js b/test/mjsunit/wasm/divrem-trap.js
index 976e473..6f3ff5d 100644
--- a/test/mjsunit/wasm/divrem-trap.js
+++ b/test/mjsunit/wasm/divrem-trap.js
@@ -33,8 +33,12 @@
 function makeBinop(opcode) {
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("main", [kAstI32, kAstI32, kAstI32])
-    .addBody([opcode, kExprGetLocal, 0, kExprGetLocal, 1])
+  builder.addFunction("main", kSig_i_ii)
+    .addBody([
+      kExprGetLocal, 0,           // --
+      kExprGetLocal, 1,           // --
+      opcode,                     // --
+    ])
     .exportFunc();
 
   return builder.instantiate().exports.main;
diff --git a/test/mjsunit/wasm/export-table.js b/test/mjsunit/wasm/export-table.js
index e85da9b..a41d85d 100644
--- a/test/mjsunit/wasm/export-table.js
+++ b/test/mjsunit/wasm/export-table.js
@@ -11,11 +11,12 @@
   var kReturnValue = 88;
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("main", [kAstI32])
+  builder.addFunction("main", kSig_i)
     .addBody([
-      kExprReturn,
       kExprI8Const,
-      kReturnValue])
+      kReturnValue,
+      kExprReturn, kArity1
+    ])
     .exportFunc();
 
   var module = builder.instantiate();
@@ -31,11 +32,12 @@
 
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("main", [kAstI32])
+  builder.addFunction("main", kSig_i)
     .addBody([
-      kExprReturn,
       kExprI8Const,
-      kReturnValue])
+      kReturnValue,
+      kExprReturn, kArity1
+    ])
     .exportAs("blah")
     .exportAs("foo");
 
@@ -48,3 +50,25 @@
   assertEquals(kReturnValue, module.exports.foo());
   assertEquals(kReturnValue, module.exports.blah());
 })();
+
+
+(function testNumericName() {
+  var kReturnValue = 93;
+
+  var builder = new WasmModuleBuilder();
+
+  builder.addFunction("main", kSig_i)
+    .addBody([
+      kExprI8Const,
+      kReturnValue,
+      kExprReturn, kArity1
+    ])
+    .exportAs("0");
+
+  var module = builder.instantiate();
+
+  assertEquals("object", typeof module.exports);
+  assertEquals("function", typeof module.exports["0"]);
+
+  assertEquals(kReturnValue, module.exports["0"]());
+})();
diff --git a/test/mjsunit/wasm/ffi-error.js b/test/mjsunit/wasm/ffi-error.js
index 649ee27..b6474c6 100644
--- a/test/mjsunit/wasm/ffi-error.js
+++ b/test/mjsunit/wasm/ffi-error.js
@@ -10,13 +10,14 @@
 function testCallFFI(ffi) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = [kAstI32, kAstF64, kAstF64];
+  var sig_index = kSig_i_dd;
   builder.addImport("fun", sig_index);
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,   // --
-      kExprGetLocal, 0,     // --
-      kExprGetLocal, 1])    // --
+      kExprGetLocal, 0,              // --
+      kExprGetLocal, 1,              // --
+      kExprCallFunction, kArity2, 0, // --
+    ])    // --
     .exportFunc();
 
   var module = builder.instantiate(ffi);
diff --git a/test/mjsunit/wasm/ffi.js b/test/mjsunit/wasm/ffi.js
index 61fcf02..87dfe3b 100644
--- a/test/mjsunit/wasm/ffi.js
+++ b/test/mjsunit/wasm/ffi.js
@@ -10,13 +10,14 @@
 function testCallFFI(func, check) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([kAstI32, kAstF64, kAstF64]);
+  var sig_index = builder.addSignature(kSig_i_dd);
   builder.addImport("func", sig_index);
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,       // --
-      kExprGetLocal, 0,         // --
-      kExprGetLocal, 1])        // --
+      kExprGetLocal, 0,            // --
+      kExprGetLocal, 1,            // --
+      kExprCallImport, kArity2, 0  // --
+    ])        // --
     .exportFunc();
 
   var main = builder.instantiate({func: func}).exports.main;
@@ -184,14 +185,14 @@
 
   var builder = new WasmModuleBuilder();
 
-  builder.addImport("func", [kAstStmt, type, type]);
-  builder.addFunction("main", [kAstI32, type, type])
+  builder.addImport("func", makeSig_v_xx(type));
+  builder.addFunction("main", makeSig_r_xx(kAstI32, type))
     .addBody([
-      kExprBlock, 2,          // --
-      kExprCallImport, 0,     // --
-      kExprGetLocal, 0,       // --
-      kExprGetLocal, 1,       // --
-      kExprI8Const, 99])      // --
+      kExprGetLocal, 0,            // --
+      kExprGetLocal, 1,            // --
+      kExprCallImport, kArity2, 0, // --
+      kExprI8Const, 99             // --
+    ])                             // --
     .exportFunc()
 
   var main = builder.instantiate(ffi).exports.main;
@@ -240,15 +241,15 @@
 function testCallPrint() {
   var builder = new WasmModuleBuilder();
 
-  builder.addImport("print", [kAstStmt, kAstI32]);
-  builder.addImport("print", [kAstStmt, kAstF64]);
-  builder.addFunction("main", [kAstStmt, kAstF64])
+  builder.addImport("print", makeSig_v_x(kAstI32));
+  builder.addImport("print", makeSig_v_x(kAstF64));
+  builder.addFunction("main", makeSig_v_x(kAstF64))
     .addBody([
-      kExprBlock, 2,            // --
-      kExprCallImport, 0,       // --
-      kExprI8Const, 97,         // --
-      kExprCallImport, 1,       // --
-      kExprGetLocal, 0])        // --
+      kExprI8Const, 97,             // --
+      kExprCallImport, kArity1, 0,  // --
+      kExprGetLocal, 0,             // --
+      kExprCallImport, kArity1, 1   // --
+    ])        // --
     .exportFunc()
 
   var main = builder.instantiate({print: print}).exports.main;
diff --git a/test/mjsunit/wasm/function-prototype.js b/test/mjsunit/wasm/function-prototype.js
index db04b95..25339ad 100644
--- a/test/mjsunit/wasm/function-prototype.js
+++ b/test/mjsunit/wasm/function-prototype.js
@@ -10,7 +10,7 @@
 (function TestFunctionPrototype() {
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("nine", [kAstI32])
+  builder.addFunction("nine", kSig_i)
     .addBody([kExprI8Const, 9])
     .exportFunc();
 
diff --git a/test/mjsunit/wasm/gc-frame.js b/test/mjsunit/wasm/gc-frame.js
index 8387d26..5fa9b05 100644
--- a/test/mjsunit/wasm/gc-frame.js
+++ b/test/mjsunit/wasm/gc-frame.js
@@ -10,14 +10,13 @@
 function makeFFI(func, t) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([t,t,t,t,t,t,t,t,t,t,t]);
+  var sig_index = builder.addSignature([10,t,t,t,t,t,t,t,t,t,t,1,t]);
   builder.addImport("func", sig_index);
   // Try to create a frame with lots of spilled values and parameters
   // on the stack to try to catch GC bugs in the reference maps for
   // the different parts of the stack.
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,       // --
       kExprGetLocal, 0,         // --
       kExprGetLocal, 1,         // --
       kExprGetLocal, 2,         // --
@@ -28,7 +27,7 @@
       kExprGetLocal, 7,         // --
       kExprGetLocal, 8,         // --
       kExprGetLocal, 9,         // --
-      kExprCallImport, 0,       // --
+      kExprCallImport, 10, 0,   // --
       kExprGetLocal, 0,         // --
       kExprGetLocal, 1,         // --
       kExprGetLocal, 2,         // --
@@ -38,7 +37,8 @@
       kExprGetLocal, 6,         // --
       kExprGetLocal, 7,         // --
       kExprGetLocal, 8,         // --
-      kExprGetLocal, 9          // --
+      kExprGetLocal, 9,         // --
+      kExprCallImport, 10, 0    // --
     ])                          // --
     .exportFunc();
 
diff --git a/test/mjsunit/wasm/import-table.js b/test/mjsunit/wasm/import-table.js
index 7579901..c3f8cb9 100644
--- a/test/mjsunit/wasm/import-table.js
+++ b/test/mjsunit/wasm/import-table.js
@@ -10,13 +10,13 @@
 function testCallImport(func, check) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([kAstI32, kAstF64, kAstF64]);
+  var sig_index = builder.addSignature(kSig_i_dd);
   builder.addImport("func", sig_index);
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,          // --
       kExprGetLocal, 0,            // --
-      kExprGetLocal, 1])           // --
+      kExprGetLocal, 1,            // --
+      kExprCallImport, 2, 0])      // --
     .exportAs("main");
 
   var main = builder.instantiate({func: func}).exports.main;
@@ -186,14 +186,14 @@
 
   var builder = new WasmModuleBuilder();
 
-  builder.addImport("func", [kAstStmt, type, type]);
-  builder.addFunction("main", [kAstI32, type, type])
+  builder.addImport("func", makeSig_v_xx(type));
+  builder.addFunction("main", makeSig_r_xx(kAstI32, type))
     .addBody([
-      kExprBlock, 2,              // --
-      kExprCallImport, 0,         // --
       kExprGetLocal, 0,           // --
       kExprGetLocal, 1,           // --
-      kExprI8Const, 99])
+      kExprCallImport, 2, 0,      // --
+      kExprI8Const, 99,           // --
+    ])
     .exportFunc("main");
 
   var main = builder.instantiate(ffi).exports.main;
@@ -241,15 +241,15 @@
 
 function testCallPrint() {
   var builder = new WasmModuleBuilder();
-  builder.addImport("print", [kAstStmt, kAstI32]);
-  builder.addImport("print", [kAstStmt, kAstF64]);
-  builder.addFunction("main", [kAstStmt, kAstF64])
+  builder.addImport("print", makeSig_v_x(kAstI32));
+  builder.addImport("print", makeSig_r_x(kAstF64, kAstF64));
+  builder.addFunction("main", makeSig_r_x(kAstF64, kAstF64))
     .addBody([
-      kExprBlock, 2,              // --
-      kExprCallImport, 0,         // --
-      kExprI8Const, 97,           // --
-      kExprCallImport, 1,         // --
-      kExprGetLocal, 0])          // --
+      kExprI8Const, 97,             // --
+      kExprCallImport, kArity1, 0,  // --
+      kExprGetLocal, 0,             // --
+      kExprCallImport, kArity1, 1   // --
+    ])
     .exportFunc();
 
   var main = builder.instantiate({print: print}).exports.main;
@@ -266,13 +266,14 @@
 function testCallImport2(foo, bar, expected) {
   var builder = new WasmModuleBuilder();
 
-  builder.addImport("foo", [kAstI32]);
-  builder.addImport("bar", [kAstI32]);
-  builder.addFunction("main", [kAstI32])
+  builder.addImport("foo", kSig_i);
+  builder.addImport("bar", kSig_i);
+  builder.addFunction("main", kSig_i)
     .addBody([
+      kExprCallImport, kArity0, 0, // --
+      kExprCallImport, kArity0, 1, // --
       kExprI32Add,                 // --
-      kExprCallImport, 0,          // --
-      kExprCallImport, 1])          // --
+    ])                             // --
     .exportFunc();
 
   var main = builder.instantiate({foo: foo, bar: bar}).exports.main;
diff --git a/test/mjsunit/wasm/indirect-calls.js b/test/mjsunit/wasm/indirect-calls.js
index 3258687..80bee41 100644
--- a/test/mjsunit/wasm/indirect-calls.js
+++ b/test/mjsunit/wasm/indirect-calls.js
@@ -10,22 +10,25 @@
 var module = (function () {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([kAstI32, kAstI32, kAstI32]);
+  var sig_index = builder.addSignature(kSig_i_ii);
   builder.addImport("add", sig_index);
   builder.addFunction("add", sig_index)
     .addBody([
-      kExprCallImport, 0, kExprGetLocal, 0, kExprGetLocal, 1
+      kExprGetLocal, 0, kExprGetLocal, 1, kExprCallImport, kArity2, 0
     ]);
   builder.addFunction("sub", sig_index)
     .addBody([
-      kExprI32Sub, kExprGetLocal, 0, kExprGetLocal, 1
+      kExprGetLocal, 0,             // --
+      kExprGetLocal, 1,             // --
+      kExprI32Sub,                  // --
     ]);
-  builder.addFunction("main", [kAstI32, kAstI32, kAstI32, kAstI32])
+  builder.addFunction("main", kSig_i_iii)
     .addBody([
-      kExprCallIndirect, sig_index,
       kExprGetLocal, 0,
       kExprGetLocal, 1,
-      kExprGetLocal, 2])
+      kExprGetLocal, 2,
+      kExprCallIndirect, kArity2, sig_index
+    ])
     .exportFunc()
   builder.appendToFunctionTable([0, 1, 2]);
 
diff --git a/test/mjsunit/wasm/instantiate-module-basic.js b/test/mjsunit/wasm/instantiate-module-basic.js
index bc13122..800dcc1 100644
--- a/test/mjsunit/wasm/instantiate-module-basic.js
+++ b/test/mjsunit/wasm/instantiate-module-basic.js
@@ -13,7 +13,7 @@
   var builder = new WasmModuleBuilder();
 
   builder.addMemory(1, 1, true);
-  builder.addFunction("main", [kAstI32])
+  builder.addFunction("main", kSig_i)
     .addBody([kExprI8Const, kReturnValue])
     .exportFunc();
 
diff --git a/test/mjsunit/wasm/instantiate-run-basic.js b/test/mjsunit/wasm/instantiate-run-basic.js
index 2e649a0..fe6fc14 100644
--- a/test/mjsunit/wasm/instantiate-run-basic.js
+++ b/test/mjsunit/wasm/instantiate-run-basic.js
@@ -11,7 +11,7 @@
   var kReturnValue = 107;
   var builder = new WasmModuleBuilder();
 
-  builder.addFunction("main", [kAstI32])
+  builder.addFunction("main", kSig_i_i)
     .addBody([kExprI8Const, kReturnValue])
     .exportFunc();
 
diff --git a/test/mjsunit/wasm/module-memory.js b/test/mjsunit/wasm/module-memory.js
index ef85eb2..a5e5f42 100644
--- a/test/mjsunit/wasm/module-memory.js
+++ b/test/mjsunit/wasm/module-memory.js
@@ -13,19 +13,27 @@
   var builder = new WasmModuleBuilder();
 
   builder.addMemory(1, 1, true);
-  builder.addFunction("main", [kAstI32, kAstI32])
+  builder.addFunction("main", kSig_i_i)
     .addBody([
-      kExprBlock,2,
-        kExprLoop,1,
-          kExprIf,
+    // main body: while(i) { if(mem[i]) return -1; i -= 4; } return 0;
+      kExprLoop,
+        kExprGetLocal,0,
+        kExprIf,
             kExprGetLocal,0,
-            kExprBr, 0,
-              kExprIfElse,
-                kExprI32LoadMem,0,0,kExprGetLocal,0,
-                kExprBr,2, kExprI8Const, 255,
-                kExprSetLocal,0,
-                  kExprI32Sub,kExprGetLocal,0,kExprI8Const,4,
-        kExprI8Const,0])
+          kExprI32LoadMem,0,0,
+          kExprIf,
+            kExprI8Const,255,
+            kExprReturn, kArity1,
+          kExprEnd,
+              kExprGetLocal,0,
+              kExprI8Const,4,
+            kExprI32Sub,
+          kExprSetLocal,0,
+        kExprBr, kArity1, 1,
+        kExprEnd,
+      kExprEnd,
+      kExprI8Const,0
+    ])
     .exportFunc();
 
   return builder.instantiate(null, memory);
@@ -120,14 +128,16 @@
   var builder = new WasmModuleBuilder();
 
   builder.addMemory(1, 1, true);
-  builder.addFunction("geti", [kAstI32, kAstI32, kAstI32])
+  builder.addFunction("geti", kSig_i_ii)
     .addBody([
-      kExprI32StoreMem, 0, 0, kExprGetLocal, 0, kExprI32LoadMem, 0, 0, kExprGetLocal, 1
+      kExprGetLocal, 0,
+      kExprGetLocal, 1,
+      kExprI32LoadMem, 0, 0,
+      kExprI32StoreMem, 0, 0
     ])
     .exportFunc();
 
   var module = builder.instantiate();
-
   var offset;
 
   function read() { return module.exports.geti(0, offset); }
diff --git a/test/mjsunit/wasm/parallel_compilation.js b/test/mjsunit/wasm/parallel_compilation.js
new file mode 100644
index 0000000..23c5658
--- /dev/null
+++ b/test/mjsunit/wasm/parallel_compilation.js
@@ -0,0 +1,100 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-wasm --wasm-num-compilation-tasks=10
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+function assertModule(module, memsize) {
+  // Check the module exists.
+  assertFalse(module === undefined);
+  assertFalse(module === null);
+  assertFalse(module === 0);
+  assertEquals("object", typeof module);
+
+  // Check the memory is an ArrayBuffer.
+  var mem = module.exports.memory;
+  assertFalse(mem === undefined);
+  assertFalse(mem === null);
+  assertFalse(mem === 0);
+  assertEquals("object", typeof mem);
+  assertTrue(mem instanceof ArrayBuffer);
+  for (var i = 0; i < 4; i++) {
+    module.exports.memory = 0;  // should be ignored
+    assertEquals(mem, module.exports.memory);
+  }
+
+  assertEquals(memsize, module.exports.memory.byteLength);
+}
+
+function assertFunction(module, func) {
+  assertEquals("object", typeof module.exports);
+
+  var exp = module.exports[func];
+  assertFalse(exp === undefined);
+  assertFalse(exp === null);
+  assertFalse(exp === 0);
+  assertEquals("function", typeof exp);
+  return exp;
+}
+
+(function CompileFunctionsTest() {
+
+  var builder = new WasmModuleBuilder();
+
+  builder.addMemory(1, 1, true);
+  for (i = 0; i < 1000; i++) {
+    builder.addFunction("sub" + i, kSig_i_i)
+      .addBody([                // --
+        kExprGetLocal, 0,       // --
+        kExprI32Const, i % 61,  // --
+        kExprI32Sub])           // --
+      .exportFunc()
+  }
+
+  var module = builder.instantiate();
+  assertModule(module, kPageSize);
+
+  // Check the properties of the functions.
+  for (i = 0; i < 1000; i++) {
+    var sub = assertFunction(module, "sub" + i);
+    assertEquals(33 - (i % 61), sub(33));
+  }
+})();
+
+(function CallFunctionsTest() {
+
+  var builder = new WasmModuleBuilder();
+
+  var f = []
+
+  f[0] = builder.addFunction("add0", kSig_i_ii)
+  .addBody([
+            kExprGetLocal, 0,             // --
+            kExprGetLocal, 1,             // --
+            kExprI32Add,                  // --
+          ])
+          .exportFunc()
+
+  builder.addMemory(1, 1, true);
+  for (i = 1; i < 256; i++) {
+    f[i] = builder.addFunction("add" + i, kSig_i_ii)
+      .addBody([                                            // --
+        kExprGetLocal, 0,                                   // --
+        kExprGetLocal, 1,                                   // --
+        kExprCallFunction, kArity2, f[i >>> 1].index])      // --
+      .exportFunc()
+  }
+  var module = builder.instantiate();
+  assertModule(module, kPageSize);
+
+  // Check the properties of the functions.
+  for (i = 0; i < 256; i++) {
+    var add = assertFunction(module, "add" + i);
+    assertEquals(88, add(33, 55));
+    assertEquals(88888, add(33333, 55555));
+    assertEquals(8888888, add(3333333, 5555555));
+  }
+})();
diff --git a/test/mjsunit/wasm/params.js b/test/mjsunit/wasm/params.js
index 7c2b3d1..180ab1c 100644
--- a/test/mjsunit/wasm/params.js
+++ b/test/mjsunit/wasm/params.js
@@ -17,7 +17,7 @@
 
     var builder = new WasmModuleBuilder();
 
-    builder.addFunction("select", [type, type, type])
+    builder.addFunction("select", makeSig_r_xx(type, type))
       .addBody([kExprGetLocal, which])
       .exportFunc()
 
@@ -79,7 +79,7 @@
     print("type = " + t + ", which = " + which);
 
     var builder = new WasmModuleBuilder();
-    builder.addFunction("select", [t,t,t,t,t,t,t,t,t,t,t])
+    builder.addFunction("select", [10,t,t,t,t,t,t,t,t,t,t,1,t])
       .addBody([kExprGetLocal, which])
       .exportFunc();
 
diff --git a/test/mjsunit/wasm/stack.js b/test/mjsunit/wasm/stack.js
index ed05517..a45db94 100644
--- a/test/mjsunit/wasm/stack.js
+++ b/test/mjsunit/wasm/stack.js
@@ -2,39 +2,129 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// clang-format off
 // Flags: --expose-wasm
 
 load("test/mjsunit/wasm/wasm-constants.js");
 load("test/mjsunit/wasm/wasm-module-builder.js");
 
-var expected = "Error\n" +
-    // The line numbers below will change as this test gains / loses lines..
-    "    at STACK (stack.js:24:11)\n" +     // --
-    "    at <WASM> (<anonymous>)\n" +       // TODO(jfb): wasm stack here.
-    "    at testStack (stack.js:38:18)\n" + // --
-    "    at stack.js:40:3";                 // --
-
 // The stack trace contains file path, only keep "stack.js".
 function stripPath(s) {
   return s.replace(/[^ (]*stack\.js/g, "stack.js");
 }
 
+function verifyStack(frames, expected) {
+  assertEquals(expected.length, frames.length, "number of frames mismatch");
+  expected.forEach(function(exp, i) {
+    if (exp[1] != "?") {
+      assertEquals(exp[1], frames[i].getFunctionName(),
+          "["+i+"].getFunctionName()");
+    }
+    assertEquals(exp[2], frames[i].getLineNumber(), "["+i+"].getLineNumber()");
+    if (exp[0])
+      assertEquals(exp[3], frames[i].getPosition(),
+          "["+i+"].getPosition()");
+    assertContains(exp[4], frames[i].getFileName(), "["+i+"].getFileName()");
+    var toString;
+    if (exp[0]) {
+      var funName = exp[1] == "?" ? "" : exp[1];
+      toString = funName + " (<WASM>:" + exp[2] + ":" + exp[3] + ")";
+    } else {
+      toString = exp[4] + ":" + exp[2] + ":";
+    }
+    assertContains(toString, frames[i].toString(), "["+i+"].toString()");
+  });
+}
+
+
 var stack;
 function STACK() {
   var e = new Error();
   stack = e.stack;
 }
 
-(function testStack() {
-  var builder = new WasmModuleBuilder();
+var builder = new WasmModuleBuilder();
 
-  builder.addImport("func", [kAstStmt]);
+builder.addImport("func", kSig_v_v);
 
-  builder.addFunction(undefined, [kAstStmt])
-    .addBody([kExprCallImport, 0])
-    .exportAs("main");
+builder.addFunction("main", kSig_v_v)
+  .addBody([kExprCallImport, kArity0, 0])
+  .exportAs("main");
 
-  var module = builder.instantiate({func: STACK});
+builder.addFunction("exec_unreachable", kSig_v_v)
+  .addBody([kExprUnreachable])
+  .exportAs("exec_unreachable");
+
+// Make this function unnamed, just to test also this case.
+var mem_oob_func = builder.addFunction(undefined, kSig_v_v)
+  // Access the memory at offset -1, to provoke a trap.
+  .addBody([kExprI32Const, 0x7f, kExprI32LoadMem8S, 0, 0])
+  .exportAs("mem_out_of_bounds");
+
+// Call the mem_out_of_bounds function, in order to have two WASM stack frames.
+builder.addFunction("call_mem_out_of_bounds", kSig_v_v)
+  .addBody([kExprCallFunction, kArity0, mem_oob_func.index])
+  .exportAs("call_mem_out_of_bounds");
+
+var module = builder.instantiate({func: STACK});
+
+(function testSimpleStack() {
+  var expected_string = "Error\n" +
+    // The line numbers below will change as this test gains / loses lines..
+    "    at STACK (stack.js:42:11)\n" +           // --
+    "    at main (<WASM>:0:1)\n" +                // --
+    "    at testSimpleStack (stack.js:79:18)\n" + // --
+    "    at stack.js:81:3";                       // --
+
   module.exports.main();
-  assertEquals(expected, stripPath(stack));
+  assertEquals(expected_string, stripPath(stack));
+})();
+
+// For the remaining tests, collect the Callsite objects instead of just a
+// string:
+Error.prepareStackTrace = function(error, frames) {
+  return frames;
+};
+
+(function testStackFrames() {
+  module.exports.main();
+
+  verifyStack(stack, [
+      // isWasm           function   line  pos        file
+      [   false,           "STACK",    42,   0, "stack.js"],
+      [    true,            "main",     0,   1,       null],
+      [   false, "testStackFrames",    90,   0, "stack.js"],
+      [   false,              null,    99,   0, "stack.js"]
+  ]);
+})();
+
+(function testWasmUnreachable() {
+  try {
+    module.exports.exec_unreachable();
+    fail("expected wasm exception");
+  } catch (e) {
+    assertContains("unreachable", e.message);
+    verifyStack(e.stack, [
+        // isWasm               function   line  pos        file
+        [    true,    "exec_unreachable",    1,    1,       null],
+        [   false, "testWasmUnreachable",  103,    0, "stack.js"],
+        [   false,                  null,  114,    0, "stack.js"]
+    ]);
+  }
+})();
+
+(function testWasmMemOutOfBounds() {
+  try {
+    module.exports.call_mem_out_of_bounds();
+    fail("expected wasm exception");
+  } catch (e) {
+    assertContains("out of bounds", e.message);
+    verifyStack(e.stack, [
+        // isWasm                  function   line  pos        file
+        [    true,                      "?",     2,   3,       null],
+        [    true, "call_mem_out_of_bounds",     3,   1,       null],
+        [   false, "testWasmMemOutOfBounds",   118,   0, "stack.js"],
+        [   false,                     null,   130,   0, "stack.js"]
+    ]);
+  }
 })();
diff --git a/test/mjsunit/wasm/stackwalk.js b/test/mjsunit/wasm/stackwalk.js
index 8b8fb7e..5e5a1ef 100644
--- a/test/mjsunit/wasm/stackwalk.js
+++ b/test/mjsunit/wasm/stackwalk.js
@@ -10,13 +10,14 @@
 function makeFFI(func) {
   var builder = new WasmModuleBuilder();
 
-  var sig_index = builder.addSignature([kAstI32, kAstF64, kAstF64]);
+  var sig_index = builder.addSignature(kSig_i_dd);
   builder.addImport("func", sig_index);
   builder.addFunction("main", sig_index)
     .addBody([
-      kExprCallImport, 0,       // --
-      kExprGetLocal, 0,         // --
-      kExprGetLocal, 1])        // --
+      kExprGetLocal, 0,            // --
+      kExprGetLocal, 1,            // --
+      kExprCallImport, kArity2, 0, // --
+    ])
     .exportFunc()
 
   return builder.instantiate({func: func}).exports.main;
diff --git a/test/mjsunit/wasm/start-function.js b/test/mjsunit/wasm/start-function.js
index bd4ccf2..3c5707a 100644
--- a/test/mjsunit/wasm/start-function.js
+++ b/test/mjsunit/wasm/start-function.js
@@ -37,19 +37,19 @@
   return module;
 }
 
-assertVerifies([kAstStmt], [kExprNop]);
-assertVerifies([kAstI32], [kExprI8Const, 0]);
+assertVerifies(kSig_v_v, [kExprNop]);
+assertVerifies(kSig_i, [kExprI8Const, 0]);
 
 // Arguments aren't allow to start functions.
-assertFails([kAstI32, kAstI32], [kExprGetLocal, 0]);
-assertFails([kAstI32, kAstI32, kAstF32], [kExprGetLocal, 0]);
-assertFails([kAstI32, kAstI32, kAstF32, kAstF64], [kExprGetLocal, 0]);
+assertFails(kSig_i_i, [kExprGetLocal, 0]);
+assertFails(kSig_i_ii, [kExprGetLocal, 0]);
+assertFails(kSig_i_dd, [kExprGetLocal, 0]);
 
 (function testInvalidIndex() {
   print("testInvalidIndex");
   var builder = new WasmModuleBuilder();
 
-  var func = builder.addFunction("", [kAstStmt])
+  var func = builder.addFunction("", kSig_v_v)
     .addBody([kExprNop]);
 
   builder.addStart(func.index + 1);
@@ -62,7 +62,7 @@
   print("testTwoStartFuncs");
   var builder = new WasmModuleBuilder();
 
-  var func = builder.addFunction("", [kAstStmt])
+  var func = builder.addFunction("", kSig_v_v)
     .addBody([kExprNop]);
 
   builder.addExplicitSection([kDeclStartFunction, 0]);
@@ -78,8 +78,8 @@
 
   builder.addMemory(12, 12, true);
 
-  var func = builder.addFunction("", [kAstStmt])
-    .addBody([kExprI32StoreMem, 0, 0, kExprI8Const, 0, kExprI8Const, 77]);
+  var func = builder.addFunction("", kSig_v_v)
+    .addBody([kExprI8Const, 0, kExprI8Const, 77, kExprI32StoreMem, 0, 0]);
 
   builder.addStart(func.index);
 
@@ -98,11 +98,11 @@
   }};
 
   var builder = new WasmModuleBuilder();
-  var sig_index = builder.addSignature([kAstStmt]);
+  var sig_index = builder.addSignature(kSig_v_v);
 
   builder.addImport("foo", sig_index);
   var func = builder.addFunction("", sig_index)
-    .addBody([kExprCallImport, 0]);
+    .addBody([kExprCallImport, kArity0, 0]);
 
   builder.addStart(func.index);
 
diff --git a/test/mjsunit/wasm/test-wasm-module-builder.js b/test/mjsunit/wasm/test-wasm-module-builder.js
index 50797d0..969b550 100644
--- a/test/mjsunit/wasm/test-wasm-module-builder.js
+++ b/test/mjsunit/wasm/test-wasm-module-builder.js
@@ -12,7 +12,7 @@
 (function BasicTest() {
     var module = new WasmModuleBuilder();
     module.addMemory(1, 2, false);
-    module.addFunction("foo", [kAstI32])
+    module.addFunction("foo", kSig_i)
         .addBody([kExprI8Const, 11])
         .exportAs("blarg");
 
@@ -23,9 +23,9 @@
 
 (function ImportTest() {
     var module = new WasmModuleBuilder();
-    var index = module.addImport("print", [kAstStmt, kAstI32]);
-    module.addFunction("foo", [kAstStmt])
-        .addBody([kExprCallImport, index, kExprI8Const, 13])
+    var index = module.addImport("print", makeSig_v_x(kAstI32));
+    module.addFunction("foo", kSig_v_v)
+        .addBody([kExprI8Const, 13, kExprCallImport, kArity1, index])
         .exportAs("main");
 
     var buffer = module.toBuffer(debug);
@@ -36,9 +36,9 @@
 
 (function LocalsTest() {
     var module = new WasmModuleBuilder();
-    module.addFunction(undefined, [kAstI32, kAstI32])
+    module.addFunction(undefined, kSig_i_i)
         .addLocals({i32_count: 1})
-        .addBody([kExprSetLocal, 1, kExprGetLocal, 0])
+        .addBody([kExprGetLocal, 0, kExprSetLocal, 1])
         .exportAs("main");
 
     var buffer = module.toBuffer(debug);
@@ -58,9 +58,9 @@
 
     for (p of types) {
       var module = new WasmModuleBuilder();
-      module.addFunction(undefined, [p.type, p.type])
+      module.addFunction(undefined, makeSig_r_x(p.type, p.type))
         .addLocals(p.locals)
-        .addBody([kExprSetLocal, 1, kExprGetLocal, 0])
+        .addBody([kExprGetLocal, 0, kExprSetLocal, 1])
         .exportAs("main");
 
       var buffer = module.toBuffer(debug);
@@ -72,10 +72,10 @@
 
 (function CallTest() {
     var module = new WasmModuleBuilder();
-    module.addFunction("add", [kAstI32, kAstI32, kAstI32])
-        .addBody([kExprI32Add, kExprGetLocal, 0, kExprGetLocal, 1]);
-    module.addFunction("main", [kAstI32, kAstI32, kAstI32])
-        .addBody([kExprCallFunction, 0, kExprGetLocal, 0, kExprGetLocal, 1])
+    module.addFunction("add", kSig_i_ii)
+        .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
+    module.addFunction("main", kSig_i_ii)
+        .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprCallFunction, kArity2, 0])
         .exportAs("main");
 
     var instance = module.instantiate();
@@ -85,11 +85,11 @@
 
 (function IndirectCallTest() {
     var module = new WasmModuleBuilder();
-    module.addFunction("add", [kAstI32, kAstI32, kAstI32])
-        .addBody([kExprI32Add, kExprGetLocal, 0, kExprGetLocal, 1]);
-    module.addFunction("main", [kAstI32, kAstI32, kAstI32, kAstI32])
-        .addBody([kExprCallIndirect, 0, kExprGetLocal,
-                  0, kExprGetLocal, 1, kExprGetLocal, 2])
+    module.addFunction("add", kSig_i_ii)
+        .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
+    module.addFunction("main", kSig_i_iii)
+        .addBody([kExprGetLocal,
+                  0, kExprGetLocal, 1, kExprGetLocal, 2, kExprCallIndirect, kArity2, 0])
         .exportAs("main");
     module.appendToFunctionTable([0]);
 
@@ -102,8 +102,8 @@
 (function DataSegmentTest() {
     var module = new WasmModuleBuilder();
     module.addMemory(1, 1, false);
-    module.addFunction("load", [kAstI32, kAstI32])
-        .addBody([kExprI32LoadMem, 0, 0, kExprGetLocal, 0])
+    module.addFunction("load", kSig_i_i)
+        .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0])
         .exportAs("load");
     module.addDataSegment(0, [9, 9, 9, 9], true);
 
@@ -116,7 +116,7 @@
 (function BasicTestWithUint8Array() {
     var module = new WasmModuleBuilder();
     module.addMemory(1, 2, false);
-    module.addFunction("foo", [kAstI32])
+    module.addFunction("foo", kSig_i)
         .addBody([kExprI8Const, 17])
         .exportAs("blarg");
 
@@ -141,9 +141,9 @@
 
 (function ImportTestTwoLevel() {
     var module = new WasmModuleBuilder();
-    var index = module.addImportWithModule("mod", "print", [kAstStmt, kAstI32]);
-    module.addFunction("foo", [kAstStmt])
-        .addBody([kExprCallImport, index, kExprI8Const, 19])
+    var index = module.addImportWithModule("mod", "print", makeSig_v_x(kAstI32));
+    module.addFunction("foo", kSig_v_v)
+        .addBody([kExprI8Const, 19, kExprCallImport, kArity1, index])
         .exportAs("main");
 
     var buffer = module.toBuffer(debug);
diff --git a/test/mjsunit/wasm/trap-location.js b/test/mjsunit/wasm/trap-location.js
new file mode 100644
index 0000000..5e3661d
--- /dev/null
+++ b/test/mjsunit/wasm/trap-location.js
@@ -0,0 +1,78 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-wasm
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+// Collect the Callsite objects instead of just a string:
+Error.prepareStackTrace = function(error, frames) {
+  return frames;
+};
+
+var builder = new WasmModuleBuilder();
+
+var sig_index = builder.addSignature(kSig_i_v)
+
+// Build a function to resemble this code:
+//   if (idx < 2) {
+//     return load(-2 / idx);
+//   } else if (idx == 2) {
+//     unreachable;
+//   } else {
+//     return call_indirect(idx);
+//   }
+// There are four different traps which are triggered by different input values:
+// (0) division by zero; (1) mem oob; (2) unreachable; (3) invalid call target
+// Each of them also has a different location where it traps.
+builder.addFunction("main", kSig_i_i)
+  .addBody([
+      // offset 1
+      kExprBlock,
+            kExprGetLocal, 0,
+            kExprI32Const, 2,
+          kExprI32LtU,
+        kExprIf,
+        // offset 8
+              kExprI32Const, 0x7e /* -2 */,
+              kExprGetLocal, 0,
+            kExprI32DivU,
+          // offset 13
+          kExprI32LoadMem, 0, 0,
+          kExprBr, 1, 1,
+        kExprEnd,
+        // offset 20
+            kExprGetLocal, 0,
+            kExprI32Const, 2,
+          kExprI32Eq,
+        kExprIf,
+          kExprUnreachable,
+        kExprEnd,
+        // offset 28
+          kExprGetLocal, 0,
+        kExprCallIndirect, kArity0, sig_index,
+      kExprEnd,
+  ])
+  .exportAs("main");
+
+var module = builder.instantiate();
+
+function testWasmTrap(value, reason, position) {
+  try {
+    module.exports.main(value);
+    fail("expected wasm exception");
+  } catch (e) {
+    assertEquals(kTrapMsgs[reason], e.message, "trap reason");
+    assertEquals(3, e.stack.length, "number of frames");
+    assertEquals(0, e.stack[0].getLineNumber(), "wasmFunctionIndex");
+    assertEquals(position, e.stack[0].getPosition(), "position");
+  }
+}
+
+// The actual tests:
+testWasmTrap(0, kTrapDivByZero,      12);
+testWasmTrap(1, kTrapMemOutOfBounds, 13);
+testWasmTrap(2, kTrapUnreachable,    26);
+testWasmTrap(3, kTrapFuncInvalid,    30);
diff --git a/test/mjsunit/wasm/unicode-validation.js b/test/mjsunit/wasm/unicode-validation.js
new file mode 100644
index 0000000..b2e4603
--- /dev/null
+++ b/test/mjsunit/wasm/unicode-validation.js
@@ -0,0 +1,121 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-wasm
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+function toByteArray(s) {
+  var arr = [];
+  for (var i = 0; i < s.length; ++i) {
+    arr.push(s.charCodeAt(i) & 0xff);
+  }
+  return arr;
+}
+
+function toString(arr) {
+  if (typeof arr === "string") return arr;
+  var s = "";
+  for (var b of arr) s += String.fromCharCode(b);
+  return s;
+}
+
+function toUTF8(arr) {
+  if (typeof arr === "string" || arr === undefined) return arr;
+  return decodeURIComponent(escape(toString(arr)));
+}
+
+function isValidUtf8(arr) {
+  if (typeof arr === "string" || arr === undefined) return true;
+  try {
+    var s = toUTF8(arr);
+    for (var i = 0; i < s.length; ++i)
+      if ((s.charCodeAt(i) & 0xfffe) == 0xfffe)
+        return false;
+    return true;
+  } catch (e) {
+    if (e instanceof URIError) return false;
+    throw e;
+  }
+}
+
+function checkImportsAndExports(imported_module_name, imported_function_name,
+    internal_function_name, exported_function_name, shouldThrow) {
+  var builder = new WasmModuleBuilder();
+
+  builder.addImportWithModule(imported_module_name, imported_function_name,
+      kSig_v_v);
+
+  builder.addFunction(internal_function_name, kSig_v_v)
+    .addBody([kExprCallImport, kArity0, 0])
+    .exportAs(exported_function_name);
+
+  // sanity check: does javascript agree with out shouldThrow annotation?
+  assertEquals(shouldThrow,
+      !isValidUtf8(imported_module_name) ||
+          !isValidUtf8(imported_function_name) ||
+          !isValidUtf8(exported_function_name),
+      "JavaScript does not agree with our shouldThrow expectation");
+
+  if (!shouldThrow) {
+    imported_module_name = toUTF8(imported_module_name);
+    imported_function_name = toUTF8(imported_function_name);
+  }
+
+  var ffi = new Object();
+  if (imported_function_name === undefined) {
+    ffi[imported_module_name] = function() { };
+  } else {
+    ffi[imported_module_name] = new Object();
+    ffi[imported_module_name][imported_function_name] = function() { };
+  }
+
+  var hasThrown = true;
+  try {
+    builder.instantiate(ffi);
+    hasThrown = false;
+  } catch (err) {
+    if (!shouldThrow) print(err);
+    assertTrue(shouldThrow, "Should not throw error on valid names");
+    assertContains("UTF-8", err.toString());
+  }
+  assertEquals(shouldThrow, hasThrown,
+      "Should throw validation error on invalid names");
+}
+
+function checkImportedModuleName(name, shouldThrow) {
+  checkImportsAndExports(name, "imp", "func", undefined, shouldThrow);
+}
+
+function checkImportedFunctionName(name, shouldThrow) {
+  checkImportsAndExports("module", name, "func", "func", shouldThrow);
+}
+
+function checkExportedFunctionName(name, shouldThrow) {
+  checkImportsAndExports("module", "func", "func", name, shouldThrow);
+}
+
+function checkInternalFunctionName(name) {
+  checkImportsAndExports("module", "func", name, "func", false);
+}
+
+function checkAll(name, shouldThrow) {
+  checkImportedModuleName(name, shouldThrow);
+  checkImportedFunctionName(name, shouldThrow);
+  checkExportedFunctionName(name, shouldThrow);
+  checkInternalFunctionName(name);
+}
+
+checkAll("ascii", false);
+checkAll("some math: (½)² = ¼", false);
+checkAll("中国历史系列条目\n北", false);
+checkAll(toByteArray("\xef\xb7\x8f"), false);
+checkAll(toByteArray("a\xc2\x81\xe1\x80\xbf\xf1\x80\xa0\xbf"), false);
+checkAll(toByteArray("\xff"), true);
+checkAll(toByteArray("\xed\xa0\x8f"), true);        // surrogate code points
+checkAll(toByteArray("\xe0\x82\x80"), true);        // overlong sequence
+checkAll(toByteArray("\xf4\x90\x80\x80"), true);    // beyond limit: U+110000
+checkAll(toByteArray("\xef\xbf\xbe"), true);        // non-character; U+FFFE
+checkAll(toByteArray("with\x00null"), false);
diff --git a/test/mjsunit/wasm/unreachable.js b/test/mjsunit/wasm/unreachable.js
index 3e2dffb..d77b53e 100644
--- a/test/mjsunit/wasm/unreachable.js
+++ b/test/mjsunit/wasm/unreachable.js
@@ -9,7 +9,7 @@
 
 var main = (function () {
   var builder = new WasmModuleBuilder();
-  builder.addFunction("main", [kAstStmt])
+  builder.addFunction("main", kSig_v_v)
     .addBody([kExprUnreachable])
     .exportAs("main");
 
@@ -23,4 +23,4 @@
     print("correctly caught: " + e);
     exception = e;
 }
-assertEquals("unreachable", exception);
+assertEquals("unreachable", exception.message);
diff --git a/test/mjsunit/wasm/verify-function-simple.js b/test/mjsunit/wasm/verify-function-simple.js
index aa5c676..31c23a6 100644
--- a/test/mjsunit/wasm/verify-function-simple.js
+++ b/test/mjsunit/wasm/verify-function-simple.js
@@ -8,9 +8,9 @@
 
 try {
   var data = bytes(
-      0,       kAstStmt,  // signature
-      kDeclNoLocals,      // --
-      kExprNop            // body
+      kWasmFunctionTypeForm, 0, kAstStmt,  // signature
+      kDeclNoLocals,                       // --
+      kExprNop                             // body
   );
 
   Wasm.verifyFunction(data);
@@ -23,9 +23,9 @@
 var threw = false;
 try {
   var data = bytes(
-      0,       kAstI32,   // signature
-      kDeclNoLocals,      // --
-      kExprBlock, 2, kExprNop, kExprNop  // body
+      kWasmFunctionTypeForm, 0, 1, kAstI32,     // signature
+      kDeclNoLocals,                            // --
+      kExprBlock, kExprNop, kExprNop, kExprEnd  // body
   );
 
   Wasm.verifyFunction(data);
diff --git a/test/mjsunit/wasm/wasm-constants.js b/test/mjsunit/wasm/wasm-constants.js
index cc620bb..389383e 100644
--- a/test/mjsunit/wasm/wasm-constants.js
+++ b/test/mjsunit/wasm/wasm-constants.js
@@ -21,7 +21,7 @@
 var kWasmH2 = 0x73;
 var kWasmH3 = 0x6d;
 
-var kWasmV0 = 10;
+var kWasmV0 = 11;
 var kWasmV1 = 0;
 var kWasmV2 = 0;
 var kWasmV3 = 0;
@@ -65,10 +65,16 @@
 var kDeclFunctionBodies = 0x0b;
 var kDeclNames = 0x0c;
 
+var kArity0 = 0;
+var kArity1 = 1;
+var kArity2 = 2;
+var kArity3 = 3;
+var kWasmFunctionTypeForm = 0x40;
+
 var section_names = [
-  "memory", "signatures", "functions", "globals", "data_segments",
-  "function_table", "end", "start_function", "import_table", "export_table",
-  "function_signatures", "function_bodies", "names"];
+  "memory", "type", "old_function", "global", "data",
+  "table", "end", "start", "import", "export",
+  "function", "code", "name"];
 
 // Function declaration flags
 var kDeclFunctionName   = 0x01;
@@ -83,31 +89,60 @@
 var kAstF32 = 3;
 var kAstF64 = 4;
 
+// Useful signatures
+var kSig_i = [0, 1, kAstI32];
+var kSig_d = [0, 1, kAstF64];
+var kSig_i_i = [1, kAstI32, 1, kAstI32];
+var kSig_i_ii = [2, kAstI32, kAstI32, 1, kAstI32];
+var kSig_i_iii = [3, kAstI32, kAstI32, kAstI32, 1, kAstI32];
+var kSig_d_dd = [2, kAstF64, kAstF64, 1, kAstF64];
+var kSig_l_ll = [2, kAstI64, kAstI64, 1, kAstI64];
+var kSig_i_dd = [2, kAstF64, kAstF64, 1, kAstI32];
+var kSig_v_v = [0, 0];
+var kSig_i_v = [0, 1, kAstI32];
+
+function makeSig_v_xx(x) {
+  return [2, x, x, 0];
+}
+
+function makeSig_v_x(x) {
+  return [1, x, 0];
+}
+
+function makeSig_r_xx(r, x) {
+  return [2, x, x, 1, r];
+}
+
+function makeSig_r_x(r, x) {
+  return [1, x, 1, r];
+}
+
 // Opcodes
 var kExprNop = 0x00;
 var kExprBlock = 0x01;
 var kExprLoop = 0x02;
 var kExprIf = 0x03;
-var kExprIfElse = 0x04;
+var kExprElse = 0x04;
 var kExprSelect = 0x05;
 var kExprBr = 0x06;
 var kExprBrIf = 0x07;
-var kExprTableSwitch = 0x08;
-var kExprReturn = 0x14;
-var kExprUnreachable = 0x15;
+var kExprBrTable = 0x08;
+var kExprReturn = 0x09;
+var kExprUnreachable = 0x0a;
+var kExprEnd = 0x0f;
 
-var kExprI8Const = 0x09;
-var kExprI32Const = 0x0a;
-var kExprI64Const = 0x0b;
-var kExprF64Const = 0x0c;
-var kExprF32Const = 0x0d;
-var kExprGetLocal = 0x0e;
-var kExprSetLocal = 0x0f;
-var kExprLoadGlobal = 0x10;
-var kExprStoreGlobal = 0x11;
-var kExprCallFunction = 0x12;
-var kExprCallIndirect = 0x13;
-var kExprCallImport = 0x1F;
+var kExprI32Const = 0x10;
+var kExprI64Const = 0x11;
+var kExprF64Const = 0x12;
+var kExprF32Const = 0x13;
+var kExprGetLocal = 0x14;
+var kExprSetLocal = 0x15;
+var kExprCallFunction = 0x16;
+var kExprCallIndirect = 0x17;
+var kExprCallImport = 0x18;
+var kExprI8Const = 0xcb;
+var kExprLoadGlobal = 0xcc;
+var kExprStoreGlobal = 0xcd;
 
 var kExprI32LoadMem8S = 0x20;
 var kExprI32LoadMem8U = 0x21;
@@ -290,8 +325,8 @@
       }
       threwException = false;
     } catch (e) {
-      assertEquals("string", typeof e);
-      assertEquals(kTrapMsgs[trap], e);
+      assertEquals("object", typeof e);
+      assertEquals(kTrapMsgs[trap], e.message);
       // Success.
       return;
     }
diff --git a/test/mjsunit/wasm/wasm-module-builder.js b/test/mjsunit/wasm/wasm-module-builder.js
index e1d9963..bfc4460 100644
--- a/test/mjsunit/wasm/wasm-module-builder.js
+++ b/test/mjsunit/wasm/wasm-module-builder.js
@@ -53,7 +53,7 @@
   return this;
 }
 
-// Add a signature; format is [rettype, param0, param1, ...]
+// Add a signature; format is [param_count, param0, param1, ..., retcount, ret0]
 WasmModuleBuilder.prototype.addSignature = function(sig) {
     // TODO: canonicalize signatures?
     this.signatures.push(sig);
@@ -75,9 +75,7 @@
 }
 
 WasmModuleBuilder.prototype.addImport = function(name, sig) {
-  var sig_index = (typeof sig) == "number" ? sig : this.addSignature(sig);
-  this.imports.push({module: name, name: undefined, sig_index: sig_index});
-  return this.imports.length - 1;
+  this.addImportWithModule(name, undefined, sig);
 }
 
 WasmModuleBuilder.prototype.addDataSegment = function(addr, data, init) {
@@ -107,9 +105,19 @@
 }
 
 function emit_string(bytes, string) {
-    emit_varint(bytes, string.length);
-    for (var i = 0; i < string.length; i++) {
-      emit_u8(bytes, string.charCodeAt(i));
+    // When testing illegal names, we pass a byte array directly.
+    if (string instanceof Array) {
+      emit_varint(bytes, string.length);
+      emit_bytes(bytes, string);
+      return;
+    }
+
+    // This is the hacky way to convert a JavaScript scring to a UTF8 encoded
+    // string only containing single-byte characters.
+    var string_utf8 = unescape(encodeURIComponent(string));
+    emit_varint(bytes, string_utf8.length);
+    for (var i = 0; i < string_utf8.length; i++) {
+      emit_u8(bytes, string_utf8.charCodeAt(i));
     }
 }
 
@@ -132,12 +140,14 @@
 }
 
 function emit_section(bytes, section_code, content_generator) {
-    // Start the section in a temporary buffer: its full length isn't know yet.
+    // Emit section name.
+    emit_string(bytes, section_names[section_code]);
+    // Emit the section to a temporary buffer: its full length isn't know yet.
     var tmp_bytes = [];
-    emit_string(tmp_bytes, section_names[section_code]);
     content_generator(tmp_bytes);
-    // Now that we know the section length, emit it and copy the section.
+    // Emit section length.
     emit_varint(bytes, tmp_bytes.length);
+    // Copy the temporary buffer.
     Array.prototype.push.apply(bytes, tmp_bytes);
 }
 
@@ -149,24 +159,13 @@
 
     var wasm = this;
 
-    // Add memory section
-    if (wasm.memory != undefined) {
-        if (debug) print("emitting memory @ " + bytes.length);
-        emit_section(bytes, kDeclMemory, function(bytes) {
-            emit_varint(bytes, wasm.memory.min);
-            emit_varint(bytes, wasm.memory.max);
-            emit_u8(bytes, wasm.memory.exp ? 1 : 0);
-        });
-    }
-
     // Add signatures section
     if (wasm.signatures.length > 0) {
         if (debug) print("emitting signatures @ " + bytes.length);
         emit_section(bytes, kDeclSignatures, function(bytes) {
             emit_varint(bytes, wasm.signatures.length);
             for (sig of wasm.signatures) {
-                var params = sig.length - 1;
-                emit_varint(bytes, params);
+                emit_u8(bytes, kWasmFunctionTypeForm);
                 for (var j = 0; j < sig.length; j++) {
                     emit_u8(bytes, sig[j]);
                 }
@@ -187,7 +186,7 @@
         });
     }
 
-    // Add functions section
+    // Add functions declarations
     var names = false;
     var exports = 0;
     if (wasm.functions.length > 0) {
@@ -206,6 +205,54 @@
             }
         });
 
+    }
+
+    // Add function table.
+    if (wasm.function_table.length > 0) {
+        if (debug) print("emitting function table @ " + bytes.length);
+        emit_section(bytes, kDeclFunctionTable, function(bytes) {
+            emit_varint(bytes, wasm.function_table.length);
+            for (index of wasm.function_table) {
+                emit_varint(bytes, index);
+            }
+        });
+    }
+
+    // Add memory section
+    if (wasm.memory != undefined) {
+        if (debug) print("emitting memory @ " + bytes.length);
+        emit_section(bytes, kDeclMemory, function(bytes) {
+            emit_varint(bytes, wasm.memory.min);
+            emit_varint(bytes, wasm.memory.max);
+            emit_u8(bytes, wasm.memory.exp ? 1 : 0);
+        });
+    }
+
+
+    // Add export table.
+    if (exports > 0) {
+        if (debug) print("emitting exports @ " + bytes.length);
+        emit_section(bytes, kDeclExportTable, function(bytes) {
+            emit_varint(bytes, exports);
+            for (func of wasm.functions) {
+                for (exp of func.exports) {
+                    emit_varint(bytes, func.index);
+                    emit_string(bytes, exp);
+                }
+            }
+        });
+    }
+
+    // Add start function section.
+    if (wasm.start_index != undefined) {
+        if (debug) print("emitting start function @ " + bytes.length);
+        emit_section(bytes, kDeclStartFunction, function(bytes) {
+            emit_varint(bytes, wasm.start_index);
+        });
+    }
+
+    // Add function bodies.
+    if (wasm.functions.length > 0) {
         // emit function bodies
         if (debug) print("emitting function bodies @ " + bytes.length);
         emit_section(bytes, kDeclFunctionBodies, function(bytes) {
@@ -244,50 +291,7 @@
         });
     }
 
-    // emit function names
-    if (has_names) {
-        if (debug) print("emitting names @ " + bytes.length);
-        emit_section(bytes, kDeclNames, function(bytes) {
-            emit_varint(bytes, wasm.functions.length);
-            for (func of wasm.functions) {
-                var name = func.name == undefined ? "" : func.name;
-               emit_string(bytes, name);
-               emit_u8(bytes, 0);  // local names count == 0
-            }
-        });
-    }
-
-    // Add start function section.
-    if (wasm.start_index != undefined) {
-        if (debug) print("emitting start function @ " + bytes.length);
-        emit_section(bytes, kDeclStartFunction, function(bytes) {
-            emit_varint(bytes, wasm.start_index);
-        });
-    }
-
-    if (wasm.function_table.length > 0) {
-        if (debug) print("emitting function table @ " + bytes.length);
-        emit_section(bytes, kDeclFunctionTable, function(bytes) {
-            emit_varint(bytes, wasm.function_table.length);
-            for (index of wasm.function_table) {
-                emit_varint(bytes, index);
-            }
-        });
-    }
-
-    if (exports > 0) {
-        if (debug) print("emitting exports @ " + bytes.length);
-        emit_section(bytes, kDeclExportTable, function(bytes) {
-            emit_varint(bytes, exports);
-            for (func of wasm.functions) {
-                for (exp of func.exports) {
-                    emit_varint(bytes, func.index);
-                    emit_string(bytes, exp);
-                }
-            }
-        });
-    }
-
+    // Add data segments.
     if (wasm.data_segments.length > 0) {
         if (debug) print("emitting data segments @ " + bytes.length);
         emit_section(bytes, kDeclDataSegments, function(bytes) {
@@ -300,12 +304,25 @@
         });
     }
 
-    // Emit any explicitly added sections
+    // Add any explicitly added sections
     for (exp of wasm.explicit) {
         if (debug) print("emitting explicit @ " + bytes.length);
         emit_bytes(bytes, exp);
     }
 
+    // Add function names.
+    if (has_names) {
+        if (debug) print("emitting names @ " + bytes.length);
+        emit_section(bytes, kDeclNames, function(bytes) {
+            emit_varint(bytes, wasm.functions.length);
+            for (func of wasm.functions) {
+                var name = func.name == undefined ? "" : func.name;
+                emit_string(bytes, name);
+                emit_u8(bytes, 0);  // local names count == 0
+            }
+        });
+    }
+
     // End the module.
     if (debug) print("emitting end @ " + bytes.length);
     emit_section(bytes, kDeclEnd, function(bytes) {});
diff --git a/test/mjsunit/wasm/wasm-object-api.js b/test/mjsunit/wasm/wasm-object-api.js
index 2f25c66..96088b8 100644
--- a/test/mjsunit/wasm/wasm-object-api.js
+++ b/test/mjsunit/wasm/wasm-object-api.js
@@ -10,3 +10,4 @@
 assertEquals("function", typeof Wasm.verifyFunction);
 assertEquals("function", typeof Wasm.instantiateModule);
 assertEquals("function", typeof Wasm.instantiateModuleFromAsm);
+assertFalse(undefined == Wasm.experimentalVersion);