Skip to content

Commit a63c18b

Browse files
committed
svm: migrate changeLambdaClassName to ClassFile API
1 parent 1da4c6f commit a63c18b

File tree

1 file changed

+41
-41
lines changed

1 file changed

+41
-41
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/PredefinedClassesSupport.java

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,21 @@
2525
*/
2626
package com.oracle.svm.core.hub;
2727

28+
import static java.lang.classfile.ClassFile.ConstantPoolSharingOption.NEW_POOL;
29+
2830
import java.io.Serializable;
31+
import java.lang.classfile.ClassFile;
32+
import java.lang.classfile.ClassModel;
33+
import java.lang.classfile.ClassTransform;
34+
import java.lang.classfile.MethodTransform;
35+
import java.lang.classfile.constantpool.ClassEntry;
36+
import java.lang.classfile.instruction.FieldInstruction;
37+
import java.lang.classfile.instruction.InvokeInstruction;
38+
import java.lang.classfile.instruction.NewMultiArrayInstruction;
39+
import java.lang.classfile.instruction.NewObjectInstruction;
40+
import java.lang.classfile.instruction.NewReferenceArrayInstruction;
41+
import java.lang.classfile.instruction.TypeCheckInstruction;
42+
import java.lang.constant.ClassDesc;
2943
import java.lang.reflect.Method;
3044
import java.security.ProtectionDomain;
3145
import java.util.HashSet;
@@ -44,11 +58,6 @@
4458
import com.oracle.svm.core.reflect.serialize.SerializationSupport;
4559
import com.oracle.svm.core.util.ImageHeapMap;
4660
import com.oracle.svm.core.util.VMError;
47-
import com.oracle.svm.shaded.org.objectweb.asm.ClassReader;
48-
import com.oracle.svm.shaded.org.objectweb.asm.ClassVisitor;
49-
import com.oracle.svm.shaded.org.objectweb.asm.ClassWriter;
50-
import com.oracle.svm.shaded.org.objectweb.asm.MethodVisitor;
51-
import com.oracle.svm.shaded.org.objectweb.asm.Opcodes;
5261
import com.oracle.svm.util.ClassUtil;
5362

5463
import jdk.graal.compiler.api.replacements.Fold;
@@ -332,41 +341,32 @@ public static Class<?> maybeAdjustLambdaNestHost(String className, Class<?> java
332341

333342
@Platforms(Platform.HOSTED_ONLY.class)
334343
public static byte[] changeLambdaClassName(byte[] data, String oldName, String newName) {
335-
ClassReader cr = new ClassReader(data);
336-
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
337-
338-
cr.accept(new ClassVisitor(Opcodes.ASM5, cw) {
339-
// Change lambda class name in the bytecode
340-
@Override
341-
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
342-
super.visit(version, access, newName, signature, superName, interfaces);
343-
}
344-
345-
// Change all class references in the lambda class bytecode
346-
@Override
347-
public MethodVisitor visitMethod(int access, String originalName, String desc, String signature, String[] exceptions) {
348-
return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, originalName, desc, signature, exceptions)) {
349-
@Override
350-
public void visitTypeInsn(int opcode, String type) {
351-
String name = type.equals(oldName) ? newName : type;
352-
super.visitTypeInsn(opcode, name);
353-
}
354-
355-
@Override
356-
public void visitMethodInsn(int opcode, String owner, String methodName, String descriptor, boolean isInterface) {
357-
String name = owner.equals(oldName) ? newName : owner;
358-
super.visitMethodInsn(opcode, name, methodName, descriptor, isInterface);
359-
}
360-
361-
@Override
362-
public void visitFieldInsn(int opcode, String owner, String fieldName, String descriptor) {
363-
String name = owner.equals(oldName) ? newName : owner;
364-
super.visitFieldInsn(opcode, name, fieldName, descriptor);
365-
}
366-
};
367-
}
368-
}, ClassReader.EXPAND_FRAMES);
369-
370-
return cw.toByteArray();
344+
ClassDesc oldDesc = ClassDesc.ofInternalName(oldName);
345+
ClassDesc newDesc = ClassDesc.ofInternalName(newName);
346+
347+
ClassFile classFile = ClassFile.of(NEW_POOL);
348+
ClassModel original = classFile.parse(data);
349+
350+
return classFile.transformClass(original, newDesc,
351+
ClassTransform.transformingMethods(
352+
MethodTransform.transformingCode((builder, element) -> {
353+
ClassEntry newClassEntry = builder.constantPool().classEntry(newDesc);
354+
// Pass through any unhandled elements unchanged
355+
if (element instanceof TypeCheckInstruction ti && ti.type().asSymbol().equals(oldDesc)) {
356+
builder.with(TypeCheckInstruction.of(ti.opcode(), newClassEntry));
357+
} else if (element instanceof NewObjectInstruction ti && ti.className().asSymbol().equals(oldDesc)) {
358+
builder.with(NewObjectInstruction.of(newClassEntry));
359+
} else if (element instanceof NewReferenceArrayInstruction ti && ti.componentType().asSymbol().equals(oldDesc)) {
360+
builder.with(NewReferenceArrayInstruction.of(newClassEntry));
361+
} else if (element instanceof NewMultiArrayInstruction ti && ti.arrayType().asSymbol().equals(oldDesc)) {
362+
builder.with(NewMultiArrayInstruction.of(newClassEntry, ti.dimensions()));
363+
} else if (element instanceof InvokeInstruction mi && mi.owner().asSymbol().equals(oldDesc)) {
364+
builder.with(InvokeInstruction.of(mi.opcode(), newClassEntry, mi.name(), mi.type(), mi.isInterface()));
365+
} else if (element instanceof FieldInstruction fi && fi.owner().asSymbol().equals(oldDesc)) {
366+
builder.with(FieldInstruction.of(fi.opcode(), newClassEntry, fi.name(), fi.type()));
367+
} else {
368+
builder.with(element);
369+
}
370+
})));
371371
}
372372
}

0 commit comments

Comments
 (0)