package com.coderising.jvm.cmd; import java.util.ArrayList; import java.util.List; import com.coderising.jvm.clz.ClassFile; public class CommandParser { public static final String aconst_null = "01";// �� null������ջ�� public static final String new_object = "BB";// ����һ�����󣬲���������ֵѹ��ջ��,����������ֽ����ڹ���������������ִ�����ӿڵķ������� public static final String lstore = "37";// ��ջ�� long ����ֵ���� ָ�����ر��� public static final String invokespecial = "B7";// ���ó��๹�췽����ʵ����ʼ��������˽�з���,���������byte�����ڹ�����ǰ������ʱ�ij����ص�������ָ��������ʱ�����ص�һ�������ķ������� public static final String invokevirtual = "B6";// ����ʵ������������������ֽ����ڹ���������������ָ��һ�������ķ������� public static final String getfield = "B4";//��ȡָ�����ʵ���򣬲�����ѹ��ջ�� public static final String putfield = "B5";// Ϊָ�������ʵ����ֵ,����������ֽ����ڹ���һ���������������ָ��������ʱ�ֶε�һ���������ã������ð������ֶε����ƺ����������Լ����ֶε���ķ������� public static final String getstatic = "B2";// ��ȡ�ֶεľ�̬�ֶ�ֵ public static final String ldc = "12";// �� int�� float ��String �ͳ���ֵ�ӳ�������������ջ���������һ���ֽ���һ��������������ָ����int����float���͵ij��� public static final String dup = "59";// ��ֵ������ջջ����ֵ����ѹ�������ջ public static final String bipush = "10";// �� byte ��������չΪһ�� int ���͵�ֵ value��Ȼ��valueѹ�뵽������ջ�������һ���ֽ���value public static final String aload_0 = "2A";// ����һ���������ͱ��ر���������ջ�� public static final String aload_1 = "2B";// ���ڶ������ر������������������͵�ֵѹ�������ջ,�����޲����� public static final String aload_2 = "2C"; public static final String iload = "15"; public static final String iload_1 = "1B";// ���ڶ���int�ͱ��ر���������ջ�� public static final String iload_2 = "1C"; public static final String iload_3 = "1D"; public static final String fload_3 = "25";// �����ĸ�float�ͱ��ر�����������ջ�� public static final String voidreturn = "B1";// �޷���ֵ�ķ��� public static final String ireturn = "AC";// �ӵ�ǰ�������� int public static final String freturn = "AE";// �ӵ�ǰ�������� float public static final String astore_1 = "4C";//��ջ���������������ʹ���ڶ����ֲ���������һ��NoOperand public static final String if_icmp_ge = "A2"; public static final String if_icmple = "A4"; public static final String goto_no_condition = "A7"; public static final String iconst_0 = "03";// iconst_0 ��int�� 0 ������ջ�� public static final String iconst_1 = "04"; public static final String istore_1 = "3C"; public static final String istore_2 = "3D"; public static final String iadd = "60"; public static final String iinc = "84"; public static ByteCodeCommand[] parse(ClassFile clzFile, String codes) { CommandIterator iter = new CommandIterator(codes); List<ByteCodeCommand> cmds = new ArrayList<ByteCodeCommand>(); while(iter.hasNext()){ String opCode = iter.next2CharAsString(); System.out.println("�ֽ��룺 opCode --- " + opCode); if(new_object.equalsIgnoreCase(opCode)){// new ������������������ָ�� NewObjectCmd cmd = new NewObjectCmd(clzFile, opCode); System.out.println("cmd"); cmd.setOprand1(iter.next2CharAsInt()); cmd.setOprand2(iter.next2CharAsInt()); cmds.add(cmd); }else if(invokespecial.equalsIgnoreCase(opCode)){// invokespecial ������������������ָ�� InvokeSpecialCmd cmd = new InvokeSpecialCmd(clzFile, opCode); cmd.setOprand1(iter.next2CharAsInt()); cmd.setOprand2(iter.next2CharAsInt()); cmds.add(cmd); }else if(getfield.equalsIgnoreCase(opCode)){// getfield ������������������ָ�� GetFieldCmd cmd = new GetFieldCmd(clzFile, opCode); cmd.setOprand1(iter.next2CharAsInt()); cmd.setOprand2(iter.next2CharAsInt()); cmds.add(cmd); }else if(putfield.equalsIgnoreCase(opCode)){ System.out.println("putfield"); PutFieldCmd cmd = new PutFieldCmd(clzFile, opCode); cmd.setOprand1(iter.next2CharAsInt()); cmd.setOprand2(iter.next2CharAsInt()); cmds.add(cmd); }else if(getstatic.equalsIgnoreCase(opCode)){ GetStaticFieldCmd cmd = new GetStaticFieldCmd(clzFile, opCode); cmd.setOprand1(iter.next2CharAsInt()); cmd.setOprand2(iter.next2CharAsInt()); cmds.add(cmd); }else if(invokevirtual.equalsIgnoreCase(opCode)){ InvokeVirtualCmd cmd = new InvokeVirtualCmd(clzFile, opCode); cmd.setOprand1(iter.next2CharAsInt()); cmd.setOprand2(iter.next2CharAsInt()); cmds.add(cmd); }else if(bipush.equalsIgnoreCase(opCode)){ BiPushCmd cmd = new BiPushCmd(clzFile, opCode); cmd.setOperand(iter.next2CharAsInt()); cmds.add(cmd); }else if(ldc.equalsIgnoreCase(opCode)){ LdcCmd cmd = new LdcCmd(clzFile, opCode); cmd.setOperand(iter.next2CharAsInt()); cmds.add(cmd); }else if(dup.equalsIgnoreCase(opCode) || aload_0.equalsIgnoreCase(opCode) || iconst_0.equalsIgnoreCase(opCode) || iconst_1.equalsIgnoreCase(opCode) || aload_0.equalsIgnoreCase(opCode) || aload_1.equalsIgnoreCase(opCode) || aload_2.equalsIgnoreCase(opCode) || iload_1.equalsIgnoreCase(opCode) || iload_2.equalsIgnoreCase(opCode) || iload_3.equalsIgnoreCase(opCode) || voidreturn.equalsIgnoreCase(opCode) || astore_1.equalsIgnoreCase(opCode)){ NoOperandCmd cmd = new NoOperandCmd(clzFile, opCode); cmds.add(cmd); }else{ System.out.println("the " + opCode+ "has not been implements"); } } calcuateOffset(cmds); System.out.println("cmds.size ------ " + cmds.size()); ByteCodeCommand[] result = new ByteCodeCommand[cmds.size()]; cmds.toArray(result); return result; } private static void calcuateOffset(List<ByteCodeCommand> cmds) { int offset = 0; for (ByteCodeCommand cmd : cmds) { cmd.setOffset(offset); offset += cmd.getLength(); } } private static class CommandIterator { String codes = null; int pos = 0; CommandIterator(String codes) { this.codes = codes; } public boolean hasNext() { return pos < this.codes.length(); } public String next2CharAsString() { String result = codes.substring(pos, pos + 2); pos += 2; return result; } public int next2CharAsInt() { String s = this.next2CharAsString(); return Integer.valueOf(s, 16).intValue(); } } }