Search in sources :

Example 71 with LabelNode

use of org.objectweb.asm.tree.LabelNode in project jphp by jphp-compiler.

the class TryCatchCompiler method write.

@Override
public void write(TryStmtToken token) {
    if (token.getBody() == null || token.getBody().getInstructions().isEmpty()) {
        if (token.getFinally() != null)
            expr.write(BodyStmtToken.class, token.getFinally());
        return;
    }
    expr.writeDefineVariables(token.getLocal());
    LabelNode tryStart = expr.writeLabel(node, token.getMeta().getStartLine());
    LabelNode tryEnd = new LabelNode();
    LabelNode catchStart = new LabelNode();
    LabelNode catchEnd = new LabelNode();
    LabelNode returnLabel = new LabelNode();
    method.node.tryCatchBlocks.add(0, new TryCatchBlockNode(tryStart, tryEnd, catchStart, Type.getInternalName(BaseBaseException.class)));
    if (token.getFinally() != null) {
        method.getTryStack().push(new MethodStmtCompiler.TryCatchItem(token, returnLabel));
    }
    expr.write(BodyStmtToken.class, token.getBody());
    if (token.getFinally() != null) {
        method.getTryStack().pop();
    }
    add(tryEnd);
    add(new JumpInsnNode(GOTO, catchEnd));
    add(catchStart);
    LocalVariable exception = method.addLocalVariable("~catch~" + method.nextStatementIndex(BaseException.class), catchStart, BaseBaseException.class);
    exception.setEndLabel(catchEnd);
    expr.makeVarStore(exception);
    LabelNode nextCatch = null;
    int i = 0, size = token.getCatches().size();
    LocalVariable local = null;
    LabelNode catchFail = new LabelNode();
    for (CatchStmtToken _catch : token.getCatches()) {
        if (nextCatch != null) {
            add(nextCatch);
        }
        if (i == size - 1) {
            nextCatch = catchFail;
        } else {
            nextCatch = new LabelNode();
        }
        local = method.getLocalVariable(_catch.getVariable().getName());
        List<FulledNameToken> catchExceptions = _catch.getExceptions();
        LabelNode bodyLabel = new LabelNode();
        LabelNode nextCatchLocal = new LabelNode();
        int j = 0;
        for (FulledNameToken catchException : catchExceptions) {
            if (j > 0) {
                add(nextCatchLocal);
                nextCatchLocal = new LabelNode();
            }
            expr.writePushEnv();
            expr.writeVarLoad(exception);
            expr.writePushConstString(catchException.toName());
            expr.writePushConstString(catchException.toName().toLowerCase());
            expr.writeSysDynamicCall(Environment.class, "__throwCatch", Memory.class, BaseBaseException.class, String.class, String.class);
            expr.writeVarAssign(local, _catch.getVariable(), true, false);
            expr.writePopBoolean();
            add(new JumpInsnNode(IFEQ, j == catchExceptions.size() - 1 ? nextCatch : nextCatchLocal));
            expr.stackPop();
            if (catchExceptions.size() > 1) {
                add(new JumpInsnNode(GOTO, bodyLabel));
            }
            j++;
        }
        if (catchExceptions.size() > 1) {
            add(bodyLabel);
        }
        expr.write(BodyStmtToken.class, _catch.getBody());
        add(new JumpInsnNode(GOTO, catchEnd));
        i++;
    }
    add(catchFail);
    if (token.getFinally() != null) {
        expr.write(BodyStmtToken.class, token.getFinally());
    }
    /*if (method.getTryStack().empty()) {
            expr.writePushEnv();
            expr.writeVarLoad(exception);
            expr.writeSysDynamicCall(Environment.class, "__throwFailedCatch", void.class, BaseException.class);
        } else {*/
    expr.makeVarLoad(exception);
    add(new InsnNode(ATHROW));
    // }
    add(catchEnd);
    if (token.getFinally() != null) {
        LabelNode skip = new LabelNode();
        add(new JumpInsnNode(GOTO, skip));
        // finally for return
        add(returnLabel);
        expr.write(BodyStmtToken.class, token.getFinally());
        if (method.getTryStack().empty()) {
            // all finally blocks are done
            LocalVariable retVar = method.getOrAddLocalVariable("~result~", null, Memory.class);
            expr.writeVarLoad(retVar);
            add(new InsnNode(ARETURN));
            expr.stackPop();
        } else {
            // goto next finally block
            add(new JumpInsnNode(GOTO, method.getTryStack().peek().getReturnLabel()));
        }
        add(skip);
        // other finally
        expr.write(BodyStmtToken.class, token.getFinally());
    }
    expr.writeUndefineVariables(token.getLocal());
    method.prevStatementIndex(BaseBaseException.class);
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) MethodStmtCompiler(org.develnext.jphp.core.compiler.jvm.statement.MethodStmtCompiler) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) CatchStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.CatchStmtToken) BodyStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.BodyStmtToken) FulledNameToken(org.develnext.jphp.core.tokenizer.token.expr.value.FulledNameToken)

Example 72 with LabelNode

use of org.objectweb.asm.tree.LabelNode in project jacoco by jacoco.

the class KotlinWhenFilter method ignoreDefaultBranch.

private static void ignoreDefaultBranch(final AbstractInsnNode switchNode, final IFilterOutput output) {
    final List<LabelNode> labels;
    if (switchNode.getOpcode() == Opcodes.LOOKUPSWITCH) {
        labels = ((LookupSwitchInsnNode) switchNode).labels;
    } else {
        labels = ((TableSwitchInsnNode) switchNode).labels;
    }
    final Set<AbstractInsnNode> newTargets = new HashSet<AbstractInsnNode>();
    for (final LabelNode label : labels) {
        newTargets.add(AbstractMatcher.skipNonOpcodes(label));
    }
    output.replaceBranches(switchNode, newTargets);
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) HashSet(java.util.HashSet)

Example 73 with LabelNode

use of org.objectweb.asm.tree.LabelNode in project evosuite by EvoSuite.

the class BranchPool method registerTableSwitchCases.

private void registerTableSwitchCases(BytecodeInstruction v, TableSwitchInsnNode tableSwitchNode) {
    int num = 0;
    for (int i = tableSwitchNode.min; i <= tableSwitchNode.max; i++) {
        LabelNode targetLabel = (LabelNode) tableSwitchNode.labels.get(num);
        Branch switchBranch = createSwitchCaseBranch(v, i, targetLabel);
        if (!switchBranch.isSwitchCaseBranch() || !switchBranch.isActualCase())
            throw new IllegalStateException("expect created branch to be an actual case branch of a switch");
        num++;
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode)

Example 74 with LabelNode

use of org.objectweb.asm.tree.LabelNode in project evosuite by EvoSuite.

the class BranchPool method registerLookupSwitchCases.

private void registerLookupSwitchCases(BytecodeInstruction v, LookupSwitchInsnNode lookupSwitchNode) {
    for (int i = 0; i < lookupSwitchNode.keys.size(); i++) {
        LabelNode targetLabel = (LabelNode) lookupSwitchNode.labels.get(i);
        Branch switchBranch = createSwitchCaseBranch(v, (Integer) lookupSwitchNode.keys.get(i), targetLabel);
        if (!switchBranch.isSwitchCaseBranch() || !switchBranch.isActualCase())
            throw new IllegalStateException("expect created branch to be an actual case branch of a switch");
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode)

Example 75 with LabelNode

use of org.objectweb.asm.tree.LabelNode in project evosuite by EvoSuite.

the class Instrumenter method wrapMethod.

/**
 * 	public int myMethod(int i)
 *		{
 *			try
 *			{
 *				return _sw_prototype_original_myMethod(i)
 *			}
 *			finally
 *			{
 *				Capturer.enable();
 *			}
 *		}
 *
 * @param classNode
 * @param className
 * @param methodNode
 */
@SuppressWarnings("unchecked")
private MethodNode wrapMethod(final ClassNode classNode, final String className, final MethodNode methodNode) {
    methodNode.maxStack += 4;
    // create wrapper for original method
    final MethodNode wrappingMethodNode = new MethodNode(methodNode.access, methodNode.name, methodNode.desc, methodNode.signature, (String[]) methodNode.exceptions.toArray(new String[methodNode.exceptions.size()]));
    wrappingMethodNode.maxStack = methodNode.maxStack;
    // assign annotations to wrapping method
    wrappingMethodNode.visibleAnnotations = methodNode.visibleAnnotations;
    wrappingMethodNode.visibleParameterAnnotations = methodNode.visibleParameterAnnotations;
    // remove annotations from wrapped method to avoid wrong behavior controlled by annotations
    methodNode.visibleAnnotations = null;
    methodNode.visibleParameterAnnotations = null;
    // rename original method
    methodNode.access = TransformerUtil.modifyVisibility(methodNode.access, Opcodes.ACC_PRIVATE);
    final LabelNode l0 = new LabelNode();
    final LabelNode l1 = new LabelNode();
    final LabelNode l2 = new LabelNode();
    final InsnList wInstructions = wrappingMethodNode.instructions;
    if ("<init>".equals(methodNode.name)) {
        // wrap a constructor
        methodNode.name = WRAP_NAME_PREFIX + "init" + WRAP_NAME_PREFIX;
        // move call to other constructors to new method
        AbstractInsnNode ins = null;
        ListIterator<AbstractInsnNode> iter = methodNode.instructions.iterator();
        // number of invokespecial calls before actual constructor call
        int numInvokeSpecials = 0;
        while (iter.hasNext()) {
            ins = iter.next();
            iter.remove();
            wInstructions.add(ins);
            if (ins instanceof MethodInsnNode) {
                MethodInsnNode mins = (MethodInsnNode) ins;
                if (ins.getOpcode() == Opcodes.INVOKESPECIAL) {
                    if (mins.name.startsWith("<init>")) {
                        if (numInvokeSpecials == 0) {
                            break;
                        } else {
                            numInvokeSpecials--;
                        }
                    }
                }
            } else if (ins instanceof TypeInsnNode) {
                TypeInsnNode typeIns = (TypeInsnNode) ins;
                if (typeIns.getOpcode() == Opcodes.NEW || typeIns.getOpcode() == Opcodes.NEWARRAY) {
                    numInvokeSpecials++;
                }
            }
        }
    } else {
        methodNode.name = WRAP_NAME_PREFIX + methodNode.name;
    }
    int varReturnValue = 0;
    final Type returnType = Type.getReturnType(methodNode.desc);
    if (returnType.equals(Type.VOID_TYPE)) {
        wrappingMethodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, "java/lang/Throwable"));
    } else {
        wrappingMethodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l2, "java/lang/Throwable"));
        if (!TransformerUtil.isStatic(methodNode.access)) {
            // load "this"
            varReturnValue++;
        }
        // consider method arguments to find right variable index
        final Type[] argTypes = Type.getArgumentTypes(methodNode.desc);
        for (int i = 0; i < argTypes.length; i++) {
            varReturnValue++;
            // long/double take two registers
            if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) {
                varReturnValue++;
            }
        }
        // push NULL on the stack and initialize variable for return value for it
        wInstructions.add(new InsnNode(Opcodes.ACONST_NULL));
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, varReturnValue));
    }
    int var = 0;
    // --- L0
    wInstructions.add(l0);
    wInstructions.add(this.addCaptureCall(TransformerUtil.isStatic(methodNode.access), className, wrappingMethodNode.name, wrappingMethodNode.desc, Type.getArgumentTypes(methodNode.desc)));
    if (!TransformerUtil.isStatic(methodNode.access)) {
        // load "this" to call method
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        var++;
    }
    final Type[] argTypes = Type.getArgumentTypes(methodNode.desc);
    for (int i = 0; i < argTypes.length; i++) {
        this.addLoadInsn(wInstructions, argTypes[i], var++);
        // long/double take two registers
        if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) {
            var++;
        }
    }
    if (TransformerUtil.isStatic(methodNode.access)) {
        wInstructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.name, methodNode.name, methodNode.desc));
    } else {
        wInstructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, methodNode.name, methodNode.desc));
    }
    var++;
    if (returnType.equals(Type.VOID_TYPE)) {
        wInstructions.add(new JumpInsnNode(Opcodes.GOTO, l2));
        // --- L1
        wInstructions.add(l1);
        wInstructions.add(new FrameNode(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }));
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, --var));
        this.addCaptureEnableStatement(className, methodNode, wInstructions, -1);
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, var));
        wInstructions.add(new InsnNode(Opcodes.ATHROW));
        // FIXME <--- DUPLICATE CODE
        // --- L2
        wInstructions.add(l2);
        wInstructions.add(new FrameNode(Opcodes.F_SAME, 0, null, 0, null));
        this.addCaptureEnableStatement(className, methodNode, wInstructions, -1);
        wInstructions.add(new InsnNode(Opcodes.RETURN));
    } else {
        // construct store of the wrapped method call's result
        this.addBoxingStmt(wInstructions, returnType);
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, varReturnValue));
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, varReturnValue));
        this.addUnBoxingStmt(wInstructions, returnType);
        final int storeOpcode = returnType.getOpcode(Opcodes.ISTORE);
        // might be only var
        wInstructions.add(new VarInsnNode(storeOpcode, ++var));
        // --- L1
        wInstructions.add(l1);
        this.addCaptureEnableStatement(className, methodNode, wInstructions, varReturnValue);
        // construct load of the wrapped method call's result
        int loadOpcode = returnType.getOpcode(Opcodes.ILOAD);
        wInstructions.add(new VarInsnNode(loadOpcode, var));
        // construct return of the wrapped method call's result
        this.addReturnInsn(wInstructions, returnType);
        // ---- L2
        wInstructions.add(l2);
        wInstructions.add(new FrameNode(Opcodes.F_FULL, 2, new Object[] { className, this.getInternalName(returnType) }, 1, new Object[] { "java/lang/Throwable" }));
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, --var));
        this.addCaptureEnableStatement(className, methodNode, wInstructions, varReturnValue);
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, var));
        wInstructions.add(new InsnNode(Opcodes.ATHROW));
    }
    transformWrapperCalls(methodNode);
    return wrappingMethodNode;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) FrameNode(org.objectweb.asm.tree.FrameNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) InsnList(org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Aggregations

LabelNode (org.objectweb.asm.tree.LabelNode)89 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)37 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)32 Label (org.objectweb.asm.Label)28 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)23 InsnList (org.objectweb.asm.tree.InsnList)22 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)21 InsnNode (org.objectweb.asm.tree.InsnNode)20 MethodNode (org.objectweb.asm.tree.MethodNode)19 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)17 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)16 TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)15 ClassNode (org.objectweb.asm.tree.ClassNode)14 ClassReader (org.objectweb.asm.ClassReader)12 LineNumberNode (org.objectweb.asm.tree.LineNumberNode)10 Type (org.objectweb.asm.Type)8 LocalVariableNode (org.objectweb.asm.tree.LocalVariableNode)8 LinkedList (java.util.LinkedList)6 ArrayList (java.util.ArrayList)5 LookupSwitchInsnNode (org.objectweb.asm.tree.LookupSwitchInsnNode)5