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

net.sf.beezle.mork.classfile.Set Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 1&1 Internet AG, http://www.1and1.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 */

package net.sf.beezle.mork.classfile;

import java.lang.reflect.Field;

/**
 * Instruction set.
 */

public class Set implements Constants {
    public static final InstructionEncoding[] ENCODING = new InstructionEncoding[256];
    public static final InstructionType[] TYPES = new InstructionType[256];

    private static int[] a() {
        return new int[] {};
    }
    private static int[] a(int a0) {
        return new int[] { a0 };
    }
    private static int[] a(int a0, int a1) {
        return new int[] { a0, a1 };
    }

    private static int getOpcode(String name) {
        Field f;

        try {
            f = Bytecodes.class.getField(name.toUpperCase());
        } catch (NoSuchFieldException e) {
            throw new RuntimeException("no such opcode: " + name);
        }
        try {
            return f.getInt(null);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("can read field " + name);
        }
    }

    private static InstructionType type(String name, int[] args, int encoding, int stackDiff, int succType) {
        int opcode;

        opcode = getOpcode(name);
        if (TYPES[opcode] != null) {
            throw new RuntimeException("duplicate type: " + opcode);
        }
        TYPES[opcode] =
            new InstructionType(name, opcode, args,
                                encoding, stackDiff, succType);
        return TYPES[opcode];
    }

    private static void enc(String name, int[] args, InstructionType type) {
        int opcode;

        opcode = getOpcode(name);
        if (ENCODING[opcode] != null) {
            throw new RuntimeException("duplicate encoding: " + opcode);
        }
        ENCODING[opcode] = new InstructionEncoding(name, args, type);
    }

    private static void generic(int encoding,
            String name, int[] typeArgs, int[] encArgs, int stackDiff, int succType) {
        InstructionType type;

        type = type(name, typeArgs, encoding, stackDiff, succType);
        enc(name, encArgs, type);
    }

    private static void simple(String name, int[] args, int stackDiff,
                               int succType) {
        int i;
        int[] encodedArgs;

        encodedArgs = new int[args.length];
        for (i = 0; i < args.length; i++) {
            switch (args[i]) {
            case REFTYPEREF:
                encodedArgs[i] = AE_REFTYPEREF;
                break;
            case FIELDREF:
                encodedArgs[i] = AE_FIELDREF;
                break;
            case IFMETHOD:
                encodedArgs[i] = AE_IFMETHOD;
                break;
            case METHODREF:
                encodedArgs[i] = AE_METHODREF;
                break;
            case BYTE:
            case TYPE_BYTE:
                encodedArgs[i] = AE_U1;
                break;
            default:
                throw new IllegalArgumentException(
                    name + "[" + i + "]: " + args[i]);
            }
        }
        generic(SIMPLE, name, args, encodedArgs, stackDiff, succType);
    }

    private static void lv(String name, int stackDiff) {
        InstructionType type;
        String name0;
        String name1;
        String name2;
        String name3;
        int[] args;

        name0 = name + "_0";
        name1 = name + "_1";
        name2 = name + "_2";
        name3 = name + "_3";
        args = new int[] {
            getOpcode(name0), getOpcode(name1),
            getOpcode(name2), getOpcode(name3)
        };
        type = type(name, args, LV, stackDiff, SUCC_NEXT);
        enc(name, new int[] { AE_U1 }, type);
        enc(name0, new int[] { AE_I_I0 }, type);
        enc(name1, new int[] { AE_I_I1 }, type);
        enc(name2, new int[] { AE_I_I2 }, type);
        enc(name3, new int[] { AE_I_I3 }, type);
        // "wide" is hard-wired into InstructionEncoding
    }

    private static void branch(String name, String notName, int stackDiff, int succType) {
        InstructionType type;

        type = type(name, new int[] { getOpcode(notName) },
                    BRANCH, stackDiff, succType);
        enc(name, new int[] { AE_S2 }, type);
    }

    private static void vbranch(String name, int stackDiff, int succType) {
        InstructionType type;
        String nameW;

        nameW = name + "_w";
        type = type(name, new int[] { getOpcode(nameW) },
                   VBRANCH, stackDiff, succType);
        enc(name, new int[] { AE_S2 }, type);
        enc(nameW, new int[] { AE_U4 }, type);
    }

    private static void cnst(String name) {
        InstructionType t;

        t = type(name, new int[] {}, CNST, LDC_STACK, SUCC_NEXT);
        enc("aconst_null", a(AE_I_NULL),  t);
        enc("iconst_m1",   a(AE_I_IML),   t);
        enc("iconst_0",    a(AE_I_I0),    t);
        enc("iconst_1",    a(AE_I_I1),    t);
        enc("iconst_2",    a(AE_I_I2),    t);
        enc("iconst_3",    a(AE_I_I3),    t);
        enc("iconst_4",    a(AE_I_I4),    t);
        enc("iconst_5",    a(AE_I_I5),    t);
        enc("lconst_0",    a(AE_I_L0),    t);
        enc("lconst_1",    a(AE_I_L1),    t);
        enc("fconst_0",    a(AE_I_F0),    t);
        enc("fconst_1",    a(AE_I_F1),    t);
        enc("fconst_2",    a(AE_I_F2),    t);
        enc("dconst_0",    a(AE_I_D0),    t);
        enc("dconst_1",    a(AE_I_D1),    t);
        enc("bipush",      a(AE_S1),      t);
        enc("sipush",      a(AE_S2),      t);
        enc("ldc",         a(AE_CNST),    t);
        enc("ldc_w",       a(AE_CNST_W),  t);
        enc("ldc2_w",      a(AE_CNST2_W), t);
    }

    static {
        enc("wide", new int[] {}, null);

        simple("nop", a(), 0, SUCC_NEXT);
        cnst("ldc");
        lv("iload", 1);
        lv("lload", 2);
        lv("fload", 1);
        lv("dload", 2);
        lv("aload", 1);

    // wide is hard-wired:
    generic(RT, "ret",            a(), a(AE_U1), 0, SUCC_RET);

        simple("iaload", a(), -1, SUCC_NEXT);
        simple("laload", a(), 0, SUCC_NEXT);
        simple("faload", a(), -1, SUCC_NEXT);
        simple("daload", a(), 0, SUCC_NEXT);
        simple("aaload", a(), -1, SUCC_NEXT);
        simple("baload", a(), -1, SUCC_NEXT);
        simple("caload", a(), -1, SUCC_NEXT);
        simple("saload", a(), -1, SUCC_NEXT);
        lv("istore", -1);
        lv("lstore", -2);
        lv("fstore", -1);
        lv("dstore", -2);
        lv("astore", -1);
        simple("iastore", a(), -3, SUCC_NEXT);
        simple("lastore", a(), -4, SUCC_NEXT);
        simple("fastore", a(), -3, SUCC_NEXT);
        simple("dastore", a(), -4, SUCC_NEXT);
        simple("aastore", a(), -3, SUCC_NEXT);
        simple("bastore", a(), -3, SUCC_NEXT);
        simple("castore", a(), -3, SUCC_NEXT);
        simple("sastore", a(), -3, SUCC_NEXT);
        simple("pop", a(), -1, SUCC_NEXT);
        simple("pop2", a(), -2, SUCC_NEXT);
        simple("dup", a(), 1, SUCC_NEXT);
        simple("dup_x1", a(), 1, SUCC_NEXT);
        simple("dup_x2", a(), 1, SUCC_NEXT);
        simple("dup2", a(), 2, SUCC_NEXT);
        simple("dup2_x1", a(), 2, SUCC_NEXT);
        simple("dup2_x2", a(), 2, SUCC_NEXT);
        simple("swap", a(), 0, SUCC_NEXT);
        simple("iadd", a(), -1, SUCC_NEXT);
        simple("ladd", a(), -2, SUCC_NEXT);
        simple("fadd", a(), -1, SUCC_NEXT);
        simple("dadd", a(), -2, SUCC_NEXT);
        simple("isub", a(), -1, SUCC_NEXT);
        simple("lsub", a(), -2, SUCC_NEXT);
        simple("fsub", a(), -1, SUCC_NEXT);
        simple("dsub", a(), -2, SUCC_NEXT);
        simple("imul", a(), -1, SUCC_NEXT);
        simple("lmul", a(), -2, SUCC_NEXT);
        simple("fmul", a(), -1, SUCC_NEXT);
        simple("dmul", a(), -2, SUCC_NEXT);
        simple("idiv", a(), -1, SUCC_NEXT);
        simple("ldiv", a(), -2, SUCC_NEXT);
        simple("fdiv", a(), -1, SUCC_NEXT);
        simple("ddiv", a(), -2, SUCC_NEXT);
        simple("irem", a(), -1, SUCC_NEXT);
        simple("lrem", a(), -2, SUCC_NEXT);
        simple("frem", a(), -1, SUCC_NEXT);
        simple("drem", a(), -2, SUCC_NEXT);
        simple("ineg", a(), 0, SUCC_NEXT);
        simple("lneg", a(), 0, SUCC_NEXT);
        simple("fneg", a(), 0, SUCC_NEXT);
        simple("dneg", a(), 0, SUCC_NEXT);
        simple("ishl", a(), -1, SUCC_NEXT);
        simple("lshl", a(), -1, SUCC_NEXT);
        simple("ishr", a(), -1, SUCC_NEXT);
        simple("lshr", a(), -1, SUCC_NEXT);
        simple("iushr", a(), -1, SUCC_NEXT);
        simple("lushr", a(), -1, SUCC_NEXT);
        simple("iand", a(), -1, SUCC_NEXT);
        simple("land", a(), -2, SUCC_NEXT);
        simple("ior", a(), -1, SUCC_NEXT);
        simple("lor", a(), -2, SUCC_NEXT);
        simple("ixor", a(), -1, SUCC_NEXT);
        simple("lxor", a(), -2, SUCC_NEXT);
        generic(INC, "iinc", a(), a(AE_U1, AE_S1), 0, SUCC_NEXT);
        simple("i2l", a(), 1, SUCC_NEXT);
        simple("i2f", a(), 0, SUCC_NEXT);
        simple("i2d", a(), 1, SUCC_NEXT);
        simple("l2i", a(), -1, SUCC_NEXT);
        simple("l2f", a(), -1, SUCC_NEXT);
        simple("l2d", a(), 0, SUCC_NEXT);
        simple("f2i", a(), 0, SUCC_NEXT);
        simple("f2l", a(), 1, SUCC_NEXT);
        simple("f2d", a(), 1, SUCC_NEXT);
        simple("d2i", a(), -1, SUCC_NEXT);
        simple("d2l", a(), 0, SUCC_NEXT);
        simple("d2f", a(), -1, SUCC_NEXT);
        simple("i2b", a(), 0, SUCC_NEXT);
        simple("i2c", a(), 0, SUCC_NEXT);
        simple("i2s", a(), 0, SUCC_NEXT);
        simple("lcmp", a(), -3, SUCC_NEXT);
        simple("fcmpl", a(), -1, SUCC_NEXT);
        simple("fcmpg", a(), -1, SUCC_NEXT);
        simple("dcmpl", a(), -3, SUCC_NEXT);
        simple("dcmpg", a(), -3, SUCC_NEXT);
        branch("ifeq", "ifne", -1, SUCC_BRANCH);
        branch("ifne", "ifeq", -1, SUCC_BRANCH);
        branch("iflt", "ifge", -1, SUCC_BRANCH);
        branch("ifge", "iflt", -1, SUCC_BRANCH);
        branch("ifgt", "ifle", -1, SUCC_BRANCH);
        branch("ifle", "ifgt", -1, SUCC_BRANCH);
        branch("if_icmpeq", "if_icmpne", -2, SUCC_BRANCH);
        branch("if_icmpne", "if_icmpeq", -2, SUCC_BRANCH);
        branch("if_icmplt", "if_icmpge", -2, SUCC_BRANCH);
        branch("if_icmpge", "if_icmplt", -2, SUCC_BRANCH);
        branch("if_icmpgt", "if_icmple", -2, SUCC_BRANCH);
        branch("if_icmple", "if_icmpgt", -2, SUCC_BRANCH);
        branch("if_acmpeq", "if_acmpne", -2, SUCC_BRANCH);
        branch("if_acmpne", "if_acmpeq", -2, SUCC_BRANCH);
        vbranch("goto", 0, SUCC_GOTO);
        vbranch("jsr", 1, SUCC_JSR);
        generic(TS, "tableswitch", a(), a(), -1, SUCC_TABLESWITCH);
        generic(LS, "lookupswitch", a(), a(), -1, SUCC_LOOKUPSWITCH);
        simple("ireturn", a(), -1, SUCC_NONE);
        simple("lreturn", a(), -2, SUCC_NONE);
        simple("freturn", a(), -1, SUCC_NONE);
        simple("dreturn", a(), -2, SUCC_NONE);
        simple("areturn", a(), -1, SUCC_NONE);
        simple("return", a(), 0, SUCC_NONE);
        simple("getstatic", a(FIELDREF), GETSTATIC_STACK, SUCC_NEXT);
        simple("putstatic", a(FIELDREF), PUTSTATIC_STACK, SUCC_NEXT);
        simple("getfield", a(FIELDREF), GETFIELD_STACK, SUCC_NEXT);
        simple("putfield", a(FIELDREF), PUTFIELD_STACK, SUCC_NEXT);
        simple("invokevirtual", a(METHODREF), INVOKEVIRTUAL_STACK, SUCC_NEXT);
        simple("invokespecial", a(METHODREF), INVOKESPECIAL_STACK, SUCC_NEXT);
        simple("invokestatic", a(METHODREF), INVOKESTATIC_STACK, SUCC_NEXT);
        simple("invokeinterface", a(IFMETHOD), INVOKEINTERFACE_STACK, SUCC_NEXT);
        simple("new", a(REFTYPEREF), 1, SUCC_NEXT);
        simple("newarray", a(TYPE_BYTE), 0, SUCC_NEXT);
        simple("anewarray", a(REFTYPEREF), 0, SUCC_NEXT);
        simple("arraylength", a(), 0, SUCC_NEXT);
        simple("athrow", a(), 0, SUCC_NONE);
        simple("checkcast", a(REFTYPEREF), 0, SUCC_NEXT);
        simple("instanceof", a(REFTYPEREF), 0, SUCC_NEXT);
        simple("monitorenter", a(), -1, SUCC_NEXT);
        simple("monitorexit", a(), -1, SUCC_NEXT);
        simple("multianewarray", a(REFTYPEREF, BYTE), MULTIARRAY_STACK,
                SUCC_NEXT);
        branch("ifnull", "ifnonnull", -1, SUCC_BRANCH);
        branch("ifnonnull", "ifnull", -1, SUCC_BRANCH);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy