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}