Move GLErrorTransformer into 1.7.10 project

This commit is contained in:
Jonas Herzig
2021-02-22 23:35:42 +01:00
parent 66c1f63219
commit 1329f2d703
2 changed files with 94 additions and 95 deletions

View File

@@ -1,95 +1 @@
//#if MC<=10710
//$$ package com.replaymod.core.asm;
//$$
//$$ import net.minecraft.launchwrapper.IClassTransformer;
//$$ import org.lwjgl.opengl.GL11;
//$$ import org.lwjgl.util.glu.GLU;
//$$ import org.objectweb.asm.ClassReader;
//$$ import org.objectweb.asm.ClassVisitor;
//$$ import org.objectweb.asm.ClassWriter;
//$$ import org.objectweb.asm.MethodVisitor;
//$$ import org.objectweb.asm.Opcodes;
//$$
//$$ /**
//$$ * Insert glGetError checks after all calls to any method in any GL*, ARB* and EXT* classes
//$$ */
//$$ public class GLErrorTransformer implements IClassTransformer {
//$$ private static final String GL_CLASS = "org.lwjgl.opengl.GL";
//$$ private static final String GL = GL_CLASS.replace('.', '/');
//$$ private static final String ARB_CLASS = "org.lwjgl.opengl.ARB";
//$$ private static final String ARB = ARB_CLASS.replace('.', '/');
//$$ private static final String EXT_CLASS = "org.lwjgl.opengl.EXT";
//$$ private static final String EXT = EXT_CLASS.replace('.', '/');
//$$ private static final String GLErrorTransformer_CLASS = GLErrorTransformer.class.getName();
//$$ private static final String GLErrorTransformer = GLErrorTransformer_CLASS.replace('.', '/');
//$$
//$$ @Override
//$$ public byte[] transform(String name, String transformedName, byte[] basicClass) {
//$$ if (basicClass == null) return null;
//$$
//$$ ClassReader reader = new ClassReader(basicClass);
//$$ ClassWriter writer = new ClassWriter(reader, 0);
//$$ reader.accept(new ClassVisitor(Opcodes.ASM5, writer) {
//$$ @Override
//$$ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
//$$ MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
//$$ return new MethodVisitor(Opcodes.ASM5, mv) {
//$$ @Override
//$$ public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
//$$ super.visitMethodInsn(opcode, owner, name, desc, itf);
//$$ if (owner.startsWith(GL) || owner.startsWith(ARB) || owner.startsWith(EXT)) {
//$$ visitLdcInsn(owner.replace('/', '.'));
//$$ visitLdcInsn(name);
//$$ super.visitMethodInsn(Opcodes.INVOKESTATIC, GLErrorTransformer, "glErrorCheck", "(Ljava/lang/String;Ljava/lang/String;)V", false);
//$$ }
//$$ }
//$$
//$$ @Override
//$$ public void visitMaxs(int maxStack, int maxLocals) {
//$$ super.visitMaxs(maxStack + 2, maxLocals);
//$$ }
//$$ };
//$$ }
//$$ }, 0);
//$$ return writer.toByteArray();
//$$ }
//$$
//$$ private static boolean inGlBegin;
//$$
//$$ @SuppressWarnings("unused") // Called via ASM
//$$ public static void glErrorCheck(String cls, String method) {
//$$ if (method.equals("glBegin") && cls.equals(GL_CLASS + "11")) {
//$$ if (inGlBegin) {
//$$ // glBegin within glBegin
//$$ throw new GLError(GL11.GL_INVALID_OPERATION, cls, method);
//$$ }
//$$ inGlBegin = true;
//$$ return;
//$$ }
//$$ if (inGlBegin && method.equals("glEnd") && cls.equals(GL_CLASS + "11")) {
//$$ inGlBegin = false;
//$$ }
//$$ if (inGlBegin) {
//$$ return; // Cannot call glGetError in between of glBegin and glEnd
//$$ }
//$$ int err = GL11.glGetError();
//$$ if (err != 0) {
//$$ GLError e = new GLError(err, cls, method);
//$$ if ("true".equals(System.getProperty("replaymod.glerrors.throw", "true"))) {
//$$ throw e;
//$$ } else {
//$$ e.printStackTrace();
//$$ }
//$$ }
//$$ }
//$$
//$$ public static class GLError extends RuntimeException {
//$$ private GLError(int err, String cls, String method) {
//$$ super(GLU.gluErrorString(err) + " (" + err + ")");
//$$ StackTraceElement[] stack = getStackTrace();
//$$ stack[0] = new StackTraceElement(cls, method, stack[0].getFileName(), stack[0].getLineNumber());
//$$ setStackTrace(stack);
//$$ }
//$$ }
//$$ }
//#endif
// 1.7.10 and below

View File

@@ -0,0 +1,93 @@
package com.replaymod.core.asm;
import net.minecraft.launchwrapper.IClassTransformer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* Insert glGetError checks after all calls to any method in any GL*, ARB* and EXT* classes
*/
public class GLErrorTransformer implements IClassTransformer {
private static final String GL_CLASS = "org.lwjgl.opengl.GL";
private static final String GL = GL_CLASS.replace('.', '/');
private static final String ARB_CLASS = "org.lwjgl.opengl.ARB";
private static final String ARB = ARB_CLASS.replace('.', '/');
private static final String EXT_CLASS = "org.lwjgl.opengl.EXT";
private static final String EXT = EXT_CLASS.replace('.', '/');
private static final String GLErrorTransformer_CLASS = GLErrorTransformer.class.getName();
private static final String GLErrorTransformer = GLErrorTransformer_CLASS.replace('.', '/');
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
if (basicClass == null) return null;
ClassReader reader = new ClassReader(basicClass);
ClassWriter writer = new ClassWriter(reader, 0);
reader.accept(new ClassVisitor(Opcodes.ASM5, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
return new MethodVisitor(Opcodes.ASM5, mv) {
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
super.visitMethodInsn(opcode, owner, name, desc, itf);
if (owner.startsWith(GL) || owner.startsWith(ARB) || owner.startsWith(EXT)) {
visitLdcInsn(owner.replace('/', '.'));
visitLdcInsn(name);
super.visitMethodInsn(Opcodes.INVOKESTATIC, GLErrorTransformer, "glErrorCheck", "(Ljava/lang/String;Ljava/lang/String;)V", false);
}
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
super.visitMaxs(maxStack + 2, maxLocals);
}
};
}
}, 0);
return writer.toByteArray();
}
private static boolean inGlBegin;
@SuppressWarnings("unused") // Called via ASM
public static void glErrorCheck(String cls, String method) {
if (method.equals("glBegin") && cls.equals(GL_CLASS + "11")) {
if (inGlBegin) {
// glBegin within glBegin
throw new GLError(GL11.GL_INVALID_OPERATION, cls, method);
}
inGlBegin = true;
return;
}
if (inGlBegin && method.equals("glEnd") && cls.equals(GL_CLASS + "11")) {
inGlBegin = false;
}
if (inGlBegin) {
return; // Cannot call glGetError in between of glBegin and glEnd
}
int err = GL11.glGetError();
if (err != 0) {
GLError e = new GLError(err, cls, method);
if ("true".equals(System.getProperty("replaymod.glerrors.throw", "true"))) {
throw e;
} else {
e.printStackTrace();
}
}
}
public static class GLError extends RuntimeException {
private GLError(int err, String cls, String method) {
super(GLU.gluErrorString(err) + " (" + err + ")");
StackTraceElement[] stack = getStackTrace();
stack[0] = new StackTraceElement(cls, method, stack[0].getFileName(), stack[0].getLineNumber());
setStackTrace(stack);
}
}
}