Skip to content

Instantly share code, notes, and snippets.

@DasBrain
Last active June 17, 2022 15:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DasBrain/cbc84aaec30f2c04154b7baf0c68b6f8 to your computer and use it in GitHub Desktop.
Save DasBrain/cbc84aaec30f2c04154b7baf0c68b6f8 to your computer and use it in GitHub Desktop.
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