summaryrefslogtreecommitdiffstats
path: root/src/org/jetbrains/java/decompiler/struct/StructMethod.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/jetbrains/java/decompiler/struct/StructMethod.java')
-rw-r--r--src/org/jetbrains/java/decompiler/struct/StructMethod.java317
1 files changed, 71 insertions, 246 deletions
diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java
index e3de510..b055df6 100644
--- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java
+++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java
@@ -17,267 +17,106 @@ package org.jetbrains.java.decompiler.struct;
import org.jetbrains.java.decompiler.code.*;
import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute;
-import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute;
import org.jetbrains.java.decompiler.struct.consts.ConstantPool;
+import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
import org.jetbrains.java.decompiler.util.DataInputFullStream;
import org.jetbrains.java.decompiler.util.VBStyleCollection;
import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import static org.jetbrains.java.decompiler.code.CodeConstants.*;
+
/*
- method_info {
- u2 access_flags;
- u2 name_index;
- u2 descriptor_index;
- u2 attributes_count;
- attribute_info attributes[attributes_count];
- }
+ method_info {
+ u2 access_flags;
+ u2 name_index;
+ u2 descriptor_index;
+ u2 attributes_count;
+ attribute_info attributes[attributes_count];
+ }
*/
+public class StructMethod extends StructMember {
-public class StructMethod implements CodeConstants {
-
- // *****************************************************************************
- // public fields
- // *****************************************************************************
-
- public int name_index;
-
- public int descriptor_index;
-
- // *****************************************************************************
- // private fields
- // *****************************************************************************
-
- private static final int[] opr_iconst = new int[]{-1, 0, 1, 2, 3, 4, 5};
-
- private static final int[] opr_loadstore = new int[]{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3};
-
- private static final int[] opcs_load = new int[]{opc_iload, opc_lload, opc_fload, opc_dload, opc_aload};
-
- private static final int[] opcs_store = new int[]{opc_istore, opc_lstore, opc_fstore, opc_dstore, opc_astore};
-
-
- private int accessFlags;
+ private static final int[] opr_iconst = {-1, 0, 1, 2, 3, 4, 5};
+ private static final int[] opr_loadstore = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3};
+ private static final int[] opcs_load = {opc_iload, opc_lload, opc_fload, opc_dload, opc_aload};
+ private static final int[] opcs_store = {opc_istore, opc_lstore, opc_fstore, opc_dstore, opc_astore};
- private VBStyleCollection<StructGeneralAttribute, String> attributes;
-
- private int localVariables;
-
- private int maxStack;
-
- private String name;
-
- private String descriptor;
-
- private InstructionSequence seq;
+ private final StructClass classStruct;
+ private final String name;
+ private final String descriptor;
private boolean containsCode = false;
+ private int localVariables = 0;
+ private int codeLength = 0;
+ private int codeFullLength = 0;
+ private InstructionSequence seq;
+ private boolean expanded = false;
- private StructClass classStruct;
-
-
- // lazy properties
- private boolean lazy;
-
- private boolean expanded;
-
- private byte[] code_content;
-
- private int code_length = 0;
-
- private int code_fulllength = 0;
-
- // *****************************************************************************
- // constructors
- // *****************************************************************************
-
- public StructMethod(DataInputFullStream in, boolean own, StructClass clstruct) throws IOException {
- this(in, true, own, clstruct);
- }
-
- public StructMethod(DataInputFullStream in, boolean lazy, boolean own, StructClass clstruct) throws IOException {
- this.lazy = lazy;
- this.expanded = !lazy;
- this.classStruct = clstruct;
+ public StructMethod(DataInputFullStream in, StructClass clStruct) throws IOException {
+ classStruct = clStruct;
accessFlags = in.readUnsignedShort();
- name_index = in.readUnsignedShort();
- descriptor_index = in.readUnsignedShort();
-
- ConstantPool pool = clstruct.getPool();
-
- initStrings(pool, clstruct.this_class);
-
- VBStyleCollection<StructGeneralAttribute, String> lstAttribute = new VBStyleCollection<StructGeneralAttribute, String>();
- int len = in.readUnsignedShort();
- for (int i = 0; i < len; i++) {
-
- int attr_nameindex = in.readUnsignedShort();
- String attrname = pool.getPrimitiveConstant(attr_nameindex).getString();
-
- if (StructGeneralAttribute.ATTRIBUTE_CODE.equals(attrname)) {
- if (!own) {
- // skip code in foreign classes
- in.skip(8);
- in.skip(in.readInt());
- in.skip(8 * in.readUnsignedShort());
- }
- else {
- containsCode = true;
-
- in.skip(4);
-
- maxStack = in.readUnsignedShort();
- localVariables = in.readUnsignedShort();
-
- if (lazy) {
- code_length = in.readInt();
+ int nameIndex = in.readUnsignedShort();
+ int descriptorIndex = in.readUnsignedShort();
- in.skip(code_length);
-
- int exc_length = in.readUnsignedShort();
- code_fulllength = code_length + exc_length * 8 + 2;
-
- in.skip(exc_length * 8);
- }
- else {
- seq = parseBytecode(in, in.readInt(), pool);
- }
- }
-
- // code attributes
- int length = in.readUnsignedShort();
- for (int j = 0; j < length; j++) {
- int codeattr_nameindex = in.readUnsignedShort();
- String codeattrname = pool.getPrimitiveConstant(codeattr_nameindex).getString();
-
- readAttribute(in, pool, lstAttribute, codeattr_nameindex, codeattrname);
- }
- }
- else {
- readAttribute(in, pool, lstAttribute, attr_nameindex, attrname);
- }
- }
+ ConstantPool pool = clStruct.getPool();
+ String[] values = pool.getClassElement(ConstantPool.METHOD, clStruct.qualifiedName, nameIndex, descriptorIndex);
+ name = values[0];
+ descriptor = values[1];
- attributes = lstAttribute;
+ attributes = readAttributes(in, pool);
}
-
- // *****************************************************************************
- // public methods
- // *****************************************************************************
-
- public void writeToStream(DataOutputStream out) throws IOException {
-
- out.writeShort(accessFlags);
- out.writeShort(name_index);
- out.writeShort(descriptor_index);
-
- out.writeShort(attributes.size());
-
- for (StructGeneralAttribute attr : attributes) {
- if (StructGeneralAttribute.ATTRIBUTE_CODE.equals(attr.getName())) {
- out.writeShort(attr.getAttribute_name_index());
-
- if (lazy && !expanded) {
- out.writeInt(10 + code_content.length);
- out.writeShort(maxStack);
- out.writeShort(localVariables);
- out.writeInt(code_length);
- out.write(code_content);
- }
- else {
- ByteArrayOutputStream codeout = new ByteArrayOutputStream();
- seq.writeCodeToStream(new DataOutputStream(codeout));
-
- ByteArrayOutputStream excout = new ByteArrayOutputStream();
- seq.writeExceptionsToStream(new DataOutputStream(excout));
-
- out.writeInt(10 + codeout.size() + excout.size());
-
- out.writeShort(maxStack);
- out.writeShort(localVariables);
- out.writeInt(codeout.size());
- codeout.writeTo(out);
- excout.writeTo(out);
- }
- // no attributes
- out.writeShort(0);
+ @Override
+ protected StructGeneralAttribute readAttribute(DataInputFullStream in, ConstantPool pool, String name) throws IOException {
+ if (StructGeneralAttribute.ATTRIBUTE_CODE.equals(name)) {
+ if (!classStruct.isOwn()) {
+ // skip code in foreign classes
+ in.discard(8);
+ in.discard(in.readInt());
+ in.discard(8 * in.readUnsignedShort());
}
else {
- attr.writeToStream(out);
+ containsCode = true;
+ in.discard(6);
+ localVariables = in.readUnsignedShort();
+ codeLength = in.readInt();
+ in.discard(codeLength);
+ int exc_length = in.readUnsignedShort();
+ in.discard(exc_length * 8);
+ codeFullLength = codeLength + exc_length * 8 + 2;
}
- }
- }
-
- private static void readAttribute(DataInputFullStream in,
- ConstantPool pool,
- VBStyleCollection<StructGeneralAttribute, String> lstAttribute,
- int attr_nameindex,
- String attrname) throws IOException {
- StructGeneralAttribute attribute = StructGeneralAttribute.getMatchingAttributeInstance(attr_nameindex, attrname);
+ LazyLoader.skipAttributes(in);
- if (attribute != null) {
- attrname = attribute.getName();
-
- byte[] arr = new byte[in.readInt()];
- in.readFull(arr);
- attribute.setInfo(arr);
-
- attribute.initContent(pool);
-
- if (StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(attrname) &&
- lstAttribute.containsKey(attrname)) {
- // merge all variable tables
- StructLocalVariableTableAttribute oldattr = (StructLocalVariableTableAttribute)lstAttribute.getWithKey(attrname);
- oldattr.addLocalVariableTable((StructLocalVariableTableAttribute)attribute);
- }
- else {
- lstAttribute.addWithKey(attribute, attribute.getName());
- }
- }
- else {
- in.skip(in.readInt());
+ return null;
}
- }
- private void initStrings(ConstantPool pool, int class_index) {
- String[] values = pool.getClassElement(ConstantPool.METHOD, class_index, name_index, descriptor_index);
- name = values[0];
- descriptor = values[1];
+ return super.readAttribute(in, pool, name);
}
public void expandData() throws IOException {
- if (containsCode && lazy && !expanded) {
-
- byte[] codearr = classStruct.getLoader().loadBytecode(this, code_fulllength);
-
- seq = parseBytecode(new DataInputFullStream(new ByteArrayInputStream(codearr)), code_length, classStruct.getPool());
+ if (containsCode && !expanded) {
+ byte[] code = classStruct.getLoader().loadBytecode(this, codeFullLength);
+ seq = parseBytecode(new DataInputFullStream(new ByteArrayInputStream(code)), codeLength, classStruct.getPool());
expanded = true;
}
}
public void releaseResources() throws IOException {
- if (containsCode && lazy && expanded) {
+ if (containsCode && expanded) {
seq = null;
expanded = false;
}
}
- // *****************************************************************************
- // private methods
- // *****************************************************************************
-
private InstructionSequence parseBytecode(DataInputFullStream in, int length, ConstantPool pool) throws IOException {
-
- VBStyleCollection<Instruction, Integer> collinstr = new VBStyleCollection<Instruction, Integer>();
+ VBStyleCollection<Instruction, Integer> instructions = new VBStyleCollection<Instruction, Integer>();
int bytecode_version = classStruct.getBytecodeVersion();
@@ -370,7 +209,7 @@ public class StructMethod implements CodeConstants {
case opc_invokedynamic:
if (classStruct.isVersionGE_1_7()) { // instruction unused in Java 6 and before
operands.add(new Integer(in.readUnsignedShort()));
- in.skip(2);
+ in.discard(2);
group = GROUP_INVOCATION;
i += 4;
}
@@ -420,7 +259,7 @@ public class StructMethod implements CodeConstants {
case opc_invokeinterface:
operands.add(new Integer(in.readUnsignedShort()));
operands.add(new Integer(in.readUnsignedByte()));
- in.skip(1);
+ in.discard(1);
group = GROUP_INVOCATION;
i += 4;
break;
@@ -430,7 +269,7 @@ public class StructMethod implements CodeConstants {
i += 3;
break;
case opc_tableswitch:
- in.skip((4 - (i + 1) % 4) % 4);
+ in.discard((4 - (i + 1) % 4) % 4);
i += ((4 - (i + 1) % 4) % 4); // padding
operands.add(new Integer(in.readInt()));
i += 4;
@@ -449,7 +288,7 @@ public class StructMethod implements CodeConstants {
break;
case opc_lookupswitch:
- in.skip((4 - (i + 1) % 4) % 4);
+ in.discard((4 - (i + 1) % 4) % 4);
i += ((4 - (i + 1) % 4) % 4); // padding
operands.add(new Integer(in.readInt()));
i += 4;
@@ -483,7 +322,7 @@ public class StructMethod implements CodeConstants {
Instruction instr = ConstantsUtil.getInstructionInstance(opcode, wide, group, bytecode_version, ops);
- collinstr.addWithKey(instr, new Integer(offset));
+ instructions.addWithKey(instr, new Integer(offset));
i++;
}
@@ -507,7 +346,7 @@ public class StructMethod implements CodeConstants {
lstHandlers.add(handler);
}
- InstructionSequence seq = new FullInstructionSequence(collinstr, new ExceptionTable(lstHandlers));
+ InstructionSequence seq = new FullInstructionSequence(instructions, new ExceptionTable(lstHandlers));
// initialize instructions
int i = seq.length() - 1;
@@ -524,41 +363,27 @@ public class StructMethod implements CodeConstants {
return seq;
}
- // *****************************************************************************
- // getter and setter methods
- // *****************************************************************************
+ public StructClass getClassStruct() {
+ return classStruct;
+ }
- public InstructionSequence getInstructionSequence() {
- return seq;
+ public String getName() {
+ return name;
}
public String getDescriptor() {
return descriptor;
}
- public String getName() {
- return name;
- }
-
- public int getAccessFlags() {
- return accessFlags;
+ public boolean containsCode() {
+ return containsCode;
}
public int getLocalVariables() {
return localVariables;
}
- public VBStyleCollection<StructGeneralAttribute, String> getAttributes() {
- return attributes;
- }
-
- public StructClass getClassStruct() {
- return classStruct;
- }
-
- public boolean containsCode() {
- return containsCode;
+ public InstructionSequence getInstructionSequence() {
+ return seq;
}
}
-
-