Search in sources :

Example 1 with AnnotationNode

use of org.objectweb.asm.tree.AnnotationNode in project LogisticsPipes by RS485.

the class LogisticsPipesClassInjector method transform.

@Override
@SuppressWarnings("unchecked")
public byte[] transform(String name, String transformedName, byte[] bytes) {
    if (bytes != null) {
        if (name.startsWith("logisticspipes.")) {
            final ClassReader reader = new ClassReader(bytes);
            final ClassNode node = new ClassNode();
            reader.accept(node, 0);
            if (node.visibleAnnotations != null) {
                for (AnnotationNode a : node.visibleAnnotations) {
                    if (a.desc.equals("Llogisticspipes/asm/ModVersionedClass;")) {
                        if (a.values.size() == 8 && a.values.get(0).equals("modId") && a.values.get(2).equals("version") && a.values.get(4).equals("classData") && a.values.get(6).equals("classDataDev")) {
                            String modId = a.values.get(1).toString();
                            String version = a.values.get(3).toString();
                            String classData = a.values.get(5).toString();
                            String classDataDev = a.values.get(7).toString();
                            if (ModStatusHelper.isModLoaded(modId) && !ModStatusHelper.isModVersionEqualsOrHigher(modId, version)) {
                                if (isObfEnv == null) {
                                    try {
                                        isObfEnv = (Class.forName("net.minecraft.world.World").getDeclaredField("chunkProvider") == null);
                                    } catch (Throwable e) {
                                        isObfEnv = true;
                                    }
                                }
                                bytes = transform(name, transformedName, DatatypeConverter.parseBase64Binary(isObfEnv ? classData : classDataDev));
                            }
                        } else {
                            throw new UnsupportedOperationException("Can't parse the annotations correctly");
                        }
                    }
                }
            }
        }
        return bytes;
    }
    try {
        if (name.startsWith("logisticspipes.proxy.opencomputers.asm.BaseWrapperClass$") && name.endsWith("$OpenComputersWrapper")) {
            String correctName = name.substring(56, name.length() - 21);
            Class<?> clazz = Launch.classLoader.findClass(correctName);
            bytes = ClassCreator.getWrappedClassAsBytes(CCObjectWrapper.getWrapperInformation(clazz), clazz.getName());
            Set<String> set = new TreeSet<>();
            set.add(name);
            Launch.classLoader.clearNegativeEntries(set);
            Map<String, byte[]> map = (Map<String, byte[]>) fResourceCache.get(Launch.classLoader);
            map.put(name, bytes);
            return bytes;
        }
    } catch (Exception e) {
        if (LPConstants.DEBUG) {
            // For better Debugging
            e.printStackTrace();
            return bytes;
        }
        throw new RuntimeException(e);
    }
    return bytes;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) AnnotationNode(org.objectweb.asm.tree.AnnotationNode) TreeSet(java.util.TreeSet) ClassReader(org.objectweb.asm.ClassReader) Map(java.util.Map)

Example 2 with AnnotationNode

use of org.objectweb.asm.tree.AnnotationNode in project MinecraftForge by MinecraftForge.

the class EventSubscriptionTransformer method buildEvents.

private boolean buildEvents(ClassNode classNode) throws Exception {
    // Yes, this recursively loads classes until we get this base class. THIS IS NOT A ISSUE. Coremods should handle re-entry just fine.
    // If they do not this a COREMOD issue NOT a Forge/LaunchWrapper issue.
    Class<?> parent = this.getClass().getClassLoader().loadClass(classNode.superName.replace('/', '.'));
    if (!Event.class.isAssignableFrom(parent)) {
        return false;
    }
    //Class<?> listenerListClazz = Class.forName("net.minecraftforge.fml.common.eventhandler.ListenerList", false, getClass().getClassLoader());
    Type tList = Type.getType("Lnet/minecraftforge/fml/common/eventhandler/ListenerList;");
    boolean edited = false;
    boolean hasSetup = false;
    boolean hasGetListenerList = false;
    boolean hasDefaultCtr = false;
    boolean hasCancelable = false;
    boolean hasResult = false;
    String voidDesc = Type.getMethodDescriptor(VOID_TYPE);
    String boolDesc = Type.getMethodDescriptor(BOOLEAN_TYPE);
    String listDesc = tList.getDescriptor();
    String listDescM = Type.getMethodDescriptor(tList);
    for (MethodNode method : classNode.methods) {
        if (method.name.equals("setup") && method.desc.equals(voidDesc) && (method.access & ACC_PROTECTED) == ACC_PROTECTED)
            hasSetup = true;
        if ((method.access & ACC_PUBLIC) == ACC_PUBLIC) {
            if (method.name.equals("getListenerList") && method.desc.equals(listDescM))
                hasGetListenerList = true;
            if (method.name.equals("isCancelable") && method.desc.equals(boolDesc))
                hasCancelable = true;
            if (method.name.equals("hasResult") && method.desc.equals(boolDesc))
                hasResult = true;
        }
        if (method.name.equals("<init>") && method.desc.equals(voidDesc))
            hasDefaultCtr = true;
    }
    if (classNode.visibleAnnotations != null) {
        for (AnnotationNode node : classNode.visibleAnnotations) {
            if (!hasResult && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Event$HasResult;")) {
                /* Add:
                     *      public boolean hasResult()
                     *      {
                     *            return true;
                     *      }
                     */
                MethodNode method = new MethodNode(ACC_PUBLIC, "hasResult", boolDesc, null, null);
                method.instructions.add(new InsnNode(ICONST_1));
                method.instructions.add(new InsnNode(IRETURN));
                classNode.methods.add(method);
                edited = true;
            } else if (!hasCancelable && node.desc.equals("Lnet/minecraftforge/fml/common/eventhandler/Cancelable;")) {
                /* Add:
                     *      public boolean isCancelable()
                     *      {
                     *            return true;
                     *      }
                     */
                MethodNode method = new MethodNode(ACC_PUBLIC, "isCancelable", boolDesc, null, null);
                method.instructions.add(new InsnNode(ICONST_1));
                method.instructions.add(new InsnNode(IRETURN));
                classNode.methods.add(method);
                edited = true;
            }
        }
    }
    if (hasSetup) {
        if (!hasGetListenerList)
            throw new RuntimeException("Event class defines setup() but does not define getListenerList! " + classNode.name);
        else
            return edited;
    }
    Type tSuper = Type.getType(classNode.superName);
    //Add private static ListenerList LISTENER_LIST
    classNode.fields.add(new FieldNode(ACC_PRIVATE | ACC_STATIC, "LISTENER_LIST", listDesc, null, null));
    /*Add:
         *      public <init>()
         *      {
         *              super();
         *      }
         */
    if (!hasDefaultCtr) {
        MethodNode method = new MethodNode(ACC_PUBLIC, "<init>", voidDesc, null, null);
        method.instructions.add(new VarInsnNode(ALOAD, 0));
        method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "<init>", voidDesc, false));
        method.instructions.add(new InsnNode(RETURN));
        classNode.methods.add(method);
    }
    /*Add:
         *      protected void setup()
         *      {
         *              super.setup();
         *              if (LISTENER_LIST != NULL)
         *              {
         *                      return;
         *              }
         *              LISTENER_LIST = new ListenerList(super.getListenerList());
         *      }
         */
    MethodNode method = new MethodNode(ACC_PROTECTED, "setup", voidDesc, null, null);
    method.instructions.add(new VarInsnNode(ALOAD, 0));
    method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "setup", voidDesc, false));
    method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
    LabelNode initListener = new LabelNode();
    method.instructions.add(new JumpInsnNode(IFNULL, initListener));
    method.instructions.add(new InsnNode(RETURN));
    method.instructions.add(initListener);
    method.instructions.add(new FrameNode(F_SAME, 0, null, 0, null));
    method.instructions.add(new TypeInsnNode(NEW, tList.getInternalName()));
    method.instructions.add(new InsnNode(DUP));
    method.instructions.add(new VarInsnNode(ALOAD, 0));
    method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tSuper.getInternalName(), "getListenerList", listDescM, false));
    method.instructions.add(new MethodInsnNode(INVOKESPECIAL, tList.getInternalName(), "<init>", getMethodDescriptor(VOID_TYPE, tList), false));
    method.instructions.add(new FieldInsnNode(PUTSTATIC, classNode.name, "LISTENER_LIST", listDesc));
    method.instructions.add(new InsnNode(RETURN));
    classNode.methods.add(method);
    /*Add:
         *      public ListenerList getListenerList()
         *      {
         *              return this.LISTENER_LIST;
         *      }
         */
    method = new MethodNode(ACC_PUBLIC, "getListenerList", listDescM, null, null);
    method.instructions.add(new FieldInsnNode(GETSTATIC, classNode.name, "LISTENER_LIST", listDesc));
    method.instructions.add(new InsnNode(ARETURN));
    classNode.methods.add(method);
    return true;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) FrameNode(org.objectweb.asm.tree.FrameNode) FieldNode(org.objectweb.asm.tree.FieldNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) AnnotationNode(org.objectweb.asm.tree.AnnotationNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) Event(net.minecraftforge.fml.common.eventhandler.Event) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 3 with AnnotationNode

use of org.objectweb.asm.tree.AnnotationNode in project MinecraftForge by MinecraftForge.

the class SideTransformer method remove.

private boolean remove(List<AnnotationNode> anns, String side) {
    if (anns == null) {
        return false;
    }
    for (AnnotationNode ann : anns) {
        if (ann.desc.equals(Type.getDescriptor(SideOnly.class))) {
            if (ann.values != null) {
                for (int x = 0; x < ann.values.size() - 1; x += 2) {
                    Object key = ann.values.get(x);
                    Object value = ann.values.get(x + 1);
                    if (key instanceof String && key.equals("value")) {
                        if (value instanceof String[]) {
                            if (!((String[]) value)[1].equals(side)) {
                                return true;
                            }
                        }
                    }
                }
            }
        }
    }
    return false;
}
Also used : AnnotationNode(org.objectweb.asm.tree.AnnotationNode) SideOnly(net.minecraftforge.fml.relauncher.SideOnly)

Example 4 with AnnotationNode

use of org.objectweb.asm.tree.AnnotationNode in project quasar by puniverse.

the class InstrumentMethod method accept.

public void accept(MethodVisitor mv, boolean hasAnnotation) {
    db.log(LogLevel.INFO, "Instrumenting method %s:%s#%s%s", sourceName, className, mn.name, mn.desc);
    if (mn.name.charAt(0) == '<')
        throw new UnableToInstrumentException("special method", className, mn.name, mn.desc);
    collectCallsites();
    final boolean skipInstrumentation = canInstrumentationBeSkipped(suspCallsBcis);
    emitInstrumentedAnn(db, mv, mn, sourceName, className, skipInstrumentation, startSourceLine, endSourceLine, suspCallsSourceLines, suspCallsNames, null);
    if (skipInstrumentation) {
        db.log(LogLevel.INFO, "[OPTIMIZE] Skipping instrumentation for method %s:%s#%s%s", sourceName, className, mn.name, mn.desc);
        // Dump
        mn.accept(mv);
        return;
    }
    // Else instrument
    // Must be called first, sets flags & state used below
    collectCodeBlocks();
    //noinspection ConstantConditions
    final boolean handleProxyInvocations = HANDLE_PROXY_INVOCATIONS && callsSuspendableSupers;
    mv.visitCode();
    Label lMethodStart = new Label();
    Label lMethodStart2 = new Label();
    Label lMethodEnd = new Label();
    Label lCatchSEE = new Label();
    Label lCatchUTE = new Label();
    Label lCatchAll = new Label();
    Label[] lMethodCalls = new Label[numCodeBlocks - 1];
    Label[][] refInvokeTryCatch;
    for (int i = 1; i < numCodeBlocks; i++) lMethodCalls[i - 1] = new Label();
    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue);
    //        if (verifyInstrumentation) {
    //            mv.visitInsn(Opcodes.ICONST_0);
    //            mv.visitVarInsn(Opcodes.ISTORE, lvarSuspendableCalled);
    //        }
    mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchSEE, SUSPEND_EXECUTION_NAME);
    mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchSEE, RUNTIME_SUSPEND_EXECUTION_NAME);
    if (handleProxyInvocations)
        mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchUTE, UNDECLARED_THROWABLE_NAME);
    // Prepare visitTryCatchBlocks for InvocationTargetException.
    // With reflective invocations, the SuspendExecution exception will be wrapped in InvocationTargetException. We need to catch it and unwrap it.
    // Note that the InvocationTargetException will be regenrated on every park, adding further overhead on top of the reflective call.
    // This must be done here, before all other visitTryCatchBlock, because the exception's handler
    // will be matched according to the order of in which visitTryCatchBlock has been called. Earlier calls take precedence.
    refInvokeTryCatch = new Label[numCodeBlocks - 1][];
    for (int i = 1; i < numCodeBlocks; i++) {
        final FrameInfo fi = codeBlocks[i];
        final AbstractInsnNode in = mn.instructions.get(fi.endInstruction);
        if (mn.instructions.get(fi.endInstruction) instanceof MethodInsnNode) {
            MethodInsnNode min = (MethodInsnNode) in;
            if (isReflectInvocation(min.owner, min.name)) {
                Label[] ls = new Label[3];
                for (int k = 0; k < 3; k++) ls[k] = new Label();
                refInvokeTryCatch[i - 1] = ls;
                mv.visitTryCatchBlock(ls[0], ls[1], ls[2], "java/lang/reflect/InvocationTargetException");
            }
        }
    }
    // Output try-catch blocks
    for (final Object o : mn.tryCatchBlocks) {
        final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
        if (// we allow catch of SuspendExecution only in methods annotated with @Suspendable and in lambda-generated ones.
        SUSPEND_EXECUTION_NAME.equals(tcb.type) && !hasAnnotation && !mn.name.startsWith(Classes.LAMBDA_METHOD_PREFIX))
            throw new UnableToInstrumentException("catch for SuspendExecution", className, mn.name, mn.desc);
        if (// we allow catch of SuspendExecution in method annotated with @Suspendable.
        handleProxyInvocations && UNDECLARED_THROWABLE_NAME.equals(tcb.type))
            throw new UnableToInstrumentException("catch for UndeclaredThrowableException", className, mn.name, mn.desc);
        //          if (INTERRUPTED_EXCEPTION_NAME.equals(tcb.type))
        //              throw new UnableToInstrumentException("catch for " + InterruptedException.class.getSimpleName(), className, mn.name, mn.desc);
        tcb.accept(mv);
    }
    // Output parameter annotations
    if (mn.visibleParameterAnnotations != null)
        dumpParameterAnnotations(mv, mn.visibleParameterAnnotations, true);
    if (mn.invisibleParameterAnnotations != null)
        dumpParameterAnnotations(mv, mn.invisibleParameterAnnotations, false);
    // Output method annotations
    if (mn.visibleAnnotations != null) {
        for (Object o : mn.visibleAnnotations) {
            AnnotationNode an = (AnnotationNode) o;
            an.accept(mv.visitAnnotation(an.desc, true));
        }
    }
    mv.visitTryCatchBlock(lMethodStart, lMethodEnd, lCatchAll, null);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, STACK_NAME, "getStack", "()L" + STACK_NAME + ";", false);
    mv.visitInsn(Opcodes.DUP);
    mv.visitVarInsn(Opcodes.ASTORE, lvarStack);
    // println(mv, "STACK: ", lvarStack);
    // dumpStack(mv);
    // DUAL
    mv.visitJumpInsn(Opcodes.IFNULL, lMethodStart);
    mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
    // we'll assume we have been resumed
    emitStoreResumed(mv, true);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "nextMethodEntry", "()I", false);
    mv.visitTableSwitchInsn(1, numCodeBlocks - 1, lMethodStart2, lMethodCalls);
    mv.visitLabel(lMethodStart2);
    // the following code handles the case of an instrumented method called not as part of a suspendable code path
    // isFirstInStack will return false in that case.
    mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "isFirstInStackOrPushed", "()Z", false);
    // if true
    mv.visitJumpInsn(Opcodes.IFNE, lMethodStart);
    // This will reset the fiber stack local if isFirstStack returns false.
    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.visitVarInsn(Opcodes.ASTORE, lvarStack);
    mv.visitLabel(lMethodStart);
    // no, we have not been resumed
    emitStoreResumed(mv, false);
    dumpCodeBlock(mv, 0, 0);
    // Blocks leading to suspendable calls
    for (int i = 1; i < numCodeBlocks; i++) {
        final FrameInfo fi = codeBlocks[i];
        // Emit instrumented call
        final AbstractInsnNode min = mn.instructions.get(fi.endInstruction);
        final String owner = getMethodOwner(min), name = getMethodName(min), desc = getMethodDesc(min);
        if (isYieldMethod(owner, name)) {
            // special case - call to yield
            if (min.getOpcode() != Opcodes.INVOKESTATIC)
                throw new UnableToInstrumentException("invalid call to suspending method.", className, mn.name, mn.desc);
            final int numYieldArgs = TypeAnalyzer.getNumArguments(desc);
            final boolean yieldReturnsValue = (Type.getReturnType(desc) != Type.VOID_TYPE);
            // we preserve the arguments for the call to yield on the operand stack
            emitStoreState(mv, i, fi, numYieldArgs);
            // we have not been resumed
            emitStoreResumed(mv, false);
            // emitSuspendableCalled(mv);
            // we call the yield method
            min.accept(mv);
            if (yieldReturnsValue)
                // we ignore the returned value...
                mv.visitInsn(Opcodes.POP);
            // we resume AFTER the call
            mv.visitLabel(lMethodCalls[i - 1]);
            final Label afterPostRestore = new Label();
            mv.visitVarInsn(Opcodes.ILOAD, lvarResumed);
            mv.visitJumpInsn(Opcodes.IFEQ, afterPostRestore);
            emitPostRestore(mv);
            mv.visitLabel(afterPostRestore);
            emitRestoreState(mv, i, fi, numYieldArgs);
            if (yieldReturnsValue)
                // ... and replace the returned value with the value of resumed
                mv.visitVarInsn(Opcodes.ILOAD, lvarResumed);
            dumpCodeBlock(mv, i, 1);
        } else {
            final Label lbl = new Label();
            // DUAL
            mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
            mv.visitJumpInsn(Opcodes.IFNULL, lbl);
            // normal case - call to a suspendable method - resume before the call
            emitStoreState(mv, i, fi, 0);
            // we have not been resumed
            emitStoreResumed(mv, false);
            // emitPreemptionPoint(mv, PREEMPTION_CALL);
            mv.visitLabel(lMethodCalls[i - 1]);
            emitRestoreState(mv, i, fi, 0);
            // DUAL
            mv.visitLabel(lbl);
            if (isReflectInvocation(owner, name)) {
                // We catch the InvocationTargetException and unwrap it if it wraps a SuspendExecution exception.
                Label[] ls = refInvokeTryCatch[i - 1];
                final Label startTry = ls[0];
                final Label endTry = ls[1];
                final Label startCatch = ls[2];
                final Label endCatch = new Label();
                final Label notSuspendExecution = new Label();
                // mv.visitTryCatchBlock(startTry, endTry, startCatch, "java/lang/reflect/InvocationTargetException");
                // try {
                mv.visitLabel(startTry);
                //   method.invoke()
                min.accept(mv);
                // save return value
                mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue);
                // }
                mv.visitLabel(endTry);
                mv.visitJumpInsn(Opcodes.GOTO, endCatch);
                // catch(InvocationTargetException ex) {
                mv.visitLabel(startCatch);
                mv.visitInsn(Opcodes.DUP);
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;", false);
                mv.visitTypeInsn(Opcodes.INSTANCEOF, SUSPEND_EXECUTION_NAME);
                mv.visitJumpInsn(Opcodes.IFEQ, notSuspendExecution);
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;", false);
                mv.visitLabel(notSuspendExecution);
                mv.visitInsn(Opcodes.ATHROW);
                mv.visitLabel(endCatch);
                // restore return value
                mv.visitVarInsn(Opcodes.ALOAD, lvarInvocationReturnValue);
                dumpCodeBlock(mv, i, 1);
            } else {
                // emitSuspendableCalled(mv);
                dumpCodeBlock(mv, i, 0);
            }
        }
    }
    // Emit catchall's catch section
    mv.visitLabel(lMethodEnd);
    if (handleProxyInvocations) {
        mv.visitLabel(lCatchUTE);
        mv.visitInsn(Opcodes.DUP);
        // println(mv, "CTCH: ");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;", false);
        // println(mv, "CAUSE: ");
        mv.visitTypeInsn(Opcodes.INSTANCEOF, SUSPEND_EXECUTION_NAME);
        mv.visitJumpInsn(Opcodes.IFEQ, lCatchAll);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Throwable", "getCause", "()Ljava/lang/Throwable;", false);
        mv.visitJumpInsn(Opcodes.GOTO, lCatchSEE);
    }
    mv.visitLabel(lCatchAll);
    emitPopMethod(mv);
    mv.visitLabel(lCatchSEE);
    // println(mv, "THROW: ");
    // rethrow shared between catchAll and catchSSE
    mv.visitInsn(Opcodes.ATHROW);
    if (mn.localVariables != null) {
        for (Object o : mn.localVariables) ((LocalVariableNode) o).accept(mv);
    }
    // Needed by ASM analysis
    mv.visitMaxs(mn.maxStack + ADD_OPERANDS, mn.maxLocals + NUM_LOCALS + additionalLocals);
    mv.visitEnd();
}
Also used : TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) Label(org.objectweb.asm.Label) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) AnnotationNode(org.objectweb.asm.tree.AnnotationNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode)

Example 5 with AnnotationNode

use of org.objectweb.asm.tree.AnnotationNode in project quasar by puniverse.

the class InstrumentMethod method dumpParameterAnnotations.

private static void dumpParameterAnnotations(MethodVisitor mv, List[] parameterAnnotations, boolean visible) {
    for (int i = 0; i < parameterAnnotations.length; i++) {
        if (parameterAnnotations[i] != null) {
            for (Object o : parameterAnnotations[i]) {
                AnnotationNode an = (AnnotationNode) o;
                an.accept(mv.visitParameterAnnotation(i, an.desc, visible));
            }
        }
    }
}
Also used : AnnotationNode(org.objectweb.asm.tree.AnnotationNode)

Aggregations

AnnotationNode (org.objectweb.asm.tree.AnnotationNode)16 ClassNode (org.objectweb.asm.tree.ClassNode)6 List (java.util.List)4 ClassReader (org.objectweb.asm.ClassReader)4 MethodNode (org.objectweb.asm.tree.MethodNode)4 FieldNode (org.objectweb.asm.tree.FieldNode)3 File (java.io.File)2 Type (org.objectweb.asm.Type)2 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)2 ModContainer (cpw.mods.fml.common.ModContainer)1 ArtifactVersion (cpw.mods.fml.common.versioning.ArtifactVersion)1 DefaultArtifactVersion (cpw.mods.fml.common.versioning.DefaultArtifactVersion)1 VersionRange (cpw.mods.fml.common.versioning.VersionRange)1 FileInputStream (java.io.FileInputStream)1 FileOutputStream (java.io.FileOutputStream)1 FileWriter (java.io.FileWriter)1 IOException (java.io.IOException)1 Array (java.lang.reflect.Array)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1