    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 *   https://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019package org.apache.bcel.verifier.statics;
    020
    021import java.util.Arrays;
    022
    023import org.apache.bcel.generic.Type;
    024import org.apache.bcel.verifier.exc.AssertionViolatedException;
    025import org.apache.bcel.verifier.exc.LocalVariableInfoInconsistentException;
    026
    027/**
    028 * A utility class holding the information about the names and the types of the local variables in a given method.
    029 */
    030public class LocalVariablesInfo {
    031
    032    /** The information about the local variables is stored here. */
    033    private final LocalVariableInfo[] localVariableInfos;
    034
    035    /** The constructor. */
    036    LocalVariablesInfo(final int maxLocals) {
    037        localVariableInfos = new LocalVariableInfo[maxLocals];
    038        Arrays.setAll(localVariableInfos, i -> new LocalVariableInfo());
    039    }
    040
    041    /**
    042     * Adds information about the local variable in slot 'slot'. Automatically adds information for slot+1 if 't' is
    043     * Type.LONG or Type.DOUBLE.
    044     *
    045     * @param slot Slot number for local variable information.
    046     * @param name variable name.
    047     * @param startPc Range in which the variable is valid.
    048     * @param length length of ...
    049     * @param type variable type.
    050     * @throws LocalVariableInfoInconsistentException if the new information conflicts with already gathered information.
    051     */
    052    public void add(final int slot, final String name, final int startPc, final int length, final Type type) throws LocalVariableInfoInconsistentException {
    053        // The add operation on LocalVariableInfo may throw the '...Inconsistent...' exception, we don't throw it explicitly
    054        // here.
    055
    056        if (slot < 0 || slot >= localVariableInfos.length) {
    057            throw new AssertionViolatedException("Slot number for local variable information out of range.");
    058        }
    059
    060        localVariableInfos[slot].add(name, startPc, length, type);
    061        if (type == Type.LONG) {
    062            localVariableInfos[slot + 1].add(name, startPc, length, LONG_Upper.theInstance());
    063        }
    064        if (type == Type.DOUBLE) {
    065            localVariableInfos[slot + 1].add(name, startPc, length, DOUBLE_Upper.theInstance());
    066        }
    067    }
    068
    069    /**
    070     * Returns the LocalVariableInfo for the given slot.
    071     *
    072     * @param slot Slot to query.
    073     * @return The LocalVariableInfo for the given slot.
    074     */
    075    public LocalVariableInfo getLocalVariableInfo(final int slot) {
    076        if (slot < 0 || slot >= localVariableInfos.length) {
    077            throw new AssertionViolatedException("Slot number for local variable information out of range.");
    078        }
    079        return localVariableInfos[slot];
    080    }
    081}