diff options
-rw-r--r-- | src/main/javassist/compiler/Javac.java | 33 | ||||
-rw-r--r-- | src/main/javassist/compiler/JvstCodeGen.java | 22 | ||||
-rw-r--r-- | src/main/javassist/compiler/MemberCodeGen.java | 7 | ||||
-rw-r--r-- | src/main/javassist/expr/Cast.java | 2 | ||||
-rw-r--r-- | src/main/javassist/expr/FieldAccess.java | 2 | ||||
-rw-r--r-- | src/main/javassist/expr/Instanceof.java | 2 | ||||
-rw-r--r-- | src/main/javassist/expr/MethodCall.java | 3 |
7 files changed, 61 insertions, 10 deletions
diff --git a/src/main/javassist/compiler/Javac.java b/src/main/javassist/compiler/Javac.java index e0bf3428..44c3ff11 100644 --- a/src/main/javassist/compiler/Javac.java +++ b/src/main/javassist/compiler/Javac.java @@ -384,6 +384,39 @@ public class Javac { } /** + * Prepares to use $proceed() representing a private/super's method. + * If the return type of $proceed() is void, null is pushed on the + * stack. This method is for methods invoked by INVOKESPECIAL. + * + * @param target an expression specifying the target object. + * if null, "this" is the target. + * @param classname the class name declaring the method. + * @param methodname the method name. + * @param descriptor the method descriptor. + */ + public void recordSpecialProceed(String target, String classname, + String methodname, String descriptor) + throws CompileError + { + Parser p = new Parser(new Lex(target)); + final ASTree texpr = p.parseExpression(stable); + final String cname = classname; + final String method = methodname; + final String desc = descriptor; + + ProceedHandler h = new ProceedHandler() { + public void doit(JvstCodeGen gen, Bytecode b, ASTList args) + throws CompileError + { + gen.compileInvokeSpecial(texpr, + cname, method, desc, args); + } + }; + + gen.setProceedHandler(h, proceedName); + } + + /** * Prepares to use $proceed(). */ public void recordProceed(ProceedHandler h) { diff --git a/src/main/javassist/compiler/JvstCodeGen.java b/src/main/javassist/compiler/JvstCodeGen.java index 40d39a11..5081ea1e 100644 --- a/src/main/javassist/compiler/JvstCodeGen.java +++ b/src/main/javassist/compiler/JvstCodeGen.java @@ -306,15 +306,15 @@ public class JvstCodeGen extends MemberCodeGen { } /* - public int atMethodArgsLength(ASTList args) { + public int getMethodArgsLength(ASTList args) { if (!isParamListName(args)) - return super.atMethodArgsLength(args); + return super.getMethodArgsLength(args); return paramTypeList.length; } */ - public int atMethodArgsLength(ASTList args) { + public int getMethodArgsLength(ASTList args) { String pname = paramListName; int n = 0; while (args != null) { @@ -391,6 +391,22 @@ public class JvstCodeGen extends MemberCodeGen { } */ + /* called by Javac#recordSpecialProceed(). + */ + void compileInvokeSpecial(ASTree target, String classname, + String methodname, String descriptor, + ASTList args) + throws CompileError + { + target.accept(this); + int nargs = getMethodArgsLength(args); + atMethodArgs(args, new int[nargs], new int[nargs], + new String[nargs]); + bytecode.addInvokespecial(classname, methodname, descriptor); + setReturnType(descriptor, false, false); + addNullIfVoid(); + } + /* * Makes it valid to write "return <expr>;" for a void method. */ diff --git a/src/main/javassist/compiler/MemberCodeGen.java b/src/main/javassist/compiler/MemberCodeGen.java index c97855f3..92e299f0 100644 --- a/src/main/javassist/compiler/MemberCodeGen.java +++ b/src/main/javassist/compiler/MemberCodeGen.java @@ -315,7 +315,7 @@ public class MemberCodeGen extends CodeGen { int aload0pos) throws CompileError { - int nargs = atMethodArgsLength(args); + int nargs = getMethodArgsLength(args); int[] types = new int[nargs]; int[] dims = new int[nargs]; String[] cnames = new String[nargs]; @@ -386,7 +386,7 @@ public class MemberCodeGen extends CodeGen { setReturnType(desc, isStatic, popTarget); } - public int atMethodArgsLength(ASTList args) { + public int getMethodArgsLength(ASTList args) { return ASTList.length(args); } @@ -404,8 +404,7 @@ public class MemberCodeGen extends CodeGen { } } - private void setReturnType(String desc, boolean isStatic, - boolean popTarget) + void setReturnType(String desc, boolean isStatic, boolean popTarget) throws CompileError { int i = desc.indexOf(')'); diff --git a/src/main/javassist/expr/Cast.java b/src/main/javassist/expr/Cast.java index 9003503b..5dcbbb41 100644 --- a/src/main/javassist/expr/Cast.java +++ b/src/main/javassist/expr/Cast.java @@ -138,7 +138,7 @@ public class Cast extends Expr { public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) throws CompileError { - if (gen.atMethodArgsLength(args) != 1) + if (gen.getMethodArgsLength(args) != 1) throw new CompileError(Javac.proceedName + "() cannot take more than one parameter " + "for cast"); diff --git a/src/main/javassist/expr/FieldAccess.java b/src/main/javassist/expr/FieldAccess.java index 6a7e9120..0a9cfeb1 100644 --- a/src/main/javassist/expr/FieldAccess.java +++ b/src/main/javassist/expr/FieldAccess.java @@ -260,7 +260,7 @@ public class FieldAccess extends Expr { public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) throws CompileError { - if (gen.atMethodArgsLength(args) != 1) + if (gen.getMethodArgsLength(args) != 1) throw new CompileError(Javac.proceedName + "() cannot take more than one parameter " + "for field writing"); diff --git a/src/main/javassist/expr/Instanceof.java b/src/main/javassist/expr/Instanceof.java index c9ae9138..9743c841 100644 --- a/src/main/javassist/expr/Instanceof.java +++ b/src/main/javassist/expr/Instanceof.java @@ -141,7 +141,7 @@ public class Instanceof extends Expr { public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) throws CompileError { - if (gen.atMethodArgsLength(args) != 1) + if (gen.getMethodArgsLength(args) != 1) throw new CompileError(Javac.proceedName + "() cannot take more than one parameter " + "for instanceof"); diff --git a/src/main/javassist/expr/MethodCall.java b/src/main/javassist/expr/MethodCall.java index 9eee7fe9..80b35f15 100644 --- a/src/main/javassist/expr/MethodCall.java +++ b/src/main/javassist/expr/MethodCall.java @@ -198,6 +198,9 @@ public class MethodCall extends Expr { int retVar = jc.recordReturnType(retType, true); if (c == INVOKESTATIC) jc.recordStaticProceed(classname, methodname); + else if (c == INVOKESPECIAL) + jc.recordSpecialProceed(Javac.param0Name, classname, + methodname, signature); else jc.recordProceed(Javac.param0Name, methodname); |