001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 *  Unless required by applicable law or agreed to in writing, software
012 *  distributed under the License is distributed on an "AS IS" BASIS,
013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 *  See the License for the specific language governing permissions and
015 *  limitations under the License.
016 */
017package org.apache.bcel.verifier.structurals;
018
019/**
020 * This class represents a JVM execution frame; that means, a local variable array and an operand stack.
021 */
022
023public class Frame {
024
025    /**
026     * For instance initialization methods, it is important to remember which instance it is that is not initialized yet. It
027     * will be initialized invoking another constructor later. NULL means the instance already *is* initialized.
028     *
029     * @deprecated Use the getter/setter to access the field as it may be made private in a later release
030     */
031    @Deprecated
032    protected static UninitializedObjectType _this;
033
034    /**
035     * @return the _this
036     * @since 6.0
037     */
038    public static UninitializedObjectType getThis() {
039        return _this;
040    }
041
042    /**
043     * @param _this the _this to set
044     * @since 6.0
045     */
046    public static void setThis(final UninitializedObjectType _this) {
047        Frame._this = _this;
048    }
049
050    /**
051     */
052    private final LocalVariables locals;
053
054    /**
055     */
056    private final OperandStack stack;
057
058    /**
059     */
060    public Frame(final int maxLocals, final int maxStack) {
061        locals = new LocalVariables(maxLocals);
062        stack = new OperandStack(maxStack);
063    }
064
065    /**
066     */
067    public Frame(final LocalVariables locals, final OperandStack stack) {
068        this.locals = locals;
069        this.stack = stack;
070    }
071
072    /**
073     */
074    @Override
075    protected Object clone() {
076        return new Frame(locals.getClone(), stack.getClone());
077    }
078
079    /**
080     */
081    @Override
082    public boolean equals(final Object o) {
083        if (!(o instanceof Frame)) {
084            return false; // implies "null" is non-equal.
085        }
086        final Frame f = (Frame) o;
087        return this.stack.equals(f.stack) && this.locals.equals(f.locals);
088    }
089
090    /**
091     */
092    public Frame getClone() {
093        return (Frame) clone();
094    }
095
096    /**
097     */
098    public LocalVariables getLocals() {
099        return locals;
100    }
101
102    /**
103     */
104    public OperandStack getStack() {
105        return stack;
106    }
107
108    /**
109     * @return a hash code value for the object.
110     */
111    @Override
112    public int hashCode() {
113        return stack.hashCode() ^ locals.hashCode();
114    }
115
116    /**
117     * Returns a String representation of the Frame instance.
118     */
119    @Override
120    public String toString() {
121        final StringBuilder s = new StringBuilder("Local Variables:\n");
122        s.append(locals);
123        s.append("OperandStack:\n");
124        s.append(stack);
125        return s.toString();
126    }
127}