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 |
| 6 |
| 7 load('test/mjsunit/wasm/wasm-constants.js'); |
| 8 load('test/mjsunit/wasm/wasm-module-builder.js'); |
| 9 |
| 10 var builder = new WasmModuleBuilder(); |
| 11 |
| 12 // clang-format off |
| 13 var func_idx = builder.addFunction('helper', kSig_v_v) |
| 14 .addLocals({i32_count: 1}) |
| 15 .addBody([ |
| 16 kExprNop, |
| 17 kExprI32Const, 12, |
| 18 kExprSetLocal, 0, |
| 19 ]).index; |
| 20 |
| 21 builder.addFunction('main', kSig_v_i) |
| 22 .addBody([ |
| 23 kExprGetLocal, 0, |
| 24 kExprIf, kWasmStmt, |
| 25 kExprBlock, kWasmStmt, |
| 26 kExprCallFunction, func_idx, |
| 27 kExprEnd, |
| 28 kExprEnd |
| 29 ]).exportAs('main'); |
| 30 // clang-format on |
| 31 |
| 32 var module_bytes = builder.toArray(); |
| 33 |
| 34 function testFunction(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 var setupCode = testFunction.toString() + ';\nvar module_bytes = ' + |
| 50 JSON.stringify(module_bytes) + ';\nvar instance;'; |
| 51 |
| 52 Protocol.Debugger.enable(); |
| 53 Protocol.Debugger.onScriptParsed(handleScriptParsed); |
| 54 InspectorTest.log('Running testFunction...'); |
| 55 evalWithUrl(setupCode, 'setup') |
| 56 .then(() => evalWithUrl('testFunction(module_bytes)', 'runTestFunction')) |
| 57 .then(getBreakableLocationsForAllWasmScripts) |
| 58 .then(setAllBreakableLocations) |
| 59 .then(() => InspectorTest.log('Running wasm code...')) |
| 60 .then(() => (evalWithUrl('instance.exports.main(1)', 'runWasm'), 0)) |
| 61 .then(waitForAllPauses) |
| 62 .then(() => InspectorTest.log('Finished!')) |
| 63 .then(InspectorTest.completeTest); |
| 64 |
| 65 var allBreakableLocations = []; |
| 66 |
| 67 var urls = {}; |
| 68 var numScripts = 0; |
| 69 var wasmScripts = []; |
| 70 function handleScriptParsed(messageObject) { |
| 71 var scriptId = messageObject.params.scriptId; |
| 72 var url = messageObject.params.url; |
| 73 urls[scriptId] = url; |
| 74 InspectorTest.log('Script nr ' + numScripts + ' parsed. URL: ' + url); |
| 75 ++numScripts; |
| 76 |
| 77 if (url.startsWith('wasm://')) { |
| 78 InspectorTest.log('This is a wasm script (nr ' + wasmScripts.length + ').'); |
| 79 wasmScripts.push(scriptId); |
| 80 } |
| 81 } |
| 82 |
| 83 function printFailure(message) { |
| 84 if (!message.result) { |
| 85 InspectorTest.logMessage(message); |
| 86 } |
| 87 return message; |
| 88 } |
| 89 |
| 90 function printBreakableLocations(message, expectedScriptId, source) { |
| 91 var lines = source.split('\n'); |
| 92 var locations = message.result.locations; |
| 93 InspectorTest.log(locations.length + ' breakable location(s):'); |
| 94 for (var i = 0; i < locations.length; ++i) { |
| 95 if (locations[i].scriptId != expectedScriptId) { |
| 96 InspectorTest.log( |
| 97 'SCRIPT ID MISMATCH!! ' + locations[i].scriptId + ' != ' + |
| 98 expectedScriptId); |
| 99 } |
| 100 var line = '<illegal line number>'; |
| 101 if (locations[i].lineNumber < lines.length) { |
| 102 line = lines[locations[i].lineNumber]; |
| 103 if (locations[i].columnNumber < line.length) { |
| 104 line = line.substr(0, locations[i].columnNumber) + '>' + |
| 105 line.substr(locations[i].columnNumber); |
| 106 } |
| 107 } |
| 108 InspectorTest.log( |
| 109 '[' + i + '] ' + locations[i].lineNumber + ':' + |
| 110 locations[i].columnNumber + ' || ' + line); |
| 111 } |
| 112 } |
| 113 |
| 114 function checkGetBreakableLocations(wasmScriptNr) { |
| 115 InspectorTest.log( |
| 116 'Requesting all breakable locations in wasm script ' + wasmScriptNr); |
| 117 var scriptId = wasmScripts[wasmScriptNr]; |
| 118 var source; |
| 119 return Protocol.Debugger.getScriptSource({scriptId: scriptId}) |
| 120 .then(msg => source = msg.result.scriptSource) |
| 121 .then( |
| 122 () => Protocol.Debugger.getPossibleBreakpoints( |
| 123 {start: {lineNumber: 0, columnNumber: 0, scriptId: scriptId}})) |
| 124 .then(printFailure) |
| 125 .then(msg => (allBreakableLocations.push(...msg.result.locations), msg)) |
| 126 .then(msg => printBreakableLocations(msg, scriptId, source)) |
| 127 .then( |
| 128 () => InspectorTest.log( |
| 129 'Requesting breakable locations in lines [0,3)')) |
| 130 .then(() => Protocol.Debugger.getPossibleBreakpoints({ |
| 131 start: {lineNumber: 0, columnNumber: 0, scriptId: scriptId}, |
| 132 end: {lineNumber: 3, columnNumber: 0, scriptId: scriptId} |
| 133 })) |
| 134 .then(printFailure) |
| 135 .then(msg => printBreakableLocations(msg, scriptId, source)) |
| 136 .then( |
| 137 () => InspectorTest.log( |
| 138 'Requesting breakable locations in lines [4,6)')) |
| 139 .then(() => Protocol.Debugger.getPossibleBreakpoints({ |
| 140 start: {lineNumber: 4, columnNumber: 0, scriptId: scriptId}, |
| 141 end: {lineNumber: 6, columnNumber: 0, scriptId: scriptId} |
| 142 })) |
| 143 .then(printFailure) |
| 144 .then(msg => printBreakableLocations(msg, scriptId, source)); |
| 145 } |
| 146 |
| 147 function getBreakableLocationsForAllWasmScripts() { |
| 148 InspectorTest.log('Querying breakable locations for all wasm scripts now...'); |
| 149 var promise = Promise.resolve(); |
| 150 for (var wasmScriptNr = 0; wasmScriptNr < wasmScripts.length; |
| 151 ++wasmScriptNr) { |
| 152 promise = promise.then(checkGetBreakableLocations.bind(null, wasmScriptNr)); |
| 153 } |
| 154 return promise; |
| 155 } |
| 156 |
| 157 function locationMatches(loc1, loc2) { |
| 158 return loc1.scriptId == loc2.scriptId && loc1.lineNumber == loc2.lineNumber && |
| 159 loc1.columnNumber == loc2.columnNumber; |
| 160 } |
| 161 |
| 162 function locationStr(loc) { |
| 163 return urls[loc.scriptId] + ':' + loc.lineNumber + ':' + loc.columnNumber; |
| 164 } |
| 165 |
| 166 function setBreakpoint(loc) { |
| 167 InspectorTest.log('Setting at ' + locationStr(loc)); |
| 168 function check(msg) { |
| 169 if (locationMatches(loc, msg.result.actualLocation)) { |
| 170 InspectorTest.log("Success!"); |
| 171 } else { |
| 172 InspectorTest.log("Mismatch!"); |
| 173 InspectorTest.logMessage(msg); |
| 174 } |
| 175 } |
| 176 return Protocol.Debugger.setBreakpoint({'location': loc}) |
| 177 .then(printFailure) |
| 178 .then(check); |
| 179 } |
| 180 |
| 181 function setAllBreakableLocations() { |
| 182 InspectorTest.log('Setting a breakpoint on each breakable location...'); |
| 183 var promise = Promise.resolve(); |
| 184 for (var loc of allBreakableLocations) { |
| 185 promise = promise.then(setBreakpoint.bind(null, loc)); |
| 186 } |
| 187 return promise; |
| 188 } |
| 189 |
| 190 function removePausedLocation(msg) { |
| 191 var topLocation = msg.params.callFrames[0].location; |
| 192 InspectorTest.log('Stopped at ' + locationStr(topLocation)); |
| 193 for (var i = 0; i < allBreakableLocations.length; ++i) { |
| 194 if (locationMatches(topLocation, allBreakableLocations[i])) { |
| 195 allBreakableLocations.splice(i, 1); |
| 196 --i; |
| 197 } |
| 198 } |
| 199 } |
| 200 |
| 201 function waitForAllPauses() { |
| 202 InspectorTest.log('Missing breakpoints: ' + allBreakableLocations.length); |
| 203 if (allBreakableLocations.length == 0) return; |
| 204 return Protocol.Debugger.oncePaused() |
| 205 .then(removePausedLocation) |
| 206 .then(Protocol.Debugger.resume()) |
| 207 .then(waitForAllPauses); |
| 208 } |
OLD | NEW |