Package org.candle.decompiler.intermediate.graph.context

Source Code of org.candle.decompiler.intermediate.graph.context.IntermediateGraphContext

package org.candle.decompiler.intermediate.graph.context;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.apache.bcel.generic.InstructionHandle;
import org.candle.decompiler.instruction.graph.edge.EdgeType;
import org.candle.decompiler.intermediate.code.AbstractIntermediate;
import org.candle.decompiler.intermediate.code.BlockRange;
import org.candle.decompiler.intermediate.code.BooleanBranchIntermediate;
import org.candle.decompiler.intermediate.code.CaseIntermediate;
import org.candle.decompiler.intermediate.code.CaseIntermediateComparator;
import org.candle.decompiler.intermediate.code.CatchIntermediate;
import org.candle.decompiler.intermediate.code.FinallyIntermediate;
import org.candle.decompiler.intermediate.code.GoToIntermediate;
import org.candle.decompiler.intermediate.code.IntermediateComparator;
import org.candle.decompiler.intermediate.code.SwitchIntermediate;
import org.candle.decompiler.intermediate.code.TryIntermediate;
import org.candle.decompiler.intermediate.graph.edge.ConditionEdge;
import org.candle.decompiler.intermediate.graph.edge.IntermediateEdge;
import org.candle.decompiler.util.GraphUtil;
import org.jgrapht.Graphs;
import org.jgrapht.graph.ListenableDirectedGraph;

public class IntermediateGraphContext extends GraphUtil<AbstractIntermediate> {

  private final TreeSet<AbstractIntermediate> orderedIntermediate;
  private final Map<Integer, InstructionHandle> instructionHandles;
 
  public IntermediateGraphContext(ListenableDirectedGraph<AbstractIntermediate, IntermediateEdge> graph) {
    super(graph);
    this.orderedIntermediate = new TreeSet<AbstractIntermediate>(new IntermediateComparator());
    this.instructionHandles = new TreeMap<Integer, InstructionHandle>();
   
    for(AbstractIntermediate ai : graph.vertexSet()) {
      Integer position = ai.getInstruction().getPosition();
      this.instructionHandles.put(position, ai.getInstruction());
    }
   
    this.orderedIntermediate.addAll(this.graph.vertexSet());
    this.graph.addGraphListener(new PositionalIntermediateListener(this));
  }
 
  public TreeSet<AbstractIntermediate> getOrderedIntermediate() {
    return this.orderedIntermediate;
  }
 
  public Map<Integer, InstructionHandle> getInstructionHandles() {
    return instructionHandles;
  }
 
  public InstructionHandle getInstructionHandle(Integer position) {
    return this.instructionHandles.get(position);
  }
 
  public AbstractIntermediate findNextNode(InstructionHandle ci) {
    NullIntermediate nullIntermediate = new NullIntermediate(ci);
    return this.orderedIntermediate.ceiling(nullIntermediate);
  }
 
  public AbstractIntermediate findPreviousNode(InstructionHandle ci) {
    NullIntermediate nullIntermediate = new NullIntermediate(ci);
    return this.orderedIntermediate.floor(nullIntermediate);
  }
 
  public AbstractIntermediate getTrueTarget(BooleanBranchIntermediate ci) {
    //find true edge...
    List<AbstractIntermediate> successors = getSuccessors(ci);
   
    for(AbstractIntermediate successor : successors) {
      IntermediateEdge ie  = graph.getEdge(ci, successor);
     
      if(ie instanceof ConditionEdge) {
        if(((ConditionEdge) ie).isCondition()) {
          return successor;
        }
      }
    }
   
    return null;
  }
 
  public AbstractIntermediate getTarget(GoToIntermediate gt) {
    return getSingleSuccessor(gt);
  }
 
  public AbstractIntermediate getFalseTarget(BooleanBranchIntermediate ci) {
    //find true edge...
        List<AbstractIntermediate> successors = getSuccessors(ci);
       
        for(AbstractIntermediate successor : successors) {
          IntermediateEdge ie  = graph.getEdge(ci, successor);
         
          if(ie instanceof ConditionEdge) {
            //false condition
            if(!((ConditionEdge) ie).isCondition()) {
              return successor;
            }
          }
        }
       
        return null;
  }
 
  public List<CatchIntermediate> getCatchClauses(TryIntermediate tryIntermediate) {
    //of all the successors, get the catch...
    List<AbstractIntermediate> candidates = Graphs.successorListOf(graph, tryIntermediate);

    List<CatchIntermediate> catchClauses = new ArrayList<CatchIntermediate>();
    for(AbstractIntermediate candidate : candidates) {
      if(candidate instanceof CatchIntermediate) {
        catchClauses.add((CatchIntermediate)candidate);
      }
    }
    return catchClauses;
  }
 
  public FinallyIntermediate getFinallyClause(TryIntermediate tryIntermediate) {
    //of all the successors, get the catch...
    List<AbstractIntermediate> candidates = Graphs.successorListOf(graph, tryIntermediate);

    for(AbstractIntermediate candidate : candidates) {
      if(candidate instanceof FinallyIntermediate) {
        return (FinallyIntermediate)candidate;
      }
    }
    return null;   
  }
 
  public void validateBackEdge(IntermediateEdge ie) {
    if(ie.getType() == EdgeType.EXCEPTION) {
      return;
    }
   
    int source = ie.getSourceIntermediate().getInstruction().getPosition();
    int target = ie.getTargetIntermediate().getInstruction().getPosition();
   
    if(target < source) {
      ie.setType(EdgeType.BACK);
    }
    else {
      ie.setType(EdgeType.NORMAL);
    }
  }
 
  public List<CaseIntermediate> getCases(SwitchIntermediate si) {
    List<AbstractIntermediate> intermediate = Graphs.successorListOf(graph, si);
    
    List<CaseIntermediate> switchCases = new LinkedList<CaseIntermediate>();
    for(AbstractIntermediate i : intermediate) {
      if(i instanceof CaseIntermediate) {
        switchCases.add((CaseIntermediate)i);
      }
    }
    Collections.sort(switchCases, new CaseIntermediateComparator());
    return switchCases;
  }
 
  public Set<AbstractIntermediate> getNodesWithinRange(BlockRange blockRange) {
    AbstractIntermediate start = findNextNode(blockRange.getStart());
    AbstractIntermediate end = findPreviousNode(blockRange.getEnd());
   
    return orderedIntermediate.subSet(start, false, end, false);
  }
 
 
}
TOP

Related Classes of org.candle.decompiler.intermediate.graph.context.IntermediateGraphContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.