use of org.apache.bcel.generic.InstructionList in project fb-contrib by mebigfatguy.
the class CopiedOverriddenMethod method codeEquals.
/**
* compares two code blocks to see if they are equal with regard to instructions and field accesses
*
* @param child
* the first code block
* @param parent
* the second code block
*
* @return whether the code blocks are the same
*/
private boolean codeEquals(Code child, Code parent) {
if (parent == null) {
return false;
}
byte[] childBytes = child.getCode();
byte[] parentBytes = parent.getCode();
if ((childBytes == null) || (parentBytes == null)) {
return false;
}
if (childBytes.length != parentBytes.length) {
return false;
}
InstructionHandle[] childihs = new InstructionList(childBytes).getInstructionHandles();
InstructionHandle[] parentihs = new InstructionList(parentBytes).getInstructionHandles();
if (childihs.length != parentihs.length) {
return false;
}
for (int i = 0; i < childihs.length; i++) {
InstructionHandle childih = childihs[i];
InstructionHandle parentih = parentihs[i];
Instruction childin = childih.getInstruction();
Instruction parentin = parentih.getInstruction();
if (!childin.getName().equals(parentin.getName())) {
return false;
}
if (childin instanceof FieldInstruction) {
String childFName = ((FieldInstruction) childin).getFieldName(childPoolGen);
String parentFName = ((FieldInstruction) parentin).getFieldName(parentPoolGen);
if (!childFName.equals(parentFName)) {
return false;
}
String childFSig = ((FieldInstruction) childin).getSignature(childPoolGen);
String parentFSig = ((FieldInstruction) parentin).getSignature(parentPoolGen);
if (!childFSig.equals(parentFSig)) {
return false;
}
if (childFSig.startsWith(Values.SIG_QUALIFIED_CLASS_PREFIX) || childFSig.startsWith(Values.SIG_ARRAY_PREFIX)) {
ReferenceType childRefType = ((FieldInstruction) childin).getReferenceType(childPoolGen);
ReferenceType parentRefType = ((FieldInstruction) parentin).getReferenceType(parentPoolGen);
if (!childRefType.getSignature().equals(parentRefType.getSignature())) {
return false;
}
}
} else if (childin instanceof InvokeInstruction) {
String childClassName = ((InvokeInstruction) childin).getClassName(childPoolGen);
String parentClassName = ((InvokeInstruction) parentin).getClassName(parentPoolGen);
if (!childClassName.equals(parentClassName)) {
return false;
}
String childMethodName = ((InvokeInstruction) childin).getMethodName(childPoolGen);
String parentMethodName = ((InvokeInstruction) parentin).getMethodName(parentPoolGen);
if (!childMethodName.equals(parentMethodName)) {
return false;
}
String childSignature = ((InvokeInstruction) childin).getSignature(childPoolGen);
String parentSignature = ((InvokeInstruction) parentin).getSignature(parentPoolGen);
if (!childSignature.equals(parentSignature)) {
return false;
}
} else if (childin instanceof LDC) {
Type childType = ((LDC) childin).getType(childPoolGen);
Type parentType = ((LDC) parentin).getType(parentPoolGen);
if (!childType.equals(parentType)) {
return false;
}
Object childValue = ((LDC) childin).getValue(childPoolGen);
Object parentValue = ((LDC) parentin).getValue(parentPoolGen);
if (childValue instanceof ConstantClass) {
ConstantClass childClass = (ConstantClass) childValue;
ConstantClass parentClass = (ConstantClass) parentValue;
if (!childClass.getBytes(childPoolGen.getConstantPool()).equals(parentClass.getBytes(parentPoolGen.getConstantPool()))) {
return false;
}
} else if (!childValue.equals(parentValue)) {
return false;
}
// TODO: Other Constant types
} else if (childin instanceof LDC2_W) {
Type childType = ((LDC2_W) childin).getType(childPoolGen);
Type parentType = ((LDC2_W) parentin).getType(parentPoolGen);
if (!childType.equals(parentType)) {
return false;
}
Object childValue = ((LDC2_W) childin).getValue(childPoolGen);
Object parentValue = ((LDC2_W) parentin).getValue(parentPoolGen);
if (!childValue.equals(parentValue)) {
return false;
}
} else {
if (!childin.equals(parentin)) {
return false;
}
}
}
return true;
}
use of org.apache.bcel.generic.InstructionList in project jop by jop-devel.
the class FindUsedConstants method find.
private void find(Method method) {
MethodGen mg = new MethodGen(method, clazz.getClassName(), cpool);
InstructionList il = mg.getInstructionList();
InstructionFinder f = new InstructionFinder(il);
// find instructions that access the constant pool
// collect all indices to constants in ClassInfo
String cpInstr = "CPInstruction";
for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
InstructionHandle[] match = (InstructionHandle[]) it.next();
InstructionHandle first = match[0];
CPInstruction ii = (CPInstruction) first.getInstruction();
int idx = ii.getIndex();
Constant co = cpool.getConstant(idx);
int len = 1;
switch(co.getTag()) {
case Constants.CONSTANT_Long:
case Constants.CONSTANT_Double:
len = 2;
break;
}
// we don't need the field references in the cpool anymore
if (co.getTag() != Constants.CONSTANT_Fieldref) {
getCli().addUsedConst(idx, len);
}
// also modify the index!
// Constant cnst = cpool.getConstant(ii.getIndex());
// int newIndex = addConstant(cnst);
//System.out.println(ii+" -> "+newIndex);
// ii.setIndex(newIndex);
}
il.dispose();
CodeExceptionGen[] et = mg.getExceptionHandlers();
for (int i = 0; i < et.length; i++) {
ObjectType ctype = et[i].getCatchType();
if (ctype != null) {
getCli().addUsedConst(cpool.lookupClass(ctype.getClassName()), 1);
}
}
}
use of org.apache.bcel.generic.InstructionList in project jop by jop-devel.
the class InsertSynchronized method synchronize.
private void synchronize(MethodInfo method) {
MethodCode mc = method.getCode();
InstructionList il = mc.getInstructionList();
InstructionFinder f;
// prepend monitorenter (reversed order of opcodes)
il.insert(new MONITORENTER());
if (method.isStatic()) {
// il.insert(new GET_CURRENT_CLASS());
throw new JavaClassFormatError("synchronized on static methods not yet supported");
} else {
il.insert(new ALOAD(0));
}
il.setPositions();
f = new InstructionFinder(il);
// find return instructions and insert monitorexit
String retInstr = "ReturnInstruction";
for (Iterator iterator = f.search(retInstr); iterator.hasNext(); ) {
InstructionHandle[] match = (InstructionHandle[]) iterator.next();
InstructionHandle ih = match[0];
// handle for inserted sequence
InstructionHandle newh;
if (method.isStatic()) {
// il.insert(ih, new GET_CURRENT_CLASS());
throw new JavaClassFormatError("synchronized on static methods not yet supported");
} else {
// TODO this could become a bug if JCopter ever reassigns local variable slots, then
// we could not be sure that slot 0 holds the this reference anymore.. To be on the safe side
// we should check if there is an xSTORE_0 somewhere in the code
newh = il.insert(ih, new ALOAD(0));
}
il.insert(ih, new MONITOREXIT());
// correct jumps
method.getCode().retarget(ih, newh);
}
il.setPositions();
method.compile();
}
use of org.apache.bcel.generic.InstructionList in project jop by jop-devel.
the class ControlFlowGraph method compile.
/**
* Compile the CFG back into an instruction list and store it in the associated
* MethodCode.
* <p>
* We do not order the blocks here, this is a separate optimization
* Also, we do not insert jump instructions if the fallthrough edge of a block does not
* link to the next block in the block list. Instead an error is raised.
* </p>
* TODO create method to insert jump blocks where necessary
*/
public void compile() {
InstructionList il = new InstructionList();
Object[] attributes = { KEY_CFGNODE };
Map<BasicBlock, BasicBlockNode> blockMap = buildBlockNodeMap();
for (int i = 0; i < blocks.size(); i++) {
BasicBlock bb = blocks.get(i);
BasicBlockNode bbn = blockMap.get(bb);
if (bbn == null) {
// infeasible edges..
continue;
}
for (CFGEdge e : graph.outgoingEdgesOf(bbn)) {
if (e.getKind() != EdgeKind.NEXT_EDGE)
continue;
BasicBlock target = graph.getEdgeTarget(e).getBasicBlock();
// TODO edge targets a SPLIT node, handle correctly ..
if (target == null) {
throw new ControlFlowError("Block " + i + " does fallthrough to a virtual node of type " + ((VirtualNode) graph.getEdgeTarget(e)).getKind() + " in " + methodInfo);
}
if (blocks.get(i + 1) != target) {
throw new ControlFlowError("Block " + i + " does not fall through to the next block in " + methodInfo);
}
}
}
// TODO compile is not yet fully implemented (retarget, exception-handlers, ..)
// methodInfo.getCode().setInstructionList(il);
}
use of org.apache.bcel.generic.InstructionList in project jop by jop-devel.
the class InstructionInterpreter method interpret.
public void interpret(boolean initialize) {
InstructionList il = methodInfo.getCode().getInstructionList(true, false);
InstructionHandle entry = il.getStart();
Map<InstructionHandle, T> start = new HashMap<InstructionHandle, T>();
start.put(entry, initialize ? analysis.initial(entry) : analysis.bottom());
// start at exception handler entries too?
if (startAtExceptionHandlers) {
for (CodeExceptionGen eg : methodInfo.getCode().getExceptionHandlers()) {
InstructionHandle ih = eg.getHandlerPC();
start.put(ih, initialize ? analysis.initial(eg) : analysis.bottom());
}
}
interpret(il, start, initialize);
}
Aggregations