Search in sources :

Example 31 with AbstractInsnNode

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

the class ImplicitElseTransformer method transformFieldInsnNode.

/* (non-Javadoc)
	 * @see org.evosuite.instrumentation.MethodNodeTransformer#transformFieldInsnNode(org.objectweb.asm.tree.MethodNode, org.objectweb.asm.tree.FieldInsnNode)
	 */
@SuppressWarnings("unchecked")
@Override
protected AbstractInsnNode transformFieldInsnNode(MethodNode mn, FieldInsnNode fieldNode) {
    if ((fieldNode.getOpcode() == Opcodes.PUTFIELD || fieldNode.getOpcode() == Opcodes.PUTSTATIC) && DescriptorMapping.getInstance().isTransformedOrBooleanField(fieldNode.owner, fieldNode.name, fieldNode.desc)) {
        if (addedInsns.contains(fieldNode))
            return fieldNode;
        // whether we need to pop one or two words
        if (fieldNode.getOpcode() == Opcodes.PUTFIELD) {
            AbstractInsnNode previous = fieldNode.getPrevious();
            while (previous instanceof LineNumberNode || previous instanceof FrameNode || previous.getOpcode() == Opcodes.ICONST_0 || previous.getOpcode() == Opcodes.ICONST_1) previous = previous.getPrevious();
            if (previous.getOpcode() != Opcodes.ALOAD) {
                BooleanTestabilityTransformation.logger.info("Can't handle case of " + previous);
                return fieldNode;
            }
            VarInsnNode varNode = (VarInsnNode) previous;
            if (varNode.var != 0) {
                BooleanTestabilityTransformation.logger.info("Can't handle case of " + previous);
                return fieldNode;
            }
        }
        BooleanTestabilityTransformation.logger.info("Handling PUTFIELD case!");
        // Check if ICONST_0 or ICONST_1 are on the stack
        ControlDependenceGraph cdg = GraphPool.getInstance(this.booleanTestabilityTransformation.classLoader).getCDG(this.booleanTestabilityTransformation.className.replace("/", "."), mn.name + mn.desc);
        int index = mn.instructions.indexOf(fieldNode);
        BooleanTestabilityTransformation.logger.info("Getting bytecode instruction for " + fieldNode.name + "/" + ((FieldInsnNode) mn.instructions.get(index)).name);
        InsnList nodes = mn.instructions;
        ListIterator<AbstractInsnNode> it = nodes.iterator();
        while (it.hasNext()) {
            BytecodeInstruction in = new BytecodeInstruction(this.booleanTestabilityTransformation.classLoader, this.booleanTestabilityTransformation.className, mn.name, 0, 0, it.next());
            BooleanTestabilityTransformation.logger.info(in.toString());
        }
        BytecodeInstruction insn = BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className.replace("/", "."), mn.name + mn.desc, index);
        if (insn == null)
            insn = BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className.replace("/", "."), mn.name + mn.desc, fieldNode);
        // varNode);
        if (insn == null) {
            // TODO: Find out why
            BooleanTestabilityTransformation.logger.info("ERROR: Could not find node");
            return fieldNode;
        }
        if (insn.getASMNode().getOpcode() != fieldNode.getOpcode()) {
            BooleanTestabilityTransformation.logger.info("Found wrong bytecode instruction at this index!");
            BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className, mn.name + mn.desc, fieldNode);
        }
        if (insn.getBasicBlock() == null) {
            BooleanTestabilityTransformation.logger.info("ERROR: Problematic node found");
            return fieldNode;
        }
        Set<ControlDependency> dependencies = insn.getControlDependencies();
        BooleanTestabilityTransformation.logger.info("Found flag assignment: " + insn + ", checking " + dependencies.size() + " control dependencies");
        for (ControlDependency dep : dependencies) {
            if (!addedNodes.contains(dep))
                handleDependency(dep, cdg, mn, fieldNode, insn);
        }
    }
    return fieldNode;
}
Also used : FrameNode(org.objectweb.asm.tree.FrameNode) ControlDependenceGraph(org.evosuite.graphs.cdg.ControlDependenceGraph) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) LineNumberNode(org.objectweb.asm.tree.LineNumberNode) BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnList(org.objectweb.asm.tree.InsnList) ControlDependency(org.evosuite.graphs.cfg.ControlDependency)

Example 32 with AbstractInsnNode

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

the class ImplicitElseTransformer method handleDependency.

private void handleDependency(ControlDependency dependency, ControlDependenceGraph cdg, MethodNode mn, FieldInsnNode varNode, BytecodeInstruction parentLevel) {
    if (addedNodes.contains(dependency))
        return;
    // Get the basic blocks reachable if the dependency would evaluate different
    Set<BasicBlock> blocks = cdg.getAlternativeBlocks(dependency);
    addedNodes.add(dependency);
    Set<ControlDependency> dependencies = dependency.getBranch().getInstruction().getControlDependencies();
    // ControlDependency dep = dependencies.iterator().next();
    for (ControlDependency dep : dependencies) {
        if (!addedNodes.contains(dep) && dep != dependency)
            handleDependency(dep, cdg, mn, varNode, dependency.getBranch().getInstruction());
    }
    // TODO: Need to check that there is an assignment in every alternative path through CDG
    boolean hasAssignment = false;
    for (BasicBlock block : blocks) {
        // If this block also assigns a value to the same variable
        for (BytecodeInstruction instruction : block) {
            if (instruction.getASMNode().getOpcode() == Opcodes.PUTFIELD || instruction.getASMNode().getOpcode() == Opcodes.PUTSTATIC) {
                FieldInsnNode otherFieldNode = (FieldInsnNode) instruction.getASMNode();
                FieldInsnNode thisFieldNode = varNode;
                if (otherFieldNode.owner.equals(thisFieldNode.owner) && otherFieldNode.name.equals(thisFieldNode.name)) {
                    hasAssignment = true;
                    break;
                }
            }
        }
        if (hasAssignment) {
            break;
        }
    }
    if (!hasAssignment) {
        if (dependency.getBranch().getInstruction().isSwitch()) {
            BooleanTestabilityTransformation.logger.warn("Don't know how to handle Switches yet");
            return;
        }
        TransformationStatistics.transformedImplicitElse();
        JumpInsnNode jumpNode = (JumpInsnNode) dependency.getBranch().getInstruction().getASMNode();
        FieldInsnNode newLoad = new FieldInsnNode(varNode.getOpcode() == Opcodes.PUTSTATIC ? Opcodes.GETSTATIC : Opcodes.GETFIELD, varNode.owner, varNode.name, varNode.desc);
        FieldInsnNode newStore = new FieldInsnNode(varNode.getOpcode(), varNode.owner, varNode.name, varNode.desc);
        AbstractInsnNode newOwnerLoad1 = null;
        AbstractInsnNode newOwnerLoad2 = null;
        if (varNode.getOpcode() == Opcodes.PUTFIELD) {
            // Need to copy the bloody owner
            // Check for VarInsn
            // if (varNode.getPrevious().getOpcode() == Opcodes.ALOAD) {
            newOwnerLoad1 = new VarInsnNode(Opcodes.ALOAD, 0);
            newOwnerLoad2 = new VarInsnNode(Opcodes.ALOAD, 0);
        /*
				} else {
				// Else use helper function
				// Insert DUP and
				logger.info("Wargh");
				System.exit(0);
				fieldOwnerId++;
				InsnNode dupNode = new InsnNode(Opcodes.DUP);
				mn.instructions.insertBefore(varNode, new LdcInsnNode(
				        fieldOwnerId));
				mn.instructions.insertBefore(varNode, dupNode);
				registerInstruction(mn, varNode, dupNode);
				MethodInsnNode storeOwner = new MethodInsnNode(
				        Opcodes.INVOKESTATIC,
				        "org/evosuite/instrumentation/BooleanHelper",
				        "setFieldOwner", "(ILjava/lang/Object;)V");
				mn.instructions.insertBefore(varNode, storeOwner);
				registerInstruction(mn, varNode, storeOwner);
				newOwnerLoad1 = new MethodInsnNode(Opcodes.INVOKESTATIC,
				        "org/evosuite/instrumentation/BooleanHelper",
				        "getFieldOwner", "(I)Ljava/lang/Object;");
				newOwnerLoad2 = new MethodInsnNode(Opcodes.INVOKESTATIC,
				        "org/evosuite/instrumentation/BooleanHelper",
				        "getFieldOwner", "(I)Ljava/lang/Object;");
				}
				*/
        }
        if (dependency.getBranchExpressionValue()) {
            BooleanTestabilityTransformation.logger.info("Inserting after if");
            // Insert directly after if
            mn.instructions.insert(jumpNode, newStore);
            mn.instructions.insert(jumpNode, newLoad);
            if (newOwnerLoad1 != null) {
                mn.instructions.insert(jumpNode, newOwnerLoad1);
                registerInstruction(mn, varNode, newOwnerLoad1);
            }
            if (newOwnerLoad2 != null) {
                mn.instructions.insert(jumpNode, newOwnerLoad2);
                registerInstruction(mn, varNode, newOwnerLoad2);
            }
            registerInstruction(mn, varNode, newStore);
            registerInstruction(mn, varNode, newLoad);
        } else {
            BooleanTestabilityTransformation.logger.info("Inserting as jump target");
            // Insert as jump target
            LabelNode target = jumpNode.label;
            LabelNode newTarget = new LabelNode(new Label());
            registerInstruction(mn, target, newStore);
            registerInstruction(mn, target, newLoad);
            InsnList assignment = new InsnList();
            assignment.add(new JumpInsnNode(Opcodes.GOTO, target));
            assignment.add(newTarget);
            if (newOwnerLoad1 != null) {
                assignment.add(newOwnerLoad1);
                registerInstruction(mn, target, newOwnerLoad1);
            }
            if (newOwnerLoad2 != null) {
                assignment.add(newOwnerLoad2);
                registerInstruction(mn, target, newOwnerLoad2);
            }
            assignment.add(newLoad);
            assignment.add(newStore);
            jumpNode.label = newTarget;
            mn.instructions.insertBefore(target, assignment);
        }
        addedInsns.add(newStore);
        addedInsns.add(newLoad);
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) BasicBlock(org.evosuite.graphs.cfg.BasicBlock) Label(org.objectweb.asm.Label) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnList(org.objectweb.asm.tree.InsnList) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) ControlDependency(org.evosuite.graphs.cfg.ControlDependency)

Example 33 with AbstractInsnNode

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

the class StringTransformation method transformMethod.

/**
 * <p>
 * transformMethod
 * </p>
 *
 * @param mn
 *            a {@link org.objectweb.asm.tree.MethodNode} object.
 * @return a boolean.
 */
public boolean transformMethod(MethodNode mn) {
    boolean changed = transformStrings(mn);
    if (changed) {
        try {
            mn.maxStack++;
            Analyzer a = new Analyzer(new StringBooleanInterpreter());
            a.analyze(cn.name, mn);
            Frame[] frames = a.getFrames();
            AbstractInsnNode node = mn.instructions.getFirst();
            boolean done = false;
            while (!done) {
                if (node == mn.instructions.getLast())
                    done = true;
                AbstractInsnNode next = node.getNext();
                int index = mn.instructions.indexOf(node);
                if (index >= frames.length)
                    break;
                Frame current = frames[index];
                if (current == null)
                    break;
                int size = current.getStackSize();
                if (node.getOpcode() == Opcodes.IFNE) {
                    JumpInsnNode branch = (JumpInsnNode) node;
                    if (current.getStack(size - 1) == StringBooleanInterpreter.STRING_BOOLEAN || isStringMethod(node.getPrevious())) {
                        logger.info("IFNE -> IFGT");
                        branch.setOpcode(Opcodes.IFGT);
                    }
                } else if (node.getOpcode() == Opcodes.IFEQ) {
                    JumpInsnNode branch = (JumpInsnNode) node;
                    if (current.getStack(size - 1) == StringBooleanInterpreter.STRING_BOOLEAN || isStringMethod(node.getPrevious())) {
                        logger.info("IFEQ -> IFLE");
                        branch.setOpcode(Opcodes.IFLE);
                    }
                } else if (node.getOpcode() == Opcodes.IF_ICMPEQ) {
                    JumpInsnNode branch = (JumpInsnNode) node;
                    if (current.getStack(size - 2) == StringBooleanInterpreter.STRING_BOOLEAN || isStringMethod(node.getPrevious().getPrevious())) {
                        if (node.getPrevious().getOpcode() == Opcodes.ICONST_0) {
                            branch.setOpcode(Opcodes.IFLE);
                            mn.instructions.remove(node.getPrevious());
                        } else if (node.getPrevious().getOpcode() == Opcodes.ICONST_1) {
                            branch.setOpcode(Opcodes.IFGT);
                            mn.instructions.remove(node.getPrevious());
                        }
                    }
                } else if (node.getOpcode() == Opcodes.IF_ICMPNE) {
                    JumpInsnNode branch = (JumpInsnNode) node;
                    if (current.getStack(size - 2) == StringBooleanInterpreter.STRING_BOOLEAN || isStringMethod(node.getPrevious().getPrevious())) {
                        if (node.getPrevious().getOpcode() == Opcodes.ICONST_0) {
                            branch.setOpcode(Opcodes.IFGT);
                            mn.instructions.remove(node.getPrevious());
                        } else if (node.getPrevious().getOpcode() == Opcodes.ICONST_1) {
                            branch.setOpcode(Opcodes.IFLE);
                            mn.instructions.remove(node.getPrevious());
                        }
                    }
                } else if (node.getOpcode() == Opcodes.IRETURN) {
                    if (current.getStack(size - 1) == StringBooleanInterpreter.STRING_BOOLEAN || isStringMethod(node.getPrevious())) {
                        logger.info("IFEQ -> IFLE");
                        MethodInsnNode n = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "intToBoolean", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] { Type.INT_TYPE }), false);
                        mn.instructions.insertBefore(node, n);
                    }
                }
                node = next;
            }
        } catch (Exception e) {
            logger.warn("EXCEPTION DURING STRING TRANSFORMATION: " + e);
            return changed;
        }
    }
    return changed;
}
Also used : Frame(org.objectweb.asm.tree.analysis.Frame) Type(org.objectweb.asm.Type) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) Analyzer(org.objectweb.asm.tree.analysis.Analyzer) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode)

Example 34 with AbstractInsnNode

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

the class ReplaceVariable method getLocalReplacements.

private Map<String, InsnList> getLocalReplacements(MethodNode mn, String desc, AbstractInsnNode node, Frame frame) {
    Map<String, InsnList> replacements = new HashMap<String, InsnList>();
    // if (desc.equals("I"))
    // return replacements;
    int otherNum = -1;
    if (node instanceof VarInsnNode) {
        VarInsnNode vNode = (VarInsnNode) node;
        otherNum = vNode.var;
    }
    if (otherNum == -1)
        return replacements;
    int currentId = mn.instructions.indexOf(node);
    logger.info("Looking for replacements at position " + currentId + " of variable " + otherNum + " of type " + desc);
    for (Object v : mn.localVariables) {
        LocalVariableNode localVar = (LocalVariableNode) v;
        int startId = mn.instructions.indexOf(localVar.start);
        int endId = mn.instructions.indexOf(localVar.end);
        logger.info("Checking local variable " + localVar.name + " of type " + localVar.desc + " at index " + localVar.index);
        if (!localVar.desc.equals(desc))
            logger.info("- Types do not match");
        if (localVar.index == otherNum)
            logger.info("- Replacement = original");
        if (currentId < startId)
            logger.info("- Out of scope (start)");
        if (currentId > endId)
            logger.info("- Out of scope (end)");
        BasicValue newValue = (BasicValue) frame.getLocal(localVar.index);
        if (newValue == BasicValue.UNINITIALIZED_VALUE)
            logger.info("- Not initialized");
        if (localVar.desc.equals(desc) && localVar.index != otherNum && currentId >= startId && currentId <= endId && newValue != BasicValue.UNINITIALIZED_VALUE) {
            logger.info("Adding local variable " + localVar.name + " of type " + localVar.desc + " at index " + localVar.index + ",  " + startId + "-" + endId + ", " + currentId);
            InsnList list = new InsnList();
            if (node.getOpcode() == Opcodes.GETFIELD) {
                // Remove field owner from stack
                list.add(new InsnNode(Opcodes.POP));
            }
            list.add(new VarInsnNode(getLoadOpcode(localVar), localVar.index));
            replacements.put(localVar.name, list);
        }
    }
    return replacements;
}
Also used : FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IincInsnNode(org.objectweb.asm.tree.IincInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) HashMap(java.util.HashMap) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode) BasicValue(org.objectweb.asm.tree.analysis.BasicValue)

Example 35 with AbstractInsnNode

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

the class ReplaceVariable method copy.

/**
 * <p>
 * copy
 * </p>
 *
 * @param orig
 *            a {@link org.objectweb.asm.tree.InsnList} object.
 * @return a {@link org.objectweb.asm.tree.InsnList} object.
 */
public static InsnList copy(InsnList orig) {
    Iterator<?> it = orig.iterator();
    InsnList copy = new InsnList();
    while (it.hasNext()) {
        AbstractInsnNode node = (AbstractInsnNode) it.next();
        if (node instanceof VarInsnNode) {
            VarInsnNode vn = (VarInsnNode) node;
            copy.add(new VarInsnNode(vn.getOpcode(), vn.var));
        } else if (node instanceof FieldInsnNode) {
            FieldInsnNode fn = (FieldInsnNode) node;
            copy.add(new FieldInsnNode(fn.getOpcode(), fn.owner, fn.name, fn.desc));
        } else if (node instanceof InsnNode) {
            if (node.getOpcode() != Opcodes.POP)
                copy.add(new InsnNode(node.getOpcode()));
        } else if (node instanceof LdcInsnNode) {
            copy.add(new LdcInsnNode(((LdcInsnNode) node).cst));
        } else {
            throw new RuntimeException("Unexpected node type: " + node.getClass());
        }
    }
    return copy;
}
Also used : FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IincInsnNode(org.objectweb.asm.tree.IincInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) InsnList(org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Aggregations

AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)185 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)68 MethodNode (org.objectweb.asm.tree.MethodNode)54 InsnList (org.objectweb.asm.tree.InsnList)53 InsnNode (org.objectweb.asm.tree.InsnNode)41 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)38 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)37 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)35 ClassNode (org.objectweb.asm.tree.ClassNode)33 LabelNode (org.objectweb.asm.tree.LabelNode)27 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)26 Test (org.junit.Test)25 Label (org.objectweb.asm.Label)25 ClassReader (org.objectweb.asm.ClassReader)23 TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)23 HashSet (java.util.HashSet)16 Type (org.objectweb.asm.Type)15 Frame (org.objectweb.asm.tree.analysis.Frame)13 ArrayList (java.util.ArrayList)12 TryCatchBlockNode (org.objectweb.asm.tree.TryCatchBlockNode)11