package week567_miniJVM.loader;
import structure.week1.ArrayList;
import week567_miniJVM.clz.AccessFlag;
import week567_miniJVM.clz.ClassFile;
import week567_miniJVM.clz.ClassIndex;
import week567_miniJVM.constant.ConstantInfo;
import week567_miniJVM.constant.ConstantPool;
import week567_miniJVM.constant.InfoFactory;
import week567_miniJVM.constant.NullConstantInfo;
import week567_miniJVM.field.Field;
import week567_miniJVM.method.Method;
public class ClassFileParser {
public ClassFile parse(byte[] bytes) {
ClassFile clzFile = new ClassFile();
ByteCodeIterator iter = new ByteCodeIterator(bytes);
if(!"cafebabe".equals(iter.nextUxToHexString(4))) return null;
clzFile.setVersion(iter.nextU2ToInt(),iter.nextU2ToInt());
ConstantPool pool = parseConstantPool(iter);
clzFile.setConstantPool(pool);
clzFile.setAccessFlag(parseAccessFlag(iter));
clzFile.setClassIndex(parseClassIndex(iter));
int collectionNum = iter.nextU2ToInt();
iter.skip(collectionNum*2);
clzFile.setFields(parseFields(iter,pool));
clzFile.setMethods(parseMethods(clzFile,iter));
return clzFile;
}
private ConstantPool parseConstantPool(ByteCodeIterator iter){
ConstantPool pool = new ConstantPool();
pool.addConstantInfo(new NullConstantInfo());
int lenpool = iter.nextU2ToInt();
while(lenpool>1){
lenpool -= 1;
int tag = iter.nextU1ToInt();
ConstantInfo info = InfoFactory.Invoke().getInfoObj(tag,iter,pool);
pool.addConstantInfo(info);
}
return pool;
}
private AccessFlag parseAccessFlag(ByteCodeIterator iter) {
AccessFlag caflag = new AccessFlag(iter.nextU2ToInt());
return caflag;
}
private ClassIndex parseClassIndex(ByteCodeIterator iter) {
ClassIndex clzIndex = new ClassIndex();
clzIndex.setThisClassIndex(iter.nextU2ToInt());
clzIndex.setSuperClassIndex(iter.nextU2ToInt());
return clzIndex;
}
private ArrayList<Field> parseFields(ByteCodeIterator iter,ConstantPool pool){
ArrayList<Field> fields = new ArrayList<Field>();
int fieldNum = iter.nextU2ToInt();
while(fieldNum>0){
fieldNum -= 1;
int accflag = iter.nextU2ToInt(); // 例如是public
int nameIndex = iter.nextU2ToInt();// 指向常量池的入口
int descIndex = iter.nextU2ToInt(); // 指向常量池的入口
Field field = new Field(accflag,nameIndex,descIndex,pool);
field.parse(pool,iter);
fields.add(field);
}
return fields;
}
private ArrayList<Method> parseMethods(ClassFile clzFile,ByteCodeIterator iter){
ArrayList<Method> methods = new ArrayList<Method>();
int methodNum = iter.nextU2ToInt();
while(methodNum>0){
methodNum -= 1;
int accflag = iter.nextU2ToInt();
int nameIndex = iter.nextU2ToInt();
int descIndex = iter.nextU2ToInt();
Method method = new Method(clzFile,accflag,nameIndex,descIndex);
method.parse(clzFile,iter);
methods.add(method);
}
return methods;
}
}