diff options
Diffstat (limited to 'plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/code/InstructionSequence.java')
-rw-r--r-- | plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/code/InstructionSequence.java | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/code/InstructionSequence.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/code/InstructionSequence.java new file mode 100644 index 000000000000..709a85da3952 --- /dev/null +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/code/InstructionSequence.java @@ -0,0 +1,227 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ +package org.jetbrains.java.decompiler.code; + +import org.jetbrains.java.decompiler.code.interpreter.Util; +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.struct.StructContext; +import org.jetbrains.java.decompiler.util.InterpreterUtil; +import org.jetbrains.java.decompiler.util.VBStyleCollection; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + + +public abstract class InstructionSequence { + + // ***************************************************************************** + // private fields + // ***************************************************************************** + + protected VBStyleCollection<Instruction, Integer> collinstr = new VBStyleCollection<Instruction, Integer>(); + + protected int pointer = 0; + + protected ExceptionTable exceptionTable = new ExceptionTable(); + + // ***************************************************************************** + // public methods + // ***************************************************************************** + + // to nbe overwritten + public InstructionSequence clone() { + return null; + } + + public void clear() { + collinstr.clear(); + pointer = 0; + exceptionTable = new ExceptionTable(); + } + + public void addInstruction(Instruction inst, int offset) { + collinstr.addWithKey(inst, offset); + } + + public void addInstruction(int index, Instruction inst, int offset) { + collinstr.addWithKeyAndIndex(index, inst, offset); + } + + public void addSequence(InstructionSequence seq) { + for (int i = 0; i < seq.length(); i++) { + addInstruction(seq.getInstr(i), -1); // TODO: any sensible value possible? + } + } + + public void removeInstruction(int index) { + collinstr.remove(index); + } + + public Instruction getCurrentInstr() { + return collinstr.get(pointer); + } + + public Instruction getInstr(int index) { + return collinstr.get(index); + } + + public Instruction getLastInstr() { + return collinstr.getLast(); + } + + public int getCurrentOffset() { + return collinstr.getKey(pointer).intValue(); + } + +public int getOffset(int index) { + return collinstr.getKey(index).intValue(); + } + + public int getPointerByAbsOffset(int offset) { + Integer absoffset = new Integer(offset); + if (collinstr.containsKey(absoffset)) { + return collinstr.getIndexByKey(absoffset); + } + else { + return -1; + } + } + + public int getPointerByRelOffset(int offset) { + Integer absoffset = new Integer(collinstr.getKey(pointer).intValue() + offset); + if (collinstr.containsKey(absoffset)) { + return collinstr.getIndexByKey(absoffset); + } + else { + return -1; + } + } + + public void setPointerByAbsOffset(int offset) { + Integer absoffset = new Integer(collinstr.getKey(pointer).intValue() + offset); + if (collinstr.containsKey(absoffset)) { + pointer = collinstr.getIndexByKey(absoffset); + } + } + + public int length() { + return collinstr.size(); + } + + public boolean isEmpty() { + return collinstr.isEmpty(); + } + + public void addToPointer(int diff) { + this.pointer += diff; + } + + public String toString() { + return toString(0); + } + + public String toString(int indent) { + + String new_line_separator = DecompilerContext.getNewLineSeparator(); + + StringBuilder buf = new StringBuilder(); + + for (int i = 0; i < collinstr.size(); i++) { + buf.append(InterpreterUtil.getIndentString(indent)); + buf.append(collinstr.getKey(i).intValue()); + buf.append(": "); + buf.append(collinstr.get(i).toString()); + buf.append(new_line_separator); + } + + return buf.toString(); + } + + public void writeCodeToStream(DataOutputStream out) throws IOException { + + for (int i = 0; i < collinstr.size(); i++) { + collinstr.get(i).writeToStream(out, collinstr.getKey(i).intValue()); + } + } + + public void writeExceptionsToStream(DataOutputStream out) throws IOException { + + List<ExceptionHandler> handlers = exceptionTable.getHandlers(); + + out.writeShort(handlers.size()); + for (int i = 0; i < handlers.size(); i++) { + handlers.get(i).writeToStream(out); + } + } + + public void sortHandlers(final StructContext context) { + + Collections.sort(exceptionTable.getHandlers(), new Comparator<ExceptionHandler>() { + + public int compare(ExceptionHandler handler0, ExceptionHandler handler1) { + + if (handler0.to == handler1.to) { + if (handler0.exceptionClass == null) { + return 1; + } + else { + if (handler1.exceptionClass == null) { + return -1; + } + else if (handler0.exceptionClass.equals(handler1.exceptionClass)) { + return (handler0.from > handler1.from) ? -1 : 1; // invalid code + } + else { + if (Util.instanceOf(context, handler0.exceptionClass, handler1.exceptionClass)) { + return -1; + } + else { + return 1; + } + } + } + } + else { + return (handler0.to > handler1.to) ? 1 : -1; + } + } + }); + } + + + // ***************************************************************************** + // getter and setter methods + // ***************************************************************************** + + public int getPointer() { + return pointer; + } + + public void setPointer(int pointer) { + this.pointer = pointer; + } + + public ExceptionTable getExceptionTable() { + return exceptionTable; + } + + public void setExceptionTable(ExceptionTable exceptionTable) { + this.exceptionTable = exceptionTable; + } +} |