use of org.apache.bcel.generic.ConstantPushInstruction in project jop by jop-devel.
the class LoopBounds method transfer.
public ContextMap<CallString, Map<Location, ValueMapping>> transfer(InstructionHandle stmt, FlowEdge edge, ContextMap<CallString, Map<Location, ValueMapping>> input, Interpreter<CallString, Map<Location, ValueMapping>> interpreter, Map<InstructionHandle, ContextMap<CallString, Map<Location, ValueMapping>>> state) {
Context context = new Context(input.getContext());
Map<Location, ValueMapping> in = (Map<Location, ValueMapping>) input.get(context.callString);
ContextMap<CallString, Map<Location, ValueMapping>> retval = new ContextMap<CallString, Map<Location, ValueMapping>>(context, new LinkedHashMap<CallString, Map<Location, ValueMapping>>());
Instruction instruction = stmt.getInstruction();
// shortcut for infeasible paths
if (in == null) {
context.stackPtr += instruction.produceStack(context.constPool()) - instruction.consumeStack(context.constPool());
return retval;
}
Map<Location, ValueMapping> result = new LinkedHashMap<Location, ValueMapping>();
retval.put(context.callString, result);
switch(instruction.getOpcode()) {
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;
result = new LinkedHashMap<Location, ValueMapping>(in);
retval.put(context.callString, result);
int value = instr.getValue().intValue();
result.put(new Location(context.stackPtr), new ValueMapping(value));
}
break;
case Constants.ACONST_NULL:
result = in;
retval.put(context.callString, result);
break;
case Constants.LDC:
case Constants.LDC_W:
{
LDC instr = (LDC) instruction;
result = new LinkedHashMap<Location, ValueMapping>(in);
retval.put(context.callString, result);
Type type = instr.getType(context.constPool());
if (type.equals(Type.INT)) {
Integer value = (Integer) instr.getValue(context.constPool());
result.put(new Location(context.stackPtr), new ValueMapping(value));
} else if (type.equals(Type.STRING)) {
String value = (String) instr.getValue(context.constPool());
String name = "char[]";
name += "@" + context.method() + ":" + stmt.getPosition();
result.put(new Location(name + ".length"), new ValueMapping(value.length()));
// System.out.println(name+": \""+value+"\"");
}
}
break;
case Constants.LDC2_W:
result = in;
retval.put(context.callString, result);
break;
case Constants.ISTORE_0:
case Constants.ISTORE_1:
case Constants.ISTORE_2:
case Constants.ISTORE_3:
case Constants.ISTORE:
{
StoreInstruction instr = (StoreInstruction) instruction;
int index = instr.getIndex();
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 1 && l.stackLoc != index) {
result.put(l, in.get(l));
}
if (l.stackLoc == context.stackPtr - 1) {
ValueMapping v = new ValueMapping(in.get(l), true);
if (in.get(l).source == null || in.get(l).source.stackLoc != index) {
v.defscope = ValueMapping.scope;
}
result.put(new Location(index), v);
}
}
}
break;
case Constants.ASTORE_0:
case Constants.ASTORE_1:
case Constants.ASTORE_2:
case Constants.ASTORE_3:
case Constants.ASTORE:
result = in;
retval.put(context.callString, result);
break;
case Constants.LSTORE_0:
case Constants.LSTORE_1:
case Constants.LSTORE_2:
case Constants.LSTORE_3:
case Constants.LSTORE:
// drop top entries to avoid clobbering
filterSet(in, result, context.stackPtr - 2);
break;
case Constants.ILOAD_0:
case Constants.ILOAD_1:
case Constants.ILOAD_2:
case Constants.ILOAD_3:
case Constants.ILOAD:
{
LoadInstruction instr = (LoadInstruction) instruction;
filterSet(in, result, context.stackPtr);
int index = instr.getIndex();
for (Location l : in.keySet()) {
if (l.stackLoc == index) {
ValueMapping m = new ValueMapping(in.get(l), true);
m.source = l;
result.put(new Location(context.stackPtr), m);
}
}
}
break;
case Constants.ALOAD_0:
case Constants.ALOAD_1:
case Constants.ALOAD_2:
case Constants.ALOAD_3:
case Constants.ALOAD:
result = in;
retval.put(context.callString, result);
break;
case Constants.ARRAYLENGTH:
{
filterSet(in, result, context.stackPtr - 1);
DFATool p = interpreter.getDFATool();
Set<String> receivers = p.getReceivers(stmt, context.callString);
Location location = new Location(context.stackPtr - 1);
boolean valid = false;
if (receivers == null) {
System.out.println("no receivers at: " + context.callString.toStringList() + context.method() + stmt);
} else {
for (String arrayName : receivers) {
ValueMapping m = in.get(new Location(arrayName + ".length"));
if (m != null) {
ValueMapping value = new ValueMapping(m, false);
value.join(result.get(location));
result.put(location, value);
valid = true;
}
}
}
if (!valid) {
result.put(new Location(context.stackPtr - 1), new ValueMapping());
}
}
break;
case Constants.PUTFIELD:
{
PUTFIELD instr = (PUTFIELD) instruction;
int fieldSize = instr.getFieldType(context.constPool()).getSize();
for (Location l : in.keySet()) {
if (l.stackLoc >= 0 && l.stackLoc < context.stackPtr - 1 - fieldSize) {
result.put(l, in.get(l));
}
}
// System.out.println(context.stackPtr+","+fieldSize+": "+result);
DFATool p = interpreter.getDFATool();
Set<String> receivers = p.getReceivers(stmt, context.callString);
if (receivers == null) {
warnNoReceiver(context, stmt);
} else {
for (String fieldName : receivers) {
String f = fieldName.substring(fieldName.lastIndexOf("."), fieldName.length());
String strippedName;
if (fieldName.indexOf("@") >= 0) {
strippedName = fieldName.split("@")[0] + f;
} else {
strippedName = fieldName;
}
if (p.containsField(strippedName)) {
for (Location l : in.keySet()) {
if (l.stackLoc < 0 && !receivers.contains(l.heapLoc)) {
result.put(l, in.get(l));
}
if (l.stackLoc == context.stackPtr - 1) {
result.put(new Location(fieldName), new ValueMapping(in.get(l), false));
}
}
}
}
}
}
break;
case Constants.GETFIELD:
{
GETFIELD instr = (GETFIELD) instruction;
filterSet(in, result, context.stackPtr - 1);
DFATool p = interpreter.getDFATool();
Set<String> receivers = p.getReceivers(stmt, context.callString);
Location location = new Location(context.stackPtr - 1);
boolean valid = false;
if (receivers == null) {
warnNoReceiver(context, stmt);
} else {
for (String fieldName : receivers) {
String f = fieldName.substring(fieldName.lastIndexOf("."), fieldName.length());
String strippedName;
if (fieldName.indexOf("@") >= 0) {
strippedName = fieldName.split("@")[0] + f;
} else {
strippedName = fieldName;
}
if (p.containsField(strippedName)) {
for (Location l : in.keySet()) {
if (l.heapLoc.equals(fieldName)) {
ValueMapping value = new ValueMapping(in.get(l), false);
value.join(result.get(location));
result.put(location, value);
valid = true;
}
}
}
}
}
if (!valid && !(instr.getFieldType(context.constPool()) instanceof ReferenceType)) {
result.put(new Location(context.stackPtr - 1), new ValueMapping());
}
}
break;
case Constants.PUTSTATIC:
{
PUTSTATIC instr = (PUTSTATIC) instruction;
int fieldSize = instr.getFieldType(context.constPool()).getSize();
for (Location l : in.keySet()) {
if (l.stackLoc >= 0 && l.stackLoc < context.stackPtr - fieldSize) {
result.put(l, in.get(l));
}
}
DFATool p = interpreter.getDFATool();
Set<String> receivers = p.getReceivers(stmt, context.callString);
for (String fieldName : receivers) {
if (p.containsField(fieldName)) {
for (Location l : in.keySet()) {
if (l.stackLoc < 0 && !receivers.contains(l.heapLoc)) {
result.put(l, in.get(l));
}
if (l.stackLoc == context.stackPtr - 1) {
result.put(new Location(fieldName), new ValueMapping(in.get(l), false));
}
}
}
}
}
break;
case Constants.GETSTATIC:
{
GETSTATIC instr = (GETSTATIC) instruction;
result = new LinkedHashMap<Location, ValueMapping>(in);
retval.put(context.callString, result);
DFATool p = interpreter.getDFATool();
Set<String> receivers = p.getReceivers(stmt, context.callString);
Location location = new Location(context.stackPtr);
boolean valid = false;
for (String fieldName : receivers) {
if (p.containsField(fieldName)) {
for (Location l : in.keySet()) {
if (l.heapLoc.equals(fieldName)) {
ValueMapping value = new ValueMapping(in.get(l), false);
value.join(result.get(location));
result.put(location, value);
valid = true;
}
}
}
}
if (!valid && !(instr.getFieldType(context.constPool()) instanceof ReferenceType)) {
result.put(new Location(context.stackPtr), new ValueMapping());
}
}
break;
case Constants.IASTORE:
case Constants.CASTORE:
case Constants.SASTORE:
case Constants.BASTORE:
{
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 3) {
result.put(l, in.get(l));
}
}
DFATool p = interpreter.getDFATool();
Set<String> receivers = p.getReceivers(stmt, context.callString);
if (receivers == null) {
warnNoReceiver(context, stmt);
break;
}
for (String name : receivers) {
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
Location loc = new Location(name);
ValueMapping val = new ValueMapping(in.get(l), false);
val.join(in.get(loc));
result.put(loc, val);
}
}
}
}
break;
case Constants.AASTORE:
{
filterSet(in, result, context.stackPtr - 3);
}
break;
case Constants.IALOAD:
case Constants.CALOAD:
case Constants.SALOAD:
case Constants.BALOAD:
{
filterSet(in, result, context.stackPtr - 2);
DFATool p = interpreter.getDFATool();
Location location = new Location(context.stackPtr - 2);
boolean valid = false;
Set<String> receivers = p.getReceivers(stmt, context.callString);
for (String name : receivers) {
for (Location l : in.keySet()) {
if (l.heapLoc.equals(name)) {
ValueMapping value = new ValueMapping(in.get(l), false);
value.join(result.get(location));
result.put(location, value);
valid = true;
}
}
}
if (!valid) {
result.put(new Location(context.stackPtr - 2), new ValueMapping(0));
}
}
break;
case Constants.AALOAD:
{
ValueMapping v = in.get(new Location(context.stackPtr - 1));
if (v == null) {
logger.warn("no value at: " + context.callString.toStringList() + context.method() + stmt);
} else {
recordArrayIndex(stmt, context, v.assigned);
}
filterSet(in, result, context.stackPtr - 2);
}
break;
case Constants.DUP:
{
for (Location l : in.keySet()) {
result.put(l, in.get(l));
if (l.stackLoc == context.stackPtr - 1) {
result.put(new Location(context.stackPtr), new ValueMapping(in.get(l), true));
}
}
}
break;
case Constants.DUP_X1:
{
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 2) {
result.put(l, in.get(l));
}
if (l.stackLoc == context.stackPtr - 1) {
result.put(new Location(context.stackPtr - 2), new ValueMapping(in.get(l), true));
result.put(new Location(context.stackPtr), new ValueMapping(in.get(l), true));
}
if (l.stackLoc == context.stackPtr - 2) {
result.put(new Location(context.stackPtr - 1), new ValueMapping(in.get(l), true));
}
}
}
break;
case Constants.DUP2:
{
for (Location l : in.keySet()) {
result.put(l, in.get(l));
if (l.stackLoc == context.stackPtr - 2) {
result.put(new Location(context.stackPtr), new ValueMapping(in.get(l), true));
}
if (l.stackLoc == context.stackPtr - 1) {
result.put(new Location(context.stackPtr + 1), new ValueMapping(in.get(l), true));
}
}
}
break;
case Constants.POP:
{
filterSet(in, result, context.stackPtr - 1);
}
break;
case Constants.POP2:
{
filterSet(in, result, context.stackPtr - 2);
}
break;
case Constants.IINC:
{
IINC instr = (IINC) instruction;
int index = instr.getIndex();
int increment = instr.getIncrement();
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr) {
result.put(l, in.get(l));
}
if (l.stackLoc == index) {
ValueMapping m = new ValueMapping(in.get(l), true);
m.assigned.add(increment);
m.constrained.add(increment);
Interval operand = new Interval(increment, increment);
if (m.increment != null && !m.softinc) {
m.increment.join(operand);
} else if (m.increment != null && m.softinc) {
if ((m.increment.getLb() < 0 && operand.getUb() > 0) || (m.increment.getUb() > 0 && operand.getLb() < 0)) {
m.increment.join(operand);
} else {
m.increment = operand;
}
m.softinc = false;
} else {
m.increment = operand;
m.softinc = false;
}
result.put(l, m);
}
}
}
break;
case Constants.IADD:
{
Interval operand = new Interval();
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
operand = in.get(l).assigned;
}
}
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 2) {
result.put(l, in.get(l));
} else if (l.stackLoc == context.stackPtr - 2) {
ValueMapping m = new ValueMapping(in.get(l), true);
m.assigned.add(operand);
m.constrained.add(operand);
if (m.increment != null && !m.softinc) {
m.increment.join(operand);
} else if (m.increment != null && m.softinc) {
if ((m.increment.getLb() < 0 && operand.getUb() > 0) || (m.increment.getUb() > 0 && operand.getLb() < 0)) {
m.increment.join(operand);
} else {
m.increment = operand;
}
m.softinc = false;
} else {
m.increment = operand;
m.softinc = false;
}
result.put(l, m);
}
}
}
break;
case Constants.ISUB:
{
Interval operand = new Interval();
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
operand = in.get(l).assigned;
}
}
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 2) {
result.put(l, in.get(l));
} else if (l.stackLoc == context.stackPtr - 2) {
ValueMapping m = new ValueMapping(in.get(l), true);
m.assigned.sub(operand);
m.constrained.sub(operand);
// decrement rather than increment
operand.neg();
if (m.increment != null && !m.softinc) {
m.increment.join(operand);
} else if (m.increment != null && m.softinc) {
if ((m.increment.getLb() < 0 && operand.getUb() > 0) || (m.increment.getUb() > 0 && operand.getLb() < 0)) {
m.increment.join(operand);
} else {
m.increment = operand;
}
m.softinc = false;
} else {
m.increment = operand;
m.softinc = false;
}
result.put(l, m);
}
}
}
break;
case Constants.INEG:
{
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 1) {
result.put(l, in.get(l));
} else if (l.stackLoc == context.stackPtr - 1) {
ValueMapping m = new ValueMapping(in.get(l), true);
m.assigned.neg();
m.constrained.neg();
m.increment = new Interval();
result.put(l, m);
}
}
}
break;
case Constants.IUSHR:
{
Interval operand = new Interval();
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
operand = in.get(l).assigned;
}
}
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 2) {
result.put(l, in.get(l));
} else if (l.stackLoc == context.stackPtr - 2) {
ValueMapping m = new ValueMapping(in.get(l), true);
m.assigned.ushr(operand);
m.constrained.ushr(operand);
m.increment = new Interval();
result.put(l, m);
}
}
}
break;
case Constants.ISHR:
{
Interval operand = new Interval();
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
operand = in.get(l).assigned;
}
}
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 2) {
result.put(l, in.get(l));
} else if (l.stackLoc == context.stackPtr - 2) {
ValueMapping m = new ValueMapping(in.get(l), true);
m.assigned.shr(operand);
m.constrained.shr(operand);
m.increment = new Interval();
result.put(l, m);
}
}
}
break;
case Constants.IMUL:
{
Interval operand = new Interval();
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
operand = in.get(l).assigned;
}
}
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 2) {
result.put(l, in.get(l));
} else if (l.stackLoc == context.stackPtr - 2) {
ValueMapping m = new ValueMapping(in.get(l), true);
m.assigned.mul(operand);
m.constrained.mul(operand);
m.increment = new Interval();
result.put(l, m);
}
}
}
break;
case Constants.IDIV:
{
Interval operand = new Interval();
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
operand = in.get(l).assigned;
}
}
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 2) {
result.put(l, in.get(l));
} else if (l.stackLoc == context.stackPtr - 2) {
ValueMapping m = new ValueMapping(in.get(l), true);
m.assigned.div(operand);
m.constrained.div(operand);
m.increment = new Interval();
result.put(l, m);
}
}
}
break;
case Constants.IAND:
case Constants.IOR:
case Constants.IXOR:
case Constants.IREM:
case Constants.ISHL:
{
// TODO: we could be more clever for some operations
for (Location l : in.keySet()) {
if (l.stackLoc < context.stackPtr - 2) {
result.put(l, in.get(l));
} else if (l.stackLoc == context.stackPtr - 2) {
ValueMapping m = new ValueMapping();
result.put(l, m);
}
}
}
break;
case Constants.I2B:
case Constants.I2C:
case Constants.I2S:
// TODO: is this really correct?
result = in;
retval.put(context.callString, result);
break;
case Constants.MONITORENTER:
result = in;
retval.put(context.callString, result);
context.syncLevel++;
break;
case Constants.MONITOREXIT:
result = in;
retval.put(context.callString, result);
context.syncLevel--;
if (context.syncLevel < 0) {
System.err.println("Synchronization level mismatch.");
System.exit(-1);
}
break;
case Constants.CHECKCAST:
result = in;
retval.put(context.callString, result);
break;
case Constants.INSTANCEOF:
{
filterSet(in, result, context.stackPtr - 1);
ValueMapping bool = new ValueMapping();
bool.assigned.setLb(0);
bool.assigned.setUb(1);
result.put(new Location(context.stackPtr - 1), bool);
}
break;
case Constants.NEW:
{
result = in;
retval.put(context.callString, result);
}
break;
case Constants.NEWARRAY:
{
NEWARRAY instr = (NEWARRAY) instruction;
String name = instr.getType().toString();
name += "@" + context.method() + ":" + stmt.getPosition();
filterSet(in, result, context.stackPtr - 1);
boolean valid = false;
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
result.put(new Location(name + ".length"), in.get(l));
recordSize(stmt, context, in.get(l).assigned);
valid = true;
}
}
if (!valid) {
ValueMapping v = new ValueMapping();
result.put(new Location(name + ".length"), v);
recordSize(stmt, context, v.assigned);
}
}
break;
case Constants.ANEWARRAY:
{
ANEWARRAY instr = (ANEWARRAY) instruction;
String name = instr.getType(context.constPool()).toString() + "[]";
name += "@" + context.method() + ":" + stmt.getPosition();
// System.out.println("NEW ARRAY: "+name);
filterSet(in, result, context.stackPtr - 1);
boolean valid = false;
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
result.put(new Location(name + ".length"), in.get(l));
recordSize(stmt, context, in.get(l).assigned);
valid = true;
}
}
if (!valid) {
ValueMapping v = new ValueMapping();
result.put(new Location(name + ".length"), v);
recordSize(stmt, context, v.assigned);
}
}
break;
case Constants.MULTIANEWARRAY:
{
MULTIANEWARRAY instr = (MULTIANEWARRAY) instruction;
int dim = instr.getDimensions();
filterSet(in, result, context.stackPtr - dim);
String type = instr.getType(context.constPool()).toString();
type = type.substring(0, type.indexOf("["));
Interval[] size = new Interval[dim];
for (int i = 1; i <= dim; i++) {
String name = type;
for (int k = 0; k < i; k++) {
name += "[]";
}
name += "@" + context.method() + ":" + stmt.getPosition();
boolean valid = false;
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - i) {
result.put(new Location(name + ".length"), in.get(l));
if (size[i - 1] != null) {
size[i - 1].join(in.get(l).assigned);
} else {
size[i - 1] = in.get(l).assigned;
}
valid = true;
}
}
if (!valid) {
ValueMapping v = new ValueMapping();
result.put(new Location(name + ".length"), v);
size[i - 1] = v.assigned;
}
}
recordSize(stmt, context, size);
}
break;
case Constants.GOTO:
result = in;
retval.put(context.callString, result);
break;
case Constants.IFNULL:
case Constants.IFNONNULL:
{
checkScope(context, stmt);
filterSet(in, result, context.stackPtr - 1);
}
break;
case Constants.IF_ACMPEQ:
case Constants.IF_ACMPNE:
{
checkScope(context, stmt);
filterSet(in, result, context.stackPtr - 2);
}
break;
case Constants.IFEQ:
case Constants.IFNE:
case Constants.IFLT:
case Constants.IFGE:
case Constants.IFLE:
case Constants.IFGT:
checkScope(context, stmt);
result = doIf(stmt, edge, context, in, result);
retval.put(context.callString, result);
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:
checkScope(context, stmt);
result = doIfIcmp(stmt, edge, context, in, result);
retval.put(context.callString, result);
break;
case Constants.LOOKUPSWITCH:
case Constants.TABLESWITCH:
result = in;
retval.put(context.callString, result);
break;
case Constants.INVOKEVIRTUAL:
case Constants.INVOKEINTERFACE:
case Constants.INVOKESTATIC:
case Constants.INVOKESPECIAL:
{
DFATool p = interpreter.getDFATool();
Set<String> receivers = p.getReceivers(stmt, context.callString);
if (receivers == null) {
warnUnknownReceivers(context, stmt);
result = in;
break;
}
for (String methodName : receivers) {
doInvoke(methodName, stmt, context, input, interpreter, state, retval);
}
}
break;
case Constants.ARETURN:
case Constants.RETURN:
{
filterSet(in, result, 0);
}
break;
case Constants.IRETURN:
{
filterSet(in, result, 0);
for (Location l : in.keySet()) {
if (l.stackLoc == context.stackPtr - 1) {
result.put(new Location(0), new ValueMapping(in.get(l), false));
}
}
}
break;
default:
// System.out.println("unknown instruction: "+stmt);
result = in;
retval.put(context.callString, result);
break;
}
// System.out.println(stmt);
// System.out.print(stmt.getInstruction()+":\t{ ");
// if (retval != null) {
// for (Iterator<Map<Location, ValueMapping>> k = retval.values().iterator(); k.hasNext(); ) {
// Map<Location, ValueMapping> m = k.next();
// System.out.print(m+", ");
// }
// }
// System.out.println("}");
context.stackPtr += instruction.produceStack(context.constPool()) - instruction.consumeStack(context.constPool());
return retval;
}
use of org.apache.bcel.generic.ConstantPushInstruction 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.ConstantPushInstruction in project jop by jop-devel.
the class InlineHelper method needsNullpointerCheck.
/**
* Check if an exception must be generated if the 'this' reference is null.
* This test can return false if
* <ul><li>There is no 'this' reference</li>
* <li>The DFA analysis showed that the reference is never null</li>
* <li>The inlined code will always generate an exception anyway</li>
* <li>Generating checks has been disabled by configuration</li>
* </ul>
* <p>
* The callstring does not need to start or to end at the method to optimize. However since the callstring is
* used to check the DFA results if available, the callstring must match what the DFA expects, i.e. if
* the DFA-results and -callstrings are updated during inlining, this callstring must not include inlined
* invokes. Contrariwise if the DFA results are not updated during inline, the callstring must contain already
* inlined invokes.
* </p>
*
* @param callString The callstring including the invokesite of the invokee. The top invokesite does not need to
* refer to an invoke instruction, and the referenced invoker method does not need to
* be the method containing the invoke to inline (e.g. if the invoke to inline has
* been inlined itself). However the callstring needs to match what the DFA expects.
* @param invokee the devirtualized invokee.
* @param analyzeCode if false, skip checking the code of the invokee.
* @return true if a nullpointer check code should be generated.
*/
public boolean needsNullpointerCheck(CallString callString, MethodInfo invokee, boolean analyzeCode) {
if (inlineConfig.skipNullpointerChecks())
return false;
InvokeSite invokeSite = callString.top();
// check if we have a 'this' reference anyway
if (invokeSite.isInvokeStatic() || invokeSite.isJVMCall()) {
return false;
}
// TODO check the DFA results if available
if (jcopter.useDFA()) {
} else if ("<init>".equals(invokee.getShortName())) {
// the NP check in this case (and hope that compilers for languages other than Java do the same..)
return false;
}
if (!analyzeCode) {
return true;
}
// check if the code will always throw an exception anyway (without producing any side effects before throwing)
ValueMapAnalysis analysis = new ValueMapAnalysis(invokee);
analysis.loadParameters();
InstructionList list = invokee.getCode().getInstructionList(true, false);
for (InstructionHandle ih : list.getInstructionHandles()) {
Instruction instr = ih.getInstruction();
if (instr instanceof ConstantPushInstruction || instr instanceof LocalVariableInstruction) {
analysis.transfer(instr);
} else if (instr instanceof GETFIELD || instr instanceof PUTFIELD || instr instanceof INVOKEVIRTUAL || instr instanceof INVOKEINTERFACE || instr instanceof INVOKESPECIAL) {
int down = instr.consumeStack(invokee.getConstantPoolGen());
ValueInfo value = analysis.getValueTable().top(down);
// the same way as the inlined invoke
if (value.isThisReference()) {
return false;
}
break;
} else {
// we ignore all other instructions (for now..)
break;
}
}
return true;
}
Aggregations