📄 attributeinfo.java
字号:
/* JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine Release Version 2.0 A project from the Physics Dept, The University of Oxford Copyright (C) 2007 Isis Innovation Limited This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Details (including contact information) can be found at: www.physics.ox.ac.uk/jpc*/package org.jpc.classfile;
import java.io.*;
import java.util.*;
public abstract class AttributeInfo
{
public abstract void write(DataOutputStream out) throws IOException;
public static AttributeInfo construct(DataInputStream in, ConstantPoolInfo[] pool) throws IOException
{
int index = in.readUnsignedShort();
int tag = pool[index].getTag();
AttributeInfo temp;
if (tag == ConstantPoolInfo.UTF8)
{
String s = ((ConstantPoolInfo.Utf8Info) pool[index]).getBytes();
if (s.equals("SourceFile"))
return new SourceFileAttribute(in, index);
else if (s.equals("ConstantValue"))
return new ConstantValueAttribute(in, index);
else if (s.equals("Code"))
return new CodeAttribute(in, index, pool);
else if (s.equals("StackMapTable"))
return new StackMapTableAttribute(in, index);
else if (s.equals("Exceptions"))
return new ExceptionsAttribute(in, index);
else if (s.equals("InnerClasses"))
return new InnerClassesAttribute(in, index);
else if (s.equals("EnclosingMethod"))
return new EnclosingMethodAttribute(in, index);
else if (s.equals("Synthetic"))
return new SyntheticAttribute(in, index);
else if (s.equals("Signature"))
return new SignatureAttribute(in, index);
else if (s.equals("LineNumberTable"))
return new LineNumberTableAttribute(in, index);
else if (s.equals("LocalVariableTable"))
return new LocalVariableTableAttribute(in, index);
else if (s.equals("Deprecated"))
return new DeprecatedAttribute(in, index);
else
return new UnknownAttribute(in, index);
}
return null;
}
abstract static class Attribute extends AttributeInfo
{
protected int attributeNameIndex;
protected int attributeLength;
Attribute(DataInputStream in, int index) throws IOException
{
attributeNameIndex = index;
attributeLength = in.readInt();
}
public void write(DataOutputStream out) throws IOException
{
out.writeShort(attributeNameIndex);
out.writeInt(attributeLength);
}
}
public static class ConstantValueAttribute extends Attribute
{
private int constantValueIndex;
ConstantValueAttribute(DataInputStream in, int index) throws IOException
{
super(in, index);
constantValueIndex = in.readUnsignedShort();
}
public void write(DataOutputStream out) throws IOException
{
super.write(out);
out.writeShort(constantValueIndex);
}
}
public static class CodeAttribute extends Attribute
{
private int maxStack;
private int maxLocals;
private int codeLength;
private int[] code;
private int exceptionTableLength;
private ExceptionEntry[] exceptionTable;
private int attributesCount;
private AttributeInfo[] attributes;
CodeAttribute(DataInputStream in, int index, ConstantPoolInfo[] pool) throws IOException
{
super(in, index);
maxStack = in.readUnsignedShort();
maxLocals = in.readUnsignedShort();
codeLength = in.readInt();
code = new int[codeLength];
for(int i = 0; i < codeLength; i++)
code[i] = in.readUnsignedByte();
exceptionTableLength = in.readUnsignedShort();
exceptionTable = new ExceptionEntry[exceptionTableLength];
for(int i = 0; i < exceptionTableLength; i++)
exceptionTable[i] = new ExceptionEntry(in);
attributesCount = in.readUnsignedShort();
attributes = new AttributeInfo[attributesCount];
for(int i = 0; i < attributesCount; i++)
attributes[i] = AttributeInfo.construct(in, pool);
}
public int getMaxStack() { return maxStack; }
public int getMaxLocals() { return maxLocals; }
public int[] getCode()
{
int[] a = new int[code.length];
System.arraycopy(code, 0, a, 0, a.length);
return a;
// return Arrays.copyOf(code, code.length);
}
public void setCode(int[] newCode, ClassFile cf, int argLength)
{
setCode(newCode, newCode.length, cf, argLength);
}
public void setCode(int[] newCode, int newCodeLength, ClassFile cf, int argLength)
{
code = new int[newCodeLength];
System.arraycopy(newCode, 0, code, 0, code.length);
// code = Arrays.copyOf(newCode, newCodeLength);
attributeLength += newCodeLength - codeLength;
codeLength = newCodeLength;
maxStack = JavaCodeAnalyser.getMaxStackDepth(code, 0, cf);
maxLocals = Math.max(JavaCodeAnalyser.getMaxLocalVariables(code), argLength + 1); //+1 accounts for 'this' the hidden argument
}
public ExceptionEntry[] getExceptionTable()
{
ExceptionEntry[] a = new ExceptionEntry[exceptionTable.length];
System.arraycopy(exceptionTable, 0, a, 0, a.length);
return a;
// return (ExceptionEntry[]) Arrays.copyOf(exceptionTable, exceptionTable.length);
}
public void setExceptionTable(ExceptionEntry[] newTable, ClassFile cf)
{
setExceptionTable(newTable, newTable.length, cf);
}
public void setExceptionTable(ExceptionEntry[] newTable, int newTableLength, ClassFile cf)
{
for (int i = 0; i < newTableLength; i++) {
ExceptionEntry handler = newTable[i];
if (handler.handlerPC < code.length)
maxStack = Math.max(maxStack, JavaCodeAnalyser.getMaxStackDepth(code, handler.handlerPC, cf) + 1);
}
exceptionTable = new ExceptionEntry[newTableLength];
System.arraycopy(newTable, 0, exceptionTable, 0, exceptionTable.length);
// exceptionTable = (ExceptionEntry[]) Arrays.copyOf(newTable, newTableLength);
attributeLength += 8 * (newTableLength - exceptionTableLength);
exceptionTableLength = newTableLength;
}
public void write(DataOutputStream out) throws IOException
{
super.write(out);
out.writeShort(maxStack);
out.writeShort(maxLocals);
out.writeInt(codeLength);
for(int i = 0; i < codeLength; i++)
out.writeByte(code[i]);
out.writeShort(exceptionTableLength);
for(int i = 0; i < exceptionTableLength; i++)
exceptionTable[i].write(out);
out.writeShort(attributesCount);
for(int i = 0; i < attributesCount; i++)
attributes[i].write(out);
}
public static class ExceptionEntry
{
private final int startPC;
private final int endPC;
private final int handlerPC;
private final int catchType;
public ExceptionEntry(int start, int end, int handler, int type)
{
startPC = start;
endPC = end;
handlerPC = handler;
catchType = type;
}
ExceptionEntry(DataInputStream in) throws IOException
{
startPC = in.readUnsignedShort();
endPC = in.readUnsignedShort();
handlerPC = in.readUnsignedShort();
catchType = in.readUnsignedShort();
}
void write(DataOutputStream out) throws IOException
{
out.writeShort(startPC);
out.writeShort(endPC);
out.writeShort(handlerPC);
out.writeShort(catchType);
}
}
}
public static class StackMapTableAttribute extends Attribute
{
private int numberOfEntries;
private StackMapFrame[] entries;
StackMapTableAttribute(DataInputStream in, int index) throws IOException
{
super(in, index);
numberOfEntries = in.readUnsignedShort();
entries = new StackMapFrame[numberOfEntries];
for(int i = 0; i < numberOfEntries; i++)
entries[i] = StackMapFrame.construct(in);
}
public void write(DataOutputStream out) throws IOException
{
super.write(out);
out.writeInt(numberOfEntries);
for(int i = 0; i < numberOfEntries; i++)
entries[i].write(out);
}
public abstract static class StackMapFrame
{
protected int frameType;
public static final int SAME_L = 0;
public static final int SAME_H = 63;
public static final int SAME_LOCALS_1_STACK_ITEM_L = 64;
public static final int SAME_LOCALS_1_STACK_ITEM_H = 127;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -