📄 instructionfactory.java
字号:
*/ public static ArithmeticInstruction createBinaryOperation(String op, Type type) { char first = op.toCharArray()[0]; switch(type.getType()) { case Constants.T_BYTE: case Constants.T_SHORT: case Constants.T_INT: case Constants.T_CHAR: return createBinaryIntOp(first, op); case Constants.T_LONG: return createBinaryLongOp(first, op); case Constants.T_FLOAT: return createBinaryFloatOp(first); case Constants.T_DOUBLE: return createBinaryDoubleOp(first); default: throw new RuntimeException("Invalid type " + type); } } /** * @param size size of operand, either 1 (int, e.g.) or 2 (double) */ public static StackInstruction createPop(int size) { return (size == 2)? (StackInstruction)POP2 : (StackInstruction)POP; } /** * @param size size of operand, either 1 (int, e.g.) or 2 (double) */ public static StackInstruction createDup(int size) { return (size == 2)? (StackInstruction)DUP2 : (StackInstruction)DUP; } /** * @param size size of operand, either 1 (int, e.g.) or 2 (double) */ public static StackInstruction createDup_2(int size) { return (size == 2)? (StackInstruction)DUP2_X2 : (StackInstruction)DUP_X2; } /** * @param size size of operand, either 1 (int, e.g.) or 2 (double) */ public static StackInstruction createDup_1(int size) { return (size == 2)? (StackInstruction)DUP2_X1 : (StackInstruction)DUP_X1; } /** * @param index index of local variable */ public static LocalVariableInstruction createStore(Type type, int index) { switch(type.getType()) { case Constants.T_BOOLEAN: case Constants.T_CHAR: case Constants.T_BYTE: case Constants.T_SHORT: case Constants.T_INT: return new ISTORE(index); case Constants.T_FLOAT: return new FSTORE(index); case Constants.T_DOUBLE: return new DSTORE(index); case Constants.T_LONG: return new LSTORE(index); case Constants.T_ARRAY: case Constants.T_OBJECT: return new ASTORE(index); default: throw new RuntimeException("Invalid type " + type); } } /** * @param index index of local variable */ public static LocalVariableInstruction createLoad(Type type, int index) { switch(type.getType()) { case Constants.T_BOOLEAN: case Constants.T_CHAR: case Constants.T_BYTE: case Constants.T_SHORT: case Constants.T_INT: return new ILOAD(index); case Constants.T_FLOAT: return new FLOAD(index); case Constants.T_DOUBLE: return new DLOAD(index); case Constants.T_LONG: return new LLOAD(index); case Constants.T_ARRAY: case Constants.T_OBJECT: return new ALOAD(index); default: throw new RuntimeException("Invalid type " + type); } } /** * @param type type of elements of array, i.e., array.getElementType() */ public static ArrayInstruction createArrayLoad(Type type) { switch(type.getType()) { case Constants.T_BOOLEAN: case Constants.T_BYTE: return BALOAD; case Constants.T_CHAR: return CALOAD; case Constants.T_SHORT: return SALOAD; case Constants.T_INT: return IALOAD; case Constants.T_FLOAT: return FALOAD; case Constants.T_DOUBLE: return DALOAD; case Constants.T_LONG: return LALOAD; case Constants.T_ARRAY: case Constants.T_OBJECT: return AALOAD; default: throw new RuntimeException("Invalid type " + type); } } /** * @param type type of elements of array, i.e., array.getElementType() */ public static ArrayInstruction createArrayStore(Type type) { switch(type.getType()) { case Constants.T_BOOLEAN: case Constants.T_BYTE: return BASTORE; case Constants.T_CHAR: return CASTORE; case Constants.T_SHORT: return SASTORE; case Constants.T_INT: return IASTORE; case Constants.T_FLOAT: return FASTORE; case Constants.T_DOUBLE: return DASTORE; case Constants.T_LONG: return LASTORE; case Constants.T_ARRAY: case Constants.T_OBJECT: return AASTORE; default: throw new RuntimeException("Invalid type " + type); } } /** Create conversion operation for two stack operands, this may be an I2C, instruction, e.g., * if the operands are basic types and CHECKCAST if they are reference types. */ public Instruction createCast(Type src_type, Type dest_type) { if((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { byte dest = dest_type.getType(); byte src = src_type.getType(); if(dest == Constants.T_LONG && (src == Constants.T_CHAR || src == Constants.T_BYTE || src == Constants.T_SHORT)) src = Constants.T_INT; String[] short_names = { "C", "F", "D", "B", "S", "I", "L" }; String name = "de.fub.bytecode.generic." + short_names[src - Constants.T_CHAR] + "2" + short_names[dest - Constants.T_CHAR]; Instruction i = null; try { i = (Instruction)java.lang.Class.forName(name).newInstance(); } catch(Exception e) { throw new RuntimeException("Could not find instruction: " + name); } return i; } else if((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { if(dest_type instanceof ArrayType) return new CHECKCAST(cp.addArrayClass((ArrayType)dest_type)); else return new CHECKCAST(cp.addClass(((ObjectType)dest_type).getClassName())); } else throw new RuntimeException("Can not cast " + src_type + " to " + dest_type); } public GETFIELD createGetField(String class_name, String name, Type t) { return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature())); } public GETSTATIC createGetStatic(String class_name, String name, Type t) { return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature())); } public PUTFIELD createPutField(String class_name, String name, Type t) { return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature())); } public PUTSTATIC createPutStatic(String class_name, String name, Type t) { return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature())); } public CHECKCAST createCheckCast(ReferenceType t) { if(t instanceof ArrayType) return new CHECKCAST(cp.addArrayClass((ArrayType)t)); else return new CHECKCAST(cp.addClass((ObjectType)t)); } public NEW createNew(ObjectType t) { return new NEW(cp.addClass(t)); } public NEW createNew(String s) { return createNew(new ObjectType(s)); } /** Create new array of given size and type. */ public AllocationInstruction createNewArray(Type t, short dim) { if(dim == 1) { if(t instanceof ObjectType) return new ANEWARRAY(cp.addClass((ObjectType)t)); else if(t instanceof ArrayType) return new ANEWARRAY(cp.addArrayClass((ArrayType)t)); else return new NEWARRAY(((BasicType)t).getType()); } else { ArrayType at; if(t instanceof ArrayType) at = (ArrayType)t; else at = new ArrayType(t, dim); return new MULTIANEWARRAY(cp.addArrayClass(at), dim); } } /** Create "null" value for reference types, 0 for basic types like int */ public static Instruction createNull(Type type) { switch(type.getType()) { case Constants.T_ARRAY: case Constants.T_OBJECT: return ACONST_NULL; case Constants.T_INT: case Constants.T_SHORT: case Constants.T_BOOLEAN: case Constants.T_CHAR: case Constants.T_BYTE: return ICONST_0; case Constants.T_FLOAT: return FCONST_0; case Constants.T_DOUBLE: return DCONST_0; case Constants.T_LONG: return LCONST_0; case Constants.T_VOID: return NOP; default: throw new RuntimeException("Invalid type: " + type); } } /** Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH. * For those you should use the SWITCH compeund instruction. */ public static BranchInstruction createBranchInstruction(short opcode, InstructionHandle target) { switch(opcode) { case Constants.IFEQ: return new IFEQ(target); case Constants.IFNE: return new IFNE(target); case Constants.IFLT: return new IFLT(target); case Constants.IFGE: return new IFGE(target); case Constants.IFGT: return new IFGT(target); case Constants.IFLE: return new IFLE(target); case Constants.IF_ICMPEQ: return new IF_ICMPEQ(target); case Constants.IF_ICMPNE: return new IF_ICMPNE(target); case Constants.IF_ICMPLT: return new IF_ICMPLT(target); case Constants.IF_ICMPGE: return new IF_ICMPGE(target); case Constants.IF_ICMPGT: return new IF_ICMPGT(target); case Constants.IF_ICMPLE: return new IF_ICMPLE(target); case Constants.IF_ACMPEQ: return new IF_ACMPEQ(target); case Constants.IF_ACMPNE: return new IF_ACMPNE(target); case Constants.GOTO: return new GOTO(target); case Constants.JSR: return new JSR(target); case Constants.IFNULL: return new IFNULL(target); case Constants.IFNONNULL: return new IFNONNULL(target); case Constants.GOTO_W: return new GOTO_W(target); case Constants.JSR_W: return new JSR_W(target); default: throw new RuntimeException("Invalid opcode: " + opcode); } } public void setClassGen(ClassGen c) { cg = c; } public ClassGen getClassGen() { return cg; } public void setConstantPool(ConstantPoolGen c) { cp = c; } public ConstantPoolGen getConstantPool() { return cp; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -