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 5import { SourceResolver } from "../src/source-resolver"; 6import { SelectionBroker } from "../src/selection-broker"; 7import { DisassemblyView } from "../src/disassembly-view"; 8import { GraphMultiView } from "../src/graphmultiview"; 9import { CodeMode, CodeView } from "../src/code-view"; 10import { Tabs } from "../src/tabs"; 11import { Resizer } from "../src/resizer"; 12import * as C from "../src/constants"; 13import { InfoView } from "./info-view"; 14 15window.onload = function () { 16 let multiview: GraphMultiView = null; 17 let disassemblyView: DisassemblyView = null; 18 let sourceViews: Array<CodeView> = []; 19 let selectionBroker: SelectionBroker = null; 20 let sourceResolver: SourceResolver = null; 21 const resizer = new Resizer(panesUpdatedCallback, 75, 75); 22 const sourceTabsContainer = document.getElementById(C.SOURCE_PANE_ID); 23 const sourceTabs = new Tabs(sourceTabsContainer); 24 sourceTabs.addTab("+").classList.add("last-tab", "persistent-tab"); 25 const disassemblyTabsContainer = document.getElementById(C.GENERATED_PANE_ID); 26 const disassemblyTabs = new Tabs(disassemblyTabsContainer); 27 disassemblyTabs.addTab("+").classList.add("last-tab", "persistent-tab"); 28 const [infoTab, infoContainer] = sourceTabs.addTabAndContent("Info"); 29 infoTab.classList.add("persistent-tab"); 30 infoContainer.classList.add("viewpane", "scrollable"); 31 const infoView = new InfoView(infoContainer); 32 infoView.show(); 33 sourceTabs.activateTab(infoTab); 34 35 function panesUpdatedCallback() { 36 if (multiview) multiview.onresize(); 37 } 38 39 function loadFile(txtRes: string) { 40 sourceTabs.clearTabsAndContent(); 41 disassemblyTabs.clearTabsAndContent(); 42 // If the JSON isn't properly terminated, assume compiler crashed and 43 // add best-guess empty termination 44 if (txtRes[txtRes.length - 2] == ',') { 45 txtRes += '{"name":"disassembly","type":"disassembly","data":""}]}'; 46 } 47 try { 48 sourceViews.forEach(sv => sv.hide()); 49 if (multiview) multiview.hide(); 50 multiview = null; 51 document.getElementById("ranges").innerHTML = ''; 52 document.getElementById('ranges').style.visibility = "hidden"; 53 document.getElementById('show-hide-ranges').style.visibility = "hidden"; 54 if (disassemblyView) disassemblyView.hide(); 55 sourceViews = []; 56 sourceResolver = new SourceResolver(); 57 selectionBroker = new SelectionBroker(sourceResolver); 58 59 const jsonObj = JSON.parse(txtRes); 60 61 let fnc = null; 62 // Backwards compatibility. 63 if (typeof jsonObj.function == 'string') { 64 fnc = { 65 functionName: fnc, 66 sourceId: -1, 67 startPosition: jsonObj.sourcePosition, 68 endPosition: jsonObj.sourcePosition + jsonObj.source.length, 69 sourceText: jsonObj.source, 70 backwardsCompatibility: true 71 }; 72 } else { 73 fnc = Object.assign(jsonObj.function, { backwardsCompatibility: false }); 74 } 75 76 sourceResolver.setInlinings(jsonObj.inlinings); 77 sourceResolver.setSourceLineToBytecodePosition(jsonObj.sourceLineToBytecodePosition); 78 sourceResolver.setSources(jsonObj.sources, fnc); 79 sourceResolver.setNodePositionMap(jsonObj.nodePositions); 80 sourceResolver.parsePhases(jsonObj.phases); 81 82 const [sourceTab, sourceContainer] = sourceTabs.addTabAndContent("Source"); 83 sourceContainer.classList.add("viewpane", "scrollable"); 84 sourceTabs.activateTab(sourceTab); 85 const sourceView = new CodeView(sourceContainer, selectionBroker, sourceResolver, fnc, CodeMode.MAIN_SOURCE); 86 sourceView.show(); 87 sourceViews.push(sourceView); 88 89 sourceResolver.forEachSource(source => { 90 const sourceView = new CodeView(sourceContainer, selectionBroker, sourceResolver, source, CodeMode.INLINED_SOURCE); 91 sourceView.show(); 92 sourceViews.push(sourceView); 93 }); 94 95 const [disassemblyTab, disassemblyContainer] = disassemblyTabs.addTabAndContent("Disassembly"); 96 disassemblyContainer.classList.add("viewpane", "scrollable"); 97 disassemblyTabs.activateTab(disassemblyTab); 98 disassemblyView = new DisassemblyView(disassemblyContainer, selectionBroker); 99 disassemblyView.initializeCode(fnc.sourceText); 100 if (sourceResolver.disassemblyPhase) { 101 disassemblyView.initializePerfProfile(jsonObj.eventCounts); 102 disassemblyView.showContent(sourceResolver.disassemblyPhase.data); 103 disassemblyView.show(); 104 } 105 106 multiview = new GraphMultiView(C.INTERMEDIATE_PANE_ID, selectionBroker, sourceResolver); 107 multiview.show(); 108 } catch (err) { 109 if (window.confirm("Error: Exception during load of TurboFan JSON file:\n" + 110 "error: " + err.message + "\nDo you want to clear session storage?")) { 111 window.sessionStorage.clear(); 112 } 113 return; 114 } 115 } 116 117 function initializeUploadHandlers() { 118 // The <input> form #upload-helper with type file can't be a picture. 119 // We hence keep it hidden, and forward the click from the picture 120 // button #upload. 121 document.getElementById("upload").addEventListener("click", e => { 122 document.getElementById("upload-helper").click(); 123 e.stopPropagation(); 124 }); 125 document.getElementById("upload-helper").addEventListener("change", 126 function (this: HTMLInputElement) { 127 const uploadFile = this.files && this.files[0]; 128 if (uploadFile) { 129 const filereader = new FileReader(); 130 filereader.onload = () => { 131 const txtRes = filereader.result; 132 if (typeof txtRes == 'string') { 133 loadFile(txtRes); 134 } 135 }; 136 filereader.readAsText(uploadFile); 137 } 138 } 139 ); 140 window.addEventListener("keydown", (e: KeyboardEvent) => { 141 if (e.keyCode == 76 && e.ctrlKey) { // CTRL + L 142 document.getElementById("upload-helper").click(); 143 e.stopPropagation(); 144 e.preventDefault(); 145 } 146 }); 147 } 148 149 initializeUploadHandlers(); 150 resizer.updatePanes(); 151}; 152