1// Copyright 2015 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, sourcePositionValid } from "../src/source-resolver"; 6import { ClearableHandler, SelectionHandler, NodeSelectionHandler, BlockSelectionHandler, InstructionSelectionHandler, RegisterAllocationSelectionHandler } from "../src/selection-handler"; 7 8export class SelectionBroker { 9 sourceResolver: SourceResolver; 10 allHandlers: Array<ClearableHandler>; 11 sourcePositionHandlers: Array<SelectionHandler>; 12 nodeHandlers: Array<NodeSelectionHandler>; 13 blockHandlers: Array<BlockSelectionHandler>; 14 instructionHandlers: Array<InstructionSelectionHandler>; 15 registerAllocationHandlers: Array<RegisterAllocationSelectionHandler>; 16 17 constructor(sourceResolver) { 18 this.allHandlers = []; 19 this.sourcePositionHandlers = []; 20 this.nodeHandlers = []; 21 this.blockHandlers = []; 22 this.instructionHandlers = []; 23 this.registerAllocationHandlers = []; 24 this.sourceResolver = sourceResolver; 25 } 26 27 addSourcePositionHandler(handler: SelectionHandler & ClearableHandler) { 28 this.allHandlers.push(handler); 29 this.sourcePositionHandlers.push(handler); 30 } 31 32 addNodeHandler(handler: NodeSelectionHandler & ClearableHandler) { 33 this.allHandlers.push(handler); 34 this.nodeHandlers.push(handler); 35 } 36 37 addBlockHandler(handler: BlockSelectionHandler & ClearableHandler) { 38 this.allHandlers.push(handler); 39 this.blockHandlers.push(handler); 40 } 41 42 addInstructionHandler(handler: InstructionSelectionHandler & ClearableHandler) { 43 this.allHandlers.push(handler); 44 this.instructionHandlers.push(handler); 45 } 46 47 addRegisterAllocatorHandler(handler: RegisterAllocationSelectionHandler & ClearableHandler) { 48 this.allHandlers.push(handler); 49 this.registerAllocationHandlers.push(handler); 50 } 51 52 broadcastInstructionSelect(from, instructionOffsets, selected) { 53 // Select the lines from the disassembly (right panel) 54 for (const b of this.instructionHandlers) { 55 if (b != from) b.brokeredInstructionSelect(instructionOffsets, selected); 56 } 57 58 // Select the lines from the source panel (left panel) 59 const pcOffsets = this.sourceResolver.instructionsToKeyPcOffsets(instructionOffsets); 60 for (const offset of pcOffsets) { 61 const nodes = this.sourceResolver.nodesForPCOffset(offset)[0]; 62 const sourcePositions = this.sourceResolver.nodeIdsToSourcePositions(nodes); 63 for (const b of this.sourcePositionHandlers) { 64 if (b != from) b.brokeredSourcePositionSelect(sourcePositions, selected); 65 } 66 } 67 68 // The middle panel lines have already been selected so there's no need to reselect them. 69 } 70 71 broadcastSourcePositionSelect(from, sourcePositions, selected) { 72 sourcePositions = sourcePositions.filter(l => { 73 if (!sourcePositionValid(l)) { 74 console.log("Warning: invalid source position"); 75 return false; 76 } 77 return true; 78 }); 79 80 // Select the lines from the source panel (left panel) 81 for (const b of this.sourcePositionHandlers) { 82 if (b != from) b.brokeredSourcePositionSelect(sourcePositions, selected); 83 } 84 85 // Select the nodes (middle panel) 86 const nodes = this.sourceResolver.sourcePositionsToNodeIds(sourcePositions); 87 for (const b of this.nodeHandlers) { 88 if (b != from) b.brokeredNodeSelect(nodes, selected); 89 } 90 91 for (const node of nodes) { 92 const instructionOffsets = this.sourceResolver.nodeIdToInstructionRange[node]; 93 // Skip nodes which do not have an associated instruction range. 94 if (instructionOffsets == undefined) continue; 95 96 // Select the lines from the disassembly (right panel) 97 for (const b of this.instructionHandlers) { 98 if (b != from) b.brokeredInstructionSelect(instructionOffsets, selected); 99 } 100 101 // Select the lines from the middle panel for the register allocation phase. 102 for (const b of this.registerAllocationHandlers) { 103 if (b != from) b.brokeredRegisterAllocationSelect(instructionOffsets, selected); 104 } 105 } 106 } 107 108 broadcastNodeSelect(from, nodes, selected) { 109 // Select the nodes (middle panel) 110 for (const b of this.nodeHandlers) { 111 if (b != from) b.brokeredNodeSelect(nodes, selected); 112 } 113 114 // Select the lines from the source panel (left panel) 115 const sourcePositions = this.sourceResolver.nodeIdsToSourcePositions(nodes); 116 for (const b of this.sourcePositionHandlers) { 117 if (b != from) b.brokeredSourcePositionSelect(sourcePositions, selected); 118 } 119 120 for (const node of nodes) { 121 const instructionOffsets = this.sourceResolver.nodeIdToInstructionRange[node]; 122 // Skip nodes which do not have an associated instruction range. 123 if (instructionOffsets == undefined) continue; 124 // Select the lines from the disassembly (right panel) 125 for (const b of this.instructionHandlers) { 126 if (b != from) b.brokeredInstructionSelect(instructionOffsets, selected); 127 } 128 129 // Select the lines from the middle panel for the register allocation phase. 130 for (const b of this.registerAllocationHandlers) { 131 if (b != from) b.brokeredRegisterAllocationSelect(instructionOffsets, selected); 132 } 133 } 134 } 135 136 broadcastBlockSelect(from, blocks, selected) { 137 for (const b of this.blockHandlers) { 138 if (b != from) b.brokeredBlockSelect(blocks, selected); 139 } 140 } 141 142 broadcastClear(from) { 143 this.allHandlers.forEach(function (b) { 144 if (b != from) b.brokeredClear(); 145 }); 146 } 147} 148