    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.structurals;
    020
    021/**
    022 * This class represents a JVM execution frame; that means, a local variable array and an operand stack.
    023 */
    024
    025public class Frame {
    026
    027    /**
    028     * For instance initialization methods, it is important to remember which instance it is that is not initialized yet. It
    029     * will be initialized invoking another constructor later. NULL means the instance already *is* initialized.
    030     *
    031     * @deprecated Use the getter/setter to access the field as it may be made private in a later release
    032     */
    033    @Deprecated
    034    protected static UninitializedObjectType _this;
    035
    036    /**
    037     * Gets the static _this reference.
    038     *
    039     * @return the _this.
    040     * @since 6.0
    041     */
    042    public static UninitializedObjectType getThis() {
    043        return _this;
    044    }
    045
    046    /**
    047     * Sets the static _this reference.
    048     *
    049     * @param _this the _this to set.
    050     * @since 6.0
    051     */
    052    public static void setThis(final UninitializedObjectType _this) {
    053        Frame._this = _this;
    054    }
    055
    056    /**
    057     * The local variables.
    058     */
    059    private final LocalVariables locals;
    060
    061    /**
    062     * The operand stack.
    063     */
    064    private final OperandStack stack;
    065
    066    /**
    067     * Constructs a Frame.
    068     *
    069     * @param maxLocals the maximum number of local variables.
    070     * @param maxStack the maximum stack size.
    071     */
    072    public Frame(final int maxLocals, final int maxStack) {
    073        locals = new LocalVariables(maxLocals);
    074        stack = new OperandStack(maxStack);
    075    }
    076
    077    /**
    078     * Constructs a Frame.
    079     *
    080     * @param locals the local variables.
    081     * @param stack the operand stack.
    082     */
    083    public Frame(final LocalVariables locals, final OperandStack stack) {
    084        this.locals = locals;
    085        this.stack = stack;
    086    }
    087
    088    /**
    089     * Creates a clone of this frame.
    090     *
    091     * @return a clone of this frame.
    092     */
    093    @Override
    094    protected Object clone() {
    095        return new Frame(locals.getClone(), stack.getClone());
    096    }
    097
    098    /**
    099     * Checks if this frame equals another object.
    100     *
    101     * @param o the object to compare.
    102     * @return true if equal, false otherwise.
    103     */
    104    @Override
    105    public boolean equals(final Object o) {
    106        if (!(o instanceof Frame)) {
    107            return false; // implies "null" is non-equal.
    108        }
    109        final Frame f = (Frame) o;
    110        return this.stack.equals(f.stack) && this.locals.equals(f.locals);
    111    }
    112
    113    /**
    114     * Gets a clone of this frame.
    115     *
    116     * @return a clone of this frame.
    117     */
    118    public Frame getClone() {
    119        return (Frame) clone();
    120    }
    121
    122    /**
    123     * Gets the local variables.
    124     *
    125     * @return the local variables.
    126     */
    127    public LocalVariables getLocals() {
    128        return locals;
    129    }
    130
    131    /**
    132     * Gets the operand stack.
    133     *
    134     * @return the operand stack.
    135     */
    136    public OperandStack getStack() {
    137        return stack;
    138    }
    139
    140    /**
    141     * @return a hash code value for the object.
    142     */
    143    @Override
    144    public int hashCode() {
    145        return stack.hashCode() ^ locals.hashCode();
    146    }
    147
    148    /**
    149     * Returns a String representation of the Frame instance.
    150     */
    151    @Override
    152    public String toString() {
    153        final StringBuilder s = new StringBuilder("Local Variables:\n");
    154        s.append(locals);
    155        s.append("OperandStack:\n");
    156        s.append(stack);
    157        return s.toString();
    158    }
    159}