Index: test/mjsunit/wasm/debug-break.js |
diff --git a/test/mjsunit/wasm/debug-break.js b/test/mjsunit/wasm/debug-break.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..476eff5fe42c928125f84764c1b4b8b10239eb44 |
--- /dev/null |
+++ b/test/mjsunit/wasm/debug-break.js |
@@ -0,0 +1,153 @@ |
+// 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 --expose-debug-as debug |
+ |
+load("test/mjsunit/wasm/wasm-constants.js"); |
+load("test/mjsunit/wasm/wasm-module-builder.js"); |
+ |
+Debug = debug.Debug |
+ |
+// Initialized in setup(). |
+var exception; |
+var break_positions; |
+var module; |
+var scripts; |
+var first; |
+ |
+function listener(event, exec_state, event_data, data) { |
+ try { |
+ if (event == Debug.DebugEvent.Break) { |
+ var num_frames = exec_state.frameCount(); |
+ assertTrue(num_frames > 0); |
+ // Record the position in all wasm frames. |
+ var wasm_positions = []; |
+ for (var i = 0; i < num_frames; ++i) { |
+ var frame = exec_state.frame(i); |
+ var script = frame.details().script(); |
+ if (script.type != Debug.ScriptType.Wasm) continue; |
+ var pos = frame.sourcePosition(); |
+ wasm_positions.push(pos); |
+ } |
+ print("break at wasm positions [" + wasm_positions+"]"); |
+ break_positions.push(wasm_positions); |
+ } else if (event == Debug.DebugEvent.AfterCompile) { |
+ var script = event_data.script(); |
+ if (script.scriptType() == Debug.ScriptType.Wasm) { |
+ var name = script.name(); |
+ // Wasm script URLs end in /$func_index. |
+ var func = parseInt(name.substr(name.lastIndexOf("/")+1)); |
+ scripts[func] = script; |
+ } |
+ } |
+ } catch (e) { |
+ print("exception: " + e); |
+ exception = e; |
+ } |
+}; |
+ |
+var builder = new WasmModuleBuilder(); |
+ |
+builder.addImport("dbg", kSig_v_v); |
+ |
+builder.addFunction("nop", makeSig([kAstI32], [])) |
+ .addBody([kExprNop, kExprNop, kExprNop, |
+ // offset 6 |
+ kExprGetLocal, 0, kExprIf, |
+ // offset 7 |
+ kExprCallImport, kArity0, 0, |
+ kExprEnd]); |
+ |
+// First parameter determines the number of calls to nop(), the second one |
+// determines whether the imported function should be called. |
+builder.addFunction("call_nop", makeSig([kAstI32, kAstI32], [])) |
+ .addBody([ |
+ kExprLoop, |
+ kExprI32Const, 0, |
+ // offset 4 |
+ kExprGetLocal, 0, |
+ kExprI32Ne, kExprIf, |
+ kExprI32Const, (-1 & 0x7f), kExprGetLocal, 0, kExprI32Add, kExprSetLocal, 0, |
+ // offset 15 |
+ kExprGetLocal, 1, |
+ // offset 17 |
+ kExprCallFunction, kArity1, 0, |
+ kExprBr, kArity0, 1, |
+ kExprEnd, |
+ kExprEnd, |
+ ]) |
+ .exportAs("main"); |
+ |
+function dbg() { |
+ if (first) debugger; |
+ first = 0; |
+} |
+ |
+function setup() { |
+ first = 1; |
+ module = builder.instantiate({"dbg": dbg}); |
+ exception = null; |
+ break_positions = []; |
+ scripts = []; |
+} |
+ |
+// Test setting break points. |
+// We set 1 or more breakpoints in 1 or more functions, and remove some or all |
+// of them again. |
+// One function is called from wasm, the other one as exported function via |
+// JavaScript. |
+(function testWasmBreakpoint() { |
+ setup(); |
+ Debug.setListener(listener); |
+ |
+ // Call the program with indirect call, should have one break with positions |
+ // at the wasm call sites. |
+ module.exports.main(1, 1); |
+ assertArrayEquals([[7, 17]], break_positions); |
+ // But both scripts should be there now. |
+ assertEquals(2, scripts.length); |
+ assertArrayEquals(["0", "1"], Object.keys(scripts)); |
+ |
+ // Set break point in "nop" function, offset 1. |
+ print("set break point at position 1"); |
+ var break_1 = Debug.setBreakPointByScriptIdAndPosition(scripts[0].id(), 1, undefined, 1); |
+ // Call the program again without indirect call -> now 1 break in the inner |
+ // wasm function. |
+ break_positions = []; |
+ module.exports.main(1, 0); |
+ assertArrayEquals([[1, 17]], break_positions); |
+ |
+ // Set another break point in "nop" function, offset 6. |
+ print("set break point at position 6"); |
+ var break_6 = Debug.setBreakPointByScriptIdAndPosition(scripts[0].id(), 6, undefined, 1); |
+ // See if we hit both breakpoints. |
+ break_positions = []; |
+ module.exports.main(1, 0); |
+ assertArrayEquals([[1, 17], [6, 17]], break_positions); |
+ |
+ // Remove first break point, and add two in "call_nop", offsets 4 and 15. |
+ print("disable break point at position 1"); |
+ break_1.disable(); |
+ print("set break point at position 4"); |
+ var break_4 = Debug.setBreakPointByScriptIdAndPosition(scripts[1].id(), 4, undefined, 1); |
+ print("set break point at position 15"); |
+ var break_15 = Debug.setBreakPointByScriptIdAndPosition(scripts[1].id(), 15, undefined, 1); |
+ // Now call the program to run two iterations of nop, and check the |
+ // breakpoints. |
+ break_positions = []; |
+ module.exports.main(2, 0); |
+ assertArrayEquals([[4], [15], [6, 17], [4], [15], [6, 17], [4]], break_positions); |
+ |
+ // Remove all break points, check that no break is triggered. |
+ print("disable break points at positions 6, 4 and 15"); |
+ break_6.disable(); |
+ break_4.disable(); |
+ break_15.disable(); |
+ break_positions = []; |
+ module.exports.main(1, 0); |
+ assertArrayEquals([], break_positions); |
+ |
+ Debug.setListener(null); |
+ if (exception) throw exception; |
+})(); |