forked from MirrorHub/authlib-injector
72 lines
3.1 KiB
Java
72 lines
3.1 KiB
Java
/*
|
|
* Copyright (C) 2021 Haowei Wen <yushijinhun@gmail.com> and contributors
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
package moe.yushi.authlibinjector.transform;
|
|
|
|
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
|
import static org.objectweb.asm.Opcodes.ACC_STATIC;
|
|
import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
|
|
import static org.objectweb.asm.Opcodes.ALOAD;
|
|
import static org.objectweb.asm.Opcodes.ARETURN;
|
|
import static org.objectweb.asm.Opcodes.ASM9;
|
|
import static org.objectweb.asm.Opcodes.DUP;
|
|
import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
|
|
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
|
|
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
|
|
import static org.objectweb.asm.Opcodes.NEW;
|
|
import java.util.Optional;
|
|
import org.objectweb.asm.ClassVisitor;
|
|
import org.objectweb.asm.MethodVisitor;
|
|
|
|
class CallbackMetafactoryTransformer implements TransformUnit {
|
|
|
|
@Override
|
|
public Optional<ClassVisitor> transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext context) {
|
|
return Optional.of(new ClassVisitor(ASM9, writer) {
|
|
@Override
|
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
|
super.visit(version, access, name, signature, superName, interfaces);
|
|
|
|
MethodVisitor mv = super.visitMethod(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC,
|
|
CallbackSupport.METAFACTORY_NAME,
|
|
CallbackSupport.METAFACTORY_SIGNATURE,
|
|
null, null);
|
|
mv.visitCode();
|
|
mv.visitTypeInsn(NEW, "java/lang/invoke/ConstantCallSite");
|
|
mv.visitInsn(DUP);
|
|
mv.visitVarInsn(ALOAD, 0);
|
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/ClassLoader", "getSystemClassLoader", "()Ljava/lang/ClassLoader;", false);
|
|
mv.visitVarInsn(ALOAD, 3);
|
|
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassLoader", "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", false);
|
|
mv.visitVarInsn(ALOAD, 1);
|
|
mv.visitVarInsn(ALOAD, 2);
|
|
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findStatic", "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;", false);
|
|
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/invoke/ConstantCallSite", "<init>", "(Ljava/lang/invoke/MethodHandle;)V", false);
|
|
mv.visitInsn(ARETURN);
|
|
mv.visitMaxs(-1, -1);
|
|
mv.visitEnd();
|
|
|
|
context.markModified();
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Callback Metafactory Transformer";
|
|
}
|
|
}
|