]> source.dussan.org Git - javassist.git/commitdiff
modifies the implementation of that invokes an interface default method
authorchibash <chiba@javassist.org>
Tue, 23 Feb 2016 10:22:13 +0000 (19:22 +0900)
committerchibash <chiba@javassist.org>
Tue, 23 Feb 2016 10:22:13 +0000 (19:22 +0900)
src/main/javassist/bytecode/Bytecode.java
src/main/javassist/compiler/Javac.java
src/main/javassist/compiler/JvstCodeGen.java
src/main/javassist/expr/MethodCall.java
src/test/javassist/JvstTest5.java
src/test/test5/ProceedDefault.java [new file with mode: 0644]

index 282a01a396ce312d7be4f7789de48d13d3ee27a5..4de69dab30f3dec02178ffd444d908b625a5184c 100644 (file)
@@ -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);
     }
index f98d1d2323ab6660e1e3036e419f1633f88a5539..fc3d803f977fd9c3dfc8c490567f85732618dca2 100644 (file)
@@ -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);
                 }
 
             };
index e929578be2e4ebaefef5677ed9b17a55fea6f365..797db0ce84cde2def898987d2f3674374d47d279 100644 (file)
@@ -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();
     }
index 7971bbda35344a19233e687962bbbbcfa287fa02..0fbdf0c361e1a94d82e1067292e82e8d997ce329 100644 (file)
@@ -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);
 
index eff7b45144bf86a33c2edae1bc014ca62b2c737a..3c195fafe9313be0bc7ae5fdaa9cb899a3f199c6 100644 (file)
@@ -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 (file)
index 0000000..18e2ee1
--- /dev/null
@@ -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();
+    }
+}