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

at.yawk.valda.ir.code.Invoke Maven / Gradle / Ivy

The newest version!
package at.yawk.valda.ir.code;

import at.yawk.valda.ir.MethodMirror;
import at.yawk.valda.ir.MethodReference;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.Singular;
import lombok.ToString;

/**
 * @author yawkat
 */
@EqualsAndHashCode(callSuper = false)
@ToString
public final class Invoke extends Instruction {
    public static final Slot PARAMETERS = Slot.variadic("parameters", Invoke::getParameters, Invoke::setParameters);
    public static final Slot RETURN_VALUE = Slot.optional(
            "returnValue", Invoke::getReturnValue, Invoke::setReturnValue);

    @Getter @Setter @NonNull private Type type;
    @NonNull private final MethodReference.Invoke method;
    @NonNull @Getter @Setter private List parameters;
    @Nullable @Getter @Setter private LocalVariable returnValue;

    @Builder
    private Invoke(
            @NonNull Type type,
            MethodMirror method,
            @NonNull @Singular List parameters,
            @Nullable LocalVariable returnValue
    ) {
        this.type = type;
        this.method = SecretsHolder.secrets.newInvoke(method, this);
        this.parameters = parameters;
        this.returnValue = returnValue;
    }

    public MethodMirror getMethod() {
        return method.getReferencedMethod();
    }

    @Override
    void linkClasspath() {
        method.getReferencedMethod().getReferences().add(method);
    }

    @Override
    void unlinkClasspath() {
        method.getReferencedMethod().getReferences().remove(method);
    }

    @Override
    public Collection getInputSlots() {
        return Collections.singletonList(PARAMETERS);
    }

    @Override
    public Collection getOutputSlots() {
        return ImmutableList.of(RETURN_VALUE);
    }

    public enum Type {
        /**
         * Normal invocation. For non-static methods this is {@code invoke-virtual}, for static methods it is
         * equivalent to {@link #SPECIAL}. For interfaces this is invoke-interface instead of invoke-virtual.
         */
        NORMAL,
        /**
         * Non-virtual invocation (java {@code invokespecial}) of a method. For static methods, this translates to
         * {@code invoke-static}. For private methods, this translates to {@code invoke-direct}. For other methods
         * (super calls) this translates to {@code invoke-super}.
         */
        SPECIAL,
        /**
         * New instance allocation together with constructor invocation. This is a pseudo-instruction and maps to a
         * {@code new-instance} and constructor call.
         */
        NEW_INSTANCE,
    }

    public static class InvokeBuilder {
        {
            type = Type.NORMAL;
        }

        public InvokeBuilder newInstance() {
            return type(Type.NEW_INSTANCE);
        }

        public InvokeBuilder special() {
            return type(Type.SPECIAL);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy