// print the object on the top of the stack public Assembler printObject() { mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitInsn(SWAP); mv.visitMethodInsn( INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false); return this; }
public Assembler defaultValue(String desc) { int typeCode = desc.charAt(0); switch (typeCode) { case '[': case 'L': mv.visitInsn(ACONST_NULL); break; case 'Z': case 'C': case 'B': case 'S': case 'I': mv.visitInsn(ICONST_0); break; case 'J': mv.visitInsn(LCONST_0); break; case 'F': mv.visitInsn(FCONST_0); break; case 'D': mv.visitInsn(DCONST_0); break; } return this; }
public Assembler push(int value) { if (value >= -1 && value <= 5) { mv.visitInsn(ICONST_0 + value); } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { mv.visitIntInsn(BIPUSH, value); } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { mv.visitIntInsn(SIPUSH, value); } else { mv.visitLdcInsn(value); } return this; }
public Assembler sub(Type t) { int opcode = -1; switch (t.getSort()) { case Type.SHORT: case Type.BYTE: case Type.INT: { opcode = ISUB; break; } case Type.LONG: { opcode = LSUB; break; } case Type.FLOAT: { opcode = FSUB; break; } case Type.DOUBLE: { opcode = DSUB; break; } } if (opcode != -1) { mv.visitInsn(opcode); } return this; }
public Assembler dupReturnValue(int returnOpcode) { switch (returnOpcode) { case IRETURN: case FRETURN: case ARETURN: mv.visitInsn(DUP); break; case LRETURN: case DRETURN: mv.visitInsn(DUP2); break; case RETURN: break; default: throw new IllegalArgumentException("not return"); } return this; }
/** Generate class bytes for java.lang.Runnable implementation and return the same. */ public byte[] generate(Method method, String className) { int modifiers = method.getModifiers(); // make sure that the method is public static // and accepts no arguments if (!Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers) || method.getParameterTypes().length != 0) { throw new IllegalArgumentException(); } Class clazz = method.getDeclaringClass(); modifiers = clazz.getModifiers(); // make sure that the class is public as well if (!Modifier.isPublic(modifiers)) { throw new IllegalArgumentException(); } ClassWriter cw = InstrumentUtils.newClassWriter(); cw.visit( V1_1, ACC_PUBLIC, className, null, "java/lang/Object", new String[] {"java/lang/Runnable"}); // creates a MethodWriter for the (implicit) constructor MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); // pushes the 'this' variable mw.visitVarInsn(ALOAD, 0); // invokes the super class constructor mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mw.visitInsn(RETURN); mw.visitMaxs(1, 1); mw.visitEnd(); // creates a MethodWriter for the 'main' method mw = cw.visitMethod(ACC_PUBLIC, "run", "()V", null, null); // invokes the given method mw.visitMethodInsn( INVOKESTATIC, Type.getInternalName(method.getDeclaringClass()), method.getName(), Type.getMethodDescriptor(method)); mw.visitInsn(RETURN); mw.visitMaxs(1, 1); mw.visitEnd(); return cw.toByteArray(); }
public Assembler dupValue(String desc) { int typeCode = desc.charAt(0); switch (typeCode) { case '[': case 'L': case 'Z': case 'C': case 'B': case 'S': case 'I': mv.visitInsn(DUP); break; case 'J': case 'D': mv.visitInsn(DUP2); break; default: throw new RuntimeException("invalid signature"); } return this; }
public Assembler unbox(String desc) { int typeCode = desc.charAt(0); switch (typeCode) { case '[': case 'L': mv.visitTypeInsn(CHECKCAST, Type.getType(desc).getInternalName()); break; case 'Z': mv.visitTypeInsn(CHECKCAST, JAVA_LANG_BOOLEAN); invokeVirtual(JAVA_LANG_BOOLEAN, BOOLEAN_VALUE, BOOLEAN_VALUE_DESC); break; case 'C': mv.visitTypeInsn(CHECKCAST, JAVA_LANG_CHARACTER); invokeVirtual(JAVA_LANG_CHARACTER, CHAR_VALUE, CHAR_VALUE_DESC); break; case 'B': mv.visitTypeInsn(CHECKCAST, JAVA_LANG_NUMBER); invokeVirtual(JAVA_LANG_NUMBER, BYTE_VALUE, BYTE_VALUE_DESC); break; case 'S': mv.visitTypeInsn(CHECKCAST, JAVA_LANG_NUMBER); invokeVirtual(JAVA_LANG_NUMBER, SHORT_VALUE, SHORT_VALUE_DESC); break; case 'I': mv.visitTypeInsn(CHECKCAST, JAVA_LANG_NUMBER); invokeVirtual(JAVA_LANG_NUMBER, INT_VALUE, INT_VALUE_DESC); break; case 'J': mv.visitTypeInsn(CHECKCAST, JAVA_LANG_NUMBER); invokeVirtual(JAVA_LANG_NUMBER, LONG_VALUE, LONG_VALUE_DESC); break; case 'F': mv.visitTypeInsn(CHECKCAST, JAVA_LANG_NUMBER); invokeVirtual(JAVA_LANG_NUMBER, FLOAT_VALUE, FLOAT_VALUE_DESC); break; case 'D': mv.visitTypeInsn(CHECKCAST, JAVA_LANG_NUMBER); invokeVirtual(JAVA_LANG_NUMBER, DOUBLE_VALUE, DOUBLE_VALUE_DESC); break; } return this; }
public Assembler invokeInterface(String owner, String method, String desc) { mv.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc, true); return this; }
public Assembler invokeStatic(String owner, String method, String desc) { mv.visitMethodInsn(INVOKESTATIC, owner, method, desc, false); return this; }
public Assembler invokeSpecial(String owner, String method, String desc) { mv.visitMethodInsn(INVOKESPECIAL, owner, method, desc, false); return this; }
public Assembler pop() { mv.visitInsn(POP); return this; }
public Assembler ldc(Object o) { if (o instanceof Integer) { int i = (int) o; if (i >= -1 && i <= 5) { int opcode = -1; switch (i) { case 0: { opcode = ICONST_0; break; } case 1: { opcode = ICONST_1; break; } case 2: { opcode = ICONST_2; break; } case 3: { opcode = ICONST_3; break; } case 4: { opcode = ICONST_4; break; } case 5: { opcode = ICONST_5; break; } case -1: { opcode = ICONST_M1; break; } } mv.visitInsn(opcode); return this; } } if (o instanceof Long) { long l = (long) o; if (l >= 0 && l <= 1) { int opcode = -1; switch ((int) l) { case 0: { opcode = LCONST_0; break; } case 1: { opcode = LCONST_1; break; } } mv.visitInsn(opcode); return this; } } mv.visitLdcInsn(o); return this; }
public Assembler arrayStore(Type type) { mv.visitInsn(type.getOpcode(IASTORE)); return this; }
public Assembler label(Label l) { mv.visitLabel(l); return this; }
public Assembler newArray(Type t) { mv.visitTypeInsn(ANEWARRAY, t.getInternalName()); return this; }
public Assembler storeField(Type owner, String name, Type t) { mv.visitFieldInsn(Opcodes.PUTFIELD, owner.getInternalName(), name, t.getDescriptor()); return this; }
public Assembler newInstance(Type t) { mv.visitTypeInsn(NEW, t.getInternalName()); return this; }
public Assembler swap() { mv.visitInsn(SWAP); return this; }
public Assembler dup2() { mv.visitInsn(DUP2); return this; }
public Assembler loadNull() { mv.visitInsn(ACONST_NULL); return this; }
public Assembler storeLocal(Type type, int index) { mv.visitVarInsn(type.getOpcode(ISTORE), index); return this; }
public Assembler putStatic(String owner, String name, String desc) { mv.visitFieldInsn(PUTSTATIC, owner, name, desc); return this; }
public Assembler println(String msg) { mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitLdcInsn(msg); invokeVirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V"); return this; }
public Assembler arrayLoad(Type type) { mv.visitInsn(type.getOpcode(IALOAD)); return this; }
public Assembler loadLocal(Type type, int index) { mv.visitVarInsn(type.getOpcode(ILOAD), index); return this; }
public Assembler jump(int opcode, Label l) { mv.visitJumpInsn(opcode, l); return this; }
public Assembler invokeVirtual(String owner, String method, String desc) { mv.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc, false); return this; }
public Assembler ldc(Object o) { mv.visitLdcInsn(o); return this; }
public Assembler loadStaticField(Type owner, String name, Type t) { mv.visitFieldInsn(Opcodes.GETSTATIC, owner.getInternalName(), name, t.getDescriptor()); return this; }