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