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 */
017
018package org.apache.commons.compress.harmony.unpack200.bytecode;
019
020import org.apache.commons.compress.harmony.unpack200.Segment;
021import org.apache.commons.compress.harmony.unpack200.SegmentConstantPool;
022
023/**
024 * This class keeps track of operands used. It provides API to let other classes get next elements, and also knows about
025 * which classes have been used recently in super, this and new references.
026 */
027public class OperandManager {
028
029    int[] bcCaseCount;
030    int[] bcCaseValue;
031    int[] bcByte;
032    int[] bcShort;
033    int[] bcLocal;
034    int[] bcLabel;
035    int[] bcIntRef;
036    int[] bcFloatRef;
037    int[] bcLongRef;
038    int[] bcDoubleRef;
039    int[] bcStringRef;
040    int[] bcClassRef;
041    int[] bcFieldRef;
042    int[] bcMethodRef;
043    int[] bcIMethodRef;
044    int[] bcThisField;
045    int[] bcSuperField;
046    int[] bcThisMethod;
047    int[] bcSuperMethod;
048    int[] bcInitRef;
049    int[] wideByteCodes;
050
051    int bcCaseCountIndex;
052    int bcCaseValueIndex;
053    int bcByteIndex;
054    int bcShortIndex;
055    int bcLocalIndex;
056    int bcLabelIndex;
057    int bcIntRefIndex;
058    int bcFloatRefIndex;
059    int bcLongRefIndex;
060    int bcDoubleRefIndex;
061    int bcStringRefIndex;
062    int bcClassRefIndex;
063    int bcFieldRefIndex;
064    int bcMethodRefIndex;
065    int bcIMethodRefIndex;
066    int bcThisFieldIndex;
067    int bcSuperFieldIndex;
068    int bcThisMethodIndex;
069    int bcSuperMethodIndex;
070    int bcInitRefIndex;
071    int wideByteCodeIndex;
072
073    Segment segment;
074
075    String currentClass;
076    String superClass;
077    String newClass;
078
079    public OperandManager(final int[] bcCaseCount, final int[] bcCaseValue, final int[] bcByte, final int[] bcShort,
080        final int[] bcLocal, final int[] bcLabel, final int[] bcIntRef, final int[] bcFloatRef, final int[] bcLongRef,
081        final int[] bcDoubleRef, final int[] bcStringRef, final int[] bcClassRef, final int[] bcFieldRef,
082        final int[] bcMethodRef, final int[] bcIMethodRef, final int[] bcThisField, final int[] bcSuperField,
083        final int[] bcThisMethod, final int[] bcSuperMethod, final int[] bcInitRef, final int[] wideByteCodes) {
084        this.bcCaseCount = bcCaseCount;
085        this.bcCaseValue = bcCaseValue;
086        this.bcByte = bcByte;
087        this.bcShort = bcShort;
088        this.bcLocal = bcLocal;
089        this.bcLabel = bcLabel;
090        this.bcIntRef = bcIntRef;
091        this.bcFloatRef = bcFloatRef;
092        this.bcLongRef = bcLongRef;
093        this.bcDoubleRef = bcDoubleRef;
094        this.bcStringRef = bcStringRef;
095        this.bcClassRef = bcClassRef;
096        this.bcFieldRef = bcFieldRef;
097        this.bcMethodRef = bcMethodRef;
098        this.bcIMethodRef = bcIMethodRef;
099
100        this.bcThisField = bcThisField;
101        this.bcSuperField = bcSuperField;
102        this.bcThisMethod = bcThisMethod;
103        this.bcSuperMethod = bcSuperMethod;
104        this.bcInitRef = bcInitRef;
105        this.wideByteCodes = wideByteCodes;
106    }
107
108    public int nextCaseCount() {
109        return bcCaseCount[bcCaseCountIndex++];
110    }
111
112    public int nextCaseValues() {
113        return bcCaseValue[bcCaseValueIndex++];
114    }
115
116    public int nextByte() {
117        return bcByte[bcByteIndex++];
118    }
119
120    public int nextShort() {
121        return bcShort[bcShortIndex++];
122    }
123
124    public int nextLocal() {
125        return bcLocal[bcLocalIndex++];
126    }
127
128    public int nextLabel() {
129        return bcLabel[bcLabelIndex++];
130    }
131
132    public int nextIntRef() {
133        return bcIntRef[bcIntRefIndex++];
134    }
135
136    public int nextFloatRef() {
137        return bcFloatRef[bcFloatRefIndex++];
138    }
139
140    public int nextLongRef() {
141        return bcLongRef[bcLongRefIndex++];
142    }
143
144    public int nextDoubleRef() {
145        return bcDoubleRef[bcDoubleRefIndex++];
146    }
147
148    public int nextStringRef() {
149        return bcStringRef[bcStringRefIndex++];
150    }
151
152    public int nextClassRef() {
153        return bcClassRef[bcClassRefIndex++];
154    }
155
156    public int nextFieldRef() {
157        return bcFieldRef[bcFieldRefIndex++];
158    }
159
160    public int nextMethodRef() {
161        return bcMethodRef[bcMethodRefIndex++];
162    }
163
164    public int nextIMethodRef() {
165        return bcIMethodRef[bcIMethodRefIndex++];
166    }
167
168    public int nextThisFieldRef() {
169        return bcThisField[bcThisFieldIndex++];
170    }
171
172    public int nextSuperFieldRef() {
173        return bcSuperField[bcSuperFieldIndex++];
174    }
175
176    public int nextThisMethodRef() {
177        return bcThisMethod[bcThisMethodIndex++];
178    }
179
180    public int nextSuperMethodRef() {
181        return bcSuperMethod[bcSuperMethodIndex++];
182    }
183
184    public int nextInitRef() {
185        return bcInitRef[bcInitRefIndex++];
186    }
187
188    public int nextWideByteCode() {
189        return wideByteCodes[wideByteCodeIndex++];
190    }
191
192    public void setSegment(final Segment segment) {
193        this.segment = segment;
194    }
195
196    public SegmentConstantPool globalConstantPool() {
197        return segment.getConstantPool();
198    }
199
200    public void setCurrentClass(final String string) {
201        currentClass = string;
202    }
203
204    public void setSuperClass(final String string) {
205        superClass = string;
206    }
207
208    public void setNewClass(final String string) {
209        newClass = string;
210    }
211
212    public String getCurrentClass() {
213        if (null == currentClass) {
214            throw new Error("Current class not set yet");
215        }
216        return currentClass;
217    }
218
219    public String getSuperClass() {
220        if (null == superClass) {
221            throw new Error("SuperClass not set yet");
222        }
223        return superClass;
224    }
225
226    public String getNewClass() {
227        if (null == newClass) {
228            throw new Error("New class not set yet");
229        }
230        return newClass;
231    }
232}