package com.github.wdn.coding2017.jvm.attr;
import com.github.wdn.coding2017.jvm.clz.ClassFile;
import com.github.wdn.coding2017.jvm.cmd.ByteCodeCommand;
import com.github.wdn.coding2017.jvm.cmd.CommandParser;
import com.github.wdn.coding2017.jvm.constant.ConstantPool;
import com.github.wdn.coding2017.jvm.loader.ByteCodeIterator;
import com.github.wdn.coding2017.jvm.util.Util;
/**
* Created by Administrator on 2017/4/12 0012.
*/
public class CodeAttr extends AttributeInfo {
private int maxStack;
private int maxLocals;
private String code;
private LineNumberTable lineNumTable;
private LocalVariableTable localVarTable;
private StackMapTable stackMapTable;
private ByteCodeCommand[] cmds;
public CodeAttr(int attributeNameIndex, int attributeLength, int maxStack, int maxLocals, String code,ByteCodeCommand[] commands) {
super(attributeNameIndex, attributeLength);
this.maxStack = maxStack;
this.maxLocals = maxLocals;
this.code = code;
this.cmds = commands;
}
public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){
int attributeNameIndex = iter.readU2ToInt();
int attributeLength = iter.readU4ToInt();
int maxStack = iter.readU2ToInt();
int maxLocals = iter.readU2ToInt();
String codeStr = iter.readCustomToString(iter.readU4ToInt());
ByteCodeCommand[] cmds = CommandParser.parse(clzFile,codeStr);
CodeAttr codeAttr = new CodeAttr(attributeNameIndex,attributeLength, maxStack, maxLocals, codeStr, cmds);
int ExceptionCount = iter.readU2ToInt();
if (ExceptionCount > 0) {
throw new RuntimeException("方法有异常待解析");
}
int codeAttributesCount = iter.readU2ToInt();
for (int k = 0; k < codeAttributesCount; k++) {
int codeAttributeNameIndex = iter.readU2ToInt();
String codeAttributeType = clzFile.getConstantPool().getConstantInfo(codeAttributeNameIndex).getValue();
codeAttributeType = Util.hexString2String(codeAttributeType);
if ("LineNumberTable".equals(codeAttributeType)) {
LineNumberTable lineNumberTable = LineNumberTable.parse(iter);
codeAttr.setLineNumTable(lineNumberTable);
} else if ("LocalVariableTable".equals(codeAttributeType)) {
LocalVariableTable localVariableTable = LocalVariableTable.parse(iter);
codeAttr.setLocalVarTable(localVariableTable);
}else if ("StackMapTable".equals(codeAttributeType)) {
StackMapTable stackMapTable = StackMapTable.parse(iter);
codeAttr.setStackMapTable(stackMapTable);
} else {
throw new RuntimeException("未知的Code附加属性类型" + codeAttributeType);
}
}
return codeAttr;
}
@Override
public String toString(){
return code;
}
public int getMaxStack() {
return maxStack;
}
public void setMaxStack(int maxStack) {
this.maxStack = maxStack;
}
public int getMaxLocals() {
return maxLocals;
}
public void setMaxLocals(int maxLocals) {
this.maxLocals = maxLocals;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public void setLineNumTable(LineNumberTable lineNumTable) {
this.lineNumTable = lineNumTable;
}
public void setLocalVarTable(LocalVariableTable localVarTable) {
this.localVarTable = localVarTable;
}
public void setStackMapTable(StackMapTable stackMapTable) {
this.stackMapTable = stackMapTable;
}
public ByteCodeCommand[] getCmds() {
return cmds;
}
}