package com.coderising.jvm.loader;
import java.io.UnsupportedEncodingException;
import com.coderising.jvm.clz.AccessFlag;
import com.coderising.jvm.clz.ClassFile;
import com.coderising.jvm.clz.ClassIndex;
import com.coderising.jvm.constant.ClassInfo;
import com.coderising.jvm.constant.ConstantPool;
import com.coderising.jvm.constant.FieldRefInfo;
import com.coderising.jvm.constant.MethodRefInfo;
import com.coderising.jvm.constant.NameAndTypeInfo;
import com.coderising.jvm.constant.NullConstantInfo;
import com.coderising.jvm.constant.StringInfo;
import com.coderising.jvm.constant.UTF8Info;
public class ClassFileParser {
public ClassFile parse(byte[] codes) {
ClassFile classFile = new ClassFile();
ByteCodeIterator iter = new ByteCodeIterator(codes);
String magicNumber = iter.nextU4ToString();
System.out.println("magicNumber:"+magicNumber);
int minorVersion = iter.nextU2ToInt();
int majorVersion = iter.nextU2ToInt();
classFile.setMinorVersion(minorVersion);
classFile.setMajorVersion(majorVersion);
ConstantPool constantPool = this.parseConstantPool(iter);
classFile.setConstPool(constantPool);
AccessFlag accessFlag = this.parseAccessFlag(iter);
classFile.setAccessFlag(accessFlag);
ClassIndex classIndex = this.parseClassIndex(iter);
classFile.setClassIndex(classIndex);
return classFile;
}
private AccessFlag parseAccessFlag(ByteCodeIterator iter){
AccessFlag accessFlag = new AccessFlag(iter.nextU2ToInt());
return accessFlag;
}
private ClassIndex parseClassIndex(ByteCodeIterator iter){
int thisClassIndex = iter.nextU2ToInt();
int superClassIndex = iter.nextU2ToInt();
ClassIndex classIndex = new ClassIndex();
classIndex.setThisClassIndex(thisClassIndex);
classIndex.setSuperClassIndex(superClassIndex);
return classIndex;
}
private ConstantPool parseConstantPool(ByteCodeIterator iter){
ConstantPool constantPool = new ConstantPool();
constantPool.addConstantInfo(new NullConstantInfo());
int constantNumber = iter.nextU2ToInt();//常量池项的个数
for(int i = 1;i <= constantNumber - 1;i++){
int type = iter.nextU1ToInt();
if(type == 1){
//UTF8Info
int length = iter.nextU2ToInt();
byte[] bytes = iter.getBytes(length);
String value = "";
try {
value = new String(bytes,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
UTF8Info utf8Info = new UTF8Info(constantPool);
utf8Info.setLength(length);
utf8Info.setValue(value);
constantPool.addConstantInfo(utf8Info);
}else if(type == 7){
//ClassInfo
int utf8Index = iter.nextU2ToInt();
ClassInfo classInfo = new ClassInfo(constantPool);
classInfo.setUtf8Index(utf8Index);
constantPool.addConstantInfo(classInfo);
}else if(type == 8){
//StringInfo
int index = iter.nextU2ToInt();
StringInfo stringInfo = new StringInfo(constantPool);
stringInfo.setIndex(index);
constantPool.addConstantInfo(stringInfo);
}else if(type == 9){
//FieldRefInfo
int classInfoIndex = iter.nextU2ToInt();
int nameAndTypeIndex = iter.nextU2ToInt();
FieldRefInfo fieldRefInfo = new FieldRefInfo(constantPool);
fieldRefInfo.setClassInfoIndex(classInfoIndex);
fieldRefInfo.setNameAndTypeIndex(nameAndTypeIndex);
constantPool.addConstantInfo(fieldRefInfo);
}else if(type == 10){
//MethodRefInfo
int classInfoIndex = iter.nextU2ToInt();
int nameAndTypeIndex = iter.nextU2ToInt();
MethodRefInfo methodRefInfo = new MethodRefInfo(constantPool);
methodRefInfo.setClassInfoIndex(classInfoIndex);
methodRefInfo.setNameAndTypeIndex(nameAndTypeIndex);
constantPool.addConstantInfo(methodRefInfo);
}else if(type == 12){
//NameAndTypeInfo
int nameIndex = iter.nextU2ToInt();
int descriptorIndex = iter.nextU2ToInt();
NameAndTypeInfo nameAndTypeInfo = new NameAndTypeInfo(constantPool);
nameAndTypeInfo.setIndex1(nameIndex);
nameAndTypeInfo.setIndex2(descriptorIndex);
constantPool.addConstantInfo(nameAndTypeInfo);
}else{
//
throw new RuntimeException("该常量项还未实现!!!");
}
}
return constantPool;
}
}