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 8load("test/mjsunit/wasm/wasm-constants.js"); 9load("test/mjsunit/wasm/wasm-module-builder.js"); 10 11// The stack trace contains file path, only keep "stack.js". 12function stripPath(s) { 13 return s.replace(/[^ (]*stack\.js/g, "stack.js"); 14} 15 16function 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 37var stack; 38function STACK() { 39 var e = new Error(); 40 stack = e.stack; 41} 42 43var builder = new WasmModuleBuilder(); 44 45builder.addImport("func", kSig_v_v); 46 47builder.addFunction("main", kSig_v_v) 48 .addBody([kExprCallImport, kArity0, 0]) 49 .exportAs("main"); 50 51builder.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. 56var 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. 62builder.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 66var 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: 82Error.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