Search in sources :

Example 11 with BytecodeInstruction

use of org.evosuite.graphs.cfg.BytecodeInstruction in project evosuite by EvoSuite.

the class ImplicitElseTransformer method handleDependency.

private void handleDependency(ControlDependency dependency, ControlDependenceGraph cdg, MethodNode mn, VarInsnNode 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.ISTORE) {
                VarInsnNode otherVarNode = (VarInsnNode) instruction.getASMNode();
                VarInsnNode thisVarNode = varNode;
                if (otherVarNode.var == thisVarNode.var) {
                    hasAssignment = true;
                    break;
                }
            }
        }
        if (hasAssignment) {
            break;
        }
    }
    if (!hasAssignment) {
        TransformationStatistics.transformedImplicitElse();
        if (dependency.getBranch().getInstruction().isSwitch()) {
            BooleanTestabilityTransformation.logger.warn("Don't know how to handle Switches yet");
            return;
        }
        JumpInsnNode jumpNode = (JumpInsnNode) dependency.getBranch().getInstruction().getASMNode();
        VarInsnNode newStore = new VarInsnNode(Opcodes.ISTORE, varNode.var);
        VarInsnNode newLoad = new VarInsnNode(Opcodes.ILOAD, varNode.var);
        if (dependency.getBranchExpressionValue()) {
            BooleanTestabilityTransformation.logger.info("Inserting else branch directly after if");
            // Insert directly after if
            if (isDefinedBefore(mn, varNode, jumpNode)) {
                mn.instructions.insert(jumpNode, newStore);
                mn.instructions.insert(jumpNode, newLoad);
                registerInstruction(mn, varNode, newStore);
                registerInstruction(mn, varNode, newLoad);
            }
        } else {
            BooleanTestabilityTransformation.logger.info("Inserting else branch as jump target");
            // Insert as jump target
            if (isDefinedBefore(mn, varNode, jumpNode)) {
                LabelNode target = jumpNode.label;
                LabelNode newTarget = new LabelNode(new Label());
                // jumpNode or target?
                registerInstruction(mn, jumpNode.getNext(), newStore);
                registerInstruction(mn, jumpNode.getNext(), newLoad);
                InsnList assignment = new InsnList();
                assignment.add(new JumpInsnNode(Opcodes.GOTO, target));
                assignment.add(newTarget);
                assignment.add(newLoad);
                assignment.add(newStore);
                jumpNode.label = newTarget;
                mn.instructions.insertBefore(target, assignment);
            }
        }
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) BasicBlock(org.evosuite.graphs.cfg.BasicBlock) Label(org.objectweb.asm.Label) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnList(org.objectweb.asm.tree.InsnList) ControlDependency(org.evosuite.graphs.cfg.ControlDependency)

Example 12 with BytecodeInstruction

use of org.evosuite.graphs.cfg.BytecodeInstruction in project evosuite by EvoSuite.

the class ImplicitElseTransformer method registerInstruction.

private void registerInstruction(MethodNode mn, AbstractInsnNode oldValue, AbstractInsnNode newValue) {
    BytecodeInstruction oldInstruction = BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className, mn.name + mn.desc, oldValue);
    BytecodeInstruction instruction = BytecodeInstructionFactory.createBytecodeInstruction(this.booleanTestabilityTransformation.classLoader, this.booleanTestabilityTransformation.className, mn.name + mn.desc, oldInstruction.getInstructionId(), 0, newValue);
    instruction.setBasicBlock(oldInstruction.getBasicBlock());
    BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).registerInstruction(instruction);
}
Also used : BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction)

Example 13 with BytecodeInstruction

use of org.evosuite.graphs.cfg.BytecodeInstruction 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 14 with BytecodeInstruction

use of org.evosuite.graphs.cfg.BytecodeInstruction in project evosuite by EvoSuite.

the class MutationInstrumentation method analyze.

/* (non-Javadoc)
	 * @see org.evosuite.cfg.instrumentation.MethodInstrumentation#analyze(org.objectweb.asm.tree.MethodNode, java.lang.String, java.lang.String, int)
	 */
/**
 * {@inheritDoc}
 */
@SuppressWarnings("unchecked")
@Override
public void analyze(ClassLoader classLoader, MethodNode mn, String className, String methodName, int access) {
    if (methodName.startsWith("<clinit>"))
        return;
    if (methodName.startsWith(ClassResetter.STATIC_RESET))
        return;
    RawControlFlowGraph graph = GraphPool.getInstance(classLoader).getRawCFG(className, methodName);
    Iterator<AbstractInsnNode> j = mn.instructions.iterator();
    getFrames(mn, className);
    boolean constructorInvoked = false;
    if (!methodName.startsWith("<init>"))
        constructorInvoked = true;
    logger.info("Applying mutation operators ");
    int frameIndex = 0;
    int numMutants = 0;
    if (frames.length != mn.instructions.size()) {
        logger.error("Number of frames does not match number number of bytecode instructions: " + frames.length + "/" + mn.instructions.size());
        logger.error("Skipping mutation of method " + className + "." + methodName);
        return;
    }
    // + " vs " + mn.instructions.size();
    while (j.hasNext()) {
        Frame currentFrame = frames[frameIndex++];
        AbstractInsnNode in = j.next();
        if (!constructorInvoked) {
            if (in.getOpcode() == Opcodes.INVOKESPECIAL) {
                if (className.matches(".*\\$\\d+$")) {
                    // so best not mutate the constructor
                    continue;
                }
                MethodInsnNode cn = (MethodInsnNode) in;
                Set<String> superClasses = new HashSet<String>();
                if (DependencyAnalysis.getInheritanceTree() != null && DependencyAnalysis.getInheritanceTree().hasClass(className))
                    superClasses.addAll(DependencyAnalysis.getInheritanceTree().getSuperclasses(className));
                superClasses.add(className);
                String classNameWithDots = ResourceList.getClassNameFromResourcePath(cn.owner);
                if (superClasses.contains(classNameWithDots)) {
                    constructorInvoked = true;
                }
            } else {
                continue;
            }
        }
        boolean inInstrumentation = false;
        for (BytecodeInstruction v : graph.vertexSet()) {
            // If the bytecode is instrumented by EvoSuite, then don't mutate
            if (v.isLabel()) {
                LabelNode labelNode = (LabelNode) v.getASMNode();
                if (labelNode.getLabel() instanceof AnnotatedLabel) {
                    AnnotatedLabel aLabel = (AnnotatedLabel) labelNode.getLabel();
                    if (aLabel.isStartTag()) {
                        inInstrumentation = true;
                    } else {
                        inInstrumentation = false;
                    }
                }
            }
            if (inInstrumentation) {
                continue;
            }
            // If this is in the CFG
            if (in.equals(v.getASMNode())) {
                logger.info(v.toString());
                List<Mutation> mutations = new LinkedList<Mutation>();
                // TODO: More than one mutation operator might apply to the same instruction
                for (MutationOperator mutationOperator : mutationOperators) {
                    if (numMutants++ > Properties.MAX_MUTANTS_PER_METHOD) {
                        logger.info("Reached maximum number of mutants per method");
                        break;
                    }
                    // logger.info("Checking mutation operator on instruction " + v);
                    if (mutationOperator.isApplicable(v)) {
                        logger.info("Applying mutation operator " + mutationOperator.getClass().getSimpleName());
                        mutations.addAll(mutationOperator.apply(mn, className, methodName, v, currentFrame));
                    }
                }
                if (!mutations.isEmpty()) {
                    logger.info("Adding instrumentation for mutation");
                    // InsnList instrumentation = getInstrumentation(in, mutations);
                    addInstrumentation(mn, in, mutations);
                }
            }
            if (numMutants > Properties.MAX_MUTANTS_PER_METHOD) {
                break;
            }
        }
    }
    j = mn.instructions.iterator();
    logger.info("Result of mutation: ");
    while (j.hasNext()) {
        AbstractInsnNode in = j.next();
        logger.info(new BytecodeInstruction(classLoader, className, methodName, 0, 0, in).toString());
    }
    logger.info("Done.");
// mn.maxStack += 3;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) Frame(org.objectweb.asm.tree.analysis.Frame) BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) LinkedList(java.util.LinkedList) RawControlFlowGraph(org.evosuite.graphs.cfg.RawControlFlowGraph) MutationOperator(org.evosuite.instrumentation.mutation.MutationOperator) AnnotatedLabel(org.evosuite.runtime.instrumentation.AnnotatedLabel) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) Mutation(org.evosuite.coverage.mutation.Mutation) HashSet(java.util.HashSet)

Example 15 with BytecodeInstruction

use of org.evosuite.graphs.cfg.BytecodeInstruction in project evosuite by EvoSuite.

the class DefUseInstrumentation method analyze.

/*
	 * (non-Javadoc)
	 * 
	 * @see org.evosuite.cfg.MethodInstrumentation#analyze(org.objectweb
	 * .asm.tree.MethodNode, org.jgrapht.Graph, java.lang.String,
	 * java.lang.String)
	 */
/**
 * {@inheritDoc}
 */
@SuppressWarnings("unchecked")
@Override
public void analyze(ClassLoader classLoader, MethodNode mn, String className, String methodName, int access) {
    RawControlFlowGraph completeCFG = GraphPool.getInstance(classLoader).getRawCFG(className, methodName);
    logger.info("Applying DefUse instrumentation on CFG with " + completeCFG.vertexCount() + " nodes");
    Iterator<AbstractInsnNode> j = mn.instructions.iterator();
    while (j.hasNext()) {
        AbstractInsnNode in = j.next();
        for (BytecodeInstruction v : completeCFG.vertexSet()) {
            if ((ArrayUtil.contains(Properties.CRITERION, Criterion.DEFUSE) || ArrayUtil.contains(Properties.CRITERION, Criterion.ALLDEFS)) && in.equals(v.getASMNode()) && v.isDefUse()) {
                boolean isValidDU = false;
                if (v.isMethodCallOfField()) {
                    // keep track of field method calls, though we do not
                    // know
                    // how to handle them at this point during the analysis
                    // (need complete CCFGs first)
                    isValidDU = DefUsePool.addAsFieldMethodCall(v);
                } else {
                    // keep track of uses
                    if (v.isUse())
                        isValidDU = DefUsePool.addAsUse(v);
                    // keep track of definitions
                    if (v.isDefinition())
                        isValidDU = DefUsePool.addAsDefinition(v) || isValidDU;
                }
                if (isValidDU) {
                    boolean staticContext = v.isStaticDefUse() || ((access & Opcodes.ACC_STATIC) > 0);
                    // adding instrumentation for defuse-coverage
                    InsnList instrumentation = getInstrumentation(v, staticContext, className, methodName, mn);
                    if (instrumentation == null)
                        throw new IllegalStateException("error instrumenting node " + v.toString());
                    if (v.isMethodCallOfField())
                        mn.instructions.insertBefore(v.getASMNode(), instrumentation);
                    else if (v.isArrayStoreInstruction())
                        mn.instructions.insertBefore(v.getSourceOfArrayReference().getASMNode(), instrumentation);
                    else // mn.instructions.insertBefore(v.getSourceOfArrayReference().getASMNode(), instrumentation);
                    if (v.isUse())
                        mn.instructions.insert(v.getASMNode(), instrumentation);
                    else
                        mn.instructions.insertBefore(v.getASMNode(), instrumentation);
                }
            }
        }
    }
}
Also used : BytecodeInstruction(org.evosuite.graphs.cfg.BytecodeInstruction) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnList(org.objectweb.asm.tree.InsnList) RawControlFlowGraph(org.evosuite.graphs.cfg.RawControlFlowGraph)

Aggregations

BytecodeInstruction (org.evosuite.graphs.cfg.BytecodeInstruction)28 RawControlFlowGraph (org.evosuite.graphs.cfg.RawControlFlowGraph)10 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)6 ControlDependency (org.evosuite.graphs.cfg.ControlDependency)5 InsnList (org.objectweb.asm.tree.InsnList)5 HashSet (java.util.HashSet)4 LabelNode (org.objectweb.asm.tree.LabelNode)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 Branch (org.evosuite.coverage.branch.Branch)3 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 CCFGCodeNode (org.evosuite.graphs.ccfg.CCFGCodeNode)2 ControlDependenceGraph (org.evosuite.graphs.cdg.ControlDependenceGraph)2 BasicBlock (org.evosuite.graphs.cfg.BasicBlock)2 ControlFlowEdge (org.evosuite.graphs.cfg.ControlFlowEdge)2 AnnotatedLabel (org.evosuite.runtime.instrumentation.AnnotatedLabel)2 Label (org.objectweb.asm.Label)2 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)2