All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.llamalad7.mixinextras.expression.impl.pool.LocalDef Maven / Gradle / Ivy

package com.llamalad7.mixinextras.expression.impl.pool;

import com.llamalad7.mixinextras.expression.impl.flow.FlowValue;
import com.llamalad7.mixinextras.expression.impl.flow.expansion.InsnExpander;
import com.llamalad7.mixinextras.utils.InjectorUtils;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.VarInsnNode;
import org.spongepowered.asm.mixin.injection.modify.InvalidImplicitDiscriminatorException;
import org.spongepowered.asm.mixin.injection.modify.LocalVariableDiscriminator;
import org.spongepowered.asm.mixin.injection.modify.LocalVariableDiscriminator.Context;
import org.spongepowered.asm.mixin.injection.struct.InjectionInfo;
import org.spongepowered.asm.mixin.injection.struct.Target;
import org.spongepowered.asm.util.Annotations;

public class LocalDef implements MemberDefinition {
    private final LocalVariableDiscriminator discriminator;
    private final InjectionInfo info;
    private final Type targetLocalType;
    private final boolean isArgsOnly;
    private final Target target;

    LocalDef(AnnotationNode local, InjectionInfo info, Target target) {
        discriminator = LocalVariableDiscriminator.parse(local);
        this.info = info;
        targetLocalType = Annotations.getValue(local, "type", Type.VOID_TYPE);
        isArgsOnly = Annotations.getValue(local, "argsOnly", (Boolean) false);
        this.target = target;
    }

    @Override
    public boolean matches(FlowValue node) {
        AbstractInsnNode virtualInsn = node.getInsn();
        if (!(virtualInsn instanceof VarInsnNode)) {
            return false;
        }
        VarInsnNode virtualVarInsn = (VarInsnNode) virtualInsn;
        AbstractInsnNode actualInsn = InsnExpander.getRepresentative(node);
        if (virtualVarInsn.getOpcode() >= Opcodes.ISTORE && virtualVarInsn.getOpcode() <= Opcodes.ASTORE) {
            actualInsn = actualInsn.getNext();
        }
        Context context = InjectorUtils.getOrCreateLocalContext(target, target.addInjectionNode(actualInsn), info, targetLocalType, isArgsOnly);
        if (discriminator.printLVT()) {
            InjectorUtils.printLocals(target, actualInsn, context, discriminator, targetLocalType, isArgsOnly);
            info.addCallbackInvocation(info.getMethod());
        }
        int index;
        try {
            index = discriminator.findLocal(context);
        } catch (InvalidImplicitDiscriminatorException ignored) {
            return false;
        }
        return virtualVarInsn.var == index;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy