- 236
- 4
- 22
Доброй ночи всем. Нужна мелкая помощь по asm`у. Вообщем, очень часто бывают случаи, где нужно "запаковать" значение в локальную переменную. Допустим чтобы вставить код до RETURN`а / THROW`a и не только. Так вот, чтобы "создать" эту переменную я всегда пользовался следующим кодом, который сам же написал, и как ни странно, он работал нормально:
Но по неизвестным причинам этот способ перестал работать и начал давать ошибку при использовании. Возможно беда в флагах для ClassReader и(или) ClassWriter. Для них я в последнее время юзаю примерно такую логику, не знаю на сколько она верна, ибо в гугле нет инфы, как определить, какие флаги нужно сюда пихать, по этому если знаете как правильнее - напишите. Текущий код:
Основной же мой вопрос - как "доделать" метод генерации локальных переменных в методе, чтобы не было подобных ошибок (краш ниже)?
Генерация локальной переменной:
public static LocalVariableNode createLocalField(MethodNode method, String descriptor) {
var label = new LabelNode();
if (method.localVariables == null)
method.localVariables = new ArrayList();
var defaultName = "varASM_";
var suffix = method.localVariables.stream().filter(var -> var.name.startsWith(defaultName)).map((varx) -> varx.name.substring(defaultName.length())).mapToInt(ASMUtils::parseInt).max().orElse(-1) + 1;
var var = new LocalVariableNode(defaultName + suffix, descriptor, (String)null, label, label, method.localVariables.size());
method.localVariables.add(var);
return var;
}
private static int parseInt(String str) {
try {
return Integer.parseInt(str);
} catch (Exception var2) {
return 0;
}
}
Основа трансформера:
public byte[] transform(String name, String transformedName, byte[] clazzBytes) {
ClassNode classNode = new ClassNode();
int majorVersion = (clazzBytes[6] & 255) << 8 | clazzBytes[7] & 255;
boolean java7 = majorVersion > 50;
ClassReader classReader = new ClassReader(clazzBytes);
classReader.accept(classNode, java7 ? 4 : 8);
//Сам трансформер
ClassWriter writer = new ClassWriter(java7 ? 2 : 1);
classNode.accept(writer);
return writer.toByteArray();
}
- Краш-лог
-
[00:15:36] [main/ERROR] [LaunchWrapper]: Unable to launch
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_292]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_292]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_292]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_292]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
at GradleStart.main(Unknown Source) [start/:?]
Caused by: java.lang.NoClassDefFoundError: net/minecraft/block/BlockStaticLiquid
at net.minecraft.block.Block.registerBlocks(Block.java:250) ~[Block.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:457) ~[Bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more
Caused by: java.lang.ClassNotFoundException: net.minecraft.block.BlockStaticLiquid
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191) ~[launchwrapper-1.12.jar:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_292]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_292]
at net.minecraft.block.Block.registerBlocks(Block.java:250) ~[Block.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:457) ~[Bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
at org.objectweb.asm.Frame.merge(Frame.java:1311) ~[asm-debug-all-5.0.3.jar:5.0.3]
at org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1475) ~[asm-debug-all-5.0.3.jar:5.0.3]
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:834) ~[asm-debug-all-5.0.3.jar:5.0.3]
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:726) ~[asm-debug-all-5.0.3.jar:5.0.3]
at org.objectweb.asm.tree.ClassNode.accept(ClassNode.java:412) ~[asm-debug-all-5.0.3.jar:5.0.3]
at com.mymod.core.handlers.ASMHandler.transform(ASMHandler.java:53) ~[main/:?]
at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279) ~[launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176) ~[launchwrapper-1.12.jar:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_292]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_292]
at net.minecraft.block.Block.registerBlocks(Block.java:250) ~[Block.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:457) ~[Bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more
Краш-лог:
[00:15:36] [main/ERROR] [LaunchWrapper]: Unable to launch
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_292]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_292]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_292]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_292]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
at GradleStart.main(Unknown Source) [start/:?]
Caused by: java.lang.NoClassDefFoundError: net/minecraft/block/BlockStaticLiquid
at net.minecraft.block.Block.registerBlocks(Block.java:250) ~[Block.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:457) ~[Bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more
Caused by: java.lang.ClassNotFoundException: net.minecraft.block.BlockStaticLiquid
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191) ~[launchwrapper-1.12.jar:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_292]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_292]
at net.minecraft.block.Block.registerBlocks(Block.java:250) ~[Block.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:457) ~[Bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: -1
at org.objectweb.asm.Frame.merge(Frame.java:1311) ~[asm-debug-all-5.0.3.jar:5.0.3]
at org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1475) ~[asm-debug-all-5.0.3.jar:5.0.3]
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:834) ~[asm-debug-all-5.0.3.jar:5.0.3]
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:726) ~[asm-debug-all-5.0.3.jar:5.0.3]
at org.objectweb.asm.tree.ClassNode.accept(ClassNode.java:412) ~[asm-debug-all-5.0.3.jar:5.0.3]
at com.mymod.core.handlers.ASMHandler.transform(ASMHandler.java:53) ~[main/:?]
at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279) ~[launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176) ~[launchwrapper-1.12.jar:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_292]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_292]
at net.minecraft.block.Block.registerBlocks(Block.java:250) ~[Block.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:457) ~[Bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more