OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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 load('test/mjsunit/wasm/wasm-constants.js'); |
| 6 load('test/mjsunit/wasm/wasm-module-builder.js'); |
| 7 |
| 8 var builder = new WasmModuleBuilder(); |
| 9 |
| 10 var func_a_idx = |
| 11 builder.addFunction('wasm_A', kSig_v_v).addBody([kExprNop, kExprNop]).index; |
| 12 |
| 13 // wasm_B calls wasm_A <param0> times. |
| 14 builder.addFunction('wasm_B', kSig_v_i) |
| 15 .addBody([ |
| 16 // clang-format off |
| 17 kExprLoop, kWasmStmt, // while |
| 18 kExprGetLocal, 0, // - |
| 19 kExprIf, kWasmStmt, // if <param0> != 0 |
| 20 kExprGetLocal, 0, // - |
| 21 kExprI32Const, 1, // - |
| 22 kExprI32Sub, // - |
| 23 kExprSetLocal, 0, // decrease <param0> |
| 24 kExprCallFunction, func_a_idx, // - |
| 25 kExprBr, 1, // continue |
| 26 kExprEnd, // - |
| 27 kExprEnd, // break |
| 28 // clang-format on |
| 29 ]) |
| 30 .exportAs('main'); |
| 31 |
| 32 var module_bytes = builder.toArray(); |
| 33 |
| 34 function instantiate(bytes) { |
| 35 var buffer = new ArrayBuffer(bytes.length); |
| 36 var view = new Uint8Array(buffer); |
| 37 for (var i = 0; i < bytes.length; ++i) { |
| 38 view[i] = bytes[i] | 0; |
| 39 } |
| 40 |
| 41 var module = new WebAssembly.Module(buffer); |
| 42 // Set global variable. |
| 43 instance = new WebAssembly.Instance(module); |
| 44 } |
| 45 |
| 46 var evalWithUrl = (code, url) => Protocol.Runtime.evaluate( |
| 47 {'expression': code + '\n//# sourceURL=v8://test/' + url}); |
| 48 |
| 49 Protocol.Debugger.onPaused(handlePaused); |
| 50 var wasm_B_scriptId; |
| 51 var step_actions = [ |
| 52 'stepInto', // == stepOver, to call instruction |
| 53 'stepInto', // into call to wasm_A |
| 54 'stepOver', // over first nop |
| 55 'stepOut', // out of wasm_A |
| 56 'stepOut', // out of wasm_B, stop on breakpoint again |
| 57 'stepOver', // to call |
| 58 'stepOver', // over call |
| 59 'resume', // to next breakpoint (third iteration) |
| 60 'stepInto', // to call |
| 61 'stepInto', // into wasm_A |
| 62 'stepOut', // out to wasm_B |
| 63 // now step 9 times, until we are in wasm_A again. |
| 64 'stepInto', 'stepInto', 'stepInto', 'stepInto', 'stepInto', 'stepInto', |
| 65 'stepInto', 'stepInto', 'stepInto', |
| 66 // 3 more times, back to wasm_B. |
| 67 'stepInto', 'stepInto', 'stepInto', |
| 68 // then just resume. |
| 69 'resume' |
| 70 ]; |
| 71 var sources = {}; |
| 72 var urls = {}; |
| 73 var afterTwoSourcesCallback; |
| 74 |
| 75 Protocol.Debugger.enable() |
| 76 .then(() => InspectorTest.log('Installing code an global variable.')) |
| 77 .then( |
| 78 () => evalWithUrl('var instance;\n' + instantiate.toString(), 'setup')) |
| 79 .then(() => InspectorTest.log('Calling instantiate function.')) |
| 80 .then( |
| 81 () => |
| 82 (evalWithUrl( |
| 83 'instantiate(' + JSON.stringify(module_bytes) + ')', |
| 84 'callInstantiate'), |
| 85 0)) |
| 86 .then(waitForTwoWasmScripts) |
| 87 .then( |
| 88 () => InspectorTest.log( |
| 89 'Setting breakpoint on line 7 (on the setlocal before the call), url
' + |
| 90 urls[wasm_B_scriptId])) |
| 91 .then( |
| 92 () => Protocol.Debugger.setBreakpoint( |
| 93 {'location': {'scriptId': wasm_B_scriptId, 'lineNumber': 7}})) |
| 94 .then(printFailure) |
| 95 .then(msg => InspectorTest.logMessage(msg.result.actualLocation)) |
| 96 .then(() => evalWithUrl('instance.exports.main(4)', 'runWasm')) |
| 97 .then(() => InspectorTest.log('exports.main returned!')) |
| 98 .then(() => InspectorTest.log('Finished!')) |
| 99 .then(InspectorTest.completeTest); |
| 100 |
| 101 function printFailure(message) { |
| 102 if (!message.result) { |
| 103 InspectorTest.logMessage(message); |
| 104 } |
| 105 return message; |
| 106 } |
| 107 |
| 108 function waitForTwoWasmScripts() { |
| 109 var num = 0; |
| 110 InspectorTest.log('Waiting for two wasm scripts to be parsed.'); |
| 111 var promise = new Promise(fulfill => gotBothSources = fulfill); |
| 112 function waitForMore() { |
| 113 if (num == 2) return promise; |
| 114 Protocol.Debugger.onceScriptParsed() |
| 115 .then(handleNewScript) |
| 116 .then(waitForMore); |
| 117 } |
| 118 function handleNewScript(msg) { |
| 119 var url = msg.params.url; |
| 120 if (!url.startsWith('wasm://')) { |
| 121 InspectorTest.log('Ignoring script with url ' + url); |
| 122 return; |
| 123 } |
| 124 num += 1; |
| 125 var scriptId = msg.params.scriptId; |
| 126 urls[scriptId] = url; |
| 127 InspectorTest.log('Got wasm script: ' + url); |
| 128 if (url.substr(-2) == '-1') wasm_B_scriptId = scriptId; |
| 129 InspectorTest.log('Requesting source for ' + url + '...'); |
| 130 Protocol.Debugger.getScriptSource({scriptId: scriptId}) |
| 131 .then(printFailure) |
| 132 .then(msg => sources[scriptId] = msg.result.scriptSource) |
| 133 .then(InspectorTest.log) |
| 134 .then(() => Object.keys(sources).length == 2 ? gotBothSources() : 0); |
| 135 } |
| 136 waitForMore(); |
| 137 return promise; |
| 138 } |
| 139 |
| 140 function printPauseLocation(scriptId, lineNr, columnNr) { |
| 141 var lines = sources[scriptId].split('\n'); |
| 142 var line = '<illegal line number>'; |
| 143 if (lineNr < lines.length) { |
| 144 line = lines[lineNr]; |
| 145 if (columnNr < line.length) { |
| 146 line = line.substr(0, columnNr) + '>' + line.substr(columnNr); |
| 147 } |
| 148 } |
| 149 InspectorTest.log( |
| 150 'Paused at ' + urls[scriptId] + ':' + lineNr + ':' + columnNr + ': ' + |
| 151 line); |
| 152 } |
| 153 |
| 154 function handlePaused(msg) { |
| 155 var loc = msg.params.callFrames[0].location; |
| 156 printPauseLocation(loc.scriptId, loc.lineNumber, loc.columnNumber); |
| 157 var action = step_actions.shift(); |
| 158 InspectorTest.log('Step action: ' + action); |
| 159 Protocol.Debugger[action](); |
| 160 } |
OLD | NEW |