summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/javassist/compiler/Javac.java33
-rw-r--r--src/main/javassist/compiler/JvstCodeGen.java22
-rw-r--r--src/main/javassist/compiler/MemberCodeGen.java7
-rw-r--r--src/main/javassist/expr/Cast.java2
-rw-r--r--src/main/javassist/expr/FieldAccess.java2
-rw-r--r--src/main/javassist/expr/Instanceof.java2
-rw-r--r--src/main/javassist/expr/MethodCall.java3
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);