use of org.apache.bcel.generic.FieldInstruction 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.FieldInstruction in project jop by jop-devel.
the class InlineHelper method prepareInlining.
/**
* Prepare the invokee for inlining into the invokesite, by widening access restrictions or renaming
* methods to prevent incorrect method resolving.
* <p>
* This may change the code of the invokee, so this needs to be done before inlining the code.
* The CFG of the invokee will be removed.
* </p><p>
* This code assumes that {@link #canInline(CallString, InvokeSite, MethodInfo)} returned true for this invoke.
* </p>
*
* @param invoker the method where the code will be inlined to.
* @param invokee the method to inline.
*/
public void prepareInlining(MethodInfo invoker, MethodInfo invokee) {
MethodCode code = invokee.getCode();
InstructionList il = code.getInstructionList();
for (InstructionHandle ih : il.getInstructionHandles()) {
Instruction instr = ih.getInstruction();
if (instr instanceof InvokeInstruction) {
InvokeSite invokeSite = code.getInvokeSite(ih);
MethodRef ref = invokeSite.getInvokeeRef();
MethodInfo method = ref.getMethodInfo();
// we already checked that everything can be resolved
// nothing special to do for invokespecial here (checkInvokeSpecial only skips, no special return codes)
// check what we need to do
CheckResult rs = checkNeedsPublic(invoker, invokee, ref.getClassInfo(), method);
if (rs == CheckResult.NEEDS_PUBLIC) {
makePublic(method);
}
if (rs == CheckResult.NEEDS_PUBLIC_RENAME) {
if (method.isPrivate()) {
// TODO check the class for invokers, change to invokevirtual
} else {
// if the method is package visible, we need to rename all overriding methods
// too (but not methods from subclasses in different packages which do not override this)
// TODO update overriding methods
// TODO need to update all possible call sites
}
makePublic(method);
throw new AppInfoError("Implement me!");
}
} else if (instr instanceof FieldInstruction) {
FieldRef ref = code.getFieldRef(ih);
FieldInfo field = ref.getFieldInfo();
// we already checked that everything can be resolved
// check if fields need to be set to public
CheckResult rs = checkNeedsPublic(invoker, invokee, ref.getClassInfo(), field);
if (rs == CheckResult.NEEDS_PUBLIC) {
makePublic(field);
}
if (rs == CheckResult.NEEDS_PUBLIC_RENAME) {
throw new AppInfoError("Invalid returncode: renaming of fields not required");
}
}
}
}
use of org.apache.bcel.generic.FieldInstruction in project jop by jop-devel.
the class InlineHelper method checkCode.
/**
* check the code of the invoked method if it contains instructions which prevent inlining.
*
* @param invoker the method into which the invokee will be inlined.
* @param invokee the invoked method.
* @return true if the code can be inlined and {@link #prepareInlining(MethodInfo, MethodInfo)} will succeed.
*/
private boolean checkCode(MethodInfo invoker, MethodInfo invokee) {
MethodCode code = invokee.getCode();
// Go through code, check for access to fields and invocations
for (InstructionHandle ih : code.getInstructionList(true, false).getInstructionHandles()) {
Instruction instr = ih.getInstruction();
if (instr instanceof InvokeInstruction) {
InvokeSite invokeSite = code.getInvokeSite(ih);
MethodRef ref = invokeSite.getInvokeeRef();
MethodInfo method = ref.getMethodInfo();
if (method == null) {
// TODO perform basic check on classnames if invoked method must already be public?
return false;
}
// invokespecial is somewhat, well, special..
if (invokeSite.isInvokeSpecial()) {
if (checkInvokeSpecial(invoker, invokee, invokeSite, ref.getClassInfo(), method) == CheckResult.SKIP) {
return false;
}
} else {
// check if fields need to be set to public
if (checkNeedsPublic(invoker, invokee, ref.getClassInfo(), method) == CheckResult.SKIP) {
return false;
}
}
} else if (instr instanceof FieldInstruction) {
FieldRef ref = code.getFieldRef(ih);
FieldInfo field = ref.getFieldInfo();
if (field == null) {
// TODO perform basic check on classnames if field is already public?
return false;
}
// check if fields need to be set to public
if (checkNeedsPublic(invoker, invokee, ref.getClassInfo(), field) == CheckResult.SKIP) {
return false;
}
}
}
return true;
}
use of org.apache.bcel.generic.FieldInstruction in project jop by jop-devel.
the class ValueMapAnalysis method transfer.
public void transfer(Instruction instruction) {
switch(instruction.getOpcode()) {
case Constants.NOP:
break;
case Constants.ACONST_NULL:
values.push(new ValueInfo(Type.NULL));
break;
case Constants.ICONST_M1:
case Constants.ICONST_0:
case Constants.ICONST_1:
case Constants.ICONST_2:
case Constants.ICONST_3:
case Constants.ICONST_4:
case Constants.ICONST_5:
case Constants.BIPUSH:
case Constants.SIPUSH:
{
ConstantPushInstruction instr = (ConstantPushInstruction) instruction;
int value = instr.getValue().intValue();
values.push(new ValueInfo(instr.getType(cpg), new ConstantIntegerInfo(value)));
break;
}
case Constants.LCONST_0:
case Constants.LCONST_1:
{
ConstantPushInstruction instr = (ConstantPushInstruction) instruction;
long value = instr.getValue().longValue();
values.push(new ValueInfo(instr.getType(cpg), new ConstantLongInfo(value)));
break;
}
case Constants.FCONST_0:
case Constants.FCONST_1:
case Constants.FCONST_2:
{
ConstantPushInstruction instr = (ConstantPushInstruction) instruction;
float value = instr.getValue().floatValue();
values.push(new ValueInfo(instr.getType(cpg), new ConstantFloatInfo(value)));
break;
}
case Constants.DCONST_0:
case Constants.DCONST_1:
{
ConstantPushInstruction instr = (ConstantPushInstruction) instruction;
double value = instr.getValue().doubleValue();
values.push(new ValueInfo(instr.getType(cpg), new ConstantDoubleInfo(value)));
break;
}
case Constants.LDC:
case Constants.LDC_W:
case Constants.LDC2_W:
{
CPInstruction instr = (CPInstruction) instruction;
values.push(new ValueInfo(methodInfo.getClassInfo().getConstantInfo(instr.getIndex())));
break;
}
case Constants.ISTORE_0:
case Constants.ISTORE_1:
case Constants.ISTORE_2:
case Constants.ISTORE_3:
case Constants.ISTORE:
case Constants.ASTORE_0:
case Constants.ASTORE_1:
case Constants.ASTORE_2:
case Constants.ASTORE_3:
case Constants.ASTORE:
case Constants.LSTORE_0:
case Constants.LSTORE_1:
case Constants.LSTORE_2:
case Constants.LSTORE_3:
case Constants.LSTORE:
case Constants.DSTORE_0:
case Constants.DSTORE_1:
case Constants.DSTORE_2:
case Constants.DSTORE_3:
case Constants.DSTORE:
case Constants.FSTORE_0:
case Constants.FSTORE_1:
case Constants.FSTORE_2:
case Constants.FSTORE_3:
case Constants.FSTORE:
{
StoreInstruction instr = (StoreInstruction) instruction;
int index = instr.getIndex();
values.setLocalValue(index, values.popValue());
break;
}
case Constants.ILOAD_0:
case Constants.ILOAD_1:
case Constants.ILOAD_2:
case Constants.ILOAD_3:
case Constants.ILOAD:
case Constants.LLOAD_0:
case Constants.LLOAD_1:
case Constants.LLOAD_2:
case Constants.LLOAD_3:
case Constants.LLOAD:
case Constants.FLOAD_0:
case Constants.FLOAD_1:
case Constants.FLOAD_2:
case Constants.FLOAD_3:
case Constants.FLOAD:
case Constants.DLOAD_0:
case Constants.DLOAD_1:
case Constants.DLOAD_2:
case Constants.DLOAD_3:
case Constants.DLOAD:
case Constants.ALOAD_0:
case Constants.ALOAD_1:
case Constants.ALOAD_2:
case Constants.ALOAD_3:
case Constants.ALOAD:
{
LoadInstruction instr = (LoadInstruction) instruction;
int index = instr.getIndex();
values.push(values.getLocalValue(index));
break;
}
case Constants.DUP:
values.push(values.top());
break;
case Constants.DUP_X1:
values.insert(2, values.top());
break;
case Constants.DUP_X2:
values.insert(3, values.top());
case Constants.DUP2:
values.push(values.top(1), false);
values.push(values.top(1), false);
break;
case Constants.DUP2_X1:
values.insert(3, values.top(1));
values.insert(3, values.top(0));
break;
case Constants.DUP2_X2:
values.insert(4, values.top(1));
values.insert(4, values.top(0));
break;
case Constants.POP:
values.pop();
break;
case Constants.POP2:
values.pop();
values.pop();
break;
case Constants.SWAP:
values.insert(1, values.pop());
break;
case Constants.IASTORE:
case Constants.LASTORE:
case Constants.FASTORE:
case Constants.DASTORE:
case Constants.CASTORE:
case Constants.SASTORE:
case Constants.BASTORE:
case Constants.AASTORE:
values.popValue();
values.pop();
values.pop();
break;
case Constants.IALOAD:
case Constants.LALOAD:
case Constants.FALOAD:
case Constants.DALOAD:
case Constants.CALOAD:
case Constants.SALOAD:
case Constants.BALOAD:
case Constants.AALOAD:
{
values.pop();
values.pop();
Type t = ((ArrayInstruction) instruction).getType(cpg);
values.push(new ValueInfo(t));
break;
}
case Constants.IINC:
{
int i = ((IINC) instruction).getIndex();
ValueInfo old = values.getLocalValue(i);
if (old.isConstantValue() && old.getConstantValue() instanceof ConstantIntegerInfo) {
ConstantIntegerInfo value = (ConstantIntegerInfo) old.getConstantValue();
int newval = value.getValue() + ((IINC) instruction).getIncrement();
values.setLocalValue(i, new ValueInfo(new ConstantIntegerInfo(newval)));
} else {
values.setLocalValue(i, new ValueInfo(Type.INT));
}
break;
}
case Constants.IADD:
case Constants.ISUB:
case Constants.IMUL:
case Constants.IDIV:
case Constants.IREM:
case Constants.IAND:
case Constants.IOR:
case Constants.IXOR:
case Constants.ISHL:
case Constants.ISHR:
case Constants.IUSHR:
values.pop();
case Constants.INEG:
values.pop();
values.push(new ValueInfo(Type.INT));
break;
case Constants.FADD:
case Constants.FSUB:
case Constants.FMUL:
case Constants.FDIV:
case Constants.FREM:
values.pop();
case Constants.FNEG:
values.pop();
values.push(new ValueInfo(Type.FLOAT));
break;
case Constants.LADD:
case Constants.LSUB:
case Constants.LMUL:
case Constants.LDIV:
case Constants.LREM:
case Constants.LAND:
case Constants.LOR:
case Constants.LXOR:
values.pop();
values.pop();
case Constants.LNEG:
values.pop();
values.pop();
values.push(new ValueInfo(Type.LONG));
break;
case Constants.DADD:
case Constants.DSUB:
case Constants.DMUL:
case Constants.DDIV:
case Constants.DREM:
values.pop();
values.pop();
case Constants.DNEG:
values.pop();
values.pop();
values.push(new ValueInfo(Type.DOUBLE));
break;
case Constants.LSHL:
case Constants.LSHR:
case Constants.LUSHR:
values.pop();
values.pop();
values.pop();
values.push(new ValueInfo(Type.LONG));
break;
case Constants.I2B:
case Constants.I2C:
case Constants.I2S:
case Constants.I2L:
case Constants.I2F:
case Constants.I2D:
case Constants.L2I:
case Constants.L2F:
case Constants.L2D:
case Constants.F2I:
case Constants.F2L:
case Constants.F2D:
case Constants.D2I:
case Constants.D2L:
case Constants.D2F:
{
values.popValue();
values.push(new ValueInfo(((ConversionInstruction) instruction).getType(cpg)));
break;
}
case Constants.LCMP:
case Constants.DCMPL:
case Constants.DCMPG:
values.pop();
values.pop();
case Constants.FCMPL:
case Constants.FCMPG:
values.pop();
values.pop();
values.push(new ValueInfo(Type.INT));
break;
case Constants.IF_ICMPEQ:
case Constants.IF_ICMPNE:
case Constants.IF_ICMPLT:
case Constants.IF_ICMPGE:
case Constants.IF_ICMPGT:
case Constants.IF_ICMPLE:
case Constants.IF_ACMPEQ:
case Constants.IF_ACMPNE:
values.pop();
case Constants.IFEQ:
case Constants.IFNE:
case Constants.IFLT:
case Constants.IFGE:
case Constants.IFLE:
case Constants.IFGT:
case Constants.IFNULL:
case Constants.IFNONNULL:
values.pop();
break;
case Constants.GOTO:
case Constants.RET:
break;
case Constants.JSR:
// This is of type 'returnAddress'
values.push(new ValueInfo(Type.INT));
break;
case Constants.ARETURN:
case Constants.IRETURN:
case Constants.LRETURN:
case Constants.FRETURN:
case Constants.DRETURN:
case Constants.RETURN:
values.clearStack();
break;
case Constants.LOOKUPSWITCH:
case Constants.TABLESWITCH:
values.pop();
break;
case Constants.GETFIELD:
values.pop();
case Constants.GETSTATIC:
{
FieldInstruction f = (FieldInstruction) instruction;
ConstantFieldInfo field = (ConstantFieldInfo) methodInfo.getClassInfo().getConstantInfo(f.getIndex());
values.push(new ValueInfo(f.getFieldType(cpg), field.getValue()));
break;
}
case Constants.PUTFIELD:
values.pop();
case Constants.PUTSTATIC:
{
FieldInstruction f = (FieldInstruction) instruction;
values.pop(f.getFieldType(cpg).getSize());
break;
}
case Constants.INVOKEVIRTUAL:
case Constants.INVOKEINTERFACE:
case Constants.INVOKESPECIAL:
values.pop();
case Constants.INVOKESTATIC:
{
InvokeInstruction invoke = (InvokeInstruction) instruction;
values.pop(TypeHelper.getNumSlots(invoke.getArgumentTypes(cpg)));
values.push(new ValueInfo(invoke.getReturnType(cpg)));
break;
}
case Constants.MONITORENTER:
case Constants.MONITOREXIT:
values.pop();
break;
case Constants.ATHROW:
ValueInfo ref = values.pop();
values.clearStack();
values.push(ref);
break;
case Constants.CHECKCAST:
break;
case Constants.INSTANCEOF:
values.pop();
values.push(new ValueInfo(Type.INT));
break;
case Constants.NEW:
values.push(new ValueInfo(((NEW) instruction).getType(cpg)));
break;
case Constants.NEWARRAY:
{
Type t = ((NEWARRAY) instruction).getType();
values.push(new ValueInfo(new ArrayType(t, 1)));
break;
}
case Constants.ANEWARRAY:
{
Type t = ((ANEWARRAY) instruction).getType(cpg);
values.push(new ValueInfo(new ArrayType(t, 1)));
break;
}
case Constants.MULTIANEWARRAY:
{
MULTIANEWARRAY instr = (MULTIANEWARRAY) instruction;
values.pop(instr.getDimensions());
values.push(new ValueInfo(new ArrayType(instr.getType(cpg), instr.getDimensions())));
break;
}
case Constants.ARRAYLENGTH:
values.pop();
values.push(new ValueInfo(Type.INT));
break;
default:
throw new AppInfoError("Instruction not supported: " + instruction);
}
}
use of org.apache.bcel.generic.FieldInstruction in project jop by jop-devel.
the class JOPModel method getNativeOpCode.
/* performance hot spot */
public int getNativeOpCode(MethodInfo context, Instruction instr) {
if (isSpecialInvoke(context, instr)) {
INVOKESTATIC isi = (INVOKESTATIC) instr;
String methodName = isi.getMethodName(context.getConstantPoolGen());
return JopInstr.getNative(methodName);
} else if (instr instanceof FieldInstruction) {
FieldInstruction finstr = (FieldInstruction) instr;
Type ftype = finstr.getFieldType(context.getConstantPoolGen());
boolean isRef = ftype instanceof ReferenceType;
boolean isLong = ftype == BasicType.LONG || ftype == BasicType.DOUBLE;
if (finstr instanceof GETSTATIC) {
if (isRef) {
return JopInstr.get("getstatic_ref");
} else if (isLong) {
return JopInstr.get("getstatic_long");
}
} else if (finstr instanceof PUTSTATIC) {
if (isRef) {
if (!com.jopdesign.build.JOPizer.USE_RTTM) {
/* FIXME: This should not be hardcoded? */
return JopInstr.get("putstatic_ref");
}
} else if (isLong) {
return JopInstr.get("putstatic_long");
}
} else if (finstr instanceof GETFIELD) {
if (isRef) {
return JopInstr.get("getfield_ref");
} else if (isLong) {
return JopInstr.get("getfield_long");
}
} else if (finstr instanceof PUTFIELD) {
if (isRef) {
if (!com.jopdesign.build.JOPizer.USE_RTTM) {
/* FIXME: This should not be hardcoded? */
return JopInstr.get("putfield_ref");
}
} else if (isLong) {
return JopInstr.get("putfield_long");
}
}
return instr.getOpcode();
} else {
return instr.getOpcode();
}
}
Aggregations