View Javadoc

1   /*
2    * Copyright  2000-2004 The Apache Software Foundation
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License"); 
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License. 
15   *
16   */
17  package org.apache.bcel.generic;
18  
19  import java.io.DataOutputStream;
20  import java.io.IOException;
21  import org.apache.bcel.util.ByteSequence;
22  
23  /***
24   * IINC - Increment local variable by constant
25   *
26   * @version $Id: IINC.java 386056 2006-03-15 11:31:56Z tcurdt $
27   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
28   */
29  public class IINC extends LocalVariableInstruction {
30  
31      private boolean wide;
32      private int c;
33  
34  
35      /***
36       * Empty constructor needed for the Class.newInstance() statement in
37       * Instruction.readInstruction(). Not to be used otherwise.
38       */
39      IINC() {
40      }
41  
42  
43      /***
44       * @param n index of local variable
45       * @param c increment factor
46       */
47      public IINC(int n, int c) {
48          super(); // Default behaviour of LocalVariableInstruction causes error
49          this.opcode = org.apache.bcel.Constants.IINC;
50          this.length = (short) 3;
51          setIndex(n); // May set wide as side effect
52          setIncrement(c);
53      }
54  
55  
56      /***
57       * Dump instruction as byte code to stream out.
58       * @param out Output stream
59       */
60      public void dump( DataOutputStream out ) throws IOException {
61          if (wide) {
62              out.writeByte(org.apache.bcel.Constants.WIDE);
63          }
64          out.writeByte(opcode);
65          if (wide) {
66              out.writeShort(n);
67              out.writeShort(c);
68          } else {
69              out.writeByte(n);
70              out.writeByte(c);
71          }
72      }
73  
74  
75      private final void setWide() {
76          wide = (n > org.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE);
77          if (wide) {
78              length = 6; // wide byte included  
79          } else {
80              length = 3;
81          }
82      }
83  
84  
85      /***
86       * Read needed data (e.g. index) from file.
87       */
88      protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
89          this.wide = wide;
90          if (wide) {
91              length = 6;
92              n = bytes.readUnsignedShort();
93              c = bytes.readShort();
94          } else {
95              length = 3;
96              n = bytes.readUnsignedByte();
97              c = bytes.readByte();
98          }
99      }
100 
101 
102     /***
103      * @return mnemonic for instruction
104      */
105     public String toString( boolean verbose ) {
106         return super.toString(verbose) + " " + c;
107     }
108 
109 
110     /***
111      * Set index of local variable.
112      */
113     public final void setIndex( int n ) {
114         if (n < 0) {
115             throw new ClassGenException("Negative index value: " + n);
116         }
117         this.n = n;
118         setWide();
119     }
120 
121 
122     /***
123      * @return increment factor
124      */
125     public final int getIncrement() {
126         return c;
127     }
128 
129 
130     /***
131      * Set increment factor.
132      */
133     public final void setIncrement( int c ) {
134         this.c = c;
135         setWide();
136     }
137 
138 
139     /*** @return int type
140      */
141     public Type getType( ConstantPoolGen cp ) {
142         return Type.INT;
143     }
144 
145 
146     /***
147      * Call corresponding visitor method(s). The order is:
148      * Call visitor methods of implemented interfaces first, then
149      * call methods according to the class hierarchy in descending order,
150      * i.e., the most specific visitXXX() call comes last.
151      *
152      * @param v Visitor object
153      */
154     public void accept( Visitor v ) {
155         v.visitLocalVariableInstruction(this);
156         v.visitIINC(this);
157     }
158 }