diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2007-06-02 14:12:36 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2007-06-02 14:12:36 +0000 |
commit | b8445cabacd7ab2a9c04bc5936583060f35ef505 (patch) | |
tree | 0d3ed708d5c2ef0b2849e45b44d1ec3e250062a5 /src/main/javassist/compiler | |
parent | 8242ef42ef19f1f6a3f15e9b230f0317067f3863 (diff) | |
download | javassist-b8445cabacd7ab2a9c04bc5936583060f35ef505.tar.gz javassist-b8445cabacd7ab2a9c04bc5936583060f35ef505.zip |
fixed bugs related to stack map tables.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@378 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main/javassist/compiler')
-rw-r--r-- | src/main/javassist/compiler/CodeGen.java | 27 | ||||
-rw-r--r-- | src/main/javassist/compiler/Javac.java | 16 | ||||
-rw-r--r-- | src/main/javassist/compiler/MemberCodeGen.java | 54 |
3 files changed, 81 insertions, 16 deletions
diff --git a/src/main/javassist/compiler/CodeGen.java b/src/main/javassist/compiler/CodeGen.java index dfcddc4e..0712d906 100644 --- a/src/main/javassist/compiler/CodeGen.java +++ b/src/main/javassist/compiler/CodeGen.java @@ -53,7 +53,13 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { */ protected static abstract class ReturnHook { ReturnHook next; - protected abstract void doit(Bytecode b, int opcode); + + /** + * Returns true if the generated code ends with return, + * throw, or goto. + */ + protected abstract boolean doit(Bytecode b, int opcode); + protected ReturnHook(CodeGen gen) { next = gen.returnHooks; gen.returnHooks = this; @@ -607,7 +613,10 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { } for (ReturnHook har = returnHooks; har != null; har = har.next) - har.doit(bytecode, op); + if (har.doit(bytecode, op)) { + hasReturned = true; + return; + } bytecode.addOpcode(op); hasReturned = true; @@ -645,9 +654,10 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { bc.addOpcode(MONITORENTER); ReturnHook rh = new ReturnHook(this) { - protected void doit(Bytecode b, int opcode) { + protected boolean doit(Bytecode b, int opcode) { b.addAload(var); b.addOpcode(MONITOREXIT); + return false; } }; @@ -665,10 +675,13 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { bc.addIndex(0); } - int pc4 = bc.currentPc(); - rh.doit(bc, 0); // the 2nd arg is ignored. - bc.addOpcode(ATHROW); - bc.addExceptionHandler(pc, pc2, pc4, 0); + if (pc < pc2) { // if the body is not empty + int pc4 = bc.currentPc(); + rh.doit(bc, 0); // the 2nd arg is ignored. + bc.addOpcode(ATHROW); + bc.addExceptionHandler(pc, pc2, pc4, 0); + } + if (!hasReturned) bc.write16bit(pc3, bc.currentPc() - pc3 + 1); diff --git a/src/main/javassist/compiler/Javac.java b/src/main/javassist/compiler/Javac.java index d32fddcf..b3d275b3 100644 --- a/src/main/javassist/compiler/Javac.java +++ b/src/main/javassist/compiler/Javac.java @@ -27,6 +27,7 @@ import javassist.Modifier; import javassist.bytecode.Bytecode; import javassist.bytecode.CodeAttribute; import javassist.bytecode.LocalVariableAttribute; +import javassist.bytecode.BadBytecode; import javassist.bytecode.Opcode; import javassist.NotFoundException; @@ -89,8 +90,17 @@ public class Javac { try { if (mem instanceof FieldDecl) return compileField((FieldDecl)mem); - else - return compileMethod(p, (MethodDecl)mem); + else { + CtBehavior cb = compileMethod(p, (MethodDecl)mem); + CtClass decl = cb.getDeclaringClass(); + cb.getMethodInfo2() + .rebuildStackMapIf6(decl.getClassPool(), + decl.getClassFile2()); + return cb; + } + } + catch (BadBytecode bb) { + throw new CompileError(bb.getMessage()); } catch (CannotCompileException e) { throw new CompileError(e.getMessage()); @@ -128,7 +138,7 @@ public class Javac { return f; } - private CtMember compileMethod(Parser p, MethodDecl md) + private CtBehavior compileMethod(Parser p, MethodDecl md) throws CompileError { int mod = MemberResolver.getModifiers(md.getModifiers()); diff --git a/src/main/javassist/compiler/MemberCodeGen.java b/src/main/javassist/compiler/MemberCodeGen.java index 3d7ed373..71849957 100644 --- a/src/main/javassist/compiler/MemberCodeGen.java +++ b/src/main/javassist/compiler/MemberCodeGen.java @@ -24,8 +24,6 @@ import java.util.ArrayList; /* Code generator methods depending on javassist.* classes. */ public class MemberCodeGen extends CodeGen { - public static final int JAVA5_VER = 49; - protected MemberResolver resolver; protected CtClass thisClass; protected MethodInfo thisMethod; @@ -106,11 +104,11 @@ public class MemberCodeGen extends CodeGen { private void jsrJmp(Bytecode b) { b.addOpcode(Opcode.GOTO); - jsrList.add(new Integer(b.currentPc())); + jsrList.add(new int[] {b.currentPc(), var}); b.addIndex(0); } - protected void doit(Bytecode b, int opcode) { + protected boolean doit(Bytecode b, int opcode) { switch (opcode) { case Opcode.RETURN : jsrJmp(b); @@ -143,6 +141,47 @@ public class MemberCodeGen extends CodeGen { default : throw new RuntimeException("fatal"); } + + return false; + } + } + + static class JsrHook2 extends ReturnHook { + int var; + int target; + + JsrHook2(CodeGen gen, int[] retTarget) { + super(gen); + target = retTarget[0]; + var = retTarget[1]; + } + + protected boolean doit(Bytecode b, int opcode) { + switch (opcode) { + case Opcode.RETURN : + break; + case ARETURN : + b.addAstore(var); + break; + case IRETURN : + b.addIstore(var); + break; + case LRETURN : + b.addLstore(var); + break; + case DRETURN : + b.addDstore(var); + break; + case FRETURN : + b.addFstore(var); + break; + default : + throw new RuntimeException("fatal"); + } + + b.addOpcode(Opcode.GOTO); + b.addIndex(target - b.currentPc() + 3); + return true; } } @@ -236,9 +275,12 @@ public class MemberCodeGen extends CodeGen { Bytecode bc = bytecode; int n = returnList.size(); for (int i = 0; i < n; ++i) { - int pc = ((Integer)returnList.get(i)).intValue(); + final int[] ret = (int[])returnList.get(i); + int pc = ret[0]; bc.write16bit(pc, bc.currentPc() - pc + 1); + ReturnHook hook = new JsrHook2(this, ret); finallyBlock.accept(this); + hook.remove(this); if (!hasReturned) { bc.addOpcode(Opcode.GOTO); bc.addIndex(pc + 3 - bc.currentPc()); @@ -923,7 +965,7 @@ public class MemberCodeGen extends CodeGen { } protected void atClassObject2(String cname) throws CompileError { - if (getMajorVersion() < JAVA5_VER) + if (getMajorVersion() < ClassFile.JAVA_5) super.atClassObject2(cname); else bytecode.addLdc(bytecode.getConstPool().addClassInfo(cname)); |