package com.coderising.jvm.attribute; import com.coderising.jvm.clasfile.ClassFile; import com.coderising.jvm.constant.Utf8Info; import com.coderising.jvm.loader.ByteCodeIterator; public class CodeAttr extends AttributeInfo{ private int attrLen; private int maxStack; private int maxLocals; private int codeLen; private String code; private LineNumberTable lineNumTable; private LocalVariableTable localVarTable; private StackMapTable stackMapTable; public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code) { super(attrNameIndex, attrLen); this.maxLocals = maxLocals; this.maxStack = maxStack; this.code = code; this.codeLen = codeLen; } public String getCodeString(){ return this.code; } public static CodeAttr parse(ClassFile classFile, ByteCodeIterator iterator) { iterator.back(2); int attrNameIndex = iterator.next2BytesToInt(); int attrLen = iterator.next4BytesToInt(); int maxstack = iterator.next2BytesToInt(); int maxlocals = iterator.next2BytesToInt(); int codelen = iterator.next4BytesToInt(); String code = iterator.nextXBytesToString(codelen); CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxstack, maxlocals, codelen, code); int exceptionCount = iterator.next2BytesToInt(); if (exceptionCount > 0) { throw new RuntimeException("Exception is null." + exceptionCount); } int childCount = iterator.next2BytesToInt(); if (childCount > 0) { for (int i = 0; i < childCount; i++) { int childIndex = iterator.next2BytesToInt(); String attrName = classFile.getPool().getUtf8String(childIndex); if (AttributeInfo.LINE_NUM_TABLE.equals(attrName)) { LineNumberTable lineNumber = LineNumberTable.parse(iterator); codeAttr.setLineNumTable(lineNumber); } else if(AttributeInfo.LOCAL_VAR_TABLE.equals(attrName)){ LocalVariableTable localVarTable = LocalVariableTable.parse(classFile,iterator); codeAttr.setLocalVarTable(localVarTable); } else if(AttributeInfo.STACK_MAP_TABLE.equals(attrName)){ StackMapTable stackMapTable = StackMapTable.parse(classFile,iterator); codeAttr.setStackMapTable(stackMapTable); } else { throw new RuntimeException("This " + attrName +"is not added."); } } } return codeAttr; } public void setLineNumTable(LineNumberTable lineNumTable) { this.lineNumTable = lineNumTable; } public void setLocalVarTable(LocalVariableTable localVarTable) { this.localVarTable = localVarTable; } public void setStackMapTable(StackMapTable stackMapTable) { this.stackMapTable = stackMapTable; } }