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;
}
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);
}
}
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;
}
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;
}
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;
}
Aggregations