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/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"]
+    ]);
+  }
 })();