aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchibash <chiba@javassist.org>2016-02-23 19:22:13 +0900
committerchibash <chiba@javassist.org>2016-02-23 19:22:13 +0900
commitd2d00601aa273adc4ceb47cc449fada0d35cb893 (patch)
tree208fe176ac144aace2a97f4add6d3a3a4e563663
parent949def744d8a9c7e4edec31a24b00651ad1fada3 (diff)
downloadjavassist-d2d00601aa273adc4ceb47cc449fada0d35cb893.tar.gz
javassist-d2d00601aa273adc4ceb47cc449fada0d35cb893.zip
modifies the implementation of that invokes an interface default method
-rw-r--r--src/main/javassist/bytecode/Bytecode.java16
-rw-r--r--src/main/javassist/compiler/Javac.java12
-rw-r--r--src/main/javassist/compiler/JvstCodeGen.java7
-rw-r--r--src/main/javassist/expr/MethodCall.java2
-rw-r--r--src/test/javassist/JvstTest5.java15
-rw-r--r--src/test/test5/ProceedDefault.java13
6 files changed, 52 insertions, 13 deletions
diff --git a/src/main/javassist/bytecode/Bytecode.java b/src/main/javassist/bytecode/Bytecode.java
index 282a01a3..4de69dab 100644
--- a/src/main/javassist/bytecode/Bytecode.java
+++ b/src/main/javassist/bytecode/Bytecode.java
@@ -976,13 +976,27 @@ public class Bytecode extends ByteVector implements Cloneable, Opcode {
* @see Descriptor#ofConstructor(CtClass[])
*/
public void addInvokespecial(boolean isInterface, int clazz, String name, String desc) {
- add(INVOKESPECIAL);
int index;
if (isInterface)
index = constPool.addInterfaceMethodrefInfo(clazz, name, desc);
else
index = constPool.addMethodrefInfo(clazz, name, desc);
+ addInvokespecial(index, desc);
+ }
+
+ /**
+ * Appends INVOKESPECIAL.
+ *
+ * @param index the index of <code>CONSTANT_Methodref_info</code>
+ * or <code>CONSTANT_InterfaceMethodref_info</code>
+ * @param desc the descriptor of the method signature.
+ *
+ * @see Descriptor#ofMethod(CtClass,CtClass[])
+ * @see Descriptor#ofConstructor(CtClass[])
+ */
+ public void addInvokespecial(int index, String desc) {
+ add(INVOKESPECIAL);
addIndex(index);
growStack(Descriptor.dataSize(desc) - 1);
}
diff --git a/src/main/javassist/compiler/Javac.java b/src/main/javassist/compiler/Javac.java
index f98d1d23..fc3d803f 100644
--- a/src/main/javassist/compiler/Javac.java
+++ b/src/main/javassist/compiler/Javac.java
@@ -516,27 +516,25 @@ public class Javac {
* @param methodname the method name.
* @param descriptor the method descriptor.
*/
- public void recordSpecialProceed(String target, String classname,
- String methodname, String descriptor)
+ public void recordSpecialProceed(String target, final String classname,
+ final String methodname, final String descriptor,
+ final int methodIndex)
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.compileInvokeSpecial(texpr, methodIndex, descriptor, args);
}
public void setReturnType(JvstTypeChecker c, ASTList args)
throws CompileError
{
- c.compileInvokeSpecial(texpr, cname, method, desc, args);
+ c.compileInvokeSpecial(texpr, classname, methodname, descriptor, args);
}
};
diff --git a/src/main/javassist/compiler/JvstCodeGen.java b/src/main/javassist/compiler/JvstCodeGen.java
index e929578b..797db0ce 100644
--- a/src/main/javassist/compiler/JvstCodeGen.java
+++ b/src/main/javassist/compiler/JvstCodeGen.java
@@ -393,16 +393,15 @@ public class JvstCodeGen extends MemberCodeGen {
/* called by Javac#recordSpecialProceed().
*/
- void compileInvokeSpecial(ASTree target, String classname,
- String methodname, String descriptor,
- ASTList args)
+ void compileInvokeSpecial(ASTree target, int methodIndex,
+ 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);
+ bytecode.addInvokespecial(methodIndex, descriptor);
setReturnType(descriptor, false, false);
addNullIfVoid();
}
diff --git a/src/main/javassist/expr/MethodCall.java b/src/main/javassist/expr/MethodCall.java
index 7971bbda..0fbdf0c3 100644
--- a/src/main/javassist/expr/MethodCall.java
+++ b/src/main/javassist/expr/MethodCall.java
@@ -215,7 +215,7 @@ public class MethodCall extends Expr {
jc.recordStaticProceed(classname, methodname);
else if (c == INVOKESPECIAL)
jc.recordSpecialProceed(Javac.param0Name, classname,
- methodname, signature);
+ methodname, signature, index);
else
jc.recordProceed(Javac.param0Name, methodname);
diff --git a/src/test/javassist/JvstTest5.java b/src/test/javassist/JvstTest5.java
index eff7b451..3c195faf 100644
--- a/src/test/javassist/JvstTest5.java
+++ b/src/test/javassist/JvstTest5.java
@@ -7,6 +7,8 @@ import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import javassist.bytecode.InnerClassesAttribute;
+import javassist.expr.ExprEditor;
+import javassist.expr.MethodCall;
public class JvstTest5 extends JvstTestRoot {
public JvstTest5(String name) {
@@ -168,4 +170,17 @@ public class JvstTest5 extends JvstTestRoot {
java.lang.annotation.Annotation[] annotations = o.getClass().getDeclaredAnnotations();
assertEquals(1, annotations.length);
}
+
+ public void testProceedToDefaultMethod() throws Exception {
+ CtClass cc = ClassPool.getDefault().get("test5.ProceedDefault");
+ CtMethod mth = cc.getDeclaredMethod("bar");
+ mth.instrument(new ExprEditor() {
+ public void edit(MethodCall c) throws CannotCompileException {
+ c.replace("$_ = $proceed($$) + 10000;");
+ }
+ });
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(21713, invoke(obj, "run"));
+ }
}
diff --git a/src/test/test5/ProceedDefault.java b/src/test/test5/ProceedDefault.java
new file mode 100644
index 00000000..18e2ee18
--- /dev/null
+++ b/src/test/test5/ProceedDefault.java
@@ -0,0 +1,13 @@
+package test5;
+
+interface ProceedDefaultI {
+ default int foo() { return 13; }
+}
+
+public class ProceedDefault implements ProceedDefaultI {
+ public int run() { return bar(); }
+ public int foo() { return 1700; }
+ public int bar() {
+ return foo() + ProceedDefaultI.super.foo();
+ }
+}