package org.wsc.coderising.jvm.loader;
import java.io.UnsupportedEncodingException;
import org.wsc.coderising.jvm.clz.AccessFlag;
import org.wsc.coderising.jvm.clz.ClassFile;
import org.wsc.coderising.jvm.clz.ClassIndex;
import org.wsc.coderising.jvm.constant.ClassInfo;
import org.wsc.coderising.jvm.constant.ConstantPool;
import org.wsc.coderising.jvm.constant.FieldRefInfo;
import org.wsc.coderising.jvm.constant.MethodRefInfo;
import org.wsc.coderising.jvm.constant.NameAndTypeInfo;
import org.wsc.coderising.jvm.constant.NullConstantInfo;
import org.wsc.coderising.jvm.constant.StringInfo;
import org.wsc.coderising.jvm.constant.UTF8Info;
public class ClassFileParser {
public ClassFile parse(byte[] codes) {
ClassFile classFile = new ClassFile();
ByteCodeIterator iter = new ByteCodeIterator(codes);
String magicNumber = iter.nextU4ToHexString();
if (!"cafebabe".equals(magicNumber))
return null;
classFile.setMinorVersion(iter.nextU2ToInt());// 次版本
classFile.setMajorVersion(iter.nextU2ToInt());// 主版本
//解析常量池
ConstantPool pool = parseConstantPool(iter);
classFile.setConstPool(pool);
//访问标识
classFile.setAccessFlag(parseAccessFlag(iter));
//类及其父类
classFile.setClassIndex(parseClassIndex(iter));
return classFile;
}
private AccessFlag parseAccessFlag(ByteCodeIterator iter) {
return new AccessFlag(iter.nextU2ToInt());
}
private ClassIndex parseClassIndex(ByteCodeIterator iter) {
ClassIndex classIndex = new ClassIndex();
classIndex.setThisClassIndex(iter.nextU2ToInt());
classIndex.setSuperClassIndex(iter.nextU2ToInt());
return classIndex;
}
private ConstantPool parseConstantPool(ByteCodeIterator iter) {
// 常量池计数值
int constantPoolCount = iter.nextU2ToInt();
System.out.println("constant pool count:" + constantPoolCount);
// 常量池
ConstantPool pool = new ConstantPool();
pool.addConstantInfo(new NullConstantInfo());// 常量池索引从1开始
for (int i = 1; i < constantPoolCount; i++) {
int tag = iter.nextU1ToInt();
switch (tag) {
case 1://UTF-8 String
int length = iter.nextU2ToInt();
String utf8Str = null;
try {
utf8Str = new String(iter.getBytes(length),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
UTF8Info utf8Info = new UTF8Info(pool);
utf8Info.setValue(utf8Str);
utf8Info.setLength(length);
pool.addConstantInfo(utf8Info);
break;
case 7://类或接口的符号引用
ClassInfo classInfo = new ClassInfo(pool);
classInfo.setUtf8Index(iter.nextU2ToInt());
pool.addConstantInfo(classInfo);
break;
case 8://字符串类型字面量
StringInfo stringInfo = new StringInfo(pool);
stringInfo.setIndex(iter.nextU2ToInt());
pool.addConstantInfo(stringInfo);
break;
case 9://字段的符号引用
FieldRefInfo fieldRefInfo = new FieldRefInfo(pool);
fieldRefInfo.setClassInfoIndex(iter.nextU2ToInt());
fieldRefInfo.setNameAndTypeIndex(iter.nextU2ToInt());
pool.addConstantInfo(fieldRefInfo);
break;
case 10://类中方法的符号引用
MethodRefInfo methodRefInfo = new MethodRefInfo(pool);
methodRefInfo.setClassInfoIndex(iter.nextU2ToInt());
methodRefInfo.setNameAndTypeIndex(iter.nextU2ToInt());
pool.addConstantInfo(methodRefInfo);
break;
case 12://字段或方法的部门符号引用
NameAndTypeInfo nameAndType = new NameAndTypeInfo(pool);
nameAndType.setIndex1(iter.nextU2ToInt());
nameAndType.setIndex2(iter.nextU2ToInt());
pool.addConstantInfo(nameAndType);
break;
default:
throw new RuntimeException("the constant pool tag:" + tag + " is not implements");
}
}
return pool;
}
}