Package org.objectweb.asm.tree

Examples of org.objectweb.asm.tree.MethodInsnNode


            if (f != null) { // reachable ?
                AbstractInsnNode in = mn.instructions.get(i);
                if (in.getType() == AbstractInsnNode.METHOD_INSN || in.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN) {
                    Boolean susp = true;
                    if (in.getType() == AbstractInsnNode.METHOD_INSN) {
                        final MethodInsnNode min = (MethodInsnNode) in;
                        int opcode = min.getOpcode();

                        if (isReflectInvocation(min.owner, min.name))
                            db.log(LogLevel.DEBUG, "Reflective method call at instruction %d is assumed suspendable", i);
                        else if (isMethodHandleInvocation(min.owner, min.name))
                            db.log(LogLevel.DEBUG, "MethodHandle invocation at instruction %d is assumed suspendable", i);
                        else if (isInvocationHandlerInvocation(min.owner, min.name))
                            db.log(LogLevel.DEBUG, "InvocationHandler invocation at instruction %d is assumed suspendable", i);
                        else {
                            SuspendableType st = db.isMethodSuspendable(min.owner, min.name, min.desc, opcode);
                            if (st == SuspendableType.NON_SUSPENDABLE)
                                susp = false;
                            else if (st == null) {
                                db.log(LogLevel.WARNING, "Method not found in class - assuming suspendable: %s#%s%s (at %s#%s)", min.owner, min.name, min.desc, className, mn.name);
                                susp = true;
                            } else if (susp)
                                db.log(LogLevel.DEBUG, "Method call at instruction %d to %s#%s%s is suspendable", i, min.owner, min.name, min.desc);
                            if (st == SuspendableType.SUSPENDABLE_SUPER)
                                this.hasSuspendableSuperCalls = true;
                        }
                    } else { // invoke dynamic
                        final InvokeDynamicInsnNode idin = (InvokeDynamicInsnNode) in;
                        if (idin.bsm.getOwner().equals("java/lang/invoke/LambdaMetafactory")) { // lambda
                            db.log(LogLevel.DEBUG, "Lambda at instruction %d", i);
                            susp = false;
                        } else
                            db.log(LogLevel.DEBUG, "InvokeDynamic Method call at instruction %d to is assumed suspendable", i);
                    }

                    if (susp) {
                        FrameInfo fi = addCodeBlock(f, i);
                        splitTryCatch(fi);
                    } else {
                        if (in.getType() == AbstractInsnNode.METHOD_INSN) {// not invokedynamic
                            final MethodInsnNode min = (MethodInsnNode) in;
                            db.log(LogLevel.DEBUG, "Method call at instruction %d to %s#%s%s is not suspendable", i, min.owner, min.name, min.desc);
                            int blockingId = isBlockingCall(min);
                            if (blockingId >= 0 && !isAllowedToBlock(className, mn.name)) {
                                int mask = 1 << blockingId;
                                if (!db.isAllowBlocking()) {
View Full Code Here


        Label[][] 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");
                }
            }
        }

        for (Object o : mn.tryCatchBlocks) {
            final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
            if (EXCEPTION_NAME.equals(tcb.type) && !hasAnnotation) // we allow catch of SuspendExecution in method annotated with @Suspendable.
                throw new UnableToInstrumentException("catch for SuspendExecution", className, mn.name, mn.desc);
            if (handleProxyInvocations && UNDECLARED_THROWABLE_NAME.equals(tcb.type)) // we allow catch of SuspendExecution in method annotated with @Suspendable.
                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);
        }

        if (mn.visibleParameterAnnotations != null)
            dumpParameterAnnotations(mv, mn.visibleParameterAnnotations, true);

        if (mn.invisibleParameterAnnotations != null)
            dumpParameterAnnotations(mv, mn.invisibleParameterAnnotations, false);

        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 + ";");
        mv.visitInsn(Opcodes.DUP);
        mv.visitVarInsn(Opcodes.ASTORE, lvarStack);

        // println(mv, "STACK: ", lvarStack);
        // dumpStack(mv);
        if (DUAL) {
            mv.visitJumpInsn(Opcodes.IFNULL, lMethodStart);
            mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
        }

        emitStoreResumed(mv, true); // we'll assume we have been resumed

        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "nextMethodEntry", "()I");
        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");
        mv.visitJumpInsn(Opcodes.IFNE, lMethodStart); // if true
        mv.visitInsn(Opcodes.ACONST_NULL);
        mv.visitVarInsn(Opcodes.ASTORE, lvarStack);

        mv.visitLabel(lMethodStart);

        emitStoreResumed(mv, false); // no, we have not been resumed

        dumpCodeBlock(mv, 0, 0);

        for (int i = 1; i < numCodeBlocks; i++) {
            FrameInfo fi = codeBlocks[i];

            MethodInsnNode min = (MethodInsnNode) (mn.instructions.get(fi.endInstruction));
            if (isYieldMethod(min.owner, min.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(min.desc);
                final boolean yieldReturnsValue = (Type.getReturnType(min.desc) != Type.VOID_TYPE);

                emitStoreState(mv, i, fi, numYieldArgs); // we preserve the arguments for the call to yield on the operand stack
                emitStoreResumed(mv, false); // we have not been resumed
                // emitSuspendableCalled(mv);

                min.accept(mv);                              // we call the yield method
                if (yieldReturnsValue)
                    mv.visitInsn(Opcodes.POP);               // we ignore the returned value...
                mv.visitLabel(lMethodCalls[i - 1]);          // we resume AFTER the call

                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)
                    mv.visitVarInsn(Opcodes.ILOAD, lvarResumed); // ... and replace the returned value with the value of resumed

                dumpCodeBlock(mv, i, 1);    // skip the call
            } else {
                final Label lbl = new Label();
                if (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);
                emitStoreResumed(mv, false); // we have not been resumed
                // emitPreemptionPoint(mv, PREEMPTION_CALL);

                mv.visitLabel(lMethodCalls[i - 1]);
                emitRestoreState(mv, i, fi, 0);

                if (DUAL)
                    mv.visitLabel(lbl);

                if (isReflectInvocation(min.owner, min.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");
                    mv.visitLabel(startTry);   // try {
                    min.accept(mv);            //   method.invoke()
                    mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue); // save return value
                    mv.visitLabel(endTry);     // }
                    mv.visitJumpInsn(Opcodes.GOTO, endCatch);
                    mv.visitLabel(startCatch); // catch(InvocationTargetException ex) {
                    mv.visitInsn(Opcodes.DUP);
View Full Code Here

                        db.log(LogLevel.WARNING, "Method %s#%s%s contains synchronization", className, mn.name, mn.desc);
                    }
                    break;

                case Opcodes.INVOKESPECIAL:
                    MethodInsnNode min = (MethodInsnNode) ins;
                    if ("<init>".equals(min.name)) {
                        int argSize = TypeAnalyzer.getNumArguments(min.desc);
                        Frame frame = frames[i];
                        int stackIndex = frame.getStackSize() - argSize - 1;
                        Value thisValue = frame.getStack(stackIndex);
View Full Code Here

        for (int i = 0; i < numIns; i++) {
            Frame f = frames[i];
            if (f != null) { // reachable ?
                AbstractInsnNode in = mn.instructions.get(i);
                if (in.getType() == AbstractInsnNode.METHOD_INSN) {
                    MethodInsnNode min = (MethodInsnNode) in;
                    int opcode = min.getOpcode();
                    Boolean susp = db.isMethodSuspendable(min.owner, min.name, min.desc, opcode);
                    if(susp == null) {
                        db.log(LogLevel.WARNING, "Method not found in class - assuming suspendable: %s#%s%s", min.owner, min.name, min.desc);
                        susp = true;
                    }
View Full Code Here

        dumpCodeBlock(mv, 0, 0);

        for (int i = 1; i < numCodeBlocks; i++) {
            FrameInfo fi = codeBlocks[i];

            MethodInsnNode min = (MethodInsnNode) (mn.instructions.get(fi.endInstruction));
            if (isYieldMethod(min.owner, min.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(min.desc);
                final boolean yieldReturnsValue = (Type.getReturnType(min.desc) != Type.VOID_TYPE);

                emitStoreState(mv, i, fi, numYieldArgs); // we preserve the arguments for the call to yield on the operand stack
                emitStoreResumed(mv, false); // we have not been resumed

                min.accept(mv);                              // we call the yield method
                if (yieldReturnsValue)
                    mv.visitInsn(Opcodes.POP);               // we ignore the returned value...
                mv.visitLabel(lMethodCalls[i - 1]);          // we resume AFTER the call

                final Label afterPostRestore = new Label();
View Full Code Here

                        db.log(LogLevel.WARNING, "Method %s#%s%s contains synchronisation", className, mn.name, mn.desc);
                    }
                    break;

                case Opcodes.INVOKESPECIAL:
                    MethodInsnNode min = (MethodInsnNode) ins;
                    if ("<init>".equals(min.name)) {
                        int argSize = TypeAnalyzer.getNumArguments(min.desc);
                        Frame frame = frames[i];
                        int stackIndex = frame.getStackSize() - argSize - 1;
                        Value thisValue = frame.getStack(stackIndex);
View Full Code Here

        }
        current = current.getPrevious();
        InsnList toAdd = new InsnList();
        toAdd.add(new VarInsnNode(Opcodes.ALOAD, 0));
        toAdd.add(new VarInsnNode(Opcodes.ALOAD, 1));
        toAdd.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "logisticspipes/proxy/buildcraft/BCPipeWireHooks", "updateSignalStateForColor", "(Lbuildcraft/transport/Pipe;Lbuildcraft/api/transport/PipeWire;)V"));
        toAdd.add(getLabelNode(new Label()));
        m.instructions.insert(current, toAdd);
      }
      if(m.name.equals("readNearbyPipesSignal")) {
        MethodNode mv = new MethodNode(Opcodes.ASM4, m.access, m.name, m.desc, m.signature, m.exceptions.toArray(new String[0])) {
          boolean handled = false;
          @Override
          public void visitInsn(int opcode) {
            if(!handled) {
              handled = true;
              super.visitVarInsn(Opcodes.ALOAD, 0);
              super.visitVarInsn(Opcodes.ALOAD, 1);
              super.visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/proxy/buildcraft/BCPipeWireHooks", "readNearbyPipesSignal_Pre", "(Lbuildcraft/transport/Pipe;Lbuildcraft/api/transport/PipeWire;)Z");
            } else {
              super.visitInsn(opcode);
            }
          }
        };

        m.accept(mv);
       
        InsnList list = mv.instructions;
        AbstractInsnNode current = list.getLast();
        while(!(current instanceof InsnNode && ((InsnNode)current).getOpcode() == Opcodes.RETURN)) {
          current = current.getPrevious();
        }
        current = current.getPrevious();
        InsnList toAdd = new InsnList();
        toAdd.add(new VarInsnNode(Opcodes.ALOAD, 0));
        toAdd.add(new VarInsnNode(Opcodes.ALOAD, 1));
        toAdd.add(new VarInsnNode(Opcodes.ILOAD, 2));
        toAdd.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "logisticspipes/proxy/buildcraft/BCPipeWireHooks", "readNearbyPipesSignal_Post", "(Lbuildcraft/transport/Pipe;Lbuildcraft/api/transport/PipeWire;Z)V"));
        toAdd.add(getLabelNode(new Label()));
        mv.instructions.insert(current, toAdd);
       
        node.methods.set(node.methods.indexOf(m), mv);
      }
View Full Code Here

            Frame f = frames[i];
            if (f != null) { // reachable ?
                AbstractInsnNode in = mn.instructions.get(i);
                if (in.getType() == AbstractInsnNode.METHOD_INSN || in.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN) {
                    Boolean susp = true;
                    MethodInsnNode min = null;
                    if (in.getType() == AbstractInsnNode.METHOD_INSN) {
                        min = (MethodInsnNode) in;
                        int opcode = min.getOpcode();

                        if (isReflectInvocation(min.owner, min.name))
                            db.log(LogLevel.DEBUG, "Reflective method call at instruction %d is assumed suspendable", i);
                        else if (isMethodHandleInvocation(min.owner, min.name))
                            db.log(LogLevel.DEBUG, "MethodHandle invocation at instruction %d is assumed suspendable", i);
View Full Code Here

        // 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.
        Label[][] refInvokeTryCatch = new Label[numCodeBlocks - 1][];
        for (int i = 1; i < numCodeBlocks; i++) {
            FrameInfo fi = codeBlocks[i];
            MethodInsnNode min = (MethodInsnNode) (mn.instructions.get(fi.endInstruction));
            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");
            }
        }

        for (Object o : mn.tryCatchBlocks) {
            TryCatchBlockNode tcb = (TryCatchBlockNode) o;
            if (EXCEPTION_NAME.equals(tcb.type) && !hasAnnotation) // we allow catch of SuspendExecution in method annotated with @Suspendable.
                throw new UnableToInstrumentException("catch for " + SUSPEND_EXECUTION_CLASS.getSimpleName(), 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);
        }

        if (mn.visibleParameterAnnotations != null)
            dumpParameterAnnotations(mv, mn.visibleParameterAnnotations, true);

        if (mn.invisibleParameterAnnotations != null)
            dumpParameterAnnotations(mv, mn.invisibleParameterAnnotations, false);

        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 + ";");
        mv.visitInsn(Opcodes.DUP);
        mv.visitVarInsn(Opcodes.ASTORE, lvarStack);

        if (DUAL) {
            mv.visitJumpInsn(Opcodes.IFNULL, lMethodStart);
            mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
        }

        emitStoreResumed(mv, true); // we'll assume we have been resumed

        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "nextMethodEntry", "()I");
        mv.visitTableSwitchInsn(1, numCodeBlocks - 1, lMethodStart, lMethodCalls);

        mv.visitLabel(lMethodStart);

        emitStoreResumed(mv, false); // no, we have not been resumed

        dumpCodeBlock(mv, 0, 0);

        for (int i = 1; i < numCodeBlocks; i++) {
            FrameInfo fi = codeBlocks[i];

            MethodInsnNode min = (MethodInsnNode) (mn.instructions.get(fi.endInstruction));
            if (isYieldMethod(min.owner, min.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(min.desc);
                final boolean yieldReturnsValue = (Type.getReturnType(min.desc) != Type.VOID_TYPE);

                emitStoreState(mv, i, fi, numYieldArgs); // we preserve the arguments for the call to yield on the operand stack
                emitStoreResumed(mv, false); // we have not been resumed

                min.accept(mv);                              // we call the yield method
                if (yieldReturnsValue)
                    mv.visitInsn(Opcodes.POP);               // we ignore the returned value...
                mv.visitLabel(lMethodCalls[i - 1]);          // we resume AFTER the call

                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)
                    mv.visitVarInsn(Opcodes.ILOAD, lvarResumed); // ... and replace the returned value with the value of resumed

                dumpCodeBlock(mv, i, 1);    // skip the call
            } else {
                final Label lbl = new Label();
                if (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);
                emitStoreResumed(mv, false); // we have not been resumed
                emitPreemptionPoint(mv, PREEMPTION_CALL);

                mv.visitLabel(lMethodCalls[i - 1]);
                emitRestoreState(mv, i, fi, 0);

                if (DUAL)
                    mv.visitLabel(lbl);

                if (isReflectInvocation(min.owner, min.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();

                    // mv.visitTryCatchBlock(startTry, endTry, startCatch, "java/lang/reflect/InvocationTargetException");
                    mv.visitLabel(startTry);   // try {
                    min.accept(mv);            //   method.invoke()
                    mv.visitVarInsn(Opcodes.ASTORE, lvarInvocationReturnValue); // save return value
                    mv.visitLabel(endTry);     // }
                    mv.visitJumpInsn(Opcodes.GOTO, endCatch);
                    mv.visitLabel(startCatch); // catch(InvocationTargetException ex) {
                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/InvocationTargetException", "getCause", "()Ljava/lang/Throwable;");
View Full Code Here

                        db.log(LogLevel.WARNING, "Method %s#%s%s contains synchronisation", className, mn.name, mn.desc);
                    }
                    break;

                case Opcodes.INVOKESPECIAL:
                    MethodInsnNode min = (MethodInsnNode) ins;
                    if ("<init>".equals(min.name)) {
                        int argSize = TypeAnalyzer.getNumArguments(min.desc);
                        Frame frame = frames[i];
                        int stackIndex = frame.getStackSize() - argSize - 1;
                        Value thisValue = frame.getStack(stackIndex);
View Full Code Here

TOP

Related Classes of org.objectweb.asm.tree.MethodInsnNode

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.