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

jdk.internal.org.objectweb.asm.util.CheckMethodAdapter Maven / Gradle / Ivy

There is a newer version: 17.alpha.0.57
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * This file is available under and governed by the GNU General Public
 * License version 2 only, as published by the Free Software Foundation.
 * However, the following notice accompanied the original version of this
 * file:
 *
 * ASM: a very small and fast Java bytecode manipulation framework
 * Copyright (c) 2000-2011 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 jdk.internal.org.objectweb.asm.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.Attribute;
import jdk.internal.org.objectweb.asm.ConstantDynamic;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.TypePath;
import jdk.internal.org.objectweb.asm.TypeReference;
import jdk.internal.org.objectweb.asm.tree.MethodNode;
import jdk.internal.org.objectweb.asm.tree.analysis.Analyzer;
import jdk.internal.org.objectweb.asm.tree.analysis.AnalyzerException;
import jdk.internal.org.objectweb.asm.tree.analysis.BasicValue;
import jdk.internal.org.objectweb.asm.tree.analysis.BasicVerifier;

/**
 * A {@link MethodVisitor} that checks that its methods are properly used. More precisely this
 * method adapter checks each instruction individually, i.e., each visit method checks some
 * preconditions based only on its arguments - such as the fact that the given opcode is
 * correct for a given visit method. This adapter can also perform some basic data flow checks (more
 * precisely those that can be performed without the full class hierarchy - see {@link
 * jdk.internal.org.objectweb.asm.tree.analysis.BasicVerifier}). For instance in a method whose signature is
 * {@code void m ()}, the invalid instruction IRETURN, or the invalid sequence IADD L2I will be
 * detected if the data flow checks are enabled. These checks are enabled by using the {@link
 * #CheckMethodAdapter(int,String,String,MethodVisitor,Map)} constructor. They are not performed if
 * any other constructor is used.
 *
 * @author Eric Bruneton
 */
public class CheckMethodAdapter extends MethodVisitor {

    /** The 'generic' instruction visit methods (i.e. those that take an opcode argument). */
    private enum Method {
        VISIT_INSN,
        VISIT_INT_INSN,
        VISIT_VAR_INSN,
        VISIT_TYPE_INSN,
        VISIT_FIELD_INSN,
        VISIT_METHOD_INSN,
        VISIT_JUMP_INSN
    }

    /** The method to use to visit each instruction. Only generic methods are represented here. */
    private static final Method[] OPCODE_METHODS = {
        Method.VISIT_INSN, // NOP
        Method.VISIT_INSN, // ACONST_NULL
        Method.VISIT_INSN, // ICONST_M1
        Method.VISIT_INSN, // ICONST_0
        Method.VISIT_INSN, // ICONST_1
        Method.VISIT_INSN, // ICONST_2
        Method.VISIT_INSN, // ICONST_3
        Method.VISIT_INSN, // ICONST_4
        Method.VISIT_INSN, // ICONST_5
        Method.VISIT_INSN, // LCONST_0
        Method.VISIT_INSN, // LCONST_1
        Method.VISIT_INSN, // FCONST_0
        Method.VISIT_INSN, // FCONST_1
        Method.VISIT_INSN, // FCONST_2
        Method.VISIT_INSN, // DCONST_0
        Method.VISIT_INSN, // DCONST_1
        Method.VISIT_INT_INSN, // BIPUSH
        Method.VISIT_INT_INSN, // SIPUSH
        null, // LDC
        null, // LDC_W
        null, // LDC2_W
        Method.VISIT_VAR_INSN, // ILOAD
        Method.VISIT_VAR_INSN, // LLOAD
        Method.VISIT_VAR_INSN, // FLOAD
        Method.VISIT_VAR_INSN, // DLOAD
        Method.VISIT_VAR_INSN, // ALOAD
        null, // ILOAD_0
        null, // ILOAD_1
        null, // ILOAD_2
        null, // ILOAD_3
        null, // LLOAD_0
        null, // LLOAD_1
        null, // LLOAD_2
        null, // LLOAD_3
        null, // FLOAD_0
        null, // FLOAD_1
        null, // FLOAD_2
        null, // FLOAD_3
        null, // DLOAD_0
        null, // DLOAD_1
        null, // DLOAD_2
        null, // DLOAD_3
        null, // ALOAD_0
        null, // ALOAD_1
        null, // ALOAD_2
        null, // ALOAD_3
        Method.VISIT_INSN, // IALOAD
        Method.VISIT_INSN, // LALOAD
        Method.VISIT_INSN, // FALOAD
        Method.VISIT_INSN, // DALOAD
        Method.VISIT_INSN, // AALOAD
        Method.VISIT_INSN, // BALOAD
        Method.VISIT_INSN, // CALOAD
        Method.VISIT_INSN, // SALOAD
        Method.VISIT_VAR_INSN, // ISTORE
        Method.VISIT_VAR_INSN, // LSTORE
        Method.VISIT_VAR_INSN, // FSTORE
        Method.VISIT_VAR_INSN, // DSTORE
        Method.VISIT_VAR_INSN, // ASTORE
        null, // ISTORE_0
        null, // ISTORE_1
        null, // ISTORE_2
        null, // ISTORE_3
        null, // LSTORE_0
        null, // LSTORE_1
        null, // LSTORE_2
        null, // LSTORE_3
        null, // FSTORE_0
        null, // FSTORE_1
        null, // FSTORE_2
        null, // FSTORE_3
        null, // DSTORE_0
        null, // DSTORE_1
        null, // DSTORE_2
        null, // DSTORE_3
        null, // ASTORE_0
        null, // ASTORE_1
        null, // ASTORE_2
        null, // ASTORE_3
        Method.VISIT_INSN, // IASTORE
        Method.VISIT_INSN, // LASTORE
        Method.VISIT_INSN, // FASTORE
        Method.VISIT_INSN, // DASTORE
        Method.VISIT_INSN, // AASTORE
        Method.VISIT_INSN, // BASTORE
        Method.VISIT_INSN, // CASTORE
        Method.VISIT_INSN, // SASTORE
        Method.VISIT_INSN, // POP
        Method.VISIT_INSN, // POP2
        Method.VISIT_INSN, // DUP
        Method.VISIT_INSN, // DUP_X1
        Method.VISIT_INSN, // DUP_X2
        Method.VISIT_INSN, // DUP2
        Method.VISIT_INSN, // DUP2_X1
        Method.VISIT_INSN, // DUP2_X2
        Method.VISIT_INSN, // SWAP
        Method.VISIT_INSN, // IADD
        Method.VISIT_INSN, // LADD
        Method.VISIT_INSN, // FADD
        Method.VISIT_INSN, // DADD
        Method.VISIT_INSN, // ISUB
        Method.VISIT_INSN, // LSUB
        Method.VISIT_INSN, // FSUB
        Method.VISIT_INSN, // DSUB
        Method.VISIT_INSN, // IMUL
        Method.VISIT_INSN, // LMUL
        Method.VISIT_INSN, // FMUL
        Method.VISIT_INSN, // DMUL
        Method.VISIT_INSN, // IDIV
        Method.VISIT_INSN, // LDIV
        Method.VISIT_INSN, // FDIV
        Method.VISIT_INSN, // DDIV
        Method.VISIT_INSN, // IREM
        Method.VISIT_INSN, // LREM
        Method.VISIT_INSN, // FREM
        Method.VISIT_INSN, // DREM
        Method.VISIT_INSN, // INEG
        Method.VISIT_INSN, // LNEG
        Method.VISIT_INSN, // FNEG
        Method.VISIT_INSN, // DNEG
        Method.VISIT_INSN, // ISHL
        Method.VISIT_INSN, // LSHL
        Method.VISIT_INSN, // ISHR
        Method.VISIT_INSN, // LSHR
        Method.VISIT_INSN, // IUSHR
        Method.VISIT_INSN, // LUSHR
        Method.VISIT_INSN, // IAND
        Method.VISIT_INSN, // LAND
        Method.VISIT_INSN, // IOR
        Method.VISIT_INSN, // LOR
        Method.VISIT_INSN, // IXOR
        Method.VISIT_INSN, // LXOR
        null, // IINC
        Method.VISIT_INSN, // I2L
        Method.VISIT_INSN, // I2F
        Method.VISIT_INSN, // I2D
        Method.VISIT_INSN, // L2I
        Method.VISIT_INSN, // L2F
        Method.VISIT_INSN, // L2D
        Method.VISIT_INSN, // F2I
        Method.VISIT_INSN, // F2L
        Method.VISIT_INSN, // F2D
        Method.VISIT_INSN, // D2I
        Method.VISIT_INSN, // D2L
        Method.VISIT_INSN, // D2F
        Method.VISIT_INSN, // I2B
        Method.VISIT_INSN, // I2C
        Method.VISIT_INSN, // I2S
        Method.VISIT_INSN, // LCMP
        Method.VISIT_INSN, // FCMPL
        Method.VISIT_INSN, // FCMPG
        Method.VISIT_INSN, // DCMPL
        Method.VISIT_INSN, // DCMPG
        Method.VISIT_JUMP_INSN, // IFEQ
        Method.VISIT_JUMP_INSN, // IFNE
        Method.VISIT_JUMP_INSN, // IFLT
        Method.VISIT_JUMP_INSN, // IFGE
        Method.VISIT_JUMP_INSN, // IFGT
        Method.VISIT_JUMP_INSN, // IFLE
        Method.VISIT_JUMP_INSN, // IF_ICMPEQ
        Method.VISIT_JUMP_INSN, // IF_ICMPNE
        Method.VISIT_JUMP_INSN, // IF_ICMPLT
        Method.VISIT_JUMP_INSN, // IF_ICMPGE
        Method.VISIT_JUMP_INSN, // IF_ICMPGT
        Method.VISIT_JUMP_INSN, // IF_ICMPLE
        Method.VISIT_JUMP_INSN, // IF_ACMPEQ
        Method.VISIT_JUMP_INSN, // IF_ACMPNE
        Method.VISIT_JUMP_INSN, // GOTO
        Method.VISIT_JUMP_INSN, // JSR
        Method.VISIT_VAR_INSN, // RET
        null, // TABLESWITCH
        null, // LOOKUPSWITCH
        Method.VISIT_INSN, // IRETURN
        Method.VISIT_INSN, // LRETURN
        Method.VISIT_INSN, // FRETURN
        Method.VISIT_INSN, // DRETURN
        Method.VISIT_INSN, // ARETURN
        Method.VISIT_INSN, // RETURN
        Method.VISIT_FIELD_INSN, // GETSTATIC
        Method.VISIT_FIELD_INSN, // PUTSTATIC
        Method.VISIT_FIELD_INSN, // GETFIELD
        Method.VISIT_FIELD_INSN, // PUTFIELD
        Method.VISIT_METHOD_INSN, // INVOKEVIRTUAL
        Method.VISIT_METHOD_INSN, // INVOKESPECIAL
        Method.VISIT_METHOD_INSN, // INVOKESTATIC
        Method.VISIT_METHOD_INSN, // INVOKEINTERFACE
        null, // INVOKEDYNAMIC
        Method.VISIT_TYPE_INSN, // NEW
        Method.VISIT_INT_INSN, // NEWARRAY
        Method.VISIT_TYPE_INSN, // ANEWARRAY
        Method.VISIT_INSN, // ARRAYLENGTH
        Method.VISIT_INSN, // ATHROW
        Method.VISIT_TYPE_INSN, // CHECKCAST
        Method.VISIT_TYPE_INSN, // INSTANCEOF
        Method.VISIT_INSN, // MONITORENTER
        Method.VISIT_INSN, // MONITOREXIT
        null, // WIDE
        null, // MULTIANEWARRAY
        Method.VISIT_JUMP_INSN, // IFNULL
        Method.VISIT_JUMP_INSN // IFNONNULL
    };

    private static final String INVALID = "Invalid ";
    private static final String INVALID_DESCRIPTOR = "Invalid descriptor: ";
    private static final String INVALID_TYPE_REFERENCE = "Invalid type reference sort 0x";
    private static final String INVALID_LOCAL_VARIABLE_INDEX = "Invalid local variable index";
    private static final String MUST_NOT_BE_NULL_OR_EMPTY = " (must not be null or empty)";
    private static final String START_LABEL = "start label";
    private static final String END_LABEL = "end label";

    /** The class version number. */
    public int version;

    /** The access flags of the visited method. */
    private int access;

    /**
      * The number of method parameters that can have runtime visible annotations. 0 means that all the
      * parameters from the method descriptor can have annotations.
      */
    private int visibleAnnotableParameterCount;

    /**
      * The number of method parameters that can have runtime invisible annotations. 0 means that all
      * the parameters from the method descriptor can have annotations.
      */
    private int invisibleAnnotableParameterCount;

    /** Whether the {@link #visitCode} method has been called. */
    private boolean visitCodeCalled;

    /** Whether the {@link #visitMaxs} method has been called. */
    private boolean visitMaxCalled;

    /** Whether the {@link #visitEnd} method has been called. */
    private boolean visitEndCalled;

    /** The number of visited instructions so far. */
    private int insnCount;

    /** The index of the instruction designated by each visited label. */
    private final Map labelInsnIndices;

    /** The labels referenced by the visited method. */
    private Set




© 2015 - 2025 Weber Informatics LLC | Privacy Policy