⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generatoradapter.java

📁 asm的源码包 并且包含英文的文档
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
        final TableSwitchGenerator generator,
        final boolean useTable)
    {
        for (int i = 1; i < keys.length; ++i) {
            if (keys[i] < keys[i - 1]) {
                throw new IllegalArgumentException("keys must be sorted ascending");
            }
        }
        Label def = newLabel();
        Label end = newLabel();
        if (keys.length > 0) {
            int len = keys.length;
            int min = keys[0];
            int max = keys[len - 1];
            int range = max - min + 1;
            if (useTable) {
                Label[] labels = new Label[range];
                Arrays.fill(labels, def);
                for (int i = 0; i < len; ++i) {
                    labels[keys[i] - min] = newLabel();
                }
                mv.visitTableSwitchInsn(min, max, def, labels);
                for (int i = 0; i < range; ++i) {
                    Label label = labels[i];
                    if (label != def) {
                        mark(label);
                        generator.generateCase(i + min, end);
                    }
                }
            } else {
                Label[] labels = new Label[len];
                for (int i = 0; i < len; ++i) {
                    labels[i] = newLabel();
                }
                mv.visitLookupSwitchInsn(def, keys, labels);
                for (int i = 0; i < len; ++i) {
                    mark(labels[i]);
                    generator.generateCase(keys[i], end);
                }
            }
        }
        mark(def);
        generator.generateDefault();
        mark(end);
    }

    /**
     * Generates the instruction to return the top stack value to the caller.
     */
    public void returnValue() {
        mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    }

    // ------------------------------------------------------------------------
    // Instructions to load and store fields
    // ------------------------------------------------------------------------

    /**
     * Generates a get field or set field instruction.
     * 
     * @param opcode the instruction's opcode.
     * @param ownerType the class in which the field is defined.
     * @param name the name of the field.
     * @param fieldType the type of the field.
     */
    private void fieldInsn(
        final int opcode,
        final Type ownerType,
        final String name,
        final Type fieldType)
    {
        mv.visitFieldInsn(opcode,
                ownerType.getInternalName(),
                name,
                fieldType.getDescriptor());
    }

    /**
     * Generates the instruction to push the value of a static field on the
     * stack.
     * 
     * @param owner the class in which the field is defined.
     * @param name the name of the field.
     * @param type the type of the field.
     */
    public void getStatic(final Type owner, final String name, final Type type)
    {
        fieldInsn(Opcodes.GETSTATIC, owner, name, type);
    }

    /**
     * Generates the instruction to store the top stack value in a static field.
     * 
     * @param owner the class in which the field is defined.
     * @param name the name of the field.
     * @param type the type of the field.
     */
    public void putStatic(final Type owner, final String name, final Type type)
    {
        fieldInsn(Opcodes.PUTSTATIC, owner, name, type);
    }

    /**
     * Generates the instruction to push the value of a non static field on the
     * stack.
     * 
     * @param owner the class in which the field is defined.
     * @param name the name of the field.
     * @param type the type of the field.
     */
    public void getField(final Type owner, final String name, final Type type) {
        fieldInsn(Opcodes.GETFIELD, owner, name, type);
    }

    /**
     * Generates the instruction to store the top stack value in a non static
     * field.
     * 
     * @param owner the class in which the field is defined.
     * @param name the name of the field.
     * @param type the type of the field.
     */
    public void putField(final Type owner, final String name, final Type type) {
        fieldInsn(Opcodes.PUTFIELD, owner, name, type);
    }

    // ------------------------------------------------------------------------
    // Instructions to invoke methods
    // ------------------------------------------------------------------------

    /**
     * Generates an invoke method instruction.
     * 
     * @param opcode the instruction's opcode.
     * @param type the class in which the method is defined.
     * @param method the method to be invoked.
     */
    private void invokeInsn(
        final int opcode,
        final Type type,
        final Method method)
    {
        String owner = type.getSort() == Type.ARRAY
                ? type.getDescriptor()
                : type.getInternalName();
        mv.visitMethodInsn(opcode,
                owner,
                method.getName(),
                method.getDescriptor());
    }

    /**
     * Generates the instruction to invoke a normal method.
     * 
     * @param owner the class in which the method is defined.
     * @param method the method to be invoked.
     */
    public void invokeVirtual(final Type owner, final Method method) {
        invokeInsn(Opcodes.INVOKEVIRTUAL, owner, method);
    }

    /**
     * Generates the instruction to invoke a constructor.
     * 
     * @param type the class in which the constructor is defined.
     * @param method the constructor to be invoked.
     */
    public void invokeConstructor(final Type type, final Method method) {
        invokeInsn(Opcodes.INVOKESPECIAL, type, method);
    }

    /**
     * Generates the instruction to invoke a static method.
     * 
     * @param owner the class in which the method is defined.
     * @param method the method to be invoked.
     */
    public void invokeStatic(final Type owner, final Method method) {
        invokeInsn(Opcodes.INVOKESTATIC, owner, method);
    }

    /**
     * Generates the instruction to invoke an interface method.
     * 
     * @param owner the class in which the method is defined.
     * @param method the method to be invoked.
     */
    public void invokeInterface(final Type owner, final Method method) {
        invokeInsn(Opcodes.INVOKEINTERFACE, owner, method);
    }

    // ------------------------------------------------------------------------
    // Instructions to create objects and arrays
    // ------------------------------------------------------------------------

    /**
     * Generates a type dependent instruction.
     * 
     * @param opcode the instruction's opcode.
     * @param type the instruction's operand.
     */
    private void typeInsn(final int opcode, final Type type) {
        String desc;
        if (type.getSort() == Type.ARRAY) {
            desc = type.getDescriptor();
        } else {
            desc = type.getInternalName();
        }
        mv.visitTypeInsn(opcode, desc);
    }

    /**
     * Generates the instruction to create a new object.
     * 
     * @param type the class of the object to be created.
     */
    public void newInstance(final Type type) {
        typeInsn(Opcodes.NEW, type);
    }

    /**
     * Generates the instruction to create a new array.
     * 
     * @param type the type of the array elements.
     */
    public void newArray(final Type type) {
        int typ;
        switch (type.getSort()) {
            case Type.BOOLEAN:
                typ = Opcodes.T_BOOLEAN;
                break;
            case Type.CHAR:
                typ = Opcodes.T_CHAR;
                break;
            case Type.BYTE:
                typ = Opcodes.T_BYTE;
                break;
            case Type.SHORT:
                typ = Opcodes.T_SHORT;
                break;
            case Type.INT:
                typ = Opcodes.T_INT;
                break;
            case Type.FLOAT:
                typ = Opcodes.T_FLOAT;
                break;
            case Type.LONG:
                typ = Opcodes.T_LONG;
                break;
            case Type.DOUBLE:
                typ = Opcodes.T_DOUBLE;
                break;
            default:
                typeInsn(Opcodes.ANEWARRAY, type);
                return;
        }
        mv.visitIntInsn(Opcodes.NEWARRAY, typ);
    }

    // ------------------------------------------------------------------------
    // Miscelaneous instructions
    // ------------------------------------------------------------------------

    /**
     * Generates the instruction to compute the length of an array.
     */
    public void arrayLength() {
        mv.visitInsn(Opcodes.ARRAYLENGTH);
    }

    /**
     * Generates the instruction to throw an exception.
     */
    public void throwException() {
        mv.visitInsn(Opcodes.ATHROW);
    }

    /**
     * Generates the instructions to create and throw an exception. The
     * exception class must have a constructor with a single String argument.
     * 
     * @param type the class of the exception to be thrown.
     * @param msg the detailed message of the exception.
     */
    public void throwException(final Type type, final String msg) {
        newInstance(type);
        dup();
        push(msg);
        invokeConstructor(type, Method.getMethod("void <init> (String)"));
        throwException();
    }

    /**
     * Generates the instruction to check that the top stack value is of the
     * given type.
     * 
     * @param type a class or interface type.
     */
    public void checkCast(final Type type) {
        if (!type.equals(OBJECT_TYPE)) {
            typeInsn(Opcodes.CHECKCAST, type);
        }
    }

    /**
     * Generates the instruction to test if the top stack value is of the given
     * type.
     * 
     * @param type a class or interface type.
     */
    public void instanceOf(final Type type) {
        typeInsn(Opcodes.INSTANCEOF, type);
    }

    /**
     * Generates the instruction to get the monitor of the top stack value.
     */
    public void monitorEnter() {
        mv.visitInsn(Opcodes.MONITORENTER);
    }

    /**
     * Generates the instruction to release the monitor of the top stack value.
     */
    public void monitorExit() {
        mv.visitInsn(Opcodes.MONITOREXIT);
    }

    // ------------------------------------------------------------------------
    // Non instructions
    // ------------------------------------------------------------------------

    /**
     * Marks the end of the visited method.
     */
    public void endMethod() {
        if ((access & Opcodes.ACC_ABSTRACT) == 0) {
            mv.visitMaxs(0, 0);
        }
        mv.visitEnd();
    }

    /**
     * Marks the start of an exception handler.
     * 
     * @param start beginning of the exception handler's scope (inclusive).
     * @param end end of the exception handler's scope (exclusive).
     * @param exception internal name of the type of exceptions handled by the
     *        handler.
     */
    public void catchException(
        final Label start,
        final Label end,
        final Type exception)
    {
        mv.visitTryCatchBlock(start, end, mark(), exception.getInternalName());
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -