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

org.nd4j.bytebuddy.arithmetic.relative.RelativeByteBuddyIntArithmetic Maven / Gradle / Ivy

package org.nd4j.bytebuddy.arithmetic.relative;

import net.bytebuddy.dynamic.scaffold.InstrumentedType;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.implementation.bytecode.constant.IntegerConstant;
import net.bytebuddy.implementation.bytecode.member.MethodReturn;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes;


/**
 * Handles actual arithmetic
 * between 2 numbers:
 * add
 * sub
 * mul
 * div
 * mod
 *
 * @author Adam Gibson
 */
public class RelativeByteBuddyIntArithmetic implements Implementation {
    private int val1, val2;
    private Operation op;


    /**
     * Initialize with 2 values
     * and an operation to do on them
     * @param val1
     * @param val2
     * @param op
     */
    public RelativeByteBuddyIntArithmetic(int val1, int val2, Operation op) {
        this.val1 = val1;
        this.val2 = val2;
        this.op = op;
    }


    /**
     * Returns the proper stack manipulation
     * for the given operation
     * @param operation the arithmetic operation to do
     * @return the stack manipulation for the given operation
     */
    public static StackManipulation opFor(Operation operation) {
        switch (operation) {
            case ADD:
                return IntegerAddition.INSTANCE;
            case SUB:
                return IntegerSubtraction.INSTANCE;
            case MUL:
                return IntegerMultiplication.INSTANCE;
            case DIV:
                return IntegerDivision.INSTANCE;
            case MOD:
                return IntegerMod.INSTANCE;
            default:
                throw new IllegalArgumentException("Illegal type of operation ");
        }
    }


    @Override
    public InstrumentedType prepare(InstrumentedType instrumentedType) {
        return instrumentedType;
    }

    @Override
    public ByteCodeAppender appender(Target implementationTarget) {
        return new RelativeIntegerArithmeticByteCodeAppender(val1, val2, op);
    }

    public enum Operation {
        ADD, SUB, MUL, DIV, MOD
    }

    public enum IntegerSubtraction implements StackManipulation {

        INSTANCE;

        @Override
        public boolean isValid() {
            return true;
        }

        @Override
        public Size apply(MethodVisitor methodVisitor, Context implementationContext) {
            methodVisitor.visitInsn(Opcodes.ISUB);
            return new Size(-1, 0);
        }
    }

    public enum IntegerAddition implements StackManipulation {

        INSTANCE;

        @Override
        public boolean isValid() {
            return true;
        }

        @Override
        public Size apply(MethodVisitor methodVisitor, Context implementationContext) {
            methodVisitor.visitInsn(Opcodes.IADD);
            return new Size(-1, 0);
        }
    }

    public enum IntegerMultiplication implements StackManipulation {

        INSTANCE;

        @Override
        public boolean isValid() {
            return true;
        }

        @Override
        public Size apply(MethodVisitor methodVisitor, Context implementationContext) {
            methodVisitor.visitInsn(Opcodes.IMUL);
            return new Size(-1, 0);
        }
    }

    public enum IntegerDivision implements StackManipulation {

        INSTANCE;

        @Override
        public boolean isValid() {
            return true;
        }

        @Override
        public Size apply(MethodVisitor methodVisitor, Context implementationContext) {
            methodVisitor.visitInsn(Opcodes.IDIV);
            return new Size(-1, 0);
        }
    }

    public enum IntegerMod implements StackManipulation {

        INSTANCE;

        @Override
        public boolean isValid() {
            return true;
        }

        @Override
        public Size apply(MethodVisitor methodVisitor, Context implementationContext) {
            methodVisitor.visitInsn(Opcodes.IREM);
            return new Size(-1, 0);
        }
    }

    /**
     * Modulus operator between 2 ints
     * @param val1
     * @param val2
     * @return
     */
    public static StackManipulation[] mod(int val1, int val2) {
        return new StackManipulation[] {IntegerConstant.forValue(val1), IntegerConstant.forValue(val2),
                        IntegerMod.INSTANCE, MethodReturn.INTEGER};
    }

    /**
     * Division operator between 2 ints
     * @param val1
     * @param val2
     * @return
     */
    public static StackManipulation[] div(int val1, int val2) {
        return new StackManipulation[] {IntegerConstant.forValue(val1), IntegerConstant.forValue(val2),
                        IntegerDivision.INSTANCE, MethodReturn.INTEGER};
    }


    /**
     * Multiplication operator between 2 ints
     * @param val1
     * @param val2
     * @return
     */
    public static StackManipulation[] times(int val1, int val2) {
        return new StackManipulation[] {IntegerConstant.forValue(val1), IntegerConstant.forValue(val2),
                        IntegerMultiplication.INSTANCE, MethodReturn.INTEGER};
    }



}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy