| // 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( | 
 |     'Test retrieving scope information when pausing in wasm functions'); | 
 | session.setupScriptMap(); | 
 | Protocol.Debugger.enable(); | 
 |  | 
 | let evaluate = code => Protocol.Runtime.evaluate({expression: code}); | 
 |  | 
 | (async function test() { | 
 |   let scriptId = await instantiateWasm(); | 
 |   await setBreakpoint(scriptId); | 
 |   printPauseLocationsAndContinue(); | 
 |   await evaluate('instance.exports.main(4)'); | 
 |   InspectorTest.log('exports.main returned. Test finished.'); | 
 |   InspectorTest.completeTest(); | 
 | })(); | 
 |  | 
 | async function printPauseLocationsAndContinue() { | 
 |   while (true) { | 
 |     let msg = await Protocol.Debugger.oncePaused(); | 
 |     let loc = msg.params.callFrames[0].location; | 
 |     InspectorTest.log('Paused:'); | 
 |     await session.logSourceLocation(loc); | 
 |     await dumpScopeChainsOnPause(msg); | 
 |     Protocol.Debugger.stepOver(); | 
 |   } | 
 | } | 
 |  | 
 | async function instantiateWasm() { | 
 |   utils.load('test/mjsunit/wasm/wasm-constants.js'); | 
 |   utils.load('test/mjsunit/wasm/wasm-module-builder.js'); | 
 |  | 
 |   var builder = new WasmModuleBuilder(); | 
 |  | 
 |   builder.addFunction('func', kSig_v_i) | 
 |       .addLocals( | 
 |           {i32_count: 1, f64_count: 1}, ['i32Arg', undefined, 'unicodeā¼f64']) | 
 |       .addBody([ | 
 |         // Set param 0 to 11. | 
 |         kExprI32Const, 11, kExprSetLocal, 0, | 
 |         // Set local 1 to 47. | 
 |         kExprI32Const, 47, kExprSetLocal, 1, | 
 |         // Set local 2 to 1/7. | 
 |         kExprI32Const, 1, kExprF64UConvertI32, kExprI32Const, 7, | 
 |         kExprF64UConvertI32, kExprF64Div, kExprSetLocal, 2 | 
 |       ]) | 
 |       .exportAs('main'); | 
 |  | 
 |   var module_bytes = builder.toArray(); | 
 |  | 
 |   function instantiate(bytes) { | 
 |     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); | 
 |     // Set global variable. | 
 |     instance = new WebAssembly.Instance(module); | 
 |   } | 
 |  | 
 |   InspectorTest.log('Installing code and global variable.'); | 
 |   await evaluate('var instance;\n' + instantiate.toString()); | 
 |   InspectorTest.log('Calling instantiate function.'); | 
 |   evaluate('instantiate(' + JSON.stringify(module_bytes) + ')'); | 
 |   return waitForWasmScript(); | 
 | } | 
 |  | 
 | async function setBreakpoint(scriptId) { | 
 |   InspectorTest.log('Setting breakpoint on line 2 (first instruction)'); | 
 |   let breakpoint = await Protocol.Debugger.setBreakpoint( | 
 |       {'location': {'scriptId': scriptId, 'lineNumber': 2}}); | 
 |   printFailure(breakpoint); | 
 |   InspectorTest.logMessage(breakpoint.result.actualLocation); | 
 | } | 
 |  | 
 | function printFailure(message) { | 
 |   if (!message.result) { | 
 |     InspectorTest.logMessage(message); | 
 |   } | 
 |   return message; | 
 | } | 
 |  | 
 | async function waitForWasmScript() { | 
 |   InspectorTest.log('Waiting for wasm script to be parsed.'); | 
 |   while (true) { | 
 |     let script_msg = await Protocol.Debugger.onceScriptParsed(); | 
 |     let url = script_msg.params.url; | 
 |     if (!url.startsWith('wasm://')) { | 
 |       continue; | 
 |     } | 
 |     InspectorTest.log('Got wasm script!'); | 
 |     return script_msg.params.scriptId; | 
 |   } | 
 | } | 
 |  | 
 | async function getValueString(value) { | 
 |   if (value.type == 'object') { | 
 |     var msg = await Protocol.Runtime.getProperties({objectId: value.objectId}); | 
 |     printFailure(msg); | 
 |     let printProperty = elem => '"' + elem.name + '"' + | 
 |         ': ' + elem.value.description + ' (' + elem.value.type + ')'; | 
 |     return msg.result.result.map(printProperty).join(', '); | 
 |   } | 
 |   return JSON.stringify(value.value) + ' (' + value.type + ')'; | 
 | } | 
 |  | 
 | async function dumpProperties(message) { | 
 |   printFailure(message); | 
 |   for (var value of message.result.result) { | 
 |     var value_str = await getValueString(value.value); | 
 |     InspectorTest.log('   ' + value.name + ': ' + value_str); | 
 |   } | 
 | } | 
 |  | 
 | async function dumpScopeChainsOnPause(message) { | 
 |   for (var frame of message.params.callFrames) { | 
 |     var functionName = frame.functionName || '(anonymous)'; | 
 |     var lineNumber = frame.location ? frame.location.lineNumber : frame.lineNumber; | 
 |     var columnNumber = frame.location ? frame.location.columnNumber : frame.columnNumber; | 
 |     InspectorTest.log(`at ${functionName} (${lineNumber}:${columnNumber}):`); | 
 |     for (var scope of frame.scopeChain) { | 
 |       InspectorTest.logObject(' - scope (' + scope.type + '):'); | 
 |       if (scope.type == 'global') { | 
 |         InspectorTest.logObject('   -- skipped'); | 
 |       } else { | 
 |         var properties = await Protocol.Runtime.getProperties( | 
 |             {'objectId': scope.object.objectId}); | 
 |         await dumpProperties(properties); | 
 |       } | 
 |     } | 
 |   } | 
 | } |