| // Copyright 2017 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. |
| |
| let {session, contextGroup, Protocol} = InspectorTest.start('Tests imports in wasm'); |
| |
| utils.load('test/mjsunit/wasm/wasm-module-builder.js'); |
| |
| // Build two modules A and B. A defines function func, which contains a |
| // breakpoint. This function is then imported by B and called via main. The |
| // breakpoint must be hit. |
| // This failed before (http://crbug.com/v8/5971). |
| |
| var builder_a = new WasmModuleBuilder(); |
| var func_idx = builder_a.addFunction('func', kSig_v_v) |
| .addBody([kExprNop]) |
| .exportFunc() |
| .index; |
| var module_a_bytes = builder_a.toArray(); |
| |
| var builder_b = new WasmModuleBuilder(); |
| var import_idx = builder_b.addImport('imp', 'f', kSig_v_v); |
| builder_b.addFunction('main', kSig_v_v) |
| .addBody([kExprCallFunction, import_idx]) |
| .exportFunc(); |
| var module_b_bytes = builder_b.toArray(); |
| |
| function instantiate(bytes, imp) { |
| var buffer = new ArrayBuffer(bytes.length); |
| var view = new Uint8Array(buffer); |
| for (var i = 0; i < bytes.length; ++i) { |
| view[i] = bytes[i] | 0; |
| } |
| |
| var module = new WebAssembly.Module(buffer); |
| // Add to global instances array. |
| instances.push(new WebAssembly.Instance(module, imp)); |
| } |
| |
| var evalWithUrl = (code, url) => Protocol.Runtime.evaluate( |
| {'expression': code + '\n//# sourceURL=v8://test/' + url}); |
| |
| session.setupScriptMap(); |
| |
| // Main promise chain: |
| Protocol.Debugger.enable() |
| .then(() => InspectorTest.log('Installing code and global variable.')) |
| .then( |
| () => evalWithUrl( |
| 'var instances = [];\n' + instantiate.toString(), 'setup')) |
| .then(() => InspectorTest.log('Calling instantiate function for module A.')) |
| .then( |
| () => |
| (evalWithUrl( |
| 'instantiate(' + JSON.stringify(module_a_bytes) + ')', |
| 'instantiateA'), |
| 0)) |
| .then(() => InspectorTest.log('Waiting for wasm script to be parsed.')) |
| .then(waitForWasmScript) |
| .then(url => (InspectorTest.log('Setting breakpoint in line 1:'), url)) |
| .then( |
| url => |
| Protocol.Debugger.setBreakpointByUrl({lineNumber: 1, url: url})) |
| .then(printFailure) |
| .then(msg => session.logSourceLocations(msg.result.locations)) |
| .then(() => InspectorTest.log('Calling instantiate function for module B.')) |
| .then( |
| () => |
| (evalWithUrl( |
| 'instantiate(' + JSON.stringify(module_b_bytes) + |
| ', {imp: {f: instances[0].exports.func}})', |
| 'instantiateB'), |
| 0)) |
| .then(() => InspectorTest.log('Calling main function on module B.')) |
| .then(() => evalWithUrl('instances[1].exports.main()', 'runWasm')) |
| .then(() => InspectorTest.log('exports.main returned.')) |
| .then(() => InspectorTest.log('Finished.')) |
| .then(InspectorTest.completeTest); |
| |
| // Separate promise chain for the asynchronous pause: |
| Protocol.Debugger.oncePaused() |
| .then(msg => msg.params.callFrames[0].location) |
| .then( |
| loc => |
| (InspectorTest.log( |
| 'Paused at ' + loc.lineNumber + ':' + loc.columnNumber + '.'), |
| loc)) |
| .then(session.logSourceLocation.bind(session)) |
| .then( |
| () => InspectorTest.log( |
| 'Getting current stack trace via "new Error().stack".')) |
| .then(() => evalWithUrl('new Error().stack', 'getStack')) |
| .then(msg => InspectorTest.log(msg.result.result.value)) |
| .then(Protocol.Debugger.resume); |
| |
| function printFailure(message) { |
| if (!message.result) { |
| InspectorTest.logMessage(message); |
| } |
| return message; |
| } |
| |
| function waitForWasmScript(msg) { |
| if (!msg || !msg.params.url.startsWith('wasm://')) { |
| return Protocol.Debugger.onceScriptParsed().then(waitForWasmScript); |
| } |
| InspectorTest.log('Got wasm script!'); |
| return Promise.resolve(msg.params.url); |
| } |