From 6097c60e19f08f0b8dd20b474159d82804139f7e Mon Sep 17 00:00:00 2001 From: aclement Date: Thu, 30 Oct 2008 15:43:43 +0000 Subject: [PATCH] 173978: test and fix: local var table for method-execution and around advice --- .../aspectj/weaver/bcel/LazyMethodGen.java | 71 ++++++++++++++++--- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java index 720626882..57e1286e1 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java @@ -894,7 +894,7 @@ public final class LazyMethodGen implements Traceable { if (newAnnotations != null) { for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) { AnnotationAJ element = (AnnotationAJ) iter.next(); - gen.addAnnotation(new AnnotationGen(((BcelAnnotation)element).getBcelAnnotation(), gen.getConstantPool(), true)); + gen.addAnnotation(new AnnotationGen(((BcelAnnotation) element).getBcelAnnotation(), gen.getConstantPool(), true)); } } @@ -1028,7 +1028,15 @@ public final class LazyMethodGen implements Traceable { } addExceptionHandlers(gen, map, exceptionList); - addLocalVariables(gen, localVariables); + 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 @@ -1042,6 +1050,37 @@ public final class LazyMethodGen implements Traceable { } } + private void createNewLocalVariables(MethodGen gen) { + gen.removeLocalVariables(); + // ignore or for now + if (!getName().startsWith("<")) { + int slot = 0; + InstructionHandle start = gen.getInstructionList().getStart(); + InstructionHandle end = gen.getInstructionList().getEnd(); + // Add a 'this' if non-static + if (!isStatic()) { + String cname = this.enclosingClass.getClassName(); + if (cname == null) { + return; // give up for now + } + Type enclosingType = BcelWorld.makeBcelType(UnresolvedType.forName(cname)); + gen.addLocalVariable("this", enclosingType, slot++, start, end); + } + // Add entries for the method arguments + String[] paramNames = (memberView == null ? null : memberView.getParameterNames()); + if (paramNames != null) { + for (int i = 0; i < argumentTypes.length; i++) { + String pname = paramNames[i]; + if (pname == null) { + pname = "arg" + i; + } + gen.addLocalVariable(pname, argumentTypes[i], slot, start, end); + slot += argumentTypes[i].getSize(); + } + } + } + } + /* * 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. @@ -1132,7 +1171,15 @@ public final class LazyMethodGen implements Traceable { } } gen.setInstructionList(theBody); - addLocalVariables(gen, localVariables); + 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 @@ -1403,14 +1450,16 @@ public final class LazyMethodGen implements Traceable { * A good body is a body with the following properties: * *
    - *
  • For each branch instruction S in body, target T of S is in body.
  • For each branch instruction S in body, target T of - * S has S as a targeter.
  • For each instruction T in body, for each branch instruction S that is a targeter of T, S is in - * body.
  • For each non-range-handle instruction T in body, for each instruction S that is a targeter of T, S is either a - * branch instruction, an exception range or a tag
  • For each range-handle instruction T in body, there is exactly one - * targeter S that is a range.
  • For each range-handle instruction T in body, the range R targeting T is in body.
  • For - * each instruction T in body, for each exception range R targeting T, R is in body.
  • For each exception range R in body, - * let T := R.handler. T is in body, and R is one of T's targeters
  • All ranges are properly nested: For all ranges Q and R, - * if Q.start preceeds R.start, then R.end preceeds Q.end. + *
  • For each branch instruction S in body, target T of S is in body. + *
  • For each branch instruction S in body, target T of S has S as a targeter. + *
  • For each instruction T in body, for each branch instruction S that is a targeter of T, S is in body. + *
  • For each non-range-handle instruction T in body, for each instruction S that is a targeter of T, S is either a branch + * instruction, an exception range or a tag + *
  • For each range-handle instruction T in body, there is exactly one targeter S that is a range. + *
  • For each range-handle instruction T in body, the range R targeting T is in body. + *
  • For each instruction T in body, for each exception range R targeting T, R is in body. + *
  • For each exception range R in body, let T := R.handler. T is in body, and R is one of T's targeters + *
  • All ranges are properly nested: For all ranges Q and R, if Q.start preceeds R.start, then R.end preceeds Q.end. *
* * Where the shorthand "R is in body" means "R.start is in body, R.end is in body, and any InstructionHandle stored in a field -- 2.39.5