From 33812d04ebbb971e984dcb8c8f34f0cc7ba5e4c3 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Thu, 26 Sep 2024 23:49:34 -0700 Subject: [PATCH 1/2] Manually emit stack frames in EnumValueOfRewriteRule --- .../papermc/asm/rules/rename/EnumValueOfRewriteRule.java | 8 ++++++++ src/test/java/io/papermc/asm/TestUtil.java | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/papermc/asm/rules/rename/EnumValueOfRewriteRule.java b/src/main/java/io/papermc/asm/rules/rename/EnumValueOfRewriteRule.java index c47da46..14f63b0 100644 --- a/src/main/java/io/papermc/asm/rules/rename/EnumValueOfRewriteRule.java +++ b/src/main/java/io/papermc/asm/rules/rename/EnumValueOfRewriteRule.java @@ -66,6 +66,8 @@ public void generateMethod(final GeneratorAdapterFactory factory, final MethodCa methodGenerator.visitLookupSwitchInsn(lookupSwitchEndLabel, lookupSwitchKeys, labels); for (int i = 0; i < labels.length; i++) { methodGenerator.mark(labels[i]); + // LocalVariableSorter inserts trailing int local for i == 0 + methodGenerator.visitFrame(Opcodes.F_NEW, 1, new Object[]{"java/lang/String"}, 1, new Object[]{"java/lang/String"}); // generate case final List matchingStrings = hashToField.get(lookupSwitchKeys[i]); if (matchingStrings.size() == 1) { @@ -93,11 +95,13 @@ public void generateMethod(final GeneratorAdapterFactory factory, final MethodCa methodGenerator.goTo(lookupSwitchEndLabel); if (nestedLabels[j] != lookupSwitchEndLabel) { methodGenerator.mark(nestedLabels[j]); // mark start of next label (except last one) + methodGenerator.visitFrame(Opcodes.F_NEW, 1, new Object[]{"java/lang/String"}, 1, new Object[]{"java/lang/String"}); } } } } methodGenerator.mark(lookupSwitchEndLabel); + methodGenerator.visitFrame(Opcodes.F_NEW, 1, new Object[]{"java/lang/String"}, 1, new Object[]{"java/lang/String"}); methodGenerator.loadLocal(tableSwitchIndexLocal); final Label[] tableSwitchLabels = new Label[tableSwitchIndexToRenamedField.length]; for (int i = 0; i < tableSwitchLabels.length; i++) { @@ -108,12 +112,16 @@ public void generateMethod(final GeneratorAdapterFactory factory, final MethodCa methodGenerator.visitTableSwitchInsn(0, tableSwitchIndexToRenamedField.length - 1, tableSwitchDefaultLabel, tableSwitchLabels); for (int i = 0; i < tableSwitchIndexToRenamedField.length; i++) { methodGenerator.mark(tableSwitchLabels[i]); + methodGenerator.visitFrame(Opcodes.F_NEW, 1, new Object[]{"java/lang/String"}, 1, new Object[]{"java/lang/String"}); methodGenerator.push(tableSwitchIndexToRenamedField[i]); methodGenerator.goTo(tableSwitchEndLabel); } methodGenerator.mark(tableSwitchDefaultLabel); + methodGenerator.visitFrame(Opcodes.F_NEW, 1, new Object[]{"java/lang/String"}, 1, new Object[]{"java/lang/String"}); methodGenerator.loadArg(0); // default to the passed in value methodGenerator.mark(tableSwitchEndLabel); + // LocalVariableSorter inserts trailing int local + methodGenerator.visitFrame(Opcodes.F_NEW, 1, new Object[]{"java/lang/String"}, 2, new Object[]{"java/lang/String", "java/lang/String"}); methodGenerator.invokeStatic(Type.getType(original.owner().descriptorString()), new Method(original.name(), original.descriptor().descriptorString())); methodGenerator.returnValue(); methodGenerator.endMethod(); diff --git a/src/test/java/io/papermc/asm/TestUtil.java b/src/test/java/io/papermc/asm/TestUtil.java index 5d9a926..88fa2c5 100644 --- a/src/test/java/io/papermc/asm/TestUtil.java +++ b/src/test/java/io/papermc/asm/TestUtil.java @@ -54,9 +54,9 @@ public byte[] process(final byte[] bytes) { final ClassReader classReader = new ClassReader(bytes); final ClassWriter classWriter; if (this.copyFromClassReader()) { - classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS); } else { - classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); } classReader.accept(this.factory.createVisitor(classWriter), 0); return classWriter.toByteArray(); From 4ee50f50dff0d14d7a2c7029a016b06ec4c7a635 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:53:35 -0700 Subject: [PATCH 2/2] Update comments --- .../io/papermc/asm/rules/rename/EnumValueOfRewriteRule.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/io/papermc/asm/rules/rename/EnumValueOfRewriteRule.java b/src/main/java/io/papermc/asm/rules/rename/EnumValueOfRewriteRule.java index 14f63b0..139233b 100644 --- a/src/main/java/io/papermc/asm/rules/rename/EnumValueOfRewriteRule.java +++ b/src/main/java/io/papermc/asm/rules/rename/EnumValueOfRewriteRule.java @@ -66,7 +66,7 @@ public void generateMethod(final GeneratorAdapterFactory factory, final MethodCa methodGenerator.visitLookupSwitchInsn(lookupSwitchEndLabel, lookupSwitchKeys, labels); for (int i = 0; i < labels.length; i++) { methodGenerator.mark(labels[i]); - // LocalVariableSorter inserts trailing int local for i == 0 + // LocalVariableSorter will insert the trailing int local for this and all following visitFrame calls; adding it manually would cause duplicate locals in the frame methodGenerator.visitFrame(Opcodes.F_NEW, 1, new Object[]{"java/lang/String"}, 1, new Object[]{"java/lang/String"}); // generate case final List matchingStrings = hashToField.get(lookupSwitchKeys[i]); @@ -120,7 +120,6 @@ public void generateMethod(final GeneratorAdapterFactory factory, final MethodCa methodGenerator.visitFrame(Opcodes.F_NEW, 1, new Object[]{"java/lang/String"}, 1, new Object[]{"java/lang/String"}); methodGenerator.loadArg(0); // default to the passed in value methodGenerator.mark(tableSwitchEndLabel); - // LocalVariableSorter inserts trailing int local methodGenerator.visitFrame(Opcodes.F_NEW, 1, new Object[]{"java/lang/String"}, 2, new Object[]{"java/lang/String", "java/lang/String"}); methodGenerator.invokeStatic(Type.getType(original.owner().descriptorString()), new Method(original.name(), original.descriptor().descriptorString())); methodGenerator.returnValue();