public boolean forDEBUG_structuralChangesCode = false;
public boolean forDEBUG_bridgingCode = false;
public boolean optimizedMatching = true;
+ public boolean generateNewLvts = true;
protected long timersPerJoinpoint = 25000;
protected long timersPerType = 250;
public final static String xsetITD_VERSION_DEFAULT = xsetITD_VERSION_2NDGEN;
public final static String xsetMINIMAL_MODEL = "minimalModel";
public final static String xsetTARGETING_RUNTIME_1610 = "targetRuntime1_6_10";
+
+ // This option allows you to prevent AspectJ adding local variable tables - some tools (e.g. dex) may
+ // not like what gets created because even though it is valid, the bytecode they are processing has
+ // unexpected quirks that mean the table entries are violated in the code. See issue:
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=470658
+ public final static String xsetGENERATE_NEW_LVTS="generateNewLocalVariableTables";
public boolean isInJava5Mode() {
return behaveInJava5Way;
s = p.getProperty(xsetDEBUG_BRIDGING, "false");
forDEBUG_bridgingCode = s.equalsIgnoreCase("true");
+ s = p.getProperty(xsetGENERATE_NEW_LVTS,"true");
+ generateNewLvts = s.equalsIgnoreCase("true");
+ if (!generateNewLvts) {
+ getMessageHandler().handleMessage(MessageUtil.info("[generateNewLvts=false] for methods without an incoming local variable table, do not generate one"));
+ }
+
s = p.getProperty(xsetOPTIMIZED_MATCHING, "true");
optimizedMatching = s.equalsIgnoreCase("true");
if (!optimizedMatching) {
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.World;
import org.aspectj.weaver.tools.Traceable;
/**
*/
public final class LazyMethodGen implements Traceable {
+ private static final AnnotationAJ[] NO_ANNOTATIONAJ = new AnnotationAJ[] {};
+
private int modifiers;
private Type returnType;
private final String name;
int highestLineNumber = 0;
boolean wasPackedOptimally = false;
private Method savedMethod = null;
- private static final AnnotationAJ[] NO_ANNOTATIONAJ = new AnnotationAJ[] {};
+
+ // Some tools that may post process the output bytecode do not long local variable tables
+ // to be generated as one reason the tables may be missing in the first place is because
+ // the bytecode is odd. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=470658
+ private final boolean originalMethodHasLocalVariableTable;
/*
* We use LineNumberTags and not Gens.
this.attributes = new ArrayList<Attribute>();
this.enclosingClass = enclosingClass;
assertGoodBody();
+ this.originalMethodHasLocalVariableTable = true; // it is a new method, we want an lvar table
// @AJ advice are not inlined by default since requires further analysis and weaving ordering control
// TODO AV - improve - note: no room for improvement as long as aspects are reweavable
throw new RuntimeException("bad abstract method with code: " + m + " on " + enclosingClass);
}
this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
-
+ this.originalMethodHasLocalVariableTable = savedMethod.getLocalVariableTable()!=null;
this.modifiers = m.getModifiers();
this.name = m.getName();
this.memberView = m;
this.modifiers = savedMethod.getModifiers();
this.name = m.getName();
-
+ this.originalMethodHasLocalVariableTable = savedMethod.getLocalVariableTable() != null;
// @AJ advice are not inlined by default since requires further analysis
// and weaving ordering control
// TODO AV - improve - note: no room for improvement as long as aspects
}
addExceptionHandlers(gen, map, exceptionList);
- if (localVariables.size() == 0) {
- // Might be a case of 173978 where around advice on an execution join point
- // has caused everything to be extracted from the method and thus we
- // are left with no local variables, not even the ones for 'this' and
- // parameters passed to the method
- createNewLocalVariables(gen);
- } else {
- addLocalVariables(gen, localVariables);
+ if (originalMethodHasLocalVariableTable || enclosingClass
+ .getBcelObjectType()
+ .getResolvedTypeX()
+ .getWorld().generateNewLvts) {
+ if (localVariables.size() == 0) {
+ // Might be a case of 173978 where around advice on an execution join point
+ // has caused everything to be extracted from the method and thus we
+ // are left with no local variables, not even the ones for 'this' and
+ // parameters passed to the method
+ createNewLocalVariables(gen);
+ } else {
+ addLocalVariables(gen, localVariables);
+ }
}
// JAVAC adds line number tables (with just one entry) to generated
}
}
+ private World getWorld() {
+ return enclosingClass.getBcelObjectType().getResolvedTypeX().getWorld();
+ }
/*
* Optimized packing that does a 'local packing' of the code rather than building a brand new method and packing into it. Only
* usable when the packing is going to be done just once.
}
}
gen.setInstructionList(theBody);
- if (localVariables.size() == 0) {
- // Might be a case of 173978 where around advice on an execution join point
- // has caused everything to be extracted from the method and thus we
- // are left with no local variables, not even the ones for 'this' and
- // parameters passed to the method
- createNewLocalVariables(gen);
- } else {
- addLocalVariables(gen, localVariables);
+ if (originalMethodHasLocalVariableTable || getWorld().generateNewLvts) {
+ if (localVariables.size() == 0) {
+ // Might be a case of 173978 where around advice on an execution join point
+ // has caused everything to be extracted from the method and thus we
+ // are left with no local variables, not even the ones for 'this' and
+ // parameters passed to the method
+ createNewLocalVariables(gen);
+ } else {
+ addLocalVariables(gen, localVariables);
+ }
}
-
// JAVAC adds line number tables (with just one entry) to generated
// accessor methods - this
// keeps some tools that rely on finding at least some form of