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

📄 adviceadapter.java

📁 asm的源码包 并且包含英文的文档
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/***
 * ASM: a very small and fast Java bytecode manipulation framework
 * Copyright (c) 2000-2005 INRIA, France Telecom
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.objectweb.asm.commons;

import java.util.ArrayList;
import java.util.HashMap;

import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

/**
 * A {@link org.objectweb.asm.MethodAdapter} to insert before, after and around
 * advices in methods and constructors. <p> The behavior for constructors is
 * like this: <ol>
 * 
 * <li>as long as the INVOKESPECIAL for the object initialization has not been
 * reached, every bytecode instruction is dispatched in the ctor code visitor</li>
 * 
 * <li>when this one is reached, it is only added in the ctor code visitor and
 * a JP invoke is added</li>
 * 
 * <li>after that, only the other code visitor receives the instructions</li>
 * 
 * </ol>
 * 
 * @author Eugene Kuleshov
 * @author Eric Bruneton
 */
public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
{
    private static final Object THIS = new Object();
    private static final Object OTHER = new Object();

    protected int methodAccess;
    protected String methodDesc;

    private boolean constructor;
    private boolean superInitialized;
    private ArrayList stackFrame;
    private HashMap branches;

    /**
     * Creates a new {@link AdviceAdapter}.
     * 
     * @param mv the method visitor to which this adapter delegates calls.
     * @param access the method's access flags (see {@link Opcodes}).
     * @param name the method's name.
     * @param desc the method's descriptor (see {@link Type Type}).
     */
    public AdviceAdapter(
        final MethodVisitor mv,
        final int access,
        final String name,
        final String desc)
    {
        super(mv, access, name, desc);
        methodAccess = access;
        methodDesc = desc;

        constructor = "<init>".equals(name);
    }

    public void visitCode() {
        mv.visitCode();
        if (!constructor) {
            superInitialized = true;
            onMethodEnter();
        } else {
            stackFrame = new ArrayList();
            branches = new HashMap();
        }
    }

    public void visitLabel(final Label label) {
        mv.visitLabel(label);

        if (constructor && branches != null) {
            ArrayList frame = (ArrayList) branches.get(label);
            if (frame != null) {
                stackFrame = frame;
                branches.remove(label);
            }
        }
    }

    public void visitInsn(final int opcode) {
        if (constructor) {
            switch (opcode) {
                case RETURN: // empty stack
                    onMethodExit(opcode);
                    break;

                case IRETURN: // 1 before n/a after
                case FRETURN: // 1 before n/a after
                case ARETURN: // 1 before n/a after
                case ATHROW: // 1 before n/a after
                    popValue();
                    popValue();
                    onMethodExit(opcode);
                    break;

                case LRETURN: // 2 before n/a after
                case DRETURN: // 2 before n/a after
                    popValue();
                    popValue();
                    onMethodExit(opcode);
                    break;

                case NOP:
                case LALOAD: // remove 2 add 2
                case DALOAD: // remove 2 add 2
                case LNEG:
                case DNEG:
                case FNEG:
                case INEG:
                case L2D:
                case D2L:
                case F2I:
                case I2B:
                case I2C:
                case I2S:
                case I2F:
                case Opcodes.ARRAYLENGTH:
                    break;

                case ACONST_NULL:
                case ICONST_M1:
                case ICONST_0:
                case ICONST_1:
                case ICONST_2:
                case ICONST_3:
                case ICONST_4:
                case ICONST_5:
                case FCONST_0:
                case FCONST_1:
                case FCONST_2:
                case F2L: // 1 before 2 after
                case F2D:
                case I2L:
                case I2D:
                    pushValue(OTHER);
                    break;

                case LCONST_0:
                case LCONST_1:
                case DCONST_0:
                case DCONST_1:
                    pushValue(OTHER);
                    pushValue(OTHER);
                    break;

                case IALOAD: // remove 2 add 1
                case FALOAD: // remove 2 add 1
                case AALOAD: // remove 2 add 1
                case BALOAD: // remove 2 add 1
                case CALOAD: // remove 2 add 1
                case SALOAD: // remove 2 add 1
                case POP:
                case IADD:
                case FADD:
                case ISUB:
                case LSHL: // 3 before 2 after
                case LSHR: // 3 before 2 after
                case LUSHR: // 3 before 2 after
                case L2I: // 2 before 1 after
                case L2F: // 2 before 1 after
                case D2I: // 2 before 1 after
                case D2F: // 2 before 1 after
                case FSUB:
                case FMUL:
                case FDIV:
                case FREM:
                case FCMPL: // 2 before 1 after
                case FCMPG: // 2 before 1 after
                case IMUL:
                case IDIV:
                case IREM:
                case ISHL:
                case ISHR:
                case IUSHR:
                case IAND:
                case IOR:
                case IXOR:
                case MONITORENTER:
                case MONITOREXIT:
                    popValue();
                    break;

                case POP2:
                case LSUB:
                case LMUL:
                case LDIV:
                case LREM:
                case LADD:
                case LAND:
                case LOR:
                case LXOR:
                case DADD:
                case DMUL:
                case DSUB:
                case DDIV:
                case DREM:
                    popValue();
                    popValue();
                    break;

                case IASTORE:
                case FASTORE:
                case AASTORE:
                case BASTORE:
                case CASTORE:
                case SASTORE:
                case LCMP: // 4 before 1 after
                case DCMPL:
                case DCMPG:
                    popValue();
                    popValue();
                    popValue();
                    break;

                case LASTORE:
                case DASTORE:
                    popValue();
                    popValue();
                    popValue();
                    popValue();
                    break;

                case DUP:
                    pushValue(peekValue());
                    break;

                case DUP_X1:
                    // TODO optimize this
                {
                    Object o1 = popValue();
                    Object o2 = popValue();
                    pushValue(o1);
                    pushValue(o2);
                    pushValue(o1);
                }
                    break;

                case DUP_X2:
                    // TODO optimize this
                {
                    Object o1 = popValue();
                    Object o2 = popValue();
                    Object o3 = popValue();
                    pushValue(o1);
                    pushValue(o3);
                    pushValue(o2);
                    pushValue(o1);
                }
                    break;

                case DUP2:
                    // TODO optimize this
                {
                    Object o1 = popValue();
                    Object o2 = popValue();
                    pushValue(o2);
                    pushValue(o1);
                    pushValue(o2);
                    pushValue(o1);
                }
                    break;

                case DUP2_X1:
                    // TODO optimize this
                {
                    Object o1 = popValue();
                    Object o2 = popValue();
                    Object o3 = popValue();
                    pushValue(o2);
                    pushValue(o1);
                    pushValue(o3);
                    pushValue(o2);
                    pushValue(o1);
                }
                    break;

                case DUP2_X2:
                    // TODO optimize this
                {
                    Object o1 = popValue();
                    Object o2 = popValue();
                    Object o3 = popValue();
                    Object o4 = popValue();
                    pushValue(o2);
                    pushValue(o1);
                    pushValue(o4);
                    pushValue(o3);
                    pushValue(o2);
                    pushValue(o1);
                }
                    break;

⌨️ 快捷键说明

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