diff --git a/src/main/java/net/raphimc/viaproxy/injection/Java17ToJava8.java b/src/main/java/net/raphimc/viaproxy/injection/Java17ToJava8.java index c6ed00e..f59293b 100644 --- a/src/main/java/net/raphimc/viaproxy/injection/Java17ToJava8.java +++ b/src/main/java/net/raphimc/viaproxy/injection/Java17ToJava8.java @@ -143,10 +143,10 @@ public class Java17ToJava8 implements IBytecodeTransformer { list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Collections", "unmodifiableList", "(Ljava/util/List;)Ljava/util/List;")); } } else if (min.name.equals("copyOf")) { - // TODO: Fix - /*list.add(new TypeInsnNode(Opcodes.NEW, "java/util/ArrayList")); - list.add(new InsnNode(Opcodes.DUP)); - list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "", "(Ljava/util/Collection;)V"));*/ + list.add(new TypeInsnNode(Opcodes.NEW, "java/util/ArrayList")); + list.add(new InsnNode(Opcodes.DUP_X1)); + list.add(new InsnNode(Opcodes.SWAP)); + list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "", "(Ljava/util/Collection;)V")); list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Collections", "unmodifiableList", "(Ljava/util/List;)Ljava/util/List;")); } @@ -188,10 +188,10 @@ public class Java17ToJava8 implements IBytecodeTransformer { list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Collections", "unmodifiableSet", "(Ljava/util/Set;)Ljava/util/Set;")); } } else if (min.name.equals("copyOf")) { - // TODO: Fix - /*list.add(new TypeInsnNode(Opcodes.NEW, "java/util/HashSet")); - list.add(new InsnNode(Opcodes.DUP)); - list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/HashSet", "", "(Ljava/util/Collection;)V"));*/ + list.add(new TypeInsnNode(Opcodes.NEW, "java/util/HashSet")); + list.add(new InsnNode(Opcodes.DUP_X1)); + list.add(new InsnNode(Opcodes.SWAP)); + list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/HashSet", "", "(Ljava/util/Collection;)V")); list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Collections", "unmodifiableSet", "(Ljava/util/Set;)Ljava/util/Set;")); } @@ -216,11 +216,34 @@ public class Java17ToJava8 implements IBytecodeTransformer { if (min.name.equals("of")) { final Type[] args = Type.getArgumentTypes(min.desc); - if (args.length == 0) { + if (args.length != 1 || args[0].getSort() != Type.ARRAY) { + int freeVarIndex = ASMUtils.getFreeVarIndex(method); + + int argCount = args.length; + if (argCount % 2 != 0) { + throw new RuntimeException("Map.of() requires an even number of arguments"); + } + list.add(new TypeInsnNode(Opcodes.NEW, "java/util/HashMap")); list.add(new InsnNode(Opcodes.DUP)); list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/HashMap", "", "()V")); + list.add(new VarInsnNode(Opcodes.ASTORE, freeVarIndex)); + for (int i = 0; i < argCount / 2; i++) { + list.add(new VarInsnNode(Opcodes.ALOAD, freeVarIndex)); + list.add(new InsnNode(Opcodes.DUP_X2)); + list.add(new InsnNode(Opcodes.POP)); + list.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")); + list.add(new InsnNode(Opcodes.POP)); + } + list.add(new VarInsnNode(Opcodes.ALOAD, freeVarIndex)); + list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Collections", "unmodifiableMap", "(Ljava/util/Map;)Ljava/util/Map;")); } + } else if (min.name.equals("copyOf")) { + list.add(new TypeInsnNode(Opcodes.NEW, "java/util/HashMap")); + list.add(new InsnNode(Opcodes.DUP_X1)); + list.add(new InsnNode(Opcodes.SWAP)); + list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/HashMap", "", "(Ljava/util/Map;)V")); + list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Collections", "unmodifiableMap", "(Ljava/util/Map;)Ljava/util/Map;")); } if (list.size() != 0) {