11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciimport { PROF_COLS, UNICODE_BLOCK } from "../src/constants"; 61cb0ef41Sopenharmony_ciimport { SelectionBroker } from "../src/selection-broker"; 71cb0ef41Sopenharmony_ciimport { TextView } from "../src/text-view"; 81cb0ef41Sopenharmony_ciimport { MySelection } from "./selection"; 91cb0ef41Sopenharmony_ciimport { anyToString, interpolate } from "./util"; 101cb0ef41Sopenharmony_ciimport { InstructionSelectionHandler } from "./selection-handler"; 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciconst toolboxHTML = `<div id="disassembly-toolbox"> 131cb0ef41Sopenharmony_ci<form> 141cb0ef41Sopenharmony_ci <label><input id="show-instruction-address" type="checkbox" name="instruction-address">Show addresses</label> 151cb0ef41Sopenharmony_ci <label><input id="show-instruction-binary" type="checkbox" name="instruction-binary">Show binary literal</label> 161cb0ef41Sopenharmony_ci <label><input id="highlight-gap-instructions" type="checkbox" name="instruction-binary">Highlight gap instructions</label> 171cb0ef41Sopenharmony_ci</form> 181cb0ef41Sopenharmony_ci</div>`; 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ciexport class DisassemblyView extends TextView { 211cb0ef41Sopenharmony_ci SOURCE_POSITION_HEADER_REGEX: any; 221cb0ef41Sopenharmony_ci addrEventCounts: any; 231cb0ef41Sopenharmony_ci totalEventCounts: any; 241cb0ef41Sopenharmony_ci maxEventCounts: any; 251cb0ef41Sopenharmony_ci posLines: Array<any>; 261cb0ef41Sopenharmony_ci instructionSelectionHandler: InstructionSelectionHandler; 271cb0ef41Sopenharmony_ci offsetSelection: MySelection; 281cb0ef41Sopenharmony_ci showInstructionAddressHandler: () => void; 291cb0ef41Sopenharmony_ci showInstructionBinaryHandler: () => void; 301cb0ef41Sopenharmony_ci highlightGapInstructionsHandler: () => void; 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci createViewElement() { 331cb0ef41Sopenharmony_ci const pane = document.createElement('div'); 341cb0ef41Sopenharmony_ci pane.setAttribute('id', "disassembly"); 351cb0ef41Sopenharmony_ci pane.innerHTML = 361cb0ef41Sopenharmony_ci `<pre id='disassembly-text-pre' class='prettyprint prettyprinted'> 371cb0ef41Sopenharmony_ci <ul class='disassembly-list nolinenums noindent'> 381cb0ef41Sopenharmony_ci </ul> 391cb0ef41Sopenharmony_ci </pre>`; 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci return pane; 421cb0ef41Sopenharmony_ci } 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci constructor(parentId, broker: SelectionBroker) { 451cb0ef41Sopenharmony_ci super(parentId, broker); 461cb0ef41Sopenharmony_ci const view = this; 471cb0ef41Sopenharmony_ci const ADDRESS_STYLE = { 481cb0ef41Sopenharmony_ci associateData: (text, fragment: HTMLElement) => { 491cb0ef41Sopenharmony_ci const matches = text.match(/(?<address>0?x?[0-9a-fA-F]{8,16})(?<addressSpace>\s+)(?<offset>[0-9a-f]+)(?<offsetSpace>\s*)/); 501cb0ef41Sopenharmony_ci const offset = Number.parseInt(matches.groups["offset"], 16); 511cb0ef41Sopenharmony_ci const instructionKind = view.sourceResolver.getInstructionKindForPCOffset(offset); 521cb0ef41Sopenharmony_ci fragment.dataset.instructionKind = instructionKind; 531cb0ef41Sopenharmony_ci fragment.title = view.sourceResolver.instructionKindToReadableName(instructionKind); 541cb0ef41Sopenharmony_ci const blockIds = view.sourceResolver.getBlockIdsForOffset(offset); 551cb0ef41Sopenharmony_ci const blockIdElement = document.createElement("SPAN"); 561cb0ef41Sopenharmony_ci blockIdElement.className = "block-id com linkable-text"; 571cb0ef41Sopenharmony_ci blockIdElement.innerText = ""; 581cb0ef41Sopenharmony_ci if (blockIds && blockIds.length > 0) { 591cb0ef41Sopenharmony_ci blockIds.forEach(blockId => view.addHtmlElementForBlockId(blockId, fragment)); 601cb0ef41Sopenharmony_ci blockIdElement.innerText = `B${blockIds.join(",")}:`; 611cb0ef41Sopenharmony_ci blockIdElement.dataset.blockId = `${blockIds.join(",")}`; 621cb0ef41Sopenharmony_ci } 631cb0ef41Sopenharmony_ci fragment.appendChild(blockIdElement); 641cb0ef41Sopenharmony_ci const addressElement = document.createElement("SPAN"); 651cb0ef41Sopenharmony_ci addressElement.className = "instruction-address"; 661cb0ef41Sopenharmony_ci addressElement.innerText = matches.groups["address"]; 671cb0ef41Sopenharmony_ci const offsetElement = document.createElement("SPAN"); 681cb0ef41Sopenharmony_ci offsetElement.innerText = matches.groups["offset"]; 691cb0ef41Sopenharmony_ci fragment.appendChild(addressElement); 701cb0ef41Sopenharmony_ci fragment.appendChild(document.createTextNode(matches.groups["addressSpace"])); 711cb0ef41Sopenharmony_ci fragment.appendChild(offsetElement); 721cb0ef41Sopenharmony_ci fragment.appendChild(document.createTextNode(matches.groups["offsetSpace"])); 731cb0ef41Sopenharmony_ci fragment.classList.add('tag'); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci if (!Number.isNaN(offset)) { 761cb0ef41Sopenharmony_ci let pcOffset = view.sourceResolver.getKeyPcOffset(offset); 771cb0ef41Sopenharmony_ci if (pcOffset == -1) pcOffset = Number(offset); 781cb0ef41Sopenharmony_ci fragment.dataset.pcOffset = `${pcOffset}`; 791cb0ef41Sopenharmony_ci addressElement.classList.add('linkable-text'); 801cb0ef41Sopenharmony_ci offsetElement.classList.add('linkable-text'); 811cb0ef41Sopenharmony_ci } 821cb0ef41Sopenharmony_ci return true; 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci }; 851cb0ef41Sopenharmony_ci const UNCLASSIFIED_STYLE = { 861cb0ef41Sopenharmony_ci css: 'com' 871cb0ef41Sopenharmony_ci }; 881cb0ef41Sopenharmony_ci const NUMBER_STYLE = { 891cb0ef41Sopenharmony_ci css: ['instruction-binary', 'lit'] 901cb0ef41Sopenharmony_ci }; 911cb0ef41Sopenharmony_ci const COMMENT_STYLE = { 921cb0ef41Sopenharmony_ci css: 'com' 931cb0ef41Sopenharmony_ci }; 941cb0ef41Sopenharmony_ci const OPCODE_ARGS = { 951cb0ef41Sopenharmony_ci associateData: function (text, fragment) { 961cb0ef41Sopenharmony_ci fragment.innerHTML = text; 971cb0ef41Sopenharmony_ci const replacer = (match, hexOffset) => { 981cb0ef41Sopenharmony_ci const offset = Number.parseInt(hexOffset, 16); 991cb0ef41Sopenharmony_ci let keyOffset = view.sourceResolver.getKeyPcOffset(offset); 1001cb0ef41Sopenharmony_ci if (keyOffset == -1) keyOffset = Number(offset); 1011cb0ef41Sopenharmony_ci const blockIds = view.sourceResolver.getBlockIdsForOffset(offset); 1021cb0ef41Sopenharmony_ci let block = ""; 1031cb0ef41Sopenharmony_ci let blockIdData = ""; 1041cb0ef41Sopenharmony_ci if (blockIds && blockIds.length > 0) { 1051cb0ef41Sopenharmony_ci block = `B${blockIds.join(",")} `; 1061cb0ef41Sopenharmony_ci blockIdData = `data-block-id="${blockIds.join(",")}"`; 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci return `<span class="tag linkable-text" data-pc-offset="${keyOffset}" ${blockIdData}>${block}${match}</span>`; 1091cb0ef41Sopenharmony_ci }; 1101cb0ef41Sopenharmony_ci const html = text.replace(/<.0?x?([0-9a-fA-F]+)>/g, replacer); 1111cb0ef41Sopenharmony_ci fragment.innerHTML = html; 1121cb0ef41Sopenharmony_ci return true; 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci }; 1151cb0ef41Sopenharmony_ci const OPCODE_STYLE = { 1161cb0ef41Sopenharmony_ci css: 'kwd' 1171cb0ef41Sopenharmony_ci }; 1181cb0ef41Sopenharmony_ci const BLOCK_HEADER_STYLE = { 1191cb0ef41Sopenharmony_ci associateData: function (text, fragment) { 1201cb0ef41Sopenharmony_ci if (view.sourceResolver.hasBlockStartInfo()) return false; 1211cb0ef41Sopenharmony_ci const matches = /\d+/.exec(text); 1221cb0ef41Sopenharmony_ci if (!matches) return true; 1231cb0ef41Sopenharmony_ci const blockId = matches[0]; 1241cb0ef41Sopenharmony_ci fragment.dataset.blockId = blockId; 1251cb0ef41Sopenharmony_ci fragment.innerHTML = text; 1261cb0ef41Sopenharmony_ci fragment.className = "com block"; 1271cb0ef41Sopenharmony_ci return true; 1281cb0ef41Sopenharmony_ci } 1291cb0ef41Sopenharmony_ci }; 1301cb0ef41Sopenharmony_ci const SOURCE_POSITION_HEADER_STYLE = { 1311cb0ef41Sopenharmony_ci css: 'com' 1321cb0ef41Sopenharmony_ci }; 1331cb0ef41Sopenharmony_ci view.SOURCE_POSITION_HEADER_REGEX = /^\s*--[^<]*<.*(not inlined|inlined\((\d+)\)):(\d+)>\s*--/; 1341cb0ef41Sopenharmony_ci const patterns = [ 1351cb0ef41Sopenharmony_ci [ 1361cb0ef41Sopenharmony_ci [/^0?x?[0-9a-fA-F]{8,16}\s+[0-9a-f]+\s+/, ADDRESS_STYLE, 1], 1371cb0ef41Sopenharmony_ci [view.SOURCE_POSITION_HEADER_REGEX, SOURCE_POSITION_HEADER_STYLE, -1], 1381cb0ef41Sopenharmony_ci [/^\s+-- B\d+ start.*/, BLOCK_HEADER_STYLE, -1], 1391cb0ef41Sopenharmony_ci [/^.*/, UNCLASSIFIED_STYLE, -1] 1401cb0ef41Sopenharmony_ci ], 1411cb0ef41Sopenharmony_ci [ 1421cb0ef41Sopenharmony_ci [/^\s*[0-9a-f]+\s+/, NUMBER_STYLE, 2], 1431cb0ef41Sopenharmony_ci [/^\s*[0-9a-f]+\s+[0-9a-f]+\s+/, NUMBER_STYLE, 2], 1441cb0ef41Sopenharmony_ci [/^.*/, null, -1] 1451cb0ef41Sopenharmony_ci ], 1461cb0ef41Sopenharmony_ci [ 1471cb0ef41Sopenharmony_ci [/^REX.W \S+\s+/, OPCODE_STYLE, 3], 1481cb0ef41Sopenharmony_ci [/^\S+\s+/, OPCODE_STYLE, 3], 1491cb0ef41Sopenharmony_ci [/^\S+$/, OPCODE_STYLE, -1], 1501cb0ef41Sopenharmony_ci [/^.*/, null, -1] 1511cb0ef41Sopenharmony_ci ], 1521cb0ef41Sopenharmony_ci [ 1531cb0ef41Sopenharmony_ci [/^\s+/, null], 1541cb0ef41Sopenharmony_ci [/^[^;]+$/, OPCODE_ARGS, -1], 1551cb0ef41Sopenharmony_ci [/^[^;]+/, OPCODE_ARGS, 4], 1561cb0ef41Sopenharmony_ci [/^;/, COMMENT_STYLE, 5] 1571cb0ef41Sopenharmony_ci ], 1581cb0ef41Sopenharmony_ci [ 1591cb0ef41Sopenharmony_ci [/^.+$/, COMMENT_STYLE, -1] 1601cb0ef41Sopenharmony_ci ] 1611cb0ef41Sopenharmony_ci ]; 1621cb0ef41Sopenharmony_ci view.setPatterns(patterns); 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci const linkHandler = (e: MouseEvent) => { 1651cb0ef41Sopenharmony_ci if (!(e.target instanceof HTMLElement)) return; 1661cb0ef41Sopenharmony_ci const offsetAsString = typeof e.target.dataset.pcOffset != "undefined" ? e.target.dataset.pcOffset : e.target.parentElement.dataset.pcOffset; 1671cb0ef41Sopenharmony_ci const offset = Number.parseInt(offsetAsString, 10); 1681cb0ef41Sopenharmony_ci if ((typeof offsetAsString) != "undefined" && !Number.isNaN(offset)) { 1691cb0ef41Sopenharmony_ci view.offsetSelection.select([offset], true); 1701cb0ef41Sopenharmony_ci const nodes = view.sourceResolver.nodesForPCOffset(offset)[0]; 1711cb0ef41Sopenharmony_ci if (nodes.length > 0) { 1721cb0ef41Sopenharmony_ci e.stopPropagation(); 1731cb0ef41Sopenharmony_ci if (!e.shiftKey) { 1741cb0ef41Sopenharmony_ci view.selectionHandler.clear(); 1751cb0ef41Sopenharmony_ci } 1761cb0ef41Sopenharmony_ci view.selectionHandler.select(nodes, true); 1771cb0ef41Sopenharmony_ci } else { 1781cb0ef41Sopenharmony_ci view.updateSelection(); 1791cb0ef41Sopenharmony_ci } 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci return undefined; 1821cb0ef41Sopenharmony_ci }; 1831cb0ef41Sopenharmony_ci view.divNode.addEventListener('click', linkHandler); 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci const linkHandlerBlock = e => { 1861cb0ef41Sopenharmony_ci const blockId = e.target.dataset.blockId; 1871cb0ef41Sopenharmony_ci if (typeof blockId != "undefined") { 1881cb0ef41Sopenharmony_ci const blockIds = blockId.split(","); 1891cb0ef41Sopenharmony_ci if (!e.shiftKey) { 1901cb0ef41Sopenharmony_ci view.selectionHandler.clear(); 1911cb0ef41Sopenharmony_ci } 1921cb0ef41Sopenharmony_ci view.blockSelectionHandler.select(blockIds, true); 1931cb0ef41Sopenharmony_ci } 1941cb0ef41Sopenharmony_ci }; 1951cb0ef41Sopenharmony_ci view.divNode.addEventListener('click', linkHandlerBlock); 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci this.offsetSelection = new MySelection(anyToString); 1981cb0ef41Sopenharmony_ci const instructionSelectionHandler = { 1991cb0ef41Sopenharmony_ci clear: function () { 2001cb0ef41Sopenharmony_ci view.offsetSelection.clear(); 2011cb0ef41Sopenharmony_ci view.updateSelection(); 2021cb0ef41Sopenharmony_ci broker.broadcastClear(instructionSelectionHandler); 2031cb0ef41Sopenharmony_ci }, 2041cb0ef41Sopenharmony_ci select: function (instructionIds, selected) { 2051cb0ef41Sopenharmony_ci view.offsetSelection.select(instructionIds, selected); 2061cb0ef41Sopenharmony_ci view.updateSelection(); 2071cb0ef41Sopenharmony_ci broker.broadcastBlockSelect(instructionSelectionHandler, instructionIds, selected); 2081cb0ef41Sopenharmony_ci }, 2091cb0ef41Sopenharmony_ci brokeredInstructionSelect: function (instructionIds, selected) { 2101cb0ef41Sopenharmony_ci const firstSelect = view.offsetSelection.isEmpty(); 2111cb0ef41Sopenharmony_ci const keyPcOffsets = view.sourceResolver.instructionsToKeyPcOffsets(instructionIds); 2121cb0ef41Sopenharmony_ci view.offsetSelection.select(keyPcOffsets, selected); 2131cb0ef41Sopenharmony_ci view.updateSelection(firstSelect); 2141cb0ef41Sopenharmony_ci }, 2151cb0ef41Sopenharmony_ci brokeredClear: function () { 2161cb0ef41Sopenharmony_ci view.offsetSelection.clear(); 2171cb0ef41Sopenharmony_ci view.updateSelection(); 2181cb0ef41Sopenharmony_ci } 2191cb0ef41Sopenharmony_ci }; 2201cb0ef41Sopenharmony_ci this.instructionSelectionHandler = instructionSelectionHandler; 2211cb0ef41Sopenharmony_ci broker.addInstructionHandler(instructionSelectionHandler); 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci const toolbox = document.createElement("div"); 2241cb0ef41Sopenharmony_ci toolbox.id = "toolbox-anchor"; 2251cb0ef41Sopenharmony_ci toolbox.innerHTML = toolboxHTML; 2261cb0ef41Sopenharmony_ci view.divNode.insertBefore(toolbox, view.divNode.firstChild); 2271cb0ef41Sopenharmony_ci const instructionAddressInput: HTMLInputElement = view.divNode.querySelector("#show-instruction-address"); 2281cb0ef41Sopenharmony_ci const lastShowInstructionAddress = window.sessionStorage.getItem("show-instruction-address"); 2291cb0ef41Sopenharmony_ci instructionAddressInput.checked = lastShowInstructionAddress == 'true'; 2301cb0ef41Sopenharmony_ci const showInstructionAddressHandler = () => { 2311cb0ef41Sopenharmony_ci window.sessionStorage.setItem("show-instruction-address", `${instructionAddressInput.checked}`); 2321cb0ef41Sopenharmony_ci for (const el of view.divNode.querySelectorAll(".instruction-address")) { 2331cb0ef41Sopenharmony_ci el.classList.toggle("invisible", !instructionAddressInput.checked); 2341cb0ef41Sopenharmony_ci } 2351cb0ef41Sopenharmony_ci }; 2361cb0ef41Sopenharmony_ci instructionAddressInput.addEventListener("change", showInstructionAddressHandler); 2371cb0ef41Sopenharmony_ci this.showInstructionAddressHandler = showInstructionAddressHandler; 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci const instructionBinaryInput: HTMLInputElement = view.divNode.querySelector("#show-instruction-binary"); 2401cb0ef41Sopenharmony_ci const lastShowInstructionBinary = window.sessionStorage.getItem("show-instruction-binary"); 2411cb0ef41Sopenharmony_ci instructionBinaryInput.checked = lastShowInstructionBinary == 'true'; 2421cb0ef41Sopenharmony_ci const showInstructionBinaryHandler = () => { 2431cb0ef41Sopenharmony_ci window.sessionStorage.setItem("show-instruction-binary", `${instructionBinaryInput.checked}`); 2441cb0ef41Sopenharmony_ci for (const el of view.divNode.querySelectorAll(".instruction-binary")) { 2451cb0ef41Sopenharmony_ci el.classList.toggle("invisible", !instructionBinaryInput.checked); 2461cb0ef41Sopenharmony_ci } 2471cb0ef41Sopenharmony_ci }; 2481cb0ef41Sopenharmony_ci instructionBinaryInput.addEventListener("change", showInstructionBinaryHandler); 2491cb0ef41Sopenharmony_ci this.showInstructionBinaryHandler = showInstructionBinaryHandler; 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ci const highlightGapInstructionsInput: HTMLInputElement = view.divNode.querySelector("#highlight-gap-instructions"); 2521cb0ef41Sopenharmony_ci const lastHighlightGapInstructions = window.sessionStorage.getItem("highlight-gap-instructions"); 2531cb0ef41Sopenharmony_ci highlightGapInstructionsInput.checked = lastHighlightGapInstructions == 'true'; 2541cb0ef41Sopenharmony_ci const highlightGapInstructionsHandler = () => { 2551cb0ef41Sopenharmony_ci window.sessionStorage.setItem("highlight-gap-instructions", `${highlightGapInstructionsInput.checked}`); 2561cb0ef41Sopenharmony_ci view.divNode.classList.toggle("highlight-gap-instructions", highlightGapInstructionsInput.checked); 2571cb0ef41Sopenharmony_ci }; 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci highlightGapInstructionsInput.addEventListener("change", highlightGapInstructionsHandler); 2601cb0ef41Sopenharmony_ci this.highlightGapInstructionsHandler = highlightGapInstructionsHandler; 2611cb0ef41Sopenharmony_ci } 2621cb0ef41Sopenharmony_ci 2631cb0ef41Sopenharmony_ci updateSelection(scrollIntoView: boolean = false) { 2641cb0ef41Sopenharmony_ci super.updateSelection(scrollIntoView); 2651cb0ef41Sopenharmony_ci const keyPcOffsets = this.sourceResolver.nodesToKeyPcOffsets(this.selection.selectedKeys()); 2661cb0ef41Sopenharmony_ci if (this.offsetSelection) { 2671cb0ef41Sopenharmony_ci for (const key of this.offsetSelection.selectedKeys()) { 2681cb0ef41Sopenharmony_ci keyPcOffsets.push(Number(key)); 2691cb0ef41Sopenharmony_ci } 2701cb0ef41Sopenharmony_ci } 2711cb0ef41Sopenharmony_ci for (const keyPcOffset of keyPcOffsets) { 2721cb0ef41Sopenharmony_ci const elementsToSelect = this.divNode.querySelectorAll(`[data-pc-offset='${keyPcOffset}']`); 2731cb0ef41Sopenharmony_ci for (const el of elementsToSelect) { 2741cb0ef41Sopenharmony_ci el.classList.toggle("selected", true); 2751cb0ef41Sopenharmony_ci } 2761cb0ef41Sopenharmony_ci } 2771cb0ef41Sopenharmony_ci } 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci initializeCode(sourceText, sourcePosition: number = 0) { 2801cb0ef41Sopenharmony_ci const view = this; 2811cb0ef41Sopenharmony_ci view.addrEventCounts = null; 2821cb0ef41Sopenharmony_ci view.totalEventCounts = null; 2831cb0ef41Sopenharmony_ci view.maxEventCounts = null; 2841cb0ef41Sopenharmony_ci view.posLines = new Array(); 2851cb0ef41Sopenharmony_ci // Comment lines for line 0 include sourcePosition already, only need to 2861cb0ef41Sopenharmony_ci // add sourcePosition for lines > 0. 2871cb0ef41Sopenharmony_ci view.posLines[0] = sourcePosition; 2881cb0ef41Sopenharmony_ci if (sourceText && sourceText != "") { 2891cb0ef41Sopenharmony_ci const base = sourcePosition; 2901cb0ef41Sopenharmony_ci let current = 0; 2911cb0ef41Sopenharmony_ci const sourceLines = sourceText.split("\n"); 2921cb0ef41Sopenharmony_ci for (let i = 1; i < sourceLines.length; i++) { 2931cb0ef41Sopenharmony_ci // Add 1 for newline character that is split off. 2941cb0ef41Sopenharmony_ci current += sourceLines[i - 1].length + 1; 2951cb0ef41Sopenharmony_ci view.posLines[i] = base + current; 2961cb0ef41Sopenharmony_ci } 2971cb0ef41Sopenharmony_ci } 2981cb0ef41Sopenharmony_ci } 2991cb0ef41Sopenharmony_ci 3001cb0ef41Sopenharmony_ci initializePerfProfile(eventCounts) { 3011cb0ef41Sopenharmony_ci const view = this; 3021cb0ef41Sopenharmony_ci if (eventCounts !== undefined) { 3031cb0ef41Sopenharmony_ci view.addrEventCounts = eventCounts; 3041cb0ef41Sopenharmony_ci 3051cb0ef41Sopenharmony_ci view.totalEventCounts = {}; 3061cb0ef41Sopenharmony_ci view.maxEventCounts = {}; 3071cb0ef41Sopenharmony_ci for (const evName in view.addrEventCounts) { 3081cb0ef41Sopenharmony_ci if (view.addrEventCounts.hasOwnProperty(evName)) { 3091cb0ef41Sopenharmony_ci const keys = Object.keys(view.addrEventCounts[evName]); 3101cb0ef41Sopenharmony_ci const values = keys.map(key => view.addrEventCounts[evName][key]); 3111cb0ef41Sopenharmony_ci view.totalEventCounts[evName] = values.reduce((a, b) => a + b); 3121cb0ef41Sopenharmony_ci view.maxEventCounts[evName] = values.reduce((a, b) => Math.max(a, b)); 3131cb0ef41Sopenharmony_ci } 3141cb0ef41Sopenharmony_ci } 3151cb0ef41Sopenharmony_ci } else { 3161cb0ef41Sopenharmony_ci view.addrEventCounts = null; 3171cb0ef41Sopenharmony_ci view.totalEventCounts = null; 3181cb0ef41Sopenharmony_ci view.maxEventCounts = null; 3191cb0ef41Sopenharmony_ci } 3201cb0ef41Sopenharmony_ci } 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ci showContent(data): void { 3231cb0ef41Sopenharmony_ci console.time("disassembly-view"); 3241cb0ef41Sopenharmony_ci super.initializeContent(data, null); 3251cb0ef41Sopenharmony_ci this.showInstructionAddressHandler(); 3261cb0ef41Sopenharmony_ci this.showInstructionBinaryHandler(); 3271cb0ef41Sopenharmony_ci this.highlightGapInstructionsHandler(); 3281cb0ef41Sopenharmony_ci console.timeEnd("disassembly-view"); 3291cb0ef41Sopenharmony_ci } 3301cb0ef41Sopenharmony_ci 3311cb0ef41Sopenharmony_ci // Shorten decimals and remove trailing zeroes for readability. 3321cb0ef41Sopenharmony_ci humanize(num) { 3331cb0ef41Sopenharmony_ci return num.toFixed(3).replace(/\.?0+$/, "") + "%"; 3341cb0ef41Sopenharmony_ci } 3351cb0ef41Sopenharmony_ci 3361cb0ef41Sopenharmony_ci processLine(line) { 3371cb0ef41Sopenharmony_ci const view = this; 3381cb0ef41Sopenharmony_ci let fragments = super.processLine(line); 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ci // Add profiling data per instruction if available. 3411cb0ef41Sopenharmony_ci if (view.totalEventCounts) { 3421cb0ef41Sopenharmony_ci const matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line); 3431cb0ef41Sopenharmony_ci if (matches) { 3441cb0ef41Sopenharmony_ci const newFragments = []; 3451cb0ef41Sopenharmony_ci for (const event in view.addrEventCounts) { 3461cb0ef41Sopenharmony_ci if (!view.addrEventCounts.hasOwnProperty(event)) continue; 3471cb0ef41Sopenharmony_ci const count = view.addrEventCounts[event][matches[1]]; 3481cb0ef41Sopenharmony_ci let str = " "; 3491cb0ef41Sopenharmony_ci const cssCls = "prof"; 3501cb0ef41Sopenharmony_ci if (count !== undefined) { 3511cb0ef41Sopenharmony_ci const perc = count / view.totalEventCounts[event] * 100; 3521cb0ef41Sopenharmony_ci 3531cb0ef41Sopenharmony_ci let col = { r: 255, g: 255, b: 255 }; 3541cb0ef41Sopenharmony_ci for (let i = 0; i < PROF_COLS.length; i++) { 3551cb0ef41Sopenharmony_ci if (perc === PROF_COLS[i].perc) { 3561cb0ef41Sopenharmony_ci col = PROF_COLS[i].col; 3571cb0ef41Sopenharmony_ci break; 3581cb0ef41Sopenharmony_ci } else if (perc > PROF_COLS[i].perc && perc < PROF_COLS[i + 1].perc) { 3591cb0ef41Sopenharmony_ci const col1 = PROF_COLS[i].col; 3601cb0ef41Sopenharmony_ci const col2 = PROF_COLS[i + 1].col; 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci const val = perc - PROF_COLS[i].perc; 3631cb0ef41Sopenharmony_ci const max = PROF_COLS[i + 1].perc - PROF_COLS[i].perc; 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ci col.r = Math.round(interpolate(val, max, col1.r, col2.r)); 3661cb0ef41Sopenharmony_ci col.g = Math.round(interpolate(val, max, col1.g, col2.g)); 3671cb0ef41Sopenharmony_ci col.b = Math.round(interpolate(val, max, col1.b, col2.b)); 3681cb0ef41Sopenharmony_ci break; 3691cb0ef41Sopenharmony_ci } 3701cb0ef41Sopenharmony_ci } 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci str = UNICODE_BLOCK; 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ci const fragment = view.createFragment(str, cssCls); 3751cb0ef41Sopenharmony_ci fragment.title = event + ": " + view.humanize(perc) + " (" + count + ")"; 3761cb0ef41Sopenharmony_ci fragment.style.color = "rgb(" + col.r + ", " + col.g + ", " + col.b + ")"; 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_ci newFragments.push(fragment); 3791cb0ef41Sopenharmony_ci } else { 3801cb0ef41Sopenharmony_ci newFragments.push(view.createFragment(str, cssCls)); 3811cb0ef41Sopenharmony_ci } 3821cb0ef41Sopenharmony_ci } 3831cb0ef41Sopenharmony_ci fragments = newFragments.concat(fragments); 3841cb0ef41Sopenharmony_ci } 3851cb0ef41Sopenharmony_ci } 3861cb0ef41Sopenharmony_ci return fragments; 3871cb0ef41Sopenharmony_ci } 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ci detachSelection() { return null; } 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci public searchInputAction(searchInput: HTMLInputElement, e: Event, onlyVisible: boolean): void { 3921cb0ef41Sopenharmony_ci throw new Error("Method not implemented."); 3931cb0ef41Sopenharmony_ci } 3941cb0ef41Sopenharmony_ci} 395