From 9adc1a3526d58f7123a0837d4c5c68eb6a7099dd Mon Sep 17 00:00:00 2001 From: LiuChuliang 刘楚梁 Date: Thu, 18 Jan 2024 16:11:16 +0800 Subject: support bootstrap method coping when using code coping --- src/test/javassist/bytecode/BytecodeTest.java | 39 +++++++++++++++++++++------ src/test/test4/InvokeDynCopyDest.java | 11 ++++++++ src/test/test4/InvokeDynCopySrc.java | 17 ++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 src/test/test4/InvokeDynCopyDest.java create mode 100644 src/test/test4/InvokeDynCopySrc.java (limited to 'src/test') diff --git a/src/test/javassist/bytecode/BytecodeTest.java b/src/test/javassist/bytecode/BytecodeTest.java index eac420bc..68e3b2c2 100644 --- a/src/test/javassist/bytecode/BytecodeTest.java +++ b/src/test/javassist/bytecode/BytecodeTest.java @@ -6,6 +6,7 @@ import junit.framework.*; import javassist.*; import javassist.bytecode.annotation.*; import javassist.bytecode.SignatureAttribute.*; +import test4.InvokeDynCopyDest; @SuppressWarnings("unused") public class BytecodeTest extends TestCase { @@ -461,19 +462,19 @@ public class BytecodeTest extends TestCase { public void testSignatureChange() throws Exception { changeMsig("(TS;[TS;)Ljava/lang/Object", "java/lang/Object", - "(TS;[TS;)Ljava/lang/Object", "java/lang/Objec"); + "(TS;[TS;)Ljava/lang/Object", "java/lang/Objec"); changeMsig("(TS;[TS;)TT;", "java/lang/Object", - "(TS;[TS;)TT;", "java/lang/Objec"); + "(TS;[TS;)TT;", "java/lang/Objec"); changeMsig("(TS;[TS;)Ljava/lang/Object2;", "java/lang/Object", - "(TS;[TS;)Ljava/lang/Object2;", "java/lang/Objec"); + "(TS;[TS;)Ljava/lang/Object2;", "java/lang/Objec"); changeMsig("(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object", - "(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object2"); + "(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object2"); changeMsig2("(TS;[TS;)TT;", "java/lang/Object", - "(TS;[TS;)TT;", "java/lang/Objec"); + "(TS;[TS;)TT;", "java/lang/Objec"); changeMsig2("(TS;[TS;)Ljava/lang/Object2;", "java/lang/Object", - "(TS;[TS;)Ljava/lang/Object2;", "java/lang/Objec"); + "(TS;[TS;)Ljava/lang/Object2;", "java/lang/Objec"); changeMsig2("(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object", - "(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object2"); + "(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object2"); String sig = "LPoi$Foo;LBar;LBar2;"; String res = "LPoi$Foo;LBar;LBar2;"; changeMsig(sig, "java/lang/String", res, "java/lang/String2"); @@ -683,7 +684,7 @@ public class BytecodeTest extends TestCase { assertFalse(fi1.equals(fi3)); assertFalse(fi1.equals(ci1)); assertFalse(fi1.equals(null)); - + LongInfo li1 = new LongInfo(12345L, n++); LongInfo li2 = new LongInfo(12345L, n++); LongInfo li3 = new LongInfo(-12345L, n++); @@ -834,6 +835,28 @@ public class BytecodeTest extends TestCase { assertEquals("(I)V", cPool2.getUtf8Info(cPool2.getMethodTypeInfo(mtIndex))); } + public void testInvokeDynamicWithCopy() throws Exception { + CtClass srcCc = loader.get("test4.InvokeDynCopySrc"); + CtClass destCc = loader.get("test4.InvokeDynCopyDest"); + + // copy source constructor to dest + for (CtConstructor constructor : destCc.getConstructors()) { + for (CtConstructor srcClassConstructor : srcCc.getConstructors()) { + if (constructor.getSignature().equalsIgnoreCase(srcClassConstructor.getSignature())) { + constructor.setBody(srcClassConstructor, null); + } + } + } + + // set dest class method body by source class + destCc.getDeclaredMethod("getString").setBody(srcCc.getDeclaredMethod("getString"), new ClassMap()); + + Object destObj = (new Loader(loader)).loadClass(destCc.getName()).getConstructor().newInstance(); + + // if don't copy bootstrap method and static lambda method it will throw exception when invoke + assertEquals("hello", destObj.getClass().getMethod("getString").invoke(destObj)); + } + public static Test suite() { TestSuite suite = new TestSuite("Bytecode Tests"); suite.addTestSuite(BytecodeTest.class); diff --git a/src/test/test4/InvokeDynCopyDest.java b/src/test/test4/InvokeDynCopyDest.java new file mode 100644 index 00000000..003c7c53 --- /dev/null +++ b/src/test/test4/InvokeDynCopyDest.java @@ -0,0 +1,11 @@ +package test4; + +public class InvokeDynCopyDest { + public InvokeDynCopyDest() { + System.out.println("my output:" + getString()); + } + + public String getString() { + return "dest"; + } +} diff --git a/src/test/test4/InvokeDynCopySrc.java b/src/test/test4/InvokeDynCopySrc.java new file mode 100644 index 00000000..83291f7b --- /dev/null +++ b/src/test/test4/InvokeDynCopySrc.java @@ -0,0 +1,17 @@ +package test4; + +import java.util.function.Supplier; + +public class InvokeDynCopySrc { + public InvokeDynCopySrc() { + System.out.println("source class:" + getString()); + } + + public String getString() { + Supplier stringSupplier = () -> { + return "hello"; + }; + + return stringSupplier.get(); + } +} -- cgit v1.2.3