Home | History | Annotate | Download | only in wasm
      1 // Copyright 2016 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // clang-format off
      6 // Flags: --expose-wasm
      7 
      8 load("test/mjsunit/wasm/wasm-constants.js");
      9 load("test/mjsunit/wasm/wasm-module-builder.js");
     10 
     11 // The stack trace contains file path, only keep "stack.js".
     12 function stripPath(s) {
     13   return s.replace(/[^ (]*stack\.js/g, "stack.js");
     14 }
     15 
     16 function verifyStack(frames, expected) {
     17   assertEquals(expected.length, frames.length, "number of frames mismatch");
     18   expected.forEach(function(exp, i) {
     19     assertEquals(exp[1], frames[i].getFunctionName(),
     20         "["+i+"].getFunctionName()");
     21     assertEquals(exp[2], frames[i].getLineNumber(), "["+i+"].getLineNumber()");
     22     if (exp[0])
     23       assertEquals(exp[3], frames[i].getPosition(),
     24           "["+i+"].getPosition()");
     25     assertContains(exp[4], frames[i].getFileName(), "["+i+"].getFileName()");
     26     var toString;
     27     if (exp[0]) {
     28       toString = exp[1] + " (<WASM>[" + exp[2] + "]+" + exp[3] + ")";
     29     } else {
     30       toString = exp[4] + ":" + exp[2] + ":";
     31     }
     32     assertContains(toString, frames[i].toString(), "["+i+"].toString()");
     33   });
     34 }
     35 
     36 
     37 var stack;
     38 function STACK() {
     39   var e = new Error();
     40   stack = e.stack;
     41 }
     42 
     43 var builder = new WasmModuleBuilder();
     44 
     45 builder.addImport("func", kSig_v_v);
     46 
     47 builder.addFunction("main", kSig_v_v)
     48   .addBody([kExprCallImport, kArity0, 0])
     49   .exportAs("main");
     50 
     51 builder.addFunction("exec_unreachable", kSig_v_v)
     52   .addBody([kExprUnreachable])
     53   .exportAs("exec_unreachable");
     54 
     55 // Make this function unnamed, just to test also this case.
     56 var mem_oob_func = builder.addFunction(undefined, kSig_v_v)
     57   // Access the memory at offset -1, to provoke a trap.
     58   .addBody([kExprI32Const, 0x7f, kExprI32LoadMem8S, 0, 0])
     59   .exportAs("mem_out_of_bounds");
     60 
     61 // Call the mem_out_of_bounds function, in order to have two WASM stack frames.
     62 builder.addFunction("call_mem_out_of_bounds", kSig_v_v)
     63   .addBody([kExprCallFunction, kArity0, mem_oob_func.index])
     64   .exportAs("call_mem_out_of_bounds");
     65 
     66 var module = builder.instantiate({func: STACK});
     67 
     68 (function testSimpleStack() {
     69   var expected_string = "Error\n" +
     70     // The line numbers below will change as this test gains / loses lines..
     71     "    at STACK (stack.js:39:11)\n" +           // --
     72     "    at main (<WASM>[0]+1)\n" +               // --
     73     "    at testSimpleStack (stack.js:76:18)\n" + // --
     74     "    at stack.js:78:3";                       // --
     75 
     76   module.exports.main();
     77   assertEquals(expected_string, stripPath(stack));
     78 })();
     79 
     80 // For the remaining tests, collect the Callsite objects instead of just a
     81 // string:
     82 Error.prepareStackTrace = function(error, frames) {
     83   return frames;
     84 };
     85 
     86 (function testStackFrames() {
     87   module.exports.main();
     88 
     89   verifyStack(stack, [
     90       // isWasm           function   line  pos        file
     91       [   false,           "STACK",    39,   0, "stack.js"],
     92       [    true,            "main",     0,   1,       null],
     93       [   false, "testStackFrames",    87,   0, "stack.js"],
     94       [   false,              null,    96,   0, "stack.js"]
     95   ]);
     96 })();
     97 
     98 (function testWasmUnreachable() {
     99   try {
    100     module.exports.exec_unreachable();
    101     fail("expected wasm exception");
    102   } catch (e) {
    103     assertContains("unreachable", e.message);
    104     verifyStack(e.stack, [
    105         // isWasm               function   line  pos        file
    106         [    true,    "exec_unreachable",    1,    1,       null],
    107         [   false, "testWasmUnreachable",  100,    0, "stack.js"],
    108         [   false,                  null,  111,    0, "stack.js"]
    109     ]);
    110   }
    111 })();
    112 
    113 (function testWasmMemOutOfBounds() {
    114   try {
    115     module.exports.call_mem_out_of_bounds();
    116     fail("expected wasm exception");
    117   } catch (e) {
    118     assertContains("out of bounds", e.message);
    119     verifyStack(e.stack, [
    120         // isWasm                  function   line  pos        file
    121         [    true,                       "",     2,   3,       null],
    122         [    true, "call_mem_out_of_bounds",     3,   1,       null],
    123         [   false, "testWasmMemOutOfBounds",   115,   0, "stack.js"],
    124         [   false,                     null,   127,   0, "stack.js"]
    125     ]);
    126   }
    127 })();
    128