public static byte[] dump1() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv; MethodVisitor mv; cw.visit(V1_4, ACC_SUPER, "pkg/Outer$1", null, "pkg/Outer", null); cw.visitOuterClass("pkg/Outer", "m", "()V"); cw.visitInnerClass("pkg/Outer$1", null, null, 0); fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null); fv.visitEnd(); mv = cw.visitMethod(0, "<init>", "(Lpkg/Outer;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "pkg/Outer", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"); mv.visitLdcInsn(" "); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); mv.visitMethodInsn(INVOKESTATIC, "pkg/Outer", "access$000", "(Lpkg/Outer;)I"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }
private static byte[] generate(String name, Class<?> type, Class<?> parameter) { name = name.replace('.', '/'); String typeName = Type.getInternalName(type); String typeDesc = Type.getDescriptor(type); String parameterName = Type.getInternalName(parameter); String parameterDesc = Type.getDescriptor(parameter); String constructSignature = '(' + parameterDesc + ')' + typeDesc; ClassWriter cw = new ClassWriter(0); MethodVisitor mv; cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, name, null, BASE_CLASS, null); { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Class;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, BASE_CLASS, "<init>", "(Ljava/lang/Class;)V", false); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "construct", constructSignature, null, null); mv.visitCode(); mv.visitTypeInsn(NEW, typeName); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, typeName, "<init>", '(' + parameterDesc + ")V", false); mv.visitInsn(ARETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "construct", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, parameterName); mv.visitMethodInsn(INVOKEVIRTUAL, name, "construct", constructSignature, false); mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
public Class<?> createWrapper(Method callback) { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; String name = getUniqueName(callback); String desc = name.replace('.', '/'); String instType = Type.getInternalName(callback.getDeclaringClass()); String eventType = Type.getInternalName(callback.getParameterTypes()[0]); /* System.out.println("Name: " + name); System.out.println("Desc: " + desc); System.out.println("InstType: " + instType); System.out.println("Callback: " + callback.getName() + Type.getMethodDescriptor(callback)); System.out.println("Event: " + eventType); */ cw.visit( V1_6, ACC_PUBLIC | ACC_SUPER, desc, null, "java/lang/Object", new String[] {HANDLER_DESC}); cw.visitSource(".dynamic", null); { cw.visitField(ACC_PUBLIC, "instance", "Ljava/lang/Object;", null, null).visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Object;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, desc, "instance", "Ljava/lang/Object;"); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "invoke", HANDLER_FUNC_DESC, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, desc, "instance", "Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, instType); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, eventType); mv.visitMethodInsn( INVOKEVIRTUAL, instType, callback.getName(), Type.getMethodDescriptor(callback)); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return LOADER.define(name, cw.toByteArray()); }
private void buildObjectAccessor(ClassWriter cw, Class cls) { MethodVisitor mv; if (fDebugEn) { debug("--> buildAccessor cls=" + cls.getName()); } // Constructor String tgt_clsname = getClassName(cls); String cls_name = getClassLeafName(cls); // Read method // // 0 - this // 1 - parent // 2 - object mv = cw.visitMethod( ACC_PRIVATE, "read" + cls_name, "(L" + fChildItem + ";" + "L" + tgt_clsname + ";)V", null, new String[] {fDBFormatException}); mv.visitCode(); visit(false, tgt_clsname, mv, cls); mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); // Write method // // 0 - this // 1 - object mv = cw.visitMethod( ACC_PRIVATE, "write" + cls_name, // "(L" + tgt_clsname + ";)V", "(L" + tgt_clsname + ";)V", null, new String[] {fDBWriteException}); mv.visitCode(); visit(true, tgt_clsname, mv, cls); mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); if (fDebugEn) { debug("<-- buildAccessor cls=" + cls.getName()); } }
@Override public void generateMethods(Object classVisitor) { assert classVisitor instanceof ClassVisitor; ClassVisitor cv = (ClassVisitor) classVisitor; // generated by compiling the class: // class foo { public ClassLoader getFrameworkClassLoader() { return // getClass().getClassLoader(); } } // and then running ASMifier on it: // java -classpath asm-debug-all-5.0.2.jar:. org.objectweb.asm.util.ASMifier foo MethodVisitor mv = cv.visitMethod( ACC_PUBLIC, "getFrameworkClassLoader", "()Ljava/lang/ClassLoader;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;", false); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // generated code ends. }
private void writeNonAbstractMethodWrapper( ClassVisitor visitor, Type generatedType, Class<?> managedTypeClass, Method method) { Label start = new Label(); Label end = new Label(); Label handler = new Label(); MethodVisitor methodVisitor = declareMethod(visitor, method); methodVisitor.visitTryCatchBlock(start, end, handler, null); setCanCallSettersField(methodVisitor, generatedType, false); methodVisitor.visitLabel(start); invokeSuperMethod(methodVisitor, managedTypeClass, method); methodVisitor.visitLabel(end); setCanCallSettersField(methodVisitor, generatedType, true); methodVisitor.visitInsn(ARETURN); methodVisitor.visitLabel(handler); setCanCallSettersField(methodVisitor, generatedType, true); methodVisitor.visitInsn(ATHROW); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
public static byte[] dumpInner() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv; MethodVisitor mv; cw.visit(V1_4, ACC_SUPER, "pkg/Outer$Inner", null, "java/lang/Object", null); cw.visitInnerClass("pkg/Outer$Inner", "pkg/Outer", "C", 0); fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null); fv.visitEnd(); mv = cw.visitMethod(0, "<init>", "(Lpkg/Outer;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, "pkg/Outer$Inner", "this$0", "Lpkg/Outer;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }
private void build_boilerplate(ClassWriter cw) { String classname = "SVDBPersistenceDelegate"; String full_classname = transform_cls(fTargetPkg) + "/" + classname; cw.visit( Opcodes.V1_5, ACC_PROTECTED + ACC_PUBLIC + ACC_SUPER, full_classname, null, fBaseClass, null); cw.visitSource(classname + ".java", null); MethodVisitor mv; // Constructor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, fBaseClass, "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); buildItemDispatchMethods(cw); buildObjectDispatchMethods(cw); }
@Override public void visitEnd() { if (methVisitor != null) { handleResult( new InstanceMethodExposer( onType, access, methodName, methodDesc, typeName, methVisitor.names, methVisitor.defaults, methVisitor.type, methVisitor.doc)); } if (newExp != null) { handleNewExposer(newExp); } if (classMethVisitor != null) { handleResult( new ClassMethodExposer( onType, access, methodName, methodDesc, typeName, classMethVisitor.names, classMethVisitor.defaults, classMethVisitor.doc)); } super.visitEnd(); }
protected void injectSetByName(ClassWriter classWriter) { MethodVisitor methodVisitor = classWriter.visitMethod( ACC_PUBLIC, "set", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V", null, new String[] {"java/lang/IllegalAccessException"}); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitVarInsn(ALOAD, 2); methodVisitor.visitMethodInsn( INVOKESPECIAL, getAccessorNameInternal(this.getTarget(), this.getAccessorType()), "getIndex", "(Ljava/lang/String;)I", false); methodVisitor.visitVarInsn(ALOAD, 3); methodVisitor.visitMethodInsn( INVOKEVIRTUAL, getAccessorNameInternal(this.getTarget(), this.getAccessorType()), "set", "(Ljava/lang/Object;ILjava/lang/Object;)V", false); methodVisitor.visitInsn(RETURN); methodVisitor.visitMaxs(4, 4); methodVisitor.visitEnd(); }
protected void injectGetByIndex( ClassWriter classWriter, String targetClassName, List<Field> fields) { MethodVisitor methodVisitor = classWriter.visitMethod( ACC_PUBLIC, "get", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, new String[] {getInternalName(ILLEGAL_ACCESS_EXCEPTION.getCanonicalName())}); Boxer boxer = new Boxer(methodVisitor); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ILOAD, 2); int maxStack = 6; Label[] labels = new Label[fields.size()]; Label errorLabel = new Label(); for (int i = 0; i < fields.size(); i++) { labels[i] = new Label(); } methodVisitor.visitTableSwitchInsn(0, labels.length - 1, errorLabel, labels); if (!fields.isEmpty()) { maxStack--; for (int i = 0; i < fields.size(); i++) { Field field = fields.get(i); Class<?> type = field.getType(); String fieldDescriptor = Type.getDescriptor(type); methodVisitor.visitLabel(labels[i]); if (i == 0) methodVisitor.visitFrame(F_APPEND, 1, new Object[] {targetClassName}, 0, null); else methodVisitor.visitFrame(F_SAME, 0, null, 0, null); if (isPublic(field)) { methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitTypeInsn(CHECKCAST, targetClassName); methodVisitor.visitFieldInsn(GETFIELD, targetClassName, field.getName(), fieldDescriptor); boxer.box(Type.getType(type)); } else { injectReflectiveGetter(methodVisitor); } methodVisitor.visitInsn(ARETURN); } methodVisitor.visitLabel(errorLabel); methodVisitor.visitFrame(F_SAME, 0, null, 0, null); } injectException(methodVisitor, IllegalAccessException.class); methodVisitor.visitMaxs(maxStack, 3); methodVisitor.visitEnd(); }
private void finalizeToString(MethodVisitor mv) { // The StringBuilder is on the top of the stack from the last append() - // duplicate it for call to replace() mv.visitVarInsn(ALOAD, 1); mv.visitInsn(DUP); // The replace starts at 2 characters before the end, to remove the // extra command and space added mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "length", "()I", false); mv.visitLdcInsn(2); mv.visitInsn(ISUB); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "length", "()I", false); mv.visitLdcInsn("}"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "replace", "(IILjava/lang/String;)Ljava/lang/StringBuilder;", false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
private void generateAccessor( ClassWriter cw, Class<?> parentType, String internalName, Property<Class<?>, Method> property) { Method accessor = property.getAccessor(); MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, accessor.getName(), Type.getMethodDescriptor(accessor), null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, internalName, property.getName(), Type.getDescriptor(property.getLeastSpecificType())); if (!property.isLeastSpecificType()) { mv.visitTypeInsn(CHECKCAST, Type.getInternalName(property.getType())); } mv.visitInsn(Type.getType(property.getType()).getOpcode(IRETURN)); mv.visitMaxs(0, 0); mv.visitEnd(); }
public void visitFunctionDeclaration(FunctionDeclarationContext function) { symbolTable.newScope(); Function f = buildFunction(function); returnType = f.getReturnValueType(); f.getArguments().stream().forEach(symbolTable::defineVariable); Type[] argTypes = f.getArguments() .stream() .flatMap(variable -> Stream.of(variable.getValueType().toAsmType())) .toArray(Type[]::new); String descriptor = Type.getMethodDescriptor(f.getReturnValueType().toAsmType(), argTypes); if ("main".equals(f.getName())) { if (!f.getArguments().isEmpty()) { throw new GenerationException("Main function must have zero arguments"); } descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String[].class)); } method = writer.visitMethod(ACC_PUBLIC | ACC_STATIC, f.getName(), descriptor, null, null); BlockContext block = function.functionBody().block(); visitBlock(block); checkReturn(block); method.visitMaxs(0, 0); method.visitEnd(); symbolTable.dropScope(); }
private void createAddMessage(ClassNode cn) { Pattern p = new PatternBuilder() .add( new InstructionElement(ALOAD), new LdcElement(new LdcInsnNode("")), new InstructionElement(ALOAD), new InstructionElement(INVOKEVIRTUAL)) .build(); MethodInsnNode ebola1 = null; for (MethodNode mn : cn.methods) { if (!p.contains(mn.instructions)) continue; int offset = p.getOffset(mn.instructions); ebola1 = (MethodInsnNode) mn.instructions.get(offset + 3); } { MethodVisitor mv = cn.visitMethod(ACC_PUBLIC, "addChatMessage", "(Ljava/lang/String;)V", null, null); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn(""); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, ebola1.owner, ebola1.name, ebola1.desc, ebola1.itf); mv.visitInsn(RETURN); mv.visitEnd(); } }
public void addSetMethod(MetaBeanProperty property) throws Exception { MetaMethod setter = property.getSetter(); Type paramType = Type.getType(setter.getParameterTypes()[0].getTheClass()); Type returnType = Type.getType(setter.getReturnType()); String setterDescriptor = Type.getMethodDescriptor(returnType, new Type[] {paramType}); // GENERATE public void <propName>(<type> v) { <setter>(v) } String setMethodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {paramType}); MethodVisitor methodVisitor = visitor.visitMethod( Opcodes.ACC_PUBLIC, property.getName(), setMethodDescriptor, null, new String[0]); methodVisitor.visitCode(); // GENERATE <setter>(v) methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitVarInsn(paramType.getOpcode(Opcodes.ILOAD), 1); methodVisitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, generatedType.getInternalName(), setter.getName(), setterDescriptor); // END methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
private static <T> void appendGetDelayedCellSetter( DelayedCellSetterFactory<T, ?>[] delayedCellSetters, ClassWriter cw, String targetType, String classType, int maxMethodSize) { MethodVisitor mv; mv = cw.visitMethod( ACC_PUBLIC, "getDelayedCellSetter", "(I)L" + DELAYED_CELL_SETTER_TYPE + ";", "(I)L" + DELAYED_CELL_SETTER_TYPE + "<L" + targetType + ";*>;", null); mv.visitCode(); if (delayedCellSetters.length != 0) { final int switchStart = 0; final int switchEnd = delayedCellSetters.length; appendGetDelayedCellSetterSwitch(delayedCellSetters, classType, mv, switchStart, switchEnd); } mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); mv.visitMaxs(1, 2); mv.visitEnd(); }
private static <T> void appendCellValue( CellSetter<T>[] setters, boolean ignoreException, ClassWriter cw, String classType) { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "cellValue", "([CIII)V", null, null); mv.visitCode(); if (setters.length != 0) { if (ignoreException) { callCellValue(mv, classType); } else { Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); mv.visitLabel(l0); callCellValue(mv, classType); mv.visitLabel(l1); Label l3 = new Label(); mv.visitJumpInsn(GOTO, l3); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Exception"}); mv.visitVarInsn(ASTORE, 5); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 4); mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn( INVOKEVIRTUAL, classType, "fieldError", "(ILjava/lang/Exception;)V", false); mv.visitLabel(l3); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } } mv.visitInsn(RETURN); mv.visitMaxs(5, 6); mv.visitEnd(); }
private static <T> void appendApplyDelayedCellSetterN( DelayedCellSetterFactory<T, ?>[] delayedCellSetters, ClassWriter cw, String classType) { MethodVisitor mv; for (int i = 0; i < delayedCellSetters.length; i++) { if (delayedCellSetters[i] != null) { mv = cw.visitMethod( ACC_PRIVATE, "applyDelayedCellSetter" + i, "()V", null, new String[] {"java/lang/Exception"}); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, classType, "delayedCellSetter" + i, "L" + DELAYED_CELL_SETTER_TYPE + ";"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, classType, "currentInstance", "Ljava/lang/Object;"); mv.visitMethodInsn( INVOKEINTERFACE, DELAYED_CELL_SETTER_TYPE, "set", "(Ljava/lang/Object;)V", true); mv.visitInsn(RETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } } }
private static byte[] generateEventExecutor(Method m, String name) { final boolean staticMethod = Modifier.isStatic(m.getModifiers()); ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); writer.visit( V1_8, ACC_PUBLIC, name, null, "java/lang/Object", new String[] {Type.getInternalName(EventExecutor.class)}); // Generate constructor MethodVisitor methodGenerator = writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); methodGenerator.visitVarInsn(ALOAD, 0); methodGenerator.visitMethodInsn( INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); // Invoke the super class (Object) constructor methodGenerator.visitInsn(RETURN); methodGenerator.visitMaxs(1, 1); methodGenerator.visitEnd(); // Generate the execute method methodGenerator = writer.visitMethod( ACC_PUBLIC, "fire", "(Ljava/lang/Object;Ljava/lang/Object;)V", null, null); if (!staticMethod) { methodGenerator.visitVarInsn(ALOAD, 1); methodGenerator.visitTypeInsn(CHECKCAST, Type.getInternalName(m.getDeclaringClass())); } methodGenerator.visitVarInsn(ALOAD, 2); methodGenerator.visitTypeInsn(CHECKCAST, Type.getInternalName(m.getParameterTypes()[0])); methodGenerator.visitMethodInsn( staticMethod ? INVOKESTATIC : INVOKEVIRTUAL, Type.getInternalName(m.getDeclaringClass()), m.getName(), Type.getMethodDescriptor(m), m.getDeclaringClass().isInterface()); if (m.getReturnType() != void.class) { methodGenerator.visitInsn(POP); } methodGenerator.visitInsn(RETURN); methodGenerator.visitMaxs(staticMethod ? 1 : 2, 3); methodGenerator.visitEnd(); writer.visitEnd(); return writer.toByteArray(); }
public byte[] dump() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv; MethodVisitor mv; cw.visit( V1_4, ACC_PUBLIC + ACC_SUPER + ACC_DEPRECATED, "pkg/Outer", null, "java/lang/Object", null); cw.visitInnerClass("pkg/Outer$Inner", "pkg/Outer", "C", 0); cw.visitInnerClass("pkg/Outer$1", null, null, 0); fv = cw.visitField(ACC_PRIVATE + ACC_DEPRECATED, "i", "I", null, null); fv.visitEnd(); mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cw.visitMethod(ACC_DEPRECATED, "m", "()V", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "pkg/Outer$1"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "pkg/Outer$1", "<init>", "(Lpkg/Outer;)V"); mv.visitInsn(POP); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cw.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "access$000", "(Lpkg/Outer;)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "pkg/Outer", "i", "I"); mv.visitInsn(IRETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }
protected static void injectEmptyConstructor(ClassWriter classWriter) { MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); methodVisitor.visitInsn(RETURN); methodVisitor.visitMaxs(1, 1); methodVisitor.visitEnd(); }
private static void insertConstructor(ClassWriter cw) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, "com/esotericsoftware/reflectasm/FieldAccess", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); }
protected static void injectGetTargetClass(ClassWriter classWriter, Class<?> targetClass) { MethodVisitor methodVisitor = classWriter.visitMethod( ACC_PUBLIC, "getTargetClass", "()Ljava/lang/Class;", "()Ljava/lang/Class<*>;", null); methodVisitor.visitCode(); methodVisitor.visitLdcInsn(Type.getType(targetClass)); methodVisitor.visitInsn(ARETURN); methodVisitor.visitMaxs(1, 1); methodVisitor.visitEnd(); }
private static void insertGetString( ClassWriter cw, String classNameInternal, ArrayList<Field> fields) { int maxStack = 6; MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, "getString", "(Ljava/lang/Object;I)Ljava/lang/String;", null, null); mv.visitCode(); mv.visitVarInsn(ILOAD, 2); if (!fields.isEmpty()) { maxStack--; Label[] labels = new Label[fields.size()]; Label labelForInvalidTypes = new Label(); boolean hasAnyBadTypeLabel = false; for (int i = 0, n = labels.length; i < n; i++) { if (fields.get(i).getType().equals(String.class)) labels[i] = new Label(); else { labels[i] = labelForInvalidTypes; hasAnyBadTypeLabel = true; } } Label defaultLabel = new Label(); mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); for (int i = 0, n = labels.length; i < n; i++) { if (!labels[i].equals(labelForInvalidTypes)) { Field field = fields.get(i); mv.visitLabel(labels[i]); mv.visitFrame(F_SAME, 0, null, 0, null); if (!Modifier.isStatic(field.getModifiers())) { mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, classNameInternal); } mv.visitFieldInsn( Modifier.isStatic(field.getModifiers()) ? GETSTATIC : GETFIELD, classNameInternal, field.getName(), "Ljava/lang/String;"); mv.visitInsn(ARETURN); } } // Rest of fields: different type if (hasAnyBadTypeLabel) { mv.visitLabel(labelForInvalidTypes); mv.visitFrame(F_SAME, 0, null, 0, null); insertThrowExceptionForFieldType(mv, "String"); } // Default: field not found mv.visitLabel(defaultLabel); mv.visitFrame(F_SAME, 0, null, 0, null); } insertThrowExceptionForFieldNotFound(mv); mv.visitMaxs(maxStack, 3); mv.visitEnd(); }
private void addGetter(String methodName, String methodDescriptor, MethodCodeBody body) throws Exception { MethodVisitor methodVisitor = visitor.visitMethod( Opcodes.ACC_PUBLIC, methodName, methodDescriptor, null, new String[0]); methodVisitor.visitCode(); body.add(methodVisitor); methodVisitor.visitInsn(Opcodes.ARETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
private void addSetter(Method method, MethodCodeBody body) throws Exception { String methodDescriptor = Type.getMethodDescriptor(method); MethodVisitor methodVisitor = visitor.visitMethod( Opcodes.ACC_PUBLIC, method.getName(), methodDescriptor, null, new String[0]); methodVisitor.visitCode(); body.add(methodVisitor); methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
public static byte[] dump() throws Exception { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; cw.visit(52, ACC_PUBLIC + ACC_SUPER, "DummyBundleClass", null, "java/lang/Object", null); cw.visitSource("DummyBundleClass.java", null); { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLineNumber(1, l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitInsn(RETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "LDummyBundleClass;", null, l0, l1, 0); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLineNumber(4, l0); mv.visitInsn(RETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("args", "[Ljava/lang/String;", null, l0, l1, 0); mv.visitMaxs(0, 1); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
@Test public void testLineNumberNegative() { Label l1 = new Label(); sanitizer.visitCode(); sanitizer.visitLineNumber(15, l1); sanitizer.visitInsn(Opcodes.RETURN); sanitizer.visitMaxs(0, 0); sanitizer.visitEnd(); expected.visitInsn(Opcodes.RETURN); expected.visitMaxs(0, 0); expected.visitEnd(); assertOutput(); }
byte[] compile(String name) { // class header String[] itfs = {Expression.class.getName()}; ClassWriter cw = new ClassWriter(true); cw.visit(V1_1, ACC_PUBLIC, name, null, "java/lang/Object", itfs); // default public constructor MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // eval method mv = cw.visitMethod(ACC_PUBLIC, "eval", "(II)I", null, null); compile(mv); mv.visitInsn(IRETURN); // max stack and max locals automatically computed mv.visitMaxs(0, 0); mv.visitEnd(); return cw.toByteArray(); }