Last active
June 17, 2022 15:30
-
-
Save DasBrain/cbc84aaec30f2c04154b7baf0c68b6f8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package test.se17; | |
import java.lang.constant.ClassDesc; | |
import java.lang.constant.ConstantDesc; | |
import java.lang.constant.DirectMethodHandleDesc; | |
import java.lang.constant.DirectMethodHandleDesc.Kind; | |
import java.lang.constant.DynamicConstantDesc; | |
import java.lang.constant.MethodHandleDesc; | |
import java.lang.constant.MethodTypeDesc; | |
import java.lang.invoke.TypeDescriptor; | |
import java.util.Arrays; | |
import org.objectweb.asm.ConstantDynamic; | |
import org.objectweb.asm.Handle; | |
import org.objectweb.asm.Type; | |
public final class ASMUtils { | |
private ASMUtils() { | |
} | |
public static String toInternal(TypeDescriptor.OfField<?> td) { | |
String desc = td.descriptorString(); | |
if (desc.charAt(0) != 'L') { | |
throw new IllegalArgumentException("expected class, got " + desc); | |
} | |
return desc.substring(1, desc.length() - 1); | |
} | |
public static ClassDesc fromInternal(String name) { | |
return ClassDesc.ofDescriptor("L" + name + ";"); | |
} | |
public static ConstantDesc fromASM(Object o) { | |
if (o instanceof Integer i) | |
return i; | |
if (o instanceof Float f) | |
return f; | |
if (o instanceof Long l) | |
return l; | |
if (o instanceof Double d) | |
return d; | |
if (o instanceof String s) | |
return s; | |
if (o instanceof Type t) | |
return fromASM(t); | |
if (o instanceof Handle h) | |
return fromASM(h); | |
if (o instanceof ConstantDynamic cd) | |
return fromASM(cd); | |
throw new IllegalArgumentException("Unknown Type passed: " + o.getClass()); | |
} | |
public static Integer fromASM(Integer i) { | |
return i; | |
} | |
public static Float fromASM(Float f) { | |
return f; | |
} | |
public static Long fromASM(Long l) { | |
return l; | |
} | |
public static Double fromASM(Double d) { | |
return d; | |
} | |
public static String fromASM(String s) { | |
return s; | |
} | |
public static ConstantDesc fromASM(Type t) { | |
return switch (t.getSort()) { | |
case Type.METHOD -> MethodTypeDesc.ofDescriptor(t.getDescriptor()); | |
default -> ClassDesc.ofDescriptor(t.getDescriptor()); | |
}; | |
} | |
public static DirectMethodHandleDesc fromASM(Handle h) { | |
return MethodHandleDesc.of(Kind.valueOf(h.getTag(), h.isInterface()), | |
fromInternal(h.getOwner()), h.getName(), h.getDesc()); | |
} | |
public static DynamicConstantDesc<?> fromASM(ConstantDynamic cd) { | |
ConstantDesc[] args = new ConstantDesc[cd.getBootstrapMethodArgumentCount()]; | |
for (int i = 0; i < cd.getBootstrapMethodArgumentCount(); i++) { | |
args[i] = fromASM(cd.getBootstrapMethodArgument(i)); | |
} | |
return DynamicConstantDesc.ofNamed(fromASM(cd.getBootstrapMethod()), cd.getName(), | |
ClassDesc.ofDescriptor(cd.getDescriptor()), args); | |
} | |
public static Object toASM(ConstantDesc desc) { | |
if (desc instanceof Integer i) | |
return i; | |
if (desc instanceof Float f) | |
return f; | |
if (desc instanceof Long l) | |
return l; | |
if (desc instanceof Double d) | |
return d; | |
if (desc instanceof String s) | |
return s; | |
if (desc instanceof DynamicConstantDesc<?> dcd) | |
return toASM(dcd); | |
if (desc instanceof ClassDesc cd) | |
return toASM((TypeDescriptor) cd); // Primitives implement both DCD & CD | |
if (desc instanceof MethodTypeDesc mtd) | |
return toASM((TypeDescriptor) mtd); | |
if (desc instanceof DirectMethodHandleDesc dmhd) | |
return toASM(dmhd); | |
throw new AssertionError("Should not reach here"); | |
} | |
public static Integer toASM(Integer i) { | |
return i; | |
} | |
public static Float toASM(Float f) { | |
return f; | |
} | |
public static Long toASM(Long l) { | |
return l; | |
} | |
public static Double toASM(Double d) { | |
return d; | |
} | |
public static String toASM(String s) { | |
return s; | |
} | |
public static ConstantDynamic toASM(DynamicConstantDesc<?> dcd) { | |
return new ConstantDynamic(dcd.constantName(), dcd.constantType().descriptorString(), | |
toASM(dcd.bootstrapMethod()), | |
Arrays.stream(dcd.bootstrapArgs()).map(ASMUtils::toASM).toArray()); | |
} | |
public static Type toASM(TypeDescriptor td) { | |
return Type.getType(td.descriptorString()); | |
} | |
public static Handle toASM(DirectMethodHandleDesc dmhd) { | |
return new Handle(dmhd.refKind(), toInternal(dmhd.owner()), dmhd.methodName(), | |
dmhd.lookupDescriptor(), dmhd.isOwnerInterface()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment