use of org.apache.bcel.classfile.LocalVariableTable in project commons-bcel by apache.
the class MethodGen method getMethod.
/**
* Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively,
* before calling this method (the same applies for max locals).
*
* @return method object
*/
public Method getMethod() {
final String signature = getSignature();
final ConstantPoolGen _cp = super.getConstantPool();
final int name_index = _cp.addUtf8(super.getName());
final int signature_index = _cp.addUtf8(signature);
/* Also updates positions of instructions, i.e., their indices
*/
byte[] byte_code = null;
if (il != null) {
byte_code = il.getByteCode();
}
LineNumberTable lnt = null;
LocalVariableTable lvt = null;
/* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
*/
if (!variableList.isEmpty() && !stripAttributes) {
updateLocalVariableTable(getLocalVariableTable(_cp));
addCodeAttribute(lvt = getLocalVariableTable(_cp));
}
if (localVariableTypeTable != null) {
// LocalVariable length in LocalVariableTypeTable is not updated automatically. It's a difference with LocalVariableTable.
if (lvt != null) {
adjustLocalVariableTypeTable(lvt);
}
addCodeAttribute(localVariableTypeTable);
}
if (!lineNumberList.isEmpty() && !stripAttributes) {
addCodeAttribute(lnt = getLineNumberTable(_cp));
}
final Attribute[] code_attrs = getCodeAttributes();
/* Each attribute causes 6 additional header bytes
*/
int attrs_len = 0;
for (final Attribute code_attr : code_attrs) {
attrs_len += code_attr.getLength() + 6;
}
final CodeException[] c_exc = getCodeExceptions();
// Every entry takes 8 bytes
final int exc_len = c_exc.length * 8;
Code code = null;
if (il != null && !isAbstract() && !isNative()) {
// Remove any stale code attribute
final Attribute[] attributes = getAttributes();
for (final Attribute a : attributes) {
if (a instanceof Code) {
removeAttribute(a);
}
}
code = new Code(_cp.addUtf8("Code"), // prologue byte code
8 + byte_code.length + 2 + // exceptions
exc_len + 2 + // attributes
attrs_len, maxStack, maxLocals, byte_code, c_exc, code_attrs, _cp.getConstantPool());
addAttribute(code);
}
final Attribute[] annotations = addRuntimeAnnotationsAsAttribute(_cp);
final Attribute[] parameterAnnotations = addRuntimeParameterAnnotationsAsAttribute(_cp);
ExceptionTable et = null;
if (!throwsList.isEmpty()) {
addAttribute(et = getExceptionTable(_cp));
// Add `Exceptions' if there are "throws" clauses
}
final Method m = new Method(super.getAccessFlags(), name_index, signature_index, getAttributes(), _cp.getConstantPool());
// Undo effects of adding attributes
if (lvt != null) {
removeCodeAttribute(lvt);
}
if (localVariableTypeTable != null) {
removeCodeAttribute(localVariableTypeTable);
}
if (lnt != null) {
removeCodeAttribute(lnt);
}
if (code != null) {
removeAttribute(code);
}
if (et != null) {
removeAttribute(et);
}
removeRuntimeAttributes(annotations);
removeRuntimeAttributes(parameterAnnotations);
return m;
}
use of org.apache.bcel.classfile.LocalVariableTable in project commons-bcel by apache.
the class PLSETestCase method testB295.
/**
* BCEL-295:
*/
@Test
public void testB295() throws Exception {
final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME + ".data.PLSETestClass2");
final ClassGen cg = new ClassGen(clazz);
final ConstantPoolGen pool = cg.getConstantPool();
// 'main'
final Method m = cg.getMethodAt(1);
final LocalVariableTable lvt = m.getLocalVariableTable();
// 'i'
final LocalVariable lv = lvt.getLocalVariable(2, 4);
// System.out.println(lv);
final MethodGen mg = new MethodGen(m, cg.getClassName(), pool);
final LocalVariableTable new_lvt = mg.getLocalVariableTable(mg.getConstantPool());
// 'i'
final LocalVariable new_lv = new_lvt.getLocalVariable(2, 4);
// System.out.println(new_lv);
assertEquals(lv.getLength(), new_lv.getLength(), "live range length");
}
use of org.apache.bcel.classfile.LocalVariableTable in project avro-util by linkedin.
the class OldSchemaConstructableUsageDetector method lookForSchemaConstructableVariables.
protected void lookForSchemaConstructableVariables(ClassContext classContext) {
for (Method method : classContext.getMethodsInCallOrder()) {
Type returnType = method.getReturnType();
if (checkSignature(returnType.getSignature())) {
BugInstance bug = new BugInstance(this, BUG_TYPE, NORMAL_PRIORITY).addClassAndMethod(classContext.getJavaClass(), method);
bugReporter.reportBug(bug);
}
if (method.isAbstract() || method.isNative()) {
// method arguments show up in the local variables table below, but not for abstract/native methods
Type[] argumentTypes = method.getArgumentTypes();
for (Type argumentType : argumentTypes) {
if (checkSignature(argumentType.getSignature())) {
// TODO - figure out how to get argument name or index
BugInstance bug = new BugInstance(this, BUG_TYPE, NORMAL_PRIORITY).addClassAndMethod(classContext.getJavaClass(), method);
bugReporter.reportBug(bug);
}
}
// no variables to look at
continue;
}
// includes method args
LocalVariableTable localVariableTable = method.getLocalVariableTable();
if (localVariableTable == null) {
return;
}
for (LocalVariable variable : localVariableTable.getLocalVariableTable()) {
if (checkSignature(variable.getSignature())) {
// TODO - figure out how to add sour line number?
BugInstance bug = new BugInstance(this, BUG_TYPE, NORMAL_PRIORITY).addClassAndMethod(classContext.getJavaClass(), method);
bugReporter.reportBug(bug);
}
}
}
}
use of org.apache.bcel.classfile.LocalVariableTable in project spotbugs by spotbugs.
the class FindUselessObjects method analyzeMethod.
private void analyzeMethod(ClassContext classContext, Method method) throws CheckedAnalysisException {
LocalVariableTable lvt = method.getLocalVariableTable();
UselessValuesContext context = new UselessValuesContext(classContext, method);
context.initObservedValues();
if (context.isEmpty()) {
return;
}
context.enhanceViaMergeTree();
boolean changed;
int iteration = 0;
do {
changed = false;
if (++iteration > MAX_ITERATIONS) {
AnalysisContext.logError("FindUselessObjects: " + classContext.getClassDescriptor().getDottedClassName() + "." + method.getName() + method.getSignature() + ": cannot converge after " + MAX_ITERATIONS + " iterations; method is skipped");
return;
}
for (Iterator<GenLocation> iterator = context.genIterator(); iterator.hasNext() && !context.isEmpty(); ) {
GenLocation location = iterator.next();
Instruction inst = location.getHandle().getInstruction();
ValueNumberFrame before = location.frameBefore();
if (!before.isValid()) {
continue;
}
if (inst instanceof IINC) {
int index = ((IINC) inst).getIndex();
Set<ValueInfo> vals = context.getLiveVals(before.getValue(index));
if (vals != null) {
changed |= context.propagateValues(vals, null, location.frameAfter().getValue(index));
}
continue;
}
int nconsumed = inst.consumeStack(context.cpg);
if (nconsumed > 0) {
ValueNumber[] vns = new ValueNumber[nconsumed];
before.getTopStackWords(vns);
for (int i = 0; i < nconsumed; i++) {
ValueNumber vn = vns[i];
Set<ValueInfo> vals = context.getLiveVals(vn);
if (vals != null) {
switch(inst.getOpcode()) {
case ASTORE:
case ASTORE_0:
case ASTORE_1:
case ASTORE_2:
case ASTORE_3:
for (ValueInfo vi : vals) {
if (vi.var == null && vi.origValue == vn.getNumber()) {
int index = ((StoreInstruction) inst).getIndex();
LocalVariable lv = lvt == null ? null : lvt.getLocalVariable(index, location.getHandle().getNext().getPosition());
vi.var = lv == null ? "var$" + index : lv.getName();
vi.hasObjectOnlyCall = false;
changed = true;
}
}
break;
case POP:
case POP2:
case DUP:
case DUP2:
case DUP_X1:
case DUP2_X1:
case ISTORE:
case ISTORE_0:
case ISTORE_1:
case ISTORE_2:
case ISTORE_3:
case LSTORE:
case LSTORE_0:
case LSTORE_1:
case LSTORE_2:
case LSTORE_3:
case FSTORE:
case FSTORE_0:
case FSTORE_1:
case FSTORE_2:
case FSTORE_3:
case DSTORE:
case DSTORE_0:
case DSTORE_1:
case DSTORE_2:
case DSTORE_3:
case SWAP:
case IMPDEP1:
case IMPDEP2:
case CHECKCAST:
case MONITORENTER:
break;
case IADD:
case LADD:
case FADD:
case DADD:
case ISUB:
case LSUB:
case FSUB:
case DSUB:
case IMUL:
case DMUL:
case LMUL:
case FMUL:
case IDIV:
case DDIV:
case LDIV:
case FDIV:
case INEG:
case LNEG:
case FNEG:
case DNEG:
case IREM:
case LREM:
case FREM:
case DREM:
case ISHL:
case LSHL:
case ISHR:
case LSHR:
case IUSHR:
case LUSHR:
case IAND:
case LAND:
case IOR:
case LOR:
case IXOR:
case LXOR:
case I2L:
case I2F:
case I2D:
case L2I:
case L2F:
case L2D:
case F2I:
case F2L:
case F2D:
case D2I:
case D2L:
case D2F:
case I2B:
case I2C:
case I2S:
case LCMP:
case FCMPL:
case FCMPG:
case DCMPL:
case DCMPG:
case ARRAYLENGTH:
changed |= context.propagateValues(vals, null, location.frameAfter().getTopValue());
break;
case GETFIELD:
case AALOAD:
case DALOAD:
case BALOAD:
case CALOAD:
case LALOAD:
case SALOAD:
case IALOAD:
changed |= context.propagateValues(vals, vn, location.frameAfter().getTopValue());
break;
case AASTORE:
case DASTORE:
case BASTORE:
case CASTORE:
case LASTORE:
case SASTORE:
case IASTORE:
case PUTFIELD:
if (i == 0) {
ValueNumber value = vns[vns.length - 1];
if (!value.hasFlag(ValueNumber.CONSTANT_VALUE) && !value.hasFlag(ValueNumber.CONSTANT_CLASS_OBJECT) && !context.observedValues.containsKey(value.getNumber())) {
changed |= context.setDerivedEscape(vals, vn);
}
changed |= context.setObjectOnly(vals, vn);
} else {
if (context.escaped(vns[0])) {
changed |= context.setEscape(vals);
} else {
changed |= context.propagateValues(vals, null, vns[0]);
}
}
break;
case INVOKESTATIC:
case INVOKESPECIAL:
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
MethodDescriptor m = new MethodDescriptor((InvokeInstruction) inst, context.cpg);
XMethod xMethod = null;
try {
Type type = location.typeFrameBefore().getStackValue(nconsumed - 1);
xMethod = Global.getAnalysisCache().getClassAnalysis(XClass.class, DescriptorFactory.createClassDescriptorFromSignature(type.getSignature())).findMatchingMethod(m);
} catch (CheckedAnalysisException e) {
// ignore
}
if (xMethod != null) {
m = xMethod.getMethodDescriptor();
}
MethodSideEffectStatus status = noSideEffectMethods.status(m);
if (status == MethodSideEffectStatus.NSE || status == MethodSideEffectStatus.SE_CLINIT) {
if (m.getName().equals(CONSTRUCTOR_NAME)) {
if (vns[0].equals(context.thisValue)) {
changed |= context.setEscape(vals);
} else {
changed |= context.propagateValues(vals, null, vns[0]);
}
} else {
changed |= context.propagateToReturnValue(vals, vn, location, m);
}
break;
}
if (status == MethodSideEffectStatus.OBJ) {
if (i == 0) {
changed |= context.setDerivedEscape(vals, vn);
changed |= context.propagateToReturnValue(vals, vn, location, m);
changed |= context.setObjectOnly(vals, vn);
break;
} else {
if (!context.escaped(vns[0])) {
changed |= context.propagateValues(vals, null, vns[0]);
changed |= context.propagateToReturnValue(vals, vn, location, m);
break;
}
}
}
changed |= context.setEscape(vals);
break;
default:
changed |= context.setEscape(vals);
break;
}
}
}
}
}
} while (changed);
context.report();
}
use of org.apache.bcel.classfile.LocalVariableTable in project spotbugs by spotbugs.
the class TrainLongInstantfParams method visit.
@Override
public void visit(Code obj) {
if (!getMethod().isPublic() && !getMethod().isProtected()) {
return;
}
SignatureParser p = new SignatureParser(getMethodSig());
LocalVariableTable t = obj.getLocalVariableTable();
if (t == null) {
return;
}
ParameterProperty property = new ParameterProperty();
int index = getMethod().isStatic() ? 0 : 1;
int parameterNumber = 0;
for (Iterator<String> i = p.parameterSignatureIterator(); i.hasNext(); ) {
String s = i.next();
LocalVariable localVariable = t.getLocalVariable(index, 0);
if (localVariable != null) {
String name = localVariable.getName();
if ("J".equals(s) && (name.toLowerCase().indexOf("instant") >= 0 || name.startsWith("date"))) {
// System.out.println(getFullyQualifiedMethodName() + " " + s + " " + index + " " + name);
property.setParamWithProperty(parameterNumber, true);
}
}
if ("J".equals(s) || "D".equals(s)) {
index += 2;
} else {
index += 1;
}
parameterNumber++;
}
if (!property.isEmpty()) {
// System.out.println(getFullyQualifiedMethodName() + " " + property);
database.setProperty(getMethodDescriptor(), property);
}
}
Aggregations