Fork of the Fernflower decompiler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fernflower/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java

267 lines
6.7 KiB

11 years ago
/*
* Copyright 2000-2014 JetBrains s.r.o.
11 years ago
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
11 years ago
*
* http://www.apache.org/licenses/LICENSE-2.0
11 years ago
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
11 years ago
*/
package org.jetbrains.java.decompiler.code.cfg;
11 years ago
import org.jetbrains.java.decompiler.code.Instruction;
import org.jetbrains.java.decompiler.code.InstructionSequence;
import org.jetbrains.java.decompiler.code.SimpleInstructionSequence;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.modules.decompiler.decompose.IGraphNode;
11 years ago
import java.util.ArrayList;
import java.util.List;
11 years ago
public class BasicBlock implements IGraphNode {
// *****************************************************************************
// public fields
// *****************************************************************************
public int id = 0;
public int mark = 0;
// *****************************************************************************
// private fields
// *****************************************************************************
private InstructionSequence seq = new SimpleInstructionSequence();
private List<BasicBlock> preds = new ArrayList<BasicBlock>();
private List<BasicBlock> succs = new ArrayList<BasicBlock>();
private List<Integer> instrOldOffsets = new ArrayList<Integer>();
private List<BasicBlock> predExceptions = new ArrayList<BasicBlock>();
private List<BasicBlock> succExceptions = new ArrayList<BasicBlock>();
public BasicBlock() {
}
public BasicBlock(int id) {
this.id = id;
}
// *****************************************************************************
// public methods
// *****************************************************************************
public Object clone() {
BasicBlock block = new BasicBlock();
block.id = id;
block.setSeq(seq.clone());
block.setInstrOldOffsets(new ArrayList<Integer>(instrOldOffsets));
return block;
}
public void free() {
preds.clear();
succs.clear();
instrOldOffsets.clear();
succExceptions.clear();
seq = new SimpleInstructionSequence();
}
public Instruction getInstruction(int index) {
return seq.getInstr(index);
}
public Instruction getLastInstruction() {
if (seq.isEmpty()) {
return null;
}
else {
return seq.getLastInstr();
}
}
public int size() {
return seq.length();
}
public void addPredecessor(BasicBlock block) {
preds.add(block);
}
public void removePredecessor(BasicBlock block) {
while (preds.remove(block)) ;
}
public void addSuccessor(BasicBlock block) {
succs.add(block);
block.addPredecessor(this);
}
public void removeSuccessor(BasicBlock block) {
while (succs.remove(block)) ;
block.removePredecessor(this);
}
// FIXME: unify block comparisons: id or direkt equality
public void replaceSuccessor(BasicBlock oldBlock, BasicBlock newBlock) {
for (int i = 0; i < succs.size(); i++) {
if (succs.get(i).id == oldBlock.id) {
succs.set(i, newBlock);
oldBlock.removePredecessor(this);
newBlock.addPredecessor(this);
}
}
for (int i = 0; i < succExceptions.size(); i++) {
if (succExceptions.get(i).id == oldBlock.id) {
succExceptions.set(i, newBlock);
oldBlock.removePredecessorException(this);
newBlock.addPredecessorException(this);
}
}
}
public void addPredecessorException(BasicBlock block) {
predExceptions.add(block);
}
public void removePredecessorException(BasicBlock block) {
while (predExceptions.remove(block)) ;
}
public void addSuccessorException(BasicBlock block) {
if (!succExceptions.contains(block)) {
succExceptions.add(block);
block.addPredecessorException(this);
}
}
public void removeSuccessorException(BasicBlock block) {
while (succExceptions.remove(block)) ;
block.removePredecessorException(this);
}
public String toString() {
return toString(0);
}
public String toString(int indent) {
String new_line_separator = DecompilerContext.getNewLineSeparator();
return id + ":" + new_line_separator + seq.toString(indent);
}
public String toStringOldIndices() {
String new_line_separator = DecompilerContext.getNewLineSeparator();
StringBuilder buf = new StringBuilder();
for (int i = 0; i < seq.length(); i++) {
if (i < instrOldOffsets.size()) {
buf.append(instrOldOffsets.get(i));
}
else {
buf.append("-1");
}
buf.append(": ");
buf.append(seq.getInstr(i).toString());
buf.append(new_line_separator);
}
return buf.toString();
}
public boolean isSuccessor(BasicBlock block) {
for (BasicBlock succ : succs) {
if (succ.id == block.id) {
return true;
}
}
return false;
}
public boolean isPredecessor(BasicBlock block) {
for (int i = 0; i < preds.size(); i++) {
if (preds.get(i).id == block.id) {
return true;
}
}
return false;
}
// *****************************************************************************
// getter and setter methods
// *****************************************************************************
public List<Integer> getInstrOldOffsets() {
return instrOldOffsets;
}
public void setInstrOldOffsets(List<Integer> instrInds) {
this.instrOldOffsets = instrInds;
}
public List<? extends IGraphNode> getPredecessors() {
List<BasicBlock> lst = new ArrayList<BasicBlock>(preds);
lst.addAll(predExceptions);
return lst;
}
public List<BasicBlock> getPreds() {
return preds;
}
public void setPreds(List<BasicBlock> preds) {
this.preds = preds;
}
public InstructionSequence getSeq() {
return seq;
}
public void setSeq(InstructionSequence seq) {
this.seq = seq;
}
public List<BasicBlock> getSuccs() {
return succs;
}
public void setSuccs(List<BasicBlock> succs) {
this.succs = succs;
}
public List<BasicBlock> getSuccExceptions() {
return succExceptions;
}
public void setSuccExceptions(List<BasicBlock> succExceptions) {
this.succExceptions = succExceptions;
}
public List<BasicBlock> getPredExceptions() {
return predExceptions;
}
public void setPredExceptions(List<BasicBlock> predExceptions) {
this.predExceptions = predExceptions;
}
11 years ago
}