OLD | NEW |
(Empty) | |
| 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 // Flags: --expose-wasm --expose-debug-as debug |
| 6 |
| 7 load("test/mjsunit/wasm/wasm-constants.js"); |
| 8 load("test/mjsunit/wasm/wasm-module-builder.js"); |
| 9 |
| 10 Debug = debug.Debug |
| 11 |
| 12 // Initialized in setup(). |
| 13 var exception; |
| 14 var break_positions; |
| 15 var module; |
| 16 var scripts; |
| 17 var first; |
| 18 |
| 19 function listener(event, exec_state, event_data, data) { |
| 20 try { |
| 21 if (event == Debug.DebugEvent.Break) { |
| 22 var num_frames = exec_state.frameCount(); |
| 23 assertTrue(num_frames > 0); |
| 24 // Record the position in all wasm frames. |
| 25 var wasm_positions = []; |
| 26 for (var i = 0; i < num_frames; ++i) { |
| 27 var frame = exec_state.frame(i); |
| 28 var script = frame.details().script(); |
| 29 if (script.type != Debug.ScriptType.Wasm) continue; |
| 30 var pos = frame.sourcePosition(); |
| 31 wasm_positions.push(pos); |
| 32 } |
| 33 print("break at wasm positions [" + wasm_positions+"]"); |
| 34 break_positions.push(wasm_positions); |
| 35 } else if (event == Debug.DebugEvent.AfterCompile) { |
| 36 var script = event_data.script(); |
| 37 if (script.scriptType() == Debug.ScriptType.Wasm) { |
| 38 var name = script.name(); |
| 39 // Wasm script URLs end in /$func_index. |
| 40 var func = parseInt(name.substr(name.lastIndexOf("/")+1)); |
| 41 scripts[func] = script; |
| 42 } |
| 43 } |
| 44 } catch (e) { |
| 45 print("exception: " + e); |
| 46 exception = e; |
| 47 } |
| 48 }; |
| 49 |
| 50 var builder = new WasmModuleBuilder(); |
| 51 |
| 52 builder.addImport("dbg", kSig_v_v); |
| 53 |
| 54 builder.addFunction("nop", makeSig([kAstI32], [])) |
| 55 .addBody([kExprNop, kExprNop, kExprNop, |
| 56 // offset 6 |
| 57 kExprGetLocal, 0, kExprIf, |
| 58 // offset 7 |
| 59 kExprCallImport, kArity0, 0, |
| 60 kExprEnd]); |
| 61 |
| 62 // First parameter determines the number of calls to nop(), the second one |
| 63 // determines whether the imported function should be called. |
| 64 builder.addFunction("call_nop", makeSig([kAstI32, kAstI32], [])) |
| 65 .addBody([ |
| 66 kExprLoop, |
| 67 kExprI32Const, 0, |
| 68 // offset 4 |
| 69 kExprGetLocal, 0, |
| 70 kExprI32Ne, kExprIf, |
| 71 kExprI32Const, (-1 & 0x7f), kExprGetLocal, 0, kExprI32Add, kExprSetLoc
al, 0, |
| 72 // offset 15 |
| 73 kExprGetLocal, 1, |
| 74 // offset 17 |
| 75 kExprCallFunction, kArity1, 0, |
| 76 kExprBr, kArity0, 1, |
| 77 kExprEnd, |
| 78 kExprEnd, |
| 79 ]) |
| 80 .exportAs("main"); |
| 81 |
| 82 function dbg() { |
| 83 if (first) debugger; |
| 84 first = 0; |
| 85 } |
| 86 |
| 87 function setup() { |
| 88 first = 1; |
| 89 module = builder.instantiate({"dbg": dbg}); |
| 90 exception = null; |
| 91 break_positions = []; |
| 92 scripts = []; |
| 93 } |
| 94 |
| 95 // Test setting break points. |
| 96 // We set 1 or more breakpoints in 1 or more functions, and remove some or all |
| 97 // of them again. |
| 98 // One function is called from wasm, the other one as exported function via |
| 99 // JavaScript. |
| 100 (function testWasmBreakpoint() { |
| 101 setup(); |
| 102 Debug.setListener(listener); |
| 103 |
| 104 // Call the program with indirect call, should have one break with positions |
| 105 // at the wasm call sites. |
| 106 module.exports.main(1, 1); |
| 107 assertArrayEquals([[7, 17]], break_positions); |
| 108 // But both scripts should be there now. |
| 109 assertEquals(2, scripts.length); |
| 110 assertArrayEquals(["0", "1"], Object.keys(scripts)); |
| 111 |
| 112 // Set break point in "nop" function, offset 1. |
| 113 print("set break point at position 1"); |
| 114 var break_1 = Debug.setBreakPointByScriptIdAndPosition(scripts[0].id(), 1, und
efined, 1); |
| 115 // Call the program again without indirect call -> now 1 break in the inner |
| 116 // wasm function. |
| 117 break_positions = []; |
| 118 module.exports.main(1, 0); |
| 119 assertArrayEquals([[1, 17]], break_positions); |
| 120 |
| 121 // Set another break point in "nop" function, offset 6. |
| 122 print("set break point at position 6"); |
| 123 var break_6 = Debug.setBreakPointByScriptIdAndPosition(scripts[0].id(), 6, und
efined, 1); |
| 124 // See if we hit both breakpoints. |
| 125 break_positions = []; |
| 126 module.exports.main(1, 0); |
| 127 assertArrayEquals([[1, 17], [6, 17]], break_positions); |
| 128 |
| 129 // Remove first break point, and add two in "call_nop", offsets 4 and 15. |
| 130 print("disable break point at position 1"); |
| 131 break_1.disable(); |
| 132 print("set break point at position 4"); |
| 133 var break_4 = Debug.setBreakPointByScriptIdAndPosition(scripts[1].id(), 4, und
efined, 1); |
| 134 print("set break point at position 15"); |
| 135 var break_15 = Debug.setBreakPointByScriptIdAndPosition(scripts[1].id(), 15, u
ndefined, 1); |
| 136 // Now call the program to run two iterations of nop, and check the |
| 137 // breakpoints. |
| 138 break_positions = []; |
| 139 module.exports.main(2, 0); |
| 140 assertArrayEquals([[4], [15], [6, 17], [4], [15], [6, 17], [4]], break_positio
ns); |
| 141 |
| 142 // Remove all break points, check that no break is triggered. |
| 143 print("disable break points at positions 6, 4 and 15"); |
| 144 break_6.disable(); |
| 145 break_4.disable(); |
| 146 break_15.disable(); |
| 147 break_positions = []; |
| 148 module.exports.main(1, 0); |
| 149 assertArrayEquals([], break_positions); |
| 150 |
| 151 Debug.setListener(null); |
| 152 if (exception) throw exception; |
| 153 })(); |
OLD | NEW |