com.llamalad7.mixinextras.utils.InjectorUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mixinextras-fabric Show documentation
Show all versions of mixinextras-fabric Show documentation
Companion library to Mixin with lots of features to improve the compatibility and concision of your mixins!
package com.llamalad7.mixinextras.utils;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.spongepowered.asm.mixin.injection.struct.InjectionNodes.InjectionNode;
import org.spongepowered.asm.mixin.injection.struct.Target;
import org.spongepowered.asm.util.Bytecode;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
public class InjectorUtils {
private static final MixinExtrasLogger LOGGER = MixinExtrasLogger.get("InjectorUtils");
public static boolean isVirtualRedirect(InjectionNode node) {
return node.isReplaced() && node.hasDecoration("redirector") && node.getCurrentTarget().getOpcode() != Opcodes.INVOKESTATIC;
}
public static boolean isDynamicInstanceofRedirect(InjectionNode node) {
AbstractInsnNode originalTarget = node.getOriginalTarget();
AbstractInsnNode currentTarget = node.getCurrentTarget();
return originalTarget.getOpcode() == Opcodes.INSTANCEOF
&& currentTarget instanceof MethodInsnNode
&& Type.getReturnType(((MethodInsnNode) currentTarget).desc).equals(Type.getType(Class.class));
}
public static void checkForDupedNews(Map> targets) {
for (Map.Entry> entry : targets.entrySet()) {
for (InjectionNode node : entry.getValue()) {
AbstractInsnNode currentTarget = node.getCurrentTarget();
if (currentTarget.getOpcode() == Opcodes.NEW) {
if (currentTarget.getNext().getOpcode() == Opcodes.DUP) {
node.decorate(Decorations.NEW_IS_DUPED, true);
}
}
}
}
}
public static boolean isDupedNew(InjectionNode node) {
AbstractInsnNode currentTarget = node.getCurrentTarget();
return currentTarget != null && currentTarget.getOpcode() == Opcodes.NEW && node.hasDecoration(Decorations.NEW_IS_DUPED);
}
public static boolean isDupedFactoryRedirect(InjectionNode node) {
AbstractInsnNode originalTarget = node.getOriginalTarget();
return node.isReplaced() && originalTarget.getOpcode() == Opcodes.NEW && !node.hasDecoration(Decorations.WRAPPED) && node.hasDecoration(Decorations.NEW_IS_DUPED);
}
public static AbstractInsnNode findFactoryRedirectThrowString(Target target, AbstractInsnNode start) {
for (ListIterator it = target.insns.iterator(target.indexOf(start)); it.hasNext(); ) {
AbstractInsnNode insn = it.next();
if (insn instanceof LdcInsnNode) {
LdcInsnNode ldc = (LdcInsnNode) insn;
if (ldc.cst instanceof String && ((String) ldc.cst).startsWith("@Redirect constructor handler ")) {
return ldc;
}
}
}
LOGGER.warn(
"Please inform LlamaLad7! Failed to find factory redirect throw string for {}",
Bytecode.describeNode(start)
);
return null;
}
}